wine-staging/patches/kernel32-GetVolumePathName/0004-kernel32-Handle-semi-DOS-paths-in-GetVolumePathName.patch

65 lines
2.6 KiB
Diff

From c46f7883a62e17b59e10d3bdabf5e0e26a989009 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Tue, 16 Jun 2015 08:17:23 -0600
Subject: kernel32: Handle semi-DOS paths in GetVolumePathName.
---
dlls/kernel32/tests/volume.c | 8 ++++++++
dlls/kernel32/volume.c | 14 ++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
index 3eb7fed..5b117b8 100644
--- a/dlls/kernel32/tests/volume.c
+++ b/dlls/kernel32/tests/volume.c
@@ -663,6 +663,14 @@ static void test_GetVolumePathNameA(void)
"\\\\ReallyBogus\\InvalidDrive:\\" /* win2k, winxp */, sizeof(volume_path),
ERROR_INVALID_NAME, NO_ERROR
},
+ { /* test 15: poor quality input, valid output, valid output length, different drive */
+ "D::", "D:\\", sizeof(volume_path),
+ NO_ERROR, NO_ERROR
+ },
+ { /* test 16: unused drive letter */
+ "M::", "C:\\", 4,
+ ERROR_FILE_NOT_FOUND, ERROR_MORE_DATA
+ },
};
BOOL ret, success;
DWORD error;
diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index 4720cb4..3eef540 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -1818,7 +1818,7 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl
BOOL WINAPI GetVolumePathNameW(LPCWSTR filename, LPWSTR volumepathname, DWORD buflen)
{
const WCHAR ntprefixW[] = { '\\','\\','?','\\',0 };
- const WCHAR fallbackpathW[] = { 'C',':','\\',0 };
+ WCHAR fallbackpathW[] = { 'C',':','\\',0 };
NTSTATUS status = STATUS_SUCCESS;
WCHAR *volumenameW = NULL, *c;
int pos, last_pos, stop_pos;
@@ -1897,7 +1897,17 @@ BOOL WINAPI GetVolumePathNameW(LPCWSTR filename, LPWSTR volumepathname, DWORD bu
goto cleanup;
}
- /* DOS-style paths revert to C:\ (anything not beginning with a slash) */
+ /* DOS-style paths (anything not beginning with a slash) have fallback replies */
+ if (filename[1] == ':')
+ {
+ /* if the path is semi-sane (X:) then use the given drive letter (if it is mounted) */
+ fallbackpathW[0] = filename[0];
+ if (!isalpha(filename[0]) || GetDriveTypeW( fallbackpathW ) == DRIVE_NO_ROOT_DIR)
+ {
+ status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto cleanup;
+ }
+ }
last_pos = strlenW(fallbackpathW) - 1; /* points to \\ */
filename = fallbackpathW;
status = STATUS_SUCCESS;
--
1.9.1