https://git.reactos.org/?p=reactos.git;a=commitdiff;h=42d5dfd3de5e65da6137413c98b5ab0cbc11325e

commit 42d5dfd3de5e65da6137413c98b5ab0cbc11325e
Author:     Oleg Dubinskiy <oleg.dubinski...@gmail.com>
AuthorDate: Sun Dec 29 17:25:43 2024 +0100
Commit:     GitHub <nore...@github.com>
CommitDate: Sun Dec 29 17:25:43 2024 +0100

    [SHELL32] SHELL_FindExecutable: import new path handling code from Wine 
10.0-rc3 (#7588)
    
    
https://gitlab.winehq.org/wine/wine/-/blob/wine-10.0-rc3/dlls/shell32/shlexec.c?ref_type=tags#L631
    
https://gitlab.winehq.org/wine/wine/-/commit/0bad544aab9e2c9ee93bbabac0386e02c58a39c0
    Import new path handling code from Wine 10.0-rc3. It uses PathResolveW(), 
which was hacked in ReactOS for a long time but has been implemented properly 
starting from 0.4.15-dev. So now it should work correctly, and we don't need to 
use SearchPathW() anymore.
    This fixes a heap corruption from shell32.dll when launching SpotifyXP 
2.0.3 Beta and trying to login with Spotify credentials via OAuth login method. 
Also it fixes the same heap corruption when pressing Update button in CCleaner 
5.39.6399.
    CORE-14670, CORE-19953
---
 dll/win32/shell32/shlexec.cpp | 61 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp
index 6af8844632e..85c7feab0ff 100644
--- a/dll/win32/shell32/shlexec.cpp
+++ b/dll/win32/shell32/shlexec.cpp
@@ -756,8 +756,10 @@ 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[256];      /* result of SearchPath */
+    WCHAR xlpFile[MAX_PATH]; /* result of SearchPath */
     DWORD attribs;           /* file attributes */
+    WCHAR curdir[MAX_PATH];
+    const WCHAR *search_paths[3] = {0};
 
     TRACE("%s\n", debugstr_w(lpFile));
 
@@ -782,17 +784,56 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR 
lpFile, LPCWSTR lpVerb,
         return 33;
     }
 
-    if (SearchPathW(lpPath, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, 
NULL))
+    GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
+    if (!PathIsFileSpecW(lpFile))
     {
-        TRACE("SearchPathW returned non-zero\n");
-        lpFile = xlpFile;
-        /* The file was found in the application-supplied default directory 
(or the system search path) */
+        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';
     }
-    else if (lpPath && SearchPathW(NULL, lpFile, L".exe", ARRAY_SIZE(xlpFile), 
xlpFile, NULL))
+    else
     {
-        TRACE("SearchPathW returned non-zero\n");
-        lpFile = xlpFile;
-        /* The file was found in one of the directories in the system-wide 
search path */
+        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';
     }
 
     attribs = GetFileAttributesW(lpFile);
@@ -932,7 +973,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR 
lpFile, LPCWSTR lpVerb,
         }
     }
 
-    TRACE("returning %s\n", debugstr_w(lpResult));
+    TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval);
     return retval;
 }
 

Reply via email to