Skip to content

Instantly share code, notes, and snippets.

@smourier
Created August 1, 2017 06:51
Show Gist options
  • Save smourier/6f632f37b1cfda085421b079f52d2301 to your computer and use it in GitHub Desktop.
Save smourier/6f632f37b1cfda085421b079f52d2301 to your computer and use it in GitHub Desktop.
ScanBluetoothPorts
using System;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
ScanBluetoothPorts();
}
static void ScanBluetoothPorts()
{
var p = new BLUETOOTH_DEVICE_SEARCH_PARAMS()
{
fReturnAuthenticated = true,
fReturnConnected = true,
fReturnUnknown = true,
fReturnRemembered = true,
dwSize = Marshal.SizeOf<BLUETOOTH_DEVICE_SEARCH_PARAMS>(),
cTimeoutMultiplier = 10
};
var info = new BLUETOOTH_DEVICE_INFO()
{
dwSize = Marshal.SizeOf<BLUETOOTH_DEVICE_INFO>()
};
int i = 0;
var ptr = BluetoothFindFirstDevice(ref p, ref info);
while (ptr != IntPtr.Zero)
{
Console.WriteLine(GetLocalServicePortName(i) + " -> " + info.szName);
info = new BLUETOOTH_DEVICE_INFO();
if (!BluetoothFindNextDevice(ptr, ref info))
{
BluetoothFindDeviceClose(ptr);
break;
}
i++;
}
}
static string GetLocalServicePortName(int index)
{
using (var key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\LocalServices\" + SerialPortServiceClass_UUID.ToString("B") + @"\" + index, false))
{
int instanceId = (int)key.GetValue("PnpInstance");
var sb = new StringBuilder(256);
ulong address = 0;
int err = BluetoothGetServicePnpInstance(ref address, SerialPortServiceClass_UUID, instanceId, sb, sb.Capacity, out IntPtr instanceKey);
if (err == 0)
{
using (var rk = RegistryKey.FromHandle(new SafeRegistryHandle(instanceKey, true)))
{
return rk.GetValue("PortName") as string;
}
}
}
return null;
}
// officially undocumented, but check https://download.microsoft.com/download/9/3/5/935520EC-D9E2-413E-BEA7-0B865A79B18C/Basics%20of%20Secure%20Design%20Development%20Test.ppsx
// slide #62
[DllImport("BluetoothApis.dll", SetLastError = true)]
private static extern int BluetoothGetServicePnpInstance(ref ulong pDeviceAddress, [MarshalAs(UnmanagedType.LPStruct)] Guid ServiceGuid, int InstanceId, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder buffer, int BufferSize, out IntPtr phKey);
[DllImport("BluetoothApis.dll", SetLastError = true)]
private static extern IntPtr BluetoothFindFirstDevice(ref BLUETOOTH_DEVICE_SEARCH_PARAMS pbtsp, ref BLUETOOTH_DEVICE_INFO pbtdi);
[DllImport("BluetoothApis.dll", SetLastError = true)]
private static extern bool BluetoothFindNextDevice(IntPtr hFind, ref BLUETOOTH_DEVICE_INFO pbtdi);
[DllImport("BluetoothApis.dll", SetLastError = true)]
private static extern bool BluetoothFindDeviceClose(IntPtr hFind);
private static readonly Guid SerialPortServiceClass_UUID = new Guid("00001101-0000-1000-8000-00805F9B34FB");
private const int BLUETOOTH_MAX_NAME_SIZE = 248;
[StructLayout(LayoutKind.Sequential)]
private struct BLUETOOTH_DEVICE_SEARCH_PARAMS
{
public int dwSize;
public bool fReturnAuthenticated;
public bool fReturnRemembered;
public bool fReturnUnknown;
public bool fReturnConnected;
public bool fIssueInquiry;
public byte cTimeoutMultiplier;
public IntPtr hRadio;
}
[StructLayout(LayoutKind.Sequential)]
private struct SYSTEMTIME
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct BLUETOOTH_DEVICE_INFO
{
public int dwSize;
public ulong Address;
public int ulClassofDevice;
public bool fConnected;
public bool fRemembered;
public bool fAuthenticated;
public SYSTEMTIME stLastSeen;
public SYSTEMTIME stLastUsed;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BLUETOOTH_MAX_NAME_SIZE)]
public string szName;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment