From: Bernhard Übelacker bernhardu@mailbox.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57027 --- dlls/kernel32/tests/file.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index cf0c40d5cd6..b2951edd0aa 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -6317,6 +6317,41 @@ static void test_eof(void) ok(ret, "failed to delete %s, error %lu\n", debugstr_a(filename), GetLastError()); }
+static void test_GetFinalPathNameByHandleW_more_than_MAX_PATH(void) +{ + WCHAR file_name[MAX_PATH] = {0}; + WCHAR test_path[MAX_PATH * 2] = {0}; + WCHAR result_path[MAX_PATH * 2]; + DWORD count; + HANDLE file; + + lstrcpyW(test_path, L"\\?\"); + count = GetTempPathW(ARRAY_SIZE(test_path) - 4, test_path + 4); + ok(count, "Failed to get temp path, error %lu\n", GetLastError()); + count += 4; + + if (test_path[count - 1] != L'\') + lstrcatW(test_path, L"\"); + + for (int i = 0; i < ARRAY_SIZE(file_name) - 5; i++) + file_name[i] = L'a'; + lstrcatW(test_path, file_name); + + file = CreateFileW(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); + ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %lu\n", GetLastError()); + + memset(result_path, 0xcb, sizeof(result_path)); + count = pGetFinalPathNameByHandleW(file, result_path, ARRAY_SIZE(result_path), FILE_NAME_NORMALIZED); + todo_wine + ok(count == lstrlenW(test_path), "Expected length %u, got %lu\n", lstrlenW(test_path), count); + todo_wine + ok(lstrcmpiW(test_path, result_path) == 0, "Expected %s, got %s\n", + wine_dbgstr_w(test_path), wine_dbgstr_w(result_path)); + + CloseHandle(file); +} + START_TEST(file) { char temp_path[MAX_PATH]; @@ -6383,6 +6418,7 @@ START_TEST(file) test_file_access(); test_GetFinalPathNameByHandleA(); test_GetFinalPathNameByHandleW(); + test_GetFinalPathNameByHandleW_more_than_MAX_PATH(); test_SetFileInformationByHandle(); test_SetFileRenameInfo(); test_GetFileAttributesExW();
From: Bernhard Übelacker bernhardu@mailbox.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57027 --- dlls/kernel32/tests/file.c | 2 -- dlls/kernelbase/file.c | 54 ++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index b2951edd0aa..54d7d0c1c01 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -6343,9 +6343,7 @@ static void test_GetFinalPathNameByHandleW_more_than_MAX_PATH(void)
memset(result_path, 0xcb, sizeof(result_path)); count = pGetFinalPathNameByHandleW(file, result_path, ARRAY_SIZE(result_path), FILE_NAME_NORMALIZED); - todo_wine ok(count == lstrlenW(test_path), "Expected length %u, got %lu\n", lstrlenW(test_path), count); - todo_wine ok(lstrcmpiW(test_path, result_path) == 0, "Expected %s, got %s\n", wine_dbgstr_w(test_path), wine_dbgstr_w(result_path));
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 7d8b6844456..d511ad39efc 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -1776,13 +1776,12 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleA( HANDLE file, LPSTR pat DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR path, DWORD count, DWORD flags ) { - WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1]; - OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer; + OBJECT_NAME_INFORMATION *info = NULL; WCHAR drive_part[MAX_PATH]; DWORD drive_part_len = 0; NTSTATUS status; DWORD result = 0; - ULONG dummy; + ULONG buffer_size; WCHAR *ptr;
TRACE( "(%p,%p,%ld,%lx)\n", file, path, count, flags ); @@ -1795,20 +1794,37 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa }
/* get object name */ - status = NtQueryObject( file, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ); - if (!set_ntstatus( status )) return 0; + buffer_size = sizeof(*info) + (MAX_PATH + 1) * sizeof(WCHAR); + do + { + if (info) + HeapFree( GetProcessHeap(), 0, info ); + info = HeapAlloc( GetProcessHeap(), 0, buffer_size ); + if (!info) + return ERROR_OUTOFMEMORY; + + status = NtQueryObject( file, ObjectNameInformation, info, buffer_size, &buffer_size ); + } while (status == STATUS_BUFFER_OVERFLOW); + + if (!set_ntstatus( status )) + { + result = 0; + goto cleanup; + }
if (!info->Name.Buffer) { SetLastError( ERROR_INVALID_HANDLE ); - return 0; + result = 0; + goto cleanup; } if (info->Name.Length < 4 * sizeof(WCHAR) || info->Name.Buffer[0] != '\' || info->Name.Buffer[1] != '?' || info->Name.Buffer[2] != '?' || info->Name.Buffer[3] != '\' ) { FIXME("Unexpected object name: %s\n", debugstr_wn(info->Name.Buffer, info->Name.Length / sizeof(WCHAR))); SetLastError( ERROR_GEN_FAILURE ); - return 0; + result = 0; + goto cleanup; }
/* add terminating null character, remove "\??\" */ @@ -1826,7 +1842,11 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa /* Get information required for VOLUME_NAME_NONE, VOLUME_NAME_GUID and VOLUME_NAME_NT */ if (flags == VOLUME_NAME_NONE || flags == VOLUME_NAME_GUID || flags == VOLUME_NAME_NT) { - if (!GetVolumePathNameW( info->Name.Buffer, drive_part, MAX_PATH )) return 0; + if (!GetVolumePathNameW( info->Name.Buffer, drive_part, MAX_PATH )) + { + result = 0; + goto cleanup; + } drive_part_len = lstrlenW(drive_part); if (!drive_part_len || drive_part_len > lstrlenW(info->Name.Buffer) || drive_part[drive_part_len-1] != '\' || @@ -1835,7 +1855,8 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa FIXME( "Path %s returned by GetVolumePathNameW does not match file path %s\n", debugstr_w(drive_part), debugstr_w(info->Name.Buffer) ); SetLastError( ERROR_GEN_FAILURE ); - return 0; + result = 0; + goto cleanup; } }
@@ -1851,7 +1872,11 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa WCHAR volume_prefix[51];
/* GetVolumeNameForVolumeMountPointW sets error code on failure */ - if (!GetVolumeNameForVolumeMountPointW( drive_part, volume_prefix, 50 )) return 0; + if (!GetVolumeNameForVolumeMountPointW( drive_part, volume_prefix, 50 )) + { + result = 0; + goto cleanup; + } ptr = info->Name.Buffer + drive_part_len; result = lstrlenW(volume_prefix) + lstrlenW(ptr); if (result < count) @@ -1871,7 +1896,11 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa
/* QueryDosDeviceW sets error code on failure */ drive_part[drive_part_len - 1] = 0; - if (!QueryDosDeviceW( drive_part, nt_prefix, MAX_PATH )) return 0; + if (!QueryDosDeviceW( drive_part, nt_prefix, MAX_PATH )) + { + result = 0; + goto cleanup; + } ptr = info->Name.Buffer + drive_part_len - 1; result = lstrlenW(nt_prefix) + lstrlenW(ptr); if (result < count) @@ -1905,6 +1934,9 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFinalPathNameByHandleW( HANDLE file, LPWSTR pa WARN("Invalid combination of flags: %lx\n", flags); SetLastError( ERROR_INVALID_PARAMETER ); } + +cleanup: + HeapFree( GetProcessHeap(), 0, info ); return result; }