shell32 patch 23 d
Martin Fuchs
martin-fuchs at gmx.net
Thu Mar 4 16:15:40 CST 2004
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 4 Mar 2004 22:06:12 -0000
@@ -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