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