shell32: Handle the directory parameter in ShellExecute functions

André Hentschel nerv at dawncrow.de
Sun Aug 28 11:02:31 CDT 2011


based on a patch from AF
see http://bugs.winehq.org/show_bug.cgi?id=8439 (1.2)
---
 dlls/shell32/shlexec.c       |   31 +++++++++++--------------------
 dlls/shell32/tests/shlexec.c |    5 ++++-
 2 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c
index 3f7a170..be1ad35 100644
--- a/dlls/shell32/shlexec.c
+++ b/dlls/shell32/shlexec.c
@@ -1536,9 +1536,8 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
         SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
         SEE_MASK_UNICODE       | SEE_MASK_ASYNCOK      | SEE_MASK_HMONITOR;
 
-    WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
-    WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd;
-    DWORD dwApplicationNameLen = MAX_PATH+2;
+    WCHAR wszApplicationName[MAX_PATH], parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
+    WCHAR *wszParameters, *wszDir, *wcmd;
     DWORD parametersLen = sizeof(parametersBuffer) / sizeof(WCHAR);
     DWORD dirLen = sizeof(dirBuffer) / sizeof(WCHAR);
     DWORD wcmdLen = sizeof(wcmdBuffer) / sizeof(WCHAR);
@@ -1565,15 +1564,10 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 
     /* make copies of all path/command strings */
     if (!sei_tmp.lpFile)
-    {
-        wszApplicationName = HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen*sizeof(WCHAR));
-        *wszApplicationName = '\0';
-    }
+        wszApplicationName[0] = '\0';
     else if (*sei_tmp.lpFile == '\"')
     {
         DWORD l = strlenW(sei_tmp.lpFile+1);
-        if(l >= dwApplicationNameLen) dwApplicationNameLen = l+1;
-        wszApplicationName = HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen*sizeof(WCHAR));
         memcpy(wszApplicationName, sei_tmp.lpFile+1, (l+1)*sizeof(WCHAR));
         if (wszApplicationName[l-1] == '\"')
             wszApplicationName[l-1] = '\0';
@@ -1581,8 +1575,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
         TRACE("wszApplicationName=%s\n",debugstr_w(wszApplicationName));
     } else {
         DWORD l = strlenW(sei_tmp.lpFile)+1;
-        if(l > dwApplicationNameLen) dwApplicationNameLen = l+1;
-        wszApplicationName = HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen*sizeof(WCHAR));
         memcpy(wszApplicationName, sei_tmp.lpFile, l*sizeof(WCHAR));
     }
 
@@ -1614,6 +1606,12 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
     else
 	*wszDir = '\0';
 
+    if (wszDir)
+    {
+        LPCWSTR wszOtherDirs[] = {wszDir, NULL};
+        PathFindOnPathW( wszApplicationName, wszOtherDirs);
+    }
+
     /* adjust string pointers to point to the new buffers */
     sei_tmp.lpFile = wszApplicationName;
     sei_tmp.lpParameters = wszParameters;
@@ -1638,7 +1636,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 	    IShellExecuteHookW_Release(pSEH);
 
 	    if (hr == S_OK) {
-                HeapFree(GetProcessHeap(), 0, wszApplicationName);
                 if (wszParameters != parametersBuffer)
                     HeapFree(GetProcessHeap(), 0, wszParameters);
                 if (wszDir != dirBuffer)
@@ -1655,7 +1652,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
     if ( ERROR_SUCCESS == ShellExecute_FromContextMenu( &sei_tmp ) )
     {
         sei->hInstApp = (HINSTANCE) 33;
-        HeapFree(GetProcessHeap(), 0, wszApplicationName);
         if (wszParameters != parametersBuffer)
             HeapFree(GetProcessHeap(), 0, wszParameters);
         if (wszDir != dirBuffer)
@@ -1669,7 +1665,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
                                       execfunc );
         if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
             do_error_dialog(retval, sei_tmp.hwnd);
-        HeapFree(GetProcessHeap(), 0, wszApplicationName);
         if (wszParameters != parametersBuffer)
             HeapFree(GetProcessHeap(), 0, wszParameters);
         if (wszDir != dirBuffer)
@@ -1683,7 +1678,7 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
         appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
                                                    parametersLen,
                                                    wszApplicationName,
-                                                   dwApplicationNameLen );
+                                                   MAX_PATH );
     }
 
     /* expand environment strings */
@@ -1694,9 +1689,7 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
         buf = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
 
         ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len+1);
-        HeapFree(GetProcessHeap(), 0, wszApplicationName);
-        dwApplicationNameLen = len+1;
-        wszApplicationName = buf;
+        strcpyW(wszApplicationName, buf);
         /* appKnownSingular unmodified */
 
         sei_tmp.lpFile = wszApplicationName;
@@ -1819,7 +1812,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 
     retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
     if (retval > 32) {
-        HeapFree(GetProcessHeap(), 0, wszApplicationName);
         if (wszParameters != parametersBuffer)
             HeapFree(GetProcessHeap(), 0, wszParameters);
         if (wszDir != dirBuffer)
@@ -1883,7 +1875,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 
     TRACE("retval %lu\n", retval);
 
-    HeapFree(GetProcessHeap(), 0, wszApplicationName);
     if (wszParameters != parametersBuffer)
         HeapFree(GetProcessHeap(), 0, wszParameters);
     if (wszDir != dirBuffer)
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 31b0930..ea9cbc5 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -2204,6 +2204,7 @@ static void test_commandline(void)
 static void test_directory(void)
 {
     char path[MAX_PATH], newdir[MAX_PATH];
+    char libext[] = ".so", *extpos;
     char params[1024];
     int rc;
 
@@ -2226,7 +2227,9 @@ static void test_directory(void)
     ok(rc > 32, "%s returned %d\n", shell_call, rc);
     okChildInt("argcA", 4);
     okChildString("argvA3", "Exec");
-    todo_wine okChildPath("longPath", path);
+    /* strip the .so extension for comparison */
+    if ((extpos = strstr(path, libext))) *extpos = 0;
+    okChildPath("longPath", path);
 
     DeleteFile(path);
     RemoveDirectoryA(newdir);
-- 

Best Regards, André Hentschel



More information about the wine-patches mailing list