https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1b3eed58cac4cd7f8ebfee...
commit 1b3eed58cac4cd7f8ebfeecbe1f244076c83a8b8 Author: Doug Lyons douglyons@douglyons.com AuthorDate: Sun Sep 24 15:35:28 2023 -0500 Commit: GitHub noreply@github.com CommitDate: Sun Sep 24 20:35:28 2023 +0000
[SHELL32] Fix for shlexec.cpp regressions (#5282)
fixes CORE-18967 'Taskbar toolbar - Right click > Open folder fails' by restoring the code-path we removed with the guilty 0.4.15-dev-3847-g /9b716539182864bc077e362febcda74da50287ed
and add test_sei_lpIDList to shell32:ShellExecuteEx apitest test to protect that functionality on future attempts to simplify. --- dll/win32/shell32/shlexec.cpp | 33 ++++++++++++++++ .../rostests/apitests/shell32/ShellExecuteEx.cpp | 45 ++++++++++++++++++++++ 2 files changed, 78 insertions(+)
diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 292c8db8292..ce8113aefa9 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -2124,6 +2124,39 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) *end = L'\0'; lpFile = wfileName; } + /* We have to test sei instead of sei_tmp because sei_tmp had its + * input fMask modified above in SHELL_translate_idlist. + * This code is needed to handle the case where we only have an + * lpIDList with multiple CLSID/PIDL's (not 'My Computer' only) */ + else if ((sei->fMask & SEE_MASK_IDLIST) == SEE_MASK_IDLIST) + { + WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH]; + LPWSTR space, s; + + LPWSTR beg = wszApplicationName; + for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1) + { + int idx = space - sei_tmp.lpFile; + memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR)); + buffer[idx] = '\0'; + + if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL, + buffer, L".exe", _countof(xlpFile), xlpFile, NULL)) + { + /* separate out command from parameter string */ + LPCWSTR p = space + 1; + + while(isspaceW(*p)) + ++p; + + strcpyW(wszParameters, p); + *space = L'\0'; + + break; + } + } + lpFile = sei_tmp.lpFile; + } else { lpFile = sei_tmp.lpFile; diff --git a/modules/rostests/apitests/shell32/ShellExecuteEx.cpp b/modules/rostests/apitests/shell32/ShellExecuteEx.cpp index d239467d859..29f03be94b8 100644 --- a/modules/rostests/apitests/shell32/ShellExecuteEx.cpp +++ b/modules/rostests/apitests/shell32/ShellExecuteEx.cpp @@ -467,6 +467,48 @@ static void test_properties() ok_ptr(info.hInstApp, (HINSTANCE)2); }
+static void test_sei_lpIDList() +{ + /* This tests ShellExecuteEx with lpIDList for explorer C:\ */ + + /* ITEMIDLIST for CLSID of 'My Computer' followed by PIDL for 'C:' */ + BYTE lpitemidlist[30] = { 0x14, 0, 0x1f, 0, 0xe0, 0x4f, 0xd0, 0x20, 0xea, + 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0, 0x2b, 0x30, 0x30, 0x9d, // My Computer + 0x8, 0, 0x23, 0x43, 0x3a, 0x5c, 0x5c, 0, 0, 0,}; // C:\ + NUL-NUL ending + BYTE *lpBytes; + lpBytes = lpitemidlist; + + SHELLEXECUTEINFOW ShellExecInfo; + BOOL Result; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + HWND hWnd; + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + ZeroMemory(&ShellExecInfo, sizeof(ShellExecInfo)); + ShellExecInfo.cbSize = sizeof(ShellExecInfo); + ShellExecInfo.fMask = SEE_MASK_IDLIST; + ShellExecInfo.hwnd = NULL; + ShellExecInfo.nShow = SW_SHOWNORMAL; + ShellExecInfo.lpFile = NULL; + ShellExecInfo.lpDirectory = NULL; + ShellExecInfo.lpIDList = lpBytes; + + Result = ShellExecuteExW(&ShellExecInfo); + ok(Result == TRUE, "ShellExecuteEx lpIDList 'C:\' failed\n"); + trace("sei_lpIDList returned: %s\n", Result ? "SUCCESS" : "FAILURE"); + if (Result) + { + Sleep(700); + // Terminate Window + hWnd = FindWindowW(L"CabinetWClass", L"Local Disk (C:)"); + PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); + } +} + START_TEST(ShellExecuteEx) { DoAppPathTest(); @@ -475,4 +517,7 @@ START_TEST(ShellExecuteEx)
DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, TRUE); Sleep(100); + + test_sei_lpIDList(); + }