From: Vibhav Pant vibhavp@gmail.com
--- .../tests/bluetooth.c | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+)
diff --git a/dlls/windows.devices.bluetooth/tests/bluetooth.c b/dlls/windows.devices.bluetooth/tests/bluetooth.c index 1d2ef394842..03e6dbda30a 100644 --- a/dlls/windows.devices.bluetooth/tests/bluetooth.c +++ b/dlls/windows.devices.bluetooth/tests/bluetooth.c @@ -50,6 +50,157 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) IUnknown_Release( unk ); }
+struct inspectable_async_handler +{ + IAsyncOperationCompletedHandler_IInspectable iface; + const GUID *iid; + IAsyncOperation_IInspectable *async; + AsyncStatus status; + BOOL invoked; + HANDLE event; + LONG ref; +}; + +static inline struct inspectable_async_handler *impl_from_IAsyncOperationCompletedHandler_IInspectable( IAsyncOperationCompletedHandler_IInspectable *iface ) +{ + return CONTAINING_RECORD( iface, struct inspectable_async_handler, iface ); +} + +static HRESULT WINAPI inspectable_async_handler_QueryInterface( IAsyncOperationCompletedHandler_IInspectable *iface, REFIID iid, void **out ) +{ + struct inspectable_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_IInspectable( iface ); + if (IsEqualGUID( iid, &IID_IUnknown ) || IsEqualGUID( iid, &IID_IAgileObject ) || IsEqualGUID( iid, impl->iid )) + { + 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 inspectable_async_handler_AddRef( IAsyncOperationCompletedHandler_IInspectable *iface ) +{ + struct inspectable_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_IInspectable( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG WINAPI inspectable_async_handler_Release( IAsyncOperationCompletedHandler_IInspectable *iface ) +{ + struct inspectable_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_IInspectable( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI inspectable_async_handler_Invoke( IAsyncOperationCompletedHandler_IInspectable *iface, IAsyncOperation_IInspectable *async, + AsyncStatus status ) +{ + struct inspectable_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_IInspectable( iface ); + ok( !impl->invoked, "invoked twice\n" ); + impl->async = async; + impl->status = status; + if (impl->event) SetEvent( impl->event ); + return S_OK; +} + +static const IAsyncOperationCompletedHandler_IInspectableVtbl inspectable_async_handler_vtbl = +{ + /* IUnknown */ + inspectable_async_handler_QueryInterface, + inspectable_async_handler_AddRef, + inspectable_async_handler_Release, + /* IAsyncOperationCompletedHandler<IInspectable> */ + inspectable_async_handler_Invoke +}; + +static WINAPI IAsyncOperationCompletedHandler_IInspectable *inspectable_async_handler_create( HANDLE event, const GUID *iid ) +{ + struct inspectable_async_handler *impl; + + if (!(impl = calloc( 1, sizeof(*impl) ))) return NULL; + impl->iface.lpVtbl = &inspectable_async_handler_vtbl; + impl->iid = iid; + impl->event = event; + impl->ref = 1; + return &impl->iface; +} + +static void await_bluetoothledevice( int line, IAsyncOperation_BluetoothLEDevice *async ) +{ + IAsyncOperationCompletedHandler_IInspectable *handler; + HANDLE event; + HRESULT hr; + DWORD ret; + + event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok_(__FILE__, line)( !!event, "CreateEventW failed, error %lu\n", GetLastError() ); + + handler = inspectable_async_handler_create( event, &IID_IAsyncOperationCompletedHandler_BluetoothLEDevice ); + ok_( __FILE__, line )( !!handler, "inspectable_async_handler_create failed\n" ); + hr = IAsyncOperation_BluetoothLEDevice_put_Completed( async, (IAsyncOperationCompletedHandler_BluetoothLEDevice *)handler ); + ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr ); + IAsyncOperationCompletedHandler_IInspectable_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() ); +} + +static void check_bluetoothledevice_async( int line, IAsyncOperation_BluetoothLEDevice *async, + UINT32 expect_id, AsyncStatus expect_status, + HRESULT expect_hr, IBluetoothLEDevice **result ) +{ + AsyncStatus async_status; + IAsyncInfo *async_info; + HRESULT hr, async_hr; + UINT32 async_id; + + hr = IAsyncOperation_BluetoothLEDevice_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_BluetoothLEDevice_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_BluetoothAdapterStatics(void) { static const WCHAR *default_res = L"System.Devices.InterfaceClassGuid:="{92383B0E-F90E-4AC9-8D44-8C2D0D0EBDA2}" " @@ -138,6 +289,59 @@ static void test_BluetoothDeviceStatics( void ) IBluetoothDeviceStatics_Release( statics ); }
+static void test_BluetoothLEDeviceStatics( void ) +{ + static const WCHAR *class_name = RuntimeClass_Windows_Devices_Bluetooth_BluetoothLEDevice; + IAsyncOperation_BluetoothLEDevice *async_op; + IBluetoothLEDeviceStatics *statics; + IActivationFactory *factory; + IBluetoothLEDevice *device = NULL; + HSTRING str; + HRESULT hr; + + WindowsCreateString( class_name, wcslen( class_name ), &str ); + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void *)&factory ); + WindowsDeleteString( str ); + todo_wine ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + todo_wine win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); + return; + } + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + hr = IActivationFactory_QueryInterface( factory, &IID_IBluetoothLEDeviceStatics, (void **)&statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + IActivationFactory_Release( factory ); + if (FAILED( hr )) + { + skip( "BluetoothLEDeviceStatics not available.\n" ); + return; + } + + str = NULL; + hr = IBluetoothLEDeviceStatics_GetDeviceSelector( statics, &str ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + todo_wine ok( !WindowsIsStringEmpty( str ), "got empty device selector string.\n" ); + WindowsDeleteString( str ); + + /* Use an invalid Bluetooth address. */ + hr = IBluetoothLEDeviceStatics_FromBluetoothAddressAsync( statics, 0, &async_op ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + + if (hr == S_OK) + { + await_bluetoothledevice( __LINE__, async_op ); + check_bluetoothledevice_async( __LINE__, async_op, 1, Completed, S_OK, &device ); + ok( !device, "got device %p != NULL\n", device ); + if (device) IBluetoothLEDevice_Release( device ); + } + + IBluetoothLEDeviceStatics_Release( statics ); +} + START_TEST(bluetooth) { HRESULT hr; @@ -147,6 +351,7 @@ START_TEST(bluetooth)
test_BluetoothAdapterStatics(); test_BluetoothDeviceStatics(); + test_BluetoothLEDeviceStatics();
RoUninitialize(); }