[PATCH 3/3] wbemprox: Get the disk drive serial number from mountmgr.

Hans Leidekker hans at codeweavers.com
Mon May 18 02:49:41 CDT 2020


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49160
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wbemprox/builtin.c     | 40 +++++++++++++++++++++++++++++++++++--
 dlls/wbemprox/tests/query.c | 26 ++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index ddd12d6ebcb..6a35737da59 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -44,6 +44,8 @@
 #include "ntsecapi.h"
 #include "winspool.h"
 #include "setupapi.h"
+#define WINE_MOUNTMGR_EXTENSIONS
+#include <ddk/mountmgr.h>
 
 #include "wine/asm.h"
 #include "wine/debug.h"
@@ -140,7 +142,7 @@ static const struct column col_diskdrive[] =
     { L"MediaType",     CIM_STRING },
     { L"Model",         CIM_STRING },
     { L"PNPDeviceID",   CIM_STRING },
-    { L"SerialNumber",  CIM_STRING },
+    { L"SerialNumber",  CIM_STRING|COL_FLAG_DYNAMIC },
     { L"Size",          CIM_UINT64 },
 };
 static const struct column col_diskdrivetodiskpartition[] =
@@ -2081,6 +2083,40 @@ static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
     }
     return free.QuadPart;
 }
+static WCHAR *get_diskdrive_serialnumber( WCHAR drive_letter )
+{
+    WCHAR *ret = NULL;
+    struct mountmgr_unix_drive input;
+    struct mountmgr_unix_drive *data;
+    HANDLE handle;
+    DWORD size = 256;
+
+    memset( &input, 0, sizeof(input) );
+    input.letter = drive_letter;
+
+    if ((handle = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                               NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) goto done;
+    for (;;)
+    {
+        if (!(data = heap_alloc( size ))) break;
+
+        if (DeviceIoControl( handle, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, &input, sizeof(input), data, size, NULL, NULL ))
+        {
+            if (data->disk_serial_offset) ret = heap_strdupAW( (const char *)data + data->disk_serial_offset );
+            heap_free( data );
+            break;
+        }
+
+        heap_free( data );
+        if (GetLastError() == ERROR_MORE_DATA) size = data->size;
+        else break;
+    }
+    CloseHandle( handle );
+
+done:
+    if (!ret) return heap_strdupW( L"WINEHDISK" );
+    return ret;
+}
 
 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
 {
@@ -2114,7 +2150,7 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr *
             rec->mediatype     = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media";
             rec->model         = L"Wine Disk Drive";
             rec->pnpdevice_id  = L"IDE\\Disk\\VEN_WINE";
-            rec->serialnumber  = L"WINEHDISK";
+            rec->serialnumber  = get_diskdrive_serialnumber( root[0] );
             get_freespace( root, &size );
             rec->size          = size;
             if (!match_row( table, row, cond, &status ))
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index a9b4910ebfa..578e9308df7 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -1456,6 +1456,31 @@ static void test_Win32_DesktopMonitor( IWbemServices *services )
     SysFreeString( wql );
 }
 
+static void test_Win32_DiskDrive( IWbemServices *services )
+{
+    BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( L"SELECT * FROM Win32_DiskDrive" );
+    IEnumWbemClassObject *result;
+    IWbemClassObject *obj;
+    HRESULT hr;
+    DWORD count;
+
+    hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    for (;;)
+    {
+        hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
+        if (hr != S_OK) break;
+
+        check_property( obj, L"DeviceID", VT_BSTR, CIM_STRING );
+        IWbemClassObject_Release( obj );
+    }
+
+    IEnumWbemClassObject_Release( result );
+    SysFreeString( query );
+    SysFreeString( wql );
+}
+
 static void test_Win32_DisplayControllerConfiguration( IWbemServices *services )
 {
     BSTR wql = SysAllocString( L"wql" );
@@ -1561,6 +1586,7 @@ START_TEST(query)
     test_Win32_ComputerSystemProduct( services );
     test_Win32_Bios( services );
     test_Win32_DesktopMonitor( services );
+    test_Win32_DiskDrive( services );
     test_Win32_DisplayControllerConfiguration( services );
     test_Win32_IP4RouteTable( services );
     test_Win32_OperatingSystem( services );
-- 
2.20.1




More information about the wine-devel mailing list