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