From: Vibhav Pant vibhavp@gmail.com
--- .../tests/devices.c | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+)
diff --git a/dlls/windows.devices.enumeration/tests/devices.c b/dlls/windows.devices.enumeration/tests/devices.c index ae76e5d754a..fe986835d4b 100644 --- a/dlls/windows.devices.enumeration/tests/devices.c +++ b/dlls/windows.devices.enumeration/tests/devices.c @@ -135,6 +135,199 @@ static void device_watcher_handler_create( struct device_watcher_handler *impl ) impl->ref = 1; }
+struct deviceinformationcollection_async_handler +{ + IAsyncOperationCompletedHandler_DeviceInformationCollection iface; + + IAsyncOperation_DeviceInformationCollection *async; + AsyncStatus status; + BOOL invoked; + HANDLE event; + LONG ref; +}; + +static inline struct deviceinformationcollection_async_handler * +impl_from_IAsyncOperationCompletedHandler_DeviceInformationCollection( + IAsyncOperationCompletedHandler_DeviceInformationCollection *iface ) +{ + return CONTAINING_RECORD( iface, struct deviceinformationcollection_async_handler, iface ); +} + +static HRESULT WINAPI deviceinformationcollection_async_handler_QueryInterface( + IAsyncOperationCompletedHandler_DeviceInformationCollection *iface, REFIID iid, void **out ) +{ + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IAsyncOperationCompletedHandler_DeviceInformationCollection )) + { + IUnknown_AddRef( iface ); + *out = iface; + return S_OK; + } + + if (winetest_debug > 1) trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI deviceinformationcollection_async_handler_AddRef( + IAsyncOperationCompletedHandler_DeviceInformationCollection *iface ) +{ + struct deviceinformationcollection_async_handler *impl; + impl = impl_from_IAsyncOperationCompletedHandler_DeviceInformationCollection( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG WINAPI deviceinformationcollection_async_handler_Release( + IAsyncOperationCompletedHandler_DeviceInformationCollection *iface ) +{ + struct deviceinformationcollection_async_handler *impl; + ULONG ref; + + impl = impl_from_IAsyncOperationCompletedHandler_DeviceInformationCollection( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + return ref; +} + +static HRESULT WINAPI deviceinformationcollection_async_handler_Invoke( + IAsyncOperationCompletedHandler_DeviceInformationCollection *iface, + IAsyncOperation_DeviceInformationCollection *async, AsyncStatus status ) +{ + struct deviceinformationcollection_async_handler *impl; + + impl = impl_from_IAsyncOperationCompletedHandler_DeviceInformationCollection( iface ); + ok( !impl->invoked, "invoked twice\n" ); + impl->invoked = TRUE; + impl->async = async; + impl->status = status; + if (impl->event) SetEvent( impl-> event ); + + return S_OK; +} + +static IAsyncOperationCompletedHandler_DeviceInformationCollectionVtbl deviceinformationcollection_async_handler_vtbl = +{ + /* IUnknown */ + deviceinformationcollection_async_handler_QueryInterface, + deviceinformationcollection_async_handler_AddRef, + deviceinformationcollection_async_handler_Release, + /* IAsyncOperationCompletedHandler<DeviceInformationCollection> */ + deviceinformationcollection_async_handler_Invoke, +}; + +static IAsyncOperationCompletedHandler_DeviceInformationCollection * +deviceinformationcollection_async_handler_create( HANDLE event ) +{ + struct deviceinformationcollection_async_handler *impl; + + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return NULL; + impl->iface.lpVtbl = &deviceinformationcollection_async_handler_vtbl; + impl->event = event; + impl->ref = 1; + + return &impl->iface; +} + +#define await_deviceinformationcollection( a ) await_deviceinformationcollection_( __LINE__, ( a ) ) +static void await_deviceinformationcollection_( int line, IAsyncOperation_DeviceInformationCollection *async ) +{ + IAsyncOperationCompletedHandler_DeviceInformationCollection *handler; + HANDLE event; + HRESULT hr; + DWORD ret; + + event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok_(__FILE__, line)( !!event, "CreateEventW failed, error %lu\n", GetLastError() ); + + handler = deviceinformationcollection_async_handler_create( event ); + ok_(__FILE__, line)( !!handler, "deviceinformationcollection_async_handler_create failed\n" ); + hr = IAsyncOperation_DeviceInformationCollection_put_Completed( async, handler ); + ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr ); + IAsyncOperationCompletedHandler_DeviceInformationCollection_Release( handler ); + + ret = WaitForSingleObject( event, 5000 ); + ok_(__FILE__, line)( !ret, "WaitForSingleObject returned %#lx\n", ret ); + ret = CloseHandle( event ); + ok_(__FILE__, line)( ret, "CloseHandle failed, error %lu\n", GetLastError() ); +} + +#define check_deviceinformationcollection_async( a, b, c, d, e ) check_deviceinformationcollection_async_( __LINE__, a, b, c, d, e ) +static void check_deviceinformationcollection_async_( + int line, IAsyncOperation_DeviceInformationCollection *async, UINT32 expect_id, + AsyncStatus expect_status, HRESULT expect_hr, IVectorView_DeviceInformation **result ) +{ + AsyncStatus async_status; + IAsyncInfo *async_info; + HRESULT hr, async_hr; + UINT32 async_id; + + hr = IAsyncOperation_DeviceInformationCollection_QueryInterface( async, &IID_IAsyncInfo, (void **)&async_info ); + ok_(__FILE__, line)( hr == S_OK, "QueryInterface returned %#lx\n", hr ); + + async_id = 0xdeadbeef; + hr = IAsyncInfo_get_Id( async_info, &async_id ); + if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Id returned %#lx\n", hr ); + else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Id returned %#lx\n", hr ); + ok_(__FILE__, line)( async_id == expect_id, "got id %u\n", async_id ); + + async_status = 0xdeadbeef; + hr = IAsyncInfo_get_Status( async_info, &async_status ); + if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Status returned %#lx\n", hr ); + else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Status returned %#lx\n", hr ); + ok_(__FILE__, line)( async_status == expect_status, "got status %u\n", async_status ); + + async_hr = 0xdeadbeef; + hr = IAsyncInfo_get_ErrorCode( async_info, &async_hr ); + if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_ErrorCode returned %#lx\n", hr ); + else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_ErrorCode returned %#lx\n", hr ); + if (expect_status < 4) todo_wine_if(FAILED(expect_hr)) ok_(__FILE__, line)( async_hr == expect_hr, "got error %#lx\n", async_hr ); + else ok_(__FILE__, line)( async_hr == E_ILLEGAL_METHOD_CALL, "got error %#lx\n", async_hr ); + + IAsyncInfo_Release( async_info ); + + hr = IAsyncOperation_DeviceInformationCollection_GetResults( async, result ); + switch (expect_status) + { + case Completed: + case Error: + todo_wine_if(FAILED(expect_hr)) + ok_(__FILE__, line)( hr == expect_hr, "GetResults returned %#lx\n", hr ); + break; + case Canceled: + case Started: + default: + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "GetResults returned %#lx\n", hr ); + break; + } +} + +static void test_DeviceInformation_obj( int line, IDeviceInformation *info ) +{ + HRESULT hr; + HSTRING str; + boolean bool_val; + + hr = IDeviceInformation_get_Id( info, &str ); + ok_(__FILE__, line)( SUCCEEDED( hr ), "got hr %#lx\n", hr ); + trace_(__FILE__, line)( "id: %s\n", debugstr_hstring( str ) ); + WindowsDeleteString( str ); + str = NULL; + hr = IDeviceInformation_get_Name( info, &str ); + todo_wine ok_(__FILE__, line)( SUCCEEDED( hr ), "got hr %#lx\n", hr ); + trace_(__FILE__, line)( " name: %s\n", debugstr_hstring( str ) ); + WindowsDeleteString( str ); + hr = IDeviceInformation_get_IsEnabled( info, &bool_val ); + todo_wine ok_(__FILE__, line)( SUCCEEDED( hr ), "got hr %#lx\n", hr ); + trace_(__FILE__, line)( " enabled: %d\n", bool_val ); + hr = IDeviceInformation_get_IsDefault( info, &bool_val ); + todo_wine ok_(__FILE__, line)( SUCCEEDED( hr ), "got hr %#lx\n", hr ); + trace_(__FILE__, line)( " default: %d\n", bool_val ); +} + static void test_DeviceInformation( void ) { static const WCHAR *device_info_name = L"Windows.Devices.Enumeration.DeviceInformation"; @@ -147,6 +340,8 @@ static void test_DeviceInformation( void ) IDeviceInformationStatics *device_info_statics; IDeviceWatcher *device_watcher; DeviceWatcherStatus status = 0xdeadbeef; + IAsyncOperation_DeviceInformationCollection *infocollection_async = NULL; + IVectorView_DeviceInformation *info_collection = NULL; ULONG ref; HSTRING str; HRESULT hr; @@ -273,6 +468,46 @@ static void test_DeviceInformation( void ) ok( stopped_handler.args == NULL, "stopped_handler not invoked\n" );
IDeviceWatcher_Release( device_watcher ); + + hr = IDeviceInformationStatics_FindAllAsync( device_info_statics, &infocollection_async ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (infocollection_async) + { + todo_wine await_deviceinformationcollection( infocollection_async ); + todo_wine check_deviceinformationcollection_async( infocollection_async, 1, Completed, S_OK, &info_collection ); + IAsyncOperation_DeviceInformationCollection_Release( infocollection_async ); + } + if (info_collection) + { + UINT32 idx = 0, size = 0; + + hr = IVectorView_DeviceInformation_get_Size( info_collection, &size ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + for (idx = 0; idx < size ;idx++) + { + IDeviceInformation *info; + winetest_push_context("info_collection %u", idx); + hr = IVectorView_DeviceInformation_GetAt( info_collection, idx, &info ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr); + if (SUCCEEDED( hr )) + { + UINT32 idx2 = 0; + boolean found = FALSE; + + test_DeviceInformation_obj(__LINE__, info); + IDeviceInformation_Release( info ); + hr = IVectorView_DeviceInformation_IndexOf( info_collection, info, &idx2, &found ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + ok( found, "Expected IndexOf to return true\n" ); + ok( idx == idx2, "%u != %u\n", idx, idx2); + } + } + winetest_pop_context(); + } + } + IDeviceInformationStatics_Release( device_info_statics ); skip_device_statics: IInspectable_Release( inspectable );