From: "Erich E. Hoover" Subject: [PATCH 4/8] kernel32: Handle semi-DOS paths in GetVolumePathName. Message-Id: Date: Thu, 18 Jun 2015 19:16:15 -0600 Add support for "semi-DOS" paths, these paths revert to the drive letter specified in the first character. According to my tests, all that's necessary to trigger this behavior is to have a semicolon for the second character in the input string. From 66b6403e1a421deaa962d3f8707e3cfd315bef1e Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" 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