[NTDLL_APITESTS]
[reactos.git] / rostests / apitests / ntdll / RtlDoesFileExists.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlDoesFileExists_U*
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #include <stdio.h>
12 #include <ndk/rtlfuncs.h>
13
14 #define ok_bool_file(value, expected, file) do { \
15 if (expected) \
16 ok(value == TRUE, "File '%ls' should exist, but does not\n", file); \
17 else \
18 ok(value == FALSE, "File '%ls' should not exist, but does\n", file);\
19 } while (0)
20
21 #define ok_eq_ustr(str1, str2) do { \
22 ok((str1)->Buffer == (str2)->Buffer, "Buffer modified\n"); \
23 ok((str1)->Length == (str2)->Length, "Length modified\n"); \
24 ok((str1)->MaximumLength == (str2)->MaximumLength, "MaximumLength modified\n"); \
25 } while (0)
26
27 /*
28 BOOLEAN
29 NTAPI
30 RtlDoesFileExists_U(
31 IN PCWSTR FileName
32 );
33
34 BOOLEAN
35 NTAPI
36 RtlDoesFileExists_UEx(
37 IN PCWSTR FileName,
38 IN BOOLEAN SucceedIfBusy
39 );
40
41 BOOLEAN
42 NTAPI
43 RtlDoesFileExists_UStr(
44 IN PUNICODE_STRING FileName
45 );
46
47 BOOLEAN
48 NTAPI
49 RtlDoesFileExists_UstrEx(
50 IN PCUNICODE_STRING FileName,
51 IN BOOLEAN SucceedIfBusy
52 );
53 */
54
55 static
56 BOOLEAN
57 (NTAPI
58 *RtlDoesFileExists_UEx)(
59 IN PCWSTR FileName,
60 IN BOOLEAN SucceedIfBusy
61 )
62 //= (PVOID)0x7c8187d0 // 2003 sp1 x86
63 //= (PVOID)0x7769aeb2 // win7 sp1 wow64
64 ;
65
66 static
67 BOOLEAN
68 (NTAPI
69 *RtlDoesFileExists_UStr)(
70 IN PUNICODE_STRING FileName
71 )
72 //= (PVOID)0x7c8474e5 // 2003 sp1 x86
73 //= (PVOID)0x776ff304 // win7 sp1 wow64
74 ;
75
76 static
77 BOOLEAN
78 (NTAPI
79 *RtlDoesFileExists_UstrEx)(
80 IN PCUNICODE_STRING FileName,
81 IN BOOLEAN SucceedIfBusy
82 )
83 //= (PVOID)0x7c830f89 // 2003 sp1 x86
84 //= (PVOID)0x7769addb // win7 sp1 wow64
85 ;
86
87 START_TEST(RtlDoesFileExists)
88 {
89 BOOLEAN Ret;
90 struct
91 {
92 PCWSTR FileName;
93 BOOLEAN Exists;
94 } Tests[] =
95 {
96 { L"", FALSE },
97 { L"?", FALSE },
98 { L"*", FALSE },
99 { L":", FALSE },
100 { L";", FALSE },
101 { L"\"", FALSE },
102 { L".", TRUE },
103 { L"..", TRUE },
104 { L"/", TRUE },
105 { L"//", FALSE },
106 { L"///", FALSE },
107 { L"\\/", FALSE },
108 { L"\\//", FALSE },
109 { L"\\\\/", FALSE },
110 { L"\\/\\", FALSE },
111 { L"\\/\\\\", FALSE },
112 { L"\\/\\/\\", FALSE },
113 { L"\\", TRUE },
114 { L"\\\\", FALSE },
115 { L"\\\\\\", FALSE },
116 { L"\\\\.", FALSE },
117 { L"\\\\.\\", FALSE },
118 { L"\\\\.\\GLOBAL??", FALSE },
119 { L"\\\\.\\GLOBAL??\\", FALSE },
120 { L"\\\\?", FALSE },
121 { L"\\\\??", FALSE },
122 { L"\\\\??\\", FALSE },
123 { L"\\\\??\\C:\\", FALSE },
124 { L"\\\\.", FALSE },
125 { L"\\\\.\\", FALSE },
126 { L"C:", TRUE },
127 { L"C:/", TRUE },
128 { L"C:/\\", TRUE },
129 { L"C:\\/", TRUE },
130 { L"C:\\/\\", TRUE },
131 { L"C://", TRUE },
132 { L"C:\\", TRUE },
133 { L"C:\\\\", TRUE },
134 { L"C:\\%ls", TRUE },
135 { L"C:/%ls", TRUE },
136 { L"C://%ls", TRUE },
137 { L"C:\\/%ls", TRUE },
138 { L"C:/\\%ls", TRUE },
139 { L"C:\\/\\%ls", TRUE },
140 { L"C:\\%ls\\", TRUE },
141 { L"C:\\%ls\\ThisFolderExists", TRUE },
142 { L"C:\\%ls\\ThisFolderExists\\", TRUE },
143 { L"C:\\%ls\\ThisFolderExists ", TRUE },
144 { L"C:\\%ls\\ThisFolderExists ", TRUE },
145 { L"C:\\%ls\\ThisFolderExists ", TRUE },
146 { L"C:\\%ls\\ThisFolderExists:", FALSE },
147 { L"C:\\%ls\\ThisFolderExists\t", FALSE },
148 { L"C:\\%ls\\ThisFolderExists\n", FALSE },
149 { L"C:\\%ls\\ThisFolderExists\r", FALSE },
150 { L" C:\\%ls\\ThisFolderExists", FALSE },
151 { L"C:\\%ls\\ ThisFolderExists", FALSE },
152 { L"C:\\%ls \\ThisFolderExists", FALSE },
153 { L"C:\\%ls\\ThisDoesntExist", FALSE },
154 { L"C:\\\\%ls\\\\ThisFolderExists", TRUE },
155 { L"C:\\%ls\\ThisFolderExists\\ThisFileExists", TRUE },
156 { L"c:\\%ls\\thisfolderexists\\thisfileexists", TRUE },
157 { L"C:\\%ls\\THISFOLDEREXISTS\\THISFILEEXISTS", TRUE },
158 { L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe",TRUE },
159 { L"C:\\%ls\\ThisFolderExists\\SomeProgram", FALSE },
160 { L"C:\\%ls\\ThisFolderExists\\With", FALSE },
161 { L"C:\\%ls\\ThisFolderExists\\With Space", TRUE },
162 { L"C:\\%ls\\ThisFolderExists\\Without", TRUE },
163 { L"C:\\%ls\\ThisFolderExists\\Without Space", FALSE },
164 { L"C:\\%ls abc", FALSE },
165 { L"\"C:\\%ls\" abc", FALSE },
166 { L"\"C:\\\"", FALSE },
167 { L"C:\\%ls;C:\\", FALSE },
168 { L"%%SystemRoot%%", FALSE },
169 { L"%%SystemRoot%%\\", FALSE },
170 { L"%%SystemRoot%%\\system32", FALSE },
171 { L"NUL", FALSE },
172 { L"CON", FALSE },
173 { L"COM1", FALSE },
174 { L"\\?", FALSE },
175 { L"\\??", FALSE },
176 { L"\\??\\", FALSE },
177 { L"\\??\\C", FALSE },
178 { L"\\??\\C:", FALSE },
179 { L"\\??\\C:\\", FALSE }, // TRUE on Win7
180 { L"\\??\\C:\\%ls\\ThisFolderExists", FALSE }, // TRUE on Win7
181 };
182 ULONG i;
183 WCHAR FileName[MAX_PATH];
184 WCHAR CustomPath[MAX_PATH] = L"RtlDoesFileExists_U_TestPath";
185 BOOL Success;
186 HANDLE Handle;
187
188 if (!RtlDoesFileExists_UEx)
189 {
190 RtlDoesFileExists_UEx = (PVOID)GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlDoesFileExists_UEx");
191 if (!RtlDoesFileExists_UEx)
192 skip("RtlDoesFileExists_UEx unavailable\n");
193 }
194
195 if (!RtlDoesFileExists_UStr)
196 {
197 RtlDoesFileExists_UStr = (PVOID)GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlDoesFileExists_UStr");
198 if (!RtlDoesFileExists_UStr)
199 skip("RtlDoesFileExists_UStr unavailable\n");
200 }
201
202 if (!RtlDoesFileExists_UstrEx)
203 {
204 RtlDoesFileExists_UstrEx = (PVOID)GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlDoesFileExists_UstrEx");
205 if (!RtlDoesFileExists_UstrEx)
206 skip("RtlDoesFileExists_UstrEx unavailable\n");
207 }
208
209 StartSeh()
210 Ret = RtlDoesFileExists_U(NULL);
211 ok(Ret == FALSE, "NULL file exists?!\n");
212 EndSeh(STATUS_SUCCESS);
213
214 if (RtlDoesFileExists_UEx)
215 {
216 StartSeh()
217 Ret = RtlDoesFileExists_UEx(NULL, TRUE);
218 ok(Ret == FALSE, "NULL file exists?!\n");
219 Ret = RtlDoesFileExists_UEx(NULL, FALSE);
220 ok(Ret == FALSE, "NULL file exists?!\n");
221 EndSeh(STATUS_SUCCESS);
222 }
223
224 if (RtlDoesFileExists_UStr)
225 {
226 StartSeh() Ret = RtlDoesFileExists_UStr(NULL); EndSeh(STATUS_ACCESS_VIOLATION);
227 }
228
229 if (RtlDoesFileExists_UstrEx)
230 {
231 StartSeh() RtlDoesFileExists_UstrEx(NULL, FALSE); EndSeh(STATUS_ACCESS_VIOLATION);
232 StartSeh() RtlDoesFileExists_UstrEx(NULL, TRUE); EndSeh(STATUS_ACCESS_VIOLATION);
233 }
234
235 swprintf(FileName, L"C:\\%ls", CustomPath);
236 /* Make sure this directory doesn't exist */
237 while (GetFileAttributesW(FileName) != INVALID_FILE_ATTRIBUTES)
238 {
239 wcscat(CustomPath, L"X");
240 swprintf(FileName, L"C:\\%ls", CustomPath);
241 }
242 Success = CreateDirectoryW(FileName, NULL);
243 ok(Success, "CreateDirectory failed, results might not be accurate\n");
244 swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath);
245 Success = CreateDirectoryW(FileName, NULL);
246 ok(Success, "CreateDirectory failed, results might not be accurate\n");
247 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath);
248 Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);
249 ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n");
250 if (Handle != INVALID_HANDLE_VALUE)
251 {
252 /* Check SucceedIfBusy behavior */
253 if (RtlDoesFileExists_UEx)
254 {
255 Ret = RtlDoesFileExists_UEx(FileName, TRUE);
256 ok_bool_file(Ret, TRUE, FileName);
257 /* TODO: apparently we have to do something worse to make this fail */
258 Ret = RtlDoesFileExists_UEx(FileName, FALSE);
259 ok_bool_file(Ret, TRUE, FileName);
260 }
261 if (RtlDoesFileExists_UstrEx)
262 {
263 UNICODE_STRING FileNameString;
264 UNICODE_STRING TempString;
265 RtlInitUnicodeString(&FileNameString, FileName);
266 TempString = FileNameString;
267 Ret = RtlDoesFileExists_UstrEx(&FileNameString, TRUE);
268 ok_eq_ustr(&FileNameString, &TempString);
269 ok_bool_file(Ret, TRUE, FileName);
270 /* TODO: apparently we have to do something worse to make this fail */
271 Ret = RtlDoesFileExists_UstrEx(&FileNameString, FALSE);
272 ok_eq_ustr(&FileNameString, &TempString);
273 ok_bool_file(Ret, TRUE, FileName);
274 }
275 CloseHandle(Handle);
276 }
277
278 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe", CustomPath);
279 Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);
280 ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n");
281 if (Handle != INVALID_HANDLE_VALUE) CloseHandle(Handle);
282
283 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\With Space", CustomPath);
284 Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);
285 ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n");
286 if (Handle != INVALID_HANDLE_VALUE) CloseHandle(Handle);
287
288 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\Without", CustomPath);
289 Handle = CreateFileW(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);
290 ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n");
291 if (Handle != INVALID_HANDLE_VALUE) CloseHandle(Handle);
292
293 for (i = 0; i < sizeof(Tests) / sizeof(Tests[0]); i++)
294 {
295 swprintf(FileName, Tests[i].FileName, CustomPath);
296 StartSeh()
297 Ret = RtlDoesFileExists_U(FileName);
298 ok_bool_file(Ret, Tests[i].Exists, FileName);
299 EndSeh(STATUS_SUCCESS);
300 if (RtlDoesFileExists_UEx)
301 {
302 StartSeh()
303 Ret = RtlDoesFileExists_UEx(FileName, TRUE);
304 ok_bool_file(Ret, Tests[i].Exists, FileName);
305 EndSeh(STATUS_SUCCESS);
306 StartSeh()
307 Ret = RtlDoesFileExists_UEx(FileName, FALSE);
308 ok_bool_file(Ret, Tests[i].Exists, FileName);
309 EndSeh(STATUS_SUCCESS);
310 }
311 /* TODO: use guarded memory to make sure these don't touch the null terminator */
312 if (RtlDoesFileExists_UStr)
313 {
314 UNICODE_STRING FileNameString;
315 UNICODE_STRING TempString;
316 RtlInitUnicodeString(&FileNameString, FileName);
317 TempString = FileNameString;
318 StartSeh()
319 Ret = RtlDoesFileExists_UStr(&FileNameString);
320 ok_bool_file(Ret, Tests[i].Exists, FileName);
321 EndSeh(STATUS_SUCCESS);
322 ok_eq_ustr(&FileNameString, &TempString);
323 }
324 if (RtlDoesFileExists_UstrEx)
325 {
326 UNICODE_STRING FileNameString;
327 UNICODE_STRING TempString;
328 RtlInitUnicodeString(&FileNameString, FileName);
329 TempString = FileNameString;
330 StartSeh()
331 Ret = RtlDoesFileExists_UstrEx(&FileNameString, TRUE);
332 ok_bool_file(Ret, Tests[i].Exists, FileName);
333 EndSeh(STATUS_SUCCESS);
334 ok_eq_ustr(&FileNameString, &TempString);
335 StartSeh()
336 Ret = RtlDoesFileExists_UstrEx(&FileNameString, FALSE);
337 ok_bool_file(Ret, Tests[i].Exists, FileName);
338 EndSeh(STATUS_SUCCESS);
339 ok_eq_ustr(&FileNameString, &TempString);
340 }
341 }
342
343 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\Without", CustomPath);
344 Success = DeleteFileW(FileName);
345 ok(Success, "DeleteFile failed (%lu), test might leave stale file\n", GetLastError());
346 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\With Space", CustomPath);
347 Success = DeleteFileW(FileName);
348 ok(Success, "DeleteFile failed (%lu), test might leave stale file\n", GetLastError());
349 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe", CustomPath);
350 Success = DeleteFileW(FileName);
351 ok(Success, "DeleteFile failed (%lu), test might leave stale file\n", GetLastError());
352
353 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath);
354 Success = DeleteFileW(FileName);
355 ok(Success, "DeleteFile failed (%lu), test might leave stale file\n", GetLastError());
356 swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath);
357 Success = RemoveDirectoryW(FileName);
358 ok(Success, "RemoveDirectory failed (%lu), test might leave stale directory\n", GetLastError());
359 swprintf(FileName, L"C:\\%ls", CustomPath);
360 Success = RemoveDirectoryW(FileName);
361 ok(Success, "RemoveDirectory failed (%lu), test might leave stale directory\n", GetLastError());
362 }