Alexandre Julliard : kernel32: Use the NT name to retrieve label and serial in GetVolumeInformationW.

Alexandre Julliard julliard at winehq.org
Wed Oct 20 13:24:37 CDT 2010


Module: wine
Branch: master
Commit: 357b50600bb11cfda1c7a155d85278a07134ad51
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=357b50600bb11cfda1c7a155d85278a07134ad51

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Oct 20 12:26:54 2010 +0200

kernel32: Use the NT name to retrieve label and serial in GetVolumeInformationW.

---

 dlls/kernel32/volume.c |   79 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index 0a3cc6a..b65d67b 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -209,15 +209,31 @@ static DWORD get_mountmgr_drive_type( LPCWSTR root )
 }
 
 /* get the label by reading it from a file at the root of the filesystem */
-static void get_filesystem_label( const WCHAR *device, WCHAR *label, DWORD len )
+static void get_filesystem_label( const UNICODE_STRING *device, WCHAR *label, DWORD len )
 {
+    static const WCHAR labelW[] = {'.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
     HANDLE handle;
-    WCHAR labelW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
+    UNICODE_STRING name;
+    IO_STATUS_BLOCK io;
+    OBJECT_ATTRIBUTES attr;
 
-    labelW[0] = device[4];
-    handle = CreateFileW( labelW, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
-                          OPEN_EXISTING, 0, 0 );
-    if (handle != INVALID_HANDLE_VALUE)
+    label[0] = 0;
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.Attributes = OBJ_CASE_INSENSITIVE;
+    attr.ObjectName = &name;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+
+    name.MaximumLength = device->Length + sizeof(labelW);
+    name.Length = name.MaximumLength - sizeof(WCHAR);
+    if (!(name.Buffer = HeapAlloc( GetProcessHeap(), 0, name.MaximumLength ))) return;
+
+    memcpy( name.Buffer, device->Buffer, device->Length );
+    memcpy( name.Buffer + device->Length / sizeof(WCHAR), labelW, sizeof(labelW) );
+    if (!NtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                     FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))
     {
         char buffer[256], *p;
         DWORD size;
@@ -230,19 +246,34 @@ static void get_filesystem_label( const WCHAR *device, WCHAR *label, DWORD len )
         if (!MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, label, len ))
             label[len-1] = 0;
     }
-    else label[0] = 0;
+    RtlFreeUnicodeString( &name );
 }
 
 /* get the serial number by reading it from a file at the root of the filesystem */
-static DWORD get_filesystem_serial( const WCHAR *device )
+static DWORD get_filesystem_serial( const UNICODE_STRING *device )
 {
+    static const WCHAR serialW[] = {'.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',0};
     HANDLE handle;
-    WCHAR serialW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',0};
+    UNICODE_STRING name;
+    IO_STATUS_BLOCK io;
+    OBJECT_ATTRIBUTES attr;
+    DWORD ret = 0;
 
-    serialW[0] = device[4];
-    handle = CreateFileW( serialW, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
-                          OPEN_EXISTING, 0, 0 );
-    if (handle != INVALID_HANDLE_VALUE)
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.Attributes = OBJ_CASE_INSENSITIVE;
+    attr.ObjectName = &name;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+
+    name.MaximumLength = device->Length + sizeof(serialW);
+    name.Length = name.MaximumLength - sizeof(WCHAR);
+    if (!(name.Buffer = HeapAlloc( GetProcessHeap(), 0, name.MaximumLength ))) return 0;
+
+    memcpy( name.Buffer, device->Buffer, device->Length );
+    memcpy( name.Buffer + device->Length / sizeof(WCHAR), serialW, sizeof(serialW) );
+    if (!NtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                     FILE_SYNCHRONOUS_IO_NONALERT ))
     {
         char buffer[32];
         DWORD size;
@@ -250,9 +281,10 @@ static DWORD get_filesystem_serial( const WCHAR *device )
         if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
         CloseHandle( handle );
         buffer[size] = 0;
-        return strtoul( buffer, NULL, 16 );
+        ret = strtoul( buffer, NULL, 16 );
     }
-    else return 0;
+    RtlFreeUnicodeString( &name );
+    return ret;
 }
 
 
@@ -377,8 +409,8 @@ static enum fs_type VOLUME_ReadCDSuperblock( HANDLE handle, BYTE *buff )
 /**************************************************************************
  *                              VOLUME_GetSuperblockLabel
  */
-static void VOLUME_GetSuperblockLabel( const WCHAR *device, enum fs_type type, const BYTE *superblock,
-                                       WCHAR *label, DWORD len )
+static void VOLUME_GetSuperblockLabel( const UNICODE_STRING *device, enum fs_type type,
+                                       const BYTE *superblock, WCHAR *label, DWORD len )
 {
     const BYTE *label_ptr = NULL;
     DWORD label_len;
@@ -431,7 +463,8 @@ static void VOLUME_GetSuperblockLabel( const WCHAR *device, enum fs_type type, c
 /**************************************************************************
  *                              VOLUME_GetSuperblockSerial
  */
-static DWORD VOLUME_GetSuperblockSerial( const WCHAR *device, enum fs_type type, const BYTE *superblock )
+static DWORD VOLUME_GetSuperblockSerial( const UNICODE_STRING *device, enum fs_type type,
+                                         const BYTE *superblock )
 {
     switch(type)
     {
@@ -515,7 +548,6 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
     static const WCHAR cdfsW[] = {'C','D','F','S',0};
     static const WCHAR default_rootW[] = {'\\',0};
 
-    WCHAR device[] = {'\\','\\','.','\\','A',':',0};
     HANDLE handle;
     NTSTATUS status;
     UNICODE_STRING nt_name;
@@ -539,7 +571,6 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
         SetLastError( ERROR_INVALID_NAME );
         goto done;
     }
-    device[4] = nt_name.Buffer[4];
 
     /* try to open the device */
 
@@ -585,8 +616,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
         TRACE( "%s: found fs type %d\n", debugstr_w(nt_name.Buffer), type );
         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 );
+        if (label && label_len) VOLUME_GetSuperblockLabel( &nt_name, type, superblock, label, label_len );
+        if (serial) *serial = VOLUME_GetSuperblockSerial( &nt_name, type, superblock );
         goto fill_fs_info;
     }
     else TRACE( "cannot open device %s: err %d\n", debugstr_w(nt_name.Buffer), GetLastError() );
@@ -608,8 +639,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
     }
     if (info.DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) type = FS_ISO9660;
 
-    if (label && label_len) get_filesystem_label( device, label, label_len );
-    if (serial) *serial = get_filesystem_serial( device );
+    if (label && label_len) get_filesystem_label( &nt_name, label, label_len );
+    if (serial) *serial = get_filesystem_serial( &nt_name );
 
 fill_fs_info:  /* now fill in the information that depends on the file system type */
 




More information about the wine-cvs mailing list