📄 btgw.cxx
字号:
//
// 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.
//
/**
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Abstract:
Windows CE Bluetooth application sample
**/
#include <windows.h>
#include <winsock2.h>
#include <ras.h>
#include <raserror.h>
#include <afdfunc.h>
#include <ws2bth.h>
#include <bt_sdp.h>
#include <bthapi.h>
#include <bt_api.h>
extern "C" DWORD RasIOControl(LPVOID hRasConn, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut);
#undef WSAGetLastError
#define WSAGetLastError() GetLastError()
//
// Constants & macros
//
//
#define IPADDR(x) ((x>>24) & 0x000000ff), ((x>>16) & 0x000000ff), ((x>>8) & 0x000000ff), (x & 0x000000ff)
#define CRLF L"\r\n"
#define CONFIG_NAME L"WinCEBlueGW.config"
#define CONFIG_NAME_SZ (sizeof(CONFIG_NAME)/sizeof(WCHAR) - 1)
#define GW_SLEEP 30
#define SDP_RECORD_SIZE 0x0000004d
#define SDP_CHANNEL_OFFSET 26
static const BYTE rgbSdpRecordLAN[] = {
0x35, 0x4b, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19,
0x11, 0x02, 0x09, 0x00, 0x04, 0x35, 0x0c, 0x35,
0x03, 0x19, 0x01, 0x00, 0x35, 0x05, 0x19, 0x00,
0x03, 0x08,
0x01, // server channel goes here (+26)
0x09, 0x00, 0x06, 0x35, 0x09,
0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01,
0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06,
0x19, 0x11, 0x02, 0x09, 0x01, 0x00, 0x09, 0x01,
0x00, 0x25, 0x12, 'L', 'a', 'n', ' ', 'A',
'c', 'c', 'e', 's', 's', ' ', 'P', 'r',
'o', 'f', 'i', 'l', 'e'
};
static const BYTE rgbSdpRecordDUN[] = {
0x35, 0x4b, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19,
0x11, 0x03, 0x09, 0x00, 0x04, 0x35, 0x0c, 0x35,
0x03, 0x19, 0x01, 0x00, 0x35, 0x05, 0x19, 0x00,
0x03, 0x08,
0x01, // server channel goes here (+26)
0x09, 0x00, 0x06, 0x35, 0x09,
0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01,
0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06,
0x19, 0x11, 0x03, 0x09, 0x01, 0x00, 0x09, 0x01,
0x00, 0x25, 0x12, 'D', 'i', 'a', 'l', '-',
'u', 'p', ' ', 'N', 'e', 't', 'w', 'o',
'r', 'k', 'i', 'n', 'g'
};
const DWORD bmProhibitAll = RASEO_ProhibitPAP |
RASEO_ProhibitCHAP |
RASEO_ProhibitMsCHAP |
RASEO_ProhibitMsCHAP2 |
RASEO_ProhibitEAP;
//
// Data types
//
//
struct Port {
Port *pNext;
unsigned int fOld : 1;
unsigned int fModem : 1;
int index;
int index2;
unsigned char channel;
HANDLE hDevice; // Primary port
HANDLE hDevice2; // Secondary port (when primary is a filter)
HANDLE hFile; // File handle
HANDLE hThread; // Monitoring thread
WCHAR szDevName[_MAX_PATH];
Port (void) {
memset (this, 0, sizeof(*this));
hFile = INVALID_HANDLE_VALUE;
}
};
struct Security {
Security *pNext;
int fDeletePIN;
int fDeleteKEY;
BT_ADDR bt;
int cPin;
int cKey;
unsigned char acPin[16];
unsigned char acKey[16];
Security (void) {
memset (this, 0, sizeof(*this));
}
};
struct Config {
Port *pPortList;
Security *pSecurityList;
int fa;
int fe;
unsigned int uiRasAuth;
Config (void) {
memset (this, 0, sizeof(*this));
}
};
struct PortThreadArgs {
HANDLE hFile;
int fLan;
};
static inline WCHAR hxd(unsigned char c) {
if (c >= 10)
return c - 10 + 'a';
return c + '0';
}
static int GetDI (WCHAR **pp, unsigned int *pi) {
while (iswspace(**pp))
++*pp;
int iDig = 0;
*pi = 0;
while (iswdigit (**pp)) {
int c = **pp;
c = c - '0';
if ((c < 0) || (c > 9))
return FALSE;
*pi = *pi * 10 + c;
++*pp;
++iDig;
}
if ((iDig <= 0) || (iDig > 10))
return FALSE;
return TRUE;
}
static int GetBA (WCHAR **pp, BT_ADDR *pba) {
memset (pba, 0, sizeof (BT_ADDR));
while (iswspace(**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 ((! iswspace(**pp)) && (**pp != '\0'))
return FALSE;
return TRUE;
}
static int GetUx (WCHAR **pp, void *pRes, int nDigs, int fPrefix) {
while (iswspace(**pp))
++*pp;
if (fPrefix) {
if (**pp != '0')
return FALSE;
++*pp;
if (**pp != 'x')
return FALSE;
++*pp;
}
int iDig = 0;
int iRes = 0;
while (iswxdigit (**pp)) {
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;
iRes = iRes * 16 + c;
++*pp;
++iDig;
}
if (iDig != nDigs) // ???????????? iDig > nDig
return FALSE;
switch (nDigs) {
case 2:
*(unsigned char *)pRes = (unsigned char)iRes;
break;
case 4:
*(unsigned short *)pRes = (unsigned short)iRes;
break;
case 8:
*(unsigned int *)pRes = (unsigned int)iRes;
break;
}
return TRUE;
}
//
// PPP server configuration and management
//
//
static DWORD GetServerParameters(RASCNTL_SERVERSTATUS *pParameters) {
DWORD cbParameters;
DWORD dwResult = RasIOControl(0, RASCNTL_SERVER_GET_PARAMETERS, 0, 0, (unsigned char *)pParameters, sizeof(*pParameters), &cbParameters);
if (dwResult != 0)
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Unable to get PPP server parameters, error=%d" CRLF, dwResult));
return dwResult;
}
static DWORD SetServerParameters(RASCNTL_SERVERSTATUS *pParameters) {
DWORD dwResult = RasIOControl(0, RASCNTL_SERVER_SET_PARAMETERS, (unsigned char *)pParameters, sizeof(*pParameters), NULL, 0, NULL);
if (dwResult != 0)
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Unable to set PPP server parameters, error=%d" CRLF, dwResult));
return dwResult;
}
static DWORD SetGlobalPPPConfig (void) {
DWORD fDHCP = TRUE;
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\gateway", 0, KEY_READ, &hk)) {
DWORD dwType = 0;
DWORD dwSize = sizeof(fDHCP);
RegQueryValueEx (hk, L"UseDHCP", NULL, &dwType, (BYTE *)&fDHCP, &dwSize);
if (! fDHCP) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: NOT using DHCP for dialup lines" CRLF));
}
RegCloseKey (hk);
}
RASCNTL_SERVERSTATUS Parameters;
DWORD dwResult = RasIOControl(0, RASCNTL_SERVER_ENABLE, 0, 0, NULL, 0, NULL);
if (dwResult != ERROR_SUCCESS)
return dwResult;
dwResult = GetServerParameters(&Parameters);
if (dwResult == ERROR_SUCCESS) {
Parameters.bUseDhcpAddresses = fDHCP;
dwResult = SetServerParameters(&Parameters);
}
if (dwResult == ERROR_SUCCESS) {
RASCNTL_SERVERUSERCREDENTIALS Credentials;
memset(&Credentials, 0, sizeof(Credentials));
wcscpy (Credentials.tszUserName, L"guest");
strcpy ((char *)Credentials.password, "guest");
Credentials.cbPassword = strlen ((char *)Credentials.password) + 1;
dwResult = RasIOControl(0, RASCNTL_SERVER_USER_SET_CREDENTIALS, (PUCHAR)&Credentials, sizeof(Credentials), NULL, 0, NULL);
}
return dwResult;
}
static DWORD GetLineDevices (LPRASDEVINFOW *ppRasDevInfo, PDWORD pcDevices) {
DWORD cbNeeded = 0;
DWORD dwResult = ERROR_SUCCESS;
*pcDevices = 0;
*ppRasDevInfo = NULL;
RasIOControl(0, RASCNTL_ENUMDEV, NULL, 0, (PUCHAR)&cbNeeded, 0, pcDevices);
if (cbNeeded) {
*ppRasDevInfo = (LPRASDEVINFOW)malloc(cbNeeded);
if (*ppRasDevInfo == NULL) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Unable to allocate %d bytes of memory to store device info" CRLF, cbNeeded));
dwResult = ERROR_OUTOFMEMORY;
} else {
(*ppRasDevInfo)->dwSize = sizeof(RASDEVINFOW);
dwResult = RasIOControl(0, RASCNTL_ENUMDEV, (PUCHAR)*ppRasDevInfo, 0, (PUCHAR)&cbNeeded, 0, pcDevices);
}
}
return dwResult;
}
static void DisplayPPP (void) {
RASCNTL_SERVERSTATUS *pStatus = NULL;
DWORD cbStatus = 0;
//
// First pass is to get the size
//
RasIOControl(0, RASCNTL_SERVER_GET_STATUS, 0, 0, NULL, 0, &cbStatus);
if (cbStatus)
pStatus = (RASCNTL_SERVERSTATUS *)malloc (cbStatus);
if (pStatus) {
DWORD dwResult = RasIOControl(0, RASCNTL_SERVER_GET_STATUS, 0, 0, (PUCHAR)pStatus, cbStatus, &cbStatus);
if (dwResult == ERROR_SUCCESS) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Ras Server Status:" CRLF));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tEnabled = %x" CRLF, pStatus->bEnable));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tFlags = %x" CRLF, pStatus->bmFlags));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tUseDhcpAddresses = %d" CRLF, pStatus->bUseDhcpAddresses));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tStaticIpAddrStart = %u.%u.%u.%u" CRLF, IPADDR(pStatus->dwStaticIpAddrStart)));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tStaticIpAddrCount = %u" CRLF, pStatus->dwStaticIpAddrCount));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tAuthenticationMethods = %x" CRLF, pStatus->bmAuthenticationMethods));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: \tNumLines = %u" CRLF, pStatus->dwNumLines));
//
// Per line info is in an array immediately following the global server status struct
//
RASCNTL_SERVERLINE *pLine = (RASCNTL_SERVERLINE *)(&pStatus[1]);
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Configured Line Devices:" CRLF));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Type Flags IdleTO Name" CRLF));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: ------ ----- ------ ----" CRLF));
for (int iLine = 0; iLine < (int)pStatus->dwNumLines; iLine++, pLine++)
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: %6s %5x %6d %s" CRLF, pLine->rasDevInfo.szDeviceType, pLine->bmFlags, pLine->DisconnectIdleSeconds, pLine->rasDevInfo.szDeviceName));
} else
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: RasIOControl failed, error = %d" CRLF, dwResult));
free(pStatus);
}
LPRASDEVINFOW pRasDevInfo;
DWORD cDevices;
DWORD dwResult = GetLineDevices(&pRasDevInfo, &cDevices);
if (dwResult == 0) {
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: Available RAS Line Devices:" CRLF));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: ## Type Name" CRLF));
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: -- ------ ----" CRLF));
for (int iDevice = 0; iDevice < (int)cDevices; iDevice++)
RETAILMSG(1, (L"BLUETOOTH GATEWAY:: %2d %6s %s" CRLF, iDevice, pRasDevInfo[iDevice].szDeviceType, pRasDevInfo[iDevice].szDeviceName));
}
if (pRasDevInfo)
free (pRasDevInfo);
}
static DWORD GetDeviceInfo (WCHAR *szDeviceName, RASDEVINFO *DeviceInfo) {
LPRASDEVINFOW pRasDevInfo;
DWORD cDevices;
DWORD dwResult = GetLineDevices(&pRasDevInfo, &cDevices);
if (dwResult == ERROR_SUCCESS) {
dwResult = ERROR_NOT_FOUND;
for (int i = 0; i < (int)cDevices; i++) {
if (_tcscmp(pRasDevInfo[i].szDeviceName, szDeviceName) == 0) {
*DeviceInfo = pRasDevInfo[i];
dwResult = ERROR_SUCCESS;
break;
}
}
}
if (pRasDevInfo)
free (pRasDevInfo);
return dwResult;
}
static DWORD
LineGetParameters(
IN RASCNTL_SERVERLINE *pLine,
OUT RASCNTL_SERVERLINE **ppOutBuf,
OUT DWORD *pdwOutBufSize)
{
DWORD dwResult = 0;
PRASCNTL_SERVERLINE pOutBuf = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -