From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/Makefile.in | 1 + dlls/bluetoothapis/main.c | 121 +++++++++++++++++++++++++++---- dlls/bluetoothapis/tests/radio.c | 24 +++--- 3 files changed, 121 insertions(+), 25 deletions(-)
diff --git a/dlls/bluetoothapis/Makefile.in b/dlls/bluetoothapis/Makefile.in index 1fd74074703..3e2e230fe55 100644 --- a/dlls/bluetoothapis/Makefile.in +++ b/dlls/bluetoothapis/Makefile.in @@ -1,5 +1,6 @@ MODULE = bluetoothapis.dll IMPORTLIB = bluetoothapis +IMPORTS = setupapi
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/bluetoothapis/main.c b/dlls/bluetoothapis/main.c index 5d9087a9a47..4d34a0eceae 100644 --- a/dlls/bluetoothapis/main.c +++ b/dlls/bluetoothapis/main.c @@ -22,13 +22,25 @@ #include <stdarg.h> #include <windef.h> #include <winbase.h> +#include <winuser.h> +#include <winreg.h>
#include "wine/debug.h" #include "bthsdpdef.h" #include "bluetoothapis.h" +#include "setupapi.h" + +#include "initguid.h" +#include "bthdef.h"
WINE_DEFAULT_DEBUG_CHANNEL(bluetoothapis);
+struct bluetooth_find_radio_handle +{ + HDEVINFO devinfo; + DWORD idx; +}; + /********************************************************************* * BluetoothFindFirstDevice */ @@ -43,22 +55,70 @@ HBLUETOOTH_DEVICE_FIND WINAPI BluetoothFindFirstDevice(BLUETOOTH_DEVICE_SEARCH_P /********************************************************************* * BluetoothFindFirstRadio */ -HBLUETOOTH_RADIO_FIND WINAPI BluetoothFindFirstRadio(BLUETOOTH_FIND_RADIO_PARAMS *params, HANDLE *radio) +HBLUETOOTH_RADIO_FIND WINAPI BluetoothFindFirstRadio( BLUETOOTH_FIND_RADIO_PARAMS *params, HANDLE *radio ) { - FIXME("(%p %p): stub!\n", params, radio); - *radio = NULL; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + struct bluetooth_find_radio_handle *find; + HANDLE device_ret; + + TRACE( "(%p, %p)\n", params, radio ); + + if (!params) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + if (params->dwSize != sizeof( *params )) + { + SetLastError( ERROR_REVISION_MISMATCH ); + return NULL; + } + if (!(find = calloc( 1, sizeof( *find ) ))) + { + SetLastError( ERROR_OUTOFMEMORY ); + return NULL; + } + + find->devinfo = + SetupDiGetClassDevsW( &GUID_BTHPORT_DEVICE_INTERFACE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); + if (find->devinfo == INVALID_HANDLE_VALUE) + { + free( find ); + return NULL; + } + + if (!BluetoothFindNextRadio( find, &device_ret )) + { + DWORD err; + err = GetLastError(); + BluetoothFindRadioClose( find ); + find = NULL; + SetLastError( err ); + } + else + *radio = device_ret; + + return find; }
/********************************************************************* * BluetoothFindRadioClose */ -BOOL WINAPI BluetoothFindRadioClose(HBLUETOOTH_RADIO_FIND find) +BOOL WINAPI BluetoothFindRadioClose( HBLUETOOTH_RADIO_FIND find_handle ) { - FIXME("(%p): stub!\n", find); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + struct bluetooth_find_radio_handle *find = find_handle; + + TRACE( "(%p)\n", find_handle ); + + if (!find_handle) + { + SetLastError( ERROR_INVALID_HANDLE ); + return FALSE; + } + + SetupDiDestroyDeviceInfoList( find->devinfo ); + free( find ); + SetLastError( ERROR_SUCCESS ); + return TRUE; }
/********************************************************************* @@ -74,11 +134,46 @@ BOOL WINAPI BluetoothFindDeviceClose(HBLUETOOTH_DEVICE_FIND find) /********************************************************************* * BluetoothFindNextRadio */ -BOOL WINAPI BluetoothFindNextRadio(HBLUETOOTH_RADIO_FIND find, HANDLE *radio) +BOOL WINAPI BluetoothFindNextRadio( HBLUETOOTH_RADIO_FIND find_handle, HANDLE *radio ) { - FIXME("(%p, %p): stub!\n", find, radio); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof( WCHAR )]; + struct bluetooth_find_radio_handle *find = find_handle; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)buffer; + SP_DEVICE_INTERFACE_DATA iface_data; + HANDLE device_ret; + BOOL found; + + TRACE( "(%p, %p)\n", find_handle, radio ); + + if (!find_handle) + { + SetLastError( ERROR_INVALID_HANDLE ); + return FALSE; + } + + iface_detail->cbSize = sizeof( *iface_detail ); + iface_data.cbSize = sizeof( iface_data ); + found = FALSE; + while (SetupDiEnumDeviceInterfaces( find->devinfo, NULL, &GUID_BTHPORT_DEVICE_INTERFACE, find->idx++, + &iface_data )) + { + if (!SetupDiGetDeviceInterfaceDetailW( find->devinfo, &iface_data, iface_detail, sizeof( buffer ), NULL, + NULL )) + continue; + device_ret = + CreateFileW( iface_detail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); + if (device_ret != INVALID_HANDLE_VALUE) + { + found = TRUE; + break; + } + } + + if (found) + *radio = device_ret; + + return found; }
/********************************************************************* diff --git a/dlls/bluetoothapis/tests/radio.c b/dlls/bluetoothapis/tests/radio.c index 19643c1db55..0dac1f99233 100644 --- a/dlls/bluetoothapis/tests/radio.c +++ b/dlls/bluetoothapis/tests/radio.c @@ -40,8 +40,8 @@ void test_BluetoothFindFirstRadio( void ) find = BluetoothFindFirstRadio( NULL, &radio ); ok( !find, "Expected %p to be NULL\n", find ); err = GetLastError(); - todo_wine ok( err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER ); - todo_wine ok( radio == dummy, "%p != %p\n", radio, dummy ); + ok( err == ERROR_INVALID_PARAMETER, "%lu != %d\n", err, ERROR_INVALID_PARAMETER ); + ok( radio == dummy, "%p != %p\n", radio, dummy );
radio = dummy; find_params.dwSize = 0; @@ -49,19 +49,19 @@ void test_BluetoothFindFirstRadio( void ) find = BluetoothFindFirstRadio( &find_params, &radio ); ok ( !find, "Expected %p to be NULL\n", find ); err = GetLastError(); - todo_wine ok( err == ERROR_REVISION_MISMATCH, "%lu != %d\n", err, ERROR_REVISION_MISMATCH ); - todo_wine ok( radio == dummy, "%p != %p\n", radio, dummy ); + ok( err == ERROR_REVISION_MISMATCH, "%lu != %d\n", err, ERROR_REVISION_MISMATCH ); + ok( radio == dummy, "%p != %p\n", radio, dummy );
find_params.dwSize = sizeof( find_params ); SetLastError( 0xdeadbeef ); find = BluetoothFindFirstRadio( &find_params, &radio ); err = GetLastError(); exp = find ? ERROR_SUCCESS : ERROR_NO_MORE_ITEMS; - todo_wine ok( err == exp, "%lu != %lu\n", err, exp ); + ok( err == exp, "%lu != %lu\n", err, exp ); if (find) { CloseHandle( radio ); - todo_wine ok( BluetoothFindRadioClose( find ), "BluetoothFindRadioClose failed: %lu\n", GetLastError() ); + ok( BluetoothFindRadioClose( find ), "BluetoothFindRadioClose failed: %lu\n", GetLastError() ); } }
@@ -85,10 +85,10 @@ void test_BluetoothFindNextRadio( void ) radio = dummy; SetLastError( 0xdeadbeef ); ret = BluetoothFindNextRadio( NULL, &radio ); - todo_wine ok( !ret, "Expected BluetoothFindNextRadio to return FALSE\n" ); + ok( !ret, "Expected BluetoothFindNextRadio to return FALSE\n" ); err = GetLastError(); - todo_wine ok( err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE ); - todo_wine ok( radio == dummy, "%p != %p\n", radio, dummy ); + ok( err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE ); + ok( radio == dummy, "%p != %p\n", radio, dummy );
for(;;) { @@ -97,12 +97,12 @@ void test_BluetoothFindNextRadio( void ) if (!ret) { err = GetLastError(); - todo_wine ok( err == ERROR_NO_MORE_ITEMS, "%lu != %d\n", err, ERROR_NO_MORE_ITEMS ); + ok( err == ERROR_NO_MORE_ITEMS, "%lu != %d\n", err, ERROR_NO_MORE_ITEMS ); break; } CloseHandle( radio ); } - todo_wine ok( BluetoothFindRadioClose( find ), "BluetoothFindRadioClose failed: %lu\n", GetLastError() ); + ok( BluetoothFindRadioClose( find ), "BluetoothFindRadioClose failed: %lu\n", GetLastError() ); }
void test_BluetoothFindRadioClose( void ) @@ -112,7 +112,7 @@ void test_BluetoothFindRadioClose( void ) SetLastError( 0xdeadbeef ); ok( !BluetoothFindRadioClose( NULL ), "Expected BluetoothFindRadioClose to return FALSE\n" ); err = GetLastError(); - todo_wine ok( err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE ); + ok( err == ERROR_INVALID_HANDLE, "%lu != %d\n", err, ERROR_INVALID_HANDLE ); }
START_TEST( radio )