mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Add patch for GetFinalPathNameByHandle.
This commit is contained in:
parent
4c1c303b62
commit
06af5d9963
@ -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"))
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
4
patches/kernel32-GetFinalPathNameByHandle/definition
Normal file
4
patches/kernel32-GetFinalPathNameByHandle/definition
Normal file
@ -0,0 +1,4 @@
|
||||
Author: Michael Müller
|
||||
Subject: Implement GetFinalPathNameByHandle in kernel32.
|
||||
Revision: 1
|
||||
Fixes: [36073] Some applications neeed kernel32.GetFinalPathNameByHandle
|
Loading…
Reference in New Issue
Block a user