Module: wine Branch: master Commit: e8e13308eae427a88394abaab28dfb5ab7f149b6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8e13308eae427a88394abaab2...
Author: Erich E. Hoover erich.e.hoover@wine-staging.com Date: Tue Jun 16 08:17:23 2015 -0600
kernel32: Handle semi-DOS paths in GetVolumePathName.
Add support for "semi-DOS" paths, these paths revert to the drive letter specified in the first character.
---
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 a6b2b3d..ac6aa48 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) { static const WCHAR ntprefixW[] = { '\','\','?','\',0 }; - static 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 (!isalphaW(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;