1c2c66affSColin Finck /* 2c2c66affSColin Finck * PROJECT: ReactOS api tests 3c2c66affSColin Finck * LICENSE: GPLv2+ - See COPYING in the top level directory 4c2c66affSColin Finck * PURPOSE: Testing ShellExecuteEx 5c2c66affSColin Finck * PROGRAMMER: Yaroslav Veremenko <yaroslav@veremenko.info> 6c35a8498SKatayama Hirofumi MZ * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 7c2c66affSColin Finck */ 8c2c66affSColin Finck 9c2c66affSColin Finck #include "shelltest.h" 10*436cfa94SKatayama Hirofumi MZ #include "closewnd.h" 11ab4c0d6aSKatayama Hirofumi MZ #include <pstypes.h> 12ab4c0d6aSKatayama Hirofumi MZ #include <psfuncs.h> 13ab4c0d6aSKatayama Hirofumi MZ #include <stdlib.h> 14c35a8498SKatayama Hirofumi MZ #include <stdio.h> 15ab4c0d6aSKatayama Hirofumi MZ #include <strsafe.h> 16ab4c0d6aSKatayama Hirofumi MZ #include <versionhelpers.h> 17c2c66affSColin Finck 18ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_dir[MAX_PATH]; 19ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_dir[MAX_PATH]; 20ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_notepad[MAX_PATH]; 21ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_notepad[MAX_PATH]; 22ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_test_exe[MAX_PATH]; 23ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_test_exe[MAX_PATH]; 24ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_bat_file[MAX_PATH]; 25ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_bat_file[MAX_PATH]; 26ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_txt_file[MAX_PATH]; 27ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_txt_file[MAX_PATH]; 28ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_notepad_cmdline[MAX_PATH]; 29ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_notepad_cmdline[MAX_PATH]; 30ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_win_test_exe_cmdline[MAX_PATH]; 31ab4c0d6aSKatayama Hirofumi MZ static WCHAR s_sys_test_exe_cmdline[MAX_PATH]; 32ab4c0d6aSKatayama Hirofumi MZ static BOOL s_bWow64; 33c2c66affSColin Finck 34ab4c0d6aSKatayama Hirofumi MZ #define REG_APPPATHS L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" 35ab4c0d6aSKatayama Hirofumi MZ 36ab4c0d6aSKatayama Hirofumi MZ typedef enum TEST_RESULT 37c2c66affSColin Finck { 38ab4c0d6aSKatayama Hirofumi MZ TEST_FAILED, 39ab4c0d6aSKatayama Hirofumi MZ TEST_SUCCESS_NO_PROCESS, 40ab4c0d6aSKatayama Hirofumi MZ TEST_SUCCESS_WITH_PROCESS, 41ab4c0d6aSKatayama Hirofumi MZ } TEST_RESULT; 42c35a8498SKatayama Hirofumi MZ 43c35a8498SKatayama Hirofumi MZ typedef struct TEST_ENTRY 44c35a8498SKatayama Hirofumi MZ { 45ab4c0d6aSKatayama Hirofumi MZ INT line; 46ab4c0d6aSKatayama Hirofumi MZ TEST_RESULT result; 47ab4c0d6aSKatayama Hirofumi MZ LPCWSTR lpFile; 48ab4c0d6aSKatayama Hirofumi MZ LPCWSTR cmdline; 49ab4c0d6aSKatayama Hirofumi MZ } TEST_ENTRY, *PTEST_ENTRY; 50c35a8498SKatayama Hirofumi MZ 51ab4c0d6aSKatayama Hirofumi MZ static void 52ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(INT line, TEST_RESULT result, LPCWSTR lpFile, LPCWSTR cmdline = NULL); 53c35a8498SKatayama Hirofumi MZ 54ab4c0d6aSKatayama Hirofumi MZ static void TEST_DoTestEntries(void) 55c35a8498SKatayama Hirofumi MZ { 56ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, NULL); 57ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L""); 58ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_FAILED, L"This is an invalid path."); 59ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_sys_bat_file, NULL); 60ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_sys_test_exe, s_sys_test_exe_cmdline); 61ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_sys_txt_file, NULL); 62ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_win_bat_file, NULL); 63ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_win_notepad, s_win_notepad_cmdline); 64ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_win_test_exe, s_win_test_exe_cmdline); 65ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, s_win_txt_file, NULL); 66ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"notepad", s_sys_notepad_cmdline); 67ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"notepad.exe", s_sys_notepad_cmdline); 68ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"\"notepad.exe\"", s_sys_notepad_cmdline); 69ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"\"notepad\"", s_sys_notepad_cmdline); 70ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"test program.exe", s_sys_test_exe_cmdline); 71ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"\"test program.exe\"", s_sys_test_exe_cmdline); 72ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, s_win_dir); 73ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, s_sys_dir); 74ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_FAILED, L"shell:ThisIsAnInvalidName"); 75ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"); // My Computer 76ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"); // My Computer (with shell:) 77c35a8498SKatayama Hirofumi MZ 78ab4c0d6aSKatayama Hirofumi MZ if (!IsWindowsVistaOrGreater()) 79c35a8498SKatayama Hirofumi MZ { 80ab4c0d6aSKatayama Hirofumi MZ WCHAR szCurDir[MAX_PATH]; 81ab4c0d6aSKatayama Hirofumi MZ GetCurrentDirectoryW(_countof(szCurDir), szCurDir); 82ab4c0d6aSKatayama Hirofumi MZ SetCurrentDirectoryW(s_sys_dir); 83ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_FAILED, L"::{21EC2020-3AEA-1069-A2DD-08002B30309D}"); // Control Panel (without path) 84ab4c0d6aSKatayama Hirofumi MZ SetCurrentDirectoryW(szCurDir); 85c35a8498SKatayama Hirofumi MZ } 86c35a8498SKatayama Hirofumi MZ 87ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"); // Control Panel (with path) 88ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"); // Control Panel (with path and shell:) 89ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:AppData"); 90ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Common Desktop"); 91ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Common Programs"); 92ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Common Start Menu"); 93ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Common StartUp"); 94ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:ControlPanelFolder"); 95ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Desktop"); 96ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Favorites"); 97ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Fonts"); 98ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Local AppData"); 99ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:My Pictures"); 100ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Personal"); 101ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Programs"); 102ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Recent"); 103ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:RecycleBinFolder"); 104ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:SendTo"); 105ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:Start Menu"); 106ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_NO_PROCESS, L"shell:StartUp"); 107307ce1a5SHermès Bélusca-Maïto } 108307ce1a5SHermès Bélusca-Maïto 109ab4c0d6aSKatayama Hirofumi MZ static LPWSTR 110ab4c0d6aSKatayama Hirofumi MZ getCommandLineFromProcess(HANDLE hProcess) 111c35a8498SKatayama Hirofumi MZ { 112ab4c0d6aSKatayama Hirofumi MZ PEB peb; 113ab4c0d6aSKatayama Hirofumi MZ PROCESS_BASIC_INFORMATION info; 114ab4c0d6aSKatayama Hirofumi MZ RTL_USER_PROCESS_PARAMETERS Params; 1154854a1d7SKatayama Hirofumi MZ NTSTATUS Status; 1164854a1d7SKatayama Hirofumi MZ BOOL ret; 117ab4c0d6aSKatayama Hirofumi MZ 1184854a1d7SKatayama Hirofumi MZ Status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), NULL); 1194854a1d7SKatayama Hirofumi MZ ok_ntstatus(Status, STATUS_SUCCESS); 1204854a1d7SKatayama Hirofumi MZ 1214854a1d7SKatayama Hirofumi MZ ret = ReadProcessMemory(hProcess, info.PebBaseAddress, &peb, sizeof(peb), NULL); 1224854a1d7SKatayama Hirofumi MZ if (!ret) 1234854a1d7SKatayama Hirofumi MZ trace("ReadProcessMemory failed (%ld)\n", GetLastError()); 1244854a1d7SKatayama Hirofumi MZ 125ab4c0d6aSKatayama Hirofumi MZ ReadProcessMemory(hProcess, peb.ProcessParameters, &Params, sizeof(Params), NULL); 1264854a1d7SKatayama Hirofumi MZ if (!ret) 1274854a1d7SKatayama Hirofumi MZ trace("ReadProcessMemory failed (%ld)\n", GetLastError()); 128ab4c0d6aSKatayama Hirofumi MZ 129ab4c0d6aSKatayama Hirofumi MZ LPWSTR cmdline = Params.CommandLine.Buffer; 1304854a1d7SKatayama Hirofumi MZ if (!cmdline) 1314854a1d7SKatayama Hirofumi MZ trace("!cmdline\n"); 1324854a1d7SKatayama Hirofumi MZ 1334854a1d7SKatayama Hirofumi MZ SIZE_T cbCmdLine = Params.CommandLine.Length; 1344854a1d7SKatayama Hirofumi MZ if (!cbCmdLine) 1354854a1d7SKatayama Hirofumi MZ trace("!cbCmdLine\n"); 1364854a1d7SKatayama Hirofumi MZ 1374854a1d7SKatayama Hirofumi MZ LPWSTR pszBuffer = (LPWSTR)calloc(cbCmdLine + sizeof(WCHAR), 1); 1384854a1d7SKatayama Hirofumi MZ if (!pszBuffer) 1394854a1d7SKatayama Hirofumi MZ trace("!pszBuffer\n"); 1404854a1d7SKatayama Hirofumi MZ 1414854a1d7SKatayama Hirofumi MZ ret = ReadProcessMemory(hProcess, cmdline, pszBuffer, cbCmdLine, NULL); 1424854a1d7SKatayama Hirofumi MZ if (!ret) 1434854a1d7SKatayama Hirofumi MZ trace("ReadProcessMemory failed (%ld)\n", GetLastError()); 1444854a1d7SKatayama Hirofumi MZ 1454854a1d7SKatayama Hirofumi MZ pszBuffer[cbCmdLine / sizeof(WCHAR)] = UNICODE_NULL; 146ab4c0d6aSKatayama Hirofumi MZ 147ab4c0d6aSKatayama Hirofumi MZ return pszBuffer; // needs free() 148ab4c0d6aSKatayama Hirofumi MZ } 149ab4c0d6aSKatayama Hirofumi MZ 150ab4c0d6aSKatayama Hirofumi MZ static void TEST_DoTestEntryStruct(const TEST_ENTRY *pEntry) 151ab4c0d6aSKatayama Hirofumi MZ { 152ab4c0d6aSKatayama Hirofumi MZ SHELLEXECUTEINFOW info = { sizeof(info) }; 153*436cfa94SKatayama Hirofumi MZ info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_WAITFORINPUTIDLE | 154*436cfa94SKatayama Hirofumi MZ SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC; 155ab4c0d6aSKatayama Hirofumi MZ info.hwnd = NULL; 156ab4c0d6aSKatayama Hirofumi MZ info.lpVerb = NULL; 157ab4c0d6aSKatayama Hirofumi MZ info.lpFile = pEntry->lpFile; 158c35a8498SKatayama Hirofumi MZ info.nShow = SW_SHOWNORMAL; 159c35a8498SKatayama Hirofumi MZ 160ab4c0d6aSKatayama Hirofumi MZ BOOL ret = ShellExecuteExW(&info); 161ab4c0d6aSKatayama Hirofumi MZ 162ab4c0d6aSKatayama Hirofumi MZ TEST_RESULT result; 163ab4c0d6aSKatayama Hirofumi MZ if (ret && info.hProcess) 164ab4c0d6aSKatayama Hirofumi MZ result = TEST_SUCCESS_WITH_PROCESS; 165ab4c0d6aSKatayama Hirofumi MZ else if (ret && !info.hProcess) 166ab4c0d6aSKatayama Hirofumi MZ result = TEST_SUCCESS_NO_PROCESS; 167ab4c0d6aSKatayama Hirofumi MZ else 168ab4c0d6aSKatayama Hirofumi MZ result = TEST_FAILED; 169ab4c0d6aSKatayama Hirofumi MZ 170ab4c0d6aSKatayama Hirofumi MZ ok(pEntry->result == result, 171ab4c0d6aSKatayama Hirofumi MZ "Line %d: result: %d vs %d\n", pEntry->line, pEntry->result, result); 172ab4c0d6aSKatayama Hirofumi MZ 173ab4c0d6aSKatayama Hirofumi MZ if (pEntry->result == TEST_SUCCESS_WITH_PROCESS && pEntry->cmdline && !s_bWow64) 174c35a8498SKatayama Hirofumi MZ { 175ab4c0d6aSKatayama Hirofumi MZ LPWSTR cmdline = getCommandLineFromProcess(info.hProcess); 176ab4c0d6aSKatayama Hirofumi MZ if (!cmdline) 177c35a8498SKatayama Hirofumi MZ { 178ab4c0d6aSKatayama Hirofumi MZ skip("!cmdline\n"); 179c35a8498SKatayama Hirofumi MZ } 180c35a8498SKatayama Hirofumi MZ else 181c35a8498SKatayama Hirofumi MZ { 182ab4c0d6aSKatayama Hirofumi MZ ok(lstrcmpiW(pEntry->cmdline, cmdline) == 0, 183ab4c0d6aSKatayama Hirofumi MZ "Line %d: cmdline: '%ls' vs '%ls'\n", pEntry->line, 184ab4c0d6aSKatayama Hirofumi MZ pEntry->cmdline, cmdline); 185c35a8498SKatayama Hirofumi MZ } 186c35a8498SKatayama Hirofumi MZ 187ab4c0d6aSKatayama Hirofumi MZ TerminateProcess(info.hProcess, 0xDEADFACE); 188ab4c0d6aSKatayama Hirofumi MZ free(cmdline); 189f80de47cSMark Jansen } 190ab4c0d6aSKatayama Hirofumi MZ 191c35a8498SKatayama Hirofumi MZ CloseHandle(info.hProcess); 192c35a8498SKatayama Hirofumi MZ } 193c35a8498SKatayama Hirofumi MZ 194ab4c0d6aSKatayama Hirofumi MZ static void 195ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(INT line, TEST_RESULT result, LPCWSTR lpFile, LPCWSTR cmdline) 196ab4c0d6aSKatayama Hirofumi MZ { 197ab4c0d6aSKatayama Hirofumi MZ TEST_ENTRY entry = { line, result, lpFile, cmdline }; 198ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntryStruct(&entry); 199ab4c0d6aSKatayama Hirofumi MZ } 200ab4c0d6aSKatayama Hirofumi MZ 201c35a8498SKatayama Hirofumi MZ static BOOL 202ab4c0d6aSKatayama Hirofumi MZ enableTokenPrivilege(LPCWSTR pszPrivilege) 203c35a8498SKatayama Hirofumi MZ { 204ab4c0d6aSKatayama Hirofumi MZ HANDLE hToken; 205ab4c0d6aSKatayama Hirofumi MZ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 206c35a8498SKatayama Hirofumi MZ return FALSE; 207ab4c0d6aSKatayama Hirofumi MZ 208ab4c0d6aSKatayama Hirofumi MZ TOKEN_PRIVILEGES tkp = { 0 }; 209ab4c0d6aSKatayama Hirofumi MZ if (!LookupPrivilegeValueW(NULL, pszPrivilege, &tkp.Privileges[0].Luid)) 210ab4c0d6aSKatayama Hirofumi MZ return FALSE; 211ab4c0d6aSKatayama Hirofumi MZ 212ab4c0d6aSKatayama Hirofumi MZ tkp.PrivilegeCount = 1; 213ab4c0d6aSKatayama Hirofumi MZ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 214ab4c0d6aSKatayama Hirofumi MZ return AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, NULL); 215c35a8498SKatayama Hirofumi MZ } 216c35a8498SKatayama Hirofumi MZ 217ab4c0d6aSKatayama Hirofumi MZ static WINDOW_LIST s_List1, s_List2; 218ab4c0d6aSKatayama Hirofumi MZ 219ab4c0d6aSKatayama Hirofumi MZ static BOOL TEST_Start(void) 220ab4c0d6aSKatayama Hirofumi MZ { 221ab4c0d6aSKatayama Hirofumi MZ // Check Wow64 222ab4c0d6aSKatayama Hirofumi MZ s_bWow64 = FALSE; 223ab4c0d6aSKatayama Hirofumi MZ IsWow64Process(GetCurrentProcess(), &s_bWow64); 224ab4c0d6aSKatayama Hirofumi MZ if (s_bWow64) 225ab4c0d6aSKatayama Hirofumi MZ skip("Wow64: Command Line check is skipped\n"); 226ab4c0d6aSKatayama Hirofumi MZ 227ab4c0d6aSKatayama Hirofumi MZ // getCommandLineFromProcess needs this 228ab4c0d6aSKatayama Hirofumi MZ enableTokenPrivilege(SE_DEBUG_NAME); 229ab4c0d6aSKatayama Hirofumi MZ 230ab4c0d6aSKatayama Hirofumi MZ // s_win_dir 231ab4c0d6aSKatayama Hirofumi MZ GetWindowsDirectoryW(s_win_dir, _countof(s_win_dir)); 232ab4c0d6aSKatayama Hirofumi MZ 233ab4c0d6aSKatayama Hirofumi MZ // s_sys_dir 234ab4c0d6aSKatayama Hirofumi MZ GetSystemDirectoryW(s_sys_dir, _countof(s_sys_dir)); 235ab4c0d6aSKatayama Hirofumi MZ 236ab4c0d6aSKatayama Hirofumi MZ // s_win_notepad 237ab4c0d6aSKatayama Hirofumi MZ GetWindowsDirectoryW(s_win_notepad, _countof(s_win_notepad)); 238ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_win_notepad, L"notepad.exe"); 239ab4c0d6aSKatayama Hirofumi MZ 240ab4c0d6aSKatayama Hirofumi MZ // s_sys_notepad 241ab4c0d6aSKatayama Hirofumi MZ GetSystemDirectoryW(s_sys_notepad, _countof(s_sys_notepad)); 242ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_sys_notepad, L"notepad.exe"); 243ab4c0d6aSKatayama Hirofumi MZ 244c35a8498SKatayama Hirofumi MZ // s_win_test_exe 245ab4c0d6aSKatayama Hirofumi MZ GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe)); 246ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_win_test_exe, L"test program.exe"); 247ab4c0d6aSKatayama Hirofumi MZ BOOL ret = CopyFileW(s_win_notepad, s_win_test_exe, FALSE); 248c35a8498SKatayama Hirofumi MZ if (!ret) 249c35a8498SKatayama Hirofumi MZ { 250c35a8498SKatayama Hirofumi MZ skip("Please retry with admin rights\n"); 251ab4c0d6aSKatayama Hirofumi MZ return FALSE; 252c35a8498SKatayama Hirofumi MZ } 253c35a8498SKatayama Hirofumi MZ 254c35a8498SKatayama Hirofumi MZ // s_sys_test_exe 255ab4c0d6aSKatayama Hirofumi MZ GetSystemDirectoryW(s_sys_test_exe, _countof(s_sys_test_exe)); 256ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_sys_test_exe, L"test program.exe"); 257ab4c0d6aSKatayama Hirofumi MZ ok_int(CopyFileW(s_win_notepad, s_sys_test_exe, FALSE), TRUE); 258c35a8498SKatayama Hirofumi MZ 259c35a8498SKatayama Hirofumi MZ // s_win_bat_file 260ab4c0d6aSKatayama Hirofumi MZ GetWindowsDirectoryW(s_win_bat_file, _countof(s_win_bat_file)); 261ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_win_bat_file, L"test program.bat"); 262ab4c0d6aSKatayama Hirofumi MZ FILE *fp = _wfopen(s_win_bat_file, L"wb"); 263c35a8498SKatayama Hirofumi MZ fprintf(fp, "exit /b 3"); 264c35a8498SKatayama Hirofumi MZ fclose(fp); 265ab4c0d6aSKatayama Hirofumi MZ ok_int(PathFileExistsW(s_win_bat_file), TRUE); 266c35a8498SKatayama Hirofumi MZ 267c35a8498SKatayama Hirofumi MZ // s_sys_bat_file 268ab4c0d6aSKatayama Hirofumi MZ GetSystemDirectoryW(s_sys_bat_file, _countof(s_sys_bat_file)); 269ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_sys_bat_file, L"test program.bat"); 270ab4c0d6aSKatayama Hirofumi MZ fp = _wfopen(s_sys_bat_file, L"wb"); 271c35a8498SKatayama Hirofumi MZ fprintf(fp, "exit /b 4"); 272c35a8498SKatayama Hirofumi MZ fclose(fp); 273ab4c0d6aSKatayama Hirofumi MZ ok_int(PathFileExistsW(s_sys_bat_file), TRUE); 274c35a8498SKatayama Hirofumi MZ 275c35a8498SKatayama Hirofumi MZ // s_win_txt_file 276ab4c0d6aSKatayama Hirofumi MZ GetWindowsDirectoryW(s_win_txt_file, _countof(s_win_txt_file)); 277ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_win_txt_file, L"test_file.txt"); 278ab4c0d6aSKatayama Hirofumi MZ fp = _wfopen(s_win_txt_file, L"wb"); 279c35a8498SKatayama Hirofumi MZ fclose(fp); 280ab4c0d6aSKatayama Hirofumi MZ ok_int(PathFileExistsW(s_win_txt_file), TRUE); 281c35a8498SKatayama Hirofumi MZ 282c35a8498SKatayama Hirofumi MZ // s_sys_txt_file 283ab4c0d6aSKatayama Hirofumi MZ GetSystemDirectoryW(s_sys_txt_file, _countof(s_sys_txt_file)); 284ab4c0d6aSKatayama Hirofumi MZ PathAppendW(s_sys_txt_file, L"test_file.txt"); 285ab4c0d6aSKatayama Hirofumi MZ fp = _wfopen(s_sys_txt_file, L"wb"); 286c35a8498SKatayama Hirofumi MZ fclose(fp); 287ab4c0d6aSKatayama Hirofumi MZ ok_int(PathFileExistsW(s_sys_txt_file), TRUE); 288c35a8498SKatayama Hirofumi MZ 289ab4c0d6aSKatayama Hirofumi MZ // Check .txt settings 290ab4c0d6aSKatayama Hirofumi MZ WCHAR szPath[MAX_PATH]; 291ab4c0d6aSKatayama Hirofumi MZ FindExecutableW(s_sys_txt_file, NULL, szPath); 292ab4c0d6aSKatayama Hirofumi MZ if (lstrcmpiW(PathFindFileNameW(szPath), L"notepad.exe") != 0) 293c35a8498SKatayama Hirofumi MZ { 294ab4c0d6aSKatayama Hirofumi MZ skip("Please associate .txt with notepad.exe before tests\n"); 295f80de47cSMark Jansen return FALSE; 296f80de47cSMark Jansen } 297ab4c0d6aSKatayama Hirofumi MZ 298ab4c0d6aSKatayama Hirofumi MZ // command lines 299ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(s_win_notepad_cmdline, _countof(s_win_notepad_cmdline), 300ab4c0d6aSKatayama Hirofumi MZ L"\"%s\" ", s_win_notepad); 301ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(s_sys_notepad_cmdline, _countof(s_sys_notepad_cmdline), 302ab4c0d6aSKatayama Hirofumi MZ L"\"%s\" ", s_sys_notepad); 303ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(s_win_test_exe_cmdline, _countof(s_win_test_exe_cmdline), 304ab4c0d6aSKatayama Hirofumi MZ L"\"%s\" ", s_win_test_exe); 305ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(s_sys_test_exe_cmdline, _countof(s_sys_test_exe_cmdline), 306ab4c0d6aSKatayama Hirofumi MZ L"\"%s\" ", s_sys_test_exe); 307ab4c0d6aSKatayama Hirofumi MZ 308*436cfa94SKatayama Hirofumi MZ GetWindowList(&s_List1); 309ab4c0d6aSKatayama Hirofumi MZ 310f80de47cSMark Jansen return TRUE; 311f80de47cSMark Jansen } 312f80de47cSMark Jansen 313ab4c0d6aSKatayama Hirofumi MZ static void TEST_End(void) 314f80de47cSMark Jansen { 315ab4c0d6aSKatayama Hirofumi MZ Sleep(500); 316*436cfa94SKatayama Hirofumi MZ GetWindowList(&s_List2); 317*436cfa94SKatayama Hirofumi MZ CloseNewWindows(&s_List1, &s_List2); 318*436cfa94SKatayama Hirofumi MZ FreeWindowList(&s_List1); 319*436cfa94SKatayama Hirofumi MZ FreeWindowList(&s_List2); 320f80de47cSMark Jansen 321ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_win_test_exe); 322ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_sys_test_exe); 323ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_win_txt_file); 324ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_sys_txt_file); 325ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_win_bat_file); 326ab4c0d6aSKatayama Hirofumi MZ DeleteFileW(s_sys_bat_file); 327f80de47cSMark Jansen } 328f80de47cSMark Jansen 329f80de47cSMark Jansen static void test_properties() 330f80de47cSMark Jansen { 331ab4c0d6aSKatayama Hirofumi MZ HRESULT hrCoInit = CoInitialize(NULL); 332f80de47cSMark Jansen 3334854a1d7SKatayama Hirofumi MZ WCHAR Buffer[MAX_PATH * 4]; 334f80de47cSMark Jansen GetModuleFileNameW(NULL, Buffer, _countof(Buffer)); 335f80de47cSMark Jansen 3364854a1d7SKatayama Hirofumi MZ SHELLEXECUTEINFOW info = { sizeof(info) }; 337f80de47cSMark Jansen info.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI; 338f80de47cSMark Jansen info.lpVerb = L"properties"; 339f80de47cSMark Jansen info.lpFile = Buffer; 340f80de47cSMark Jansen info.nShow = SW_SHOW; 341f80de47cSMark Jansen 342f80de47cSMark Jansen BOOL bRet = ShellExecuteExW(&info); 343f80de47cSMark Jansen ok(bRet, "Failed! (GetLastError(): %d)\n", (int)GetLastError()); 344f80de47cSMark Jansen ok_ptr(info.hInstApp, (HINSTANCE)42); 345f80de47cSMark Jansen 346f80de47cSMark Jansen WCHAR* Extension = PathFindExtensionW(Buffer); 347f80de47cSMark Jansen if (Extension) 348f80de47cSMark Jansen { 349f80de47cSMark Jansen // The inclusion of this depends on the file display settings! 350f80de47cSMark Jansen *Extension = UNICODE_NULL; 351f80de47cSMark Jansen } 352f80de47cSMark Jansen 353f80de47cSMark Jansen // Now retry it with the extension cut off 354f80de47cSMark Jansen bRet = ShellExecuteExW(&info); 355f80de47cSMark Jansen ok(bRet, "Failed! (GetLastError(): %d)\n", (int)GetLastError()); 356f80de47cSMark Jansen ok_ptr(info.hInstApp, (HINSTANCE)42); 357f80de47cSMark Jansen 358f80de47cSMark Jansen // Now retry it with complete garabage 359ab4c0d6aSKatayama Hirofumi MZ info.lpFile = L"complete garbage, cannot run this!"; 360f80de47cSMark Jansen bRet = ShellExecuteExW(&info); 361ab4c0d6aSKatayama Hirofumi MZ ok_int(bRet, 0); 362f80de47cSMark Jansen ok_ptr(info.hInstApp, (HINSTANCE)2); 363ab4c0d6aSKatayama Hirofumi MZ 364ab4c0d6aSKatayama Hirofumi MZ if (SUCCEEDED(hrCoInit)) 365ab4c0d6aSKatayama Hirofumi MZ CoUninitialize(); 366f80de47cSMark Jansen } 367f80de47cSMark Jansen 3681b3eed58SDoug Lyons static void test_sei_lpIDList() 3691b3eed58SDoug Lyons { 370ab4c0d6aSKatayama Hirofumi MZ if (IsWindowsVistaOrGreater()) 371ab4c0d6aSKatayama Hirofumi MZ { 372ab4c0d6aSKatayama Hirofumi MZ skip("Vista+\n"); 373ab4c0d6aSKatayama Hirofumi MZ return; 374ab4c0d6aSKatayama Hirofumi MZ } 375ab4c0d6aSKatayama Hirofumi MZ 3761b3eed58SDoug Lyons /* This tests ShellExecuteEx with lpIDList for explorer C:\ */ 3771b3eed58SDoug Lyons 3781b3eed58SDoug Lyons /* ITEMIDLIST for CLSID of 'My Computer' followed by PIDL for 'C:\' */ 3791b3eed58SDoug Lyons BYTE lpitemidlist[30] = { 0x14, 0, 0x1f, 0, 0xe0, 0x4f, 0xd0, 0x20, 0xea, 3801b3eed58SDoug Lyons 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0, 0x2b, 0x30, 0x30, 0x9d, // My Computer 3811b3eed58SDoug Lyons 0x8, 0, 0x23, 0x43, 0x3a, 0x5c, 0x5c, 0, 0, 0,}; // C:\\ + NUL-NUL ending 3821b3eed58SDoug Lyons 383ab4c0d6aSKatayama Hirofumi MZ SHELLEXECUTEINFOW ShellExecInfo = { sizeof(ShellExecInfo) }; 3841b3eed58SDoug Lyons ShellExecInfo.fMask = SEE_MASK_IDLIST; 3851b3eed58SDoug Lyons ShellExecInfo.hwnd = NULL; 3861b3eed58SDoug Lyons ShellExecInfo.nShow = SW_SHOWNORMAL; 387ab4c0d6aSKatayama Hirofumi MZ ShellExecInfo.lpIDList = lpitemidlist; 388ab4c0d6aSKatayama Hirofumi MZ BOOL ret = ShellExecuteExW(&ShellExecInfo); 389ab4c0d6aSKatayama Hirofumi MZ ok_int(ret, TRUE); 390ab4c0d6aSKatayama Hirofumi MZ } 3911b3eed58SDoug Lyons 392ab4c0d6aSKatayama Hirofumi MZ static BOOL 393ab4c0d6aSKatayama Hirofumi MZ CreateAppPath(LPCWSTR pszName, LPCWSTR pszValue) 3941b3eed58SDoug Lyons { 395ab4c0d6aSKatayama Hirofumi MZ WCHAR szSubKey[MAX_PATH]; 396ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(szSubKey, _countof(szSubKey), L"%s\\%s", REG_APPPATHS, pszName); 397ab4c0d6aSKatayama Hirofumi MZ 398ab4c0d6aSKatayama Hirofumi MZ LSTATUS error; 399ab4c0d6aSKatayama Hirofumi MZ HKEY hKey; 400ab4c0d6aSKatayama Hirofumi MZ error = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szSubKey, 0, NULL, 0, KEY_WRITE, NULL, 401ab4c0d6aSKatayama Hirofumi MZ &hKey, NULL); 402ab4c0d6aSKatayama Hirofumi MZ if (error != ERROR_SUCCESS) 403ab4c0d6aSKatayama Hirofumi MZ trace("Could not create test key (%lu)\n", error); 404ab4c0d6aSKatayama Hirofumi MZ 405ab4c0d6aSKatayama Hirofumi MZ DWORD cbValue = (lstrlenW(pszValue) + 1) * sizeof(WCHAR); 406ab4c0d6aSKatayama Hirofumi MZ error = RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)pszValue, cbValue); 407ab4c0d6aSKatayama Hirofumi MZ if (error != ERROR_SUCCESS) 408ab4c0d6aSKatayama Hirofumi MZ trace("Could not set value of the test key (%lu)\n", error); 409ab4c0d6aSKatayama Hirofumi MZ 410ab4c0d6aSKatayama Hirofumi MZ RegCloseKey(hKey); 411ab4c0d6aSKatayama Hirofumi MZ 412ab4c0d6aSKatayama Hirofumi MZ return error == ERROR_SUCCESS; 413ab4c0d6aSKatayama Hirofumi MZ } 414ab4c0d6aSKatayama Hirofumi MZ 415ab4c0d6aSKatayama Hirofumi MZ static VOID 416ab4c0d6aSKatayama Hirofumi MZ DeleteAppPath(LPCWSTR pszName) 417ab4c0d6aSKatayama Hirofumi MZ { 418ab4c0d6aSKatayama Hirofumi MZ WCHAR szSubKey[MAX_PATH]; 419ab4c0d6aSKatayama Hirofumi MZ StringCchPrintfW(szSubKey, _countof(szSubKey), L"%s\\%s", REG_APPPATHS, pszName); 420ab4c0d6aSKatayama Hirofumi MZ 421ab4c0d6aSKatayama Hirofumi MZ LSTATUS error = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szSubKey); 422ab4c0d6aSKatayama Hirofumi MZ if (error != ERROR_SUCCESS) 423ab4c0d6aSKatayama Hirofumi MZ trace("Could not remove the test key (%lu)\n", error); 424ab4c0d6aSKatayama Hirofumi MZ } 425ab4c0d6aSKatayama Hirofumi MZ 426ab4c0d6aSKatayama Hirofumi MZ static void TEST_AppPath(void) 427ab4c0d6aSKatayama Hirofumi MZ { 428ab4c0d6aSKatayama Hirofumi MZ if (CreateAppPath(L"app_path_test.bat", s_win_test_exe)) 429ab4c0d6aSKatayama Hirofumi MZ { 430ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"app_path_test.bat"); 431ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_FAILED, L"app_path_test.bat.exe"); 432ab4c0d6aSKatayama Hirofumi MZ DeleteAppPath(L"app_path_test.bat"); 433ab4c0d6aSKatayama Hirofumi MZ } 434ab4c0d6aSKatayama Hirofumi MZ 435ab4c0d6aSKatayama Hirofumi MZ if (CreateAppPath(L"app_path_test.bat.exe", s_sys_test_exe)) 436ab4c0d6aSKatayama Hirofumi MZ { 437ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_FAILED, L"app_path_test.bat"); 438ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntry(__LINE__, TEST_SUCCESS_WITH_PROCESS, L"app_path_test.bat.exe"); 439ab4c0d6aSKatayama Hirofumi MZ DeleteAppPath(L"app_path_test.bat.exe"); 4401b3eed58SDoug Lyons } 4411b3eed58SDoug Lyons } 4421b3eed58SDoug Lyons 443c35a8498SKatayama Hirofumi MZ START_TEST(ShellExecuteEx) 444c35a8498SKatayama Hirofumi MZ { 445ab4c0d6aSKatayama Hirofumi MZ #ifdef _WIN64 446ab4c0d6aSKatayama Hirofumi MZ skip("Win64 is not supported yet\n"); 447ab4c0d6aSKatayama Hirofumi MZ return; 448ab4c0d6aSKatayama Hirofumi MZ #endif 449ab4c0d6aSKatayama Hirofumi MZ 450ab4c0d6aSKatayama Hirofumi MZ if (!TEST_Start()) 451ab4c0d6aSKatayama Hirofumi MZ return; 452ab4c0d6aSKatayama Hirofumi MZ 453ab4c0d6aSKatayama Hirofumi MZ TEST_AppPath(); 454ab4c0d6aSKatayama Hirofumi MZ TEST_DoTestEntries(); 455f80de47cSMark Jansen test_properties(); 4561b3eed58SDoug Lyons test_sei_lpIDList(); 4571b3eed58SDoug Lyons 458ab4c0d6aSKatayama Hirofumi MZ TEST_End(); 459c35a8498SKatayama Hirofumi MZ } 460