From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/tests/Makefile.in | 1 + dlls/bluetoothapis/tests/auth.c | 111 +++++++++++++++++++++++++++ dlls/bluetoothapis/tests/device.c | 16 +--- dlls/bluetoothapis/tests/helpers.h | 45 +++++++++++ 4 files changed, 159 insertions(+), 14 deletions(-) create mode 100644 dlls/bluetoothapis/tests/auth.c create mode 100644 dlls/bluetoothapis/tests/helpers.h
diff --git a/dlls/bluetoothapis/tests/Makefile.in b/dlls/bluetoothapis/tests/Makefile.in index 5d01bf3a809..e832f383054 100644 --- a/dlls/bluetoothapis/tests/Makefile.in +++ b/dlls/bluetoothapis/tests/Makefile.in @@ -2,6 +2,7 @@ TESTDLL = bluetoothapis.dll IMPORTS = bluetoothapis
SOURCES = \ + auth.c \ device.c \ radio.c \ sdp.c diff --git a/dlls/bluetoothapis/tests/auth.c b/dlls/bluetoothapis/tests/auth.c new file mode 100644 index 00000000000..7802e54fb78 --- /dev/null +++ b/dlls/bluetoothapis/tests/auth.c @@ -0,0 +1,111 @@ +/* + * Tests for Bluetooth authentication methods + * + * Copyright 2025 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 <stdarg.h> + +#include <windef.h> +#include <winbase.h> +#include <winnls.h> + +#include <bthsdpdef.h> +#include <bluetoothapis.h> + +#include <wine/test.h> + +#include "helpers.h" + +static HANDLE auth_events[2]; + +static void test_auth_callback_params( int line, const BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS *auth_params ) +{ + ok_( __FILE__, line )( !!auth_params, "Expected authentication params to not be NULL\n" ); + if (auth_params) + { + ULARGE_INTEGER ft = {0}; + + trace_( __FILE__, line )( "Device: %s\n", debugstr_BLUETOOTH_DEVICE_INFO( &auth_params->deviceInfo ) ); + trace_( __FILE__, line )( "Method: %#x\n", auth_params->authenticationMethod ); + trace_( __FILE__, line )( "Numeric value: %lu\n", auth_params->Numeric_Value ); + + SystemTimeToFileTime( &auth_params->deviceInfo.stLastSeen, (FILETIME *)&ft ); + ok( ft.QuadPart, "Expected stLastSeen to be greater than zero\n" ); + ft.QuadPart = 0; + SystemTimeToFileTime( &auth_params->deviceInfo.stLastUsed, (FILETIME *)&ft ); + ok( ft.QuadPart, "Expected stLastUsed to be greater than zero\n" ); + } +} + +static CALLBACK BOOL auth_ex_callback( void *data, BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS *auth_params ) +{ + test_auth_callback_params( __LINE__, auth_params ); + SetEvent( auth_events[0] ); + return TRUE; +} + +static CALLBACK BOOL auth_ex_callback_2( void *data, BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS *auth_params ) +{ + test_auth_callback_params( __LINE__, auth_params ); + SetEvent( auth_events[1] ); + return TRUE; +} + +static void test_BluetoothRegisterForAuthenticationEx( void ) +{ + HBLUETOOTH_AUTHENTICATION_REGISTRATION hreg = NULL, hreg2 = NULL; + BLUETOOTH_DEVICE_INFO info; + DWORD err; + + err = BluetoothRegisterForAuthenticationEx( NULL, NULL, NULL, NULL ); + ok( err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER ); + + info.dwSize = sizeof( info ) + 1; + err = BluetoothRegisterForAuthenticationEx( &info, &hreg, NULL, NULL ); + ok( err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER ); + + auth_events[0] = CreateEventA( NULL, FALSE, FALSE, NULL ); + auth_events[1] = CreateEventA( NULL, FALSE, FALSE, NULL ); + + BluetoothEnableIncomingConnections( NULL, TRUE ); + BluetoothEnableDiscovery( NULL, TRUE ); + + err = BluetoothRegisterForAuthenticationEx( NULL, &hreg, auth_ex_callback, NULL ); + ok( !err, "BluetoothRegisterForAuthenticationEx failed: %lu\n", err ); + ok( !!hreg, "Handle was not filled\n" ); + + err = BluetoothRegisterForAuthenticationEx( NULL, &hreg2, auth_ex_callback_2, NULL ); + ok( !err, "BluetoothRegisterForAuthenticationEx failed: %lu\n", err ); + ok( !!hreg2, "Handle was not filled\n" ); + + err = WaitForMultipleObjects( 2, auth_events, TRUE, 60000 ); + ok( !err, "WaitForMultipleObjects failed: %lu\n", err ); + + if (hreg) + ok( BluetoothUnregisterAuthentication( hreg ), "BluetoothUnregisterAuthentication failed: %lu\n", GetLastError() ); + if (hreg2) + ok( BluetoothUnregisterAuthentication( hreg2 ), "BluetoothUnregisterAuthentication failed: %lu\n", GetLastError() ); + + BluetoothEnableDiscovery( NULL, FALSE ); +} + +START_TEST( auth ) +{ + if (winetest_interactive) + test_BluetoothRegisterForAuthenticationEx(); +} diff --git a/dlls/bluetoothapis/tests/device.c b/dlls/bluetoothapis/tests/device.c index 13ccf8c2af3..f0413b6184f 100644 --- a/dlls/bluetoothapis/tests/device.c +++ b/dlls/bluetoothapis/tests/device.c @@ -29,12 +29,7 @@
#include <wine/test.h>
-extern void test_for_all_radios( const char *file, int line, void (*test)( HANDLE radio, void *data ), void *data ); - -static const char *debugstr_bluetooth_address( const BYTE *addr ) -{ - return wine_dbg_sprintf( "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] ); -} +#include "helpers.h"
void test_radio_BluetoothFindFirstDevice( HANDLE radio, void *data ) { @@ -123,7 +118,6 @@ void test_radio_BluetoothFindNextDevice( HANDLE radio, void *data ) for (;;) { BLUETOOTH_DEVICE_INFO info2 = {0}; - WCHAR buf[256]; BOOL matches;
matches = (info.fConnected && search_params.fReturnConnected) @@ -131,13 +125,7 @@ void test_radio_BluetoothFindNextDevice( HANDLE radio, void *data ) || (info.fRemembered && search_params.fReturnRemembered) || (!info.fRemembered && search_params.fReturnUnknown); ok( matches, "Device does not match filter constraints\n" ); - trace( "device %lu: %s\n", i, debugstr_bluetooth_address( info.Address.rgBytes) ); - trace( " name: %s\n", debugstr_w( info.szName ) ); - trace( " class: %#lx\n", info.ulClassofDevice ); - trace( " connected: %d, authenticated: %d, remembered: %d\n", info.fConnected, info.fAuthenticated, - info.fRemembered ); - if (GetTimeFormatEx( NULL, TIME_FORCE24HOURFORMAT, &info.stLastSeen, NULL, buf, ARRAY_SIZE( buf ) )) - trace( " last seen: %s UTC\n", debugstr_w( buf ) ); + trace( "device %lu: %s\n", i, debugstr_BLUETOOTH_DEVICE_INFO( &info ) );
info2.dwSize = sizeof( info2 ); info2.Address = info.Address; diff --git a/dlls/bluetoothapis/tests/helpers.h b/dlls/bluetoothapis/tests/helpers.h new file mode 100644 index 00000000000..1438698d45e --- /dev/null +++ b/dlls/bluetoothapis/tests/helpers.h @@ -0,0 +1,45 @@ +/* + * Helper methods + * + * Copyright 2025 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 <wine/debug.h> + +extern void test_for_all_radios( const char *file, int line, void (*test)( HANDLE radio, void *data ), void *data ); + +static inline const char *debugstr_bluetooth_address( const BYTE *addr ) +{ + return wine_dbg_sprintf( "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] ); +} + +static inline const char *debugstr_BLUETOOTH_DEVICE_INFO( const BLUETOOTH_DEVICE_INFO *info ) +{ + WCHAR last_seen[256]; + WCHAR last_used[256]; + + last_seen[0] = last_used[0] = 0; + + GetTimeFormatEx( NULL, TIME_FORCE24HOURFORMAT, &info->stLastSeen, NULL, last_seen, ARRAY_SIZE( last_seen ) ); + GetTimeFormatEx( NULL, TIME_FORCE24HOURFORMAT, &info->stLastUsed, NULL, last_used, ARRAY_SIZE( last_used ) ); + + return wine_dbg_sprintf( "{ Address: %s ulClassOfDevice: %#lx fConnected: %d fRemembered: %d fAuthenticated: %d " + "stLastSeen: %s stLastUsed: %s szName: %s }", + debugstr_bluetooth_address( info->Address.rgBytes ), info->ulClassofDevice, + info->fConnected, info->fRemembered, info->fAuthenticated, debugstr_w( last_seen ), + debugstr_w( last_used ), debugstr_w( info->szName ) ); +}