2016-11-09 22:13:26 +00:00
/*
* PROJECT : ReactOS api tests
* LICENSE : GPLv2 + - See COPYING in the top level directory
* PURPOSE : Testing ShellExecuteEx
* PROGRAMMER : Yaroslav Veremenko < yaroslav @ veremenko . info >
2021-06-07 23:07:37 +00:00
* Katayama Hirofumi MZ < katayama . hirofumi . mz @ gmail . com >
2016-11-09 22:13:26 +00:00
*/
# include "shelltest.h"
2024-03-19 22:36:14 +00:00
# include "closewnd.h"
2024-03-13 08:09:20 +00:00
# include <pstypes.h>
# include <psfuncs.h>
# include <stdlib.h>
2021-06-07 23:07:37 +00:00
# include <stdio.h>
2024-03-13 08:09:20 +00:00
# include <strsafe.h>
# include <versionhelpers.h>
2024-10-24 14:44:53 +00:00
# include <shellutils.h>
2024-07-19 08:40:36 +00:00
# include "shell32_apitest_sub.h"
2024-03-13 08:09:20 +00:00
static WCHAR s_win_dir [ MAX_PATH ] ;
static WCHAR s_sys_dir [ MAX_PATH ] ;
static WCHAR s_win_notepad [ MAX_PATH ] ;
static WCHAR s_sys_notepad [ MAX_PATH ] ;
static WCHAR s_win_test_exe [ MAX_PATH ] ;
static WCHAR s_sys_test_exe [ MAX_PATH ] ;
static WCHAR s_win_bat_file [ MAX_PATH ] ;
static WCHAR s_sys_bat_file [ MAX_PATH ] ;
static WCHAR s_win_txt_file [ MAX_PATH ] ;
static WCHAR s_sys_txt_file [ MAX_PATH ] ;
static WCHAR s_win_notepad_cmdline [ MAX_PATH ] ;
static WCHAR s_sys_notepad_cmdline [ MAX_PATH ] ;
static WCHAR s_win_test_exe_cmdline [ MAX_PATH ] ;
static WCHAR s_sys_test_exe_cmdline [ MAX_PATH ] ;
static BOOL s_bWow64 ;
# define REG_APPPATHS L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"
typedef enum TEST_RESULT
{
TEST_FAILED ,
TEST_SUCCESS_NO_PROCESS ,
TEST_SUCCESS_WITH_PROCESS ,
} TEST_RESULT ;
2016-11-09 22:13:26 +00:00
2024-03-13 08:09:20 +00:00
typedef struct TEST_ENTRY
2016-11-09 22:13:26 +00:00
{
2024-03-13 08:09:20 +00:00
INT line ;
TEST_RESULT result ;
LPCWSTR lpFile ;
LPCWSTR cmdline ;
} TEST_ENTRY , * PTEST_ENTRY ;
static void
TEST_DoTestEntry ( INT line , TEST_RESULT result , LPCWSTR lpFile , LPCWSTR cmdline = NULL ) ;
2016-11-09 22:13:26 +00:00
2024-03-13 08:09:20 +00:00
static void TEST_DoTestEntries ( void )
2016-11-09 22:13:26 +00:00
{
2024-03-13 08:09:20 +00:00
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , NULL ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_FAILED , L " This is an invalid path. " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_sys_bat_file , NULL ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_sys_test_exe , s_sys_test_exe_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_sys_txt_file , NULL ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_win_bat_file , NULL ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_win_notepad , s_win_notepad_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_win_test_exe , s_win_test_exe_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , s_win_txt_file , NULL ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " notepad " , s_sys_notepad_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " notepad.exe " , s_sys_notepad_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " \" notepad.exe \" " , s_sys_notepad_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " \" notepad \" " , s_sys_notepad_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " test program.exe " , s_sys_test_exe_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " \" test program.exe \" " , s_sys_test_exe_cmdline ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , s_win_dir ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , s_sys_dir ) ;
TEST_DoTestEntry ( __LINE__ , TEST_FAILED , L " shell:ThisIsAnInvalidName " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " ::{20D04FE0-3AEA-1069-A2D8-08002B30309D} " ) ; // My Computer
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D} " ) ; // My Computer (with shell:)
if ( ! IsWindowsVistaOrGreater ( ) )
{
WCHAR szCurDir [ MAX_PATH ] ;
GetCurrentDirectoryW ( _countof ( szCurDir ) , szCurDir ) ;
SetCurrentDirectoryW ( s_sys_dir ) ;
TEST_DoTestEntry ( __LINE__ , TEST_FAILED , L " ::{21EC2020-3AEA-1069-A2DD-08002B30309D} " ) ; // Control Panel (without path)
SetCurrentDirectoryW ( szCurDir ) ;
}
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " ::{20D04FE0-3AEA-1069-A2D8-08002B30309D} \\ ::{21EC2020-3AEA-1069-A2DD-08002B30309D} " ) ; // Control Panel (with path)
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:)
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:AppData " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Common Desktop " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Common Programs " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Common Start Menu " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Common StartUp " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:ControlPanelFolder " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Desktop " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Favorites " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Fonts " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Local AppData " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:My Pictures " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Personal " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Programs " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Recent " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:RecycleBinFolder " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:SendTo " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:Start Menu " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_NO_PROCESS , L " shell:StartUp " ) ;
2016-11-09 22:13:26 +00:00
}
2024-03-13 08:09:20 +00:00
static LPWSTR
getCommandLineFromProcess ( HANDLE hProcess )
2016-11-09 22:13:26 +00:00
{
2024-03-13 08:09:20 +00:00
PEB peb ;
PROCESS_BASIC_INFORMATION info ;
RTL_USER_PROCESS_PARAMETERS Params ;
2024-03-15 14:46:14 +00:00
NTSTATUS Status ;
BOOL ret ;
Status = NtQueryInformationProcess ( hProcess , ProcessBasicInformation , & info , sizeof ( info ) , NULL ) ;
ok_ntstatus ( Status , STATUS_SUCCESS ) ;
ret = ReadProcessMemory ( hProcess , info . PebBaseAddress , & peb , sizeof ( peb ) , NULL ) ;
if ( ! ret )
trace ( " ReadProcessMemory failed (%ld) \n " , GetLastError ( ) ) ;
2022-05-05 20:20:59 +00:00
2024-03-13 08:09:20 +00:00
ReadProcessMemory ( hProcess , peb . ProcessParameters , & Params , sizeof ( Params ) , NULL ) ;
2024-03-15 14:46:14 +00:00
if ( ! ret )
trace ( " ReadProcessMemory failed (%ld) \n " , GetLastError ( ) ) ;
2022-05-05 20:20:59 +00:00
2024-03-13 08:09:20 +00:00
LPWSTR cmdline = Params . CommandLine . Buffer ;
2024-03-15 14:46:14 +00:00
if ( ! cmdline )
trace ( " !cmdline \n " ) ;
SIZE_T cbCmdLine = Params . CommandLine . Length ;
if ( ! cbCmdLine )
trace ( " !cbCmdLine \n " ) ;
LPWSTR pszBuffer = ( LPWSTR ) calloc ( cbCmdLine + sizeof ( WCHAR ) , 1 ) ;
if ( ! pszBuffer )
trace ( " !pszBuffer \n " ) ;
ret = ReadProcessMemory ( hProcess , cmdline , pszBuffer , cbCmdLine , NULL ) ;
if ( ! ret )
trace ( " ReadProcessMemory failed (%ld) \n " , GetLastError ( ) ) ;
pszBuffer [ cbCmdLine / sizeof ( WCHAR ) ] = UNICODE_NULL ;
2024-03-13 08:09:20 +00:00
return pszBuffer ; // needs free()
2016-11-09 22:13:26 +00:00
}
2024-03-13 08:09:20 +00:00
static void TEST_DoTestEntryStruct ( const TEST_ENTRY * pEntry )
2016-11-09 22:13:26 +00:00
{
2024-03-13 08:09:20 +00:00
SHELLEXECUTEINFOW info = { sizeof ( info ) } ;
2024-03-19 22:36:14 +00:00
info . fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_WAITFORINPUTIDLE |
SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC ;
2024-03-13 08:09:20 +00:00
info . hwnd = NULL ;
info . lpVerb = NULL ;
info . lpFile = pEntry - > lpFile ;
info . nShow = SW_SHOWNORMAL ;
2016-11-09 22:13:26 +00:00
2024-03-13 08:09:20 +00:00
BOOL ret = ShellExecuteExW ( & info ) ;
TEST_RESULT result ;
if ( ret & & info . hProcess )
result = TEST_SUCCESS_WITH_PROCESS ;
else if ( ret & & ! info . hProcess )
result = TEST_SUCCESS_NO_PROCESS ;
else
result = TEST_FAILED ;
2016-11-09 22:13:26 +00:00
2024-03-13 08:09:20 +00:00
ok ( pEntry - > result = = result ,
" Line %d: result: %d vs %d \n " , pEntry - > line , pEntry - > result , result ) ;
if ( pEntry - > result = = TEST_SUCCESS_WITH_PROCESS & & pEntry - > cmdline & & ! s_bWow64 )
2016-11-09 22:13:26 +00:00
{
2024-03-13 08:09:20 +00:00
LPWSTR cmdline = getCommandLineFromProcess ( info . hProcess ) ;
if ( ! cmdline )
{
skip ( " !cmdline \n " ) ;
}
else
{
ok ( lstrcmpiW ( pEntry - > cmdline , cmdline ) = = 0 ,
" Line %d: cmdline: '%ls' vs '%ls' \n " , pEntry - > line ,
pEntry - > cmdline , cmdline ) ;
}
TerminateProcess ( info . hProcess , 0xDEADFACE ) ;
free ( cmdline ) ;
2016-11-09 22:13:26 +00:00
}
2024-03-13 08:09:20 +00:00
CloseHandle ( info . hProcess ) ;
2016-11-09 22:13:26 +00:00
}
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
static void
TEST_DoTestEntry ( INT line , TEST_RESULT result , LPCWSTR lpFile , LPCWSTR cmdline )
2021-06-07 23:07:37 +00:00
{
2024-03-13 08:09:20 +00:00
TEST_ENTRY entry = { line , result , lpFile , cmdline } ;
TEST_DoTestEntryStruct ( & entry ) ;
}
static BOOL
enableTokenPrivilege ( LPCWSTR pszPrivilege )
2021-06-07 23:07:37 +00:00
{
2024-03-13 08:09:20 +00:00
HANDLE hToken ;
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , & hToken ) )
return FALSE ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
TOKEN_PRIVILEGES tkp = { 0 } ;
if ( ! LookupPrivilegeValueW ( NULL , pszPrivilege , & tkp . Privileges [ 0 ] . Luid ) )
return FALSE ;
tkp . PrivilegeCount = 1 ;
tkp . Privileges [ 0 ] . Attributes = SE_PRIVILEGE_ENABLED ;
return AdjustTokenPrivileges ( hToken , FALSE , & tkp , 0 , NULL , NULL ) ;
}
static WINDOW_LIST s_List1 , s_List2 ;
static BOOL TEST_Start ( void )
2021-06-07 23:07:37 +00:00
{
2024-03-13 08:09:20 +00:00
// Check Wow64
s_bWow64 = FALSE ;
IsWow64Process ( GetCurrentProcess ( ) , & s_bWow64 ) ;
if ( s_bWow64 )
skip ( " Wow64: Command Line check is skipped \n " ) ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
// getCommandLineFromProcess needs this
enableTokenPrivilege ( SE_DEBUG_NAME ) ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
// s_win_dir
GetWindowsDirectoryW ( s_win_dir , _countof ( s_win_dir ) ) ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
// s_sys_dir
GetSystemDirectoryW ( s_sys_dir , _countof ( s_sys_dir ) ) ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
// s_win_notepad
GetWindowsDirectoryW ( s_win_notepad , _countof ( s_win_notepad ) ) ;
PathAppendW ( s_win_notepad , L " notepad.exe " ) ;
// s_sys_notepad
GetSystemDirectoryW ( s_sys_notepad , _countof ( s_sys_notepad ) ) ;
PathAppendW ( s_sys_notepad , L " notepad.exe " ) ;
2021-06-07 23:07:37 +00:00
// s_win_test_exe
2024-03-13 08:09:20 +00:00
GetWindowsDirectoryW ( s_win_test_exe , _countof ( s_win_test_exe ) ) ;
PathAppendW ( s_win_test_exe , L " test program.exe " ) ;
BOOL ret = CopyFileW ( s_win_notepad , s_win_test_exe , FALSE ) ;
2021-06-07 23:07:37 +00:00
if ( ! ret )
{
skip ( " Please retry with admin rights \n " ) ;
2024-03-13 08:09:20 +00:00
return FALSE ;
2021-06-07 23:07:37 +00:00
}
// s_sys_test_exe
2024-03-13 08:09:20 +00:00
GetSystemDirectoryW ( s_sys_test_exe , _countof ( s_sys_test_exe ) ) ;
PathAppendW ( s_sys_test_exe , L " test program.exe " ) ;
ok_int ( CopyFileW ( s_win_notepad , s_sys_test_exe , FALSE ) , TRUE ) ;
2021-06-07 23:07:37 +00:00
// s_win_bat_file
2024-03-13 08:09:20 +00:00
GetWindowsDirectoryW ( s_win_bat_file , _countof ( s_win_bat_file ) ) ;
PathAppendW ( s_win_bat_file , L " test program.bat " ) ;
FILE * fp = _wfopen ( s_win_bat_file , L " wb " ) ;
2021-06-07 23:07:37 +00:00
fprintf ( fp , " exit /b 3 " ) ;
fclose ( fp ) ;
2024-03-13 08:09:20 +00:00
ok_int ( PathFileExistsW ( s_win_bat_file ) , TRUE ) ;
2021-06-07 23:07:37 +00:00
// s_sys_bat_file
2024-03-13 08:09:20 +00:00
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 " ) ;
2021-06-07 23:07:37 +00:00
fprintf ( fp , " exit /b 4 " ) ;
fclose ( fp ) ;
2024-03-13 08:09:20 +00:00
ok_int ( PathFileExistsW ( s_sys_bat_file ) , TRUE ) ;
2021-06-07 23:07:37 +00:00
// s_win_txt_file
2024-03-13 08:09:20 +00:00
GetWindowsDirectoryW ( s_win_txt_file , _countof ( s_win_txt_file ) ) ;
PathAppendW ( s_win_txt_file , L " test_file.txt " ) ;
fp = _wfopen ( s_win_txt_file , L " wb " ) ;
2021-06-07 23:07:37 +00:00
fclose ( fp ) ;
2024-03-13 08:09:20 +00:00
ok_int ( PathFileExistsW ( s_win_txt_file ) , TRUE ) ;
2021-06-07 23:07:37 +00:00
// s_sys_txt_file
2024-03-13 08:09:20 +00:00
GetSystemDirectoryW ( s_sys_txt_file , _countof ( s_sys_txt_file ) ) ;
PathAppendW ( s_sys_txt_file , L " test_file.txt " ) ;
fp = _wfopen ( s_sys_txt_file , L " wb " ) ;
2021-06-07 23:07:37 +00:00
fclose ( fp ) ;
2024-03-13 08:09:20 +00:00
ok_int ( PathFileExistsW ( s_sys_txt_file ) , TRUE ) ;
2021-06-07 23:07:37 +00:00
2024-03-13 08:09:20 +00:00
// Check .txt settings
WCHAR szPath [ MAX_PATH ] ;
FindExecutableW ( s_sys_txt_file , NULL , szPath ) ;
if ( lstrcmpiW ( PathFindFileNameW ( szPath ) , L " notepad.exe " ) ! = 0 )
2021-06-07 23:07:37 +00:00
{
2024-03-13 08:09:20 +00:00
skip ( " Please associate .txt with notepad.exe before tests \n " ) ;
return FALSE ;
2021-06-07 23:07:37 +00:00
}
2024-03-13 08:09:20 +00:00
// command lines
StringCchPrintfW ( s_win_notepad_cmdline , _countof ( s_win_notepad_cmdline ) ,
L " \" %s \" " , s_win_notepad ) ;
StringCchPrintfW ( s_sys_notepad_cmdline , _countof ( s_sys_notepad_cmdline ) ,
L " \" %s \" " , s_sys_notepad ) ;
StringCchPrintfW ( s_win_test_exe_cmdline , _countof ( s_win_test_exe_cmdline ) ,
L " \" %s \" " , s_win_test_exe ) ;
StringCchPrintfW ( s_sys_test_exe_cmdline , _countof ( s_sys_test_exe_cmdline ) ,
L " \" %s \" " , s_sys_test_exe ) ;
2021-06-07 23:07:37 +00:00
2024-03-19 22:36:14 +00:00
GetWindowList ( & s_List1 ) ;
2022-02-01 22:22:44 +00:00
return TRUE ;
}
2024-03-13 08:09:20 +00:00
static void TEST_End ( void )
2022-02-01 22:22:44 +00:00
{
2024-10-24 14:44:53 +00:00
GetWindowListForClose ( & s_List2 ) ;
2024-03-19 22:36:14 +00:00
CloseNewWindows ( & s_List1 , & s_List2 ) ;
FreeWindowList ( & s_List1 ) ;
FreeWindowList ( & s_List2 ) ;
2024-03-13 08:09:20 +00:00
DeleteFileW ( s_win_test_exe ) ;
DeleteFileW ( s_sys_test_exe ) ;
DeleteFileW ( s_win_txt_file ) ;
DeleteFileW ( s_sys_txt_file ) ;
DeleteFileW ( s_win_bat_file ) ;
DeleteFileW ( s_sys_bat_file ) ;
2022-02-01 22:22:44 +00:00
}
static void test_properties ( )
{
2024-03-13 08:09:20 +00:00
HRESULT hrCoInit = CoInitialize ( NULL ) ;
2022-02-01 22:22:44 +00:00
2024-03-15 14:46:14 +00:00
WCHAR Buffer [ MAX_PATH * 4 ] ;
2022-02-01 22:22:44 +00:00
GetModuleFileNameW ( NULL , Buffer , _countof ( Buffer ) ) ;
2024-03-15 14:46:14 +00:00
SHELLEXECUTEINFOW info = { sizeof ( info ) } ;
2022-02-01 22:22:44 +00:00
info . fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI ;
info . lpVerb = L " properties " ;
info . lpFile = Buffer ;
info . nShow = SW_SHOW ;
BOOL bRet = ShellExecuteExW ( & info ) ;
ok ( bRet , " Failed! (GetLastError(): %d) \n " , ( int ) GetLastError ( ) ) ;
ok_ptr ( info . hInstApp , ( HINSTANCE ) 42 ) ;
WCHAR * Extension = PathFindExtensionW ( Buffer ) ;
if ( Extension )
{
// The inclusion of this depends on the file display settings!
* Extension = UNICODE_NULL ;
}
// Now retry it with the extension cut off
bRet = ShellExecuteExW ( & info ) ;
ok ( bRet , " Failed! (GetLastError(): %d) \n " , ( int ) GetLastError ( ) ) ;
ok_ptr ( info . hInstApp , ( HINSTANCE ) 42 ) ;
// Now retry it with complete garabage
2024-03-13 08:09:20 +00:00
info . lpFile = L " complete garbage, cannot run this! " ;
2022-02-01 22:22:44 +00:00
bRet = ShellExecuteExW ( & info ) ;
2024-03-13 08:09:20 +00:00
ok_int ( bRet , 0 ) ;
2022-02-01 22:22:44 +00:00
ok_ptr ( info . hInstApp , ( HINSTANCE ) 2 ) ;
2024-03-13 08:09:20 +00:00
if ( SUCCEEDED ( hrCoInit ) )
CoUninitialize ( ) ;
2022-02-01 22:22:44 +00:00
}
2023-09-24 20:35:28 +00:00
static void test_sei_lpIDList ( )
{
2024-10-24 14:44:53 +00:00
// Note: SEE_MASK_FLAG_NO_UI prevents the test from blocking with a MessageBox
WCHAR path [ MAX_PATH ] ;
/* This tests ShellExecuteEx with lpIDList for explorer C:\ */
GetSystemDirectoryW ( path , _countof ( path ) ) ;
PathStripToRootW ( path ) ;
LPITEMIDLIST pidl = ILCreateFromPathW ( path ) ;
if ( ! pidl )
2024-03-13 08:09:20 +00:00
{
2024-10-24 14:44:53 +00:00
skip ( " Unable to initialize test \n " ) ;
2024-03-13 08:09:20 +00:00
return ;
}
SHELLEXECUTEINFOW ShellExecInfo = { sizeof ( ShellExecInfo ) } ;
2023-09-24 20:35:28 +00:00
ShellExecInfo . nShow = SW_SHOWNORMAL ;
2024-10-24 14:44:53 +00:00
ShellExecInfo . fMask = SEE_MASK_IDLIST | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT ;
ShellExecInfo . lpIDList = pidl ;
2024-03-13 08:09:20 +00:00
BOOL ret = ShellExecuteExW ( & ShellExecInfo ) ;
ok_int ( ret , TRUE ) ;
2024-10-24 14:44:53 +00:00
ILFree ( pidl ) ;
/* This tests ShellExecuteEx with lpIDList going through IContextMenu */
CCoInit ComInit ;
pidl = SHCloneSpecialIDList ( NULL , CSIDL_PROFILE , TRUE ) ;
if ( ! pidl )
{
skip ( " Unable to initialize test \n " ) ;
return ;
}
ShellExecInfo . fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT ;
ShellExecInfo . lpIDList = pidl ;
ret = ShellExecuteExW ( & ShellExecInfo ) ;
ok_int ( ret , TRUE ) ;
ILFree ( pidl ) ;
2024-03-13 08:09:20 +00:00
}
static BOOL
CreateAppPath ( LPCWSTR pszName , LPCWSTR pszValue )
{
WCHAR szSubKey [ MAX_PATH ] ;
StringCchPrintfW ( szSubKey , _countof ( szSubKey ) , L " %s \\ %s " , REG_APPPATHS , pszName ) ;
LSTATUS error ;
HKEY hKey ;
error = RegCreateKeyExW ( HKEY_LOCAL_MACHINE , szSubKey , 0 , NULL , 0 , KEY_WRITE , NULL ,
& hKey , NULL ) ;
if ( error ! = ERROR_SUCCESS )
trace ( " Could not create test key (%lu) \n " , error ) ;
DWORD cbValue = ( lstrlenW ( pszValue ) + 1 ) * sizeof ( WCHAR ) ;
error = RegSetValueExW ( hKey , NULL , 0 , REG_SZ , ( LPBYTE ) pszValue , cbValue ) ;
if ( error ! = ERROR_SUCCESS )
trace ( " Could not set value of the test key (%lu) \n " , error ) ;
RegCloseKey ( hKey ) ;
return error = = ERROR_SUCCESS ;
}
static VOID
DeleteAppPath ( LPCWSTR pszName )
{
WCHAR szSubKey [ MAX_PATH ] ;
StringCchPrintfW ( szSubKey , _countof ( szSubKey ) , L " %s \\ %s " , REG_APPPATHS , pszName ) ;
LSTATUS error = RegDeleteKeyW ( HKEY_LOCAL_MACHINE , szSubKey ) ;
if ( error ! = ERROR_SUCCESS )
trace ( " Could not remove the test key (%lu) \n " , error ) ;
}
static void TEST_AppPath ( void )
{
if ( CreateAppPath ( L " app_path_test.bat " , s_win_test_exe ) )
{
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " app_path_test.bat " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_FAILED , L " app_path_test.bat.exe " ) ;
DeleteAppPath ( L " app_path_test.bat " ) ;
}
if ( CreateAppPath ( L " app_path_test.bat.exe " , s_sys_test_exe ) )
2023-09-24 20:35:28 +00:00
{
2024-03-13 08:09:20 +00:00
TEST_DoTestEntry ( __LINE__ , TEST_FAILED , L " app_path_test.bat " ) ;
TEST_DoTestEntry ( __LINE__ , TEST_SUCCESS_WITH_PROCESS , L " app_path_test.bat.exe " ) ;
DeleteAppPath ( L " app_path_test.bat.exe " ) ;
2023-09-24 20:35:28 +00:00
}
}
2024-07-19 08:40:36 +00:00
static void test_DoInvalidDir ( void )
{
WCHAR szSubProgram [ MAX_PATH ] ;
if ( ! FindSubProgram ( szSubProgram , _countof ( szSubProgram ) ) )
{
skip ( " shell32_apitest_sub.exe not found \n " ) ;
return ;
}
DWORD dwExitCode ;
SHELLEXECUTEINFOW sei = { sizeof ( sei ) , SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS } ;
sei . lpFile = szSubProgram ;
sei . lpParameters = L " TEST " ;
sei . nShow = SW_SHOWNORMAL ;
// Test invalid path on sei.lpDirectory
WCHAR szInvalidPath [ MAX_PATH ] = L " M: \\ This is an invalid path \n " ;
sei . lpDirectory = szInvalidPath ;
ok_int ( ShellExecuteExW ( & sei ) , TRUE ) ;
WaitForSingleObject ( sei . hProcess , 20 * 1000 ) ;
GetExitCodeProcess ( sei . hProcess , & dwExitCode ) ;
ok_long ( dwExitCode , 0 ) ;
CloseHandle ( sei . hProcess ) ;
}
2021-06-07 23:07:37 +00:00
START_TEST ( ShellExecuteEx )
{
2024-03-13 08:09:20 +00:00
# ifdef _WIN64
skip ( " Win64 is not supported yet \n " ) ;
return ;
# endif
2022-02-13 08:45:08 +00:00
2024-03-13 08:09:20 +00:00
if ( ! TEST_Start ( ) )
return ;
2023-09-24 20:35:28 +00:00
2024-03-13 08:09:20 +00:00
TEST_AppPath ( ) ;
TEST_DoTestEntries ( ) ;
test_properties ( ) ;
2023-09-24 20:35:28 +00:00
test_sei_lpIDList ( ) ;
2024-07-19 08:40:36 +00:00
test_DoInvalidDir ( ) ;
2023-09-24 20:35:28 +00:00
2024-03-13 08:09:20 +00:00
TEST_End ( ) ;
2021-06-07 23:07:37 +00:00
}