Expand environment strings in command, parameter and directory strings

of ShellExecuteExW32().
This commit is contained in:
Martin Fuchs 2004-03-18 04:04:29 +00:00 committed by Alexandre Julliard
parent b040e4bcd2
commit a06f76d6f9
3 changed files with 89 additions and 50 deletions

View File

@ -611,13 +611,14 @@ DWORD WINAPI RegEnumKey16( HKEY hkey, DWORD index, LPSTR name, DWORD name_len )
/************************************************************************* /*************************************************************************
* SHELL_Execute16 [Internal] * SHELL_Execute16 [Internal]
*/ */
static UINT SHELL_Execute16(WCHAR *lpCmd, void* env, LPSHELLEXECUTEINFOW seiW, BOOL shWait) static UINT SHELL_Execute16(const WCHAR *lpCmd, void *env, BOOL shWait,
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{ {
UINT ret; UINT ret;
char sCmd[MAX_PATH]; char sCmd[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, lpCmd, -1, sCmd, MAX_PATH, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, lpCmd, -1, sCmd, MAX_PATH, NULL, NULL);
ret = WinExec16(sCmd, seiW->nShow); ret = WinExec16(sCmd, (UINT16)psei->nShow);
seiW->hInstApp = HINSTANCE_32(ret); psei_out->hInstApp = HINSTANCE_32(ret);
return ret; return ret;
} }

View File

@ -228,8 +228,10 @@ inline static WCHAR * __SHCloneStrAtoW(WCHAR ** target, const char * source)
#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16)) #define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
#define HINSTANCE_16(h32) (LOWORD(h32)) #define HINSTANCE_16(h32) (LOWORD(h32))
typedef UINT (*SHELL_ExecuteW32)(WCHAR *lpCmd, void *env, LPSHELLEXECUTEINFOW sei, BOOL shWait); typedef UINT (*SHELL_ExecuteW32)(const WCHAR *lpCmd, void *env, BOOL shWait,
BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc); LPSHELLEXECUTEINFOW sei, LPSHELLEXECUTEINFOW sei_out);
BOOL WINAPI ShellExecuteExW32(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc);
extern WCHAR swShell32Name[MAX_PATH]; extern WCHAR swShell32Name[MAX_PATH];
extern char sShell32Name[MAX_PATH]; extern char sShell32Name[MAX_PATH];

View File

@ -129,19 +129,20 @@ static BOOL SHELL_ArgifyW(WCHAR* res, int len, const WCHAR* fmt, const WCHAR* lp
* SHELL_ExecuteW [Internal] * SHELL_ExecuteW [Internal]
* *
*/ */
static UINT SHELL_ExecuteW(WCHAR *lpCmd, void *env, LPSHELLEXECUTEINFOW sei, BOOL shWait) static UINT SHELL_ExecuteW(const WCHAR *lpCmd, void *env, BOOL shWait,
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{ {
STARTUPINFOW startup; STARTUPINFOW startup;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
UINT retval = 31; UINT retval = 31;
TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(sei->lpDirectory)); TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
ZeroMemory(&startup,sizeof(STARTUPINFOW)); ZeroMemory(&startup,sizeof(STARTUPINFOW));
startup.cb = sizeof(STARTUPINFOW); startup.cb = sizeof(STARTUPINFOW);
startup.dwFlags = STARTF_USESHOWWINDOW; startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = sei->nShow; startup.wShowWindow = psei->nShow;
if (CreateProcessW(NULL, lpCmd, NULL, NULL, FALSE, 0, if (CreateProcessW(NULL, (LPWSTR)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 /* Give 30 seconds to the app to come up, if desired. Probably only needed
when starting app immediately before making a DDE connection. */ when starting app immediately before making a DDE connection. */
@ -149,8 +150,8 @@ static UINT SHELL_ExecuteW(WCHAR *lpCmd, void *env, LPSHELLEXECUTEINFOW sei, BOO
if (WaitForInputIdle( info.hProcess, 30000 ) == -1) if (WaitForInputIdle( info.hProcess, 30000 ) == -1)
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() ); WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
retval = 33; retval = 33;
if(sei->fMask & SEE_MASK_NOCLOSEPROCESS) if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
sei->hProcess = info.hProcess; psei_out->hProcess = info.hProcess;
else else
CloseHandle( info.hProcess ); CloseHandle( info.hProcess );
CloseHandle( info.hThread ); CloseHandle( info.hThread );
@ -163,7 +164,7 @@ static UINT SHELL_ExecuteW(WCHAR *lpCmd, void *env, LPSHELLEXECUTEINFOW sei, BOO
TRACE("returning %u\n", retval); TRACE("returning %u\n", retval);
sei->hInstApp = (HINSTANCE)retval; psei_out->hInstApp = (HINSTANCE)retval;
return retval; return retval;
} }
@ -535,7 +536,8 @@ static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
*/ */
static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec, static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
const WCHAR* lpFile, void *env, const WCHAR* lpFile, void *env,
LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) SHELL_ExecuteW32 execfunc,
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{ {
static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0}; static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0};
static const WCHAR wTopic[] = {'\\','t','o','p','i','c',0}; static const WCHAR wTopic[] = {'\\','t','o','p','i','c',0};
@ -579,7 +581,7 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
{ {
static const WCHAR wIfexec[] = {'\\','i','f','e','x','e','c',0}; static const WCHAR wIfexec[] = {'\\','i','f','e','x','e','c',0};
TRACE("Launching '%s'\n", debugstr_w(start)); TRACE("Launching '%s'\n", debugstr_w(start));
ret = execfunc(start, env, sei, TRUE); ret = execfunc(start, env, TRUE, psei, psei_out);
if (ret < 32) if (ret < 32)
{ {
TRACE("Couldn't launch\n"); TRACE("Couldn't launch\n");
@ -616,7 +618,8 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
* execute_from_key [Internal] * execute_from_key [Internal]
*/ */
static UINT execute_from_key(LPWSTR key, LPCWSTR lpFile, void *env, static UINT execute_from_key(LPWSTR key, LPCWSTR lpFile, void *env,
LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) SHELL_ExecuteW32 execfunc,
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{ {
WCHAR cmd[1024] = {0}; WCHAR cmd[1024] = {0};
LONG cmdlen = sizeof(cmd); LONG cmdlen = sizeof(cmd);
@ -640,7 +643,7 @@ static UINT execute_from_key(LPWSTR key, LPCWSTR lpFile, void *env,
if (RegQueryValueW(HKEY_CLASSES_ROOT, key, param, &paramlen) == ERROR_SUCCESS) if (RegQueryValueW(HKEY_CLASSES_ROOT, key, param, &paramlen) == ERROR_SUCCESS)
{ {
TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(param)); TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(param));
retval = dde_connect(key, cmd, param, lpFile, env, sei, execfunc); retval = dde_connect(key, cmd, param, lpFile, env, execfunc, psei, psei_out);
} }
else else
{ {
@ -648,7 +651,7 @@ static UINT execute_from_key(LPWSTR key, LPCWSTR lpFile, void *env,
cmdlen /= sizeof(WCHAR); cmdlen /= sizeof(WCHAR);
cmd[cmdlen] = '\0'; cmd[cmdlen] = '\0';
SHELL_ArgifyW(param, sizeof(param)/sizeof(WCHAR), cmd, lpFile); SHELL_ArgifyW(param, sizeof(param)/sizeof(WCHAR), cmd, lpFile);
retval = execfunc(param, env, sei, FALSE); retval = execfunc(param, env, FALSE, psei, psei_out);
} }
} }
else TRACE("ooch\n"); else TRACE("ooch\n");
@ -721,7 +724,10 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
static const WCHAR wWww[] = {'w','w','w',0}; static const WCHAR wWww[] = {'w','w','w',0};
static const WCHAR wFile[] = {'f','i','l','e',0}; static const WCHAR wFile[] = {'f','i','l','e',0};
static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',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; LPWSTR pos;
void *env; void *env;
int gap, len; int gap, len;
@ -729,49 +735,67 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
LPCWSTR lpFile; LPCWSTR lpFile;
UINT retval = 31; UINT retval = 31;
WCHAR wcmd[1024]; WCHAR wcmd[1024];
WCHAR buffer[MAX_PATH];
BOOL done; 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", 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), sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
debugstr_w(sei->lpFile), debugstr_w(sei->lpParameters), debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
debugstr_w(sei->lpDirectory), sei->nShow, debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
(sei->fMask & SEE_MASK_CLASSNAME) ? debugstr_w(sei->lpClass) : "not used"); (sei_tmp.fMask & SEE_MASK_CLASSNAME) ? debugstr_w(sei_tmp.lpClass) : "not used");
sei->hProcess = NULL; sei->hProcess = NULL;
ZeroMemory(wszApplicationName,MAX_PATH);
if (sei->lpFile)
strcpyW(wszApplicationName, sei->lpFile);
ZeroMemory(wszCommandline,1024); /* make copies of all path/command strings */
if (sei->lpParameters) if (sei_tmp.lpFile)
strcpyW(wszCommandline, sei->lpParameters); 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(wszCommandline, sei_tmp.lpParameters);
else
*wszCommandline = '\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 = wszCommandline;
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_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE | SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE |
SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR )) 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 */ /* 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] = '"'; wszApplicationName[0] = '"';
SHGetPathFromIDListW(sei->lpIDList,wszApplicationName + 1); SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName+1);
strcatW(wszApplicationName, wQuote); 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 else
{ {
if (sei->fMask & SEE_MASK_IDLIST ) if (sei_tmp.fMask & SEE_MASK_IDLIST)
{ {
static const WCHAR wI[] = {'%','I',0}, wP[] = {':','%','p',0}; static const WCHAR wI[] = {'%','I',0}, wP[] = {':','%','p',0};
pos = strstrW(wszCommandline, wI); pos = strstrW(wszCommandline, wI);
if (pos) if (pos)
{ {
LPVOID pv; 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); pv = SHLockShared(hmem,0);
sprintfW(wszPidl,wP,pv ); sprintfW(wszPidl,wP,pv );
SHUnlockShared(pv); SHUnlockShared(pv);
@ -784,14 +808,14 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
} }
} }
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' */ /* launch a document by fileclass like 'WordPad.Document.1' */
/* the Commandline contains 'c:\Path\wordpad.exe "%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! */ /* 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, HCR_GetExecuteCommandW((sei_tmp.fMask & SEE_MASK_CLASSKEY) ? sei_tmp.hkeyClass : NULL,
(sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass: NULL, (sei_tmp.fMask & SEE_MASK_CLASSNAME) ? sei_tmp.lpClass: NULL,
(sei->lpVerb) ? sei->lpVerb : wszOpen, (sei_tmp.lpVerb) ? sei_tmp.lpVerb : wszOpen,
wszCommandline, sizeof(wszCommandline)/sizeof(WCHAR)); wszCommandline, sizeof(wszCommandline)/sizeof(WCHAR));
/* FIXME: get the extension of lpFile, check if it fits to the lpClass */ /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
@ -804,15 +828,27 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strcatW(wcmd, wSpace); strcatW(wcmd, wSpace);
strcatW(wcmd, wszApplicationName); strcatW(wcmd, wszApplicationName);
} }
retval = execfunc(wcmd, NULL, sei, FALSE); retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
if (retval > 32) if (retval > 32)
return TRUE; return TRUE;
else else
return FALSE; 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 */ /* 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); strcpyW(wfileName, wszApplicationName);
lpFile = wfileName; lpFile = wfileName;
@ -821,13 +857,13 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strcatW(wszApplicationName, wszCommandline); strcatW(wszApplicationName, wszCommandline);
} }
retval = execfunc(wszApplicationName, NULL, sei, FALSE); retval = execfunc(wszApplicationName, NULL, FALSE, &sei_tmp, sei);
if (retval > 32) if (retval > 32)
return TRUE; return TRUE;
/* Else, try to find the executable */ /* Else, try to find the executable */
wcmd[0] = '\0'; 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 */ if (retval > 32) /* Found */
{ {
WCHAR wszQuotedCmd[MAX_PATH+2]; WCHAR wszQuotedCmd[MAX_PATH+2];
@ -841,11 +877,11 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strcatW(wszQuotedCmd, wSpace); strcatW(wszQuotedCmd, wSpace);
strcatW(wszQuotedCmd, wszCommandline); 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) if (*lpstrProtocol)
retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei, execfunc); retval = execute_from_key(lpstrProtocol, wszApplicationName, env, execfunc, &sei_tmp, sei);
else else
retval = execfunc(wszQuotedCmd, env, sei, FALSE); retval = execfunc(wszQuotedCmd, env, FALSE, &sei_tmp, sei);
if (env) HeapFree( GetProcessHeap(), 0, env ); if (env) HeapFree( GetProcessHeap(), 0, env );
} }
else if (PathIsURLW((LPWSTR)lpFile)) /* File not found, check for URL */ else if (PathIsURLW((LPWSTR)lpFile)) /* File not found, check for URL */
@ -866,7 +902,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
strncpyW(lpstrProtocol, lpFile, iSize); strncpyW(lpstrProtocol, lpFile, iSize);
lpstrProtocol[iSize] = '\0'; lpstrProtocol[iSize] = '\0';
strcatW(lpstrProtocol, wShell); strcatW(lpstrProtocol, wShell);
strcatW(lpstrProtocol, sei->lpVerb? sei->lpVerb: wszOpen); strcatW(lpstrProtocol, sei_tmp.lpVerb? sei_tmp.lpVerb: wszOpen);
strcatW(lpstrProtocol, wCommand); strcatW(lpstrProtocol, wCommand);
/* Remove File Protocol from lpFile */ /* Remove File Protocol from lpFile */
@ -876,7 +912,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
lpFile += iSize; lpFile += iSize;
while (*lpFile == ':') lpFile++; while (*lpFile == ':') lpFile++;
} }
retval = execute_from_key(lpstrProtocol, lpFile, NULL, sei, execfunc); retval = execute_from_key(lpstrProtocol, lpFile, NULL, execfunc, &sei_tmp, sei);
} }
/* Check if file specified is in the form www.??????.*** */ /* Check if file specified is in the form www.??????.*** */
else if (!strncmpiW(lpFile, wWww, 3)) else if (!strncmpiW(lpFile, wWww, 3))
@ -885,7 +921,7 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
WCHAR lpstrTmpFile[256]; WCHAR lpstrTmpFile[256];
strcpyW(lpstrTmpFile, wHttp); strcpyW(lpstrTmpFile, wHttp);
strcatW(lpstrTmpFile, lpFile); 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); TRACE("retval %u\n", retval);