2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlDosSearchPath_U
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
10 #define WIN32_NO_STATUS
12 #include <ndk/rtlfuncs.h>
27 #define PrintablePointer(p) ((p) == InvalidPointer ? NULL : (p))
37 SIZE_T ExpectedLength
= wcslen(Expected
) * sizeof(WCHAR
);
39 BOOLEAN Result
= TRUE
;
42 if (Length
!= ExpectedLength
)
44 ok(0, "String length is %lu, expected %lu\n", (ULONG
)Length
, (ULONG
)ExpectedLength
);
48 EqualLength
= RtlCompareMemory(Buffer
, Expected
, Length
);
49 if (EqualLength
!= Length
)
51 ok(0, "String is '%S', expected '%S'\n", Buffer
, Expected
);
55 if (Buffer
[Length
/ sizeof(WCHAR
)] != UNICODE_NULL
)
57 ok(0, "Not null terminated\n");
61 /* the function nulls the rest of the buffer! */
62 for (i
= Length
+ sizeof(UNICODE_NULL
); i
< MaximumLength
; i
++)
64 UCHAR Char
= ((PUCHAR
)Buffer
)[i
];
67 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char
, (ULONG
)i
, 0);
68 /* don't count this as a failure unless the string was actually wrong */
70 /* don't flood the log */
85 PUCHAR Array
= Buffer
;
88 for (i
= 0; i
< Size
; i
++)
89 if (Array
[i
] != Value
)
91 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
108 PCWSTR ResultFileName
;
111 { L
"", L
"", NULL
, NULL
, NULL
},
112 { L
"C:\\%ls\\Folder1", L
"File1", NULL
, L
"C:\\%ls\\Folder1\\", L
"File1" },
113 /* No path: current directory */
114 { L
"", L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
115 /* Full path as FileName */
116 { L
"", L
"C:\\", NULL
, L
"C:\\", NULL
},
117 { L
"", L
"C:\\%ls\\Folder1", NULL
, L
"C:\\%ls\\", L
"Folder1" },
119 { L
"C:\\", L
"", NULL
, L
"C:\\", NULL
},
120 { L
"C:\\%ls\\Folder1", L
"", NULL
, L
"C:\\%ls\\Folder1\\", NULL
},
121 /* Full path as FileName */
122 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram.exe", NULL
, L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
123 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
124 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram", NULL
, NULL
, NULL
},
126 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram", L
".exe", NULL
, NULL
},
127 /* Both SearchPath and FileName */
128 { L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe", NULL
, L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
129 { L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
130 { L
"C:\\%ls\\Folder1\\", L
"SomeProgram", NULL
, NULL
, NULL
},
131 { L
"C:\\%ls\\Folder1\\", L
"SomeProgram", L
".exe", L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
132 { L
"C:\\%ls\\Folder1", L
"SomeProgram.exe", NULL
, L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
133 { L
"C:\\%ls\\Folder1", L
"SomeProgram.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
134 { L
"C:\\%ls\\Folder1", L
"SomeProgram", NULL
, NULL
, NULL
},
135 { L
"C:\\%ls\\Folder1", L
"SomeProgram", L
".exe", L
"C:\\%ls\\Folder1\\", L
"SomeProgram.exe" },
136 /* Full path to file in SearchPath doesn't work */
137 { L
"C:\\%ls\\Folder1\\SomeProgram.exe", L
"", NULL
, NULL
, NULL
},
139 { L
"C:\\%ls\\Folder1\\SomeProgram.exe", L
"", L
".exe", NULL
, NULL
},
140 { L
"C:\\%ls\\Folder1\\SomeProgram", L
"", NULL
, NULL
, NULL
},
141 { L
"C:\\%ls\\Folder1\\SomeProgram", L
"", L
".exe", NULL
, NULL
},
143 { L
"C:\\%ls\\Folder1", L
"File1", NULL
, L
"C:\\%ls\\Folder1\\", L
"File1" },
144 { L
"C:\\%ls\\CurrentDirectory", L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
145 { L
"C:\\%ls\\Folder1 ", L
"File1", NULL
, NULL
, NULL
},
146 { L
"C:\\%ls\\CurrentDirectory ",L
"File1", NULL
, NULL
, NULL
},
147 { L
" C:\\%ls\\Folder1", L
"File1", NULL
, NULL
, NULL
},
148 { L
" C:\\%ls\\CurrentDirectory",L
"File1", NULL
, NULL
, NULL
},
149 { L
" C:\\%ls\\Folder1 ", L
"File1", NULL
, NULL
, NULL
},
151 { L
" C:\\%ls\\CurrentDirectory ",L
"File1", NULL
, NULL
, NULL
},
152 /* Multiple search paths */
153 { L
"C:\\%ls\\Folder1;C:\\%ls\\CurrentDirectory",
154 L
"File1", NULL
, L
"C:\\%ls\\Folder1\\", L
"File1" },
155 { L
"C:\\%ls\\CurrentDirectory;C:\\%ls\\Folder1",
156 L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
157 { L
"C:\\%ls\\CurrentDirectory ; C:\\%ls\\Folder1",
158 L
"File1", NULL
, NULL
, NULL
},
159 { L
"C:\\%ls\\CurrentDirectory ;C:\\%ls\\Folder1",
160 L
"File1", NULL
, L
"C:\\%ls\\Folder1\\", L
"File1" },
161 { L
"C:\\%ls\\CurrentDirectory; C:\\%ls\\Folder1",
162 L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
163 { L
";C:\\%ls\\Folder1", L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
164 { L
";C:\\%ls\\Folder1;", L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
165 { L
";C:\\%ls\\Folder1;", L
"File1", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"File1" },
166 { L
"C:\\%ls\\Folder1", L
"OnlyInCurr", NULL
, NULL
, NULL
},
168 { L
"", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
169 { L
"", L
"OnlyInCurr ", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
170 { L
"", L
" OnlyInCurr", NULL
, NULL
, NULL
},
171 { L
" ", L
"OnlyInCurr", NULL
, NULL
, NULL
},
172 { L
";", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
173 { L
"; ", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
174 { L
" ;", L
"OnlyInCurr", NULL
, NULL
, NULL
},
175 { L
" ; ", L
"OnlyInCurr", NULL
, NULL
, NULL
},
176 { L
";C:\\%ls\\Folder1", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
177 { L
"C:\\%ls\\Folder1;", L
"OnlyInCurr", NULL
, NULL
, NULL
},
179 { L
"C:\\%ls\\Folder1;;", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
180 { L
";C:\\%ls\\Folder1;", L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
181 { L
"C:\\%ls\\Folder1;C:\\%ls\\Folder2",
182 L
"OnlyInCurr", NULL
, NULL
, NULL
},
183 { L
";C:\\%ls\\Folder1;C:\\%ls\\Folder2",
184 L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
185 { L
"C:\\%ls\\Folder1;;C:\\%ls\\Folder2",
186 L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
187 { L
"C:\\%ls\\Folder1;C:\\%ls\\Folder2;",
188 L
"OnlyInCurr", NULL
, NULL
, NULL
},
189 { L
"C:\\%ls\\Folder1;C:\\%ls\\Folder2;;",
190 L
"OnlyInCurr", NULL
, L
"C:\\%ls\\CurrentDirectory\\", L
"OnlyInCurr" },
191 /* Spaces in FileName! */
192 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram With Spaces",
193 L
".exe", NULL
, NULL
},
194 { L
"", L
"C:\\%ls\\Folder1\\SomeProgram With Spaces.exe",
195 L
".exe", NULL
, NULL
},
196 { L
"", L
"C:\\%ls\\Folder1\\Program", L
".exe", NULL
, NULL
},
198 { L
"", L
"C:\\%ls\\Folder1\\Program.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program.exe" },
199 { L
"", L
"C:\\%ls\\Folder1\\Program With", L
".exe", NULL
, NULL
},
200 { L
"", L
"C:\\%ls\\Folder1\\Program With.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With.exe" },
201 { L
"", L
"C:\\%ls\\Folder1\\Program With Spaces",L
".exe", NULL
, NULL
},
202 { L
"", L
"C:\\%ls\\Folder1\\Program With Spaces.exe",
203 L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With Spaces.exe" },
204 /* Same tests with path in SearchPath - now extensions are appended */
205 { L
"C:\\%ls\\Folder1", L
"SomeProgram With Spaces",
206 L
".exe", NULL
, NULL
},
207 { L
"C:\\%ls\\Folder1", L
"SomeProgram With Spaces.exe",
208 L
".exe", NULL
, NULL
},
209 { L
"C:\\%ls\\Folder1", L
"Program", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program.exe" },
210 { L
"C:\\%ls\\Folder1", L
"Program.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program.exe" },
211 { L
"C:\\%ls\\Folder1", L
"Program With", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With.exe" },
213 { L
"C:\\%ls\\Folder1", L
"Program With.exe", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With.exe" },
214 { L
"C:\\%ls\\Folder1", L
"Program With Spaces", L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With Spaces.exe" },
215 { L
"C:\\%ls\\Folder1", L
"Program With Spaces.exe",
216 L
".exe", L
"C:\\%ls\\Folder1\\", L
"Program With Spaces.exe" },
222 WCHAR SearchPath
[MAX_PATH
];
223 WCHAR FileName
[MAX_PATH
];
224 WCHAR ResultPath
[MAX_PATH
];
225 WCHAR Buffer
[MAX_PATH
];
228 for (i
= 0; i
< sizeof(Tests
) / sizeof(Tests
[0]); i
++)
230 swprintf(SearchPath
, Tests
[i
].SearchPath
, CustomPath
, CustomPath
, CustomPath
, CustomPath
);
231 swprintf(FileName
, Tests
[i
].FileName
, CustomPath
, CustomPath
, CustomPath
, CustomPath
);
232 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
233 PartName
= InvalidPointer
;
236 Length
= RtlDosSearchPath_U(SearchPath
,
242 EndSeh(STATUS_SUCCESS
);
244 if (Tests
[i
].ResultPath
)
246 swprintf(ResultPath
, Tests
[i
].ResultPath
, CustomPath
, CustomPath
, CustomPath
, CustomPath
);
247 if (Tests
[i
].ResultFileName
)
249 ok(PartName
== &Buffer
[wcslen(ResultPath
)],
250 "PartName = %p (%ls), expected %p\n",
251 PartName
, PrintablePointer(PartName
), &Buffer
[wcslen(ResultPath
)]);
252 wcscat(ResultPath
, Tests
[i
].ResultFileName
);
257 "PartName = %p (%ls), expected NULL\n",
258 PartName
, PrintablePointer(PartName
));
260 Okay
= CheckStringBuffer(Buffer
, Length
, sizeof(Buffer
), ResultPath
);
261 ok(Okay
== TRUE
, "CheckStringBuffer failed. Got '%ls', expected '%ls'\n", Buffer
, ResultPath
);
265 Okay
= CheckBuffer(Buffer
, sizeof(Buffer
), 0x55);
266 ok(Okay
== TRUE
, "CheckBuffer failed\n");
267 ok(Length
== 0, "Length = %lu\n", Length
);
268 ok(PartName
== InvalidPointer
,
269 "PartName = %p (%ls), expected %p\n",
270 PartName
, PrintablePointer(PartName
), InvalidPointer
);
275 #define MAKE_DIRECTORY(path) \
277 swprintf(FileName, path, CustomPath); \
278 Success = CreateDirectoryW(FileName, NULL); \
279 ok(Success, "CreateDirectory failed, results might not be accurate\n"); \
282 #define MAKE_FILE(path) \
284 swprintf(FileName, path, CustomPath); \
285 Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); \
286 ok(Handle != INVALID_HANDLE_VALUE, \
287 "CreateFile failed, results might not be accurate\n"); \
288 if (Handle != INVALID_HANDLE_VALUE) CloseHandle(Handle); \
291 #define DELETE_DIRECTORY(path) \
293 swprintf(FileName, path, CustomPath); \
294 Success = RemoveDirectoryW(FileName); \
296 "RemoveDirectory failed (%lu), test might leave stale directory\n", \
300 #define DELETE_FILE(path) \
302 swprintf(FileName, path, CustomPath); \
303 Success = DeleteFileW(FileName); \
305 "DeleteFile failed (%lu), test might leave stale file\n", \
309 START_TEST(RtlDosSearchPath_U
)
312 WCHAR Buffer
[MAX_PATH
];
316 WCHAR FileName
[MAX_PATH
];
317 WCHAR CustomPath
[MAX_PATH
] = L
"RtlDosSearchPath_U_TestPath";
320 swprintf(FileName
, L
"C:\\%ls", CustomPath
);
321 /* Make sure this directory doesn't exist */
322 while (GetFileAttributesW(FileName
) != INVALID_FILE_ATTRIBUTES
)
324 wcscat(CustomPath
, L
"X");
325 swprintf(FileName
, L
"C:\\%ls", CustomPath
);
327 Success
= CreateDirectoryW(FileName
, NULL
);
328 ok(Success
, "CreateDirectory failed, results might not be accurate\n");
330 MAKE_DIRECTORY(L
"C:\\%ls\\Folder1");
331 MAKE_DIRECTORY(L
"C:\\%ls\\Folder2");
332 MAKE_DIRECTORY(L
"C:\\%ls\\CurrentDirectory");
333 Success
= SetCurrentDirectoryW(FileName
);
334 ok(Success
, "SetCurrentDirectory failed\n");
335 MAKE_FILE(L
"C:\\%ls\\Folder1\\File1");
336 MAKE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram.exe");
337 MAKE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram2.exe");
338 MAKE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram2.exe.exe");
339 MAKE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram3.exe.exe");
340 MAKE_FILE(L
"C:\\%ls\\Folder1\\Program.exe");
341 MAKE_FILE(L
"C:\\%ls\\Folder1\\Program With.exe");
342 MAKE_FILE(L
"C:\\%ls\\Folder1\\Program With Spaces.exe");
343 MAKE_FILE(L
"C:\\%ls\\CurrentDirectory\\File1");
344 MAKE_FILE(L
"C:\\%ls\\CurrentDirectory\\OnlyInCurr");
346 /* NULL parameters */
347 StartSeh() RtlDosSearchPath_U(NULL
, NULL
, NULL
, 0, NULL
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
348 StartSeh() RtlDosSearchPath_U(NULL
, L
"" , NULL
, 0, NULL
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
349 StartSeh() RtlDosSearchPath_U(NULL
, L
"" , NULL
, 0, Buffer
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
350 StartSeh() RtlDosSearchPath_U(NULL
, L
"" , NULL
, 1, Buffer
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
351 StartSeh() RtlDosSearchPath_U(NULL
, L
"" , NULL
, 2, Buffer
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
352 StartSeh() RtlDosSearchPath_U(L
"" , NULL
, NULL
, 0, NULL
, NULL
); EndSeh(STATUS_ACCESS_VIOLATION
);
354 /* Empty strings - first one that doesn't crash */
356 Length
= RtlDosSearchPath_U(L
"", L
"", NULL
, 0, NULL
, NULL
);
357 ok(Length
== 0, "Length %lu\n", Length
);
358 EndSeh(STATUS_SUCCESS
);
360 /* Check what's initialized */
361 PartName
= InvalidPointer
;
363 Length
= RtlDosSearchPath_U(L
"", L
"", NULL
, 0, NULL
, &PartName
);
364 ok(Length
== 0, "Length = %lu\n", Length
);
365 EndSeh(STATUS_SUCCESS
);
366 ok(PartName
== InvalidPointer
, "PartName = %p\n", PartName
);
368 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
370 Length
= RtlDosSearchPath_U(L
"", L
"", NULL
, sizeof(Buffer
), Buffer
, NULL
);
371 ok(Length
== 0, "Length %lu\n", Length
);
372 EndSeh(STATUS_SUCCESS
);
373 Okay
= CheckBuffer(Buffer
, sizeof(Buffer
), 0x55);
374 ok(Okay
, "CheckBuffer failed\n");
376 PartName
= InvalidPointer
;
377 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
379 Length
= RtlDosSearchPath_U(L
"", L
"", NULL
, sizeof(Buffer
), Buffer
, &PartName
);
380 ok(Length
== 0, "Length %lu\n", Length
);
381 EndSeh(STATUS_SUCCESS
);
382 ok(PartName
== InvalidPointer
, "PartName = %p\n", PartName
);
383 Okay
= CheckBuffer(Buffer
, sizeof(Buffer
), 0x55);
384 ok(Okay
, "CheckBuffer failed\n");
386 /* Now test the actual functionality */
387 RunTestCases(CustomPath
);
390 * Clean up test folder - We can't delete it
391 * if our current directory is inside.
393 SetCurrentDirectoryW(L
"C:\\");
394 DELETE_FILE(L
"C:\\%ls\\CurrentDirectory\\OnlyInCurr");
395 DELETE_FILE(L
"C:\\%ls\\CurrentDirectory\\File1");
396 DELETE_FILE(L
"C:\\%ls\\Folder1\\Program With Spaces.exe");
397 DELETE_FILE(L
"C:\\%ls\\Folder1\\Program With.exe");
398 DELETE_FILE(L
"C:\\%ls\\Folder1\\Program.exe");
399 DELETE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram3.exe.exe");
400 DELETE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram2.exe.exe");
401 DELETE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram2.exe");
402 DELETE_FILE(L
"C:\\%ls\\Folder1\\SomeProgram.exe");
403 DELETE_FILE(L
"C:\\%ls\\Folder1\\File1");
404 DELETE_DIRECTORY(L
"C:\\%ls\\CurrentDirectory");
405 DELETE_DIRECTORY(L
"C:\\%ls\\Folder2");
406 DELETE_DIRECTORY(L
"C:\\%ls\\Folder1");
407 DELETE_DIRECTORY(L
"C:\\%ls");