[SHELL32] lpDirectory must have priority in ShellExecuteEx (#681)

Based on a patch by Mark Jansen.
CORE-14469
This commit is contained in:
Katayama Hirofumi MZ 2018-07-13 00:45:43 +09:00 committed by Hermès BÉLUSCA - MAÏTO
parent 5a637150f0
commit e018ccea4b

View file

@ -179,7 +179,7 @@ static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used,
* - use rules from here http://www.autohotkey.net/~deleyd/parameters/parameters.htm * - use rules from here http://www.autohotkey.net/~deleyd/parameters/parameters.htm
*/ */
static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len) static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len, const WCHAR* lpDir)
{ {
WCHAR xlpFile[1024]; WCHAR xlpFile[1024];
BOOL done = FALSE; BOOL done = FALSE;
@ -266,7 +266,7 @@ static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR*
if (!done || (*fmt == '1')) if (!done || (*fmt == '1'))
{ {
/*FIXME Is the call to SearchPathW() really needed? We already have separated out the parameter string in args. */ /*FIXME Is the call to SearchPathW() really needed? We already have separated out the parameter string in args. */
if (SearchPathW(NULL, lpFile, wszExe, sizeof(xlpFile) / sizeof(WCHAR), xlpFile, NULL)) if (SearchPathW(lpDir, lpFile, wszExe, sizeof(xlpFile) / sizeof(WCHAR), xlpFile, NULL))
cmd = xlpFile; cmd = xlpFile;
else else
cmd = lpFile; cmd = lpFile;
@ -829,7 +829,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
if (retval > 32) if (retval > 32)
{ {
DWORD finishedLen; DWORD finishedLen;
SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen); SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen, lpPath);
if (finishedLen > resultLen) if (finishedLen > resultLen)
ERR("Argify buffer not large enough.. truncated\n"); ERR("Argify buffer not large enough.. truncated\n");
/* Remove double quotation marks and command line arguments */ /* Remove double quotation marks and command line arguments */
@ -1062,11 +1062,11 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
} }
} }
SHELL_ArgifyW(static_res, sizeof(static_res)/sizeof(WCHAR), exec, lpFile, pidl, szCommandline, &resultLen); SHELL_ArgifyW(static_res, sizeof(static_res)/sizeof(WCHAR), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
if (resultLen > sizeof(static_res)/sizeof(WCHAR)) if (resultLen > sizeof(static_res)/sizeof(WCHAR))
{ {
res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR))); res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR)));
SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL); SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
} }
else else
res = static_res; res = static_res;
@ -1132,7 +1132,8 @@ static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env,
if (cmdlen >= sizeof(cmd) / sizeof(WCHAR)) if (cmdlen >= sizeof(cmd) / sizeof(WCHAR))
cmdlen = sizeof(cmd) / sizeof(WCHAR) - 1; cmdlen = sizeof(cmd) / sizeof(WCHAR) - 1;
cmd[cmdlen] = '\0'; cmd[cmdlen] = '\0';
SHELL_ArgifyW(param, sizeof(param) / sizeof(WCHAR), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen); SHELL_ArgifyW(param, sizeof(param) / sizeof(WCHAR), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
(psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
if (resultLen > sizeof(param) / sizeof(WCHAR)) if (resultLen > sizeof(param) / sizeof(WCHAR))
ERR("Argify buffer not large enough, truncating\n"); ERR("Argify buffer not large enough, truncating\n");
} }
@ -1512,7 +1513,8 @@ static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEIN
TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName)); TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
wcmd[0] = '\0'; wcmd[0] = '\0';
done = SHELL_ArgifyW(wcmd, sizeof(wcmd) / sizeof(WCHAR), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen); done = SHELL_ArgifyW(wcmd, sizeof(wcmd) / sizeof(WCHAR), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen,
(psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
if (!done && wszApplicationName[0]) if (!done && wszApplicationName[0])
{ {
strcatW(wcmd, L" "); strcatW(wcmd, L" ");
@ -1578,7 +1580,8 @@ static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters
sei->lpVerb, sei->lpVerb,
buffer, sizeof(buffer))) { buffer, sizeof(buffer))) {
SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen, SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen); buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
(sei->lpDirectory && *sei->lpDirectory) ? sei->lpDirectory : NULL);
if (resultLen > dwApplicationNameLen) if (resultLen > dwApplicationNameLen)
ERR("Argify buffer not large enough... truncating\n"); ERR("Argify buffer not large enough... truncating\n");
appKnownSingular = FALSE; appKnownSingular = FALSE;