1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Tests for the Find*File*A/W APIs.
5  * PROGRAMMER:      Hermès BÉLUSCA - MAÏTO
6  */
7 
8 #include "precomp.h"
9 #include <versionhelpers.h>
10 
11 /*
12  * NOTE: This test supposes the following requirements:
13  * - There is a disk attached to the letter "C:"
14  * - There is a Windows-like system installed in "C:\<installation_directory>"
15  *   which contains a sub-directory "system32"
16  * - There is no sub-directory called "foobar" in "C:\".
17  *
18  * If one of these requirements is not fulfilled, one or more tests may fail.
19  */
20 
21 static CHAR     OSDirA[MAX_PATH];       // OS directory
22 static WCHAR    OSDirW[MAX_PATH];
23 static CHAR     baseA[MAX_PATH];        // Current directory
24 static WCHAR    baseW[MAX_PATH];
25 static CHAR     selfnameA[MAX_PATH];    // Path to this executable
26 static WCHAR    selfnameW[MAX_PATH];
27 static LPSTR    exenameA;               // Executable's name
28 static LPWSTR   exenameW;
29 static INT      myARGC;
30 static LPSTR*   myARGV;
31 
32 
33 /*
34  * Fixes definition of Wine's ok_err
35  */
36 #ifdef ok_err
37 #undef ok_err
38 #endif
39 
40 #define ok_err(error) \
41     ok_int(GetLastError(), error)
42 
43 
44 /*
45  * Types of tests. Define them as macros so that calling them
46  * into the code reports the actual line where they were called.
47  */
48 #define testType1_A(lpFileName, dwInitialError, hExpectedHandleValue, dwExpectedError, bExpectedNullFilename)       \
49 do {    \
50     ZeroMemory(&fd, sizeof(fd));            \
51     SetLastError((dwInitialError));         \
52     h = FindFirstFileA((lpFileName), &fd);  \
53     ok(h == (hExpectedHandleValue), "FindFirstFileA returned 0x%p, expected 0x%p\n", h, (hExpectedHandleValue));    \
54     ok_err(dwExpectedError);                \
55     if (bExpectedNullFilename)              \
56         ok(fd.cFileName[0] == 0, "fd.cFileName != \"\"\n"); \
57     else                                    \
58         ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
59     FindClose(h);                           \
60 } while (0)
61 
62 #define testType1_W(lpFileName, dwInitialError, hExpectedHandleValue, dwExpectedError, bExpectedNullFilename)       \
63 do {    \
64     ZeroMemory(&fd, sizeof(fd));            \
65     SetLastError((dwInitialError));         \
66     h = FindFirstFileW((lpFileName), &fd);  \
67     ok(h == (hExpectedHandleValue), "FindFirstFileW returned 0x%p, expected 0x%p\n", h, (hExpectedHandleValue));    \
68     ok_err(dwExpectedError);                \
69     if (bExpectedNullFilename)              \
70         ok(fd.cFileName[0] == 0, "fd.cFileName != \"\"\n"); \
71     else                                    \
72         ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
73     FindClose(h);                           \
74 } while (0)
75 
76 #define testType2_A(lpFileName, dwInitialError, hUnexpectedHandleValue, dwExpectedError)    \
77 do {    \
78     ZeroMemory(&fd, sizeof(fd));            \
79     SetLastError((dwInitialError));         \
80     h = FindFirstFileA((lpFileName), &fd);  \
81     ok(h != (hUnexpectedHandleValue), "FindFirstFileA returned 0x%p\n", h); \
82     ok_err(dwExpectedError);                \
83     ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
84     FindClose(h);                           \
85 } while (0)
86 
87 #define testType2_W(lpFileName, dwInitialError, hUnexpectedHandleValue, dwExpectedError)    \
88 do {    \
89     ZeroMemory(&fd, sizeof(fd));            \
90     SetLastError((dwInitialError));         \
91     h = FindFirstFileW((lpFileName), &fd);  \
92     ok(h != (hUnexpectedHandleValue), "FindFirstFileW returned 0x%p\n", h); \
93     ok_err(dwExpectedError);                \
94     ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
95     FindClose(h);                           \
96 } while (0)
97 
98 #define testType3_A(lpFileName, fInfoLevelId, fSearchOp, lpSearchFilter, dwAdditionalFlags, dwInitialError, hUnexpectedHandleValue, dwExpectedError)    \
99 do {    \
100     ZeroMemory(&fd, sizeof(fd));            \
101     SetLastError((dwInitialError));         \
102     h = FindFirstFileExA((lpFileName), (fInfoLevelId), &fd, (fSearchOp), (lpSearchFilter), (dwAdditionalFlags));  \
103     ok(h != (hUnexpectedHandleValue), "FindFirstFileExA returned 0x%p\n", h); \
104     ok_err(dwExpectedError);                \
105     ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
106     FindClose(h);                           \
107 } while (0)
108 
109 #define testType3_W(lpFileName, fInfoLevelId, fSearchOp, lpSearchFilter, dwAdditionalFlags, dwInitialError, hUnexpectedHandleValue, dwExpectedError)    \
110 do {    \
111     ZeroMemory(&fd, sizeof(fd));            \
112     SetLastError((dwInitialError));         \
113     h = FindFirstFileExW((lpFileName), (fInfoLevelId), &fd, (fSearchOp), (lpSearchFilter), (dwAdditionalFlags));  \
114     ok(h != (hUnexpectedHandleValue), "FindFirstFileExW returned 0x%p\n", h); \
115     ok_err(dwExpectedError);                \
116     ok(fd.cFileName[0] != 0, "fd.cFileName == \"\"\n"); \
117     FindClose(h);                           \
118 } while (0)
119 
120 
121 static void Test_FindFirstFileA(void)
122 {
123     CHAR CurrentDirectory[MAX_PATH];
124     CHAR Buffer[MAX_PATH];
125     WIN32_FIND_DATAA fd;
126     HANDLE h;
127 
128     /* Save the current directory */
129     GetCurrentDirectoryA(_countof(CurrentDirectory), CurrentDirectory);
130 
131 /*** Tests for the root directory - root directory ***/
132     /* Modify the current directory */
133     SetCurrentDirectoryA("C:\\");
134 
135     testType1_A("C:", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
136 
137     testType1_A("C:\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
138     testType1_A("C:\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
139     testType2_A("C:\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
140 
141     testType1_A("\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
142     testType1_A("\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_INVALID_NAME, TRUE);
143     testType2_A("\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
144 
145     /* Restore the old current directory */
146     SetCurrentDirectoryA(CurrentDirectory);
147 /*****************************************************/
148 
149 /*** Tests for the root directory - long directory ***/
150     /* Modify the current directory */
151     SetCurrentDirectoryA(OSDirA); /* We expect here that OSDir is of the form: C:\OSDir */
152 
153     testType2_A("C:", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
154 
155     testType1_A("C:\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
156     testType1_A("C:\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
157     testType2_A("C:\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
158 
159     testType1_A("\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
160     testType1_A("\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_INVALID_NAME, TRUE);
161     testType2_A("\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
162 
163     /* Restore the old current directory */
164     SetCurrentDirectoryA(CurrentDirectory);
165 /*****************************************************/
166 
167 /*** Relative paths ***/
168     /*
169      * NOTE: This test does not give the same results if you launch the app
170      * from a root drive or from a long-form directory (of the form C:\dir).
171      */
172     // testType2_A("..", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
173     // testType1_A("..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
174 /**********************/
175 
176 /*** Relative paths - root directory ***/
177     /* Modify the current directory */
178     SetCurrentDirectoryA("C:\\");
179 
180     testType1_A(".", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
181     testType1_A(".\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
182     testType1_A(".\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
183     testType2_A(".\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
184 
185     testType1_A("..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
186     testType1_A("..\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
187     testType1_A("..\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
188     testType2_A("..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
189 
190     /* Restore the old current directory */
191     SetCurrentDirectoryA(CurrentDirectory);
192 /***************************************/
193 
194 /*** Relative paths - long directory ***/
195     /* Modify the current directory */
196     SetCurrentDirectoryA(OSDirA); /* We expect here that OSDir is of the form: C:\OSDir */
197 
198     testType2_A(".", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
199 
200     testType1_A(".\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
201     testType1_A(".\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
202     testType2_A(".\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
203 
204     testType1_A("..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
205 
206     testType1_A("..\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
207     testType1_A("..\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
208     testType2_A("..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
209 
210     /* Restore the old current directory */
211     SetCurrentDirectoryA(CurrentDirectory);
212 /****************************************/
213 
214 /*** Unexisting path ***/
215     testType1_A("C:\\foobar", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
216     testType1_A("C:\\foobar\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
217     testType1_A("C:\\foobar\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
218     testType1_A("C:\\foobar\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
219     testType1_A("C:\\foobar\\system32\\..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
220 
221     /* Possibly a DOS device */
222     testType1_A("C:\\foobar\\nul", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
223     testType1_A("C:\\foobar\\nul\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
224     testType1_A("C:\\foobar\\nul\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
225     testType1_A("C:\\foobar\\nul\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
226 
227     testType1_A("C:\\foobar\\toto", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
228     testType1_A("C:\\foobar\\toto\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
229     testType1_A("C:\\foobar\\toto\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
230     testType1_A("C:\\foobar\\toto\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
231 
232     strcpy(Buffer, "C:\\foobar\\");
233     strcat(Buffer, exenameA);
234     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
235 
236     strcpy(Buffer, "C:\\foobar\\.\\");
237     strcat(Buffer, exenameA);
238     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
239 /***********************/
240 
241 /*** Existing path ***/
242     strcpy(Buffer, OSDirA);
243     testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
244 
245     strcpy(Buffer, OSDirA);
246     strcat(Buffer, "\\");
247     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
248 
249     strcpy(Buffer, OSDirA);
250     strcat(Buffer, "\\\\");
251     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
252 
253     strcpy(Buffer, OSDirA);
254     strcat(Buffer, "\\*");
255     testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
256 
257     strcpy(Buffer, OSDirA);
258     strcat(Buffer, "\\.\\*");
259     testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
260 
261     strcpy(Buffer, OSDirA);
262     strcat(Buffer, "\\system32\\..\\*");
263     testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
264 
265     /* Possibly a DOS device */
266     strcpy(Buffer, OSDirA);
267     strcat(Buffer, "\\nul");
268     testType1_A(Buffer, 0xdeadbeef, (HANDLE)0x00000001, 0xdeadbeef, FALSE);
269 
270     strcpy(Buffer, OSDirA);
271     strcat(Buffer, "\\nul\\");
272     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
273 
274     strcpy(Buffer, OSDirA);
275     strcat(Buffer, "\\nul\\\\");
276     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
277 
278     strcpy(Buffer, OSDirA);
279     strcat(Buffer, "\\nul\\*");
280     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
281 
282     strcpy(Buffer, OSDirA);
283     strcat(Buffer, "\\toto");
284     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
285 
286     strcpy(Buffer, OSDirA);
287     strcat(Buffer, "\\toto\\");
288     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
289 
290     strcpy(Buffer, OSDirA);
291     strcat(Buffer, "\\toto\\\\");
292     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
293 
294     strcpy(Buffer, OSDirA);
295     strcat(Buffer, "\\toto\\*");
296     testType1_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
297 
298     // strcpy(Buffer, baseA);
299     // strcat(Buffer, "\\");
300     // strcat(Buffer, exenameA);
301     // testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
302 
303     // strcpy(Buffer, baseA);
304     // strcat(Buffer, "\\.\\");
305     // strcat(Buffer, exenameA);
306     // testType2_A(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
307 /*********************/
308 
309     return;
310 }
311 
312 static void Test_FindFirstFileW(void)
313 {
314     WCHAR CurrentDirectory[MAX_PATH];
315     WCHAR Buffer[MAX_PATH];
316     WIN32_FIND_DATAW fd;
317     HANDLE h;
318 
319     /* Save the current directory */
320     GetCurrentDirectoryW(_countof(CurrentDirectory), CurrentDirectory);
321 
322 /*** Tests for the root directory - root directory ***/
323     /* Modify the current directory */
324     SetCurrentDirectoryW(L"C:\\");
325 
326     testType1_W(L"C:", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
327 
328     testType1_W(L"C:\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
329     testType1_W(L"C:\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
330     testType2_W(L"C:\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
331 
332     testType1_W(L"\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
333     testType1_W(L"\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_INVALID_NAME, TRUE);
334     testType2_W(L"\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
335 
336     /* Restore the old current directory */
337     SetCurrentDirectoryW(CurrentDirectory);
338 /*****************************************************/
339 
340 /*** Tests for the root directory - long directory ***/
341     /* Modify the current directory */
342     SetCurrentDirectoryW(OSDirW); /* We expect here that OSDir is of the form: C:\OSDir */
343 
344     testType2_W(L"C:", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
345 
346     testType1_W(L"C:\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
347     testType1_W(L"C:\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
348     testType2_W(L"C:\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
349 
350     testType1_W(L"\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
351     testType1_W(L"\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_INVALID_NAME, TRUE);
352     testType2_W(L"\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
353 
354     /* Restore the old current directory */
355     SetCurrentDirectoryW(CurrentDirectory);
356 /*****************************************************/
357 
358 /*** Relative paths ***/
359     /*
360      * NOTE: This test does not give the same results if you launch the app
361      * from a root drive or from a long-form directory (of the form C:\dir).
362      */
363     // testType2_W(L"..", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
364     // testType1_W(L"..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
365 /**********************/
366 
367 /*** Relative paths - root directory ***/
368     /* Modify the current directory */
369     SetCurrentDirectoryW(L"C:\\");
370 
371     testType1_W(L".", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
372     testType1_W(L".\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
373     testType1_W(L".\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
374     testType2_W(L".\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
375 
376     testType1_W(L"..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
377     testType1_W(L"..\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
378     testType1_W(L"..\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
379     testType2_W(L"..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
380 
381     /* Restore the old current directory */
382     SetCurrentDirectoryW(CurrentDirectory);
383 /***************************************/
384 
385 /*** Relative paths - long directory ***/
386     /* Modify the current directory */
387     SetCurrentDirectoryW(OSDirW); /* We expect here that OSDir is of the form: C:\OSDir */
388 
389     testType2_W(L".", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
390 
391     testType1_W(L".\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
392     testType1_W(L".\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
393     testType2_W(L".\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
394 
395     testType1_W(L"..", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
396 
397     testType1_W(L"..\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
398     testType1_W(L"..\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
399     testType2_W(L"..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
400 
401     /* Restore the old current directory */
402     SetCurrentDirectoryW(CurrentDirectory);
403 /****************************************/
404 
405 /*** Unexisting path ***/
406     testType1_W(L"C:\\foobar", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
407     testType1_W(L"C:\\foobar\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
408     testType1_W(L"C:\\foobar\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
409     testType1_W(L"C:\\foobar\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
410     testType1_W(L"C:\\foobar\\system32\\..\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
411 
412     /* Possibly a DOS device */
413     testType1_W(L"C:\\foobar\\nul", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
414     testType1_W(L"C:\\foobar\\nul\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
415     testType1_W(L"C:\\foobar\\nul\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
416     testType1_W(L"C:\\foobar\\nul\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
417 
418     testType1_W(L"C:\\foobar\\toto", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
419     testType1_W(L"C:\\foobar\\toto\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
420     testType1_W(L"C:\\foobar\\toto\\\\", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
421     testType1_W(L"C:\\foobar\\toto\\*", 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
422 
423     wcscpy(Buffer, L"C:\\foobar\\");
424     wcscat(Buffer, exenameW);
425     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
426 
427     wcscpy(Buffer, L"C:\\foobar\\.\\");
428     wcscat(Buffer, exenameW);
429     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
430 /***********************/
431 
432 /*** Existing path ***/
433     wcscpy(Buffer, OSDirW);
434     testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
435 
436     wcscpy(Buffer, OSDirW);
437     wcscat(Buffer, L"\\");
438     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
439 
440     wcscpy(Buffer, OSDirW);
441     wcscat(Buffer, L"\\\\");
442     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
443 
444     wcscpy(Buffer, OSDirW);
445     wcscat(Buffer, L"\\*");
446     testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
447 
448     wcscpy(Buffer, OSDirW);
449     wcscat(Buffer, L"\\.\\*");
450     testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
451 
452     wcscpy(Buffer, OSDirW);
453     wcscat(Buffer, L"\\system32\\..\\*");
454     testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
455 
456     /* Possibly a DOS device */
457     wcscpy(Buffer, OSDirW);
458     wcscat(Buffer, L"\\nul");
459     testType1_W(Buffer, 0xdeadbeef, (HANDLE)0x00000001, 0xdeadbeef, FALSE);
460 
461     wcscpy(Buffer, OSDirW);
462     wcscat(Buffer, L"\\nul\\");
463     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
464 
465     wcscpy(Buffer, OSDirW);
466     wcscat(Buffer, L"\\nul\\\\");
467     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
468 
469     wcscpy(Buffer, OSDirW);
470     wcscat(Buffer, L"\\nul\\*");
471     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
472 
473     wcscpy(Buffer, OSDirW);
474     wcscat(Buffer, L"\\toto");
475     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND, TRUE);
476 
477     wcscpy(Buffer, OSDirW);
478     wcscat(Buffer, L"\\toto\\");
479     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
480 
481     wcscpy(Buffer, OSDirW);
482     wcscat(Buffer, L"\\toto\\\\");
483     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
484 
485     wcscpy(Buffer, OSDirW);
486     wcscat(Buffer, L"\\toto\\*");
487     testType1_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND, TRUE);
488 
489     // wcscpy(Buffer, baseW);
490     // wcscat(Buffer, L"\\");
491     // wcscat(Buffer, exenameW);
492     // testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
493 
494     // wcscpy(Buffer, baseW);
495     // wcscat(Buffer, L"\\.\\");
496     // wcscat(Buffer, exenameW);
497     // testType2_W(Buffer, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
498 /*********************/
499 
500     return;
501 }
502 
503 static void Test_FindFirstFileExA(void)
504 {
505     CHAR CurrentDirectory[MAX_PATH];
506     WIN32_FIND_DATAA fd;
507     HANDLE h;
508 
509     /* Save the current directory */
510     GetCurrentDirectoryA(_countof(CurrentDirectory), CurrentDirectory);
511     SetCurrentDirectoryA(OSDirA); /* We expect here that OSDir is of the form: C:\OSDir */
512 
513     testType3_A(".", FindExInfoStandard, FindExSearchNameMatch, NULL, 0, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
514     testType3_A(".", FindExInfoStandard, FindExSearchNameMatch, "XXX", 0, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
515 
516     /* Restore the old current directory */
517     SetCurrentDirectoryA(CurrentDirectory);
518 }
519 
520 static void Test_FindFirstFileExW(void)
521 {
522     WCHAR CurrentDirectory[MAX_PATH];
523     WIN32_FIND_DATAW fd;
524     HANDLE h;
525 
526     /* Save the current directory */
527     GetCurrentDirectoryW(_countof(CurrentDirectory), CurrentDirectory);
528     SetCurrentDirectoryW(OSDirW); /* We expect here that OSDir is of the form: C:\OSDir */
529 
530     testType3_W(L".", FindExInfoStandard, FindExSearchNameMatch, NULL, 0, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
531     testType3_W(L".", FindExInfoStandard, FindExSearchNameMatch, L"XXX", 0, 0xdeadbeef, INVALID_HANDLE_VALUE, 0xdeadbeef);
532 
533     /* Restore the old current directory */
534     SetCurrentDirectoryW(CurrentDirectory);
535 }
536 
537 static int init(void)
538 {
539     LPSTR p;
540     size_t i;
541 
542     myARGC = winetest_get_mainargs(&myARGV);
543     if (!GetCurrentDirectoryA(_countof(baseA), baseA)) return 0;
544     strcpy(selfnameA, myARGV[0]);
545 
546     /* Strip the path of selfname */
547     if ((p = strrchr(selfnameA, '\\')) != NULL)
548         exenameA = p + 1;
549     else
550         exenameA = selfnameA;
551 
552     if ((p = strrchr(exenameA, '/')) != NULL)
553         exenameA = p + 1;
554 
555     if (!GetWindowsDirectoryA(OSDirA, _countof(OSDirA))) return 0;
556 
557     /* Quick-and-dirty conversion ANSI --> UNICODE without the Win32 APIs */
558     for (i = 0 ; i <= strlen(baseA) ; ++i)
559     {
560         baseW[i] = (WCHAR)baseA[i];
561     }
562     for (i = 0 ; i <= strlen(selfnameA) ; ++i)
563     {
564         selfnameW[i] = (WCHAR)selfnameA[i];
565     }
566     exenameW = selfnameW + (exenameA - selfnameA);
567     for (i = 0 ; i <= strlen(OSDirA) ; ++i)
568     {
569         OSDirW[i] = (WCHAR)OSDirA[i];
570     }
571 
572     return 1;
573 }
574 
575 START_TEST(FindFiles)
576 {
577     int b = init();
578     ok(b, "Basic init of FindFiles test\n");
579     if (!b) return;
580 
581     Test_FindFirstFileA();
582     Test_FindFirstFileW();
583     Test_FindFirstFileExA();
584     Test_FindFirstFileExW();
585 }
586