From c7d1aa3e92bf3ac643ba138558fcc301b0e28aad Mon Sep 17 00:00:00 2001 From: Oleg Dubinskiy Date: Sat, 18 Jan 2025 21:51:58 +0100 Subject: [PATCH] [SHELL32] SHELL_FindExecutable: improve path handling code (#7633) Follow-up of 42d5dfd3de5e65da6137413c98b5ab0cbc11325e. - Revert "shell32: Fix ShellExecute for non-filespec paths." https://gitlab.winehq.org/wine/wine/-/commit/0bad544aab9e2c9ee93bbabac0386e02c58a39c0. - Apply "shell32: Look for the file name without extension also for the path search case." https://gitlab.winehq.org/wine/wine/-/commit/38b6640be91047b2cae71c103afed8a5b448542d. - Clear leading/trailing whitespaces (an improvement by Doug Lyons). - Update the comment for xlpFile buffer definition, to match the current code behaviour. This fixes some failures for the following tests: - shell32_apitest:ShellExecCmdLine: 12 failures less, - shell32_apitest:ShellExecuteEx: 5 failures less, - shell32_winetest:shlexec: crash fixed, now 13 failures as before, - wshom_winetest:wshom: crash fixed, now 2 failures less too (0 failures). I've also tested: the problem which was intended to be fixed by the guilty commit (CORE-19953) still remains fixed after this change. CORE-19964 --- dll/win32/shell32/shlexec.cpp | 66 +++++++++++------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 646a2a6c84c..b6bb1f3b224 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -748,7 +748,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, WCHAR wBuffer[256]; /* Used to GetProfileString */ UINT retval = SE_ERR_NOASSOC; WCHAR *tok; /* token pointer */ - WCHAR xlpFile[MAX_PATH]; /* result of SearchPath */ + WCHAR xlpFile[MAX_PATH]; /* result of PathResolve */ DWORD attribs; /* file attributes */ WCHAR curdir[MAX_PATH]; const WCHAR *search_paths[3] = {0}; @@ -777,55 +777,29 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, } GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir); - if (!PathIsFileSpecW(lpFile)) + if (lpPath && *lpPath) { - BOOL found = FALSE; - if (lpPath && *lpPath) - { - TRACE("lpPath %s\n", debugstr_w(lpPath)); - PathCombineW(xlpFile, lpPath, lpFile); - if (PathFileExistsDefExtW(xlpFile, WHICH_DEFAULT | WHICH_OPTIONAL) || PathFileExistsW(xlpFile)) - { - GetFullPathNameW(xlpFile, ARRAY_SIZE(xlpFile), xlpFile, NULL); - found = TRUE; - } - } - if (!found) - { - lstrcpyW(xlpFile, lpFile); - if (PathFileExistsDefExtW(xlpFile, WHICH_DEFAULT | WHICH_OPTIONAL) || PathFileExistsW(xlpFile)) - { - GetFullPathNameW(xlpFile, ARRAY_SIZE(xlpFile), xlpFile, NULL); - found = TRUE; - } - } - if (found) - { - lpFile = xlpFile; - lstrcpyW(lpResult, xlpFile); - } - else - xlpFile[0] = '\0'; + search_paths[0] = lpPath; + search_paths[1] = curdir; } else { - if (lpPath && *lpPath) - { - search_paths[0] = lpPath; - search_paths[1] = curdir; - } - else - search_paths[0] = curdir; - lstrcpyW(xlpFile, lpFile); - if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS)) - { - TRACE("PathResolveW returned non-zero\n"); - lpFile = xlpFile; - lstrcpyW(lpResult, xlpFile); - /* The file was found in lpPath or one of the directories in the system-wide search path */ - } - else - xlpFile[0] = '\0'; + search_paths[0] = curdir; + } + + lstrcpyW(xlpFile, lpFile); + if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS) || + PathFindOnPathW(xlpFile, search_paths)) + { + TRACE("PathResolveW returned non-zero\n"); + lpFile = xlpFile; + PathRemoveBlanksW(xlpFile); + lstrcpyW(lpResult, xlpFile); + /* The file was found in lpPath or one of the directories in the system-wide search path */ + } + else + { + xlpFile[0] = '\0'; } attribs = GetFileAttributesW(lpFile);