From: Julian Klemann jklemann@codeweavers.com
Fixes the UUID of ITypedEventHandler<DeviceWatcher*, IInspectable*> to match MIDL. --- tools/widl/typetree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index fef9d2e5c03..ee71a7a2899 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -168,7 +168,8 @@ static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t switch (type->type_type) { case TYPE_INTERFACE: - if (type->signature) n += strappend(buf, len, pos + n, "%s", type->signature); + if (!strcmp(type->name, "IInspectable")) n += strappend(buf, len, pos + n, "cinterface(IInspectable)"); + else if (type->signature) n += strappend(buf, len, pos + n, "%s", type->signature); else { if (!(uuid = get_attrp(type->attrs, ATTR_UUID)))
From: Julian Klemann jklemann@codeweavers.com
Remove nested namespaces and forward declares. --- include/windows.devices.enumeration.idl | 344 +++++++++++------------- 1 file changed, 156 insertions(+), 188 deletions(-)
diff --git a/include/windows.devices.enumeration.idl b/include/windows.devices.enumeration.idl index 7cde49224a1..f47df3795fa 100644 --- a/include/windows.devices.enumeration.idl +++ b/include/windows.devices.enumeration.idl @@ -27,202 +27,170 @@ import "windowscontracts.idl"; import "windows.storage.streams.idl"; import "windows.foundation.idl";
-namespace Windows { - namespace Devices { - namespace Enumeration { - typedef enum DeviceWatcherStatus DeviceWatcherStatus; - typedef enum Panel Panel; - - interface IDeviceInformation; - interface IDeviceInformationStatics; - interface IDeviceInformationStatics2; - interface IDeviceInformationUpdate; - interface IEnclosureLocation; - - runtimeclass DeviceInformation; - runtimeclass DeviceInformationUpdate; - runtimeclass DeviceThumbnail; - runtimeclass DeviceWatcher; - runtimeclass EnclosureLocation; - } +namespace Windows.Devices.Enumeration { + typedef enum DeviceWatcherStatus DeviceWatcherStatus; + typedef enum Panel Panel; + + interface IDeviceInformation; + interface IDeviceInformationStatics; + interface IDeviceInformationStatics2; + interface IDeviceInformationUpdate; + interface IEnclosureLocation; + + runtimeclass DeviceInformation; + runtimeclass DeviceInformationUpdate; + runtimeclass DeviceThumbnail; + runtimeclass DeviceWatcher; + runtimeclass EnclosureLocation; + + declare + { + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceThumbnail *>; + interface Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *>; + interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *>; + interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, IInspectable *>; + interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, Windows.Devices.Enumeration.DeviceInformationUpdate *>; } }
-namespace Windows -{ - namespace Devices +namespace Windows.Devices.Enumeration { + enum DeviceWatcherStatus + { + Created = 0, + Started = 1, + EnumerationCompleted = 2, + Stopping = 3, + Stopped = 4, + Aborted = 5 + }; + + enum Panel + { + Unknown = 0, + Front = 1, + Back = 2, + Top = 3, + Bottom = 4, + Left = 5, + Right = 6 + }; + + [ + exclusiveto(Windows.Devices.Enumeration.DeviceInformation), + uuid(aba0fb95-4398-489d-8e44-e6130927011f) + ] + interface IDeviceInformation : IInspectable { - namespace Enumeration - { - declare - { - interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceInformation *>; - interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceThumbnail *>; - interface Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *>; - interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformation *>; - interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *>; - interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, IInspectable *>; - interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, Windows.Devices.Enumeration.DeviceInformation *>; - interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, Windows.Devices.Enumeration.DeviceInformationUpdate *>; - } - } + [propget] HRESULT Id([out, retval] HSTRING *value); + [propget] HRESULT Name([out, retval] HSTRING *value); + [propget] HRESULT IsEnabled([out, retval] boolean *value); + [propget] HRESULT IsDefault([out, retval] boolean *value); + [propget] HRESULT EnclosureLocation([out, retval] Windows.Devices.Enumeration.EnclosureLocation **value); + [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value); + HRESULT Update([in] Windows.Devices.Enumeration.DeviceInformationUpdate *info); + HRESULT GetThumbnailAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *> **operation); + HRESULT GetGlyphThumbnailAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *> **operation); } -}
-namespace Windows -{ - namespace Storage + [ + exclusiveto(Windows.Devices.Enumeration.DeviceInformationUpdate), + uuid(8f315305-d972-44b7-a37e-9e822c78213b) + ] + interface IDeviceInformationUpdate : IInspectable { - namespace Streams - { - interface IContentTypeProvider; - interface IInputStream; - interface IOutputStream; - interface IRandomAccessStream; - interface IRandomAccessStreamWithContentType; - } + [propget] HRESULT Id([out, retval] HSTRING *value); + [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value); + } + + [ + exclusiveto(Windows.Devices.Enumeration.DeviceWatcher), + uuid(c9eab97d-8f6b-4f96-a9f4-abc814e22271), + ] + interface IDeviceWatcher : IInspectable + { + [eventadd] HRESULT Added([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, + Windows.Devices.Enumeration.DeviceInformation *> *handler, [out, retval] EventRegistrationToken *token); + [eventremove] HRESULT Added([in] EventRegistrationToken token); + [eventadd] HRESULT Updated([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, + Windows.Devices.Enumeration.DeviceInformationUpdate *> *handler, [out, retval] EventRegistrationToken *token); + [eventremove] HRESULT Updated([in] EventRegistrationToken token); + [eventadd] HRESULT Removed([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, + Windows.Devices.Enumeration.DeviceInformationUpdate *> *handler, [out, retval] EventRegistrationToken *token); + [eventremove] HRESULT Removed([in] EventRegistrationToken token); + [eventadd] HRESULT EnumerationCompleted([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, + IInspectable *> *handler, [out, retval] EventRegistrationToken *token); + [eventremove] HRESULT EnumerationCompleted([in] EventRegistrationToken token); + [eventadd] HRESULT Stopped([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, + IInspectable *> *handler, [out, retval] EventRegistrationToken *token); + [eventremove] HRESULT Stopped([in] EventRegistrationToken token); + [propget] HRESULT Status([out, retval] Windows.Devices.Enumeration.DeviceWatcherStatus *status); + HRESULT Start(); + HRESULT Stop(); + } + + [ + exclusiveto(Windows.Devices.Enumeration.EnclosureLocation), + uuid(42340a27-5810-459c-aabb-c65e1f813ecf) + ] + interface IEnclosureLocation : IInspectable + { + [propget] HRESULT InDock([out, retval] boolean *value); + [propget] HRESULT InLid([out, retval] boolean *value); + [propget] HRESULT Panel([out, retval] Windows.Devices.Enumeration.Panel *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Devices.Enumeration.IDeviceInformationStatics, Windows.Foundation.UniversalApiContract, 1.0), + static(Windows.Devices.Enumeration.IDeviceInformationStatics2, Windows.Foundation.UniversalApiContract, 1.0), + threading(both) + ] + runtimeclass DeviceInformation + { + [default] interface Windows.Devices.Enumeration.IDeviceInformation; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Devices.Enumeration.IDeviceInformation2; + } + + [ + marshaling_behavior(agile), + ] + runtimeclass DeviceInformationUpdate + { + [default] interface Windows.Devices.Enumeration.IDeviceInformationUpdate; + interface Windows.Devices.Enumeration.IDeviceInformationUpdate2; + } + + [ + marshaling_behavior(agile), + ] + runtimeclass DeviceThumbnail + { + [default] interface Windows.Storage.Streams.IRandomAccessStreamWithContentType; + interface Windows.Storage.Streams.IContentTypeProvider; + interface Windows.Storage.Streams.IRandomAccessStream; + interface Windows.Storage.Streams.IOutputStream; + interface Windows.Foundation.IClosable; + interface Windows.Storage.Streams.IInputStream; + } + + [ + marshaling_behavior(agile), + ] + runtimeclass DeviceWatcher + { + [default] interface Windows.Devices.Enumeration.IDeviceWatcher; + interface Windows.Devices.Enumeration.IDeviceWatcher2; } -}
-namespace Windows { - namespace Devices { - namespace Enumeration { - enum DeviceWatcherStatus - { - Created = 0, - Started = 1, - EnumerationCompleted = 2, - Stopping = 3, - Stopped = 4, - Aborted = 5 - }; - - enum Panel - { - Unknown = 0, - Front = 1, - Back = 2, - Top = 3, - Bottom = 4, - Left = 5, - Right = 6 - }; - - [ - exclusiveto(Windows.Devices.Enumeration.DeviceInformation), - uuid(aba0fb95-4398-489d-8e44-e6130927011f) - ] - interface IDeviceInformation : IInspectable - { - [propget] HRESULT Id([out, retval] HSTRING *value); - [propget] HRESULT Name([out, retval] HSTRING *value); - [propget] HRESULT IsEnabled([out, retval] boolean *value); - [propget] HRESULT IsDefault([out, retval] boolean *value); - [propget] HRESULT EnclosureLocation([out, retval] Windows.Devices.Enumeration.EnclosureLocation **value); - [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value); - HRESULT Update([in] Windows.Devices.Enumeration.DeviceInformationUpdate *info); - HRESULT GetThumbnailAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *> **operation); - HRESULT GetGlyphThumbnailAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *> **operation); - } - - [ - exclusiveto(Windows.Devices.Enumeration.DeviceInformationUpdate), - uuid(8f315305-d972-44b7-a37e-9e822c78213b) - ] - interface IDeviceInformationUpdate : IInspectable - { - [propget] HRESULT Id([out, retval] HSTRING *value); - [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value); - } - - [ - exclusiveto(Windows.Devices.Enumeration.DeviceWatcher), - uuid(c9eab97d-8f6b-4f96-a9f4-abc814e22271), - ] - interface IDeviceWatcher : IInspectable - { - [eventadd] HRESULT Added([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher*, - Windows.Devices.Enumeration.DeviceInformation *> *handler, [out, retval] EventRegistrationToken *token); - [eventremove] HRESULT Added([in] EventRegistrationToken token); - [eventadd] HRESULT Updated([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, - Windows.Devices.Enumeration.DeviceInformationUpdate *> *handler, [out, retval] EventRegistrationToken *token); - [eventremove] HRESULT Updated([in] EventRegistrationToken token); - [eventadd] HRESULT Removed([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, - Windows.Devices.Enumeration.DeviceInformationUpdate *> *handler, [out, retval] EventRegistrationToken *token); - [eventremove] HRESULT Removed([in] EventRegistrationToken token); - [eventadd] HRESULT EnumerationCompleted([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, - IInspectable *> *handler, [out, retval] EventRegistrationToken *token); - [eventremove] HRESULT EnumerationCompleted([in] EventRegistrationToken token); - [eventadd] HRESULT Stopped([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, - IInspectable *> *handler, [out, retval] EventRegistrationToken *token); - [eventremove] HRESULT Stopped([in] EventRegistrationToken token); - [propget] HRESULT Status([out, retval] Windows.Devices.Enumeration.DeviceWatcherStatus *status); - HRESULT Start(); - HRESULT Stop(); - } - - [ - exclusiveto(Windows.Devices.Enumeration.EnclosureLocation), - uuid(42340a27-5810-459c-aabb-c65e1f813ecf) - ] - interface IEnclosureLocation : IInspectable - { - [propget] HRESULT InDock([out, retval] boolean *value); - [propget] HRESULT InLid([out, retval] boolean *value); - [propget] HRESULT Panel([out, retval] Windows.Devices.Enumeration.Panel *value); - } - - [ - contract(Windows.Foundation.UniversalApiContract, 1.0), - marshaling_behavior(agile), - static(Windows.Devices.Enumeration.IDeviceInformationStatics, Windows.Foundation.UniversalApiContract, 1.0), - static(Windows.Devices.Enumeration.IDeviceInformationStatics2, Windows.Foundation.UniversalApiContract, 1.0), - threading(both) - ] - runtimeclass DeviceInformation - { - [default] interface Windows.Devices.Enumeration.IDeviceInformation; - [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Devices.Enumeration.IDeviceInformation2; - } - - [ - marshaling_behavior(agile), - ] - runtimeclass DeviceInformationUpdate - { - [default] interface Windows.Devices.Enumeration.IDeviceInformationUpdate; - interface Windows.Devices.Enumeration.IDeviceInformationUpdate2; - } - - [ - marshaling_behavior(agile), - ] - runtimeclass DeviceThumbnail - { - [default] interface Windows.Storage.Streams.IRandomAccessStreamWithContentType; - interface Windows.Storage.Streams.IContentTypeProvider; - interface Windows.Storage.Streams.IRandomAccessStream; - interface Windows.Storage.Streams.IOutputStream; - interface Windows.Foundation.IClosable; - interface Windows.Storage.Streams.IInputStream; - } - - [ - marshaling_behavior(agile), - ] - runtimeclass DeviceWatcher - { - [default] interface Windows.Devices.Enumeration.IDeviceWatcher; - interface Windows.Devices.Enumeration.IDeviceWatcher2; - } - - [ - marshaling_behavior(agile) - ] - runtimeclass EnclosureLocation - { - [default] interface Windows.Devices.Enumeration.IEnclosureLocation; - } - } + [ + marshaling_behavior(agile) + ] + runtimeclass EnclosureLocation + { + [default] interface Windows.Devices.Enumeration.IEnclosureLocation; } }
From: Julian Klemann jklemann@codeweavers.com
--- dlls/windows.devices.enumeration/main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index 0e44251de08..b5cc5b63e14 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -57,7 +57,7 @@ static inline struct windows_devices_enumeration *impl_from_IActivationFactory(I return CONTAINING_RECORD(iface, struct windows_devices_enumeration, IActivationFactory_iface); }
-static HRESULT STDMETHODCALLTYPE windows_devices_enumeration_QueryInterface( +static HRESULT WINAPI windows_devices_enumeration_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); @@ -77,7 +77,7 @@ static HRESULT STDMETHODCALLTYPE windows_devices_enumeration_QueryInterface( return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE windows_devices_enumeration_AddRef( +static ULONG WINAPI windows_devices_enumeration_AddRef( IActivationFactory *iface) { struct windows_devices_enumeration *impl = impl_from_IActivationFactory(iface); @@ -86,7 +86,7 @@ static ULONG STDMETHODCALLTYPE windows_devices_enumeration_AddRef( return ref; }
-static ULONG STDMETHODCALLTYPE windows_devices_enumeration_Release( +static ULONG WINAPI windows_devices_enumeration_Release( IActivationFactory *iface) { struct windows_devices_enumeration *impl = impl_from_IActivationFactory(iface); @@ -95,28 +95,28 @@ static ULONG STDMETHODCALLTYPE windows_devices_enumeration_Release( return ref; }
-static HRESULT STDMETHODCALLTYPE windows_devices_enumeration_GetIids( +static HRESULT WINAPI windows_devices_enumeration_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 STDMETHODCALLTYPE windows_devices_enumeration_GetRuntimeClassName( +static HRESULT WINAPI windows_devices_enumeration_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name) { FIXME("iface %p, class_name %p stub!\n", iface, class_name); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE windows_devices_enumeration_GetTrustLevel( +static HRESULT WINAPI windows_devices_enumeration_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level) { FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE windows_devices_enumeration_ActivateInstance( +static HRESULT WINAPI windows_devices_enumeration_ActivateInstance( IActivationFactory *iface, IInspectable **instance) { FIXME("iface %p, instance %p stub!\n", iface, instance);
From: Julian Klemann jklemann@codeweavers.com
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=53328 --- dlls/windows.devices.enumeration/main.c | 134 +++++++++++++++++++++--- include/windows.devices.enumeration.idl | 68 ++++++++++++ 2 files changed, 186 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index b5cc5b63e14..95f70bd9883 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -1,6 +1,7 @@ /* WinRT Windows.Devices.Enumeration implementation * * Copyright 2021 Gijs Vermeulen + * Copyright 2022 Julian Klemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +36,46 @@ #define WIDL_using_Windows_Devices_Enumeration #include "windows.devices.enumeration.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 ) +#define DEFINE_IINSPECTABLE_OUTER( pfx, iface_type, impl_type, outer_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, impl->outer_iface ) + WINE_DEFAULT_DEBUG_CHANNEL(enumeration);
static const char *debugstr_hstring(HSTRING hstr) @@ -49,6 +90,7 @@ static const char *debugstr_hstring(HSTRING hstr) struct windows_devices_enumeration { IActivationFactory IActivationFactory_iface; + IDeviceInformationStatics2 IDeviceInformationStatics2_iface; LONG ref; };
@@ -57,9 +99,11 @@ static inline struct windows_devices_enumeration *impl_from_IActivationFactory(I return CONTAINING_RECORD(iface, struct windows_devices_enumeration, IActivationFactory_iface); }
-static HRESULT WINAPI windows_devices_enumeration_QueryInterface( +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { + struct windows_devices_enumeration *impl = impl_from_IActivationFactory(iface); + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_IUnknown) || @@ -67,8 +111,13 @@ static HRESULT WINAPI windows_devices_enumeration_QueryInterface( IsEqualGUID(iid, &IID_IAgileObject) || IsEqualGUID(iid, &IID_IActivationFactory)) { - IUnknown_AddRef(iface); - *out = iface; + IInspectable_AddRef((*out = &impl->IActivationFactory_iface)); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_IDeviceInformationStatics2)) + { + IInspectable_AddRef((*out = &impl->IDeviceInformationStatics2_iface)); return S_OK; }
@@ -77,7 +126,7 @@ static HRESULT WINAPI windows_devices_enumeration_QueryInterface( return E_NOINTERFACE; }
-static ULONG WINAPI windows_devices_enumeration_AddRef( +static ULONG WINAPI factory_AddRef( IActivationFactory *iface) { struct windows_devices_enumeration *impl = impl_from_IActivationFactory(iface); @@ -86,7 +135,7 @@ static ULONG WINAPI windows_devices_enumeration_AddRef( return ref; }
-static ULONG WINAPI windows_devices_enumeration_Release( +static ULONG WINAPI factory_Release( IActivationFactory *iface) { struct windows_devices_enumeration *impl = impl_from_IActivationFactory(iface); @@ -95,28 +144,28 @@ static ULONG WINAPI windows_devices_enumeration_Release( return ref; }
-static HRESULT WINAPI windows_devices_enumeration_GetIids( +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 windows_devices_enumeration_GetRuntimeClassName( +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 windows_devices_enumeration_GetTrustLevel( +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 windows_devices_enumeration_ActivateInstance( +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance) { FIXME("iface %p, instance %p stub!\n", iface, instance); @@ -125,20 +174,73 @@ static HRESULT WINAPI windows_devices_enumeration_ActivateInstance(
static const struct IActivationFactoryVtbl activation_factory_vtbl = { - windows_devices_enumeration_QueryInterface, - windows_devices_enumeration_AddRef, - windows_devices_enumeration_Release, + factory_QueryInterface, + factory_AddRef, + factory_Release, /* IInspectable methods */ - windows_devices_enumeration_GetIids, - windows_devices_enumeration_GetRuntimeClassName, - windows_devices_enumeration_GetTrustLevel, + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, /* IActivationFactory methods */ - windows_devices_enumeration_ActivateInstance, + factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE(device_statics2, IDeviceInformationStatics2, struct windows_devices_enumeration, IActivationFactory_iface); + +static HRESULT WINAPI device_statics2_GetAqsFilterFromDeviceClass( + IDeviceInformationStatics2 *iface, DeviceClass deviceClass, HSTRING *aqsFilter) +{ + FIXME("iface %p, deviceClass %u, aqsFilter %p stub!\n", iface, deviceClass, aqsFilter); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_statics2_CreateFromIdAsync( + IDeviceInformationStatics2 *iface, HSTRING deviceId, IIterable_HSTRING *additionalProperties, + DeviceInformationKind kind, IAsyncOperation_DeviceInformation **asyncOperation) +{ + FIXME("iface %p, deviceId %s, additionalProperties %p, kind %u, asyncOperation %p stub!\n", + iface, debugstr_hstring(deviceId), additionalProperties, kind, asyncOperation); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_statics2_FindAllAsync( + IDeviceInformationStatics2 *iface, HSTRING filter, IIterable_HSTRING *additionalProperties, + DeviceInformationKind kind, IAsyncOperation_DeviceInformationCollection **asyncOperation) +{ + FIXME("iface %p, filter %s, additionalProperties %p, kind %u, asyncOperation %p stub!\n", + iface, debugstr_hstring(filter), additionalProperties, kind, asyncOperation); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_statics2_CreateWatcher( + IDeviceInformationStatics2 *iface, HSTRING filter, IIterable_HSTRING *additionalProperties, + DeviceInformationKind kind, IDeviceWatcher **watcher) +{ + FIXME("iface %p, filter %s, additionalProperties %p, kind %u, watcher %p stub!\n", + iface, debugstr_hstring(filter), additionalProperties, kind, watcher); + return E_NOTIMPL; +} + +static const struct IDeviceInformationStatics2Vtbl device_statics2_vtbl = +{ + device_statics2_QueryInterface, + device_statics2_AddRef, + device_statics2_Release, + /* IInspectable methods */ + device_statics2_GetIids, + device_statics2_GetRuntimeClassName, + device_statics2_GetTrustLevel, + /* IDeviceInformationStatics2 methods */ + device_statics2_GetAqsFilterFromDeviceClass, + device_statics2_CreateFromIdAsync, + device_statics2_FindAllAsync, + device_statics2_CreateWatcher };
static struct windows_devices_enumeration windows_devices_enumeration = { {&activation_factory_vtbl}, + {&device_statics2_vtbl}, 1 };
diff --git a/include/windows.devices.enumeration.idl b/include/windows.devices.enumeration.idl index f47df3795fa..a7cab7aba3d 100644 --- a/include/windows.devices.enumeration.idl +++ b/include/windows.devices.enumeration.idl @@ -28,6 +28,8 @@ import "windows.storage.streams.idl"; import "windows.foundation.idl";
namespace Windows.Devices.Enumeration { + typedef enum DeviceClass DeviceClass; + typedef enum DeviceInformationKind DeviceInformationKind; typedef enum DeviceWatcherStatus DeviceWatcherStatus; typedef enum Panel Panel;
@@ -38,6 +40,7 @@ namespace Windows.Devices.Enumeration { interface IEnclosureLocation;
runtimeclass DeviceInformation; + runtimeclass DeviceInformationCollection; runtimeclass DeviceInformationUpdate; runtimeclass DeviceThumbnail; runtimeclass DeviceWatcher; @@ -46,9 +49,11 @@ namespace Windows.Devices.Enumeration { declare { interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceInformationCollection *>; interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Enumeration.DeviceThumbnail *>; interface Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *>; interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformationCollection *>; interface Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceThumbnail *>; interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, IInspectable *>; interface Windows.Foundation.TypedEventHandler<Windows.Devices.Enumeration.DeviceWatcher *, Windows.Devices.Enumeration.DeviceInformation *>; @@ -57,6 +62,35 @@ namespace Windows.Devices.Enumeration { }
namespace Windows.Devices.Enumeration { + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + enum DeviceClass + { + All = 0, + AudioCapture = 1, + AudioRender = 2, + PortableStorageDevice = 3, + VideoCapture = 4, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + ImageScanner = 5, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + Location = 6 + }; + + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + enum DeviceInformationKind + { + Unknown = 0, + DeviceInterface = 1, + DeviceContainer = 2, + Device = 3, + DeviceInterfaceClass = 4, + AssociationEndpoint = 5, + AssociationEndpointContainer = 6, + AssociationEndpointService = 7, + [contract(Windows.Foundation.UniversalApiContract, 7.0)] + DevicePanel = 8 + }; + enum DeviceWatcherStatus { Created = 0, @@ -142,6 +176,28 @@ namespace Windows.Devices.Enumeration { [propget] HRESULT Panel([out, retval] Windows.Devices.Enumeration.Panel *value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Devices.Enumeration.DeviceInformation), + uuid(493b4f34-a84f-45fd-9167-15d1cb1bd1f9) + ] + interface IDeviceInformationStatics2 : IInspectable + { + HRESULT GetAqsFilterFromDeviceClass([in] Windows.Devices.Enumeration.DeviceClass deviceClass, [out, retval] HSTRING *filter); + [overload("CreateFromIdAsync")] HRESULT CreateFromIdAsyncWithKindAndAdditionalProperties([in] HSTRING deviceId, + [in] Windows.Foundation.Collections.IIterable<HSTRING> *additionalProperties, + [in] Windows.Devices.Enumeration.DeviceInformationKind kind, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformation *> **asyncOperation); + [overload("FindAllAsync")] HRESULT FindAllAsyncWithKindAqsFilterAndAdditionalProperties([in] HSTRING filter, + [in] Windows.Foundation.Collections.IIterable<HSTRING> *additionalProperties, + [in] Windows.Devices.Enumeration.DeviceInformationKind kind, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Enumeration.DeviceInformationCollection *> **asyncOperation); + [overload("CreateWatcher")] HRESULT CreateWatcherWithKindAqsFilterAndAdditionalProperties([in] HSTRING filter, + [in] Windows.Foundation.Collections.IIterable<HSTRING> *additionalProperties, + [in] Windows.Devices.Enumeration.DeviceInformationKind kind, + [out, retval] Windows.Devices.Enumeration.DeviceWatcher **watcher); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), marshaling_behavior(agile), @@ -155,6 +211,18 @@ namespace Windows.Devices.Enumeration { [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Devices.Enumeration.IDeviceInformation2; }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + ] + runtimeclass DeviceInformationCollection + { + /* FIXME: This should be: + [default] interface Windows.Foundation.Collections.IVectorView<Windows.Devices.Enumeration.DeviceInformation *>; + interface Windows.Foundation.Collections.IIterable<Windows.Devices.Enumeration.DeviceInformation *>; */ + [default] interface IInspectable; + } + [ marshaling_behavior(agile), ]
From: Julian Klemann jklemann@codeweavers.com
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=53328 --- dlls/windows.devices.enumeration/Makefile.in | 1 + .../event_handlers.c | 109 +++++++ dlls/windows.devices.enumeration/main.c | 275 ++++++++++++++---- dlls/windows.devices.enumeration/private.h | 86 ++++++ 4 files changed, 415 insertions(+), 56 deletions(-) create mode 100644 dlls/windows.devices.enumeration/event_handlers.c create mode 100644 dlls/windows.devices.enumeration/private.h
diff --git a/dlls/windows.devices.enumeration/Makefile.in b/dlls/windows.devices.enumeration/Makefile.in index a2058b3d002..77aa007c0dc 100644 --- a/dlls/windows.devices.enumeration/Makefile.in +++ b/dlls/windows.devices.enumeration/Makefile.in @@ -2,6 +2,7 @@ MODULE = windows.devices.enumeration.dll IMPORTS = combase uuid
C_SRCS = \ + event_handlers.c \ main.c
IDL_SRCS = classes.idl diff --git a/dlls/windows.devices.enumeration/event_handlers.c b/dlls/windows.devices.enumeration/event_handlers.c new file mode 100644 index 00000000000..8451cd72a76 --- /dev/null +++ b/dlls/windows.devices.enumeration/event_handlers.c @@ -0,0 +1,109 @@ +/* WinRT Windows.Devices.Enumeration implementation + * + * Copyright 2022 Bernhard K��lbl + * + * 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 "private.h" + +static CRITICAL_SECTION handlers_cs; +static CRITICAL_SECTION_DEBUG handlers_cs_debug = +{ + 0, 0, &handlers_cs, + { &handlers_cs_debug.ProcessLocksList, &handlers_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": handlers_cs") } +}; +static CRITICAL_SECTION handlers_cs = { &handlers_cs_debug, -1, 0, 0, 0, 0 }; +static EventRegistrationToken next_token = {.value = 1}; + +struct typed_event_handler_entry +{ + struct list entry; + EventRegistrationToken token; + ITypedEventHandler_IInspectable_IInspectable *handler; +}; + +HRESULT typed_event_handlers_append(struct list *list, ITypedEventHandler_IInspectable_IInspectable *handler, EventRegistrationToken *token) +{ + struct typed_event_handler_entry *entry; + + if (!(entry = calloc(1, sizeof(*entry)))) return E_OUTOFMEMORY; + ITypedEventHandler_IInspectable_IInspectable_AddRef((entry->handler = handler)); + + EnterCriticalSection(&handlers_cs); + + *token = entry->token = next_token; + next_token.value++; + list_add_tail(list, &entry->entry); + + LeaveCriticalSection(&handlers_cs); + + return S_OK; +} + +HRESULT typed_event_handlers_remove(struct list *list, EventRegistrationToken *token) +{ + struct typed_event_handler_entry *entry; + BOOL found = FALSE; + + EnterCriticalSection(&handlers_cs); + + LIST_FOR_EACH_ENTRY(entry, list, struct typed_event_handler_entry, entry) + if ((found = !memcmp(&entry->token, token, sizeof(*token)))) break; + if (found) list_remove(&entry->entry); + + LeaveCriticalSection(&handlers_cs); + + if (found) + { + ITypedEventHandler_IInspectable_IInspectable_Release(entry->handler); + free(entry); + } + + return S_OK; +} + +HRESULT typed_event_handlers_notify(struct list *list, IInspectable *sender, IInspectable *args) +{ + struct typed_event_handler_entry *entry; + + EnterCriticalSection(&handlers_cs); + + LIST_FOR_EACH_ENTRY(entry, list, struct typed_event_handler_entry, entry) + ITypedEventHandler_IInspectable_IInspectable_Invoke(entry->handler, sender, args); + + LeaveCriticalSection(&handlers_cs); + + return S_OK; +} + +HRESULT typed_event_handlers_clear(struct list *list) +{ + struct typed_event_handler_entry *entry, *entry_cursor2; + + EnterCriticalSection(&handlers_cs); + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry_cursor2, list, struct typed_event_handler_entry, entry) + { + list_remove(&entry->entry); + ITypedEventHandler_IInspectable_IInspectable_Release(entry->handler); + free(entry); + } + + LeaveCriticalSection(&handlers_cs); + + return S_OK; +} diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index 95f70bd9883..380df9512b6 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -18,63 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <stdarg.h> +#include "initguid.h" +#include "private.h"
-#define COBJMACROS -#include "windef.h" -#include "winbase.h" -#include "winstring.h" #include "wine/debug.h" -#include "objbase.h" - -#include "initguid.h" -#include "activation.h" - -#define WIDL_using_Windows_Foundation -#define WIDL_using_Windows_Foundation_Collections -#include "windows.foundation.h" -#define WIDL_using_Windows_Devices_Enumeration -#include "windows.devices.enumeration.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 ) -#define DEFINE_IINSPECTABLE_OUTER( pfx, iface_type, impl_type, outer_iface ) \ - DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, impl->outer_iface )
WINE_DEFAULT_DEBUG_CHANNEL(enumeration);
@@ -87,6 +34,208 @@ static const char *debugstr_hstring(HSTRING hstr) return wine_dbgstr_wn(str, len); }
+struct device_watcher +{ + IDeviceWatcher IDeviceWatcher_iface; + LONG ref; + + struct list stopped_handlers; +}; + +static inline struct device_watcher *impl_from_IDeviceWatcher(IDeviceWatcher *iface) +{ + return CONTAINING_RECORD(iface, struct device_watcher, IDeviceWatcher_iface); +} + +static HRESULT WINAPI device_watcher_QueryInterface( + IDeviceWatcher *iface, REFIID iid, void **out) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IDeviceWatcher)) + { + IInspectable_AddRef((*out = &impl->IDeviceWatcher_iface)); + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI device_watcher_AddRef( + IDeviceWatcher *iface) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI device_watcher_Release( + IDeviceWatcher *iface) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + { + typed_event_handlers_clear(&impl->stopped_handlers); + free(impl); + } + + return ref; +} + +static HRESULT WINAPI device_watcher_GetIids( + IDeviceWatcher *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 device_watcher_GetRuntimeClassName( + IDeviceWatcher *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_GetTrustLevel( + IDeviceWatcher *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_add_Added( + IDeviceWatcher *iface, ITypedEventHandler_DeviceWatcher_DeviceInformation *handler, + EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub!\n", iface, handler, token); + return S_OK; +} + +static HRESULT WINAPI device_watcher_remove_Added(IDeviceWatcher *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_add_Updated( + IDeviceWatcher *iface, ITypedEventHandler_DeviceWatcher_DeviceInformationUpdate *handler, + EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub!\n", iface, handler, token); + return S_OK; +} + +static HRESULT WINAPI device_watcher_remove_Updated(IDeviceWatcher *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_add_Removed( + IDeviceWatcher *iface, ITypedEventHandler_DeviceWatcher_DeviceInformationUpdate *handler, + EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub!\n", iface, handler, token); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_remove_Removed(IDeviceWatcher *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_add_EnumerationCompleted( + IDeviceWatcher *iface, ITypedEventHandler_DeviceWatcher_IInspectable *handler, EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub!\n", iface, handler, token); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_remove_EnumerationCompleted( + IDeviceWatcher *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub!\n", iface, token.value); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_add_Stopped( + IDeviceWatcher *iface, ITypedEventHandler_DeviceWatcher_IInspectable *handler, EventRegistrationToken *token) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + + TRACE("iface %p, handler %p, token %p.\n", iface, handler, token); + return typed_event_handlers_append(&impl->stopped_handlers, (ITypedEventHandler_IInspectable_IInspectable *)handler, token); +} + +static HRESULT WINAPI device_watcher_remove_Stopped(IDeviceWatcher *iface, EventRegistrationToken token) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + + TRACE("iface %p, token %#I64x.\n", iface, token.value); + return typed_event_handlers_remove(&impl->stopped_handlers, &token); +} + +static HRESULT WINAPI device_watcher_Status(IDeviceWatcher *iface, DeviceWatcherStatus *status) +{ + FIXME("iface %p, status %p stub!\n", iface, status); + return E_NOTIMPL; +} + +static HRESULT WINAPI device_watcher_Start(IDeviceWatcher *iface) +{ + FIXME("iface %p stub!\n", iface); + return S_OK; +} + +static HRESULT WINAPI device_watcher_Stop(IDeviceWatcher *iface) +{ + struct device_watcher *impl = impl_from_IDeviceWatcher(iface); + HRESULT hr; + + FIXME("iface %p stub!\n", iface); + + IDeviceWatcher_AddRef(&impl->IDeviceWatcher_iface); + hr = typed_event_handlers_notify(&impl->stopped_handlers, (IInspectable *)iface, NULL); + IDeviceWatcher_Release(&impl->IDeviceWatcher_iface); + return hr; +} + +static const struct IDeviceWatcherVtbl device_watcher_vtbl = +{ + device_watcher_QueryInterface, + device_watcher_AddRef, + device_watcher_Release, + /* IInspectable methods */ + device_watcher_GetIids, + device_watcher_GetRuntimeClassName, + device_watcher_GetTrustLevel, + /* IDeviceWatcher methods */ + device_watcher_add_Added, + device_watcher_remove_Added, + device_watcher_add_Updated, + device_watcher_remove_Updated, + device_watcher_add_Removed, + device_watcher_remove_Removed, + device_watcher_add_EnumerationCompleted, + device_watcher_remove_EnumerationCompleted, + device_watcher_add_Stopped, + device_watcher_remove_Stopped, + device_watcher_Status, + device_watcher_Start, + device_watcher_Stop, +}; + struct windows_devices_enumeration { IActivationFactory IActivationFactory_iface; @@ -216,9 +365,23 @@ static HRESULT WINAPI device_statics2_CreateWatcher( IDeviceInformationStatics2 *iface, HSTRING filter, IIterable_HSTRING *additionalProperties, DeviceInformationKind kind, IDeviceWatcher **watcher) { + struct device_watcher *this; + HRESULT hr; + FIXME("iface %p, filter %s, additionalProperties %p, kind %u, watcher %p stub!\n", iface, debugstr_hstring(filter), additionalProperties, kind, watcher); - return E_NOTIMPL; + + if (!(this = malloc(sizeof(*this)))) + return E_OUTOFMEMORY; + + this->IDeviceWatcher_iface.lpVtbl = &device_watcher_vtbl; + this->ref = 1; + + list_init(&this->stopped_handlers); + + hr = IDeviceWatcher_QueryInterface(&this->IDeviceWatcher_iface, &IID_IDeviceWatcher, (void **)watcher); + IDeviceWatcher_Release(&this->IDeviceWatcher_iface); + return hr; }
static const struct IDeviceInformationStatics2Vtbl device_statics2_vtbl = diff --git a/dlls/windows.devices.enumeration/private.h b/dlls/windows.devices.enumeration/private.h new file mode 100644 index 00000000000..13ac54723cd --- /dev/null +++ b/dlls/windows.devices.enumeration/private.h @@ -0,0 +1,86 @@ +/* WinRT Windows.Devices.Enumeration implementation + * + * Copyright 2021 Gijs Vermeulen + * + * 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 + */ + +#ifndef __WINE_WINDOWS_DEVICES_ENUMERATION_PRIVATE_H +#define __WINE_WINDOWS_DEVICES_ENUMERATION_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" +#include "objbase.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Devices_Enumeration +#include "windows.devices.enumeration.h" + +#include "wine/list.h" + +HRESULT typed_event_handlers_append(struct list *list, ITypedEventHandler_IInspectable_IInspectable *handler, EventRegistrationToken *token); +HRESULT typed_event_handlers_remove(struct list *list, EventRegistrationToken *token); +HRESULT typed_event_handlers_notify(struct list *list, IInspectable *sender, IInspectable *args); +HRESULT typed_event_handlers_clear(struct list *list); + +#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 ) +#define DEFINE_IINSPECTABLE_OUTER( pfx, iface_type, impl_type, outer_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, impl->outer_iface ) + +#endif
From: Julian Klemann jklemann@codeweavers.com
--- configure | 1 + configure.ac | 1 + .../tests/Makefile.in | 5 + .../tests/devices.c | 221 ++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 dlls/windows.devices.enumeration/tests/Makefile.in create mode 100644 dlls/windows.devices.enumeration/tests/devices.c
diff --git a/configure b/configure index 89500dc8f7a..19c151f0b19 100755 --- a/configure +++ b/configure @@ -22005,6 +22005,7 @@ wine_fn_config_makefile dlls/win87em.dll16 enable_win16 wine_fn_config_makefile dlls/winaspi.dll16 enable_win16 wine_fn_config_makefile dlls/windebug.dll16 enable_win16 wine_fn_config_makefile dlls/windows.devices.enumeration enable_windows_devices_enumeration +wine_fn_config_makefile dlls/windows.devices.enumeration/tests enable_tests wine_fn_config_makefile dlls/windows.gaming.input enable_windows_gaming_input wine_fn_config_makefile dlls/windows.gaming.input/tests enable_tests wine_fn_config_makefile dlls/windows.globalization enable_windows_globalization diff --git a/configure.ac b/configure.ac index 49d414e1d17..d75f5231f82 100644 --- a/configure.ac +++ b/configure.ac @@ -3144,6 +3144,7 @@ WINE_CONFIG_MAKEFILE(dlls/win87em.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winaspi.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/windebug.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/windows.devices.enumeration) +WINE_CONFIG_MAKEFILE(dlls/windows.devices.enumeration/tests) WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input) WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input/tests) WINE_CONFIG_MAKEFILE(dlls/windows.globalization) diff --git a/dlls/windows.devices.enumeration/tests/Makefile.in b/dlls/windows.devices.enumeration/tests/Makefile.in new file mode 100644 index 00000000000..fe8780974c8 --- /dev/null +++ b/dlls/windows.devices.enumeration/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.devices.enumeration.dll +IMPORTS = combase uuid + +C_SRCS = \ + devices.c diff --git a/dlls/windows.devices.enumeration/tests/devices.c b/dlls/windows.devices.enumeration/tests/devices.c new file mode 100644 index 00000000000..d679145e11b --- /dev/null +++ b/dlls/windows.devices.enumeration/tests/devices.c @@ -0,0 +1,221 @@ +/* + * Copyright 2022 Julian Klemann for CodeWeavers + * + * 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> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winstring.h" + +#include "initguid.h" +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Devices_Enumeration +#include "windows.devices.enumeration.h" + +#include "wine/test.h" + +struct device_watcher_handler +{ + ITypedEventHandler_DeviceWatcher_IInspectable ITypedEventHandler_DeviceWatcher_IInspectable_iface; + LONG ref; + + HANDLE event; + BOOL invoked; + IInspectable *args; +}; + +static inline struct device_watcher_handler *impl_from_ITypedEventHandler_DeviceWatcher_IInspectable( + ITypedEventHandler_DeviceWatcher_IInspectable *iface) +{ + return CONTAINING_RECORD(iface, struct device_watcher_handler, ITypedEventHandler_DeviceWatcher_IInspectable_iface); +} + +static HRESULT WINAPI device_watcher_handler_QueryInterface( + ITypedEventHandler_DeviceWatcher_IInspectable *iface, REFIID iid, void **out) +{ + struct device_watcher_handler *impl = impl_from_ITypedEventHandler_DeviceWatcher_IInspectable(iface); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_ITypedEventHandler_DeviceWatcher_IInspectable)) + { + IUnknown_AddRef(&impl->ITypedEventHandler_DeviceWatcher_IInspectable_iface); + *out = &impl->ITypedEventHandler_DeviceWatcher_IInspectable_iface; + return S_OK; + } + + trace("%s not implemented, returning E_NO_INTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI device_watcher_handler_AddRef(ITypedEventHandler_DeviceWatcher_IInspectable *iface) +{ + struct device_watcher_handler *impl = impl_from_ITypedEventHandler_DeviceWatcher_IInspectable(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + return ref; +} + +static ULONG WINAPI device_watcher_handler_Release(ITypedEventHandler_DeviceWatcher_IInspectable *iface) +{ + struct device_watcher_handler *impl = impl_from_ITypedEventHandler_DeviceWatcher_IInspectable(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + return ref; +} + +static HRESULT WINAPI device_watcher_handler_Invoke( + ITypedEventHandler_DeviceWatcher_IInspectable *iface, IDeviceWatcher *sender, IInspectable *args) +{ + struct device_watcher_handler *impl = impl_from_ITypedEventHandler_DeviceWatcher_IInspectable(iface); + trace("iface %p, sender %p, args %p\n", iface, sender, args); + + impl->invoked = TRUE; + impl->args = args; + SetEvent(impl->event); + + return S_OK; +} + +static const ITypedEventHandler_DeviceWatcher_IInspectableVtbl device_watcher_handler_vtbl = +{ + device_watcher_handler_QueryInterface, + device_watcher_handler_AddRef, + device_watcher_handler_Release, + /* ITypedEventHandler<DeviceWatcher*,IInspectable*> methods */ + device_watcher_handler_Invoke, +}; + +static void device_watcher_handler_create(struct device_watcher_handler *impl) +{ + impl->ITypedEventHandler_DeviceWatcher_IInspectable_iface.lpVtbl = &device_watcher_handler_vtbl; + impl->invoked = FALSE; + impl->ref = 1; +} + +static void test_device_watcher_stop(void) +{ + static const WCHAR *device_info_name = L"Windows.Devices.Enumeration.DeviceInformation"; + + struct device_watcher_handler stopped_handler, dummy_handler; + EventRegistrationToken stopped_token, added_token; + IInspectable *inspectable, *inspectable2; + IAgileObject *agile, *agile2; + IActivationFactory *factory; + IDeviceInformationStatics2 *device_info_statics2; + IDeviceWatcher *device_watcher; + DeviceWatcherStatus status = 0xdeadbeef; + HSTRING str; + HRESULT hr; + + device_watcher_handler_create(&dummy_handler); + device_watcher_handler_create(&stopped_handler); + stopped_handler.event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!stopped_handler.event, "failed to create event, got error %lu\n", GetLastError()); + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK, "got hr %#lx\n", hr); + + hr = WindowsCreateString(device_info_name, wcslen(device_info_name), &str); + ok(hr == S_OK, "got hr %#lx\n", hr); + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "got hr %#lx\n", hr); + WindowsDeleteString(str); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("%s runtimeclass, not registered.\n", wine_dbgstr_w(device_info_name)); + return; + } + + hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void **)&inspectable); + ok(hr == S_OK, "got hr %#lx\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IAgileObject, (void **)&agile); + ok(hr == S_OK, "got hr %#lx\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IDeviceInformationStatics2, (void **)&device_info_statics2); + ok(hr == S_OK || broken(hr == E_NOINTERFACE), "got hr %#lx\n", hr); + IActivationFactory_Release(factory); + if (hr != S_OK) + { + IAgileObject_Release(agile); + IInspectable_Release(inspectable); + win_skip("IDeviceInformationStatics2 not supported.\n"); + return; + } + + hr = IDeviceInformationStatics2_QueryInterface(device_info_statics2, &IID_IInspectable, (void **)&inspectable2); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(inspectable == inspectable2, "got inspectable %p, inspectable2 %p\n", inspectable, inspectable2); + IInspectable_Release(inspectable); + IInspectable_Release(inspectable2); + + hr = IDeviceInformationStatics2_QueryInterface(device_info_statics2, &IID_IAgileObject, (void **)&agile2); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(agile == agile2, "got agile %p, agile2 %p\n", agile, agile2); + IAgileObject_Release(agile); + IAgileObject_Release(agile2); + + hr = IDeviceInformationStatics2_CreateWatcherWithKindAqsFilterAndAdditionalProperties( + device_info_statics2, NULL, NULL, DeviceInformationKind_AssociationEndpoint, &device_watcher); + IDeviceInformationStatics2_Release(device_info_statics2); + + hr = IDeviceWatcher_add_Added( + device_watcher, + (ITypedEventHandler_DeviceWatcher_DeviceInformation *)&dummy_handler.ITypedEventHandler_DeviceWatcher_IInspectable_iface, + &added_token); + ok(hr == S_OK, "got hr %#lx\n", hr); + hr = IDeviceWatcher_add_Stopped( + device_watcher, &stopped_handler.ITypedEventHandler_DeviceWatcher_IInspectable_iface, + &stopped_token); + ok(hr == S_OK, "got hr %#lx\n", hr); + + hr = IDeviceWatcher_get_Status(device_watcher, &status); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(status == DeviceWatcherStatus_Created, "got status %u\n", status); + + hr = IDeviceWatcher_Start(device_watcher); + ok(hr == S_OK, "got hr %#lx\n", hr); + hr = IDeviceWatcher_get_Status(device_watcher, &status); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(status == DeviceWatcherStatus_Started, "got status %u\n", status); + + hr = IDeviceWatcher_Stop(device_watcher); + ok(hr == S_OK, "got hr %#lx\n", hr); + WaitForSingleObject(stopped_handler.event, INFINITE); + + hr = IDeviceWatcher_get_Status(device_watcher, &status); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(status == DeviceWatcherStatus_Stopped, "got status %u\n", status); + ok(stopped_handler.invoked, "stopped_handler not invoked\n"); + ok(stopped_handler.args == NULL, "stopped_handler not invoked\n"); + + CloseHandle(stopped_handler.event); + IDeviceWatcher_Release(device_watcher); + + RoUninitialize(); +} + +START_TEST(devices) +{ + test_device_watcher_stop(); +}
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121992
Your paranoid android.
=== w8 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 09fc:devices: unhandled exception c0000005 at 00401B96
=== w8adm (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 0a9c:devices: unhandled exception c0000005 at 00401B96
=== w864 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 0804:devices: unhandled exception c0000005 at 00401B96
=== w1064v1507 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 0b04:devices: unhandled exception c0000005 at 0040166E
=== w1064v1809 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1d18:devices: unhandled exception c0000005 at 0040166E
=== w1064 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1c3c:devices: unhandled exception c0000005 at 0040166E
=== w1064_tsign (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 0f88:devices: unhandled exception c0000005 at 0040166E
=== w10pro64 (32 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1dc8:devices: unhandled exception c0000005 at 0040166E
=== w864 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 0b18:devices: unhandled exception c0000005 at 00000000004019B8
=== w1064v1507 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 0e50:devices: unhandled exception c0000005 at 000000000040152F
=== w1064v1809 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1d10:devices: unhandled exception c0000005 at 000000000040152F
=== w1064 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1c5c:devices: unhandled exception c0000005 at 000000000040152F
=== w1064_2qxl (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1dc8:devices: unhandled exception c0000005 at 000000000040152F
=== w1064_adm (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1c3c:devices: unhandled exception c0000005 at 000000000040152F
=== w1064_tsign (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1ea8:devices: unhandled exception c0000005 at 000000000040152F
=== w10pro64 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1d5c:devices: unhandled exception c0000005 at 000000000040152F
=== w10pro64_en_AE_u8 (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 0304:devices: unhandled exception c0000005 at 000000000040152F
=== w10pro64_ar (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 07ac:devices: unhandled exception c0000005 at 000000000040152F
=== w10pro64_ja (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 1430:devices: unhandled exception c0000005 at 000000000040152F
=== w10pro64_zh_CN (64 bit report) ===
windows.devices.enumeration: devices.c:153: Test failed: got hr 0x80004002 devices.c:173: Test failed: got hr 0x80004002 170c:devices: unhandled exception c0000005 at 000000000040152F