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