From 1bc7db2e7d2c50a42c8340aa875893df970d4a8f Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Mon, 18 Mar 2024 18:24:52 +0000 Subject: [PATCH] shell32: Fix FindExecutable search path. It should look in the currect working directory, instead of the directory where the current executable is in. --- dlls/shell32/shlexec.c | 24 ++++++++++++++++-------- dlls/shell32/tests/shlexec.c | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index abb519e260d..9aa7963b71c 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(exec); typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out); +extern BOOL WINAPI PathResolveAW(void *path, const void **paths, DWORD flags); static inline BOOL isSpace(WCHAR c) { @@ -599,6 +600,8 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, WCHAR *tok; /* token pointer */ WCHAR xlpFile[256]; /* result of SearchPath */ DWORD attribs; /* file attributes */ + WCHAR curdir[MAX_PATH]; + const WCHAR *search_paths[3] = {0}; TRACE("%s\n", debugstr_w(lpFile)); @@ -623,18 +626,23 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, return 33; } - if (SearchPathW(lpPath, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, NULL)) + if (lpPath && *lpPath) + { + search_paths[0] = lpPath; + search_paths[1] = curdir; + } + else + search_paths[0] = curdir; + GetCurrentDirectoryW(MAX_PATH, curdir); + lstrcpyW(xlpFile, lpFile); + if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS)) { TRACE("SearchPathW returned non-zero\n"); lpFile = xlpFile; - /* The file was found in the application-supplied default directory (or the system search path) */ - } - else if (lpPath && SearchPathW(NULL, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, NULL)) - { - TRACE("SearchPathW returned non-zero\n"); - lpFile = xlpFile; - /* The file was found in one of the directories in the system-wide search path */ + /* The file was found in lpPath or one of the directories in the system-wide search path */ } + else + xlpFile[0] = '\0'; attribs = GetFileAttributesW(lpFile); if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY)) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index c9e23c7062e..2f95ff2e15d 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2063,7 +2063,7 @@ static void test_find_executable(void) GetCurrentDirectoryA(MAX_PATH, curdir); SetCurrentDirectoryA(tmpdir); rc=(INT_PTR)FindExecutableA(basename, NULL, command); - todo_wine ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %Id\n", basename, rc); + ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %Id\n", basename, rc); SetCurrentDirectoryA(curdir); sprintf(filename, "%s\\test file.sfe", tmpdir);