Alexandre Julliard : kernel32: Read label and serial from the filesystem when the device is accessible but unknown .

Alexandre Julliard julliard at winehq.org
Sat Dec 8 13:43:38 CST 2007


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Sat Dec  8 19:53:24 2007 +0100

kernel32: Read label and serial from the filesystem when the device is accessible but unknown.

---

 dlls/kernel32/volume.c |  109 ++++++++++++++++++++++++++---------------------
 1 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index 7f07f56..1869d0d 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -161,6 +161,52 @@ static BOOL open_device_root( LPCWSTR root, HANDLE *handle )
     return TRUE;
 }
 
+/* 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 )
+{
+    HANDLE handle;
+    WCHAR labelW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
+
+    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)
+    {
+        char buffer[256], *p;
+        DWORD size;
+
+        if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
+        CloseHandle( handle );
+        p = buffer + size;
+        while (p > buffer && (p[-1] == ' ' || p[-1] == '\r' || p[-1] == '\n')) p--;
+        *p = 0;
+        if (!MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, label, len ))
+            label[len-1] = 0;
+    }
+    else label[0] = 0;
+}
+
+/* get the serial number by reading it from a file at the root of the filesystem */
+static DWORD get_filesystem_serial( const WCHAR *device )
+{
+    HANDLE handle;
+    WCHAR serialW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',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)
+    {
+        char buffer[32];
+        DWORD size;
+
+        if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
+        CloseHandle( handle );
+        buffer[size] = 0;
+        return strtoul( buffer, NULL, 16 );
+    }
+    else return 0;
+}
 
 /* fetch the type of a drive from the registry */
 static UINT get_registry_drive_type( const WCHAR *root )
@@ -256,10 +302,11 @@ static enum fs_type VOLUME_ReadFATSuperblock( HANDLE handle, BYTE *buff )
 
     /* try a fixed disk, with a FAT partition */
     if (SetFilePointer( handle, 0, NULL, FILE_BEGIN ) != 0 ||
-        !ReadFile( handle, buff, SUPERBLOCK_SIZE, &size, NULL ) ||
-        size != SUPERBLOCK_SIZE)
+        !ReadFile( handle, buff, SUPERBLOCK_SIZE, &size, NULL ))
         return FS_ERROR;
 
+    if (size < SUPERBLOCK_SIZE) return FS_UNKNOWN;
+
     /* FIXME: do really all FAT have their name beginning with
      * "FAT" ? (At least FAT12, FAT16 and FAT32 have :)
      */
@@ -332,7 +379,7 @@ static enum fs_type VOLUME_ReadCDSuperblock( HANDLE handle, BYTE *buff )
 /**************************************************************************
  *                              VOLUME_GetSuperblockLabel
  */
-static void VOLUME_GetSuperblockLabel( enum fs_type type, const BYTE *superblock,
+static void VOLUME_GetSuperblockLabel( const WCHAR *device, enum fs_type type, const BYTE *superblock,
                                        WCHAR *label, DWORD len )
 {
     const BYTE *label_ptr = NULL;
@@ -341,9 +388,11 @@ static void VOLUME_GetSuperblockLabel( enum fs_type type, const BYTE *superblock
     switch(type)
     {
     case FS_ERROR:
-    case FS_UNKNOWN:
         label_len = 0;
         break;
+    case FS_UNKNOWN:
+        get_filesystem_label( device, label, len );
+        return;
     case FS_FAT1216:
         label_ptr = superblock + 0x2b;
         label_len = 11;
@@ -384,13 +433,14 @@ static void VOLUME_GetSuperblockLabel( enum fs_type type, const BYTE *superblock
 /**************************************************************************
  *                              VOLUME_GetSuperblockSerial
  */
-static DWORD VOLUME_GetSuperblockSerial( enum fs_type type, const BYTE *superblock )
+static DWORD VOLUME_GetSuperblockSerial( const WCHAR *device, enum fs_type type, const BYTE *superblock )
 {
     switch(type)
     {
     case FS_ERROR:
-    case FS_UNKNOWN:
         break;
+    case FS_UNKNOWN:
+        return get_filesystem_serial( device );
     case FS_FAT1216:
         return GETLONG( superblock, 0x27 );
     case FS_FAT32:
@@ -519,8 +569,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
         TRACE( "%s: found fs type %d\n", debugstr_w(device), type );
         if (type == FS_ERROR) return FALSE;
 
-        if (label && label_len) VOLUME_GetSuperblockLabel( type, superblock, label, label_len );
-        if (serial) *serial = VOLUME_GetSuperblockSerial( type, superblock );
+        if (label && label_len) VOLUME_GetSuperblockLabel( device, type, superblock, label, label_len );
+        if (serial) *serial = VOLUME_GetSuperblockSerial( device, type, superblock );
         goto fill_fs_info;
     }
     else TRACE( "cannot open device %s: err %d\n", debugstr_w(device), GetLastError() );
@@ -544,47 +594,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
         break;
     }
 
-    if (label && label_len)
-    {
-        WCHAR labelW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
-
-        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)
-        {
-            char buffer[256], *p;
-            DWORD size;
-
-            if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
-            CloseHandle( handle );
-            p = buffer + size;
-            while (p > buffer && (p[-1] == ' ' || p[-1] == '\r' || p[-1] == '\n')) p--;
-            *p = 0;
-            if (!MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, label, label_len ))
-                label[label_len-1] = 0;
-        }
-        else label[0] = 0;
-    }
-    if (serial)
-    {
-        WCHAR serialW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',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)
-        {
-            char buffer[32];
-            DWORD size;
-
-            if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
-            CloseHandle( handle );
-            buffer[size] = 0;
-            *serial = strtoul( buffer, NULL, 16 );
-        }
-        else *serial = 0;
-    }
+    if (label && label_len) get_filesystem_label( device, label, label_len );
+    if (serial) *serial = get_filesystem_serial( device );
 
 fill_fs_info:  /* now fill in the information that depends on the file system type */
 




More information about the wine-cvs mailing list