Add patch for GetFinalPathNameByHandle.

This commit is contained in:
Michael Müller 2014-08-12 20:30:54 +02:00
parent 4c1c303b62
commit 06af5d9963
5 changed files with 515 additions and 0 deletions

View File

@ -33,6 +33,7 @@ Wine-Compholio contains fixes for the following Wine bugs:
* Need for Speed 3 installer requires devices in HKEY_DYN_DATA ([Wine Bug #7115](http://bugs.winehq.org/show_bug.cgi?id=7115 "Need for Speed III installer fails in Win9X mode, reporting \"Could not get 'HardWareKey' value\" (active PnP device keys in 'HKEY_DYN_DATA\\\\Config Manager\\\\Enum' missing)"))
* Return correct IMediaSeeking stream positions in quartz ([Wine Bug #23174](http://bugs.winehq.org/show_bug.cgi?id=23174 "Fallout 3: Diologue and Video/sound issues"))
* Set ldr.EntryPoint for main executable ([Wine Bug #33034](http://bugs.winehq.org/show_bug.cgi?id=33034 "Many GFWL (Games For Windows Live) 1.x/2.x/3.x games crash or exit silently on startup (DiRT 2/3, GTA IV Steam)"))
* Some applications neeed kernel32.GetFinalPathNameByHandle ([Wine Bug #36073](http://bugs.winehq.org/show_bug.cgi?id=36073 "OneDrive crashes on unimplemented function KERNEL32.dll.GetFinalPathNameByHandleW"))
* Support for AllocateAndGetTcpExTableFromStack ([Wine Bug #34372](http://bugs.winehq.org/show_bug.cgi?id=34372 "Add missing function AllocateAndGetTcpExTableFromStack() to iphlpapi.dll"))
* Support for DwmInvalidateIconicBitmaps ([Wine Bug #32977](http://bugs.winehq.org/show_bug.cgi?id=32977 "Solidworks 2012 needs unimplemented function dwmapi.dll.DwmInvalidateIconicBitmaps (Win7 mode)"))
* Support for GetSystemTimes ([Wine Bug #19813](http://bugs.winehq.org/show_bug.cgi?id=19813 "Voddler needs GetSystemTimes to run"))

View File

@ -16,6 +16,7 @@ PATCHLIST := \
dwmapi-Invalidate_Thumbnail.ok \
fonts-Missing_Fonts.ok \
iphlpapi-TCP_Table.ok \
kernel32-GetFinalPathNameByHandle.ok \
kernel32-GetSystemTimes.ok \
kernel32-GetVolumePathName.ok \
kernel32-Named_Pipe.ok \
@ -230,6 +231,25 @@ iphlpapi-TCP_Table.ok:
echo '+ { "iphlpapi-TCP_Table", "Erich E. Hoover", "Implement AllocateAndGetTcpExTableFromStack." },'; \
) > iphlpapi-TCP_Table.ok
# Patchset kernel32-GetFinalPathNameByHandle
# |
# | Included patches:
# | * Implement GetFinalPathNameByHandle in kernel32. [by Michael Müller]
# |
# | This patchset fixes the following Wine bugs:
# | * [#36073] OneDrive crashes on unimplemented function KERNEL32.dll.GetFinalPathNameByHandleW
# |
# | Modified files:
# | * dlls/kernel32/file.c, dlls/kernel32/kernel32.spec, dlls/kernel32/tests/file.c, include/fileapi.h
# |
.INTERMEDIATE: kernel32-GetFinalPathNameByHandle.ok
kernel32-GetFinalPathNameByHandle.ok:
$(call APPLY_FILE,kernel32-GetFinalPathNameByHandle/0001-kernel32-Implement-GetFinalPathNameByHandle.patch)
$(call APPLY_FILE,kernel32-GetFinalPathNameByHandle/0002-kernel32-tests-Add-tests-for-GetFinalPathNameByHandl.patch)
@( \
echo '+ { "kernel32-GetFinalPathNameByHandle", "Michael Müller", "Implement GetFinalPathNameByHandle in kernel32." },'; \
) > kernel32-GetFinalPathNameByHandle.ok
# Patchset kernel32-GetSystemTimes
# |
# | Included patches:

View File

@ -0,0 +1,237 @@
From 5301ca38d5f079f106616c2f629464de101bd8aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 12 Aug 2014 20:24:14 +0200
Subject: kernel32: Implement GetFinalPathNameByHandle.
---
dlls/kernel32/file.c | 182 ++++++++++++++++++++++++++++++++++++++++++++
dlls/kernel32/kernel32.spec | 2 +
include/fileapi.h | 8 ++
3 files changed, 192 insertions(+)
diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
index 412659b..eb17abb 100644
--- a/dlls/kernel32/file.c
+++ b/dlls/kernel32/file.c
@@ -2810,3 +2810,185 @@ DWORD WINAPI K32GetDeviceDriverFileNameW(void *image_base, LPWSTR file_name, DWO
return 0;
}
+
+/***********************************************************************
+ * GetFinalPathNameByHandleW (KERNEL32.@)
+ */
+DWORD WINAPI GetFinalPathNameByHandleW(HANDLE file, LPWSTR path, DWORD charcount, DWORD flags)
+{
+ WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1];
+ OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer;
+ WCHAR drive_part[MAX_PATH];
+ DWORD drive_part_len;
+ NTSTATUS status;
+ DWORD result = 0;
+ ULONG dummy;
+ WCHAR *ptr;
+
+ TRACE( "(%p,%p,%d,%x)\n", file, path, charcount, flags );
+
+ /* check for invalid arguments */
+ if (!path)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+ else if (file == INVALID_HANDLE_VALUE)
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return 0;
+ }
+ else if (flags & ~(FILE_NAME_OPENED | VOLUME_NAME_GUID | VOLUME_NAME_NONE | VOLUME_NAME_NT))
+ {
+ WARN("Invalid or unsupported flags: %x\n", flags);
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ /* get object name */
+ status = NtQueryObject( file, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy );
+ if (status != STATUS_SUCCESS)
+ {
+ SetLastError( RtlNtStatusToDosError( status ) );
+ return 0;
+ }
+ else 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;
+ }
+
+ /* add terminating null character, remove "\\??\\" */
+ info->Name.Buffer[info->Name.Length / sizeof(WCHAR)] = 0;
+ info->Name.Length -= 4 * sizeof(WCHAR);
+ info->Name.Buffer += 4;
+
+ /* FILE_NAME_OPENED is not supported yet, and would require Wineserver changes */
+ if (flags & FILE_NAME_OPENED)
+ {
+ FIXME("FILE_NAME_OPENED not supported\n");
+ flags &= ~FILE_NAME_OPENED;
+ }
+
+ /* Get information required for VOLUME_NAME_NONE, VOLUME_NAME_GUID and VOLUME_NAME_DOS */
+ if (flags == VOLUME_NAME_NONE || flags == VOLUME_NAME_GUID || flags == VOLUME_NAME_NT)
+ {
+ if (!GetVolumePathNameW( info->Name.Buffer, drive_part, MAX_PATH ))
+ return 0;
+
+ drive_part_len = strlenW(drive_part);
+ if (!drive_part_len || drive_part_len > strlenW(info->Name.Buffer) ||
+ drive_part[drive_part_len-1] != '\\' ||
+ memcmp( info->Name.Buffer, drive_part, drive_part_len * sizeof(WCHAR) ))
+ {
+ 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;
+ }
+ }
+
+ if (flags == VOLUME_NAME_NONE)
+ {
+ ptr = info->Name.Buffer + drive_part_len - 1;
+ result = strlenW(ptr);
+ if (result < charcount)
+ memcpy(path, ptr, (result + 1) * sizeof(WCHAR));
+ else result++;
+ }
+ else if (flags == VOLUME_NAME_GUID)
+ {
+ WCHAR volume_prefix[51];
+
+ /* GetVolumeNameForVolumeMountPointW sets error code on failure */
+ if (!GetVolumeNameForVolumeMountPointW( drive_part, volume_prefix, 50 ))
+ return 0;
+
+ ptr = info->Name.Buffer + drive_part_len;
+ result = strlenW(volume_prefix) + strlenW(ptr);
+ if (result < charcount)
+ {
+ path[0] = 0;
+ strcatW(path, volume_prefix);
+ strcatW(path, ptr);
+ }
+ else result++;
+ }
+ else if (flags == VOLUME_NAME_NT)
+ {
+ WCHAR nt_prefix[MAX_PATH];
+
+ /* QueryDosDeviceW sets error code on failure */
+ drive_part[drive_part_len - 1] = 0;
+ if (!QueryDosDeviceW( drive_part, nt_prefix, MAX_PATH ))
+ return 0;
+
+ ptr = info->Name.Buffer + drive_part_len - 1;
+ result = strlenW(nt_prefix) + strlenW(ptr);
+ if (result < charcount)
+ {
+ path[0] = 0;
+ strcatW(path, nt_prefix);
+ strcatW(path, ptr);
+ }
+ else result++;
+ }
+ else if (flags == VOLUME_NAME_DOS)
+ {
+ static const WCHAR dos_prefix[] = {'\\','\\','?','\\', '\0'};
+
+ result = strlenW(dos_prefix) + strlenW(info->Name.Buffer);
+ if (result < charcount)
+ {
+ path[0] = 0;
+ strcatW(path, dos_prefix);
+ strcatW(path, info->Name.Buffer);
+ }
+ else result++;
+ }
+ else
+ {
+ /* Windows crashes here, but we prefer returning ERROR_INVALID_PARAMETER */
+ WARN("Invalid combination of flags: %x\n", flags);
+ SetLastError( ERROR_INVALID_PARAMETER );
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ * GetFinalPathNameByHandleA (KERNEL32.@)
+ */
+DWORD WINAPI GetFinalPathNameByHandleA(HANDLE file, LPSTR path, DWORD charcount, DWORD flags)
+{
+ WCHAR *str;
+ DWORD result;
+
+ TRACE( "(%p,%p,%d,%x)\n", file, path, charcount, flags );
+
+ if (!path || !charcount)
+ return GetFinalPathNameByHandleW(file, (LPWSTR)path, charcount, flags);
+
+ str = HeapAlloc( GetProcessHeap(), 0, charcount * sizeof(WCHAR) );
+ if (!str)
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
+ }
+
+ result = GetFinalPathNameByHandleW(file, (LPWSTR)str, charcount, flags);
+ if (result)
+ {
+ if (result < charcount)
+ {
+ result = FILE_name_WtoA( str, result, path, charcount - 1 );
+ path[result] = 0;
+ }
+ else result--; /* Why does Windows do this? */
+ }
+
+ HeapFree( GetProcessHeap(), 0, str );
+ return result;
+}
\ No newline at end of file
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 2de2119..10a5ef3 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -538,6 +538,8 @@
@ stdcall GetFileAttributesW(wstr)
@ stdcall GetFileInformationByHandle(long ptr)
@ stdcall GetFileInformationByHandleEx(long long ptr long)
+@ stdcall GetFinalPathNameByHandleA(long ptr long long)
+@ stdcall GetFinalPathNameByHandleW(long ptr long long)
@ stdcall GetFileSize(long ptr)
@ stdcall GetFileSizeEx(long ptr)
@ stdcall GetFileTime(long ptr ptr ptr)
diff --git a/include/fileapi.h b/include/fileapi.h
index 02bbbd4..0ccf9e9 100644
--- a/include/fileapi.h
+++ b/include/fileapi.h
@@ -34,6 +34,14 @@ typedef struct _CREATEFILE2_EXTENDED_PARAMETERS {
WINBASEAPI HANDLE WINAPI CreateFile2(LPCWSTR,DWORD,DWORD,DWORD,LPCREATEFILE2_EXTENDED_PARAMETERS);
+#define FILE_NAME_NORMALIZED 0x0
+#define FILE_NAME_OPENED 0x8
+
+#define VOLUME_NAME_DOS 0x0
+#define VOLUME_NAME_GUID 0x1
+#define VOLUME_NAME_NT 0x2
+#define VOLUME_NAME_NONE 0x4
+
#ifdef __cplusplus
}
#endif
--
1.8.3.2

View File

@ -0,0 +1,253 @@
From d5bb58d2350486ac12970aef61dcec95f23dfbfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 12 Aug 2014 20:25:18 +0200
Subject: kernel32/tests: Add tests for GetFinalPathNameByHandle
---
dlls/kernel32/tests/file.c | 204 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 204 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index 492a34f..490f4bd 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -34,6 +34,7 @@
#include "winerror.h"
#include "winnls.h"
#include "fileapi.h"
+#include "ntsecapi.h"
static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);
@@ -46,6 +47,8 @@ static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD
static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG);
static HRESULT (WINAPI *pCopyFile2)(PCWSTR,PCWSTR,COPYFILE2_EXTENDED_PARAMETERS*);
static HANDLE (WINAPI *pCreateFile2)(LPCWSTR, DWORD, DWORD, DWORD, CREATEFILE2_EXTENDED_PARAMETERS*);
+static DWORD (WINAPI* pGetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, DWORD);
+static DWORD (WINAPI* pGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
/* keep filename and filenameW the same */
static const char filename[] = "testfile.xxx";
@@ -85,6 +88,8 @@ static void InitFunctionPointers(void)
pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
pCopyFile2 = (void *) GetProcAddress(hkernel32, "CopyFile2");
pCreateFile2 = (void *) GetProcAddress(hkernel32, "CreateFile2");
+ pGetFinalPathNameByHandleA = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleA");
+ pGetFinalPathNameByHandleW = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleW");
}
static void test__hread( void )
@@ -4088,6 +4093,203 @@ todo_wine
}
}
+
+static void test_GetFinalPathNameByHandleA(void)
+{
+ static char prefix[] = "GetFinalPathNameByHandleA";
+ static char dos_prefix[] = "\\\\?\\";
+ char temp_path[MAX_PATH], test_path[MAX_PATH];
+ char long_path[MAX_PATH], result_path[MAX_PATH];
+ char dos_path[sizeof(dos_prefix) + MAX_PATH];
+ HANDLE hFile;
+ DWORD count;
+ UINT ret;
+
+ if (!pGetFinalPathNameByHandleA)
+ {
+ win_skip("GetFinalPathNameByHandleA is missing\n");
+ return;
+ }
+
+ /* Test calling with INVALID_HANDLE_VALUE */
+ SetLastError(0xdeadbeaf);
+ count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == 0, "Expected length 0, got %d\n", count);
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
+
+ count = GetTempPathA(MAX_PATH, temp_path);
+ ok(count, "Failed to get temp path, error %d\n", GetLastError());
+ if (!count) return;
+
+ ret = GetTempFileNameA(temp_path, prefix, 0, test_path);
+ ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
+ if (!ret) return;
+
+ ret = GetLongPathNameA(test_path, long_path, MAX_PATH);
+ ok(ret != 0, "GetLongPathNameA error %d\n", GetLastError());
+ if (!ret) return;
+
+ hFile = CreateFileA(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
+ ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
+ if (hFile == INVALID_HANDLE_VALUE) return;
+
+ dos_path[0] = 0;
+ strcat(dos_path, dos_prefix);
+ strcat(dos_path, long_path);
+
+ /* Test VOLUME_NAME_DOS with sufficient buffer size */
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleA(hFile, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == strlen(dos_path), "Expected length %d, got %d\n", strlen(dos_path), count);
+ if (count && count <= MAX_PATH)
+ ok(lstrcmpiA(dos_path, result_path) == 0, "Expected %s, got %s\n", dos_path, result_path);
+
+ /* Test VOLUME_NAME_DOS with insufficient buffer size */
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleA(hFile, result_path, strlen(dos_path)-2, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == strlen(dos_path), "Expected length %d, got %d\n", strlen(dos_path), count);
+ ok(result_path[0] == 0x11, "Result path was modified\n");
+
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleA(hFile, result_path, strlen(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == strlen(dos_path), "Expected length %d, got %d\n", strlen(dos_path), count);
+ ok(result_path[0] == 0x11, "Result path was modified\n");
+
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleA(hFile, result_path, strlen(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == strlen(dos_path), "Expected length %d, got %d\n", strlen(dos_path), count);
+ ok(result_path[0] == 0x11, "Result path was modified\n");
+
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleA(hFile, result_path, strlen(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == strlen(dos_path), "Expected length %d, got %d\n", strlen(dos_path), count);
+ ok(result_path[0] != 0x11, "Result path was not modified\n");
+ ok(result_path[strlen(dos_path)+1] == 0x11, "Buffer overflow\n");
+
+ CloseHandle(hFile);
+}
+
+static void test_GetFinalPathNameByHandleW(void)
+{
+ static WCHAR prefix[] = {'G','e','t','F','i','n','a','l','P','a','t','h','N','a','m','e','B','y','H','a','n','d','l','e','W','\0'};
+ static WCHAR dos_prefix[] = {'\\','\\','?','\\','\0'};
+ WCHAR temp_path[MAX_PATH], test_path[MAX_PATH];
+ WCHAR long_path[MAX_PATH], result_path[MAX_PATH];
+ WCHAR dos_path[MAX_PATH + sizeof(dos_prefix)];
+ WCHAR drive_part[MAX_PATH];
+ WCHAR *file_part;
+ WCHAR volume_path[MAX_PATH+50];
+ WCHAR nt_path[2*MAX_PATH];
+ HANDLE hFile;
+ DWORD count;
+ UINT ret;
+
+ if (!pGetFinalPathNameByHandleW)
+ {
+ win_skip("GetFinalPathNameByHandleW is missing\n");
+ return;
+ }
+
+ /* Test calling with INVALID_HANDLE_VALUE */
+ SetLastError(0xdeadbeaf);
+ count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == 0, "Expected length 0, got %d\n", count);
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
+
+ count = GetTempPathW(MAX_PATH, temp_path);
+ ok(count, "Failed to get temp path, error %d\n", GetLastError());
+ if (!count) return;
+
+ ret = GetTempFileNameW(temp_path, prefix, 0, test_path);
+ ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
+ if (!ret) return;
+
+ ret = GetLongPathNameW(test_path, long_path, MAX_PATH);
+ ok(ret != 0, "GetLongPathNameW error %d\n", GetLastError());
+ if (!ret) return;
+
+ hFile = CreateFileW(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
+ ok(hFile != INVALID_HANDLE_VALUE, "CreateFileW error %d\n", GetLastError());
+ if (hFile == INVALID_HANDLE_VALUE) return;
+
+ dos_path[0] = 0;
+ lstrcatW(dos_path, dos_prefix);
+ lstrcatW(dos_path, long_path);
+
+ /* Test VOLUME_NAME_DOS with sufficient buffer size */
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == lstrlenW(dos_path), "Expected length %d, got %d\n", lstrlenW(dos_path), count);
+ if (count && count <= MAX_PATH)
+ ok(lstrcmpiW(dos_path, result_path) == 0, "Expected %s, got %s\n", wine_dbgstr_w(dos_path), wine_dbgstr_w(result_path));
+
+ /* Test VOLUME_NAME_DOS with insufficient buffer size */
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, lstrlenW(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == lstrlenW(dos_path) + 1, "Expected length %d, got %d\n", lstrlenW(dos_path) + 1, count);
+ ok(result_path[0] == 0x1111, "Result path was modified\n");
+
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, lstrlenW(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == lstrlenW(dos_path) + 1, "Expected length %d, got %d\n", lstrlenW(dos_path) + 1, count);
+ ok(result_path[0] == 0x1111, "Result path was modified\n");
+
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, lstrlenW(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ ok(count == lstrlenW(dos_path), "Expected length %d, got %d\n", lstrlenW(dos_path), count);
+ ok(result_path[0] != 0x1111, "Result path was not modified\n");
+ ok(result_path[lstrlenW(dos_path)+1] == 0x1111, "Buffer overflow\n");
+
+ if (!GetVolumePathNameW(long_path, drive_part, MAX_PATH))
+ {
+ ok(0, "Failed to get drive part, error: %d\n", GetLastError());
+ CloseHandle(hFile);
+ return;
+ }
+
+ if (!GetVolumeNameForVolumeMountPointW(drive_part, volume_path, sizeof(volume_path) / sizeof(WCHAR)))
+ ok(0, "GetVolumeNameForVolumeMountPointW failed, error: %d\n", GetLastError());
+ else
+ {
+ /* Test for VOLUME_NAME_GUID */
+ lstrcatW(volume_path, long_path + lstrlenW(drive_part));
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_GUID);
+ ok(count == lstrlenW(volume_path), "Expected length %d, got %d\n", lstrlenW(volume_path), count);
+ if (count && count <= MAX_PATH)
+ ok(lstrcmpiW(volume_path, result_path) == 0, "Expected %s, got %s\n",
+ wine_dbgstr_w(volume_path), wine_dbgstr_w(result_path));
+ }
+
+ /* Test for VOLUME_NAME_NONE */
+ file_part = long_path + lstrlenW(drive_part) - 1;
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NONE);
+ ok(count == lstrlenW(file_part), "Expected length %d, got %d\n", lstrlenW(file_part), count);
+ if (count && count <= MAX_PATH)
+ ok(lstrcmpiW(file_part, result_path) == 0, "Expected %s, got %s\n",
+ wine_dbgstr_w(file_part), wine_dbgstr_w(result_path));
+
+ drive_part[lstrlenW(drive_part)-1] = 0;
+ if (!QueryDosDeviceW(drive_part, nt_path, sizeof(nt_path) / sizeof(WCHAR)))
+ ok(0, "QueryDosDeviceW failed, error: %d\n", GetLastError());
+ else
+ {
+ /* Test for VOLUME_NAME_NT */
+ lstrcatW(nt_path, file_part);
+ memset(result_path, 0x11, sizeof(result_path));
+ count = pGetFinalPathNameByHandleW(hFile, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NT);
+ ok(count == lstrlenW(nt_path), "Expected length %d, got %d\n", lstrlenW(nt_path), count);
+ if (count && count <= MAX_PATH)
+ ok(lstrcmpiW(nt_path, result_path) == 0, "Expected %s, got %s\n",
+ wine_dbgstr_w(nt_path), wine_dbgstr_w(result_path));
+ }
+
+ CloseHandle(hFile);
+}
+
START_TEST(file)
{
InitFunctionPointers();
@@ -4133,4 +4335,6 @@ START_TEST(file)
test_OpenFileById();
test_SetFileValidData();
test_file_access();
+ test_GetFinalPathNameByHandleA();
+ test_GetFinalPathNameByHandleW();
}
--
1.8.3.2

View File

@ -0,0 +1,4 @@
Author: Michael Müller
Subject: Implement GetFinalPathNameByHandle in kernel32.
Revision: 1
Fixes: [36073] Some applications neeed kernel32.GetFinalPathNameByHandle