[SHLWAPI_APITEST] Add PathFindOnPath tests. Patch by Katayama Hirofumi MZ. ROSTESTS...
[reactos.git] / rostests / apitests / shlwapi / PathFindOnPath.c
1 /*
2 * Copyright 2017 Katayama Hirofumi MZ
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include <apitest.h>
20 #include <shlwapi.h>
21 #include <assert.h>
22
23 #define EF_FULLPATH 1
24 #define EF_TESTDATA 2
25 #define EF_WIN_DIR 4
26 #define EF_SYS_DIR 8
27 #define EF_TYPE_MASK 0xF
28
29 #define EF_NAME_ONLY 16
30
31 typedef struct ENTRY
32 {
33 INT EntryNumber; /* # */
34 INT Ret;
35 DWORD Error;
36 UINT EF_;
37 LPCWSTR NameBefore;
38 LPCWSTR NameExpected;
39 LPCWSTR PathExpected;
40 LPWSTR * Dirs;
41 } ENTRY;
42
43 #define BEEF 0xBEEF /* Error Code 48879 */
44 #define DEAD 0xDEAD /* Error Code 57005 */
45 #define IGNORE_ERR 0x7F7F7F7F /* Ignore Error Code */
46 #define RAISED 9999 /* exception raised */
47
48 static WCHAR s_TestDataPath[MAX_PATH];
49 static LPWSTR s_Dirs[2];
50 static WCHAR s_WinDir[MAX_PATH];
51 static WCHAR s_SysDir[MAX_PATH];
52 static WCHAR s_FontsDir[MAX_PATH];
53 static WCHAR s_NotepadPath[MAX_PATH];
54
55 static const ENTRY s_Entries[] =
56 {
57 /* NULL or empty path */
58 { 0, 0, BEEF, EF_FULLPATH, NULL, NULL },
59 { 1, 1, BEEF, EF_FULLPATH, L"", s_SysDir },
60 /* path without dirs in Windows */
61 { 2, 0, BEEF, EF_WIN_DIR, L"", L"" },
62 { 3, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts" },
63 { 4, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad" },
64 { 5, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe" },
65 { 6, 0, BEEF, EF_WIN_DIR, L"system32", L"system32" },
66 { 7, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name" },
67 /* path with dirs in Windows */
68 { 8, 0, BEEF, EF_WIN_DIR, L"", L"", NULL, s_Dirs },
69 { 9, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
70 { 10, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad", NULL, s_Dirs },
71 { 11, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
72 { 12, 0, BEEF, EF_WIN_DIR, L"system32", L"system32", NULL, s_Dirs },
73 { 13, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
74 /* name only without dirs in Windows */
75 { 14, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", L"system32" },
76 { 15, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts" },
77 { 16, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad" },
78 { 17, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
79 { 18, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32" },
80 { 19, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
81 /* name only with dirs in Windows */
82 { 20, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
83 { 21, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", NULL, s_Dirs },
84 { 22, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
85 { 23, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
86 { 24, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32", L"system32", NULL, s_Dirs },
87 { 25, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
88 /* path without dirs in system32 */
89 { 26, 0, BEEF, EF_SYS_DIR, L"", L"" },
90 { 27, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts" },
91 { 28, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad" },
92 { 29, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe" },
93 { 30, 0, BEEF, EF_SYS_DIR, L"system32", L"system32" },
94 { 31, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name" },
95 /* path with dirs in system32 */
96 { 32, 0, BEEF, EF_SYS_DIR, L"", L"", NULL, s_Dirs },
97 { 33, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
98 { 34, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad", NULL, s_Dirs },
99 { 35, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
100 { 36, 0, BEEF, EF_SYS_DIR, L"system32", L"system32", NULL, s_Dirs },
101 { 37, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
102 /* name only without dirs in system32 */
103 { 38, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_SysDir },
104 { 39, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
105 { 40, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
106 { 41, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe" },
107 { 42, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
108 { 43, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
109 /* name only with dirs in system32 */
110 { 44, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
111 { 45, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
112 { 46, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
113 { 47, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
114 { 48, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
115 { 49, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
116 /* path without dirs in testdata dir */
117 { 50, 0, BEEF, EF_TESTDATA, L"", L"" },
118 { 51, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts" },
119 { 52, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad" },
120 { 53, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe" },
121 { 54, 0, BEEF, EF_TESTDATA, L"system32", L"system32" },
122 { 55, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name" },
123 { 56, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt" },
124 { 57, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils" },
125 { 58, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe" },
126 /* path with dirs in testdata dir */
127 { 59, 0, BEEF, EF_TESTDATA, L"", L"", NULL, s_Dirs },
128 { 60, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts", NULL, s_Dirs },
129 { 61, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad", NULL, s_Dirs },
130 { 62, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
131 { 63, 0, BEEF, EF_TESTDATA, L"system32", L"system32", NULL, s_Dirs },
132 { 64, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name", NULL, s_Dirs },
133 { 65, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt", NULL, s_Dirs },
134 { 66, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", NULL, s_Dirs },
135 { 67, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", NULL, s_Dirs },
136 /* name only without dirs in testdata dir */
137 { 68, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_SysDir },
138 { 69, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
139 { 70, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
140 { 71, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
141 { 72, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
142 { 73, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
143 { 74, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
144 { 75, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
145 { 76, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
146 /* name only with dirs in testdata dir */
147 { 77, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
148 { 78, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
149 { 79, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
150 { 80, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
151 { 81, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
152 { 82, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
153 { 83, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
154 { 84, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
155 { 85, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
156 };
157
158 static void DoEntry(INT EntryNumber, const ENTRY *pEntry, const WCHAR *PathVar)
159 {
160 WCHAR Path[MAX_PATH], PathExpected[MAX_PATH], OldPathVar[256];
161 INT Ret;
162 DWORD Error;
163
164 if (pEntry->NameBefore == NULL)
165 {
166 assert(pEntry->NameExpected == NULL);
167 assert(pEntry->PathExpected == NULL);
168 }
169
170 switch (pEntry->EF_ & EF_TYPE_MASK)
171 {
172 case EF_FULLPATH:
173 if (pEntry->NameBefore)
174 {
175 lstrcpyW(Path, pEntry->NameBefore);
176 }
177 if (pEntry->NameExpected)
178 {
179 lstrcpyW(PathExpected, pEntry->NameExpected);
180 }
181 break;
182
183 case EF_TESTDATA:
184 if (pEntry->EF_ & EF_NAME_ONLY)
185 {
186 lstrcpyW(Path, pEntry->NameBefore);
187 }
188 else
189 {
190 lstrcpyW(Path, s_TestDataPath);
191 lstrcatW(Path, L"\\");
192 lstrcatW(Path, pEntry->NameBefore);
193 }
194
195 if (pEntry->NameExpected)
196 {
197 lstrcpyW(PathExpected, s_TestDataPath);
198 lstrcatW(PathExpected, L"\\");
199 lstrcatW(PathExpected, pEntry->NameExpected);
200 }
201 break;
202
203 case EF_WIN_DIR:
204 if (pEntry->EF_ & EF_NAME_ONLY)
205 {
206 lstrcpyW(Path, pEntry->NameBefore);
207 }
208 else
209 {
210 GetWindowsDirectoryW(Path, _countof(Path));
211 lstrcatW(Path, L"\\");
212 lstrcatW(Path, pEntry->NameBefore);
213 }
214
215 if (pEntry->NameExpected)
216 {
217 GetWindowsDirectoryW(PathExpected, _countof(PathExpected));
218 lstrcatW(PathExpected, L"\\");
219 lstrcatW(PathExpected, pEntry->NameExpected);
220 }
221 break;
222
223 case EF_SYS_DIR:
224 if (pEntry->EF_ & EF_NAME_ONLY)
225 {
226 lstrcpyW(Path, pEntry->NameBefore);
227 }
228 else
229 {
230 GetSystemDirectoryW(Path, _countof(Path));
231 lstrcatW(Path, L"\\");
232 lstrcatW(Path, pEntry->NameBefore);
233 }
234
235 if (pEntry->NameExpected)
236 {
237 GetSystemDirectoryW(PathExpected, _countof(PathExpected));
238 lstrcatW(PathExpected, L"\\");
239 lstrcatW(PathExpected, pEntry->NameExpected);
240 }
241 break;
242 }
243
244 if (PathVar)
245 {
246 if (!GetEnvironmentVariableW(L"PATH", OldPathVar, _countof(OldPathVar)))
247 {
248 skip("#%d: GetEnvironmentVariableW failed\n", EntryNumber);
249 return;
250 }
251 if (!SetEnvironmentVariableW(L"PATH", PathVar))
252 {
253 skip("#%d: SetEnvironmentVariableW failed\n", EntryNumber);
254 return;
255 }
256 }
257
258 _SEH2_TRY
259 {
260 SetLastError(BEEF);
261 if (pEntry->NameBefore)
262 {
263 Ret = PathFindOnPathW(Path, (LPCWSTR *)pEntry->Dirs);
264 }
265 else
266 {
267 Ret = PathFindOnPathW(NULL, (LPCWSTR *)pEntry->Dirs);
268 }
269 Error = GetLastError();
270 }
271 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
272 {
273 Ret = RAISED;
274 Error = DEAD;
275 }
276 _SEH2_END;
277
278 if (PathVar)
279 {
280 ok(SetEnvironmentVariableW(L"PATH", OldPathVar),
281 "#%d: SetEnvironmentVariableW failed\n", EntryNumber);
282 }
283
284 ok(Ret == pEntry->Ret, "#%d: Ret expected %d, was %d.\n",
285 EntryNumber, pEntry->Ret, Ret);
286
287 if (pEntry->Error != IGNORE_ERR)
288 {
289 ok(Error == pEntry->Error, "#%d: last error expected %ld, was %ld.\n",
290 EntryNumber, pEntry->Error, Error);
291 }
292
293 if (pEntry->PathExpected)
294 {
295 ok(lstrcmpiW(Path, pEntry->PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
296 EntryNumber, wine_dbgstr_w(pEntry->PathExpected), wine_dbgstr_w(Path));
297 }
298 else if (pEntry->NameExpected)
299 {
300 ok(lstrcmpiW(Path, PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
301 EntryNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
302 }
303 }
304
305 static void Test_PathFindOnPathW(void)
306 {
307 UINT i;
308
309 for (i = 0; i < _countof(s_Entries); ++i)
310 {
311 DoEntry(s_Entries[i].EntryNumber, &s_Entries[i], NULL);
312 }
313 }
314
315 START_TEST(PathFindOnPath)
316 {
317 LPWSTR pch;
318
319 GetWindowsDirectoryW(s_WinDir, _countof(s_WinDir));
320 GetSystemDirectoryW(s_SysDir, _countof(s_SysDir));
321
322 lstrcpyW(s_FontsDir, s_WinDir);
323 lstrcatW(s_FontsDir, L"\\Fonts");
324
325 lstrcpyW(s_NotepadPath, s_SysDir);
326 lstrcatW(s_NotepadPath, L"\\notepad.exe");
327
328 GetModuleFileNameW(NULL, s_TestDataPath, _countof(s_TestDataPath));
329 pch = wcsrchr(s_TestDataPath, L'\\');
330 if (pch == NULL)
331 pch = wcsrchr(s_TestDataPath, L'/');
332 if (pch == NULL)
333 {
334 skip("GetModuleFileName and/or wcsrchr are insane.\n");
335 return;
336 }
337 lstrcpyW(pch, L"\\testdata");
338 if (GetFileAttributesW(s_TestDataPath) == INVALID_FILE_ATTRIBUTES)
339 {
340 skip("testdata is not found.\n");
341 return;
342 }
343
344 s_Dirs[0] = s_TestDataPath;
345 s_Dirs[1] = NULL;
346
347 Test_PathFindOnPathW();
348 }