[SHELL32][SHELL32_APITEST][SDK] Implement ShellExec_RunDLL (#7615)

Implementing missing features...
JIRA issue: CORE-19278
- Modify shell32.spec.
- Move function definitions
  from stubs.cpp into shlexec.cpp.
- Add prototypes to <undocshell.h>.
This commit is contained in:
Katayama Hirofumi MZ 2025-01-17 22:51:18 +09:00 committed by GitHub
parent a25e7ee9d7
commit dad3a0938a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 171 additions and 31 deletions

View file

@ -354,7 +354,7 @@
354 stdcall SheShortenPathW(wstr long) 354 stdcall SheShortenPathW(wstr long)
355 stdcall ShellAboutA(long str str long) 355 stdcall ShellAboutA(long str str long)
356 stdcall ShellAboutW(long wstr wstr long) 356 stdcall ShellAboutW(long wstr wstr long)
357 stdcall ShellExec_RunDLL(ptr ptr wstr long) 357 stdcall ShellExec_RunDLL(ptr ptr str long) ShellExec_RunDLLA
358 stdcall ShellExec_RunDLLA(ptr ptr str long) 358 stdcall ShellExec_RunDLLA(ptr ptr str long)
359 stdcall ShellExec_RunDLLW(ptr ptr wstr long) 359 stdcall ShellExec_RunDLLW(ptr ptr wstr long)
360 stdcall ShellExecuteA(long str str str str long) 360 stdcall ShellExecuteA(long str str str str long)

View file

@ -2986,3 +2986,88 @@ RealShellExecuteW(
lphProcess, lphProcess,
0); 0);
} }
// The common helper of ShellExec_RunDLLA and ShellExec_RunDLLW
static VOID
ShellExec_RunDLL_Helper(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCWSTR pszCmdLine,
_In_ INT nCmdShow)
{
TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
if (!pszCmdLine || !*pszCmdLine)
return;
// '?' enables us to specify the additional mask value
ULONG fNewMask = SEE_MASK_NOASYNC;
if (*pszCmdLine == L'?') // 1st question
{
INT MaskValue;
if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
fNewMask |= MaskValue;
PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
if (pch2ndQuestion)
pszCmdLine = pch2ndQuestion + 1;
}
WCHAR szPath[2 * MAX_PATH];
if (PathProcessCommandAW(pszCmdLine, szPath, _countof(szPath), L'C') == -1)
StrCpyNW(szPath, pszCmdLine, _countof(szPath));
// Split arguments from the path
LPWSTR Args = PathGetArgsW(szPath);
if (*Args)
*(Args - 1) = UNICODE_NULL;
PathUnquoteSpacesW(szPath);
// Execute
SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
execInfo.fMask = fNewMask;
execInfo.hwnd = hwnd;
execInfo.lpFile = szPath;
execInfo.lpParameters = Args;
execInfo.nShow = nCmdShow;
if (!ShellExecuteExW(&execInfo))
{
DWORD dwError = GetLastError();
if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
ExitProcess(dwError); // Terminate it now
}
}
/*************************************************************************
* ShellExec_RunDLLA [SHELL32.358]
*
* @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/
*/
EXTERN_C
VOID WINAPI
ShellExec_RunDLLA(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCSTR pszCmdLine,
_In_ INT nCmdShow)
{
CStringW strCmdLine = pszCmdLine; // Keep
ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
}
/*************************************************************************
* ShellExec_RunDLLW [SHELL32.359]
*
* @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/
*/
EXTERN_C
VOID WINAPI
ShellExec_RunDLLW(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCWSTR pszCmdLine,
_In_ INT nCmdShow)
{
ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
}

View file

@ -297,36 +297,6 @@ ShellHookProc(INT iCode, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
/*
* Unimplemented
*/
EXTERN_C VOID
WINAPI
ShellExec_RunDLL(HWND hwnd, HINSTANCE hInstance, LPWSTR pszCmdLine, int nCmdShow)
{
FIXME("ShellExec_RunDLL() stub\n");
}
/*
* Unimplemented
*/
EXTERN_C VOID
WINAPI
ShellExec_RunDLLA(HWND hwnd, HINSTANCE hInstance, LPSTR pszCmdLine, int nCmdShow)
{
FIXME("ShellExec_RunDLLA() stub\n");
}
/*
* Unimplemented
*/
EXTERN_C VOID
WINAPI
ShellExec_RunDLLW(HWND hwnd, HINSTANCE hInstance, LPWSTR pszCmdLine, int nCmdShow)
{
FIXME("ShellExec_RunDLLW() stub\n");
}
/* /*
* Unimplemented * Unimplemented
*/ */

View file

@ -35,6 +35,7 @@ list(APPEND SOURCE
SHRestricted.cpp SHRestricted.cpp
SHShouldShowWizards.cpp SHShouldShowWizards.cpp
She.cpp She.cpp
ShellExec_RunDLL.cpp
ShellExecCmdLine.cpp ShellExecCmdLine.cpp
ShellExecuteEx.cpp ShellExecuteEx.cpp
ShellExecuteW.cpp ShellExecuteW.cpp

View file

@ -0,0 +1,61 @@
/*
* PROJECT: ReactOS API tests
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Test for ShellExec_RunDLL
* COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#include "shelltest.h"
#include "closewnd.h"
#include <undocshell.h>
static WINDOW_LIST s_List1, s_List2;
static VOID TEST_ShellExec_RunDLL(VOID)
{
ShellExec_RunDLL(NULL, NULL, "?0?notepad.exe", SW_SHOWNORMAL);
}
static VOID TEST_ShellExec_RunDLLA(VOID)
{
ShellExec_RunDLLA(NULL, NULL, "?0?notepad.exe", SW_SHOWNORMAL);
}
static VOID TEST_ShellExec_RunDLLW(VOID)
{
ShellExec_RunDLLW(NULL, NULL, L"?0?notepad.exe", SW_SHOWNORMAL);
}
static VOID CleanupWindowList(VOID)
{
GetWindowListForClose(&s_List2);
CloseNewWindows(&s_List1, &s_List2);
FreeWindowList(&s_List1);
FreeWindowList(&s_List2);
}
START_TEST(ShellExec_RunDLL)
{
HWND hwndNotepad;
GetWindowList(&s_List1);
TEST_ShellExec_RunDLL();
Sleep(1000);
hwndNotepad = FindWindowW(L"Notepad", NULL);
ok(hwndNotepad != NULL, "Notepad not found\n");
CleanupWindowList();
GetWindowList(&s_List1);
TEST_ShellExec_RunDLLA();
Sleep(1000);
hwndNotepad = FindWindowW(L"Notepad", NULL);
ok(hwndNotepad != NULL, "Notepad not found\n");
CleanupWindowList();
GetWindowList(&s_List1);
TEST_ShellExec_RunDLLW();
Sleep(1000);
hwndNotepad = FindWindowW(L"Notepad", NULL);
ok(hwndNotepad != NULL, "Notepad not found\n");
CleanupWindowList();
}

View file

@ -35,6 +35,7 @@ extern void func_SHCreateDataObject(void);
extern void func_SHCreateFileDataObject(void); extern void func_SHCreateFileDataObject(void);
extern void func_SHCreateFileExtractIconW(void); extern void func_SHCreateFileExtractIconW(void);
extern void func_She(void); extern void func_She(void);
extern void func_ShellExec_RunDLL(void);
extern void func_ShellExecCmdLine(void); extern void func_ShellExecCmdLine(void);
extern void func_ShellExecuteEx(void); extern void func_ShellExecuteEx(void);
extern void func_ShellExecuteW(void); extern void func_ShellExecuteW(void);
@ -83,6 +84,7 @@ const struct test winetest_testlist[] =
{ "SHCreateFileDataObject", func_SHCreateFileDataObject }, { "SHCreateFileDataObject", func_SHCreateFileDataObject },
{ "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW }, { "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW },
{ "She", func_She }, { "She", func_She },
{ "ShellExec_RunDLL", func_ShellExec_RunDLL },
{ "ShellExecCmdLine", func_ShellExecCmdLine }, { "ShellExecCmdLine", func_ShellExecCmdLine },
{ "ShellExecuteEx", func_ShellExecuteEx }, { "ShellExecuteEx", func_ShellExecuteEx },
{ "ShellExecuteW", func_ShellExecuteW }, { "ShellExecuteW", func_ShellExecuteW },

View file

@ -712,6 +712,27 @@ RealShellExecuteExW(
_Out_opt_ PHANDLE lphProcess, _Out_opt_ PHANDLE lphProcess,
_In_ DWORD dwFlags); _In_ DWORD dwFlags);
VOID WINAPI
ShellExec_RunDLL(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCSTR pszCmdLine,
_In_ INT nCmdShow);
VOID WINAPI
ShellExec_RunDLLA(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCSTR pszCmdLine,
_In_ INT nCmdShow);
VOID WINAPI
ShellExec_RunDLLW(
_In_opt_ HWND hwnd,
_In_opt_ HINSTANCE hInstance,
_In_ PCWSTR pszCmdLine,
_In_ INT nCmdShow);
/* RegisterShellHook types */ /* RegisterShellHook types */
#define RSH_DEREGISTER 0 #define RSH_DEREGISTER 0
#define RSH_REGISTER 1 #define RSH_REGISTER 1