Alexandre Julliard : ntdll: Allow a second backslash after the drive letter.

Alexandre Julliard julliard at winehq.org
Wed Apr 14 16:01:19 CDT 2021


Module: wine
Branch: master
Commit: 060b28b9bafd5e0b344c847bc91e50140fbcfacb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=060b28b9bafd5e0b344c847bc91e50140fbcfacb

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Apr 14 11:46:46 2021 +0200

ntdll: Allow a second backslash after the drive letter.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/path.c | 27 +++++++++++++++------------
 dlls/ntdll/unix/file.c  |  6 ++++--
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c
index 9b6eecbfbbe..f2588c0bd98 100644
--- a/dlls/ntdll/tests/path.c
+++ b/dlls/ntdll/tests/path.c
@@ -622,15 +622,16 @@ static void test_RtlDosPathNameToNtPathName_U(void)
 
 static void test_nt_names(void)
 {
-    static const struct { const WCHAR *root, *name; NTSTATUS expect; BOOL todo; } tests[] =
+    static const struct { const WCHAR *root, *name; NTSTATUS expect, broken; BOOL todo; } tests[] =
     {
         { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS },
-        { NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
-        { NULL, L"\\??\\C:\\\\windows\\system32\\", STATUS_OBJECT_NAME_INVALID },
+        { NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
+        { NULL, L"\\??\\C:\\windows\\system32\\", STATUS_FILE_IS_A_DIRECTORY },
+        { NULL, L"\\??\\C:\\\\\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
         { NULL, L"\\??\\C:\\windows\\\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
-        { NULL, L"\\??\\C:\\windows\\system32\\.\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
+        { NULL, L"\\??\\C:\\windows\\system32\\.\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
         { NULL, L"\\??\\C:\\windows\\system32\\..\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
-        { NULL, L"\\??\\C:\\.\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
+        { NULL, L"\\??\\C:\\.\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
         { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll   ", STATUS_OBJECT_NAME_NOT_FOUND },
         { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll..", STATUS_OBJECT_NAME_NOT_FOUND },
         { NULL, L"\\??\\C:\\windows   \\system32   \\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
@@ -642,12 +643,12 @@ static void test_nt_names(void)
         { NULL, L"/??\\C:\\windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_SYNTAX_BAD },
         { NULL, L"\\??" L"/C:\\windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
         { NULL, L"\\??\\C:/windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
-        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, TRUE },
-        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND, TRUE },
+        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND, 0, TRUE },
         { NULL, L"\\??\\C:\\windows\\sys\001", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\", NULL, STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\", NULL, STATUS_SUCCESS },
-        { L"\\??\\C:\\\\", NULL, STATUS_OBJECT_NAME_INVALID },
+        { L"\\??\\C:\\\\", NULL, STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
         { L"/??\\C:\\", NULL, STATUS_OBJECT_PATH_SYNTAX_BAD },
         { L"\\??\\C:/", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
         { L"\\??" L"/C:", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
@@ -659,14 +660,15 @@ static void test_nt_names(void)
         { L"\\??\\C:\\windows\\..", NULL, STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\..\\", NULL, STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS },
+        { L"\\??\\C:\\\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS },
         { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll", STATUS_SUCCESS },
         { L"\\??\\C:\\windows\\", L"system32\\", STATUS_FILE_IS_A_DIRECTORY },
-        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, TRUE },
-        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND, TRUE },
+        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND, 0, TRUE },
         { L"\\??\\C:\\windows\\", L"\\system32\\kernel32.dll", STATUS_INVALID_PARAMETER },
         { L"\\??\\C:\\windows\\", L"/system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
-        { L"\\??\\C:\\windows\\", L".\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
+        { L"\\??\\C:\\windows\\", L".\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
         { L"\\??\\C:\\windows\\", L"..\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\", L".", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\", L"..", STATUS_OBJECT_NAME_INVALID },
@@ -703,7 +705,8 @@ static void test_nt_names(void)
         if (attr.RootDirectory) NtClose( attr.RootDirectory );
         if (handle) NtClose( handle );
         todo_wine_if( tests[i].todo )
-        ok( status == tests[i].expect, "%u: got %x / %x for %s + %s\n", i, status, tests[i].expect,
+        ok( status == tests[i].expect || broken( tests[i].broken && status == tests[i].broken ),
+            "%u: got %x / %x for %s + %s\n", i, status, tests[i].expect,
             debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
     }
 }
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 166ee85ebb7..b87da541f1d 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -3372,8 +3372,10 @@ NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **unix_name_ret
         }
     }
 
-    name += prefix_len + 1;
-    name_len -= prefix_len + 1;
+    prefix_len++;  /* skip initial backslash */
+    if (name_len > prefix_len && name[prefix_len] == '\\') prefix_len++;  /* allow a second backslash */
+    name += prefix_len;
+    name_len -= prefix_len;
 
     status = lookup_unix_name( name, name_len, &unix_name, unix_len, pos, disposition, is_unix );
     if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)




More information about the wine-cvs mailing list