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

📄 btgw.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 4 页
字号:
	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 + -