⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 蓝牙虚拟串口.cxx

📁 这些文件包括蓝牙虚拟串口与打印机程序实例
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>

#include <ras.h>

#include "ndis.h"
#include "nuiouser.h"

#include <svsutil.hxx>

#include <bt_api.h>
#include <bt_buffer.h>
#include <bt_ddi.h>

#include "btenum.hxx"

#include "bthid.h"

#define HID_CLIENT_REGKEY_SZ       _T("Software\\Microsoft\\Bluetooth\\Hid\\Hid_Class")
#define HID_REGKEY_SZ              _T("Software\\Microsoft\\Bluetooth\\Hid\\Instance")

// RAS
typedef DWORD (RASAPI * p_RasSetEntryDialParams) (LPWSTR lpszPhoneBook, LPRASDIALPARAMS lpRasDialParams, BOOL fRemovePassword);
typedef DWORD (RASAPI * p_RasGetEntryProperties) (LPWSTR lpszPhoneBook, LPWSTR szEntry, LPRASENTRY lpEntry, LPDWORD lpdwEntrySize, LPBYTE lpb, LPDWORD lpdwSize);
typedef DWORD (RASAPI * p_RasSetEntryProperties) (LPWSTR lpszPhoneBook, LPWSTR szEntry, LPRASENTRY lpEntry, DWORD dwEntrySize, LPBYTE lpb, DWORD dwSize);
typedef DWORD (RASAPI * p_RasDeleteEntry) (LPWSTR lpszPhonebook, LPWSTR lpszEntry);

static LPWSTR gszKeyNames[BTENUM_CLASSES + 1] = {L"modem", L"printer", L"lan_access", L"file_trans", L"OBEX", L"Headset", L"ActiveSync", L"HID", L"PAN", L"Handsfree", L"UNKNOWN"};
static int    gimtu[BTENUM_CLASSES + 1]       = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
static int    gauth[BTENUM_CLASSES + 1];
static int    gencr[BTENUM_CLASSES + 1];
static int    gidefault_mtu = 0;
static int    gidefault_auth = 0;
static int    gidefault_encr = 0;

static WCHAR gszAdapterName[50];

static p_RasGetEntryProperties g_pfnRasGetEntryProperties;
static p_RasSetEntryProperties g_pfnRasSetEntryProperties;
static p_RasSetEntryDialParams g_pfnRasSetEntryDialParams;
static p_RasDeleteEntry g_pfnRasDeleteEntry;

static int GetBA (WCHAR *pp, BT_ADDR *pba) {
	*pba = 0;

	while (*pp == ' ')
		++pp;

	for (int i = 0 ; i < 12 ; ++i, ++pp) {
		if (! iswxdigit (*pp))
			return FALSE;

		int c = *pp;
		if (c >= 'a')
			c = c - 'a' + 0xa;
		else if (c >= 'A')
			c = c - 'A' + 0xa;
		else c = c - '0';

		if ((c < 0) || (c > 16))
			return FALSE;

		*pba = *pba * 16 + c;
	}

	if ((*pp != ' ') && (*pp != '\0'))
		return FALSE;

	return TRUE;
}

static BOOL HexStringToDword(WCHAR *lpsz, DWORD &Value, int cDigits, WCHAR chDelim) {
    Value = 0;
    for (int Count = 0; Count < cDigits; Count++, lpsz++) {
        if (*lpsz >= '0' && *lpsz <= '9')
            Value = (Value << 4) + *lpsz - '0';
        else if (*lpsz >= 'A' && *lpsz <= 'F')
            Value = (Value << 4) + *lpsz - 'A' + 10;
        else if (*lpsz >= 'a' && *lpsz <= 'f')
            Value = (Value << 4) + *lpsz - 'a' + 10;
        else
            return(FALSE);
    }

    if (chDelim != 0)
        return *lpsz++ == chDelim;
    else
        return TRUE;
}

static int StrToGUID (WCHAR *szStr, GUID *pguid) {
    WCHAR *lpsz = szStr;
    DWORD dw;

    if (*lpsz++ != '{')
        return FALSE;

    if (!HexStringToDword(lpsz, pguid->Data1, sizeof(DWORD)*2, '-'))
        return FALSE;

    if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
        return FALSE;

    pguid->Data2 = (WORD)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
        return FALSE;

    pguid->Data3 = (WORD)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[0] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
        return FALSE;

    pguid->Data4[1] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[2] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[3] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[4] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[5] = (BYTE)dw;

    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[6] = (BYTE)dw;
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[7] = (BYTE)dw;

    if (*lpsz++ != '}')
        return FALSE;

    if (*lpsz++ != '\0')
        return FALSE;

    return TRUE;
}

static int SignalPAN (void) {
    HANDLE hEvent = OpenEvent (EVENT_ALL_ACCESS, FALSE, BTH_NAMEDEVENT_PAN_REFRESH);
    if (! hEvent)
        return FALSE;

    SetEvent (hEvent);
    CloseHandle (hEvent);

    return TRUE;
}

static void DeactivatePanDevice (BTDEV *pbtDevice) {
    WCHAR szRegKey[_MAX_PATH];
    wsprintf (szRegKey, L"COMM\\%s\\Associations\\%04x%08x", gszAdapterName, GET_NAP(pbtDevice->b), GET_SAP(pbtDevice->b));
    RegDeleteKey (HKEY_LOCAL_MACHINE, szRegKey);

    HANDLE h = CreateFile(
                    NDISUIO_DEVICE_NAME,                                //    Object name.
                    0x00,                                    //    Desired access.
                    0x00,                                            //    Share Mode.
                    NULL,                                            //    Security Attr
                    OPEN_EXISTING,                                    //    Creation Disposition.
                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,    //    Flag and Attributes..
                    (HANDLE)INVALID_HANDLE_VALUE); 
    if (INVALID_HANDLE_VALUE != h) {
        DWORD dwWritten = 0;
        
        struct {
            NDISUIO_SET_OID SetOid;
            unsigned char   uca[64];
        } NdisUioSetOid;

        NdisUioSetOid.SetOid.Oid = OID_PAN_DISCONNECT;
        NdisUioSetOid.SetOid.ptcDeviceName = L"BTPAN1";
        memcpy(&NdisUioSetOid.SetOid.Data, &pbtDevice->b, sizeof(BD_ADDR));

        DeviceIoControl(
            h,
            IOCTL_NDISUIO_SET_OID_VALUE,
            &NdisUioSetOid,
            sizeof(NdisUioSetOid),
            NULL,
            0,
            &dwWritten,
            NULL);

        CloseHandle(h);
    }
}

static int ActivatePanDevice (BTDEV *pbtDevice, int fFirstTime) {
    WCHAR szRegKey[_MAX_PATH];
    wsprintf (szRegKey, L"COMM\\%s\\Associations\\%04x%08x", gszAdapterName, GET_NAP(pbtDevice->b), GET_SAP(pbtDevice->b));

    DWORD dwDisp;
    HKEY hk;
    if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, szRegKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) {
        WCHAR szAddr[40];
        wsprintf (szAddr, L"%04x%08x", GET_NAP(pbtDevice->b), GET_SAP(pbtDevice->b));

        RegSetValueEx (hk, L"Address", 0, REG_SZ, (BYTE *)szAddr, sizeof(WCHAR) * (wcslen(szAddr) + 1));

        WCHAR szServiceId[60];
        wsprintf (szServiceId, L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
                            pbtDevice->service_id.Data1, pbtDevice->service_id.Data2, pbtDevice->service_id.Data3,
                            pbtDevice->service_id.Data4[0], pbtDevice->service_id.Data4[1], pbtDevice->service_id.Data4[2], pbtDevice->service_id.Data4[3], 
                            pbtDevice->service_id.Data4[4], pbtDevice->service_id.Data4[5], pbtDevice->service_id.Data4[6], pbtDevice->service_id.Data4[7]); 
        RegSetValueEx (hk, L"ServiceId", 0, REG_SZ, (BYTE*)szServiceId, (wcslen(szServiceId) + 1) * sizeof(WCHAR));

        WCHAR szSSID[50];
        wsprintf (szSSID, L"PAN@%04x%08x", GET_NAP(pbtDevice->b), GET_SAP(pbtDevice->b));
        RegSetValueEx (hk, L"SSID", 0, REG_SZ, (BYTE*)szSSID, (wcslen(szSSID) + 1) * sizeof(WCHAR));

        DWORD dw = 1;
        RegSetValueEx (hk, L"Priority", 0, REG_DWORD, (BYTE*)&dw, sizeof(dw));

        RegCloseKey (hk);

        HANDLE h = CreateFile(
                        NDISUIO_DEVICE_NAME,                                //    Object name.
                        0x00,                                    //    Desired access.
                        0x00,                                            //    Share Mode.
                        NULL,                                            //    Security Attr
                        OPEN_EXISTING,                                    //    Creation Disposition.
                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,    //    Flag and Attributes..
                        (HANDLE)INVALID_HANDLE_VALUE); 
        if (INVALID_HANDLE_VALUE != h) {
            DWORD dwWritten;

            struct {
                NDISUIO_SET_OID SetOid;
                unsigned char   uca[64];
            } NdisUioSetOid;

            // --- Set Authentication for the connection
            
            NdisUioSetOid.SetOid.Oid = OID_PAN_AUTHENTICATE;
            NdisUioSetOid.SetOid.ptcDeviceName = L"BTPAN1";
            *(PDWORD)NdisUioSetOid.SetOid.Data = pbtDevice->fAuth;

            dwWritten = 0;
            if (! DeviceIoControl(
                        h,
                        IOCTL_NDISUIO_SET_OID_VALUE,
                        &NdisUioSetOid,
                        sizeof(NdisUioSetOid),
                        NULL,
                        0,
                        &dwWritten,
                        NULL)) {
                CloseHandle(h);                
                return FALSE;                         
            }

            // --- Set Encryption for the connection

            NdisUioSetOid.SetOid.Oid = OID_PAN_ENCRYPT;
            NdisUioSetOid.SetOid.ptcDeviceName = L"BTPAN1";
            *(PDWORD)NdisUioSetOid.SetOid.Data = pbtDevice->fEncrypt;

            dwWritten = 0;
            if (! DeviceIoControl(
                        h,
                        IOCTL_NDISUIO_SET_OID_VALUE,
                        &NdisUioSetOid,
                        sizeof(NdisUioSetOid),
                        NULL,
                        0,
                        &dwWritten,
                        NULL)) {
                CloseHandle(h);                
                return FALSE; 
            }
            

            // --- Connect

            NdisUioSetOid.SetOid.Oid = OID_PAN_CONNECT;
            NdisUioSetOid.SetOid.ptcDeviceName = L"BTPAN1";
            memcpy(&NdisUioSetOid.SetOid.Data, &pbtDevice->b, sizeof(BD_ADDR));
            memcpy((PBYTE)NdisUioSetOid.SetOid.Data + sizeof(BD_ADDR), &pbtDevice->service_id, sizeof(GUID));

            dwWritten = 0;
            if (! DeviceIoControl(
                        h,
                        IOCTL_NDISUIO_SET_OID_VALUE,
                        &NdisUioSetOid,
                        sizeof(NdisUioSetOid),
                        NULL,
                        0,
                        &dwWritten,
                        NULL)) {
                CloseHandle(h);                
                return FALSE; 
            }

            CloseHandle(h);
            return TRUE;
        }    
    }

    return FALSE;
}

static void BthEnumInit (void) {
	static int fInited = FALSE;

	if (fInited)
		return;

	fInited = TRUE;

	HINSTANCE hCoreDll = LoadLibrary (L"coredll.dll");

	if(hCoreDll) {
		g_pfnRasGetEntryProperties = (p_RasGetEntryProperties)GetProcAddress (hCoreDll, L"RasGetEntryProperties");
		g_pfnRasSetEntryProperties = (p_RasSetEntryProperties)GetProcAddress (hCoreDll, L"RasSetEntryProperties");
		g_pfnRasSetEntryDialParams = (p_RasSetEntryDialParams)GetProcAddress (hCoreDll, L"RasSetEntryDialParams");
		g_pfnRasDeleteEntry        = (p_RasDeleteEntry)       GetProcAddress (hCoreDll, L"RasDeleteEntry");
	}

	if ((! g_pfnRasGetEntryProperties) || (! g_pfnRasSetEntryProperties) || (! g_pfnRasSetEntryDialParams) || (! g_pfnRasDeleteEntry)) {
		g_pfnRasGetEntryProperties = NULL;
		g_pfnRasSetEntryProperties = NULL;
		g_pfnRasSetEntryDialParams = NULL;
		g_pfnRasDeleteEntry        = NULL;
	}

	memset (gauth, 0, sizeof(gauth));
	memset (gencr, 0, sizeof(gencr));

	HKEY hk;
	if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\device", 0, KEY_READ, &hk))
		return;

	int iNumDevices = 0;
	DWORD dwSize = sizeof (gidefault_mtu);

	DWORD dwType;	
	if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"DefaultMtu", NULL, &dwType, (BYTE *)&gidefault_mtu, &dwSize)) ||
			(dwType != REG_DWORD) || (dwSize != sizeof(gidefault_mtu)))
		gidefault_mtu = 0;

	dwSize = sizeof (gidefault_auth);

	if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"DefaultAuth", NULL, &dwType, (BYTE *)&gidefault_auth, &dwSize)) ||
			(dwType != REG_DWORD) || (dwSize != sizeof(gidefault_auth)))
		gidefault_auth = 0;

	dwSize = sizeof (gidefault_encr);

	if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"DefaultEncrypt", NULL, &dwType, (BYTE *)&gidefault_encr, &dwSize)) ||
			(dwType != REG_DWORD) || (dwSize != sizeof(gidefault_encr)))
		gidefault_encr = 0;

	for (int i = 0; i < BTENUM_CLASSES + 1; ++i) {
		HKEY hkdetail;
		if (ERROR_SUCCESS == RegOpenKeyEx (hk, gszKeyNames[i], 0,  KEY_ALL_ACCESS , &hkdetail)) {
			dwSize = sizeof (gimtu[i]);

			if ((ERROR_SUCCESS != RegQueryValueEx (hkdetail, L"DefaultMtu", NULL, &dwType, (BYTE *)&gimtu[i], &dwSize)) ||
				(dwType != REG_DWORD) || (dwSize != sizeof(gimtu[i])))
				gimtu[i] = -1;

			dwSize = sizeof (gauth[i]);
			if ((ERROR_SUCCESS != RegQueryValueEx (hkdetail, L"DefaultAuth", NULL, &dwType, (BYTE *)&gauth[i], &dwSize)) ||
				(dwType != REG_DWORD) || (dwSize != sizeof(gauth[i])))
				gauth[i] = 0;

			if (gauth[i])
				gauth[i] = TRUE;

			dwSize = sizeof (gencr[i]);
			if ((ERROR_SUCCESS != RegQueryValueEx (hkdetail, L"DefaultEncrypt", NULL, &dwType, (BYTE *)&gencr[i], &dwSize)) ||
				(dwType != REG_DWORD) || (dwSize != sizeof(gencr[i])))
				gencr[i] = 0;

			if (gencr[i])
				gencr[i] = TRUE;

			if (i == BTENUM_DEVICE_PAN) {
				dwSize = sizeof (gszAdapterName);
				if ((ERROR_SUCCESS != RegQueryValueEx (hkdetail, L"AdapterName", NULL, &dwType, (BYTE *)gszAdapterName, &dwSize)) ||
					(dwType != REG_SZ) || (dwSize >= sizeof(gszAdapterName)))
					gszAdapterName[0] = '\0';
			}

			RegCloseKey (hkdetail);	
		}
	}

	RegCloseKey (hk);
}

int BthEnumDevices (void *pContext, BthEnumCallback pCallback) {
	BthEnumInit ();

	HKEY hk;
	if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\device", 0, KEY_READ, &hk))
		return 0;

	int iNumDevices = 0;

	for (int i = 0; i < BTENUM_CLASSES + 1; ++i) {
		HKEY hkdetail;
		if (ERROR_SUCCESS == RegOpenKeyEx (hk, gszKeyNames[i], 0,  KEY_ENUMERATE_SUB_KEYS , &hkdetail)) {
			WCHAR szTemp1[50];
			szTemp1[0] = '\0';

			DWORD dwSizeKey = sizeof(szTemp1)/sizeof(WCHAR);

			int iContinue = TRUE;
			for (int j = 0; iContinue && (ERROR_SUCCESS == RegEnumKeyEx(hkdetail, j, szTemp1, &dwSizeKey, NULL, NULL, 0, NULL)); ++j) {

				BT_ADDR b;

				HKEY hkdevice;
				if (GetBA(szTemp1, &b) && (ERROR_SUCCESS == RegOpenKeyEx (hkdetail, szTemp1, 0, KEY_READ, &hkdevice))) {
					BTDEV bdev(b, i < BTENUM_CLASSES ? i : -1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -