From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53747 --- .../Makefile.in | 2 +- .../main.c | 73 ++++++++++++++++++- .../private.h | 12 +++ .../tests/smbios.c | 4 +- 4 files changed, 86 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.system.profile.systemmanufacturers/Makefile.in b/dlls/windows.system.profile.systemmanufacturers/Makefile.in index a2d6076740f..9d07caa287c 100644 --- a/dlls/windows.system.profile.systemmanufacturers/Makefile.in +++ b/dlls/windows.system.profile.systemmanufacturers/Makefile.in @@ -1,5 +1,5 @@ MODULE = windows.system.profile.systemmanufacturers.dll -IMPORTS = combase +IMPORTS = combase oleaut32
C_SRCS = \ main.c diff --git a/dlls/windows.system.profile.systemmanufacturers/main.c b/dlls/windows.system.profile.systemmanufacturers/main.c index 35b4529ad7a..6b9c6b27cc8 100644 --- a/dlls/windows.system.profile.systemmanufacturers/main.c +++ b/dlls/windows.system.profile.systemmanufacturers/main.c @@ -128,10 +128,79 @@ static const struct IActivationFactoryVtbl factory_vtbl =
DEFINE_IINSPECTABLE( statics, ISmbiosInformationStatics, struct smbios_statics, IActivationFactory_iface )
+static HRESULT WINAPI get_bios_system_serial( BSTR *value ) +{ + const WCHAR *class = L"Win32_BIOS"; + IEnumWbemClassObject *wbem_enum; + IWbemClassObject *wbem_class; + IWbemServices *wbem_service; + IWbemLocator *wbem_locator; + VARIANT serial; + ULONG count; + HRESULT hr; + BSTR bstr; + + hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (void**)&wbem_locator ); + if (FAILED(hr)) return hr; + + bstr = SysAllocString( L"ROOT\CIMV2" ); + if (!bstr) + { + IWbemLocator_Release( wbem_locator ); + return E_OUTOFMEMORY; + } + hr = IWbemLocator_ConnectServer( wbem_locator, bstr, NULL, NULL, NULL, 0, NULL, NULL, &wbem_service ); + IWbemLocator_Release( wbem_locator ); + SysFreeString( bstr ); + if (FAILED(hr)) return hr; + + bstr = SysAllocString( class ); + if (!bstr) + { + IWbemServices_Release( wbem_service ); + return E_OUTOFMEMORY; + } + hr = IWbemServices_CreateInstanceEnum( wbem_service, bstr, WBEM_FLAG_SYSTEM_ONLY, NULL, &wbem_enum ); + IWbemServices_Release( wbem_service ); + SysFreeString( bstr ); + if (FAILED(hr)) return hr; + + hr = IEnumWbemClassObject_Next( wbem_enum, 1000, 1, &wbem_class, &count ); + IEnumWbemClassObject_Release( wbem_enum ); + if (FAILED(hr)) return hr; + + hr = IWbemClassObject_Get( wbem_class, L"SerialNumber", 0, &serial, NULL, NULL ); + IWbemClassObject_Release( wbem_class ); + if (FAILED(hr)) return hr; + + *value = V_BSTR( &serial ); + VariantClear( &serial ); + return hr; +} + static HRESULT WINAPI statics_get_SerialNumber( ISmbiosInformationStatics *iface, HSTRING *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + BSTR serial = NULL; + HSTRING ret; + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + hr = get_bios_system_serial( &serial ); + if (FAILED(hr)) + { + WARN( "Failed to get serial number, returning 0.\n" ); + serial = strdupAW("0"); + } + + if (FAILED( hr = WindowsCreateString( serial, wcslen(serial), &ret ) )) goto done; + TRACE( "Returning serial number: %s.\n", debugstr_hstring( ret ) ); + hr = WindowsDuplicateString( ret, value ); + WindowsDeleteString( ret ); + +done: + free( serial ); + return hr; }
static const struct ISmbiosInformationStaticsVtbl statics_vtbl = diff --git a/dlls/windows.system.profile.systemmanufacturers/private.h b/dlls/windows.system.profile.systemmanufacturers/private.h index 42c19710dcb..ff18b979d78 100644 --- a/dlls/windows.system.profile.systemmanufacturers/private.h +++ b/dlls/windows.system.profile.systemmanufacturers/private.h @@ -30,6 +30,8 @@ #define WIDL_using_Windows_System_Profile_SystemManufacturers #include "windows.system.profile.systemmanufacturers.h"
+#include "wbemcli.h" + #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ { \ @@ -67,3 +69,13 @@ } #define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \ DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface ) + +static inline WCHAR *strdupAW( const char *src ) +{ + WCHAR *dst; + int len; + if (!src) return NULL; + len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 ); + if ((dst = malloc( len * sizeof(*dst) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len ); + return dst; +} diff --git a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c index 0477a00dfb6..2136b3ceff9 100644 --- a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c +++ b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c @@ -73,11 +73,11 @@ static void test_Smbios_Statics(void) ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = ISmbiosInformationStatics_get_SerialNumber( smbios_statics, &serial ); - todo_wine ok( hr == S_OK || broken(hr == E_UNEXPECTED), "got hr %#lx.\n", hr ); + ok( hr == S_OK || broken(hr == E_UNEXPECTED), "got hr %#lx.\n", hr ); if (hr == S_OK) { buf = WindowsGetStringRawBuffer( serial, &len ); - todo_wine ok( buf != NULL && len > 0, "WindowsGetStringRawBuffer returned buf %p, len %u\n", buf, len ); + ok( buf != NULL && len > 0, "WindowsGetStringRawBuffer returned buf %p, len %u\n", buf, len ); WindowsDeleteString( serial ); }