Index: dll/ntdll/def/ntdll.spec =================================================================== --- dll/ntdll/def/ntdll.spec (revision 56419) +++ dll/ntdll/def/ntdll.spec (working copy) @@ -563,9 +563,13 @@ @ stdcall RtlDestroyProcessParameters(ptr) @ stdcall RtlDestroyQueryDebugBuffer(ptr) @ stdcall RtlDetermineDosPathNameType_U(wstr) +@ stdcall RtlDetermineDosPathNameType_Ustr(ptr) @ stdcall RtlDllShutdownInProgress() @ stdcall RtlDnsHostNameToComputerName(ptr ptr long) @ stdcall RtlDoesFileExists_U(wstr) +@ stdcall RtlDoesFileExists_UEx(wstr long) +@ stdcall RtlDoesFileExists_UStr(ptr) +@ stdcall RtlDoesFileExists_UstrEx(ptr long) @ stdcall RtlDosApplyFileIsolationRedirection_Ustr(long ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlDosPathNameToNtPathName_U(wstr ptr ptr ptr) ;@ stdcall RtlDosPathNameToNtPathName_U_WithStatus ; 5.2 SP1, and higher @@ -662,6 +666,7 @@ @ stdcall RtlGetFirstRange(ptr ptr ptr) ;@ stdcall RtlGetFrame @ stdcall RtlGetFullPathName_U(wstr long ptr ptr) +@ stdcall RtlGetFullPathName_Ustr(ptr long ptr ptr ptr ptr) @ stdcall RtlGetFullPathName_UstrEx(ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) @ stdcall RtlGetLastNtStatus() Index: modules/rostests/apitests/ntdll/RtlDoesFileExists.c =================================================================== --- modules/rostests/apitests/ntdll/RtlDoesFileExists.c (revision 56561) +++ modules/rostests/apitests/ntdll/RtlDoesFileExists.c (working copy) @@ -144,11 +144,27 @@ { L"C:\\/\\%ls", TRUE }, { L"C:\\%ls\\", TRUE }, { L"C:\\%ls\\ThisFolderExists", TRUE }, + { L"C:\\%ls\\ThisFolderExists ", TRUE }, + { L"C:\\%ls\\ThisFolderExists ", TRUE }, + { L"C:\\%ls\\ThisFolderExists ", TRUE }, + { L"C:\\%ls\\ThisFolderExists:", FALSE }, + { L"C:\\%ls\\ThisFolderExists\t", FALSE }, + { L"C:\\%ls\\ThisFolderExists\n", FALSE }, + { L"C:\\%ls\\ThisFolderExists\r", FALSE }, + { L" C:\\%ls\\ThisFolderExists", FALSE }, + { L"C:\\%ls\\ ThisFolderExists", FALSE }, + { L"C:\\%ls \\ThisFolderExists", FALSE }, { L"C:\\%ls\\ThisDoesntExist", FALSE }, { L"C:\\\\%ls\\\\ThisFolderExists", TRUE }, { L"C:\\%ls\\ThisFolderExists\\ThisFileExists", TRUE }, { L"c:\\%ls\\thisfolderexists\\thisfileexists", TRUE }, { L"C:\\%ls\\THISFOLDEREXISTS\\THISFILEEXISTS", TRUE }, + { L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe",TRUE }, + { L"C:\\%ls\\ThisFolderExists\\SomeProgram", FALSE }, + { L"C:\\%ls\\ThisFolderExists\\With", FALSE }, + { L"C:\\%ls\\ThisFolderExists\\With Space", TRUE }, + { L"C:\\%ls\\ThisFolderExists\\Without", TRUE }, + { L"C:\\%ls\\ThisFolderExists\\Without Space", FALSE }, { L"C:\\%ls;C:\\", FALSE }, { L"%%SystemRoot%%", FALSE }, { L"%%SystemRoot%%\\", FALSE }, @@ -252,6 +268,21 @@ } CloseHandle(Handle); } + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe", CustomPath); + Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); + ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n"); + if (Handle != INVALID_HANDLE_VALUE) + CloseHandle(Handle); + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\With Space", CustomPath); + Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); + ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n"); + if (Handle != INVALID_HANDLE_VALUE) + CloseHandle(Handle); + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\Without", CustomPath); + Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); + ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n"); + if (Handle != INVALID_HANDLE_VALUE) + CloseHandle(Handle); for (i = 0; i < sizeof(Tests) / sizeof(Tests[0]); i++) { @@ -303,13 +334,22 @@ } } + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\Without", CustomPath); + Success = DeleteFile(FileName); + ok(Success, "DeleteFile failed, test might leave stale file\n"); + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\With Space", CustomPath); + Success = DeleteFile(FileName); + ok(Success, "DeleteFile failed, test might leave stale file\n"); + swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\SomeProgram.exe", CustomPath); + Success = DeleteFile(FileName); + ok(Success, "DeleteFile failed, test might leave stale file\n"); swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath); Success = DeleteFile(FileName); ok(Success, "DeleteFile failed, test might leave stale file\n"); swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath); Success = RemoveDirectory(FileName); - ok(Success, "RemoveDirectory failed, test might leave stale directory\n"); + ok(Success, "RemoveDirectory failed %(lu), test might leave stale directory\n", GetLastError()); swprintf(FileName, L"C:\\%ls", CustomPath); Success = RemoveDirectory(FileName); - ok(Success, "RemoveDirectory failed, test might leave stale directory\n"); + ok(Success, "RemoveDirectory failed (%lu), test might leave stale directory\n", GetLastError()); } Index: modules/rostests/apitests/ntdll/RtlDosSearchPath_U.c =================================================================== --- modules/rostests/apitests/ntdll/RtlDosSearchPath_U.c (revision 56561) +++ modules/rostests/apitests/ntdll/RtlDosSearchPath_U.c (working copy) @@ -97,11 +97,221 @@ } #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL) +#define PrintablePointer(p) ((p) == InvalidPointer ? NULL : (p)) +static +VOID +RunTestCases( + PCWSTR CustomPath) +{ + struct + { + PCWSTR SearchPath; + PCWSTR FileName; + PCWSTR Extension; + PCWSTR ResultPath; + PCWSTR ResultFileName; + } Tests[] = + { + { L"", L"", NULL, NULL, NULL }, + { L"C:\\%ls\\Folder1", L"File1", NULL, L"C:\\%ls\\Folder1\\", L"File1" }, + /* No path: current directory */ + { L"", L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + /* Full path as FileName */ + { L"", L"C:\\", NULL, L"C:\\", NULL }, + { L"", L"C:\\%ls\\Folder1", NULL, L"C:\\%ls\\", L"Folder1" }, + /* No FileName */ + { L"C:\\", L"", NULL, L"C:\\", NULL }, + { L"C:\\%ls\\Folder1", L"", NULL, L"C:\\%ls\\Folder1\\", NULL }, + /* Full path as FileName */ + { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe", NULL, L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe", L".exe", L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"", L"C:\\%ls\\Folder1\\SomeProgram", NULL, NULL, NULL }, + // 10 + { L"", L"C:\\%ls\\Folder1\\SomeProgram", L".exe", NULL, NULL }, + /* Both SearchPath and FileName */ + { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe", NULL, L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe", L".exe", L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"C:\\%ls\\Folder1\\", L"SomeProgram", NULL, NULL, NULL }, + { L"C:\\%ls\\Folder1\\", L"SomeProgram", L".exe", L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"C:\\%ls\\Folder1", L"SomeProgram.exe", NULL, L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"C:\\%ls\\Folder1", L"SomeProgram.exe", L".exe", L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + { L"C:\\%ls\\Folder1", L"SomeProgram", NULL, NULL, NULL }, + { L"C:\\%ls\\Folder1", L"SomeProgram", L".exe", L"C:\\%ls\\Folder1\\", L"SomeProgram.exe" }, + /* Full path to file in SearchPath doesn't work */ + { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"", NULL, NULL, NULL }, + // 20 + { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"", L".exe", NULL, NULL }, + { L"C:\\%ls\\Folder1\\SomeProgram", L"", NULL, NULL, NULL }, + { L"C:\\%ls\\Folder1\\SomeProgram", L"", L".exe", NULL, NULL }, + /* */ + { L"C:\\%ls\\Folder1", L"File1", NULL, L"C:\\%ls\\Folder1\\", L"File1" }, + { L"C:\\%ls\\CurrentDirectory", L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L"C:\\%ls\\Folder1 ", L"File1", NULL, NULL, NULL }, + { L"C:\\%ls\\CurrentDirectory ",L"File1", NULL, NULL, NULL }, + { L" C:\\%ls\\Folder1", L"File1", NULL, NULL, NULL }, + { L" C:\\%ls\\CurrentDirectory",L"File1", NULL, NULL, NULL }, + { L" C:\\%ls\\Folder1 ", L"File1", NULL, NULL, NULL }, + // 30 + { L" C:\\%ls\\CurrentDirectory ",L"File1", NULL, NULL, NULL }, + /* multiple search paths */ + { L"C:\\%ls\\Folder1;C:\\%ls\\CurrentDirectory", + L"File1", NULL, L"C:\\%ls\\Folder1\\", L"File1" }, + { L"C:\\%ls\\CurrentDirectory;C:\\%ls\\Folder1", + L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L"C:\\%ls\\CurrentDirectory ; C:\\%ls\\Folder1", + L"File1", NULL, NULL, NULL }, + { L"C:\\%ls\\CurrentDirectory ;C:\\%ls\\Folder1", + L"File1", NULL, L"C:\\%ls\\Folder1\\", L"File1" }, + { L"C:\\%ls\\CurrentDirectory; C:\\%ls\\Folder1", + L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L";C:\\%ls\\Folder1", L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L";C:\\%ls\\Folder1;", L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L";C:\\%ls\\Folder1;", L"File1", NULL, L"C:\\%ls\\CurrentDirectory\\", L"File1" }, + { L"C:\\%ls\\Folder1", L"OnlyInCurr", NULL, NULL, NULL }, + // 40 + { L"", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"", L"OnlyInCurr ", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"", L" OnlyInCurr", NULL, NULL, NULL }, + { L" ", L"OnlyInCurr", NULL, NULL, NULL }, + { L";", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"; ", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L" ;", L"OnlyInCurr", NULL, NULL, NULL }, + { L" ; ", L"OnlyInCurr", NULL, NULL, NULL }, + { L";C:\\%ls\\Folder1", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"C:\\%ls\\Folder1;", L"OnlyInCurr", NULL, NULL, NULL }, + // 50 + { L"C:\\%ls\\Folder1;;", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L";C:\\%ls\\Folder1;", L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2", + L"OnlyInCurr", NULL, NULL, NULL }, + { L";C:\\%ls\\Folder1;C:\\%ls\\Folder2", + L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"C:\\%ls\\Folder1;;C:\\%ls\\Folder2", + L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;", + L"OnlyInCurr", NULL, NULL, NULL }, + { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;;", + L"OnlyInCurr", NULL, L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" }, + /* Spaces in FileName! */ + { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces", + L".exe", NULL, NULL }, + { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces.exe", + L".exe", NULL, NULL }, + { L"", L"C:\\%ls\\Folder1\\Program", L".exe", NULL, NULL }, + // 60 + { L"", L"C:\\%ls\\Folder1\\Program.exe", L".exe", L"C:\\%ls\\Folder1\\", L"Program.exe" }, + { L"", L"C:\\%ls\\Folder1\\Program With", L".exe", NULL, NULL }, + { L"", L"C:\\%ls\\Folder1\\Program With.exe", L".exe", L"C:\\%ls\\Folder1\\", L"Program With.exe" }, + { L"", L"C:\\%ls\\Folder1\\Program With Spaces",L".exe", NULL, NULL }, + { L"", L"C:\\%ls\\Folder1\\Program With Spaces.exe", + L".exe", L"C:\\%ls\\Folder1\\", L"Program With Spaces.exe" }, + /* Same tests with path in SearchPath - now extensions are appended */ + { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces", + L".exe", NULL, NULL }, + { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces.exe", + L".exe", NULL, NULL }, + { L"C:\\%ls\\Folder1", L"Program", L".exe", L"C:\\%ls\\Folder1\\", L"Program.exe" }, + { L"C:\\%ls\\Folder1", L"Program.exe", L".exe", L"C:\\%ls\\Folder1\\", L"Program.exe" }, + { L"C:\\%ls\\Folder1", L"Program With", L".exe", L"C:\\%ls\\Folder1\\", L"Program With.exe" }, + // 70 + { L"C:\\%ls\\Folder1", L"Program With.exe", L".exe", L"C:\\%ls\\Folder1\\", L"Program With.exe" }, + { L"C:\\%ls\\Folder1", L"Program With Spaces", L".exe", L"C:\\%ls\\Folder1\\", L"Program With Spaces.exe" }, + { L"C:\\%ls\\Folder1", L"Program With Spaces.exe", + L".exe", L"C:\\%ls\\Folder1\\", L"Program With Spaces.exe" }, + }; + ULONG Length; + PWSTR PartName; + WCHAR SearchPath[MAX_PATH]; + WCHAR FileName[MAX_PATH]; + WCHAR ResultPath[MAX_PATH]; + ULONG i; + WCHAR Buffer[MAX_PATH]; + BOOLEAN Okay; + + for (i = 0; i < sizeof(Tests) / sizeof(Tests[0]); i++) + { + trace("i = %d\n", i); + swprintf(SearchPath, Tests[i].SearchPath, CustomPath, CustomPath, CustomPath, CustomPath); + swprintf(FileName, Tests[i].FileName, CustomPath, CustomPath, CustomPath, CustomPath); + RtlFillMemory(Buffer, sizeof(Buffer), 0x55); + PartName = InvalidPointer; + Length = RtlDosSearchPath_U(SearchPath, + FileName, + Tests[i].Extension, + sizeof(Buffer), + Buffer, + &PartName); + if (Tests[i].ResultPath) + { + swprintf(ResultPath, Tests[i].ResultPath, CustomPath, CustomPath, CustomPath, CustomPath); + if (Tests[i].ResultFileName) + { + ok(PartName == &Buffer[wcslen(ResultPath)], + "PartName = %p (%ls), expected %p\n", + PartName, PrintablePointer(PartName), &Buffer[wcslen(ResultPath)]); + wcscat(ResultPath, Tests[i].ResultFileName); + } + else + { + ok(PartName == NULL, + "PartName = %p (%ls), expected NULL\n", + PartName, PrintablePointer(PartName)); + } + Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), ResultPath); + ok(Okay == TRUE, "CheckStringBuffer failed. Got '%ls', expected '%ls'\n", Buffer, ResultPath); + } + else + { + Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55); + ok(Okay == TRUE, "CheckBuffer failed\n"); + ok(Length == 0, "Length = %lu\n", Length); + ok(PartName == InvalidPointer, + "PartName = %p (%ls), expected %p\n", + PartName, PrintablePointer(PartName), InvalidPointer); + } + } +} + +#define MAKE_DIRECTORY(path) do \ +{ \ + swprintf(FileName, path, CustomPath); \ + Success = CreateDirectory(FileName, NULL); \ + ok(Success, "CreateDirectory failed, results might not be accurate\n"); \ +} while (0) + +#define MAKE_FILE(path) do \ +{ \ + swprintf(FileName, path, CustomPath); \ + Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); \ + ok(Handle != INVALID_HANDLE_VALUE, \ + "CreateFile failed, results might not be accurate\n"); \ + if (Handle != INVALID_HANDLE_VALUE) \ + CloseHandle(Handle); \ +} while (0) + +#define DELETE_DIRECTORY(path) do \ +{ \ + swprintf(FileName, path, CustomPath); \ + Success = RemoveDirectory(FileName); \ + ok(Success, \ + "RemoveDirectory failed (%lu), test might leave stale directory\n", \ + GetLastError()); \ +} while (0) + +#define DELETE_FILE(path) do \ +{ \ + swprintf(FileName, path, CustomPath); \ + Success = DeleteFile(FileName); \ + ok(Success, \ + "DeleteFile failed (%lu), test might leave stale file\n", \ + GetLastError()); \ +} while (0) + START_TEST(RtlDosSearchPath_U) { NTSTATUS ExceptionStatus; - ULONG Length; + ULONG Length = 0; WCHAR Buffer[MAX_PATH]; PWSTR PartName; BOOLEAN Okay; @@ -119,22 +329,29 @@ } Success = CreateDirectory(FileName, NULL); ok(Success, "CreateDirectory failed, results might not be accurate\n"); - swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath); - Success = CreateDirectory(FileName, NULL); - ok(Success, "CreateDirectory failed, results might not be accurate\n"); - swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath); - Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL); - ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n"); - if (Handle != INVALID_HANDLE_VALUE) - CloseHandle(Handle); + MAKE_DIRECTORY(L"C:\\%ls\\Folder1"); + MAKE_DIRECTORY(L"C:\\%ls\\Folder2"); + MAKE_DIRECTORY(L"C:\\%ls\\CurrentDirectory"); + Success = SetCurrentDirectory(FileName); + ok(Success, "SetCurrentDirectory failed\n"); + MAKE_FILE(L"C:\\%ls\\Folder1\\File1"); + MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\SomeProgram3.exe.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\Program.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\Program With.exe"); + MAKE_FILE(L"C:\\%ls\\Folder1\\Program With Spaces.exe"); + MAKE_FILE(L"C:\\%ls\\CurrentDirectory\\File1"); + MAKE_FILE(L"C:\\%ls\\CurrentDirectory\\OnlyInCurr"); /* NULL parameters */ - StartSeh() RtlDosSearchPath_U(NULL, NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 0, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 1, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 2, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh() Length = RtlDosSearchPath_U(L"", NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(NULL, NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(NULL, L"", NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(NULL, L"", NULL, 0, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(NULL, L"", NULL, 1, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(NULL, L"", NULL, 2, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() RtlDosSearchPath_U(L"", NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); /* Empty strings - first one that doesn't crash */ StartSeh() @@ -168,52 +385,24 @@ Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55); ok(Okay, "CheckBuffer failed\n"); - /* Empty path string searches in current directory */ - swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath); - Success = SetCurrentDirectory(FileName); - ok(Success, "SetCurrentDirectory failed\n"); - PartName = InvalidPointer; - RtlFillMemory(Buffer, sizeof(Buffer), 0x55); - StartSeh() - Length = RtlDosSearchPath_U(L"", L"ThisFileExists", NULL, sizeof(Buffer), Buffer, &PartName); - ok(Length == wcslen(FileName) * sizeof(WCHAR) + sizeof(L"\\ThisFileExists") - sizeof(UNICODE_NULL), "Length %lu\n", Length); - EndSeh(STATUS_SUCCESS); - ok(PartName == &Buffer[wcslen(FileName) + 1], "PartName = %p\n", PartName); - wcscat(FileName, L"\\ThisFileExists"); - Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), FileName); - ok(Okay, "CheckStringBuffer failed\n"); + /* Now test the actual functionality */ + RunTestCases(CustomPath); - /* Absolute path in FileName is also okay */ - PartName = InvalidPointer; - RtlFillMemory(Buffer, sizeof(Buffer), 0x55); - StartSeh() - Length = RtlDosSearchPath_U(L"", L"C:\\", NULL, sizeof(Buffer), Buffer, &PartName); - ok(Length == sizeof(L"C:\\") - sizeof(UNICODE_NULL), "Length %lu\n", Length); - EndSeh(STATUS_SUCCESS); - ok(PartName == NULL, "PartName = %p\n", PartName); - Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), L"C:\\"); - ok(Okay, "CheckStringBuffer failed\n"); - - /* Empty FileName also works */ - PartName = InvalidPointer; - RtlFillMemory(Buffer, sizeof(Buffer), 0x55); - StartSeh() - Length = RtlDosSearchPath_U(L"C:\\", L"", NULL, sizeof(Buffer), Buffer, &PartName); - ok(Length == sizeof(L"C:\\") - sizeof(UNICODE_NULL), "Length %lu\n", Length); - EndSeh(STATUS_SUCCESS); - ok(PartName == NULL, "PartName = %p\n", PartName); - Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), L"C:\\"); - ok(Okay, "CheckStringBuffer failed\n"); - /* Clean up test folder */ + /* We can't delete it if our current directory is inside */ SetCurrentDirectory(L"C:\\"); - swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath); - Success = DeleteFile(FileName); - ok(Success, "DeleteFile failed, test might leave stale file\n"); - swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath); - Success = RemoveDirectory(FileName); - ok(Success, "RemoveDirectory failed %(lu), test might leave stale directory\n", GetLastError()); - swprintf(FileName, L"C:\\%ls", CustomPath); - Success = RemoveDirectory(FileName); - ok(Success, "RemoveDirectory failed (%lu), test might leave stale directory\n", GetLastError()); + DELETE_FILE(L"C:\\%ls\\CurrentDirectory\\OnlyInCurr"); + DELETE_FILE(L"C:\\%ls\\CurrentDirectory\\File1"); + DELETE_FILE(L"C:\\%ls\\Folder1\\Program With Spaces.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\Program With.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\Program.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram3.exe.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram2.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\SomeProgram.exe"); + DELETE_FILE(L"C:\\%ls\\Folder1\\File1"); + DELETE_DIRECTORY(L"C:\\%ls\\CurrentDirectory"); + DELETE_DIRECTORY(L"C:\\%ls\\Folder2"); + DELETE_DIRECTORY(L"C:\\%ls\\Folder1"); + DELETE_DIRECTORY(L"C:\\%ls"); } Index: modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c =================================================================== --- modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c (revision 56561) +++ modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c (working copy) @@ -30,6 +30,7 @@ #define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus) #define ok_eq_ulong(value, expected) ok((value) == (expected), #value " = %lu, expected %lu\n", value, expected) +#define ok_eq_size(value, expected) ok((value) == (expected), #value " = %lu, expected %lu\n", (ULONG)value, (ULONG)expected) #define ok_eq_hex(value, expected) ok((value) == (expected), #value " = 0x%lx, expected 0x%lx\n", value, expected) #define ok_eq_pointer(value, expected) ok((value) == (expected), #value " = %p, expected %p\n", value, expected) @@ -54,6 +55,7 @@ UNICODE_STRING EmptyString; SIZE_T FilePartSize; SIZE_T LengthNeeded; + WCHAR Buffer[MAX_PATH]; INT i; RtlInitUnicodeString(&EmptyString, NULL); @@ -113,7 +115,7 @@ RtlInitUnicodeString(&FileNameString, NULL); RtlInitUnicodeString(&ExtensionString, NULL); RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); + RtlInitEmptyUnicodeString(&DynamicString, Buffer, sizeof(Buffer)); FullNameOut = InvalidPointer; FilePartSize = (SIZE_T)-1; LengthNeeded = (SIZE_T)-1; @@ -134,14 +136,14 @@ ok_eq_ustr(&CallerBuffer, &EmptyString); ok_eq_ustr(&DynamicString, &EmptyString); ok_eq_pointer(FullNameOut, NULL); - ok_eq_ulong(FilePartSize, 0); - ok_eq_ulong(LengthNeeded, 0); + ok_eq_size(FilePartSize, 0); + ok_eq_size(LengthNeeded, 0); /* Everything except FileNameString */ RtlInitUnicodeString(&PathString, NULL); RtlInitUnicodeString(&ExtensionString, NULL); RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); + RtlInitEmptyUnicodeString(&DynamicString, Buffer, sizeof(Buffer)); FullNameOut = InvalidPointer; FilePartSize = (SIZE_T)-1; LengthNeeded = (SIZE_T)-1; @@ -162,15 +164,15 @@ ok_eq_ustr(&CallerBuffer, &EmptyString); ok_eq_ustr(&DynamicString, &EmptyString); ok_eq_pointer(FullNameOut, NULL); - ok_eq_ulong(FilePartSize, 0); - ok_eq_ulong(LengthNeeded, 0); + ok_eq_size(FilePartSize, 0); + ok_eq_size(LengthNeeded, 0); /* Passing CallerBuffer and DynamicString, but not FullNameOut is invalid */ RtlInitUnicodeString(&PathString, NULL); RtlInitUnicodeString(&FileNameString, NULL); RtlInitUnicodeString(&ExtensionString, NULL); RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); + RtlInitEmptyUnicodeString(&DynamicString, Buffer, sizeof(Buffer)); FullNameOut = InvalidPointer; FilePartSize = (SIZE_T)-1; LengthNeeded = (SIZE_T)-1; @@ -191,15 +193,15 @@ ok_eq_ustr(&ExtensionString, &EmptyString); ok_eq_ustr(&CallerBuffer, &EmptyString); ok_eq_ustr(&DynamicString, &EmptyString); - ok_eq_ulong(FilePartSize, 0); - ok_eq_ulong(LengthNeeded, 0); + ok_eq_size(FilePartSize, 0); + ok_eq_size(LengthNeeded, 0); /* All parameters given */ RtlInitUnicodeString(&PathString, NULL); RtlInitUnicodeString(&FileNameString, NULL); RtlInitUnicodeString(&ExtensionString, NULL); RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); + RtlInitEmptyUnicodeString(&DynamicString, Buffer, sizeof(Buffer)); FullNameOut = InvalidPointer; FilePartSize = (SIZE_T)-1; LengthNeeded = (SIZE_T)-1; @@ -221,6 +223,6 @@ ok_eq_ustr(&CallerBuffer, &EmptyString); ok_eq_ustr(&DynamicString, &EmptyString); ok_eq_pointer(FullNameOut, NULL); - ok_eq_ulong(FilePartSize, 0); - ok_eq_ulong(LengthNeeded, 0); + ok_eq_size(FilePartSize, 0); + ok_eq_size(LengthNeeded, 0); }