From: Vibhav Pant vibhavp@gmail.com
--- dlls/windows.devices.enumeration/Makefile.in | 2 +- .../windows.devices.enumeration/information.c | 31 +++++++---- dlls/windows.devices.enumeration/main.c | 51 +++++++++++++++++-- dlls/windows.devices.enumeration/private.h | 2 +- .../tests/devices.c | 2 +- 5 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/dlls/windows.devices.enumeration/Makefile.in b/dlls/windows.devices.enumeration/Makefile.in index dc4c60a05e7..1d3bf5a69a3 100644 --- a/dlls/windows.devices.enumeration/Makefile.in +++ b/dlls/windows.devices.enumeration/Makefile.in @@ -1,5 +1,5 @@ MODULE = windows.devices.enumeration.dll -IMPORTS = combase uuid +IMPORTS = advapi32 combase setupapi uuid
SOURCES = \ access.c \ diff --git a/dlls/windows.devices.enumeration/information.c b/dlls/windows.devices.enumeration/information.c index d65d63795bb..c09a9ea37ef 100644 --- a/dlls/windows.devices.enumeration/information.c +++ b/dlls/windows.devices.enumeration/information.c @@ -19,10 +19,7 @@
#include "private.h"
-#include <roapi.h> - -#include <wine/debug.h> -#include <wine/rbtree.h> +#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enumeration);
@@ -30,6 +27,8 @@ struct device_information { IDeviceInformation IDeviceInformation_iface; LONG ref; + + HSTRING path; };
static inline struct device_information *impl_DeviceInterface_from_IDeviceInformation( IDeviceInformation *iface ) @@ -68,9 +67,15 @@ static ULONG WINAPI device_information_Release( IDeviceInformation *iface ) { struct device_information *impl = impl_DeviceInterface_from_IDeviceInformation( iface ); ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref );
- if (!ref) free( impl ); + if (!ref) + { + WindowsDeleteString( impl->path ); + free( impl ); + } + return ref; }
@@ -95,8 +100,9 @@ static HRESULT WINAPI device_information_GetTrustLevel( IDeviceInformation *ifac
static HRESULT WINAPI device_information_get_Id( IDeviceInformation *iface, HSTRING *id ) { - FIXME( "iface %p, id %p stub!\n", iface, id ); - return E_NOTIMPL; + struct device_information *impl = impl_DeviceInterface_from_IDeviceInformation( iface ); + TRACE( "iface %p, id %p\n", iface, id ); + return WindowsDuplicateString( impl->path, id ); }
static HRESULT WINAPI device_information_get_Name( IDeviceInformation *iface, HSTRING *name ) @@ -170,16 +176,23 @@ static const struct IDeviceInformationVtbl device_information_vtbl = device_information_GetGlyphThumbnailAsync, };
-HRESULT device_information_create( IDeviceInformation **info ) +HRESULT device_information_create( const WCHAR *path, IDeviceInformation **info ) { struct device_information *impl; + HRESULT hr;
- TRACE( "info %p\n", info ); + TRACE( "path %s, info %p\n", debugstr_w(path), info );
if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; impl->IDeviceInformation_iface.lpVtbl = &device_information_vtbl; impl->ref = 1;
+ if (FAILED(hr = WindowsCreateString( path, wcslen( path ), &impl->path ))) + { + free( impl ); + return hr; + } + *info = &impl->IDeviceInformation_iface; TRACE( "created DeviceInformation %p\n", impl ); return S_OK; diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index 9d36147a974..ba7edaa5199 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -20,6 +20,7 @@
#include "initguid.h" #include "private.h" +#include "setupapi.h"
#include "wine/debug.h"
@@ -343,20 +344,60 @@ static HRESULT WINAPI find_all_async( IUnknown *invoker, IUnknown *param, PROPVA .iterator = &IID_IIterator_DeviceInformation, }; IVectorView_DeviceInformation *view; - IDeviceInformation *device; IVector_IInspectable *vector; + HKEY iface_key; HRESULT hr; + DWORD i;
- FIXME( "invoker %p, param %p, result %p semi-stub!\n", invoker, param, result ); + TRACE( "invoker %p, param %p, result %p\n", invoker, param, result );
if (FAILED(hr = vector_create( &iids, (void *)&vector ))) return hr;
- if (SUCCEEDED(hr = device_information_create( &device ))) + if (!(iface_key = SetupDiOpenClassRegKeyExW( NULL, KEY_ENUMERATE_SUB_KEYS, DIOCR_INTERFACE, NULL, NULL ))) { - hr = IVector_IInspectable_Append( vector, (IInspectable *)device ); - IDeviceInformation_Release( device ); + IVector_IInspectable_Release( vector ); + return HRESULT_FROM_WIN32( GetLastError() ); }
+ for (i = 0; SUCCEEDED(hr); i++) + { + char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)]; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (void *)buffer; + SP_DEVICE_INTERFACE_DATA iface = {.cbSize = sizeof(iface)}; + HDEVINFO set = INVALID_HANDLE_VALUE; + GUID iface_class; + WCHAR name[40]; + DWORD j, len; + LSTATUS ret; + + len = ARRAY_SIZE(name); + ret = RegEnumKeyExW( iface_key, i, name, &len, NULL, NULL, NULL, NULL ); + if (ret == ERROR_NO_MORE_ITEMS) break; + if (ret) hr = HRESULT_FROM_WIN32( ret ); + + if (SUCCEEDED(hr) && SUCCEEDED(hr = CLSIDFromString( name, &iface_class ))) + { + set = SetupDiGetClassDevsW( &iface_class, NULL, NULL, DIGCF_DEVICEINTERFACE ); + if (set == INVALID_HANDLE_VALUE) hr = HRESULT_FROM_WIN32( GetLastError() ); + } + + for (j = 0; SUCCEEDED(hr) && SetupDiEnumDeviceInterfaces( set, NULL, &iface_class, j, &iface ); j++) + { + IDeviceInformation *info; + + detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + if (!SetupDiGetDeviceInterfaceDetailW( set, &iface, detail, sizeof(buffer), NULL, NULL )) continue; + + if (SUCCEEDED(hr = device_information_create( detail->DevicePath, &info ))) + { + hr = IVector_IInspectable_Append( vector, (IInspectable *)info ); + IDeviceInformation_Release( info ); + } + } + } + + RegCloseKey( iface_key ); + if (SUCCEEDED(hr)) hr = IVector_IInspectable_GetView( vector, (void *)&view ); IVector_IInspectable_Release( vector ); if (FAILED(hr)) return hr; diff --git a/dlls/windows.devices.enumeration/private.h b/dlls/windows.devices.enumeration/private.h index f0fa09a923a..f9a866d5f59 100644 --- a/dlls/windows.devices.enumeration/private.h +++ b/dlls/windows.devices.enumeration/private.h @@ -58,7 +58,7 @@ 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 vector_create( const struct vector_iids *iids, void **out ); -extern HRESULT device_information_create( IDeviceInformation **info ); +extern HRESULT device_information_create( const WCHAR *path, 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 6617f71a611..a6c0ce0fe03 100644 --- a/dlls/windows.devices.enumeration/tests/devices.c +++ b/dlls/windows.devices.enumeration/tests/devices.c @@ -302,7 +302,7 @@ static void test_DeviceInformation_obj( int line, IDeviceInformation *info ) boolean bool_val;
hr = IDeviceInformation_get_Id( info, &str ); - todo_wine ok_(__FILE__, line)( hr == S_OK, "got hr %#lx\n", hr ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx\n", hr ); WindowsDeleteString( str ); str = NULL; hr = IDeviceInformation_get_Name( info, &str );