Search code examples
c#.netbluetoothpinvokedeviceiocontrol

How to disconnect a bluetooth device from C# .Net in Win7


I would like to disconnect a bluetooth device from my c# .Net application, that runs on Win 7 x64.

I Know that MS provides very little functionnality reguarding BT on .Net.

I've searched 32feet.Net, and found how to connect, discover, get information, ... but nothing about disconnecting (Have I missed something ?).

Then, I found on Msdn IOCTL_BTH_DISCONNECT_DEVICE. The problem is that I can't understand how to call it. It Seems that I shoud use DeviceIOControl with Platform Invoke, but I'm afraid that I haven't got enough .Net skills to build this by myself.

Here is where I am at the moment :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.IO;

namespace BtDisco
{
    class Program
    {
        const int IOCTL_BTH_DISCONNECT_DEVICE = 0x41000c;

        [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
        public static extern bool DeviceIoControl(
            Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
            uint dwIoControlCode,
            [MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer,
            uint nInBufferSize,
            [MarshalAs(UnmanagedType.AsAny)] [Out] object OutBuffer,
            uint nOutBufferSize,
            ref uint pBytesReturned,
            [In] ref System.Threading.NativeOverlapped Overlapped
            );

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern SafeFileHandle CreateFile(
            string lpFileName,
            [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
            [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
            IntPtr lpSecurityAttributes,
            [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
            [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
            IntPtr hTemplateFile);


        static void Main(string[] args)
        {
            //http://msdn.microsoft.com/en-us/library/windows/desktop/aa363216(v=vs.85).aspx
            //hDev = Use CreateFile
            SafeFileHandle _hdev = CreateFileR(...);

            DeviceIoControl(hDev, IOCTL_BTH_DISCONNECT_DEVICE, char[] btAddr, btAddr.Length(), result, result.Length(), ref getCnt, IntPtr.Zero);
        }
    }
}

Could someone be kind enough to help me complete this ?


Solution

  • Finally, I have got it working by myself !

    I searched a bit more in the InTheHand.Net code and finally understood how to make it !

    Here is some working code (you will need InTheHand.Net if you want to use it):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Text;
    using InTheHand.Net;
    using InTheHand.Net.Bluetooth;
    using System.Runtime.InteropServices;
    
    namespace BTDisco2
    {
        class Program
        {
            const int IOCTL_BTH_DISCONNECT_DEVICE = 0x41000c;
            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            internal static extern bool DeviceIoControl(
            IntPtr hDevice,
            uint dwIoControlCode,
            ref long InBuffer,
            int nInBufferSize,
            IntPtr OutBuffer,
            int nOutBufferSize,
            out int pBytesReturned,
            IntPtr lpOverlapped);
    
            static void Main(string[] args)
            {
                var r = BluetoothRadio.PrimaryRadio;
                var h = r.Handle;
                long btAddr = BluetoothAddress.Parse("00:1b:3d:0d:ac:31").ToInt64();
                int bytesReturned = 0;
                var success = DeviceIoControl(h,
                IOCTL_BTH_DISCONNECT_DEVICE,
                ref btAddr, 8,
                IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
    
                if (!success)
                {
                    int gle = Marshal.GetLastWin32Error();
                    Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "failure: {0} = 0x{0:X}.", gle));
                }
                else
                {
                    Console.WriteLine("Success !");
                }
                while (!Console.KeyAvailable) System.Threading.Thread.Sleep(200);
            }
        }
    }