[SHELL32] Fix handling of multiple parameters in the 'Run' dialog (#665)

The "Run" dialog failed when multiple parameters wee specified.
We use instead a newly-created ShellExecCmdLine() helper function to fix the problem (as found via API-tracing on Windows).
Note that ShellExecCmdLine() starts to be exported with Vista+.

- Implement ShellExecCmdLine() function in shell32.
- Add URL support.
- Fix RunDlgProc function in shell32.
- Add a testcase for ShellExecCmdLine() function.

CORE-14790
This commit is contained in:
Katayama Hirofumi MZ 2018-08-05 20:39:17 +09:00 committed by Hermès BÉLUSCA - MAÏTO
parent ff63ef3c55
commit bfcbda227f
6 changed files with 790 additions and 15 deletions

View file

@ -527,7 +527,6 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
HWND htxt = GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH);
INT ic;
WCHAR *psz, *parent = NULL;
SHELLEXECUTEINFOW sei;
NMRUNFILEDLGW nmrfd;
ic = GetWindowTextLengthW(htxt);
@ -537,9 +536,6 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
return TRUE;
}
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei);
/*
* Allocate a new MRU entry, we need to add two characters
* for the terminating "\\1" part, then the NULL character.
@ -552,10 +548,7 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
}
GetWindowTextW(htxt, psz, ic + 1);
sei.hwnd = hwnd;
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = psz;
StrTrimW(psz, L" \t");
/*
* The precedence is the following: first the user-given
@ -563,12 +556,13 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
* directory is computed if the RFF_CALCDIRECTORY is set,
* otherwise no current directory is defined.
*/
LPCWSTR pszStartDir;
if (prfdp->lpstrDirectory)
sei.lpDirectory = prfdp->lpstrDirectory;
pszStartDir = prfdp->lpstrDirectory;
else if (prfdp->uFlags & RFF_CALCDIRECTORY)
sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile);
pszStartDir = parent = RunDlg_GetParentDir(psz);
else
sei.lpDirectory = NULL;
pszStartDir = NULL;
/* Hide the dialog for now on, we will show it up in case of retry */
ShowWindow(hwnd, SW_HIDE);
@ -585,9 +579,9 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
nmrfd.hdr.code = RFN_VALIDATE;
nmrfd.hdr.hwndFrom = hwnd;
nmrfd.hdr.idFrom = 0;
nmrfd.lpFile = sei.lpFile;
nmrfd.lpDirectory = sei.lpDirectory;
nmrfd.nShow = sei.nShow;
nmrfd.lpFile = psz;
nmrfd.lpDirectory = pszStartDir;
nmrfd.nShow = SW_SHOWNORMAL;
lRet = SendMessageW(prfdp->hwndOwner, WM_NOTIFY, 0, (LPARAM)&nmrfd.hdr);
@ -598,7 +592,8 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
break;
case RF_OK:
if (ShellExecuteExW(&sei))
if (SUCCEEDED(ShellExecCmdLine(hwnd, psz, pszStartDir, SW_SHOWNORMAL, NULL,
SECL_ALLOW_NONEXE)))
{
/* Call again GetWindowText in case the contents of the edit box has changed? */
GetWindowTextW(htxt, psz, ic + 1);