The test for ISmbiosInformationStatics_get_SerialNumber is broken on Window 10 testbot VMs, presumably because they don't have a serial number? It results in an HRESULT of E_UNEXPECTED. I added a broken test case for it. I'm assuming that normal installations of Windows return a valid serial number or at least something like "Not Specified" and not NULL. Also, on my Linux OS running cat /sys/class/dmi/id/product_serial returns "To be filled by O.E.M". So I added a fallback to return 0 as the number. Or is it fine to just return whatever string is found?
On the Windows 8 VMs, the test crashes at line 75, hr = ISmbiosInformationStatics_get_SerialNumber( smbios_statics, &serial ). Not sure what I should do in this case. I was hoping for a flag that checks if the VM is Windows 8, but there doesn't seem to be one. Should I wrap the test in if (0) or is there an alternative way?
Another weird thing is the test fails prematurely on only the 32-bit version of debian11b, saying that the runtimeclass is not registered. I'm assuming it's an issue with the testbot. Debian11 32 bit runs fine.
-- v2: windows.system.profile.systemmanufacturers: Implement ISmbiosInformationStatics_get_SerialNumber. wbemprox: Provide accurate SMBIOS serial number. windows.system.profile.systemmanufacturers/tests: Add ISmbiosInformationStatics_get_SerialNumber tests. windows.system.profile.systemmanufacturers: Stub ISmbiosInformationStatics interface. windows.system.profile.systemmanufacturers: Add stub DLL.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + ...ows.system.profile.systemmanufacturers.idl | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 include/windows.system.profile.systemmanufacturers.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 62904d8d2a0..0790fbbb3e4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -813,6 +813,7 @@ SOURCES = \ windows.storage.streams.idl \ windows.system.idl \ windows.system.power.idl \ + windows.system.profile.systemmanufacturers.idl \ windows.system.threading.idl \ windows.system.userprofile.idl \ windows.ui.idl \ diff --git a/include/windows.system.profile.systemmanufacturers.idl b/include/windows.system.profile.systemmanufacturers.idl new file mode 100644 index 00000000000..644a664020b --- /dev/null +++ b/include/windows.system.profile.systemmanufacturers.idl @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; + +namespace Windows.System.Profile.SystemManufacturers +{ + apicontract SystemManufacturersContract; + interface ISmbiosInformationStatics; + runtimeclass SmbiosInformation; + + [ + contractversion(3.0) + ] + apicontract SystemManufacturersContract + { + } + + [ + contract(Windows.System.Profile.SystemManufacturers.SystemManufacturersContract, 1.0), + exclusiveto(Windows.System.Profile.SystemManufacturers.SmbiosInformation), + uuid(080cca7c-637c-48c4-b728-f9273812db8e) + ] + interface ISmbiosInformationStatics : IInspectable + { + [propget] HRESULT SerialNumber([out, retval] HSTRING *value); + } + + [ + contract(Windows.System.Profile.SystemManufacturers.SystemManufacturersContract, 1.0), + marshaling_behavior(agile), + static(Windows.System.Profile.SystemManufacturers.ISmbiosInformationStatics, Windows.System.Profile.SystemManufacturers.SystemManufacturersContract, 1.0) + ] + runtimeclass SmbiosInformation + { + } +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + .../Makefile.in | 8 + .../classes.idl | 23 +++ .../main.c | 148 ++++++++++++++++++ .../private.h | 31 ++++ .../tests/Makefile.in | 5 + .../tests/smbios.c | 83 ++++++++++ ...ws.system.profile.systemmanufacturers.spec | 3 + 8 files changed, 303 insertions(+) create mode 100644 dlls/windows.system.profile.systemmanufacturers/Makefile.in create mode 100644 dlls/windows.system.profile.systemmanufacturers/classes.idl create mode 100644 dlls/windows.system.profile.systemmanufacturers/main.c create mode 100644 dlls/windows.system.profile.systemmanufacturers/private.h create mode 100644 dlls/windows.system.profile.systemmanufacturers/tests/Makefile.in create mode 100644 dlls/windows.system.profile.systemmanufacturers/tests/smbios.c create mode 100644 dlls/windows.system.profile.systemmanufacturers/windows.system.profile.systemmanufacturers.spec
diff --git a/configure.ac b/configure.ac index cb91c9c02b5..321d5efa50d 100644 --- a/configure.ac +++ b/configure.ac @@ -3180,6 +3180,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media) WINE_CONFIG_MAKEFILE(dlls/windows.media/tests) WINE_CONFIG_MAKEFILE(dlls/windows.networking) +WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers) +WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecs) WINE_CONFIG_MAKEFILE(dlls/windowscodecs/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecsext) diff --git a/dlls/windows.system.profile.systemmanufacturers/Makefile.in b/dlls/windows.system.profile.systemmanufacturers/Makefile.in new file mode 100644 index 00000000000..a2d6076740f --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/Makefile.in @@ -0,0 +1,8 @@ +MODULE = windows.system.profile.systemmanufacturers.dll +IMPORTS = combase + +C_SRCS = \ + main.c + +IDL_SRCS = \ + classes.idl diff --git a/dlls/windows.system.profile.systemmanufacturers/classes.idl b/dlls/windows.system.profile.systemmanufacturers/classes.idl new file mode 100644 index 00000000000..6072a782222 --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.system.profile.systemmanufacturers.dll + * + * Copyright (C) 2022 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +#include "windows.system.profile.systemmanufacturers.idl" diff --git a/dlls/windows.system.profile.systemmanufacturers/main.c b/dlls/windows.system.profile.systemmanufacturers/main.c new file mode 100644 index 00000000000..3f5e937392e --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/main.c @@ -0,0 +1,148 @@ +/* WinRT Windows.System.Profile.SystemManufacturers Implementation + * + * Copyright (C) 2022 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(smbios); + +static const char *debugstr_hstring( HSTRING hstr ) +{ + const WCHAR *str; + UINT32 len; + if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; + str = WindowsGetStringRawBuffer(hstr, &len); + return wine_dbgstr_wn(str, len); +} + +struct smbios_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct smbios_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct smbios_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct smbios_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct smbios_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct smbios_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct smbios_statics smbios_statics = +{ + {&factory_vtbl}, + 1, +}; + +static IActivationFactory *smbios_factory = &smbios_statics.IActivationFactory_iface; + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *name = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "classid %s, factory %p.\n", debugstr_hstring(classid), factory ); + + *factory = NULL; + + if (!wcscmp( name, RuntimeClass_Windows_System_Profile_SystemManufacturers_SmbiosInformation )) + IActivationFactory_QueryInterface( smbios_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.system.profile.systemmanufacturers/private.h b/dlls/windows.system.profile.systemmanufacturers/private.h new file mode 100644 index 00000000000..e3672c3aec5 --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/private.h @@ -0,0 +1,31 @@ +/* WinRT Windows.System.Profile.SystemManufacturers Implementation + * + * Copyright (C) 2022 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> +#include <stddef.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_System_Profile_SystemManufacturers +#include "windows.system.profile.systemmanufacturers.h" diff --git a/dlls/windows.system.profile.systemmanufacturers/tests/Makefile.in b/dlls/windows.system.profile.systemmanufacturers/tests/Makefile.in new file mode 100644 index 00000000000..ade0c6b12dd --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.system.profile.systemmanufacturers.dll +IMPORTS = combase + +C_SRCS = \ + smbios.c diff --git a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c new file mode 100644 index 00000000000..fa3308f21ab --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_System_Profile_SystemManufacturers +#include "windows.system.profile.systemmanufacturers.h" + +#include "wine/test.h" + +#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) +static void check_interface_( unsigned int line, void *obj, const IID *iid ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + IUnknown_Release( unk ); +} + +static void test_Smbios_Statics(void) +{ + static const WCHAR *smbios_statics_name = L"Windows.System.Profile.SystemManufacturers.SmbiosInformation"; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( smbios_statics_name, wcslen( smbios_statics_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( smbios_statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(smbios) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_Smbios_Statics(); + + RoUninitialize(); +} diff --git a/dlls/windows.system.profile.systemmanufacturers/windows.system.profile.systemmanufacturers.spec b/dlls/windows.system.profile.systemmanufacturers/windows.system.profile.systemmanufacturers.spec new file mode 100644 index 00000000000..31a5eafe950 --- /dev/null +++ b/dlls/windows.system.profile.systemmanufacturers/windows.system.profile.systemmanufacturers.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr)
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../main.c | 30 +++++++++++++++ .../private.h | 38 +++++++++++++++++++ .../tests/smbios.c | 7 ++++ 3 files changed, 75 insertions(+)
diff --git a/dlls/windows.system.profile.systemmanufacturers/main.c b/dlls/windows.system.profile.systemmanufacturers/main.c index 3f5e937392e..35b4529ad7a 100644 --- a/dlls/windows.system.profile.systemmanufacturers/main.c +++ b/dlls/windows.system.profile.systemmanufacturers/main.c @@ -36,6 +36,7 @@ static const char *debugstr_hstring( HSTRING hstr ) struct smbios_statics { IActivationFactory IActivationFactory_iface; + ISmbiosInformationStatics ISmbiosInformationStatics_iface; LONG ref; };
@@ -60,6 +61,13 @@ static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID return S_OK; }
+ if (IsEqualGUID( iid, &IID_ISmbiosInformationStatics )) + { + *out = &impl->ISmbiosInformationStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -118,9 +126,31 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+DEFINE_IINSPECTABLE( statics, ISmbiosInformationStatics, struct smbios_statics, IActivationFactory_iface ) + +static HRESULT WINAPI statics_get_SerialNumber( ISmbiosInformationStatics *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct ISmbiosInformationStaticsVtbl statics_vtbl = +{ + statics_QueryInterface, + statics_AddRef, + statics_Release, + /* IInspectable methods */ + statics_GetIids, + statics_GetRuntimeClassName, + statics_GetTrustLevel, + /* ISmbiosInformationStatics methods */ + statics_get_SerialNumber, +}; + static struct smbios_statics smbios_statics = { {&factory_vtbl}, + {&statics_vtbl}, 1, };
diff --git a/dlls/windows.system.profile.systemmanufacturers/private.h b/dlls/windows.system.profile.systemmanufacturers/private.h index e3672c3aec5..42c19710dcb 100644 --- a/dlls/windows.system.profile.systemmanufacturers/private.h +++ b/dlls/windows.system.profile.systemmanufacturers/private.h @@ -29,3 +29,41 @@
#define WIDL_using_Windows_System_Profile_SystemManufacturers #include "windows.system.profile.systemmanufacturers.h" + +#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ + static inline impl_type *impl_from( iface_type *iface ) \ + { \ + return CONTAINING_RECORD( iface, impl_type, iface_mem ); \ + } \ + static HRESULT WINAPI pfx##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_QueryInterface( (IInspectable *)(expr), iid, out ); \ + } \ + static ULONG WINAPI pfx##_AddRef( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_AddRef( (IInspectable *)(expr) ); \ + } \ + static ULONG WINAPI pfx##_Release( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_Release( (IInspectable *)(expr) ); \ + } \ + static HRESULT WINAPI pfx##_GetIids( iface_type *iface, ULONG *iid_count, IID **iids ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetIids( (IInspectable *)(expr), iid_count, iids ); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName( iface_type *iface, HSTRING *class_name ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetRuntimeClassName( (IInspectable *)(expr), class_name ); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel( iface_type *iface, TrustLevel *trust_level ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetTrustLevel( (IInspectable *)(expr), trust_level ); \ + } +#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 ) diff --git a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c index fa3308f21ab..e23a4d9adb7 100644 --- a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c +++ b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c @@ -45,6 +45,7 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) static void test_Smbios_Statics(void) { static const WCHAR *smbios_statics_name = L"Windows.System.Profile.SystemManufacturers.SmbiosInformation"; + ISmbiosInformationStatics *smbios_statics; IActivationFactory *factory; HSTRING str; HRESULT hr; @@ -66,6 +67,12 @@ static void test_Smbios_Statics(void) check_interface( factory, &IID_IInspectable ); check_interface( factory, &IID_IAgileObject );
+ hr = IActivationFactory_QueryInterface( factory, &IID_ISmbiosInformationStatics, (void **)&smbios_statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = ISmbiosInformationStatics_Release( smbios_statics ); + ok( ref == 2, "got ref %ld.\n", ref ); + ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../tests/smbios.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c index e23a4d9adb7..0477a00dfb6 100644 --- a/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c +++ b/dlls/windows.system.profile.systemmanufacturers/tests/smbios.c @@ -47,8 +47,10 @@ static void test_Smbios_Statics(void) static const WCHAR *smbios_statics_name = L"Windows.System.Profile.SystemManufacturers.SmbiosInformation"; ISmbiosInformationStatics *smbios_statics; IActivationFactory *factory; - HSTRING str; + HSTRING str, serial; + const WCHAR *buf; HRESULT hr; + UINT32 len; LONG ref;
hr = WindowsCreateString( smbios_statics_name, wcslen( smbios_statics_name ), &str ); @@ -70,6 +72,15 @@ static void test_Smbios_Statics(void) hr = IActivationFactory_QueryInterface( factory, &IID_ISmbiosInformationStatics, (void **)&smbios_statics ); 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 ); + if (hr == S_OK) + { + buf = WindowsGetStringRawBuffer( serial, &len ); + todo_wine ok( buf != NULL && len > 0, "WindowsGetStringRawBuffer returned buf %p, len %u\n", buf, len ); + WindowsDeleteString( serial ); + } + ref = ISmbiosInformationStatics_Release( smbios_statics ); ok( ref == 2, "got ref %ld.\n", ref );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wbemprox/builtin.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index b8f7d0b8dca..3e61dfa6321 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -1378,6 +1378,26 @@ static WCHAR *get_bios_releasedate( const char *buf, UINT len ) return ret; }
+static WCHAR *get_bios_system_serial_string( BYTE id, const char *buf, UINT len ) +{ + const struct smbios_header *hdr; + const struct smbios_system *system; + UINT offset; + + if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL; + system = (const struct smbios_system *)hdr; + offset = (const char *)system - buf + system->hdr.length; + + return get_smbios_string( id, buf, offset, len ); +} + +static WCHAR *get_bios_system_serial( const char *buf, UINT len ) +{ + WCHAR *ret = get_bios_system_serial_string( 4, buf, len ); + if (!ret) return wcsdup( L"0" ); + return ret; +} + static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len ) { WCHAR *ret = get_bios_string( 2, buf, len ); @@ -1455,7 +1475,7 @@ static enum fill_status fill_bios( struct table *table, const struct expr *cond rec->manufacturer = get_bios_manufacturer( buf, len ); rec->name = L"Default System BIOS"; rec->releasedate = get_bios_releasedate( buf, len ); - rec->serialnumber = L"0"; + rec->serialnumber = get_bios_system_serial( buf, len ); rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len ); rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len ); rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
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 ); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126979
Your paranoid android.
=== w8 (32 bit report) ===
windows.system.profile.systemmanufacturers: 0a94:smbios: unhandled exception c0000005 at 68662D95
=== w8adm (32 bit report) ===
windows.system.profile.systemmanufacturers: 0a48:smbios: unhandled exception c0000005 at 6D592D95
=== w864 (32 bit report) ===
windows.system.profile.systemmanufacturers: 0bf8:smbios: unhandled exception c0000005 at 73D62D95
=== w864 (64 bit report) ===
windows.system.profile.systemmanufacturers: 0ae4:smbios: unhandled exception c0000005 at 00007FFDC008368E
=== debian11b (32 bit WoW report) ===
windows.system.profile.systemmanufacturers: smbios.c:61: Test failed: got hr 0x80040154. smbios.c:64: Test failed: L"Windows.System.Profile.SystemManufacturers.SmbiosInformation" runtimeclass not registered, skipping tests.
Mohamad Al-Jaf (@maljaf) commented about dlls/windows.system.profile.systemmanufacturers/main.c:
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");
This could be changed to use wcsdup instead. But is it considered good practice having a fallback or should the function just fail completely if it fails to get a serial number using wbemprox?
```suggestion:-0+0 serial = wcsdup(L"0"); ```
Hans Leidekker (@hans) commented about dlls/wbemprox/builtin.c:
- UINT offset;
- if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
- system = (const struct smbios_system *)hdr;
- offset = (const char *)system - buf + system->hdr.length;
- return get_smbios_string( id, buf, offset, len );
+}
+static WCHAR *get_bios_system_serial( const char *buf, UINT len ) +{
- WCHAR *ret = get_bios_system_serial_string( 4, buf, len );
- if (!ret) return wcsdup( L"0" );
- return ret;
+}
Please name the getter after the property: get_bios_serialnumber(). This can be simplified to: `static WCHAR *get_bios_serialnumber( const char *buf, UINT len ) { WCHAR *ret = get_bios_string( 4, buf, len ); if (!ret) return wcsdup( L"0" ); return ret; } ` Note that on Linux this will not get a different value because serial numbers are readable only by root.
On Wed Nov 30 08:03:41 2022 +0000, Mohamad Al-Jaf wrote:
This could be changed to use wcsdup instead. But is it considered good practice having a fallback or should the function just fail completely if it fails to get a serial number using wbemprox?
serial = wcsdup(L"0");
I think it should return the failure from wbemprox. There's already a fallback there so no need to have it one here.
On Wed Nov 30 07:25:45 2022 +0000, Mohamad Al-Jaf wrote:
You're referring to the debian11b VM, right? On my Arch machine it's registered correctly as `C:\windows\system32\windows.system.profile.systemmanufacturers.dll`. BTW, how did you discover this? It's likely the long name, yeah. I have no idea how to fix it myself. Do you think it would be difficult?
I had failures when running the tests locally, creating a new prefix and running winetest in it. I don't remember exactly where things happen, probably something with `setupapi` `register_fake_dll` / `atl` registrar object.
On Wed Nov 30 07:26:54 2022 +0000, Mohamad Al-Jaf wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/1588/diffs?diff_id=21799&start_sha=b40c79732b725ba22068d6029aa08f8f085054e3#2cdb0443a3ace1abaf8e66342453a265711c0f07_221_189)
Less things to write and it removes the need of custom `heap_` helpers. It's also more canonical C, for good or worse, like `realloc` accepts `NULL` pointer (but frees with 0 size).