From d683d243f7420785d5207aab1523b4fdd3de066b Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 23 Aug 2018 22:50:07 -0500 Subject: [PATCH] ntdll: Also accept \??\ as a global namespace prefix in RtlDosPathNameToNtPathName_U(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45654 Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/ntdll/path.c | 6 ++++-- dlls/ntdll/tests/path.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index 8fe61dae5ad..9794b6728a8 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -340,7 +340,8 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name ) NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, UNICODE_STRING *ntpath, WCHAR **file_part, CURDIR *cd) { - static const WCHAR LongFileNamePfxW[] = {'\\','\\','?','\\'}; + static const WCHAR global_prefix[] = {'\\','\\','?','\\'}; + static const WCHAR global_prefix2[] = {'\\','?','?','\\'}; ULONG sz, offset; WCHAR local[MAX_PATH]; LPWSTR ptr; @@ -356,7 +357,8 @@ NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, U if (!dos_path || !*dos_path) return STATUS_OBJECT_NAME_INVALID; - if (!strncmpW(dos_path, LongFileNamePfxW, 4)) + if (!memcmp(dos_path, global_prefix, sizeof(global_prefix)) || + (!memcmp(dos_path, global_prefix2, sizeof(global_prefix2)) && dos_path[4])) { ntpath->Length = strlenW(dos_path) * sizeof(WCHAR); ntpath->MaximumLength = ntpath->Length + sizeof(WCHAR); diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c index a0320923c31..7baf474ec1a 100644 --- a/dlls/ntdll/tests/path.c +++ b/dlls/ntdll/tests/path.c @@ -396,6 +396,8 @@ static void test_RtlGetFullPathName_U(void) static void test_RtlDosPathNameToNtPathName_U(void) { + static const WCHAR broken_global_prefix[] = {'\\','?','?','\\','C',':','\\','?','?'}; + char curdir[MAX_PATH]; WCHAR path[MAX_PATH]; UNICODE_STRING nameW; @@ -487,6 +489,22 @@ static void test_RtlDosPathNameToNtPathName_U(void) { "\\\\?\\foo\\bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS }, { "\\\\?\\foo\\.", "\\??\\foo\\.", 8, STATUS_SUCCESS }, { "\\\\?\\foo\\..", "\\??\\foo\\..", 8, STATUS_SUCCESS }, + + { "\\??", "\\??\\C:\\??", 7, STATUS_SUCCESS }, + { "\\??\\", "\\??\\C:\\??\\", -1, STATUS_SUCCESS }, + + { "\\??\\/", "\\??\\/", 4, STATUS_SUCCESS }, + { "\\??\\foo", "\\??\\foo", 4, STATUS_SUCCESS }, + { "\\??\\foo/", "\\??\\foo/", 4, STATUS_SUCCESS }, + { "\\??\\foo/bar", "\\??\\foo/bar", 4, STATUS_SUCCESS }, + { "\\??\\foo/.", "\\??\\foo/.", 4, STATUS_SUCCESS }, + { "\\??\\foo/..", "\\??\\foo/..", 4, STATUS_SUCCESS }, + { "\\??\\\\", "\\??\\\\", -1, STATUS_SUCCESS }, + { "\\??\\\\\\", "\\??\\\\\\", -1, STATUS_SUCCESS }, + { "\\??\\foo\\", "\\??\\foo\\", -1, STATUS_SUCCESS }, + { "\\??\\foo\\bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS }, + { "\\??\\foo\\.", "\\??\\foo\\.", 8, STATUS_SUCCESS }, + { "\\??\\foo\\..", "\\??\\foo\\..", 8, STATUS_SUCCESS }, }; GetCurrentDirectoryA(sizeof(curdir), curdir); @@ -509,6 +527,13 @@ static void test_RtlDosPathNameToNtPathName_U(void) if (ret != TRUE) continue; + if (!strncmp(tests[i].dos, "\\??\\", 4) && tests[i].dos[4] && + broken(!memcmp(nameW.Buffer, broken_global_prefix, sizeof(broken_global_prefix)))) + { + /* Windows version prior to 2003 don't interpret the \??\ prefix */ + continue; + } + MultiByteToWideChar(CP_ACP, 0, tests[i].nt, -1, path, sizeof(path)); ok(!lstrcmpW(nameW.Buffer, path), "%s: Expected %s, got %s.\n", tests[i].dos, tests[i].nt, wine_dbgstr_w(nameW.Buffer));