1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) 4 * PURPOSE: Test for FindExecutable 5 * COPYRIGHT: Copyright 2021-2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 8 #include "shelltest.h" 9 #include <stdio.h> 10 #include <shlwapi.h> 11 12 typedef struct TEST_ENTRY 13 { 14 INT lineno; 15 UINT ret; // SE_ERR_NOASSOC, SE_ERR_FNF, or 0xBEEFCAFE (success). 16 LPCSTR file; 17 LPCSTR dir; 18 LPCSTR result; 19 } TEST_ENTRY; 20 21 static char s_win_dir[MAX_PATH]; 22 static char s_win_notepad[MAX_PATH]; 23 static char s_sys_notepad[MAX_PATH]; 24 static char s_win_test_exe[MAX_PATH]; 25 static char s_sys_test_exe[MAX_PATH]; 26 static char s_win_bat_file[MAX_PATH]; 27 static char s_sys_bat_file[MAX_PATH]; 28 static char s_win_txt_file[MAX_PATH]; 29 static char s_sys_txt_file[MAX_PATH]; 30 31 #define DIR_0 NULL 32 #define DIR_1 "." 33 #define DIR_2 ".." 34 #define DIR_3 s_win_dir 35 #define DIR_4 "(invalid)" 36 37 static const TEST_ENTRY s_entries[] = 38 { 39 { __LINE__, 0xBEEFCAFE, "notepad", DIR_0, s_sys_notepad }, 40 { __LINE__, 0xBEEFCAFE, "notepad", DIR_1, s_sys_notepad }, 41 { __LINE__, 0xBEEFCAFE, "notepad", DIR_2, s_sys_notepad }, 42 { __LINE__, 0xBEEFCAFE, "notepad", DIR_3, s_win_notepad }, 43 { __LINE__, 0xBEEFCAFE, "notepad", DIR_4, s_sys_notepad }, 44 { __LINE__, SE_ERR_FNF, " notepad", DIR_0, "" }, 45 { __LINE__, SE_ERR_FNF, " notepad", DIR_1, "" }, 46 { __LINE__, SE_ERR_FNF, " notepad", DIR_2, "" }, 47 { __LINE__, SE_ERR_FNF, " notepad", DIR_3, "" }, 48 { __LINE__, SE_ERR_FNF, " notepad", DIR_4, "" }, 49 { __LINE__, SE_ERR_FNF, "notepad ", DIR_0, "" }, 50 { __LINE__, SE_ERR_FNF, "notepad ", DIR_1, "" }, 51 { __LINE__, SE_ERR_FNF, "notepad ", DIR_2, "" }, 52 { __LINE__, SE_ERR_FNF, "notepad ", DIR_3, "" }, 53 { __LINE__, SE_ERR_FNF, "notepad ", DIR_4, "" }, 54 { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_0, s_sys_notepad }, 55 { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_1, s_sys_notepad }, 56 { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_2, s_sys_notepad }, 57 { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_3, s_win_notepad }, 58 { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_4, s_sys_notepad }, 59 { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_0, s_sys_notepad }, 60 { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_1, s_sys_notepad }, 61 { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_2, s_sys_notepad }, 62 { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_3, s_win_notepad }, 63 { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_4, s_sys_notepad }, 64 { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_0, "" }, 65 { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_1, "" }, 66 { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_2, "" }, 67 { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_3, "" }, 68 { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_4, "" }, 69 { __LINE__, SE_ERR_FNF, "C:\\notepad.exe", DIR_0, "" }, 70 { __LINE__, SE_ERR_FNF, "C:\\notepad.exe", DIR_1, "" }, 71 { __LINE__, SE_ERR_FNF, "C:\\notepad.exe", DIR_2, "" }, 72 { __LINE__, SE_ERR_FNF, "C:\\notepad.exe", DIR_3, "" }, 73 { __LINE__, SE_ERR_FNF, "C:\\notepad.exe", DIR_4, "" }, 74 { __LINE__, SE_ERR_FNF, ".\\notepad.exe", DIR_0, "" }, 75 { __LINE__, SE_ERR_FNF, ".\\notepad.exe", DIR_1, "" }, 76 { __LINE__, SE_ERR_FNF, ".\\notepad.exe", DIR_2, "" }, 77 { __LINE__, 0xBEEFCAFE, ".\\notepad.exe", DIR_3, s_win_notepad }, 78 { __LINE__, SE_ERR_FNF, ".\\notepad.exe", DIR_4, "" }, 79 { __LINE__, SE_ERR_FNF, "system32\\notepad.exe", DIR_0, "" }, 80 { __LINE__, SE_ERR_FNF, "system32\\notepad.exe", DIR_1, "" }, 81 { __LINE__, SE_ERR_FNF, "system32\\notepad.exe", DIR_2, "" }, 82 { __LINE__, 0xBEEFCAFE, "system32\\notepad.exe", DIR_3, s_sys_notepad }, 83 { __LINE__, SE_ERR_FNF, "system32\\notepad.exe", DIR_4, "" }, 84 { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_0, s_win_notepad }, 85 { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_1, s_win_notepad }, 86 { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_2, s_win_notepad }, 87 { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_3, s_win_notepad }, 88 { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_4, s_win_notepad }, 89 { __LINE__, 0xBEEFCAFE, "test program", DIR_0, s_sys_test_exe }, 90 { __LINE__, 0xBEEFCAFE, "test program", DIR_1, s_sys_test_exe }, 91 { __LINE__, 0xBEEFCAFE, "test program", DIR_2, s_sys_test_exe }, 92 { __LINE__, 0xBEEFCAFE, "test program", DIR_3, s_win_test_exe }, 93 { __LINE__, 0xBEEFCAFE, "test program", DIR_4, s_sys_test_exe }, 94 { __LINE__, SE_ERR_FNF, " test program", DIR_0, "" }, 95 { __LINE__, SE_ERR_FNF, " test program", DIR_1, "" }, 96 { __LINE__, SE_ERR_FNF, " test program", DIR_2, "" }, 97 { __LINE__, SE_ERR_FNF, " test program", DIR_3, "" }, 98 { __LINE__, SE_ERR_FNF, " test program", DIR_4, "" }, 99 { __LINE__, SE_ERR_FNF, "test program ", DIR_0, "" }, 100 { __LINE__, SE_ERR_FNF, "test program ", DIR_1, "" }, 101 { __LINE__, SE_ERR_FNF, "test program ", DIR_2, "" }, 102 { __LINE__, SE_ERR_FNF, "test program ", DIR_3, "" }, 103 { __LINE__, SE_ERR_FNF, "test program ", DIR_4, "" }, 104 { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_0, s_sys_test_exe }, 105 { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_1, s_sys_test_exe }, 106 { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_2, s_sys_test_exe }, 107 { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_3, s_win_test_exe }, 108 { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_4, s_sys_test_exe }, 109 { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_0, s_sys_test_exe }, 110 { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_1, s_sys_test_exe }, 111 { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_2, s_sys_test_exe }, 112 { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_3, s_win_test_exe }, 113 { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_4, s_sys_test_exe }, 114 { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_0, s_sys_test_exe }, 115 { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_1, s_sys_test_exe }, 116 { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_2, s_sys_test_exe }, 117 { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_3, s_win_test_exe }, 118 { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_4, s_sys_test_exe }, 119 { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_0, "" }, 120 { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_1, "" }, 121 { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_2, "" }, 122 { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_3, "" }, 123 { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_4, "" }, 124 { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_0, "" }, 125 { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_1, "" }, 126 { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_2, "" }, 127 { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_3, "" }, 128 { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_4, "" }, 129 { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_0, s_sys_bat_file }, 130 { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_1, s_sys_bat_file }, 131 { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_2, s_sys_bat_file }, 132 { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_3, s_win_bat_file }, 133 { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_4, s_sys_bat_file }, 134 { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_0, "" }, 135 { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_1, "" }, 136 { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_2, "" }, 137 { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_3, "" }, 138 { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_4, "" }, 139 { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_0, s_sys_bat_file }, 140 { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_1, s_sys_bat_file }, 141 { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_2, s_sys_bat_file }, 142 { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_3, s_win_bat_file }, 143 { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_4, s_sys_bat_file }, 144 { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_0, s_sys_notepad }, 145 { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_1, s_sys_notepad }, 146 { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_2, s_sys_notepad }, 147 { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_3, s_sys_notepad }, 148 { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_4, s_sys_notepad }, 149 { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_0, "" }, 150 { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_1, "" }, 151 { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_2, "" }, 152 { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_3, "" }, 153 { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_4, "" }, 154 { __LINE__, SE_ERR_FNF, "invalid file.InvalidExtension", DIR_0, "" }, 155 { __LINE__, SE_ERR_FNF, "invalid file.InvalidExtension", DIR_1, "" }, 156 { __LINE__, SE_ERR_FNF, "invalid file.InvalidExtension", DIR_2, "" }, 157 { __LINE__, SE_ERR_FNF, "invalid file.InvalidExtension", DIR_3, "" }, 158 { __LINE__, SE_ERR_FNF, "invalid file.InvalidExtension", DIR_4, "" }, 159 }; 160 161 static void DoTestEntry(const TEST_ENTRY *pEntry) 162 { 163 char result[MAX_PATH]; 164 result[0] = 0; 165 166 UINT ret = (UINT)(UINT_PTR)FindExecutableA(pEntry->file, pEntry->dir, result); 167 if (ret > 32) 168 ret = 0xBEEFCAFE; 169 170 ok(ret == pEntry->ret, "Line %u: ret expected %d, got %d\n", pEntry->lineno, pEntry->ret, ret); 171 172 GetLongPathNameA(result, result, _countof(result)); 173 174 ok(lstrcmpiA(result, pEntry->result) == 0, 175 "Line %u: result expected '%s', got '%s'\n", 176 pEntry->lineno, pEntry->result, result); 177 } 178 179 START_TEST(FindExecutable) 180 { 181 char cur_dir[MAX_PATH]; 182 GetCurrentDirectoryA(_countof(cur_dir), cur_dir); 183 if (PathIsRootA(cur_dir)) 184 { 185 skip("Don't use this program at root directory\n"); 186 return; 187 } 188 189 GetWindowsDirectoryA(s_win_dir, _countof(s_win_dir)); 190 191 GetWindowsDirectoryA(s_win_notepad, _countof(s_win_notepad)); 192 PathAppendA(s_win_notepad, "notepad.exe"); 193 194 GetSystemDirectoryA(s_sys_notepad, _countof(s_sys_notepad)); 195 PathAppendA(s_sys_notepad, "notepad.exe"); 196 197 GetWindowsDirectoryA(s_win_test_exe, _countof(s_win_test_exe)); 198 PathAppendA(s_win_test_exe, "test program.exe"); 199 BOOL ret = CopyFileA(s_win_notepad, s_win_test_exe, FALSE); 200 if (!ret) 201 { 202 skip("Please retry with admin rights\n"); 203 return; 204 } 205 206 GetSystemDirectoryA(s_sys_test_exe, _countof(s_sys_test_exe)); 207 PathAppendA(s_sys_test_exe, "test program.exe"); 208 ret = CopyFileA(s_win_notepad, s_sys_test_exe, FALSE); 209 if (!ret) 210 { 211 skip("Please retry with admin rights\n"); 212 return; 213 } 214 215 GetWindowsDirectoryA(s_win_bat_file, _countof(s_win_bat_file)); 216 PathAppendA(s_win_bat_file, "test program.bat"); 217 fclose(fopen(s_win_bat_file, "wb")); 218 ok_int(PathFileExistsA(s_win_bat_file), TRUE); 219 220 GetSystemDirectoryA(s_sys_bat_file, _countof(s_sys_bat_file)); 221 PathAppendA(s_sys_bat_file, "test program.bat"); 222 fclose(fopen(s_sys_bat_file, "wb")); 223 ok_int(PathFileExistsA(s_sys_bat_file), TRUE); 224 225 GetWindowsDirectoryA(s_win_txt_file, _countof(s_win_txt_file)); 226 PathAppendA(s_win_txt_file, "test file.txt"); 227 fclose(fopen(s_win_txt_file, "wb")); 228 ok_int(PathFileExistsA(s_win_txt_file), TRUE); 229 230 GetSystemDirectoryA(s_sys_txt_file, _countof(s_sys_txt_file)); 231 PathAppendA(s_sys_txt_file, "test file.txt"); 232 fclose(fopen(s_sys_txt_file, "wb")); 233 ok_int(PathFileExistsA(s_sys_txt_file), TRUE); 234 235 for (UINT iTest = 0; iTest < _countof(s_entries); ++iTest) 236 { 237 DoTestEntry(&s_entries[iTest]); 238 } 239 240 DeleteFileA(s_win_test_exe); 241 DeleteFileA(s_sys_test_exe); 242 DeleteFileA(s_win_bat_file); 243 DeleteFileA(s_sys_bat_file); 244 DeleteFileA(s_win_txt_file); 245 DeleteFileA(s_sys_txt_file); 246 } 247