mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 02:41:22 +00:00
[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:
parent
a25e7ee9d7
commit
dad3a0938a
7 changed files with 171 additions and 31 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
61
modules/rostests/apitests/shell32/ShellExec_RunDLL.cpp
Normal file
61
modules/rostests/apitests/shell32/ShellExec_RunDLL.cpp
Normal 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();
|
||||||
|
}
|
|
@ -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 },
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue