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
DoTestEntry(const TEST_ENTRY * pEntry)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
START_TEST(FindExecutable)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