Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692/* * PROJECT: ReactOS API tests * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Test for ShellExecCmdLine * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */#include "shelltest.h"#include <shlwapi.h>#include <strsafe.h>#include <versionhelpers.h>#include "shell32_apitest_sub.h"#include "closewnd.h"
#define NDEBUG#include <debug.h>#include <stdio.h>
#ifndef SECL_NO_UI #define SECL_NO_UI 0x2 #define SECL_LOG_USAGE 0x8 #define SECL_USE_IDLIST 0x10 #define SECL_ALLOW_NONEXE 0x20 #define SECL_RUNAS 0x40#endif
#define ShellExecCmdLine proxy_ShellExecCmdLine
#define shell32_hInstance GetModuleHandle(NULL)#define IDS_FILE_NOT_FOUND (-1)
static const WCHAR wszExe[] = L".exe";static const WCHAR wszCom[] = L".com";
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source){ *target = (WCHAR *)SHAlloc((lstrlenW(source) + 1) * sizeof(WCHAR) ); lstrcpyW(*target, source);}
// NOTE: You have to sync the following code to dll/win32/shell32/shlexec.cpp.static LPCWSTRSplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0){ LPCWSTR pch; size_t ich = 0; if (*psz == L'"') { // 1st argument is quoted. the string in quotes is quoted 1st argument. // [pch] --> [pszArg0+ich] for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch) { if (*pch == L'"' && pch[1] == L'"') { // doubled double quotations found! pszArg0[ich] = L'"'; } else if (*pch == L'"') { // single double quotation found! ++pch; break; } else { // otherwise pszArg0[ich] = *pch; } } } else { // 1st argument is unquoted. non-space sequence is 1st argument. // [pch] --> [pszArg0+ich] for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch) { pszArg0[ich] = *pch; } } pszArg0[ich] = 0;
// skip space while (iswspace(*pch)) ++pch;
return pch;}
HRESULT WINAPI ShellExecCmdLine( HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags){ SHELLEXECUTEINFOW info; DWORD dwSize, dwError, dwType, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; LPCWSTR pszVerb = NULL; WCHAR szFile[MAX_PATH], szFile2[MAX_PATH]; HRESULT hr; LPCWSTR pchParams; LPWSTR lpCommand = NULL;
if (pwszCommand == NULL) RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 1, (ULONG_PTR*)pwszCommand);
__SHCloneStrW(&lpCommand, pwszCommand); StrTrimW(lpCommand, L" \t");
if (dwSeclFlags & SECL_NO_UI) dwFlags |= SEE_MASK_FLAG_NO_UI; if (dwSeclFlags & SECL_LOG_USAGE) dwFlags |= SEE_MASK_FLAG_LOG_USAGE; if (dwSeclFlags & SECL_USE_IDLIST) dwFlags |= SEE_MASK_INVOKEIDLIST;
if (dwSeclFlags & SECL_RUNAS) { dwSize = 0; hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize); if (SUCCEEDED(hr) && dwSize != 0) { pszVerb = L"runas"; } }
if (UrlIsFileUrlW(lpCommand)) { StringCchCopyW(szFile, _countof(szFile), lpCommand); pchParams = NULL; } else { pchParams = SplitParams(lpCommand, szFile, _countof(szFile)); if (szFile[0] != UNICODE_NULL && szFile[1] == L':' && szFile[2] == UNICODE_NULL) { PathAddBackslashW(szFile); }
WCHAR szCurDir[MAX_PATH]; GetCurrentDirectoryW(_countof(szCurDir), szCurDir); if (pwszStartDir) { SetCurrentDirectoryW(pwszStartDir); }
if (PathIsRelativeW(szFile) && GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) && PathFileExistsW(szFile2)) { StringCchCopyW(szFile, _countof(szFile), szFile2); } else if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) || SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) || SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL)) { StringCchCopyW(szFile, _countof(szFile), szFile2); } else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL)) { StringCchCopyW(szFile, _countof(szFile), szFile2); pchParams = NULL; }
if (pwszStartDir) { SetCurrentDirectoryW(szCurDir); }
if (!(dwSeclFlags & SECL_ALLOW_NONEXE)) { if (!GetBinaryTypeW(szFile, &dwType)) { SHFree(lpCommand);
if (!(dwSeclFlags & SECL_NO_UI)) { WCHAR szText[128 + MAX_PATH], szFormat[128]; LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); StringCchPrintfW(szText, _countof(szText), szFormat, szFile); MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); } return CO_E_APPNOTFOUND; } } else { if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES) { SHFree(lpCommand);
if (!(dwSeclFlags & SECL_NO_UI)) { WCHAR szText[128 + MAX_PATH], szFormat[128]; LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); StringCchPrintfW(szText, _countof(szText), szFormat, szFile); MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); } return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } } }
ZeroMemory(&info, sizeof(info)); info.cbSize = sizeof(info); info.fMask = dwFlags; info.hwnd = hwnd; info.lpVerb = pszVerb; info.lpFile = szFile; info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL; info.lpDirectory = pwszStartDir; info.nShow = nShow; if (ShellExecuteExW(&info)) { if (info.lpIDList) CoTaskMemFree(info.lpIDList);
SHFree(lpCommand);
return S_OK; }
dwError = GetLastError();
SHFree(lpCommand);
return HRESULT_FROM_WIN32(dwError);}
#undef ShellExecCmdLine
typedef HRESULT (WINAPI *SHELLEXECCMDLINE)(HWND, LPCWSTR, LPCWSTR, INT, LPVOID, DWORD);SHELLEXECCMDLINE g_pShellExecCmdLine = NULL;
typedef struct TEST_ENTRY{ INT lineno; BOOL result; BOOL bAllowNonExe; LPCWSTR pwszCommand; LPCWSTR pwszStartDir;} TEST_ENTRY;
static WCHAR s_sub_program[MAX_PATH];static WCHAR s_win_test_exe[MAX_PATH];static WCHAR s_sys_bat_file[MAX_PATH];static WCHAR s_cur_dir[MAX_PATH];
static const TEST_ENTRY s_entries_1[] ={ // NULL { __LINE__, 0xBADFACE, FALSE, NULL, NULL }, { __LINE__, 0xBADFACE, FALSE, NULL, L"." }, { __LINE__, 0xBADFACE, FALSE, NULL, L"system32" }, { __LINE__, 0xBADFACE, FALSE, NULL, L"C:\\Program Files" }, { __LINE__, 0xBADFACE, TRUE, NULL, NULL }, { __LINE__, 0xBADFACE, TRUE, NULL, L"." }, { __LINE__, 0xBADFACE, TRUE, NULL, L"system32" }, { __LINE__, 0xBADFACE, TRUE, NULL, L"C:\\Program Files" }, // notepad { __LINE__, TRUE, FALSE, L"notepad", NULL }, { __LINE__, TRUE, FALSE, L"notepad", L"." }, { __LINE__, TRUE, FALSE, L"notepad", L"system32" }, { __LINE__, TRUE, FALSE, L"notepad", L"C:\\Program Files" }, { __LINE__, TRUE, FALSE, L"notepad \"Test File.txt\"", NULL }, { __LINE__, TRUE, FALSE, L"notepad \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"notepad", NULL }, { __LINE__, TRUE, TRUE, L"notepad", L"." }, { __LINE__, TRUE, TRUE, L"notepad", L"system32" }, { __LINE__, TRUE, TRUE, L"notepad", L"C:\\Program Files" }, { __LINE__, TRUE, TRUE, L"notepad \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"notepad \"Test File.txt\"", L"." }, // notepad.exe { __LINE__, TRUE, FALSE, L"notepad.exe", NULL }, { __LINE__, TRUE, FALSE, L"notepad.exe", L"." }, { __LINE__, TRUE, FALSE, L"notepad.exe", L"system32" }, { __LINE__, TRUE, FALSE, L"notepad.exe", L"C:\\Program Files" }, { __LINE__, TRUE, FALSE, L"notepad.exe \"Test File.txt\"", NULL }, { __LINE__, TRUE, FALSE, L"notepad.exe \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"notepad.exe", NULL }, { __LINE__, TRUE, TRUE, L"notepad.exe", L"." }, { __LINE__, TRUE, TRUE, L"notepad.exe", L"system32" }, { __LINE__, TRUE, TRUE, L"notepad.exe", L"C:\\Program Files" }, { __LINE__, TRUE, TRUE, L"notepad.exe \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"notepad.exe \"Test File.txt\"", L"." }, // C:\notepad.exe { __LINE__, FALSE, FALSE, L"C:\\notepad.exe", NULL }, { __LINE__, FALSE, FALSE, L"C:\\notepad.exe", L"." }, { __LINE__, FALSE, FALSE, L"C:\\notepad.exe", L"system32" }, { __LINE__, FALSE, FALSE, L"C:\\notepad.exe", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"C:\\notepad.exe \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"C:\\notepad.exe \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe", NULL }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe", L"." }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe", L"system32" }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"C:\\notepad.exe \"Test File.txt\"", L"." }, // "notepad" { __LINE__, TRUE, FALSE, L"\"notepad\"", NULL }, { __LINE__, TRUE, FALSE, L"\"notepad\"", L"." }, { __LINE__, TRUE, FALSE, L"\"notepad\"", L"system32" }, { __LINE__, TRUE, FALSE, L"\"notepad\"", L"C:\\Program Files" }, { __LINE__, TRUE, FALSE, L"\"notepad\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, FALSE, L"\"notepad\" \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"notepad\"", NULL }, { __LINE__, TRUE, TRUE, L"\"notepad\"", L"." }, { __LINE__, TRUE, TRUE, L"\"notepad\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"notepad\"", L"C:\\Program Files" }, { __LINE__, TRUE, TRUE, L"\"notepad\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"notepad\" \"Test File.txt\"", L"." }, // "notepad.exe" { __LINE__, TRUE, FALSE, L"\"notepad.exe\"", NULL }, { __LINE__, TRUE, FALSE, L"\"notepad.exe\"", L"." }, { __LINE__, TRUE, FALSE, L"\"notepad.exe\"", L"system32" }, { __LINE__, TRUE, FALSE, L"\"notepad.exe\"", L"C:\\Program Files" }, { __LINE__, TRUE, FALSE, L"\"notepad.exe\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, FALSE, L"\"notepad.exe\" \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\"", NULL }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\"", L"." }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\"", L"C:\\Program Files" }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"notepad.exe\" \"Test File.txt\"", L"." }, // test program { __LINE__, FALSE, FALSE, L"test program", NULL }, { __LINE__, FALSE, FALSE, L"test program", L"." }, { __LINE__, FALSE, FALSE, L"test program", L"system32" }, { __LINE__, FALSE, FALSE, L"test program", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"test program \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"test program \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"test program", NULL }, { __LINE__, FALSE, TRUE, L"test program", L"." }, { __LINE__, FALSE, TRUE, L"test program", L"system32" }, { __LINE__, FALSE, TRUE, L"test program", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"test program \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"test program \"Test File.txt\"", L"." }, // test program.exe { __LINE__, FALSE, FALSE, L"test program.exe", NULL }, { __LINE__, FALSE, FALSE, L"test program.exe", L"." }, { __LINE__, FALSE, FALSE, L"test program.exe", L"system32" }, { __LINE__, FALSE, FALSE, L"test program.exe", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"test program.exe \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"test program.exe \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"test program.exe", NULL }, { __LINE__, FALSE, TRUE, L"test program.exe", L"." }, { __LINE__, FALSE, TRUE, L"test program.exe", L"system32" }, { __LINE__, FALSE, TRUE, L"test program.exe", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"test program.exe \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"test program.exe \"Test File.txt\"", L"." }, // test program.bat { __LINE__, FALSE, FALSE, L"test program.bat", NULL }, { __LINE__, FALSE, FALSE, L"test program.bat", L"." }, { __LINE__, FALSE, FALSE, L"test program.bat", L"system32" }, { __LINE__, FALSE, FALSE, L"test program.bat", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"test program.bat \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"test program.bat \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"test program.bat", NULL }, { __LINE__, FALSE, TRUE, L"test program.bat", L"." }, { __LINE__, FALSE, TRUE, L"test program.bat", L"system32" }, { __LINE__, FALSE, TRUE, L"test program.bat", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"test program.bat \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"test program.bat \"Test File.txt\"", L"." }, // "test program" { __LINE__, FALSE, FALSE, L"\"test program\"", NULL }, { __LINE__, FALSE, FALSE, L"\"test program\"", L"." }, { __LINE__, FALSE, FALSE, L"\"test program\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"test program\"", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"\"test program\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"test program\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"\"test program\"", NULL }, { __LINE__, FALSE, TRUE, L"\"test program\"", L"." }, { __LINE__, FALSE, TRUE, L"\"test program\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"test program\"", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"\"test program\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"test program\" \"Test File.txt\"", L"." }, // "test program.exe" { __LINE__, TRUE, FALSE, L"\"test program.exe\"", NULL }, { __LINE__, TRUE, FALSE, L"\"test program.exe\"", L"." }, { __LINE__, TRUE, FALSE, L"\"test program.exe\"", L"system32" }, { __LINE__, TRUE, FALSE, L"\"test program.exe\"", L"C:\\Program Files" }, { __LINE__, TRUE, FALSE, L"\"test program.exe\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, FALSE, L"\"test program.exe\" \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"test program.exe\"", NULL }, { __LINE__, TRUE, TRUE, L"\"test program.exe\"", L"." }, { __LINE__, TRUE, TRUE, L"\"test program.exe\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"test program.exe\"", L"C:\\Program Files" }, { __LINE__, TRUE, TRUE, L"\"test program.exe\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"test program.exe\" \"Test File.txt\"", L"." }, // "test program.bat" { __LINE__, FALSE, FALSE, L"\"test program.bat\"", NULL }, { __LINE__, FALSE, FALSE, L"\"test program.bat\"", L"." }, { __LINE__, FALSE, FALSE, L"\"test program.bat\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"test program.bat\"", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"\"test program.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"test program.bat\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"\"test program.bat\"", NULL }, { __LINE__, FALSE, TRUE, L"\"test program.bat\"", L"." }, { __LINE__, FALSE, TRUE, L"\"test program.bat\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"test program.bat\"", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"\"test program.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"test program.bat\" \"Test File.txt\"", L"." }, // invalid program { __LINE__, FALSE, FALSE, L"invalid program", NULL }, { __LINE__, FALSE, FALSE, L"invalid program", L"." }, { __LINE__, FALSE, FALSE, L"invalid program", L"system32" }, { __LINE__, FALSE, FALSE, L"invalid program", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"invalid program \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"invalid program \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"invalid program", NULL }, { __LINE__, FALSE, TRUE, L"invalid program", L"." }, { __LINE__, FALSE, TRUE, L"invalid program", L"system32" }, { __LINE__, FALSE, TRUE, L"invalid program", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"invalid program \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"invalid program \"Test File.txt\"", L"." }, // \"invalid program.exe\" { __LINE__, FALSE, FALSE, L"\"invalid program.exe\"", NULL }, { __LINE__, FALSE, FALSE, L"\"invalid program.exe\"", L"." }, { __LINE__, FALSE, FALSE, L"\"invalid program.exe\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"invalid program.exe\"", L"C:\\Program Files" }, { __LINE__, FALSE, FALSE, L"\"invalid program.exe\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"invalid program.exe\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\"", NULL }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\"", L"." }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\"", L"C:\\Program Files" }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"invalid program.exe\" \"Test File.txt\"", L"." }, // My Documents { __LINE__, TRUE, TRUE, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL }, { __LINE__, TRUE, TRUE, L"shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL }, // shell:sendto { __LINE__, TRUE, TRUE, L"shell:sendto", NULL }, // https://google.com { __LINE__, TRUE, FALSE, L"https://google.com", NULL }, { __LINE__, TRUE, TRUE, L"https://google.com", NULL }, // Test File 1.txt { __LINE__, FALSE, FALSE, L"Test File 1.txt", NULL }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", L"." }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", L"system32" }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL }, // { __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // Fails on Vista, 7, 8.1 { __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" }, { __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 1.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", s_cur_dir }, // Test File 2.bat { __LINE__, FALSE, FALSE, L"Test File 2.bat", NULL }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", L"." }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", L"system32" }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", NULL }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", L"." }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", L"system32" }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", NULL }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", L"." }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", s_cur_dir },};
static const TEST_ENTRY s_entries_2[] ={ // Test File 1.txt (with setting path) { __LINE__, FALSE, FALSE, L"Test File 1.txt", NULL }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", L"." }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", L"system32" }, { __LINE__, FALSE, FALSE, L"Test File 1.txt", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\"", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL }, // { __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // Fails on Vista, 7, 8.1 { __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" }, { __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", s_cur_dir }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\" \"Test File.txt\"", s_cur_dir }, // Test File 2.bat (with setting path) { __LINE__, FALSE, FALSE, L"Test File 2.bat", NULL }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", L"." }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", L"system32" }, { __LINE__, FALSE, FALSE, L"Test File 2.bat", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\"", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 2.bat\" \"Test File.txt\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", NULL }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", L"." }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", L"system32" }, { __LINE__, FALSE, TRUE, L"Test File 2.bat", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", NULL }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", L"." }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\"", s_cur_dir }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", s_cur_dir },};
static void DoEntry(const TEST_ENTRY *pEntry){ HRESULT hr; DWORD dwSeclFlags; BOOL result;
if (pEntry->bAllowNonExe) dwSeclFlags = SECL_NO_UI | SECL_ALLOW_NONEXE; else dwSeclFlags = SECL_NO_UI;
_SEH2_TRY { if (IsReactOS()) { hr = proxy_ShellExecCmdLine(NULL, pEntry->pwszCommand, pEntry->pwszStartDir, SW_SHOWNORMAL, NULL, dwSeclFlags); } else { hr = (*g_pShellExecCmdLine)(NULL, pEntry->pwszCommand, pEntry->pwszStartDir, SW_SHOWNORMAL, NULL, dwSeclFlags); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { hr = 0xBADFACE; } _SEH2_END;
if (hr == 0xBADFACE) result = hr; else result = (hr == S_OK);
ok(result == pEntry->result, "Line %d: result expected %d, was %d\n", pEntry->lineno, pEntry->result, result);}
static WINDOW_LIST s_List1, s_List2;
static VOID TEST_ShellExecCmdLine(VOID){ GetWindowList(&s_List1);
// do tests for (size_t i = 0; i < _countof(s_entries_1); ++i) { DoEntry(&s_entries_1[i]); } SetEnvironmentVariableW(L"PATH", s_cur_dir); for (size_t i = 0; i < _countof(s_entries_2); ++i) { DoEntry(&s_entries_2[i]); }
// Execution can be asynchronous; you have to wait for it to finish. Sleep(2000);
// Close newly-opened window(s) GetWindowList(&s_List2); CloseNewWindows(&s_List1, &s_List2); FreeWindowList(&s_List1); FreeWindowList(&s_List2);}
START_TEST(ShellExecCmdLine){ using namespace std;
if (!IsReactOS()) { if (!IsWindowsVistaOrGreater()) { skip("ShellExecCmdLine is not available on this platform\n"); return; }
HMODULE hShell32 = GetModuleHandleA("shell32"); g_pShellExecCmdLine = (SHELLEXECCMDLINE)GetProcAddress(hShell32, (LPCSTR)(INT_PTR)265); if (!g_pShellExecCmdLine) { skip("ShellExecCmdLine is not found\n"); return; } }
if (!FindSubProgram(s_sub_program, _countof(s_sub_program))) { skip("shell32_apitest_sub.exe is not found\n"); return; }
// s_win_test_exe GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe)); PathAppendW(s_win_test_exe, L"test program.exe"); SetFileAttributesW(s_win_test_exe, FILE_ATTRIBUTE_NORMAL); // Clear readonly flag if it exists. BOOL ret = CopyFileW(s_sub_program, s_win_test_exe, FALSE); if (!ret) { skip("Cannot copy test files to the system root directory. (Error: %lu)\n", GetLastError()); return; }
FILE *fp;
// s_sys_bat_file GetSystemDirectoryW(s_sys_bat_file, _countof(s_sys_bat_file)); PathAppendW(s_sys_bat_file, L"test program.bat"); fp = _wfopen(s_sys_bat_file, L"wb"); fclose(fp); ok_int(PathFileExistsW(s_sys_bat_file), TRUE);
// "Test File 1.txt" fp = fopen("Test File 1.txt", "wb"); ok(fp != NULL, "failed to create a test file\n"); fclose(fp); ok_int(PathFileExistsA("Test File 1.txt"), TRUE);
// "Test File 2.bat" fp = fopen("Test File 2.bat", "wb"); ok(fp != NULL, "failed to create a test file\n"); fclose(fp); ok_int(PathFileExistsA("Test File 2.bat"), TRUE);
// s_cur_dir GetCurrentDirectoryW(_countof(s_cur_dir), s_cur_dir);
TEST_ShellExecCmdLine();
// Some process can lock the file of s_win_test_exe Sleep(1000);
// clean up SetFileAttributesW(s_win_test_exe, FILE_ATTRIBUTE_NORMAL); // Clear readonly flag ok(DeleteFileW(s_win_test_exe), "Failed to delete \"%S\".\n", s_win_test_exe); ok(DeleteFileW(s_sys_bat_file), "Failed to delete \"%S\".\n", s_sys_bat_file); ok(DeleteFileA("Test File 1.txt"), "Failed to delete \"Test File 1.txt\".\n"); ok(DeleteFileA("Test File 2.bat"), "Failed to delete \"Test File 2.bat\".\n");}