From: Vibhav Pant vibhavp@gmail.com
--- dlls/windows.devices.enumeration/Makefile.in | 1 + dlls/windows.devices.enumeration/collection.c | 38 +++- .../windows.devices.enumeration/information.c | 201 ++++++++++++++++++ dlls/windows.devices.enumeration/main.c | 21 +- dlls/windows.devices.enumeration/private.h | 5 +- .../tests/devices.c | 6 +- 6 files changed, 260 insertions(+), 12 deletions(-) create mode 100644 dlls/windows.devices.enumeration/information.c
diff --git a/dlls/windows.devices.enumeration/Makefile.in b/dlls/windows.devices.enumeration/Makefile.in index e6c1ef8ddfe..062a914e322 100644 --- a/dlls/windows.devices.enumeration/Makefile.in +++ b/dlls/windows.devices.enumeration/Makefile.in @@ -8,4 +8,5 @@ SOURCES = \ classes.idl \ collection.c \ event_handlers.c \ + information.c \ main.c \ diff --git a/dlls/windows.devices.enumeration/collection.c b/dlls/windows.devices.enumeration/collection.c index a14dfdb27c2..ac0ea8c7fe4 100644 --- a/dlls/windows.devices.enumeration/collection.c +++ b/dlls/windows.devices.enumeration/collection.c @@ -27,6 +27,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(enumeration); struct vectorview_DeviceInformation { IVectorView_DeviceInformation IVectorView_DeviceInformation_iface; + + IDeviceInformation **devices; + SIZE_T len; + LONG ref; };
@@ -76,7 +80,12 @@ static ULONG STDMETHODCALLTYPE vectorview_DeviceInformation_Release( IVectorView impl = impl_from_IVectorView_DeviceInformation( iface ); ref = InterlockedDecrement( &impl->ref ); if (!ref) + { + while (impl->len--) + IDeviceInformation_Release( impl->devices[impl->len] ); + free( impl->devices ); free( impl ); + } return ref; }
@@ -105,15 +114,29 @@ static HRESULT STDMETHODCALLTYPE vectorview_DeviceInformation_GetTrustLevel( IVe static HRESULT STDMETHODCALLTYPE vectorview_DeviceInformation_GetAt( IVectorView_DeviceInformation *iface, UINT32 index, IDeviceInformation **value ) { - FIXME( "(%p, %u, %p) stub!\n", iface, index, value ); - return E_NOTIMPL; + struct vectorview_DeviceInformation *impl; + + TRACE( "(%p, %u, %p)\n", iface, index, value ); + + impl = impl_from_IVectorView_DeviceInformation( iface ); + *value = NULL; + if (index >= impl->len) + return E_BOUNDS; + *value = impl->devices[index]; + IDeviceInformation_AddRef( *value ); + return S_OK; }
static HRESULT STDMETHODCALLTYPE vectorview_DeviceInformation_get_Size( IVectorView_DeviceInformation *iface, UINT32 *value ) { - FIXME( "(%p, %p) stub!\n", iface, value ); - return E_NOTIMPL; + struct vectorview_DeviceInformation *impl; + + TRACE( "(%p, %p)\n", iface, value ); + + impl = impl_from_IVectorView_DeviceInformation( iface ); + *value = impl->len; + return S_OK; }
static HRESULT STDMETHODCALLTYPE vectorview_DeviceInformation_IndexOf( IVectorView_DeviceInformation *iface, @@ -128,7 +151,7 @@ static HRESULT STDMETHODCALLTYPE vectorview_DeviceInformation_GetMany( IVectorVi UINT32 start, UINT32 size, IDeviceInformation **items, UINT32 *copied ) { - FIXME( "(%p, %u, %u, %p, %p): stub!\n", iface, start, size, items, copied ); + FIXME( "(%p, %u, %u, %p, %p) stub!\n", iface, start, size, items, copied ); return E_NOTIMPL; }
@@ -149,7 +172,8 @@ const static IVectorView_DeviceInformationVtbl vectorview_DeviceInformation_vtbl vectorview_DeviceInformation_GetMany };
-HRESULT vectorview_deviceinformation_create( IVectorView_DeviceInformation **view ) +HRESULT vectorview_deviceinformation_create( IDeviceInformation **devices, SIZE_T len, + IVectorView_DeviceInformation **view ) { struct vectorview_DeviceInformation *impl;
@@ -158,6 +182,8 @@ HRESULT vectorview_deviceinformation_create( IVectorView_DeviceInformation **vie return E_OUTOFMEMORY;
impl->IVectorView_DeviceInformation_iface.lpVtbl = &vectorview_DeviceInformation_vtbl; + impl->devices = devices; + impl->len = len; impl->ref = 1; *view = &impl->IVectorView_DeviceInformation_iface; return S_OK; diff --git a/dlls/windows.devices.enumeration/information.c b/dlls/windows.devices.enumeration/information.c new file mode 100644 index 00000000000..1d9cedf66e5 --- /dev/null +++ b/dlls/windows.devices.enumeration/information.c @@ -0,0 +1,201 @@ +/* DeviceInformation implementation. + * + * Copyright 2024 Vibhav Pant + * + * 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" + +#include <roapi.h> + +#include <wine/debug.h> +#include <wine/rbtree.h> + +WINE_DEFAULT_DEBUG_CHANNEL(enumeration); + +/* DeviceInformation implementation for objects with kind DeviceInformationKind_DeviceInterface. */ +struct devinfo_DeviceInterface +{ + IDeviceInformation IDeviceInformation_iface; + LONG ref; +}; + +static inline struct devinfo_DeviceInterface *impl_DeviceInterface_from_IDeviceInformation( IDeviceInformation *iface ) +{ + return CONTAINING_RECORD( iface, struct devinfo_DeviceInterface, IDeviceInformation_iface ); +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_QueryInterface( IDeviceInformation *iface, REFIID iid, + void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IDeviceInformation )) + { + IUnknown_AddRef( iface ); + *out = iface; + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE devinfo_DeviceInterface_AddRef( IDeviceInformation *iface ) +{ + struct devinfo_DeviceInterface *impl; + + TRACE( "(%p)\n", iface ); + + impl = impl_DeviceInterface_from_IDeviceInformation( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE devinfo_DeviceInterface_Release( IDeviceInformation *iface ) +{ + struct devinfo_DeviceInterface *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + + impl = impl_DeviceInterface_from_IDeviceInformation( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_GetIids( IDeviceInformation *iface, + ULONG *iid_count, IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI devinfo_DeviceInterface_GetRuntimeClassName( IDeviceInformation *iface, HSTRING *class_name ) +{ + const static WCHAR *name = RuntimeClass_Windows_Devices_Enumeration_DeviceInformation; + + TRACE( "(%p, %p)\n", iface, class_name ); + + return WindowsCreateString( name, wcslen( name ), class_name ); +} + +static HRESULT STDMETHODCALLTYPE device_information_GetTrustLevel( + IDeviceInformation *iface, TrustLevel *trust_level) +{ + FIXME("(%p, %p) stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_get_Id( IDeviceInformation *iface, HSTRING *id ) +{ + FIXME( "(%p, %p) stub!\n", iface, id ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_get_Name( IDeviceInformation *iface, HSTRING *name ) +{ + FIXME( "(%p, %p) stub!\n", iface, name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_get_IsEnabled( IDeviceInformation *iface, boolean *value ) +{ + FIXME( "(%p, %p) stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_IsDefault( IDeviceInformation *iface, boolean *value ) +{ + FIXME( "(%p, %p) stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_get_EnclosureLocation( IDeviceInformation *iface, + IEnclosureLocation **location ) +{ + FIXME( "(%p, %p) stub!\n", iface, location ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_get_Properties( IDeviceInformation *iface, + IMapView_HSTRING_IInspectable **properties ) +{ + FIXME( "(%p, %p) stub!\n", iface, properties ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_Update( IDeviceInformation *iface, + IDeviceInformationUpdate *update ) +{ + FIXME( "(%p, %p) stub!\n", iface, update ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE devinfo_DeviceInterface_GetThumbnailAsync( IDeviceInformation *iface, + IAsyncOperation_DeviceThumbnail **async ) +{ + FIXME( "(%p, %p) stub!\n", iface, async ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +devinfo_DeviceInterface_GetGlyphThumbnailAsync( IDeviceInformation *iface, IAsyncOperation_DeviceThumbnail **async ) +{ + FIXME( "(%p, %p) stub!\n", iface, async ); + return E_NOTIMPL; +} + +static const struct IDeviceInformationVtbl devinfo_DeviceInterface_vtbl = { + /* IUnknown */ + devinfo_DeviceInterface_QueryInterface, + devinfo_DeviceInterface_AddRef, + devinfo_DeviceInterface_Release, + /* IInspectable */ + devinfo_DeviceInterface_GetIids, + devinfo_DeviceInterface_GetRuntimeClassName, + device_information_GetTrustLevel, + /* IDeviceInformation */ + devinfo_DeviceInterface_get_Id, + devinfo_DeviceInterface_get_Name, + devinfo_DeviceInterface_get_IsEnabled, + devinfo_DeviceInterface_IsDefault, + devinfo_DeviceInterface_get_EnclosureLocation, + devinfo_DeviceInterface_get_Properties, + devinfo_DeviceInterface_Update, + devinfo_DeviceInterface_GetThumbnailAsync, + devinfo_DeviceInterface_GetGlyphThumbnailAsync, +}; + +HRESULT deviceinformation_iface_create( IDeviceInformation **info ) +{ + struct devinfo_DeviceInterface *impl; + + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return E_OUTOFMEMORY; + + impl->IDeviceInformation_iface.lpVtbl = &devinfo_DeviceInterface_vtbl; + impl->ref = 1; + *info = &impl->IDeviceInformation_iface; + return S_OK; +} diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index 0b705679283..8b198387155 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -335,17 +335,34 @@ static HRESULT WINAPI device_statics_CreateFromIdAsyncAdditionalProperties( IDev
static HRESULT WINAPI findall_async( IUnknown *invoker, IUnknown *param, PROPVARIANT *result ) { - HRESULT hr; + IDeviceInformation **devices; IVectorView_DeviceInformation *view; + HRESULT hr = S_OK;
FIXME( "invoker %p, param %p, result %p semi-stub!\n", invoker, param, result );
- hr = vectorview_deviceinformation_create( &view ); + devices = calloc( 1, sizeof( *devices ) ); + if (!devices) + return E_OUTOFMEMORY; + + hr = deviceinformation_iface_create( &devices[0] ); + if (FAILED( hr )) + { + free( devices ); + return hr; + } + + hr = vectorview_deviceinformation_create( devices, 1, &view ); if (SUCCEEDED( hr )) { result->vt = VT_UNKNOWN; result->punkVal = (IUnknown *)view; } + else + { + IDeviceInformation_Release( devices[0] ); + free( devices ); + } return hr; }
diff --git a/dlls/windows.devices.enumeration/private.h b/dlls/windows.devices.enumeration/private.h index a8df1a8533f..fccae4cea41 100644 --- a/dlls/windows.devices.enumeration/private.h +++ b/dlls/windows.devices.enumeration/private.h @@ -50,7 +50,10 @@ typedef HRESULT (WINAPI *async_operation_callback)( IUnknown *invoker, IUnknown extern HRESULT async_operation_device_info_collection_result_create( IUnknown *invoker, IUnknown *param, async_operation_callback callback, IAsyncOperation_DeviceInformationCollection **out ); -extern HRESULT vectorview_deviceinformation_create( IVectorView_DeviceInformation **view ); +extern HRESULT vectorview_deviceinformation_create( IDeviceInformation **devices, SIZE_T len, + IVectorView_DeviceInformation **view ); +extern HRESULT deviceinformation_iface_create( IDeviceInformation **info ); + #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ { \ diff --git a/dlls/windows.devices.enumeration/tests/devices.c b/dlls/windows.devices.enumeration/tests/devices.c index 163a2aef792..3a685addab2 100644 --- a/dlls/windows.devices.enumeration/tests/devices.c +++ b/dlls/windows.devices.enumeration/tests/devices.c @@ -485,7 +485,7 @@ static void test_DeviceInformation( void ) IDeviceInformation **devices;
hr = IVectorView_DeviceInformation_get_Size( info_collection, &size ); - todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); for (idx = 0; idx < size ;idx++) { IDeviceInformation *info; @@ -497,10 +497,10 @@ static void test_DeviceInformation( void ) UINT32 idx2 = 0; boolean found = FALSE;
- test_DeviceInformation_obj(__LINE__, info); + todo_wine test_DeviceInformation_obj(__LINE__, info); IDeviceInformation_Release( info ); hr = IVectorView_DeviceInformation_IndexOf( info_collection, info, &idx2, &found ); - ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); if (SUCCEEDED( hr )) { ok( found, "Expected IndexOf to return true\n" );