Module: wine Branch: master Commit: 060b28b9bafd5e0b344c847bc91e50140fbcfacb URL: https://source.winehq.org/git/wine.git/?a=commit;h=060b28b9bafd5e0b344c847bc...
Author: Alexandre Julliard julliard@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@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)