From ee0f0da69b3a99ce6b682b38fc6910a253ca23f8 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 20 Oct 2010 12:17:35 +0200 Subject: [PATCH] kernel32: Use RtlDosPathNameToNtPathName_U to validate the path in GetVolumeInformationW. --- dlls/kernel32/tests/volume.c | 9 ++++----- dlls/kernel32/volume.c | 35 +++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index f52c592a01e..534f0e3a6d6 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -324,7 +324,6 @@ static void test_GetVolumeInformationA(void) ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL, NULL, NULL, fs_name_buf, fs_name_len); - todo_wine ok(ret, "GetVolumeInformationA root failed, last error %u\n", GetLastError()); /* check for error on no trailing \ when current dir is subdir (windows) of queried drive */ @@ -392,7 +391,7 @@ static void test_GetVolumeInformationA(void) /* \ is current on root drive, call succeeds */ ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL, NULL, NULL, fs_name_buf, fs_name_len); - todo_wine ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError()); + ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError()); /* again, SetCurrentDirectory on another drive does not matter */ ret = SetCurrentDirectory(Root_Slash); @@ -403,7 +402,7 @@ static void test_GetVolumeInformationA(void) /* \ is current on root drive, call succeeds */ ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL, NULL, NULL, fs_name_buf, fs_name_len); - todo_wine ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError()); + ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError()); } /* try null root directory to return "root of the current directory" */ @@ -420,7 +419,7 @@ static void test_GetVolumeInformationA(void) SetLastError(0xdeadbeef); ret = pGetVolumeInformationA(Root_UNC, vol_name_buf, vol_name_size, &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); - todo_wine ok(ret || broken(!ret /* win9x */ && GetLastError()==ERROR_BAD_NETPATH), + ok(ret || broken(!ret /* win9x */ && GetLastError()==ERROR_BAD_NETPATH), "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", Root_UNC, GetLastError()); /* try again with device name space */ @@ -428,7 +427,7 @@ static void test_GetVolumeInformationA(void) SetLastError(0xdeadbeef); ret = pGetVolumeInformationA(Root_UNC, vol_name_buf, vol_name_size, &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); - todo_wine ok(ret || broken(!ret /* win9x */ && GetLastError()==ERROR_BAD_NETPATH), + ok(ret || broken(!ret /* win9x */ && GetLastError()==ERROR_BAD_NETPATH), "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", Root_UNC, GetLastError()); /* try again with a directory off the root - should generate error */ diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c index 75968645167..002a7e6d183 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c @@ -513,26 +513,29 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len, static const WCHAR fat32W[] = {'F','A','T','3','2',0}; static const WCHAR ntfsW[] = {'N','T','F','S',0}; static const WCHAR cdfsW[] = {'C','D','F','S',0}; + static const WCHAR default_rootW[] = {'\\',0}; WCHAR device[] = {'\\','\\','.','\\','A',':',0}; HANDLE handle; + UNICODE_STRING nt_name; + WCHAR *p; enum fs_type type = FS_UNKNOWN; + BOOL ret = FALSE; - if (!root) + if (!root) root = default_rootW; + if (!RtlDosPathNameToNtPathName_U( root, &nt_name, NULL, NULL )) { - WCHAR path[MAX_PATH]; - GetCurrentDirectoryW( MAX_PATH, path ); - device[4] = path[0]; + SetLastError( ERROR_PATH_NOT_FOUND ); + return FALSE; } - else + /* there must be exactly one backslash in the name, at the end */ + p = memchrW( nt_name.Buffer + 4, '\\', (nt_name.Length - 4) / sizeof(WCHAR) ); + if (p != nt_name.Buffer + nt_name.Length / sizeof(WCHAR) - 1) { - if (!root[0] || root[1] != ':' || root[lstrlenW(root)-1] != '\\' ) - { - SetLastError( ERROR_INVALID_NAME ); - return FALSE; - } - device[4] = root[0]; + SetLastError( ERROR_INVALID_NAME ); + goto done; } + device[4] = nt_name.Buffer[4]; /* try to open the device */ @@ -566,7 +569,7 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len, } CloseHandle( handle ); TRACE( "%s: found fs type %d\n", debugstr_w(device), type ); - if (type == FS_ERROR) return FALSE; + if (type == FS_ERROR) goto done; if (label && label_len) VOLUME_GetSuperblockLabel( device, type, superblock, label, label_len ); if (serial) *serial = VOLUME_GetSuperblockSerial( device, type, superblock ); @@ -581,7 +584,7 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len, case DRIVE_UNKNOWN: case DRIVE_NO_ROOT_DIR: SetLastError( ERROR_NOT_READY ); - return FALSE; + goto done; case DRIVE_REMOVABLE: case DRIVE_FIXED: case DRIVE_REMOTE: @@ -618,7 +621,11 @@ fill_fs_info: /* now fill in the information that depends on the file system ty if (flags) *flags = FILE_CASE_PRESERVED_NAMES; break; } - return TRUE; + ret = TRUE; + +done: + RtlFreeUnicodeString( &nt_name ); + return ret; }