📄 蓝牙虚拟串口.cxx
字号:
DWORD dwSize = sizeof(bdev.szDeviceName);
DWORD dwType = 0;
if ((ERROR_SUCCESS != RegQueryValueEx (hkdevice, L"name", NULL, &dwType, (BYTE *)bdev.szDeviceName, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(bdev.szDeviceName)))
bdev.szDeviceName[0] = '\0';
dwSize = sizeof(bdev.szPortName);
if ((ERROR_SUCCESS != RegQueryValueEx (hkdevice, L"port_name", NULL, &dwType, (BYTE *)bdev.szPortName, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(bdev.szPortName)))
bdev.szPortName[0] = '\0';
DWORD dw = 0;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"channel", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && dw)
bdev.ucChannel = (unsigned char)dw;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"hid_subclass", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
bdev.dwHidDevClass = dw;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"handle", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
bdev.hDevHandle = (HANDLE)dw;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"active", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)) && dw)
bdev.fActive = TRUE;
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"auth", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
bdev.fAuth = (dw != 0);
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"encrypt", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
bdev.fEncrypt = (dw != 0);
dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"mtu", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
bdev.imtu = dw;
WCHAR szServiceId[64];
dwSize = sizeof(szServiceId);
GUID g;
if ((ERROR_SUCCESS == RegQueryValueEx (hkdevice, L"service_id", NULL, &dwType, (BYTE *)szServiceId, &dwSize)) &&
(dwType == REG_SZ) && (dwSize < sizeof(szServiceId)) && StrToGUID(szServiceId, &g))
bdev.service_id = g;
dwType = 0;
dwSize = 0;
DWORD dwRes = RegQueryValueEx (hkdevice, L"sdp_record", NULL, &dwType, NULL, &dwSize);
if ((dwRes == ERROR_SUCCESS) && (dwType == REG_BINARY)) {
unsigned char *psdp = (unsigned char *)LocalAlloc(LMEM_FIXED, dwSize);
if (psdp)
dwRes = RegQueryValueEx (hkdevice, L"sdp_record", NULL, &dwType, psdp, &dwSize);
if (dwRes == ERROR_SUCCESS) {
bdev.psdp = psdp;
bdev.csdp = dwSize;
} else
LocalFree (psdp);
}
bdev.fTrusted = TRUE;
RegCloseKey (hkdevice);
++iNumDevices;
iContinue = pCallback (pContext, &bdev);
}
dwSizeKey = sizeof(szTemp1)/sizeof(WCHAR);
}
RegCloseKey (hkdetail);
}
}
RegCloseKey (hk);
return 0;
}
int BthEnumUpdate (BTDEV* bt) {
BthEnumInit ();
HKEY hkdevice;
DWORD dwDisp;
WCHAR szKey[2*_MAX_PATH];
wsprintf (szKey, L"software\\microsoft\\bluetooth\\device\\%s\\%04x%08x", bt->iDeviceClass != -1 ? gszKeyNames[bt->iDeviceClass] : L"UNKNOWN", GET_NAP(bt->b), GET_SAP(bt->b));
if(ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, szKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkdevice, &dwDisp)){
RegSetValueEx (hkdevice, L"name", 0, REG_SZ, (BYTE *)bt->szDeviceName, (wcslen (bt->szDeviceName) + 1) * sizeof(WCHAR));
RegSetValueEx (hkdevice, L"port_name", 0, REG_SZ, (BYTE *)bt->szPortName, (wcslen (bt->szPortName) + 1) * sizeof(WCHAR));
DWORD dw = bt->ucChannel;
RegSetValueEx (hkdevice, L"channel", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = bt->dwHidDevClass;
RegSetValueEx (hkdevice, L"hid_subclass", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = bt->imtu;
RegSetValueEx (hkdevice, L"mtu", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = bt->fActive;
RegSetValueEx (hkdevice, L"active", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = bt->fAuth;
RegSetValueEx (hkdevice, L"auth", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = bt->fEncrypt;
RegSetValueEx (hkdevice, L"encrypt", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = (DWORD)bt->hDevHandle;
RegSetValueEx (hkdevice, L"handle", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
WCHAR szServiceId[60];
wsprintf (szServiceId, L"{%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x}",
bt->service_id.Data1, bt->service_id.Data2, bt->service_id.Data3,
bt->service_id.Data4[0], bt->service_id.Data4[1], bt->service_id.Data4[2], bt->service_id.Data4[3],
bt->service_id.Data4[4], bt->service_id.Data4[5], bt->service_id.Data4[6], bt->service_id.Data4[7]);
RegSetValueEx (hkdevice, L"service_id", 0, REG_SZ, (BYTE*)szServiceId, (wcslen(szServiceId) + 1) * sizeof(WCHAR));
if (bt->psdp)
RegSetValueEx (hkdevice, L"sdp_record", 0, REG_BINARY, bt->psdp, bt->csdp);
else
RegDeleteValue (hkdevice, L"sdp_record");
RegCloseKey (hkdevice);
RegFlushKey (HKEY_LOCAL_MACHINE);
return TRUE;
}
return FALSE;
}
int BthEnumRemove (BTDEV* bt) {
BthEnumInit ();
WCHAR szKey[2*_MAX_PATH];
wsprintf (szKey, L"software\\microsoft\\bluetooth\\device\\%s\\%04x%08x", bt->iDeviceClass != -1 ? gszKeyNames[bt->iDeviceClass] : L"UNKNOWN", GET_NAP(bt->b), GET_SAP(bt->b));
RegDeleteKey(HKEY_LOCAL_MACHINE, szKey);
return TRUE;
}
static int DisconnectFromHidDevice(BTDEV *pbt) {
int iRet = TRUE;
ASSERT(pbt->hDevHandle);
HANDLE hFile = CreateFile (L"BHI0:", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
iRet = DeviceIoControl (hFile, BTHHID_IOCTL_HIDDisconnect, &pbt->b, sizeof(pbt->b), NULL, 0, NULL, NULL);
CloseHandle (hFile);
return iRet;
}
static int ConnectToHidDevice (BTDEV *pbt, BOOL fFirstTime) {
int iRet = TRUE;
pbt->hDevHandle = ActivateDeviceEx(HID_REGKEY_SZ, NULL, 0, HID_CLIENT_REGKEY_SZ);
if (pbt->hDevHandle == NULL)
return FALSE;
if (fFirstTime) {
HANDLE hFile = CreateFile (L"BHI0:", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
iRet = DeviceIoControl (hFile, BTHHID_IOCTL_HIDConnect, &pbt->b, sizeof(pbt->b), NULL, 0, NULL, NULL);
CloseHandle (hFile);
}
return iRet;
}
int BthEnumDeactivate (BTDEV* pbtDevice) {
BthEnumInit ();
pbtDevice->fActive = FALSE;
if (pbtDevice->iDeviceClass == BTENUM_DEVICE_HID) {
DisconnectFromHidDevice(pbtDevice);
}
if (pbtDevice->hDevHandle) {
DeactivateDevice (pbtDevice->hDevHandle);
pbtDevice->hDevHandle = NULL;
}
if(pbtDevice->iDeviceClass == BTENUM_DEVICE_PRINTER) {
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Printers\\Ports", 0, KEY_ALL_ACCESS, &hk))
return FALSE;
for (int i = 1; i < 10 ; ++i) {
WCHAR szPortName[10];
wsprintf (szPortName, L"port%d", i);
WCHAR szString[256];
DWORD dwSize = sizeof(szString);
DWORD dwType;
if (ERROR_SUCCESS == RegQueryValueEx (hk, szPortName, NULL, &dwType, (BYTE *)szString, &dwSize)) {
if ((dwType == REG_SZ) && (wcsicmp (szString, pbtDevice->szPortName) == 0)) {
RegDeleteValue (hk, szPortName);
break;
}
}
}
RegCloseKey (hk);
} else if ((pbtDevice->iDeviceClass == BTENUM_DEVICE_ASYNC) && g_pfnRasDeleteEntry)
g_pfnRasDeleteEntry (NULL, BTENUM_RAS_NAME);
else if (pbtDevice->iDeviceClass == BTENUM_DEVICE_PAN) {
DeactivatePanDevice (pbtDevice);
}
pbtDevice->szPortName[0] = '\0';
return TRUE;
}
static DWORD FindFreeBluetoothPort (BTDEV *pbt) {
for (int i = 2 ; i < 10 ; ++i) {
WCHAR szPortName[20];
wsprintf (szPortName, BTENUM_PORT_NAME L"%d:", i);
HANDLE hFile = CreateFile (szPortName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return i;
CloseHandle (hFile);
}
return 10;
}
static DWORD GetBluetoothPort (BTDEV *pbt) {
if ((wcslen (pbt->szPortName) == 5) && (pbt->szPortName[4] == ':') &&
(pbt->szPortName[3] >= '0') && (pbt->szPortName[3] <= '9'))
return pbt->szPortName[3] - '0';
return 10;
}
static int ActivateBluetoothPort (BTDEV *pbt, DWORD dwIndex) {
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.device = pbt->b;
pp.channel = pbt->ucChannel;
pp.imtu = pbt->imtu;
if (pbt->fAuth)
pp.uiportflags |= RFCOMM_PORT_FLAGS_AUTHENTICATE;
if (pbt->fEncrypt)
pp.uiportflags |= RFCOMM_PORT_FLAGS_ENCRYPT;
WCHAR szKeyName[_MAX_PATH];
wsprintf (szKeyName, L"software\\microsoft\\bluetooth\\device\\ports\\%s", pbt->szDeviceName);
HKEY hk;
DWORD dwDisp = 0;
if (ERROR_SUCCESS != RegCreateKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, NULL, 0, KEY_WRITE, NULL, &hk, &dwDisp))
return FALSE;
RegSetValueEx (hk, L"dll", 0, REG_SZ, (BYTE *)L"btd.dll", sizeof(L"btd.dll"));
RegSetValueEx (hk, L"prefix", 0, REG_SZ, (BYTE *)BTENUM_PORT_NAME, sizeof(BTENUM_PORT_NAME));
RegSetValueEx (hk, L"index", 0, REG_DWORD, (BYTE *)&dwIndex, sizeof(dwIndex));
DWORD dw = (DWORD) &pp;
RegSetValueEx (hk, L"context", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
if ((pbt->iDeviceClass == BTENUM_DEVICE_MODEM) || (pbt->iDeviceClass == BTENUM_DEVICE_LAP) || (pbt->iDeviceClass == BTENUM_DEVICE_ASYNC)) {
HKEY hk2;
if (ERROR_SUCCESS != RegCreateKeyEx (hk, L"unimodem", 0, NULL, 0, KEY_WRITE, NULL, &hk2, &dwDisp)) {
RegCloseKey (hk);
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
return FALSE;
}
RegSetValueEx (hk2, L"friendlyname", 0, REG_SZ, (BYTE *)pbt->szDeviceName, (wcslen (pbt->szDeviceName) + 1) * sizeof(WCHAR));
RegSetValueEx (hk2, L"tsp", 0, REG_SZ, (BYTE *)L"unimodem.dll", sizeof(L"unimodem.dll"));
dw = pbt->iDeviceClass == BTENUM_DEVICE_MODEM ? 1 : 0;
RegSetValueEx (hk2, L"devicetype", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
RegCloseKey (hk2);
}
RegCloseKey (hk);
pbt->hDevHandle = ActivateDevice (szKeyName, 0);
return pbt->hDevHandle != NULL;
}
int BthEnumActivate (BTDEV *pbtDevice, int fFirstTime) {
BthEnumInit ();
pbtDevice->fActive = TRUE;
//if it is an SPP-based device
if ((pbtDevice->iDeviceClass == BTENUM_DEVICE_MODEM) ||
(pbtDevice->iDeviceClass == BTENUM_DEVICE_LAP) ||
(pbtDevice->iDeviceClass == BTENUM_DEVICE_PRINTER) ||
(pbtDevice->iDeviceClass == BTENUM_DEVICE_ASYNC)) {
DWORD dwIndex = fFirstTime ? FindFreeBluetoothPort (pbtDevice) : GetBluetoothPort (pbtDevice);
if (dwIndex == 10) {
pbtDevice->fActive = FALSE;
return FALSE;
}
if (fFirstTime)
wsprintf (pbtDevice->szPortName, BTENUM_PORT_NAME L"%d:", dwIndex);
pbtDevice->fActive = ActivateBluetoothPort (pbtDevice, dwIndex);
if (! pbtDevice->fActive)
return FALSE;
}
//if printer
if (pbtDevice->iDeviceClass == BTENUM_DEVICE_PRINTER) {
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Printers\\Ports", 0, KEY_ALL_ACCESS, &hk)) {
pbtDevice->fActive = FALSE;
DeactivateDevice (pbtDevice->hDevHandle);
pbtDevice->hDevHandle = NULL;
return FALSE;
}
//add the COM port mapping into the Printer\Ports key so that other applications can pick it up
int iMinPort = 10;
WCHAR szPortName[10];
for (int i = 1; i < 10 ; ++i) {
wsprintf (szPortName, L"port%d", i);
WCHAR szString[_MAX_PATH];
DWORD dwType;
DWORD dwSize = sizeof(szString);
if (ERROR_SUCCESS == RegQueryValueEx (hk, szPortName, NULL, &dwType, (BYTE *)szString, &dwSize)) {
if ((dwType == REG_SZ) && (wcsicmp (szString, pbtDevice->szPortName) == 0)) {
RegCloseKey (hk);
return TRUE;
}
} else if (iMinPort > i)
iMinPort = i;
}
if (iMinPort < 10) {
wsprintf (szPortName, L"port%d", iMinPort);
RegSetValueEx (hk, szPortName, 0, REG_SZ, (BYTE *)pbtDevice->szPortName, (wcslen (pbtDevice->szPortName) + 1) * sizeof(WCHAR));
} else
pbtDevice->fActive = FALSE;
RegCloseKey (hk);
RegFlushKey (HKEY_LOCAL_MACHINE);
}
else if ((pbtDevice->iDeviceClass == BTENUM_DEVICE_HEADSET) ||
(pbtDevice->iDeviceClass == BTENUM_DEVICE_HANDSFREE)) {
// Open or create key to save BT_ADDR. This registry value is used by SCO driver.
HKEY hk;
DWORD dwDis = 0;
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway\\Devices\\1", 0, NULL, 0, NULL, NULL, &hk, &dwDis)) {
BD_ADDR b;
b.NAP = GET_NAP(pbtDevice->b);
b.SAP = GET_SAP(pbtDevice->b);
RegSetValueEx(hk, L"Address", 0, REG_BINARY, (PBYTE)&b, sizeof(b));
RegSetValueEx(hk, L"Service", 0, REG_BINARY, (PBYTE)&pbtDevice->service_id, sizeof(GUID));
RegCloseKey (hk);
RegFlushKey (HKEY_LOCAL_MACHINE);
} else {
pbtDevice->fActive = FALSE;
}
} else if ((pbtDevice->iDeviceClass==BTENUM_DEVICE_ASYNC) && g_pfnRasGetEntryProperties) {
RASENTRY RasEntry;
RasEntry.dwSize = sizeof(RASENTRY);
DWORD cb = sizeof(RASENTRY);
g_pfnRasGetEntryProperties (NULL, L"", &RasEntry, &cb, NULL, NULL);
RasEntry.dwfOptions &= ~(RASEO_SpecificNameServers|RASEO_SpecificIpAddr|
RASEO_IpHeaderCompression|RASEO_SwCompression|RASEO_UseCountryAndAreaCodes);
wcscpy (RasEntry.szDeviceType, L"direct");
wcsncpy (RasEntry.szDeviceName, pbtDevice->szDeviceName, sizeof(RasEntry.szDeviceName)/sizeof(RasEntry.szDeviceName[0])-1);
RasEntry.szDeviceName[sizeof(RasEntry.szDeviceName)/sizeof(RasEntry.szDeviceName[0])-1] = '\0';
g_pfnRasSetEntryProperties(NULL, BTENUM_RAS_NAME, &RasEntry, sizeof(RasEntry), NULL, 0);
RASDIALPARAMS RasDialParams;
memset((char *)&RasDialParams, 0, sizeof(RasDialParams));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
wcscpy (RasDialParams.szEntryName, BTENUM_RAS_NAME);
wcscpy (RasDialParams.szUserName, L"guest");
wcscpy (RasDialParams.szPassword, L"guest");
g_pfnRasSetEntryDialParams(NULL, &RasDialParams, FALSE);
RegFlushKey (HKEY_LOCAL_MACHINE);
} else if (pbtDevice->iDeviceClass == BTENUM_DEVICE_HID) { // HID
pbtDevice->fActive = ConnectToHidDevice (pbtDevice, fFirstTime);
} else if (pbtDevice->iDeviceClass == BTENUM_DEVICE_PAN) {
pbtDevice->fActive = ActivatePanDevice (pbtDevice, fFirstTime);
}
return pbtDevice->fActive;
}
int BthEnumGetClassDefaults (int iClass, BTDEV *pbt) {
pbt->imtu = gidefault_mtu;
pbt->fAuth = gidefault_auth;
pbt->fEncrypt = gidefault_encr;
if ((iClass >= 0) && (iClass < sizeof(gimtu)/sizeof(gimtu[0]))) {
if (gimtu[iClass] >= 0)
pbt->imtu = gimtu[iClass];
pbt->fAuth = gauth[iClass];
pbt->fEncrypt = gencr[iClass];
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -