📄 btgw.cxx
字号:
DWORD dwOutBufSize = 0,
dwNeededSize;
do
{
dwResult = RasIOControl(0, RASCNTL_SERVER_LINE_GET_PARAMETERS, (PUCHAR)pLine, sizeof(*pLine), (PUCHAR)pOutBuf, dwOutBufSize, &dwNeededSize);
if (dwResult != ERROR_BUFFER_TOO_SMALL)
break;
// Free old buffer
if (pOutBuf)
LocalFree(pOutBuf);
// Allocate new buffer
pOutBuf = (PRASCNTL_SERVERLINE)LocalAlloc (LPTR, dwNeededSize);
if (pOutBuf == NULL)
{
dwResult = ERROR_OUTOFMEMORY;
break;
}
dwOutBufSize = dwNeededSize;
} while (TRUE);
*ppOutBuf = pOutBuf;
*pdwOutBufSize = dwOutBufSize;
return dwResult;
}
static DWORD LineSetAuthentication(RASCNTL_SERVERLINE *pLine, unsigned int uiRasAuth) {
RASCNTL_SERVERLINE *pLineSettings;
DWORD cbLineSettings;
DWORD dwResult;
dwResult = LineGetParameters(pLine, &pLineSettings, &cbLineSettings);
if (dwResult == NO_ERROR)
{
if (uiRasAuth == 0)
pLineSettings->bmFlags |= PPPSRV_FLAG_ALLOW_UNAUTHENTICATED_ACCESS;
else
pLineSettings->bmFlags &= ~PPPSRV_FLAG_ALLOW_UNAUTHENTICATED_ACCESS;
dwResult = RasIOControl(0, RASCNTL_SERVER_LINE_SET_PARAMETERS, (PUCHAR)pLineSettings, cbLineSettings, NULL, 0, NULL);
LocalFree(pLineSettings);
}
return dwResult;
}
static DWORD ServerSetAuthentication (unsigned int uiRasAuth) {
if (! uiRasAuth)
return ERROR_SUCCESS;
DWORD cbStatus = 0;
// Retrieve RAS setting
DWORD dwResult = RasIOControl(0, RASCNTL_SERVER_GET_PARAMETERS, 0, 0, NULL, 0, &cbStatus);
if (dwResult && (cbStatus == 0)) {
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to get server parameters. Error code %d" CRLF, dwResult));
return dwResult;
}
RASCNTL_SERVERSTATUS *pStatus = (RASCNTL_SERVERSTATUS *) malloc ( cbStatus );
if (pStatus == NULL) {
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to get server parameters. Error code %d" CRLF, ERROR_OUTOFMEMORY));
return ERROR_OUTOFMEMORY;
}
dwResult = RasIOControl(0, RASCNTL_SERVER_GET_PARAMETERS, 0, 0, (PUCHAR)pStatus, cbStatus, &cbStatus);
if (dwResult) {
free (pStatus);
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to get server parameters. Error code %d" CRLF, dwResult));
return dwResult;
}
pStatus->bmAuthenticationMethods &= ~bmProhibitAll;
pStatus->bmAuthenticationMethods |= uiRasAuth;
dwResult = RasIOControl(0, RASCNTL_SERVER_SET_PARAMETERS, (PUCHAR)pStatus, cbStatus, 0, 0, &cbStatus);
free (pStatus);
if (dwResult) {
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to set server parameters. Error code %d" CRLF, dwResult));
return dwResult;
}
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Successfully set server authentication." CRLF));
return ERROR_SUCCESS;
}
static int AddAndEnable (WCHAR *szFriendlyName, unsigned int uiRasAuth) {
RASCNTL_SERVERLINE Line;
DWORD dwResult = GetDeviceInfo (szFriendlyName, &Line.rasDevInfo);
if (dwResult == ERROR_SUCCESS) {
if (ERROR_SUCCESS == (dwResult = RasIOControl(0, RASCNTL_SERVER_LINE_ADD, (PUCHAR)&Line, sizeof(Line), NULL, 0, NULL))) {
if (ERROR_SUCCESS == (dwResult = LineSetAuthentication(&Line, uiRasAuth))) {
if (ERROR_SUCCESS == (dwResult = RasIOControl(0, RASCNTL_SERVER_LINE_ENABLE, (PUCHAR)&Line, sizeof(Line), NULL, 0, NULL)))
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Successfully enabled device %s. Ready to receive calls." CRLF, szFriendlyName));
else
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to enable device %s. Error code %d" CRLF, szFriendlyName, dwResult));
} else
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to disable authentication for device %s. Error code %d" CRLF, szFriendlyName, dwResult));
} else
RETAILMSG (1, (L"BLUETOOTH GATEWAY:: Failed to add device %s. Error code %d" CRLF, szFriendlyName, dwResult));
} else
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Device %s is not recognized, code %d" CRLF, szFriendlyName, dwResult));
return dwResult;
}
static int DisableAndRemove (WCHAR *szFriendlyName) {
RASCNTL_SERVERLINE Line;
DWORD dwResult = GetDeviceInfo (szFriendlyName, &Line.rasDevInfo);
if (dwResult == ERROR_SUCCESS) {
RasIOControl(0, RASCNTL_SERVER_LINE_DISABLE, (PUCHAR)&Line, sizeof(Line), NULL, 0, NULL);
RasIOControl(0, RASCNTL_SERVER_LINE_REMOVE, (PUCHAR)&Line, sizeof(Line), NULL, 0, NULL);
} else
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Device %s is not recognized, code %d" CRLF, szFriendlyName, dwResult));
return dwResult;
}
//
// Port management
//
static ULONG RegisterSDP (HANDLE hFile, int fLan) {
ULONG recordHandle = 0;
DWORD port = 0;
DWORD dwSizeOut = 0;
if (! DeviceIoControl (hFile, IOCTL_BLUETOOTH_GET_RFCOMM_CHANNEL, NULL, 0, &port, sizeof(port), &dwSizeOut, NULL)) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to retrieve port server channel, error = %d" CRLF, GetLastError ()));
return 0;
}
struct {
BTHNS_SETBLOB b;
unsigned char uca[SDP_RECORD_SIZE];
} bigBlob;
ULONG ulSdpVersion = BTH_SDP_VERSION;
bigBlob.b.pRecordHandle = &recordHandle;
bigBlob.b.pSdpVersion = &ulSdpVersion;
bigBlob.b.fSecurity = 0;
bigBlob.b.fOptions = 0;
bigBlob.b.ulRecordLength = SDP_RECORD_SIZE;
memcpy (bigBlob.b.pRecord, fLan ? rgbSdpRecordLAN : rgbSdpRecordDUN, SDP_RECORD_SIZE);
bigBlob.b.pRecord[SDP_CHANNEL_OFFSET] = (unsigned char)port;
BLOB blob;
blob.cbSize = sizeof(BTHNS_SETBLOB) + SDP_RECORD_SIZE - 1;
blob.pBlobData = (PBYTE) &bigBlob;
WSAQUERYSET Service;
memset (&Service, 0, sizeof(Service));
Service.dwSize = sizeof(Service);
Service.lpBlob = &blob;
Service.dwNameSpace = NS_BTH;
int iRet = BthNsSetService (&Service, RNRSERVICE_REGISTER,0);
if (iRet != ERROR_SUCCESS) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: BthNsSetService fails with status %d" CRLF, iRet));
return 0;
}
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Created SDP record 0x%08x, channel %d" CRLF, recordHandle, port));
return recordHandle;
}
static void DeRegisterSDP (ULONG recordHandle) {
ULONG ulSdpVersion = BTH_SDP_VERSION;
BTHNS_SETBLOB delBlob;
memset (&delBlob, 0, sizeof(delBlob));
delBlob.pRecordHandle = &recordHandle;
delBlob.pSdpVersion = &ulSdpVersion;
BLOB blob;
blob.cbSize = sizeof(BTHNS_SETBLOB);
blob.pBlobData = (PBYTE) &delBlob;
WSAQUERYSET Service;
memset (&Service, 0, sizeof(Service));
Service.dwSize = sizeof(Service);
Service.lpBlob = &blob;
Service.dwNameSpace = NS_BTH;
int iErr = BthNsSetService (&Service, RNRSERVICE_DELETE, 0);
RETAILMSG (1, (L"BLUETOOTH GATEWAY: removed SDP record 0x%08x (%d)" CRLF, recordHandle, iErr));
}
static DWORD WINAPI PortThread (LPVOID lparg) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Entered port monitor thread" CRLF));
HANDLE hFile = ((PortThreadArgs *)lparg)->hFile;
int fLan = ((PortThreadArgs *)lparg)->fLan;
LocalFree (lparg);
ULONG recordHandle = 0;
// Register SDP handle, etc.
SetCommMask(hFile, EV_RLSD);
for ( ; ; ) {
DWORD Mask;
DWORD ModemStatus;
if (! GetCommModemStatus (hFile, &ModemStatus)) {
break;
}
if (ModemStatus & MS_RLSD_ON) {
BT_ADDR bt;
DWORD dwSizeOut = 0;
if (! DeviceIoControl (hFile, IOCTL_BLUETOOTH_GET_PEER_DEVICE, NULL, 0, &bt, sizeof(bt), &dwSizeOut, NULL))
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to retrieve peer device name, error = %d" CRLF, GetLastError ()));
else
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Connection detected from %04x%08x" CRLF, GET_NAP(bt), GET_SAP(bt)));
if (recordHandle)
DeRegisterSDP (recordHandle);
recordHandle = 0;
} else {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: No connection detected" CRLF));
if (! recordHandle)
recordHandle = RegisterSDP (hFile, fLan);
}
if (! WaitCommEvent(hFile, &Mask, NULL )) {
break;
}
}
if (recordHandle)
DeRegisterSDP (recordHandle);
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Exiting port monitor thread" CRLF));
return 0;
}
static void ClosePort (Port *pPort) {
if (pPort->hFile != INVALID_HANDLE_VALUE)
CloseHandle (pPort->hFile);
pPort->hFile = INVALID_HANDLE_VALUE;
if (pPort->hThread) {
WaitForSingleObject (pPort->hThread, INFINITE);
CloseHandle (pPort->hThread);
}
pPort->hThread = NULL;
WCHAR szKeyName[_MAX_PATH];
wsprintf (szKeyName, L"software\\microsoft\\bluetoothgateway\\com%d\\unimodem", pPort->index);
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
wsprintf (szKeyName, L"software\\microsoft\\bluetoothgateway\\com%d", pPort->fModem ? pPort->index2 : pPort->index);
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
if (pPort->fModem) {
wsprintf (szKeyName, L"software\\microsoft\\bluetoothgateway\\com%d", pPort->index2);
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
}
DisableAndRemove (pPort->szDevName);
if (pPort->hDevice)
DeactivateDevice (pPort->hDevice);
if (pPort->hDevice2)
DeactivateDevice (pPort->hDevice2);
pPort->hDevice = NULL;
pPort->hDevice2 = NULL;
}
static void OpenPort (Port *pPort, int fa, int fe, unsigned int uiRasAuth) {
ASSERT (pPort->hDevice == NULL);
ASSERT (pPort->hDevice2 == NULL);
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.flocal = TRUE;
pp.channel = pPort->channel;
if (! pp.channel)
pp.channel = 0xfe;
if (fa)
pp.uiportflags |= RFCOMM_PORT_FLAGS_AUTHENTICATE;
if (fe)
pp.uiportflags |= RFCOMM_PORT_FLAGS_ENCRYPT;
WCHAR szKeyName[_MAX_PATH];
wsprintf (szKeyName, L"software\\microsoft\\bluetoothgateway\\com%d", pPort->index);
HKEY hk;
DWORD dwDisp = 0;
if (ERROR_SUCCESS != RegCreateKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, NULL, 0, KEY_WRITE, NULL, &hk, &dwDisp)) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to create registry key %s, error = %d" CRLF, szKeyName, GetLastError ()));
return;
}
RegSetValueEx (hk, L"dll", 0, REG_SZ, (BYTE *)L"btd.dll", sizeof(L"btd.dll"));
RegSetValueEx (hk, L"prefix", 0, REG_SZ, (BYTE *)L"COM", sizeof(L"COM"));
DWORD dw = pPort->index;
RegSetValueEx (hk, L"index", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = (DWORD) &pp;
RegSetValueEx (hk, L"context", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
if (! pPort->fModem) {
HKEY hk2;
if (ERROR_SUCCESS != RegCreateKeyEx (hk, L"unimodem", 0, NULL, 0, KEY_WRITE, NULL, &hk2, &dwDisp)) {
RegCloseKey (hk);
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to create unimodem subkey of %s, error = %d" CRLF, szKeyName, GetLastError ()));
return;
}
RegSetValueEx (hk2, L"friendlyname", 0, REG_SZ, (BYTE *)pPort->szDevName, (wcslen (pPort->szDevName) + 1) * sizeof(WCHAR));
RegSetValueEx (hk2, L"tsp", 0, REG_SZ, (BYTE *)L"unimodem.dll", sizeof(L"unimodem.dll"));
dw = 0;
RegSetValueEx (hk2, L"devicetype", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
RegCloseKey (hk2);
}
RegCloseKey (hk);
pPort->hDevice = ActivateDevice (szKeyName, 0);
if (! pPort->hDevice) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to register port %d, error = %d" CRLF, pPort->index, GetLastError ()));
RegDeleteKey (HKEY_LOCAL_MACHINE, szKeyName);
return;
}
if (pPort->fModem) {
wsprintf (szKeyName, L"software\\microsoft\\bluetoothgateway\\com%d", pPort->index2);
if (ERROR_SUCCESS != RegCreateKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, NULL, 0, KEY_WRITE, NULL, &hk, &dwDisp)) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to create registry key %s, error = %d" CRLF, szKeyName, GetLastError ()));
ClosePort (pPort);
return;
}
RegSetValueEx (hk, L"dll", 0, REG_SZ, (BYTE *)L"btdun.dll", sizeof(L"btdun.dll"));
RegSetValueEx (hk, L"prefix", 0, REG_SZ, (BYTE *)L"COM", sizeof(L"COM"));
dw = pPort->index2;
RegSetValueEx (hk, L"index", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
dw = (DWORD) pPort->index;
RegSetValueEx (hk, L"context", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
HKEY hk2;
if (ERROR_SUCCESS != RegCreateKeyEx (hk, L"unimodem", 0, NULL, 0, KEY_WRITE, NULL, &hk2, &dwDisp)) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to create unimodem subkey of %s, error = %d" CRLF, szKeyName, GetLastError ()));
ClosePort (pPort);
return;
}
RegSetValueEx (hk2, L"friendlyname", 0, REG_SZ, (BYTE *)pPort->szDevName, (wcslen (pPort->szDevName) + 1) * sizeof(WCHAR));
RegSetValueEx (hk2, L"tsp", 0, REG_SZ, (BYTE *)L"unimodem.dll", sizeof(L"unimodem.dll"));
dw = 0;
RegSetValueEx (hk2, L"devicetype", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
RegCloseKey (hk2);
RegCloseKey (hk);
pPort->hDevice2 = ActivateDevice (szKeyName, 0);
if (! pPort->hDevice) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to register port %d, error = %d" CRLF, pPort->index2, GetLastError ()));
ClosePort (pPort);
return;
}
}
Sleep (3000); // Tapi need to process device insertion
if (ERROR_SUCCESS != AddAndEnable (pPort->szDevName, uiRasAuth)) {
ClosePort (pPort);
return;
}
WCHAR szFile[40];
wsprintf (szFile, L"COM%d:", pPort->index);
pPort->hFile = CreateFile (szFile, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (pPort->hFile == INVALID_HANDLE_VALUE) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed to open port %d, error = %d" CRLF, pPort->index, GetLastError ()));
ClosePort (pPort);
return;
}
PortThreadArgs *pArgs = (PortThreadArgs *)LocalAlloc (LMEM_FIXED, sizeof(PortThreadArgs));
if (pArgs) {
pArgs->fLan = ! pPort->fModem;
pArgs->hFile = pPort->hFile;
pPort->hThread = CreateThread (NULL, 0, PortThread, (LPVOID)pArgs, 0, NULL);
}
if (! pPort->hThread) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Failed attach thread to port %d, error = %d" CRLF, pPort->index, GetLastError ()));
ClosePort (pPort);
}
}
//
// Configuration management and parsing
//
//
#define DEFAULT_CONFIG_FILE L"AUTH=OFF\nENCRYPT=OFF\nPORT=btline0,7\nPORT=btline1,8,9\n"
static void PrintDefaultHeader (FILE *fp, WCHAR *sz) {
fwprintf (fp, L";\n; This is Bluetooth Gateway configuration file %s.\n;\n", sz);
fwprintf (fp, L"; It is automatically regenerated on every update,\n");
fwprintf (fp, L"; do not store any information (including comments)\n");
fwprintf (fp, L"; aside of information inside defined keywords.\n;\n");
fwprintf (fp, L"; The keywords legal in this file are:\n");
fwprintf (fp, L"; AUTH={ON|OFF} require authentication on connection\n");
fwprintf (fp, L"; ENCRYPT={ON|OFF} require encryption to be on on connection\n");
fwprintf (fp, L"; RASAUTH={NONE|PAP CHAP MSCHAP MSCHAPv2}\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -