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