mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[SHELL32_APITEST] Strengthen ShellExecuteEx testcase (#3731)
Investigate shell32!ShellExecuteEx function more. CORE-17351, CORE-16898, CORE-17612
This commit is contained in:
parent
a5ea259b28
commit
c35a84985a
2 changed files with 271 additions and 2 deletions
|
@ -3,9 +3,12 @@
|
||||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||||
* PURPOSE: Testing ShellExecuteEx
|
* PURPOSE: Testing ShellExecuteEx
|
||||||
* PROGRAMMER: Yaroslav Veremenko <yaroslav@veremenko.info>
|
* PROGRAMMER: Yaroslav Veremenko <yaroslav@veremenko.info>
|
||||||
|
* Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "shelltest.h"
|
#include "shelltest.h"
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define ok_ShellExecuteEx (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : TestShellExecuteEx
|
#define ok_ShellExecuteEx (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : TestShellExecuteEx
|
||||||
|
|
||||||
|
@ -81,7 +84,7 @@ TestShellExecuteEx(const WCHAR* Name, BOOL ExpectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(ShellExecuteEx)
|
static void DoAppPathTest(void)
|
||||||
{
|
{
|
||||||
ok_ShellExecuteEx(L"iexplore", TRUE);
|
ok_ShellExecuteEx(L"iexplore", TRUE);
|
||||||
ok_ShellExecuteEx(L"iexplore.exe", TRUE);
|
ok_ShellExecuteEx(L"iexplore.exe", TRUE);
|
||||||
|
@ -100,3 +103,269 @@ START_TEST(ShellExecuteEx)
|
||||||
DeleteAppPathRegKey(L"iexplore.bat.exe");
|
DeleteAppPathRegKey(L"iexplore.bat.exe");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct TEST_ENTRY
|
||||||
|
{
|
||||||
|
INT lineno;
|
||||||
|
BOOL ret;
|
||||||
|
BOOL bProcessHandle;
|
||||||
|
LPCSTR file;
|
||||||
|
LPCSTR params;
|
||||||
|
LPCSTR curdir;
|
||||||
|
} TEST_ENTRY;
|
||||||
|
|
||||||
|
static char s_sub_program[MAX_PATH];
|
||||||
|
static char s_win_test_exe[MAX_PATH];
|
||||||
|
static char s_sys_test_exe[MAX_PATH];
|
||||||
|
static char s_win_bat_file[MAX_PATH];
|
||||||
|
static char s_sys_bat_file[MAX_PATH];
|
||||||
|
static char s_win_txt_file[MAX_PATH];
|
||||||
|
static char s_sys_txt_file[MAX_PATH];
|
||||||
|
|
||||||
|
#define DONT_CARE 0x0BADF00D
|
||||||
|
|
||||||
|
static const TEST_ENTRY s_entries_1[] =
|
||||||
|
{
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.bat" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.exe" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " test program" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " test program.bat" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " test program.exe" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "test program " },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.bat " },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.exe " },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program", "TEST" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.bat", "TEST" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program.exe", "TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, ".\\test program.bat" },
|
||||||
|
{ __LINE__, FALSE, FALSE, ".\\test program.exe" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\"test program\"" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\"test program.bat\"" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\"test program.exe\"" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program\" TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program.bat\" TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program.exe\" TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " \"test program\"" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " \"test program.bat\"" },
|
||||||
|
{ __LINE__, FALSE, FALSE, " \"test program.exe\"" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program\" " },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program.bat\" " },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\"test program.exe\" " },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\".\\test program.bat\"" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "\".\\test program.exe\"" },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_win_test_exe },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_sys_test_exe },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_win_bat_file },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_sys_bat_file },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_win_bat_file, "TEST" },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_sys_bat_file, "TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "invalid program" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "invalid program.bat" },
|
||||||
|
{ __LINE__, FALSE, FALSE, "invalid program.exe" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test_file.txt" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test_file.txt", "parameters parameters" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test_file.txt", "parameters parameters", "." },
|
||||||
|
{ __LINE__, TRUE, TRUE, "shell32_apitest_sub.exe" },
|
||||||
|
{ __LINE__, TRUE, TRUE, ".\\shell32_apitest_sub.exe" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\"shell32_apitest_sub.exe\"" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\".\\shell32_apitest_sub.exe\"" },
|
||||||
|
{ __LINE__, TRUE, DONT_CARE, "https://google.com" },
|
||||||
|
{ __LINE__, TRUE, FALSE, "::{450d8fba-ad25-11d0-98a8-0800361b1103}" },
|
||||||
|
{ __LINE__, TRUE, FALSE, "shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}" },
|
||||||
|
{ __LINE__, TRUE, FALSE, "shell:sendto" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const TEST_ENTRY s_entries_2[] =
|
||||||
|
{
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "test program", "TEST" },
|
||||||
|
{ __LINE__, TRUE, TRUE, "\"test program\"" },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_win_test_exe },
|
||||||
|
{ __LINE__, TRUE, TRUE, s_sys_test_exe },
|
||||||
|
{ __LINE__, FALSE, FALSE, s_win_bat_file },
|
||||||
|
{ __LINE__, FALSE, FALSE, s_sys_bat_file },
|
||||||
|
{ __LINE__, FALSE, FALSE, s_win_bat_file, "TEST" },
|
||||||
|
{ __LINE__, FALSE, FALSE, s_sys_bat_file, "TEST" },
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct OPENWNDS
|
||||||
|
{
|
||||||
|
UINT count;
|
||||||
|
HWND *phwnd;
|
||||||
|
} OPENWNDS;
|
||||||
|
|
||||||
|
static OPENWNDS s_wi0 = { 0 }, s_wi1 = { 0 };
|
||||||
|
|
||||||
|
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||||||
|
{
|
||||||
|
OPENWNDS *info = (OPENWNDS *)lParam;
|
||||||
|
info->phwnd = (HWND *)realloc(info->phwnd, (info->count + 1) * sizeof(HWND));
|
||||||
|
if (!info->phwnd)
|
||||||
|
return FALSE;
|
||||||
|
info->phwnd[info->count] = hwnd;
|
||||||
|
++(info->count);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID DoTestEntry(const TEST_ENTRY *pEntry)
|
||||||
|
{
|
||||||
|
SHELLEXECUTEINFOA info = { sizeof(info) };
|
||||||
|
info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
|
||||||
|
info.nShow = SW_SHOWNORMAL;
|
||||||
|
info.lpFile = pEntry->file;
|
||||||
|
info.lpParameters = pEntry->params;
|
||||||
|
info.lpDirectory = pEntry->curdir;
|
||||||
|
BOOL ret = ShellExecuteExA(&info);
|
||||||
|
ok(ret == pEntry->ret, "Line %u: ret expected %d, got %d\n",
|
||||||
|
pEntry->lineno, pEntry->ret, ret);
|
||||||
|
if (!pEntry->ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((UINT)pEntry->bProcessHandle != DONT_CARE)
|
||||||
|
{
|
||||||
|
if (pEntry->bProcessHandle)
|
||||||
|
{
|
||||||
|
ok(!!info.hProcess, "Line %u: hProcess expected non-NULL\n", pEntry->lineno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(!info.hProcess, "Line %u: hProcess expected NULL\n", pEntry->lineno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForInputIdle(info.hProcess, INFINITE);
|
||||||
|
|
||||||
|
// close newly opened windows
|
||||||
|
EnumWindows(EnumWindowsProc, (LPARAM)&s_wi1);
|
||||||
|
for (UINT i1 = 0; i1 < s_wi1.count; ++i1)
|
||||||
|
{
|
||||||
|
BOOL bFound = FALSE;
|
||||||
|
for (UINT i0 = 0; i0 < s_wi0.count; ++i0)
|
||||||
|
{
|
||||||
|
if (s_wi1.phwnd[i1] == s_wi0.phwnd[i0])
|
||||||
|
{
|
||||||
|
bFound = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bFound)
|
||||||
|
PostMessageW(s_wi1.phwnd[i1], WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
free(s_wi1.phwnd);
|
||||||
|
ZeroMemory(&s_wi1, sizeof(s_wi1));
|
||||||
|
|
||||||
|
WaitForSingleObject(info.hProcess, INFINITE);
|
||||||
|
CloseHandle(info.hProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
GetSubProgramPath(void)
|
||||||
|
{
|
||||||
|
GetModuleFileNameA(NULL, s_sub_program, _countof(s_sub_program));
|
||||||
|
PathRemoveFileSpecA(s_sub_program);
|
||||||
|
PathAppendA(s_sub_program, "shell32_apitest_sub.exe");
|
||||||
|
|
||||||
|
if (!PathFileExistsA(s_sub_program))
|
||||||
|
{
|
||||||
|
PathRemoveFileSpecA(s_sub_program);
|
||||||
|
PathAppendA(s_sub_program, "testdata\\shell32_apitest_sub.exe");
|
||||||
|
|
||||||
|
if (!PathFileExistsA(s_sub_program))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DoTestEntries(void)
|
||||||
|
{
|
||||||
|
if (!GetSubProgramPath())
|
||||||
|
{
|
||||||
|
skip("shell32_apitest_sub.exe is not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// s_win_test_exe
|
||||||
|
GetWindowsDirectoryA(s_win_test_exe, _countof(s_win_test_exe));
|
||||||
|
PathAppendA(s_win_test_exe, "test program.exe");
|
||||||
|
BOOL ret = CopyFileA(s_sub_program, s_win_test_exe, FALSE);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
skip("Please retry with admin rights\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// record open windows
|
||||||
|
if (!EnumWindows(EnumWindowsProc, (LPARAM)&s_wi0))
|
||||||
|
{
|
||||||
|
skip("EnumWindows failed\n");
|
||||||
|
DeleteFileA(s_win_test_exe);
|
||||||
|
free(s_wi0.phwnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// s_sys_test_exe
|
||||||
|
GetSystemDirectoryA(s_sys_test_exe, _countof(s_sys_test_exe));
|
||||||
|
PathAppendA(s_sys_test_exe, "test program.exe");
|
||||||
|
ok_int(CopyFileA(s_sub_program, s_sys_test_exe, FALSE), TRUE);
|
||||||
|
|
||||||
|
// s_win_bat_file
|
||||||
|
GetWindowsDirectoryA(s_win_bat_file, _countof(s_win_bat_file));
|
||||||
|
PathAppendA(s_win_bat_file, "test program.bat");
|
||||||
|
FILE *fp = fopen(s_win_bat_file, "wb");
|
||||||
|
fprintf(fp, "exit /b 3");
|
||||||
|
fclose(fp);
|
||||||
|
ok_int(PathFileExistsA(s_win_bat_file), TRUE);
|
||||||
|
|
||||||
|
// s_sys_bat_file
|
||||||
|
GetSystemDirectoryA(s_sys_bat_file, _countof(s_sys_bat_file));
|
||||||
|
PathAppendA(s_sys_bat_file, "test program.bat");
|
||||||
|
fp = fopen(s_sys_bat_file, "wb");
|
||||||
|
fprintf(fp, "exit /b 4");
|
||||||
|
fclose(fp);
|
||||||
|
ok_int(PathFileExistsA(s_sys_bat_file), TRUE);
|
||||||
|
|
||||||
|
// s_win_txt_file
|
||||||
|
GetWindowsDirectoryA(s_win_txt_file, _countof(s_win_txt_file));
|
||||||
|
PathAppendA(s_win_txt_file, "test_file.txt");
|
||||||
|
fp = fopen(s_win_txt_file, "wb");
|
||||||
|
fclose(fp);
|
||||||
|
ok_int(PathFileExistsA(s_win_txt_file), TRUE);
|
||||||
|
|
||||||
|
// s_sys_txt_file
|
||||||
|
GetSystemDirectoryA(s_sys_txt_file, _countof(s_sys_txt_file));
|
||||||
|
PathAppendA(s_sys_txt_file, "test_file.txt");
|
||||||
|
fp = fopen(s_sys_txt_file, "wb");
|
||||||
|
fclose(fp);
|
||||||
|
ok_int(PathFileExistsA(s_sys_txt_file), TRUE);
|
||||||
|
|
||||||
|
for (UINT iTest = 0; iTest < _countof(s_entries_1); ++iTest)
|
||||||
|
{
|
||||||
|
DoTestEntry(&s_entries_1[iTest]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteFileA(s_win_bat_file);
|
||||||
|
DeleteFileA(s_sys_bat_file);
|
||||||
|
|
||||||
|
for (UINT iTest = 0; iTest < _countof(s_entries_2); ++iTest)
|
||||||
|
{
|
||||||
|
DoTestEntry(&s_entries_2[iTest]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteFileA(s_win_test_exe);
|
||||||
|
DeleteFileA(s_sys_test_exe);
|
||||||
|
DeleteFileA(s_win_txt_file);
|
||||||
|
DeleteFileA(s_sys_txt_file);
|
||||||
|
|
||||||
|
free(s_wi0.phwnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(ShellExecuteEx)
|
||||||
|
{
|
||||||
|
DoAppPathTest();
|
||||||
|
DoTestEntries();
|
||||||
|
}
|
||||||
|
|
|
@ -262,7 +262,7 @@ wWinMain(HINSTANCE hInstance,
|
||||||
LPWSTR lpCmdLine,
|
LPWSTR lpCmdLine,
|
||||||
INT nCmdShow)
|
INT nCmdShow)
|
||||||
{
|
{
|
||||||
if (lstrcmpiW(lpCmdLine, L"") == 0)
|
if (lstrcmpiW(lpCmdLine, L"") == 0 || lstrcmpiW(lpCmdLine, L"TEST") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s_nMode = _wtoi(lpCmdLine);
|
s_nMode = _wtoi(lpCmdLine);
|
||||||
|
|
Loading…
Reference in a new issue