Khwaab Dave
Khwaab Dave

Reputation: 43

Windows 8.1 Bluetooth LE can't get device interface

I am trying to retrieve the name and handle of all paired bluetooth devices on a windows 8.1 machine.

I can get the name, but SetupDiEnumDeviceInterfaces always returns false. I read somewhere that I need to include DIGCF_DEVICEINTERFACE in the SetupDIGetClassDevs function, but it still doesn't work.

Here is my code:

HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;

// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(
    &GUID_DEVCLASS_BLUETOOTH,
    0, 0, DIGCF_PRESENT);

if (hDevInfo == INVALID_HANDLE_VALUE)
{
    // Insert error handling here.
    return;//1;
}

// Enumerate through all devices in Set.

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i,
    &DeviceInfoData); i++)
{
    DWORD DataT;
    LPTSTR buffer = NULL;
    DWORD buffersize = 0;

    while (!SetupDiGetDeviceRegistryProperty(
        hDevInfo,
        &DeviceInfoData,
        SPDRP_FRIENDLYNAME,
        &DataT,
        (PBYTE)buffer,
        buffersize,
        &buffersize))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
            // Change the buffer size.
            if (buffer) delete(buffer);
            // Double the size to avoid problems on
            // W2k MBCS systems per KB 888609.
            buffer = new wchar_t[buffersize * 2];
        }
        else{
            // Insert error handling here.
            break;
        }
    }
    HWND deviceList = GetDlgItem(GetActiveWindow(), LIST_BOX);
    if (deviceList && buffersize > 0)
    {
        SendMessage(deviceList, LB_ADDSTRING, 0, (LPARAM)buffer);
    }
    if (buffer) delete(buffer);

   // WORKS UNTIL HERE BUT ENUMERATING THROUGH INTERFACES ALWAYS RETURNS FALSE

    SP_DEVICE_INTERFACE_DATA devIntData;
    HDEVINFO hDevInfo2 = SetupDiGetClassDevs(
        &GUID_DEVCLASS_BLUETOOTH,
        0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (SetupDiEnumDeviceInterfaces(hDevInfo2, 
        &DeviceInfoData, 
        &GUID_BLUETOOTHLE_DEVICE_INTERFACE, 
        i, 
        &devIntData))
    {
        DWORD reqSize;
        SP_DEVINFO_DATA buffer;
        while (SetupDiGetDeviceInterfaceDetail(hDevInfo2,
            &devIntData,
            NULL,
            NULL,
            &reqSize,
            &buffer))
        {
            OutputDebugString(L"DeviceINTERFACE");
        }
    }
}

I have tried putting the device enumeration outside of the name enumeration loop, but it still returns false also I would like the handle and the name to be associated so I would like them to be found in the same context.

If anyone has any sample code on a full bluetooth LE workflow in windows 8.1 (find name, find handles, find services, find characteristics, write to characteristics) and could share that with me I would greatly appreciate it. Thanks.

Upvotes: 1

Views: 1968

Answers (1)

Khwaab Dave
Khwaab Dave

Reputation: 43

Figured it out, wasn't allocating memory for my buffers properly.

EDIT: Adding code

HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(
    &GUID_DEVCLASS_BLUETOOTH,
    0, 0, DIGCF_PRESENT);

if (hDevInfo == INVALID_HANDLE_VALUE)
{
    // Insert error handling here.
    return;//1;
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i,
    &DeviceInfoData); i++)
{
    DWORD DataT;
    LPTSTR buffer = NULL;
    DWORD buffersize = 0;
    //This loop gets the name with SPDRP_FRIENDLYNAME
    while (!SetupDiGetDeviceRegistryProperty(
        hDevInfo,
        &DeviceInfoData,
        SPDRP_FRIENDLYNAME,
        &DataT,
        (PBYTE)buffer,
        buffersize,
        &buffersize))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
            // Change the buffer size.
            if (buffer) delete(buffer);
            // Double the size to avoid problems on
            // W2k MBCS systems per KB 888609.
            buffer = new wchar_t[buffersize * 2];
        }
        else{
            // Insert error handling here.
            break;
        }
    }
    DWORD DataT2;
    LPTSTR buffer2 = NULL;
    DWORD buffersize2 = 0;
    //This Loop gets the Bluetooth Address with SPDRP_HARDWAREID
    // NOTE: there is more information than just the address you will have
    // to do some string manipulation to have just the address
    while (!SetupDiGetDeviceRegistryProperty(
        hDevInfo,
        &DeviceInfoData,
        SPDRP_HARDWAREID,
        &DataT2,
        (PBYTE)buffer2,
        buffersize2,
        &buffersize2))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
            // Change the buffer size.
            if (buffer2) delete(buffer2);
            // Double the size to avoid problems on
            // W2k MBCS systems per KB 888609.
            buffer2 = new wchar_t[buffersize2 * 2];
        }
        else{
            // Insert error handling here.
            break;
        }
    }
    if (buffersize > 0)
    {
        //do what you need with the info
        //name is in buffer
        //address is in buffer2
    }
}

Next i get the handles in a different function because you need to enumerate over Interfaces and not info with SetupDiEnumDeviceInterfaces instead of SetupDiEnumDeviceInfo in the for loop Using the bluetooth address I match the two and store appropriately

Upvotes: 2

Related Questions