Skip to content

Instantly share code, notes, and snippets.

@jordanbtucker
Last active October 16, 2019 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jordanbtucker/eeed0e7c8c658279cc054cd6aeb3a395 to your computer and use it in GitHub Desktop.
Save jordanbtucker/eeed0e7c8c658279cc054cd6aeb3a395 to your computer and use it in GitHub Desktop.
#include "pch.h"
#include <windows.h>
#include <bthsdpdef.h>
#include <bthdef.h>
#include <BluetoothAPIs.h>
#include <strsafe.h>
#include <tchar.h>
#pragma comment(lib, "Bthprops.lib")
DWORD ShowErrorCode(const _TCHAR * msg, DWORD dw)
{
// Retrieve the system error message for the last-error code
_TCHAR * lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL
);
_tprintf(_T("%s: %s"), msg, lpMsgBuf);
LocalFree(lpMsgBuf);
return dw;
}
_TCHAR * FormatBTAddress(BLUETOOTH_ADDRESS address)
{
static _TCHAR ret[20];
_stprintf_s(ret, _T("%02x:%02x:%02x:%02x:%02x:%02x"),
address.rgBytes[5],
address.rgBytes[4],
address.rgBytes[3],
address.rgBytes[2],
address.rgBytes[1],
address.rgBytes[0]
);
return ret;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hRadios[256];
int nRadios;
int nPaired = 0;
///////////////////////////////////////////////////////////////////////
// Enumerate BT radios
///////////////////////////////////////////////////////////////////////
{
HBLUETOOTH_RADIO_FIND hFindRadio;
BLUETOOTH_FIND_RADIO_PARAMS radioParam;
_tprintf(_T("Enumerating radios...\n"));
radioParam.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS);
nRadios = 0;
hFindRadio = BluetoothFindFirstRadio(&radioParam, &hRadios[nRadios++]);
if (hFindRadio)
{
while (BluetoothFindNextRadio(&radioParam, &hRadios[nRadios++]));
BluetoothFindRadioClose(hFindRadio);
}
else
{
ShowErrorCode(_T("Error enumerating radios"), GetLastError());
return (1);
}
nRadios--;
_tprintf(_T("Found %d radios\n"), nRadios);
}
///////////////////////////////////////////////////////////////////////
// Keep looping until we pair with a Wii device
///////////////////////////////////////////////////////////////////////
while (nPaired == 0)
{
int radio;
for (radio = 0; radio < nRadios; radio++)
{
BLUETOOTH_RADIO_INFO radioInfo;
HBLUETOOTH_DEVICE_FIND hFind;
BLUETOOTH_DEVICE_INFO btdi;
BLUETOOTH_DEVICE_SEARCH_PARAMS srch;
radioInfo.dwSize = sizeof(radioInfo);
btdi.dwSize = sizeof(btdi);
srch.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
ShowErrorCode(_T("BluetoothGetRadioInfo"), BluetoothGetRadioInfo(hRadios[radio], &radioInfo));
_tprintf(_T("Radio %d: %ls %s\n"),
radio,
radioInfo.szName,
FormatBTAddress(radioInfo.address)
);
srch.fReturnAuthenticated = TRUE;
srch.fReturnRemembered = TRUE;
srch.fReturnConnected = TRUE;
srch.fReturnUnknown = TRUE;
srch.fIssueInquiry = TRUE;
srch.cTimeoutMultiplier = 2;
srch.hRadio = hRadios[radio];
_tprintf(_T("Scanning...\n"));
hFind = BluetoothFindFirstDevice(&srch, &btdi);
if (hFind == NULL)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
_tprintf(_T("No bluetooth devices found.\n"));
}
else
{
ShowErrorCode(_T("Error enumerating devices"), GetLastError());
return (1);
}
}
else
{
do
{
_tprintf(_T("Found: %s: %s\n"), btdi.szName, FormatBTAddress(btdi.Address));
if (!wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || !wcscmp(btdi.szName, L"Nintendo RVL-CNT-01") || !wcscmp(btdi.szName, L"Nintendo RVL-CNT-01-TR"))
{
WCHAR pass[6];
DWORD pcServices = 16;
GUID guids[16];
BOOL error = FALSE;
if (!error)
{
if (btdi.fRemembered)
{
// Make Windows forget pairing
if (ShowErrorCode(_T("BluetoothRemoveDevice"), BluetoothRemoveDevice(&btdi.Address)) != ERROR_SUCCESS)
error = TRUE;
}
}
// MAC address is passphrase
pass[0] = btdi.Address.rgBytes[0];
pass[1] = btdi.Address.rgBytes[1];
pass[2] = btdi.Address.rgBytes[2];
pass[3] = btdi.Address.rgBytes[3];
pass[4] = btdi.Address.rgBytes[4];
pass[5] = btdi.Address.rgBytes[5];
if (!error)
{
// Pair with Wii device
#pragma warning(disable: 4995)
if (ShowErrorCode(_T("BluetoothAuthenticateDevice"), BluetoothAuthenticateDevice(NULL, hRadios[radio], &btdi, pass, 6)) != ERROR_SUCCESS)
error = TRUE;
}
if (!error)
{
// If this is not done, the Wii device will not remember the pairing
if (ShowErrorCode(_T("BluetoothEnumerateInstalledServices"), BluetoothEnumerateInstalledServices(hRadios[radio], &btdi, &pcServices, guids)) != ERROR_SUCCESS)
error = TRUE;
}
if (!error)
{
// Activate service
if (ShowErrorCode(_T("BluetoothSetServiceState"), BluetoothSetServiceState(hRadios[radio], &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE)) != ERROR_SUCCESS)
error = TRUE;
}
if (!error)
{
nPaired++;
}
} // if (!wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || !wcscmp(btdi.szName, L"Nintendo RVL-CNT-01"))
} while (BluetoothFindNextDevice(hFind, &btdi));
} // if (hFind == NULL)
} // for (radio = 0; radio < nRadios; radio++)
Sleep(1000);
}
///////////////////////////////////////////////////////////////////////
// Clean up
///////////////////////////////////////////////////////////////////////
{
int radio;
for (radio = 0; radio < nRadios; radio++)
{
CloseHandle(hRadios[radio]);
}
}
_tprintf(_T("=============================================\n"));
_tprintf(_T("%d Wii devices paired\n"), nPaired);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment