Alexandre Julliard : kernel32: Use RtlDosPathNameToNtPathName_U to validate the path in GetVolumeInformationW .
Alexandre Julliard
julliard at winehq.org
Wed Oct 20 13:24:36 CDT 2010
Module: wine
Branch: master
Commit: ee0f0da69b3a99ce6b682b38fc6910a253ca23f8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee0f0da69b3a99ce6b682b38fc6910a253ca23f8
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 20 12:17:35 2010 +0200
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 f52c592..534f0e3 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 7596864..002a7e6 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;
}
More information about the wine-cvs
mailing list