1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS api tests
3c2c66affSColin Finck  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4c2c66affSColin Finck  * PURPOSE:         Test for RtlDosSearchPath_U
5c2c66affSColin Finck  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6c2c66affSColin Finck  */
7c2c66affSColin Finck 
8*283bbe73SAmine Khaldi #include "precomp.h"
9c2c66affSColin Finck 
10c2c66affSColin Finck /*
11c2c66affSColin Finck ULONG
12c2c66affSColin Finck NTAPI
13c2c66affSColin Finck RtlDosSearchPath_U(
14c2c66affSColin Finck     IN PCWSTR Path,
15c2c66affSColin Finck     IN PCWSTR FileName,
16c2c66affSColin Finck     IN PCWSTR Extension,
17c2c66affSColin Finck     IN ULONG BufferSize,
18c2c66affSColin Finck     OUT PWSTR Buffer,
19c2c66affSColin Finck     OUT PWSTR *PartName
20c2c66affSColin Finck );
21c2c66affSColin Finck */
22c2c66affSColin Finck 
23c2c66affSColin Finck #define PrintablePointer(p) ((p) == InvalidPointer ? NULL : (p))
24c2c66affSColin Finck 
25c2c66affSColin Finck static
26c2c66affSColin Finck BOOLEAN
CheckStringBuffer(PCWSTR Buffer,SIZE_T Length,SIZE_T MaximumLength,PCWSTR Expected)27c2c66affSColin Finck CheckStringBuffer(
28c2c66affSColin Finck     PCWSTR Buffer,
29c2c66affSColin Finck     SIZE_T Length,
30c2c66affSColin Finck     SIZE_T MaximumLength,
31c2c66affSColin Finck     PCWSTR Expected)
32c2c66affSColin Finck {
33c2c66affSColin Finck     SIZE_T ExpectedLength = wcslen(Expected) * sizeof(WCHAR);
34c2c66affSColin Finck     SIZE_T EqualLength;
35c2c66affSColin Finck     BOOLEAN Result = TRUE;
36c2c66affSColin Finck     SIZE_T i;
37c2c66affSColin Finck 
38c2c66affSColin Finck     if (Length != ExpectedLength)
39c2c66affSColin Finck     {
40c2c66affSColin Finck         ok(0, "String length is %lu, expected %lu\n", (ULONG)Length, (ULONG)ExpectedLength);
41c2c66affSColin Finck         Result = FALSE;
42c2c66affSColin Finck     }
43c2c66affSColin Finck 
44c2c66affSColin Finck     EqualLength = RtlCompareMemory(Buffer, Expected, Length);
45c2c66affSColin Finck     if (EqualLength != Length)
46c2c66affSColin Finck     {
47c2c66affSColin Finck         ok(0, "String is '%S', expected '%S'\n", Buffer, Expected);
48c2c66affSColin Finck         Result = FALSE;
49c2c66affSColin Finck     }
50c2c66affSColin Finck 
51c2c66affSColin Finck     if (Buffer[Length / sizeof(WCHAR)] != UNICODE_NULL)
52c2c66affSColin Finck     {
53c2c66affSColin Finck         ok(0, "Not null terminated\n");
54c2c66affSColin Finck         Result = FALSE;
55c2c66affSColin Finck     }
56c2c66affSColin Finck 
57c2c66affSColin Finck     /* the function nulls the rest of the buffer! */
58c2c66affSColin Finck     for (i = Length + sizeof(UNICODE_NULL); i < MaximumLength; i++)
59c2c66affSColin Finck     {
60c2c66affSColin Finck         UCHAR Char = ((PUCHAR)Buffer)[i];
61c2c66affSColin Finck         if (Char != 0)
62c2c66affSColin Finck         {
63c2c66affSColin Finck             ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char, (ULONG)i, 0);
64c2c66affSColin Finck             /* don't count this as a failure unless the string was actually wrong */
65c2c66affSColin Finck             //Result = FALSE;
66c2c66affSColin Finck             /* don't flood the log */
67c2c66affSColin Finck             break;
68c2c66affSColin Finck         }
69c2c66affSColin Finck     }
70c2c66affSColin Finck 
71c2c66affSColin Finck     return Result;
72c2c66affSColin Finck }
73c2c66affSColin Finck 
74c2c66affSColin Finck static
75c2c66affSColin Finck BOOLEAN
CheckBuffer(PVOID Buffer,SIZE_T Size,UCHAR Value)76c2c66affSColin Finck CheckBuffer(
77c2c66affSColin Finck     PVOID Buffer,
78c2c66affSColin Finck     SIZE_T Size,
79c2c66affSColin Finck     UCHAR Value)
80c2c66affSColin Finck {
81c2c66affSColin Finck     PUCHAR Array = Buffer;
82c2c66affSColin Finck     SIZE_T i;
83c2c66affSColin Finck 
84c2c66affSColin Finck     for (i = 0; i < Size; i++)
85c2c66affSColin Finck         if (Array[i] != Value)
86c2c66affSColin Finck         {
87c2c66affSColin Finck             trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
88c2c66affSColin Finck             return FALSE;
89c2c66affSColin Finck         }
90c2c66affSColin Finck     return TRUE;
91c2c66affSColin Finck }
92c2c66affSColin Finck 
93c2c66affSColin Finck static
94c2c66affSColin Finck VOID
RunTestCases(PCWSTR CustomPath)95c2c66affSColin Finck RunTestCases(
96c2c66affSColin Finck     PCWSTR CustomPath)
97c2c66affSColin Finck {
98c2c66affSColin Finck     struct
99c2c66affSColin Finck     {
100c2c66affSColin Finck         PCWSTR SearchPath;
101c2c66affSColin Finck         PCWSTR FileName;
102c2c66affSColin Finck         PCWSTR Extension;
103c2c66affSColin Finck         PCWSTR ResultPath;
104c2c66affSColin Finck         PCWSTR ResultFileName;
105c2c66affSColin Finck     } Tests[] =
106c2c66affSColin Finck     {
107c2c66affSColin Finck         { L"",                 L"",                     NULL,    NULL,                           NULL },
108c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"File1",                NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
109c2c66affSColin Finck         /* No path: current directory */
110c2c66affSColin Finck         { L"",                 L"File1",                NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
111c2c66affSColin Finck         /* Full path as FileName */
112c2c66affSColin Finck         { L"",                 L"C:\\",                 NULL,    L"C:\\",                        NULL },
113c2c66affSColin Finck         { L"",                 L"C:\\%ls\\Folder1",     NULL,    L"C:\\%ls\\",                   L"Folder1" },
114c2c66affSColin Finck         /* No FileName */
115c2c66affSColin Finck         { L"C:\\",             L"",                     NULL,    L"C:\\",                        NULL },
116c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"",                     NULL,    L"C:\\%ls\\Folder1\\",          NULL },
117c2c66affSColin Finck         /* Full path as FileName */
118c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
119c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
120c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram",        NULL,    NULL,                           NULL },
121c2c66affSColin Finck         // 10
122c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram",        L".exe", NULL,                           NULL },
123c2c66affSColin Finck         /* Both SearchPath and FileName */
124c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
125c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
126c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\", L"SomeProgram",        NULL,    NULL,                           NULL },
127c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\", L"SomeProgram",        L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
128c2c66affSColin Finck         { L"C:\\%ls\\Folder1",   L"SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
129c2c66affSColin Finck         { L"C:\\%ls\\Folder1",   L"SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
130c2c66affSColin Finck         { L"C:\\%ls\\Folder1",   L"SomeProgram",        NULL,    NULL,                           NULL },
131c2c66affSColin Finck         { L"C:\\%ls\\Folder1",   L"SomeProgram",        L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
132c2c66affSColin Finck         /* Full path to file in SearchPath doesn't work */
133c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"",    NULL,    NULL,                           NULL },
134c2c66affSColin Finck         // 20
135c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"",    L".exe", NULL,                           NULL },
136c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\SomeProgram",     L"",    NULL,    NULL,                           NULL },
137c2c66affSColin Finck         { L"C:\\%ls\\Folder1\\SomeProgram",     L"",    L".exe", NULL,                           NULL },
138c2c66affSColin Finck         /* */
139c2c66affSColin Finck         { L"C:\\%ls\\Folder1",          L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
140c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory", L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
141c2c66affSColin Finck         { L"C:\\%ls\\Folder1 ",         L"File1",       NULL,    NULL,                           NULL },
142c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory ",L"File1",       NULL,    NULL,                           NULL },
143c2c66affSColin Finck         { L" C:\\%ls\\Folder1",         L"File1",       NULL,    NULL,                           NULL },
144c2c66affSColin Finck         { L" C:\\%ls\\CurrentDirectory",L"File1",       NULL,    NULL,                           NULL },
145c2c66affSColin Finck         { L" C:\\%ls\\Folder1 ",        L"File1",       NULL,    NULL,                           NULL },
146c2c66affSColin Finck         // 30
147c2c66affSColin Finck         { L" C:\\%ls\\CurrentDirectory ",L"File1",      NULL,    NULL,                           NULL },
148c2c66affSColin Finck         /* Multiple search paths */
149c2c66affSColin Finck         { L"C:\\%ls\\Folder1;C:\\%ls\\CurrentDirectory",
150c2c66affSColin Finck                                         L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
151c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory;C:\\%ls\\Folder1",
152c2c66affSColin Finck                                         L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
153c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory ; C:\\%ls\\Folder1",
154c2c66affSColin Finck                                         L"File1",       NULL,    NULL,                           NULL },
155c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory ;C:\\%ls\\Folder1",
156c2c66affSColin Finck                                         L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
157c2c66affSColin Finck         { L"C:\\%ls\\CurrentDirectory; C:\\%ls\\Folder1",
158c2c66affSColin Finck                                         L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
159c2c66affSColin Finck         { L";C:\\%ls\\Folder1",         L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
160c2c66affSColin Finck         { L";C:\\%ls\\Folder1;",        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
161c2c66affSColin Finck         { L";C:\\%ls\\Folder1;",        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
162c2c66affSColin Finck         { L"C:\\%ls\\Folder1",          L"OnlyInCurr",  NULL,    NULL,                           NULL },
163c2c66affSColin Finck         // 40
164c2c66affSColin Finck         { L"",                          L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
165c2c66affSColin Finck         { L"",                          L"OnlyInCurr ", NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
166c2c66affSColin Finck         { L"",                          L" OnlyInCurr", NULL,    NULL,                           NULL },
167c2c66affSColin Finck         { L" ",                         L"OnlyInCurr",  NULL,    NULL,                           NULL },
168c2c66affSColin Finck         { L";",                         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
169c2c66affSColin Finck         { L"; ",                        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
170c2c66affSColin Finck         { L" ;",                        L"OnlyInCurr",  NULL,    NULL,                           NULL },
171c2c66affSColin Finck         { L" ; ",                       L"OnlyInCurr",  NULL,    NULL,                           NULL },
172c2c66affSColin Finck         { L";C:\\%ls\\Folder1",         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
173c2c66affSColin Finck         { L"C:\\%ls\\Folder1;",         L"OnlyInCurr",  NULL,    NULL,                           NULL },
174c2c66affSColin Finck         // 50
175c2c66affSColin Finck         { L"C:\\%ls\\Folder1;;",        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
176c2c66affSColin Finck         { L";C:\\%ls\\Folder1;",        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
177c2c66affSColin Finck         { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2",
178c2c66affSColin Finck                                         L"OnlyInCurr",  NULL,    NULL,                           NULL },
179c2c66affSColin Finck         { L";C:\\%ls\\Folder1;C:\\%ls\\Folder2",
180c2c66affSColin Finck                                         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
181c2c66affSColin Finck         { L"C:\\%ls\\Folder1;;C:\\%ls\\Folder2",
182c2c66affSColin Finck                                         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
183c2c66affSColin Finck         { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;",
184c2c66affSColin Finck                                         L"OnlyInCurr",  NULL,    NULL,                           NULL },
185c2c66affSColin Finck         { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;;",
186c2c66affSColin Finck                                         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
187c2c66affSColin Finck         /* Spaces in FileName! */
188c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces",
189c2c66affSColin Finck                                                         L".exe", NULL,                           NULL },
190c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces.exe",
191c2c66affSColin Finck                                                         L".exe", NULL,                           NULL },
192c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program",            L".exe", NULL,                           NULL },
193c2c66affSColin Finck         // 60
194c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program.exe",        L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
195c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program With",       L".exe", NULL,                           NULL },
196c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program With.exe",   L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
197c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program With Spaces",L".exe", NULL,                           NULL },
198c2c66affSColin Finck         { L"", L"C:\\%ls\\Folder1\\Program With Spaces.exe",
199c2c66affSColin Finck                                                         L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
200c2c66affSColin Finck         /* Same tests with path in SearchPath - now extensions are appended */
201c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces",
202c2c66affSColin Finck                                                         L".exe", NULL,                           NULL },
203c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces.exe",
204c2c66affSColin Finck                                                         L".exe", NULL,                           NULL },
205c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program",              L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
206c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program.exe",          L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
207c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program With",         L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
208c2c66affSColin Finck         // 70
209c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program With.exe",     L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
210c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program With Spaces",  L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
211c2c66affSColin Finck         { L"C:\\%ls\\Folder1", L"Program With Spaces.exe",
212c2c66affSColin Finck                                                         L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
213c2c66affSColin Finck     };
214c2c66affSColin Finck 
215c2c66affSColin Finck     ULONG i;
216c2c66affSColin Finck     ULONG Length;
217c2c66affSColin Finck     PWSTR PartName;
218c2c66affSColin Finck     WCHAR SearchPath[MAX_PATH];
219c2c66affSColin Finck     WCHAR FileName[MAX_PATH];
220c2c66affSColin Finck     WCHAR ResultPath[MAX_PATH];
221c2c66affSColin Finck     WCHAR Buffer[MAX_PATH];
222c2c66affSColin Finck     BOOLEAN Okay;
223c2c66affSColin Finck 
224c2c66affSColin Finck     for (i = 0; i < sizeof(Tests) / sizeof(Tests[0]); i++)
225c2c66affSColin Finck     {
226c2c66affSColin Finck         swprintf(SearchPath, Tests[i].SearchPath, CustomPath, CustomPath, CustomPath, CustomPath);
227c2c66affSColin Finck         swprintf(FileName, Tests[i].FileName, CustomPath, CustomPath, CustomPath, CustomPath);
228c2c66affSColin Finck         RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
229c2c66affSColin Finck         PartName = InvalidPointer;
230c2c66affSColin Finck 
231c2c66affSColin Finck         StartSeh()
232c2c66affSColin Finck             Length = RtlDosSearchPath_U(SearchPath,
233c2c66affSColin Finck                                         FileName,
234c2c66affSColin Finck                                         Tests[i].Extension,
235c2c66affSColin Finck                                         sizeof(Buffer),
236c2c66affSColin Finck                                         Buffer,
237c2c66affSColin Finck                                         &PartName);
238c2c66affSColin Finck         EndSeh(STATUS_SUCCESS);
239c2c66affSColin Finck 
240c2c66affSColin Finck         if (Tests[i].ResultPath)
241c2c66affSColin Finck         {
242c2c66affSColin Finck             swprintf(ResultPath, Tests[i].ResultPath, CustomPath, CustomPath, CustomPath, CustomPath);
243c2c66affSColin Finck             if (Tests[i].ResultFileName)
244c2c66affSColin Finck             {
245c2c66affSColin Finck                 ok(PartName == &Buffer[wcslen(ResultPath)],
246c2c66affSColin Finck                    "PartName = %p (%ls), expected %p\n",
247c2c66affSColin Finck                    PartName, PrintablePointer(PartName), &Buffer[wcslen(ResultPath)]);
248c2c66affSColin Finck                 wcscat(ResultPath, Tests[i].ResultFileName);
249c2c66affSColin Finck             }
250c2c66affSColin Finck             else
251c2c66affSColin Finck             {
252c2c66affSColin Finck                 ok(PartName == NULL,
253c2c66affSColin Finck                    "PartName = %p (%ls), expected NULL\n",
254c2c66affSColin Finck                    PartName, PrintablePointer(PartName));
255c2c66affSColin Finck             }
256c2c66affSColin Finck             Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), ResultPath);
257c2c66affSColin Finck             ok(Okay == TRUE, "CheckStringBuffer failed. Got '%ls', expected '%ls'\n", Buffer, ResultPath);
258c2c66affSColin Finck         }
259c2c66affSColin Finck         else
260c2c66affSColin Finck         {
261c2c66affSColin Finck             Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
262c2c66affSColin Finck             ok(Okay == TRUE, "CheckBuffer failed\n");
263c2c66affSColin Finck             ok(Length == 0, "Length = %lu\n", Length);
264c2c66affSColin Finck             ok(PartName == InvalidPointer,
265c2c66affSColin Finck                "PartName = %p (%ls), expected %p\n",
266c2c66affSColin Finck                PartName, PrintablePointer(PartName), InvalidPointer);
267c2c66affSColin Finck         }
268c2c66affSColin Finck     }
269c2c66affSColin Finck }
270c2c66affSColin Finck 
271c2c66affSColin Finck #define MAKE_DIRECTORY(path)                                                \
272c2c66affSColin Finck do {                                                                        \
273c2c66affSColin Finck     swprintf(FileName, path, CustomPath);                                   \
274c2c66affSColin Finck     Success = CreateDirectoryW(FileName, NULL);                             \
275c2c66affSColin Finck     ok(Success, "CreateDirectory failed, results might not be accurate\n"); \
276c2c66affSColin Finck } while (0)
277c2c66affSColin Finck 
278c2c66affSColin Finck #define MAKE_FILE(path)                                                     \
279c2c66affSColin Finck do {                                                                        \
280c2c66affSColin Finck     swprintf(FileName, path, CustomPath);                                   \
281c2c66affSColin Finck     Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);        \
282c2c66affSColin Finck     ok(Handle != INVALID_HANDLE_VALUE,                                      \
283c2c66affSColin Finck        "CreateFile failed, results might not be accurate\n");               \
284c2c66affSColin Finck     if (Handle != INVALID_HANDLE_VALUE) CloseHandle(Handle);                \
285c2c66affSColin Finck } while (0)
286c2c66affSColin Finck 
287c2c66affSColin Finck #define DELETE_DIRECTORY(path)                                              \
288c2c66affSColin Finck do {                                                                        \
289c2c66affSColin Finck     swprintf(FileName, path, CustomPath);                                   \
290c2c66affSColin Finck     Success = RemoveDirectoryW(FileName);                                   \
291c2c66affSColin Finck     ok(Success,                                                             \
292c2c66affSColin Finck        "RemoveDirectory failed (%lu), test might leave stale directory\n",  \
293c2c66affSColin Finck        GetLastError());                                                     \
294c2c66affSColin Finck } while (0)
295c2c66affSColin Finck 
296c2c66affSColin Finck #define DELETE_FILE(path)                                                   \
297c2c66affSColin Finck do {                                                                        \
298c2c66affSColin Finck     swprintf(FileName, path, CustomPath);                                   \
299c2c66affSColin Finck     Success = DeleteFileW(FileName);                                        \
300c2c66affSColin Finck     ok(Success,                                                             \
301c2c66affSColin Finck        "DeleteFile failed (%lu), test might leave stale file\n",            \
302c2c66affSColin Finck        GetLastError());                                                     \
303c2c66affSColin Finck } while (0)
304c2c66affSColin Finck 
START_TEST(RtlDosSearchPath_U)305c2c66affSColin Finck START_TEST(RtlDosSearchPath_U)
306c2c66affSColin Finck {
307c2c66affSColin Finck     ULONG Length = 0;
308c2c66affSColin Finck     WCHAR Buffer[MAX_PATH];
309c2c66affSColin Finck     PWSTR PartName;
310c2c66affSColin Finck     BOOLEAN Okay;
311c2c66affSColin Finck     BOOL Success;
312c2c66affSColin Finck     WCHAR FileName[MAX_PATH];
313c2c66affSColin Finck     WCHAR CustomPath[MAX_PATH] = L"RtlDosSearchPath_U_TestPath";
314c2c66affSColin Finck     HANDLE Handle;
315c2c66affSColin Finck 
316c2c66affSColin Finck     swprintf(FileName, L"C:\\%ls", CustomPath);
317c2c66affSColin Finck     /* Make sure this directory doesn't exist */
318c2c66affSColin Finck     while (GetFileAttributesW(FileName) != INVALID_FILE_ATTRIBUTES)
319c2c66affSColin Finck     {
320c2c66affSColin Finck         wcscat(CustomPath, L"X");
321c2c66affSColin Finck         swprintf(FileName, L"C:\\%ls", CustomPath);
322c2c66affSColin Finck     }
323c2c66affSColin Finck     Success = CreateDirectoryW(FileName, NULL);
324c2c66affSColin Finck     ok(Success, "CreateDirectory failed, results might not be accurate\n");
325c2c66affSColin Finck 
326c2c66affSColin Finck     MAKE_DIRECTORY(L"C:\\%ls\\Folder1");
327c2c66affSColin Finck     MAKE_DIRECTORY(L"C:\\%ls\\Folder2");
328c2c66affSColin Finck     MAKE_DIRECTORY(L"C:\\%ls\\CurrentDirectory");
329c2c66affSColin Finck     Success = SetCurrentDirectoryW(FileName);
330c2c66affSColin Finck     ok(Success, "SetCurrentDirectory failed\n");
331c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\File1");
332c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram.exe");
333c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe");
334c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe.exe");
335c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram3.exe.exe");
336c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\Program.exe");
337c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\Program With.exe");
338c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\Folder1\\Program With Spaces.exe");
339c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\CurrentDirectory\\File1");
340c2c66affSColin Finck     MAKE_FILE(L"C:\\%ls\\CurrentDirectory\\OnlyInCurr");
341c2c66affSColin Finck 
342c2c66affSColin Finck     /* NULL parameters */
343c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(NULL, NULL, NULL, 0, NULL  , NULL); EndSeh(STATUS_ACCESS_VIOLATION);
344c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(NULL, L"" , NULL, 0, NULL  , NULL); EndSeh(STATUS_ACCESS_VIOLATION);
345c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(NULL, L"" , NULL, 0, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
346c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(NULL, L"" , NULL, 1, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
347c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(NULL, L"" , NULL, 2, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
348c2c66affSColin Finck     StartSeh() RtlDosSearchPath_U(L"" , NULL, NULL, 0, NULL  , NULL); EndSeh(STATUS_ACCESS_VIOLATION);
349c2c66affSColin Finck 
350c2c66affSColin Finck     /* Empty strings - first one that doesn't crash */
351c2c66affSColin Finck     StartSeh()
352c2c66affSColin Finck         Length = RtlDosSearchPath_U(L"", L"", NULL, 0, NULL, NULL);
353c2c66affSColin Finck         ok(Length == 0, "Length %lu\n", Length);
354c2c66affSColin Finck     EndSeh(STATUS_SUCCESS);
355c2c66affSColin Finck 
356c2c66affSColin Finck     /* Check what's initialized */
357c2c66affSColin Finck     PartName = InvalidPointer;
358c2c66affSColin Finck     StartSeh()
359c2c66affSColin Finck         Length = RtlDosSearchPath_U(L"", L"", NULL, 0, NULL, &PartName);
360c2c66affSColin Finck         ok(Length == 0, "Length = %lu\n", Length);
361c2c66affSColin Finck     EndSeh(STATUS_SUCCESS);
362c2c66affSColin Finck     ok(PartName == InvalidPointer, "PartName = %p\n", PartName);
363c2c66affSColin Finck 
364c2c66affSColin Finck     RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
365c2c66affSColin Finck     StartSeh()
366c2c66affSColin Finck         Length = RtlDosSearchPath_U(L"", L"", NULL, sizeof(Buffer), Buffer, NULL);
367c2c66affSColin Finck         ok(Length == 0, "Length %lu\n", Length);
368c2c66affSColin Finck     EndSeh(STATUS_SUCCESS);
369c2c66affSColin Finck     Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
370c2c66affSColin Finck     ok(Okay, "CheckBuffer failed\n");
371c2c66affSColin Finck 
372c2c66affSColin Finck     PartName = InvalidPointer;
373c2c66affSColin Finck     RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
374c2c66affSColin Finck     StartSeh()
375c2c66affSColin Finck         Length = RtlDosSearchPath_U(L"", L"", NULL, sizeof(Buffer), Buffer, &PartName);
376c2c66affSColin Finck         ok(Length == 0, "Length %lu\n", Length);
377c2c66affSColin Finck     EndSeh(STATUS_SUCCESS);
378c2c66affSColin Finck     ok(PartName == InvalidPointer, "PartName = %p\n", PartName);
379c2c66affSColin Finck     Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
380c2c66affSColin Finck     ok(Okay, "CheckBuffer failed\n");
381c2c66affSColin Finck 
382c2c66affSColin Finck     /* Now test the actual functionality */
383c2c66affSColin Finck     RunTestCases(CustomPath);
384c2c66affSColin Finck 
385c2c66affSColin Finck     /*
386c2c66affSColin Finck      * Clean up test folder - We can't delete it
387c2c66affSColin Finck      * if our current directory is inside.
388c2c66affSColin Finck      */
389c2c66affSColin Finck     SetCurrentDirectoryW(L"C:\\");
390c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\CurrentDirectory\\OnlyInCurr");
391c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\CurrentDirectory\\File1");
392c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\Program With Spaces.exe");
393c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\Program With.exe");
394c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\Program.exe");
395c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram3.exe.exe");
396c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe.exe");
397c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe");
398c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram.exe");
399c2c66affSColin Finck     DELETE_FILE(L"C:\\%ls\\Folder1\\File1");
400c2c66affSColin Finck     DELETE_DIRECTORY(L"C:\\%ls\\CurrentDirectory");
401c2c66affSColin Finck     DELETE_DIRECTORY(L"C:\\%ls\\Folder2");
402c2c66affSColin Finck     DELETE_DIRECTORY(L"C:\\%ls\\Folder1");
403c2c66affSColin Finck     DELETE_DIRECTORY(L"C:\\%ls");
404c2c66affSColin Finck }
405