[PATCH] wineboot: Populate BIOS registry keys.

Brendan Shanks bshanks at codeweavers.com
Tue Feb 18 17:27:46 CST 2020


Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---
Note that not all WMI properties referenced are implemented yet by Wine,
future patches will add these.

 programs/wineboot/Makefile.in |   4 +-
 programs/wineboot/wineboot.c  | 143 ++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index 3921fa9644..67944a2444 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -1,7 +1,7 @@
 MODULE    = wineboot.exe
 APPMODE   = -mconsole
-IMPORTS   = uuid advapi32
-DELAYIMPORTS = shell32 shlwapi version user32 setupapi newdev
+IMPORTS   = uuid advapi32 wbemuuid
+DELAYIMPORTS = shell32 shlwapi version user32 setupapi newdev ole32 oleaut32
 
 EXTRADLLFLAGS = -mno-cygwin
 
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 8e3e234397..30d75b3214 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -72,6 +72,7 @@
 #include <shellapi.h>
 #include <setupapi.h>
 #include <newdev.h>
+#include <wbemcli.h>
 #include "resource.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
@@ -299,6 +300,145 @@ static void get_namestring( WCHAR *buf ) { }
 
 #endif  /* __i386__ || __x86_64__ */
 
+struct reg_wmi_map
+{
+    const WCHAR *registry_valname;
+    const WCHAR *wmi_propname;
+};
+static const struct reg_wmi_map bios_map[] =
+{
+    { L"BiosMajorRelease", L"SystemBiosMajorVersion" },
+    { L"BiosMinorRelease", L"SystemBiosMinorVersion" },
+    { L"BIOSReleaseDate", L"ReleaseDate" },
+    { L"BIOSVendor", L"Manufacturer" },
+    { L"BIOSVersion", L"SMBIOSBIOSVersion" },
+    { L"ECFirmwareMajorVersion", L"EmbeddedControllerMajorVersion" },
+    { L"ECFirmwareMinorVersion", L"EmbeddedControllerMinorVersion" },
+};
+static const struct reg_wmi_map baseboard_map[] =
+{
+    { L"BaseBoardManufacturer", L"Manufacturer" },
+    { L"BaseBoardProduct", L"Product" },
+    { L"BaseBoardVersion", L"Version" },
+};
+static const struct reg_wmi_map computersystem_map[] =
+{
+    { L"SystemFamily", L"SystemFamily" },
+    { L"SystemManufacturer", L"Manufacturer" },
+    { L"SystemProductName", L"Model" },
+    { L"SystemSKU", L"SystemSKUNumber" },
+};
+static const struct reg_wmi_map computersystemproduct_map[] =
+{
+    { L"SystemVersion", L"Version" },
+};
+
+static void create_bios_values( HKEY bios_key, IWbemServices *services, const WCHAR *class, const struct reg_wmi_map *map, unsigned int map_size )
+{
+    static const WCHAR select_allW[] = L"SELECT * FROM ";
+    HRESULT hr;
+    IEnumWbemClassObject *result = NULL;
+    LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY;
+    BSTR wql = NULL, query = NULL;
+    UINT len;
+
+    len = lstrlenW( class ) + ARRAY_SIZE(select_allW);
+    if (!(query = SysAllocStringLen( NULL, len ))) goto done;
+    lstrcpyW( query, select_allW );
+    lstrcatW( query, class );
+
+    if (!(wql = SysAllocString( L"WQL" ))) goto done;
+    hr = IWbemServices_ExecQuery( services, wql, query, flags, NULL, &result );
+    if (hr != S_OK) goto done;
+
+    for (;;)
+    {
+        IWbemClassObject *obj;
+        ULONG count;
+        unsigned int i;
+
+        IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count );
+        if (!count) break;
+
+        for (i = 0; i < map_size; i++)
+        {
+            BSTR str = NULL;
+            CIMTYPE cimtype;
+            VARIANT v;
+
+            if (!(str = SysAllocString( map[i].wmi_propname ))) break;
+            if (IWbemClassObject_Get( obj, str, 0, &v, &cimtype, NULL ) == WBEM_S_NO_ERROR)
+            {
+                if (V_VT( &v ) == VT_UI1)
+                {
+                    DWORD dw = V_UI1( &v );
+                    RegSetValueExW( bios_key, map[i].registry_valname, 0, REG_DWORD, (const BYTE *)&dw, sizeof(dw) );
+                }
+                else if (V_VT( &v ) == VT_BSTR)
+                {
+                    if (cimtype == CIM_DATETIME)
+                    {
+                        /* WMI/CIM datetime starts with "YYYYMMDD", but BIOSReleaseDate uses "MM/DD/YYYY" */
+                        WCHAR date[] = L"MM/DD/YYYY";
+                        const WCHAR *cimdate = V_BSTR( &v );
+                        memcpy( &date[6], &cimdate[0], 4*sizeof(WCHAR) );
+                        memcpy( &date[0], &cimdate[4], 2*sizeof(WCHAR) );
+                        memcpy( &date[3], &cimdate[6], 2*sizeof(WCHAR) );
+                        set_reg_value( bios_key, map[i].registry_valname, date );
+                    }
+                    else
+                        set_reg_value( bios_key, map[i].registry_valname, V_BSTR( &v ) );
+                }
+                VariantClear( &v );
+            }
+            SysFreeString( str );
+        }
+        IWbemClassObject_Release( obj );
+    }
+
+done:
+    if (result) IEnumWbemClassObject_Release( result );
+    SysFreeString( query );
+    SysFreeString( wql );
+}
+
+static void create_bios_key( HKEY system_key )
+{
+    HKEY bios_key;
+    HRESULT hr;
+    IWbemLocator *locator = NULL;
+    IWbemServices *services = NULL;
+    BSTR path = NULL;
+
+    if (RegCreateKeyExW( system_key, L"BIOS", 0, NULL, REG_OPTION_VOLATILE,
+                         KEY_ALL_ACCESS, NULL, &bios_key, NULL ))
+        return;
+
+    CoInitialize( NULL );
+    CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
+                          RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
+
+    hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
+                           (void **)&locator );
+    if (hr != S_OK) goto done;
+
+    if (!(path = SysAllocString( L"ROOT\\CIMV2" ))) goto done;
+    hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
+    if (hr != S_OK) goto done;
+
+    create_bios_values( bios_key, services, L"Win32_BaseBoard", baseboard_map, ARRAY_SIZE(baseboard_map) );
+    create_bios_values( bios_key, services, L"Win32_BIOS", bios_map, ARRAY_SIZE(bios_map) );
+    create_bios_values( bios_key, services, L"Win32_ComputerSystem", computersystem_map, ARRAY_SIZE(computersystem_map) );
+    create_bios_values( bios_key, services, L"Win32_ComputerSystemProduct", computersystemproduct_map, ARRAY_SIZE(computersystemproduct_map) );
+
+done:
+    if (services) IWbemServices_Release( services );
+    if (locator) IWbemLocator_Release( locator );
+    SysFreeString( path );
+    CoUninitialize();
+    RegCloseKey( bios_key );
+}
+
 /* create the volatile hardware registry keys */
 static void create_hardware_registry_keys(void)
 {
@@ -409,6 +549,9 @@ static void create_hardware_registry_keys(void)
             RegCloseKey( hkey );
         }
     }
+
+    create_bios_key( system_key );
+
     RegCloseKey( fpu_key );
     RegCloseKey( cpu_key );
     RegCloseKey( system_key );
-- 
2.24.1




More information about the wine-devel mailing list