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

📄 btpair.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 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.
//
/**
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 <windows.h>
#include <stdio.h>
#include <commctrl.h>

#include <winsock2.h>

#include <svsutil.hxx>

#include <bt_api.h>
#include <bthapi.h>
#include <initguid.h>
#include <bt_sdp.h>

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

#if defined (SDK_BUILD)
#include <aygshell.h>

typedef void (*tSHInputDialog)(HWND hwnd, UINT uMsg, WPARAM wParam);
tSHInputDialog gpSHInputDialog = NULL;
#endif

#include "resource.h"

#define APPNAME		L"BluetoothPairingUI"

#define MAX_NAME	248
#define MAX_BA		20

#define DO_NOTHING	0
#define DO_INQUIRY	1
#define DO_NAMERES	2
#define DO_STOP		4

struct InquiryResult {
	InquiryResult	*pNext;

	BT_ADDR			b;					// Address of the item
	unsigned int	fKey   : 1;			// Paired already
	unsigned int    fPin   : 1;			// Have PIN code

	unsigned char	channel;

	WCHAR			szName[256];

	InquiryResult (void) {
		memset (this, 0, sizeof(*this));
	}
};

struct Global : public SVSSynch {
	int					fState;
	HINSTANCE			hInst;
	HWND				hWnd;

	InquiryResult		*pDev;

	Global (void) {
		fState = DO_NOTHING;
		hInst  = NULL;
		hWnd   = NULL;
		pDev   = NULL;
	}
};

static Global *g_pState = NULL;

#define CHECK_STOP	\
	{													\
		if ((g_pState->fState == DO_STOP) ||			\
					(! g_pState->hWnd)) {				\
			g_pState->fState = DO_NOTHING;				\
			g_pState->Unlock ();						\
														\
			SetWindowText (hWndButton, L"Inquiry");		\
			SetWindowText (hWnd, L"Bluetooth Pairing");	\
														\
			return 0;									\
		}												\
	}

static void CleanInquiryData (void) {
	while (g_pState->pDev) {
		InquiryResult *pNext = g_pState->pDev->pNext;
		delete g_pState->pDev;
		g_pState->pDev = pNext;
	}
}

static int GetBD (WCHAR *pString, BT_ADDR *pba) {
	int NAP = 0;

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

		int c = *pString;
		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;

		NAP = NAP * 16 + c;
	}

	int SAP = 0;

	for (i = 0 ; i < 8 ; ++i, ++pString) {
		if (! iswxdigit (*pString))
			return FALSE;

		int c = *pString;
		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;

		SAP = SAP * 16 + c;
	}

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

	*pba = SET_NAP_SAP(NAP, SAP);

	return TRUE;
}


static DWORD WINAPI FillAuthInfo (LPVOID lpArg) {
	HWND hWndDevList = GetDlgItem (g_pState->hWnd, IDC_DEVICELIST);
	int fAddNew = (int)lpArg;

	ListView_DeleteAllItems (hWndDevList);

	g_pState->Lock ();

	InquiryResult *pX = g_pState->pDev;
	while (pX) {
		pX->fKey = FALSE;
		pX->fPin = FALSE;
		pX = pX->pNext;
	}

	HKEY hk;
	if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\security", 0, KEY_READ, &hk)) {
		DWORD dwIndex = 0;
		for ( ; ; ) {
			WCHAR szValName[3 + 4 + 8 + 1];
			DWORD cValName = sizeof(szValName)/sizeof(szValName[0]);
			unsigned char linkorpin[16];
			DWORD cLinkOrPin = sizeof(linkorpin);
			DWORD dwValType = 0;

			int iRes = RegEnumValue (hk, dwIndex, szValName, &cValName, NULL, &dwValType, linkorpin, &cLinkOrPin);

			if (iRes == ERROR_NO_MORE_ITEMS)
				break;

			BT_ADDR b;
			int fLink = FALSE;
			if ((iRes == ERROR_SUCCESS) && (dwValType == REG_BINARY) && (cValName > 3) && GetBD(szValName + 3, &b)) {
				int fKey = ((cLinkOrPin == sizeof(linkorpin)) && (fLink = (wcsnicmp (szValName, L"key", 3) == 0)));
				int fPin = ((cLinkOrPin <= sizeof(linkorpin)) && (cLinkOrPin > 0) && (wcsnicmp (szValName, L"pin", 3) == 0));

				if (fKey || fPin) {
					InquiryResult *pNew = g_pState->pDev;
					while (pNew && (pNew->b != b))
						pNew = pNew->pNext;

					if ((! pNew) && fAddNew) {
						pNew = new InquiryResult;

						pNew->pNext = g_pState->pDev;
						g_pState->pDev = pNew;
						pNew->b    = b;
					}

					if (pNew) {
						if (fKey)
							pNew->fKey = TRUE;

						if (fPin)
							pNew->fPin = TRUE;
					}
				}
			}

			++dwIndex;
		}

		RegCloseKey (hk);
	}

	InquiryResult *pNew = g_pState->pDev;
	int i = 0;

	while (pNew) {
		pX = g_pState->pDev;
		while (pX && (pX != pNew))
			pX = pX->pNext;

		if (! pX)
			break;

		WCHAR szTitle[300];
		if (pNew->szName[0])
			wsprintf (szTitle, L"%s (%04x%08x)", pNew->szName, GET_NAP(pNew->b), GET_SAP(pNew->b));
		else
			wsprintf (szTitle, L"%04x%08x", GET_NAP(pNew->b), GET_SAP(pNew->b));

		LV_ITEM lvi;
		memset (&lvi, 0, sizeof(lvi));

        lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;

        lvi.stateMask  = -1;		
        lvi.pszText    = szTitle;
        lvi.cchTextMax = wcslen(szTitle);
		lvi.lParam     = (LPARAM)pNew;
        lvi.iItem      = i++;
		lvi.iImage     = -1;

		if (pNew->fKey)
			lvi.iImage = 0;
		else if (pNew->fPin)
			lvi.iImage = 1;
		else
			lvi.iImage = 3;

		pNew = pNew->pNext;

		g_pState->Unlock ();

		ListView_InsertItem(hWndDevList, &lvi);
		ListView_SetColumnWidth(hWndDevList, 0, LVSCW_AUTOSIZE);

		g_pState->Lock ();
	}

	g_pState->Unlock ();

	return 0;
}

static DWORD WINAPI DoInquiry (LPVOID lpUnused) {
	g_pState->Lock ();

	HWND hWnd        = g_pState->hWnd;

	if ((! g_pState->hWnd) || (g_pState->fState == DO_STOP)) {
		g_pState->Unlock ();

		return 0;
	}
	
	if (g_pState->fState != DO_NOTHING) {
		g_pState->fState = DO_STOP;
		g_pState->Unlock ();

		SetWindowText (hWnd, L"Stopping...");

		return 0;
	}

	CleanInquiryData ();

	g_pState->Unlock ();

	HWND hWndButton  = GetDlgItem (hWnd, IDC_INQUIRY);
	HWND hWndDevList = GetDlgItem (hWnd, IDC_DEVICELIST);

	SetWindowText (hWndButton, L"STOP");
	SetWindowText (hWnd, L"Inquiry Running...");
	ListView_DeleteAllItems (hWndDevList);


	WSAQUERYSET		wsaq;
	memset (&wsaq, 0, sizeof(wsaq));
	wsaq.dwSize      = sizeof(wsaq);
	wsaq.dwNameSpace = NS_BTH;
	wsaq.lpcsaBuffer = NULL;

	HANDLE hLookup = NULL;
	int iErr = BthNsLookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup);

	if (iErr != ERROR_SUCCESS) {
		SetWindowText (hWndButton, L"Inquiry");
		SetWindowText (hWnd, L"Bluetooth Pairing");

		WCHAR szString[64];
		wsprintf (szString, L"Bluetooth hardware error %d\n", iErr);
		MessageBox (hWnd, szString, L"Error", MB_OK | MB_TOPMOST);

		return 0;
	}

	g_pState->Lock ();
	CHECK_STOP;

	while (iErr == ERROR_SUCCESS) {
		union {
			CHAR buf[5000];
			SOCKADDR_BTH	__unused;	// properly align buffer to BT_ADDR requirements
		};

		LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
		DWORD dwSize  = sizeof(buf);

		memset(pwsaResults,0,sizeof(WSAQUERYSET));
		pwsaResults->dwSize      = sizeof(WSAQUERYSET);
		pwsaResults->dwNameSpace = NS_BTH;
		pwsaResults->lpBlob      = NULL;

		SVSUTIL_ASSERT(hLookup);
		iErr = BthNsLookupServiceNext (hLookup, LUP_RETURN_ADDR, &dwSize, pwsaResults);

		if (iErr == ERROR_SUCCESS) {
			SVSUTIL_ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);

			InquiryResult *pNew = new InquiryResult;
			pNew->b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;

			pNew->pNext = g_pState->pDev;
			g_pState->pDev = pNew;
		}

⌨️ 快捷键说明

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