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 } 363