Created
August 1, 2017 06:51
-
-
Save smourier/6f632f37b1cfda085421b079f52d2301 to your computer and use it in GitHub Desktop.
ScanBluetoothPorts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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