shell32 patch 23 d [correction]

Martin Fuchs martin-fuchs at gmx.net
Tue Mar 9 15:38:01 CST 2004


Hi,

I forgot to include a piece (*psei->lpDirectory? psei->lpDirectory: NULL) while splitting the shlexec.c patch - so here is it again.


Changelog:
- expand environment strings in command, parameter and directory strings of
 ShellExecuteExW32()


Index: shlexec.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlexec.c,v
retrieving revision 1.33
diff -u -p -d -r1.33 shlexec.c
--- shlexec.c	4 Mar 2004 20:34:38 -0000	1.33
+++ shlexec.c	9 Mar 2004 21:37:06 -0000
@@ -141,7 +141,7 @@ static UINT SHELL_ExecuteW(WCHAR *lpCmd,
     startup.dwFlags = STARTF_USESHOWWINDOW;
     startup.wShowWindow = sei->nShow;
     if (CreateProcessW(NULL, lpCmd, NULL, NULL, FALSE, 0,
-                       env, sei->lpDirectory, &startup, &info))
+                       env, *psei->lpDirectory? psei->lpDirectory: NULL, &startup, &info))
     {
         /* Give 30 seconds to the app to come up, if desired. Probably only needed
            when starting app immediately before making a DDE connection. */
@@ -343,6 +343,7 @@ static UINT SHELL_FindExecutable(LPCWSTR
     WCHAR command[256];      /* command from registry */
     WCHAR wBuffer[256];      /* Used to GetProfileString */
     UINT  retval = 31;       /* default - 'No association was found' */
+    WCHAR buffer[MAX_PATH];
     WCHAR *tok;              /* token pointer */
     WCHAR xlpFile[256] = {0}; /* result of SearchPath */
 
@@ -721,7 +722,10 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
     static const WCHAR wWww[] = {'w','w','w',0};
     static const WCHAR wFile[] = {'f','i','l','e',0};
     static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',0};
-    WCHAR wszApplicationName[MAX_PATH+2],wszCommandline[1024],wszPidl[20],wfileName[MAX_PATH];
+
+    WCHAR wszApplicationName[MAX_PATH+2], wszCommandline[1024], wszDir[MAX_PATH];
+    SHELLEXECUTEINFOW sei_tmp;	/* modifyable copy of SHELLEXECUTEINFO struct */
+    WCHAR wszPidl[20], wfileName[MAX_PATH];
     LPWSTR pos;
     void *env;
     int gap, len;
@@ -731,47 +735,64 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
     WCHAR wcmd[1024];
     BOOL done;
 
+    /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
+    memcpy(&sei_tmp, sei, sizeof(sei_tmp));
+
     TRACE("mask=0x%08lx hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
-            sei->fMask, sei->hwnd, debugstr_w(sei->lpVerb),
-            debugstr_w(sei->lpFile), debugstr_w(sei->lpParameters),
-            debugstr_w(sei->lpDirectory), sei->nShow,
-            (sei->fMask & SEE_MASK_CLASSNAME) ? debugstr_w(sei->lpClass) : "not used");
+            sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
+            debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
+            debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
+            (sei_tmp.fMask & SEE_MASK_CLASSNAME) ? debugstr_w(sei_tmp.lpClass) : "not used");
 
     sei->hProcess = NULL;
-    ZeroMemory(wszApplicationName,MAX_PATH);
-    if (sei->lpFile)
-        strcpyW(wszApplicationName, sei->lpFile);
 
-    ZeroMemory(wszCommandline,1024);
-    if (sei->lpParameters)
-        strcpyW(wszCommandline, sei->lpParameters);
+    /* make copies of all path/command strings */
+    if (sei_tmp.lpFile)
+	strcpyW(wszApplicationName, sei_tmp.lpFile);
+    else
+	*wszApplicationName = '\0';
 
-    if (sei->fMask & (SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
+    if (sei_tmp.lpParameters)
+	strcpyW(wszParameters, sei_tmp.lpParameters);
+    else
+	*wszParameters = '\0';
+
+    if (sei_tmp.lpDirectory)
+	strcpyW(wszDir, sei_tmp.lpDirectory);
+    else
+	*wszDir = '\0';
+
+    /* adjust string pointers to point to the new buffers */
+    sei_tmp.lpFile = wszApplicationName;
+    sei_tmp.lpParameters = wszParameters;
+    sei_tmp.lpDirectory = wszDir;
+
+    if (sei_tmp.fMask & (SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
         SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
         SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE |
         SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
     {
-        FIXME("flags ignored: 0x%08lx\n", sei->fMask);
+        FIXME("flags ignored: 0x%08lx\n", sei_tmp.fMask);
     }
 
     /* process the IDList */
-    if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
+    if ((sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
     {
         wszApplicationName[0] = '"';
-        SHGetPathFromIDListW(sei->lpIDList,wszApplicationName + 1);
+        SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName+1);
         strcatW(wszApplicationName, wQuote);
-        TRACE("-- idlist=%p (%s)\n", sei->lpIDList, debugstr_w(wszApplicationName));
+        TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
     }
     else
     {
-        if (sei->fMask & SEE_MASK_IDLIST )
+        if (sei_tmp.fMask & SEE_MASK_IDLIST)
         {
 	    static const WCHAR wI[] = {'%','I',0}, wP[] = {':','%','p',0};
             pos = strstrW(wszCommandline, wI);
             if (pos)
             {
                 LPVOID pv;
-                HGLOBAL hmem = SHAllocShared ( sei->lpIDList, ILGetSize(sei->lpIDList), 0);
+                HGLOBAL hmem = SHAllocShared(sei_tmp.lpIDList, ILGetSize(sei_tmp.lpIDList), 0);
                 pv = SHLockShared(hmem,0);
                 sprintfW(wszPidl,wP,pv );
                 SHUnlockShared(pv);
@@ -784,14 +805,14 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
         }
     }
 
-    if (sei->fMask & (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY))
+    if (sei_tmp.fMask & (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY))
     {
 	/* launch a document by fileclass like 'WordPad.Document.1' */
         /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
         /* FIXME: szCommandline should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
-        HCR_GetExecuteCommandW((sei->fMask & SEE_MASK_CLASSKEY) ? sei->hkeyClass : NULL,
-                               (sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass: NULL,
-                               (sei->lpVerb) ? sei->lpVerb : wszOpen,
+        HCR_GetExecuteCommandW((sei_tmp.fMask & SEE_MASK_CLASSKEY) ? sei_tmp.hkeyClass : NULL,
+                               (sei_tmp.fMask & SEE_MASK_CLASSNAME) ? sei_tmp.lpClass: NULL,
+                               (sei_tmp.lpVerb) ? sei_tmp.lpVerb : wszOpen,
                                wszCommandline, sizeof(wszCommandline)/sizeof(WCHAR));
 
         /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
@@ -811,8 +832,20 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
             return FALSE;
     }
 
+    /* expand environment strings */
+    if (ExpandEnvironmentStringsW(sei_tmp.lpFile, buffer, MAX_PATH))
+	lstrcpyW(wszApplicationName, buffer);
+
+    if (*sei_tmp.lpParameters)
+        if (ExpandEnvironmentStringsW(sei_tmp.lpParameters, buffer, MAX_PATH))
+	    lstrcpyW(wszCommandline, buffer);
+
+    if (*sei_tmp.lpDirectory)
+	if (ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buffer, MAX_PATH))
+	    lstrcpyW(wszDir, buffer);
+
     /* Else, try to execute the filename */
-    TRACE("execute:'%s','%s'\n", debugstr_w(wszApplicationName), debugstr_w(wszCommandline));
+    TRACE("execute:'%s','%s','%s'\n", debugstr_w(wszApplicationName), debugstr_w(wszCommandline), debugstr_w(wszDir));
 
     strcpyW(wfileName, wszApplicationName);
     lpFile = wfileName;
@@ -827,7 +860,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
 
     /* Else, try to find the executable */
     wcmd[0] = '\0';
-    retval = SHELL_FindExecutable(sei->lpDirectory, lpFile, sei->lpVerb, wcmd, lpstrProtocol, &env);
+    retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, lpstrProtocol, &env);
     if (retval > 32)  /* Found */
     {
         WCHAR wszQuotedCmd[MAX_PATH+2];
@@ -841,7 +874,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
             strcatW(wszQuotedCmd, wSpace);
             strcatW(wszQuotedCmd, wszCommandline);
         }
-        TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(sei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
+        TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(sei_tmp.lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
         if (*lpstrProtocol)
             retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei, execfunc);
         else
@@ -866,7 +899,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
         strncpyW(lpstrProtocol, lpFile, iSize);
         lpstrProtocol[iSize] = '\0';
         strcatW(lpstrProtocol, wShell);
-        strcatW(lpstrProtocol, sei->lpVerb? sei->lpVerb: wszOpen);
+        strcatW(lpstrProtocol, sei_tmp.lpVerb? sei_tmp.lpVerb: wszOpen);
         strcatW(lpstrProtocol, wCommand);
 
         /* Remove File Protocol from lpFile */
@@ -885,7 +918,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEX
         WCHAR lpstrTmpFile[256];
         strcpyW(lpstrTmpFile, wHttp);
         strcatW(lpstrTmpFile, lpFile);
-        retval = (UINT)ShellExecuteW(sei->hwnd, sei->lpVerb, lpstrTmpFile, NULL, NULL, 0);
+        retval = (UINT)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
     }
 
     TRACE("retval %u\n", retval);





More information about the wine-patches mailing list