From: Tim Clem tclem@codeweavers.com
Fixes a regression with af35741d. --- dlls/kernel32/tests/file.c | 24 ++++++++++++++++++++++++ dlls/ntdll/unix/file.c | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 83766dfaaa2..1a5981261a5 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5436,6 +5436,30 @@ static void test_GetFinalPathNameByHandleW(void) wine_dbgstr_w(nt_path), wine_dbgstr_w(result_path));
CloseHandle(file); + + /* Roots of drives should come back with a trailing slash. */ + file = CreateFileW(L"C:\", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %lu\n", GetLastError()); + memset(result_path, 0x11, sizeof(result_path)); + count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); + lstrcpyW(dos_path, L"\\?\C:\"); + ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count); + ok(lstrcmpiW(dos_path, result_path) == 0, "Expected %s, got %s\n", + wine_dbgstr_w(dos_path), wine_dbgstr_w(result_path)); + CloseHandle(file); + + /* Other directories should not have a trailing slash. */ + file = CreateFileW(L"C:\windows\", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %lu\n", GetLastError()); + memset(result_path, 0x11, sizeof(result_path)); + count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); + lstrcpyW(dos_path, L"\\?\C:\windows"); + ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count); + ok(lstrcmpiW(dos_path, result_path) == 0, "Expected %s, got %s\n", + wine_dbgstr_w(dos_path), wine_dbgstr_w(result_path)); + CloseHandle(file); }
static void test_SetFileInformationByHandle(void) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 5bed090a45b..a6c60635e33 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -4045,8 +4045,30 @@ NTSTATUS get_nt_and_unix_names( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name if (status && status != STATUS_NO_SUCH_FILE) TRACE( "%s -> ret %x\n", debugstr_us(orig), status ); else + { + /* Trim trailing slashes from anything other than roots of drives. */ + USHORT nt_len = attr->ObjectName->Length / sizeof(WCHAR); + if (nt_len > 7 /* "??\X:" */ && attr->ObjectName->Buffer[nt_len - 1] == '\') + { + if (nt_name->Buffer) + { + nt_name->Buffer[nt_len - 1] = 0; + nt_name->Length -= sizeof(WCHAR); + } + else + { + WCHAR *buffer = malloc( nt_len * sizeof(WCHAR) ); + if (!buffer) return STATUS_NO_MEMORY; + memcpy( buffer, attr->ObjectName->Buffer, (nt_len - 1) * sizeof(WCHAR) ); + buffer[nt_len - 1] = 0; + init_unicode_string( nt_name, buffer ); + attr->ObjectName = nt_name; + } + } + TRACE( "%s -> ret %x nt %s unix %s\n", debugstr_us(orig), status, debugstr_us(attr->ObjectName), debugstr_a(*unix_name_ret) ); + } return status; }