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

📄 btloader.cxx

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

#if defined(UNDER_CE) && CE_MAJOR_VER < 0x0003
#define FILE_DEVICE_SERVICE	0x00000104
#endif

#include <service.h>

#include <bt_api.h>

#define WINCE_STACKS L"irdastk,tcpstk,btd"

int fSerial = FALSE;

int GetUx (WCHAR **pp, void *pRes, int nDigs) {
	while (**pp == ' ')
		++*pp;
	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)
		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;
}

void DebugOut (WCHAR *lpszFormat, ...) {
	WCHAR szBigBuffer[2000];
	va_list arglist;
	va_start (arglist, lpszFormat);
	wvsprintf (szBigBuffer, lpszFormat, arglist);
	va_end (arglist);

	if (fSerial)
		OutputDebugString (szBigBuffer);
	else
		wprintf (L"%s", szBigBuffer);
}

int SetTdi (WCHAR *pTdi) {
	int iRes = 0;
	HKEY hk = NULL;
	DWORD dwDisp = 0;

	if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"comm\\afd", 0, NULL,  0, KEY_WRITE, NULL, &hk, &dwDisp)) {
		DWORD dwType = REG_SZ;
		WCHAR szStacks[_MAX_PATH];
		DWORD dwStackSize = sizeof(szStacks) - sizeof(L",btd");
		szStacks[0] = '\0';

		if (ERROR_SUCCESS != RegQueryValueEx (hk, L"Stacks", NULL, &dwType, (LPBYTE)szStacks, &dwStackSize)) {
			if (wcsicmp (pTdi, L"tdi") == 0)
				RegSetValueEx (hk, L"Stacks", 0, REG_SZ, (LPBYTE)WINCE_STACKS, sizeof(WINCE_STACKS));
		} else {
			WCHAR *p = wcsstr (szStacks, L"btd");
			if (p && (*(p + 3) != ',') && (*(p + 3) != '\0'))
				p = NULL;

			if (p && (p != szStacks) && (*(p - 1) != ','))
				p = NULL;

			if ((wcsicmp (pTdi, L"tdi") == 0) && (! p) && (wcslen (szStacks) * sizeof(WCHAR) + sizeof(L",btd") < sizeof(szStacks))) {
				if (szStacks[0] == '\0')
					wcscpy (szStacks, L"btd");
				else
					wcscat (szStacks, L",btd");

				RegSetValueEx (hk, L"Stacks", 0, REG_SZ, (LPBYTE)szStacks, (wcslen (szStacks) + 1) * sizeof(WCHAR));
			} else if ((wcsicmp (pTdi, L"notdi") == 0) && p) {
				WCHAR *q = p + 3;

				if (p != szStacks) {
					++q;
					--p;
				}

				while (*p++ = *q++)
					;

				RegSetValueEx (hk, L"Stacks", 0, REG_SZ, (LPBYTE)szStacks, (wcslen (szStacks) + 1) * sizeof(WCHAR));
			}
		}

		RegCloseKey (hk);
	} else {
		DebugOut (L"Cannot create tdi registry key. Error = %d\n", GetLastError ());
		iRes = 1;
	}

	return iRes;
}

LONG recursiveDeleteKey (HKEY hkParent, WCHAR *szKey) {
	HKEY hk;
	LONG lRes = RegOpenKeyEx (hkParent, szKey, 0, KEY_ALL_ACCESS, &hk);

	if(lRes != ERROR_SUCCESS)
		return lRes;

	WCHAR sz[_MAX_PATH];
	DWORD dwSize = sizeof(sz) / sizeof(sz[0]);
	FILETIME ft;

	while (ERROR_SUCCESS == RegEnumKeyEx (hk, 0, sz, &dwSize, NULL, NULL, NULL, &ft)) {
		lRes = recursiveDeleteKey (hk, sz);

		if(lRes != ERROR_SUCCESS)
			break;

		dwSize = sizeof(sz) / sizeof(sz[0]);
	}

	RegCloseKey (hk);

	return RegDeleteKey (hkParent, szKey);
}


int wmain (int argc, WCHAR **argv) {
	WCHAR *pPgmName = argv[0];

	if ((argc > 1) && (wcsicmp (argv[1], L"-s") == 0)) {
		--argc; ++argv;
		fSerial = TRUE;
	}

	if ((argc == 2) && (wcsicmp (argv[1], L"install") == 0)) {
		HMODULE hCoreDll = LoadLibrary (L"coredll.dll");
		if (hCoreDll) {
			BOOL   (*pCeRunAppAtEvent) (TCHAR *pwszAppName, LONG lWhichEvent);
			pCeRunAppAtEvent = (BOOL (*) (TCHAR *pwszAppName, LONG lWhichEvent))GetProcAddress (hCoreDll, L"CeRunAppAtEvent");
			if (pCeRunAppAtEvent) {
				pCeRunAppAtEvent (pPgmName, 0);
				pCeRunAppAtEvent (pPgmName, NOTIFICATION_EVENT_WAKEUP);
			}
			FreeLibrary (hCoreDll);
		}
		
		exit (0);
	}

	if ((argc == 2) && (wcsicmp (argv[1], L"uninstall") == 0)) {
		recursiveDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Bluetooth");

		HMODULE hCoreDll = LoadLibrary (L"coredll.dll");

		if (hCoreDll) {
			BOOL   (*pCeRunAppAtEvent) (TCHAR *pwszAppName, LONG lWhichEvent);
			pCeRunAppAtEvent = (BOOL (*) (TCHAR *pwszAppName, LONG lWhichEvent))GetProcAddress (hCoreDll, L"CeRunAppAtEvent");
			if (pCeRunAppAtEvent)
				pCeRunAppAtEvent (pPgmName, 0);
			FreeLibrary (hCoreDll);
		}

		SetTdi (L"notdi");

		DebugOut (L"Uninstalled successfully\n");
		exit(0);
	}

	if ((argc == 2) && (wcsicmp (argv[1], L"load") == 0)) {
		HANDLE hDevice = RegisterDevice (L"BTD", 0, L"btd.dll", 0);

		DebugOut (L"hDevice = 0x%08x GetLastError = 0x%08x (%d)\n", hDevice, GetLastError (), GetLastError ());

		if (hDevice) {
			HKEY hk;
			if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Bluetooth", 0, KEY_READ, &hk)) {
				RegSetValueEx (hk, L"btd_handle", 0, REG_DWORD, (LPBYTE)&hDevice, sizeof(hDevice));
				RegCloseKey (hk);
			}
		}

		exit (0);
	}

	if ((argc == 2) && (wcsicmp (argv[1], L"unload") == 0)) {
		HKEY hk;
		if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Bluetooth", 0, KEY_READ, &hk)) {
			HANDLE hDevice = NULL;
			DWORD dwSize = sizeof (hDevice);
			DWORD dwType;

			if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"btd_handle", NULL, &dwType, (LPBYTE)&hDevice, &dwSize)) &&
				(dwType == REG_DWORD) && (dwSize == sizeof (hDevice)) && hDevice) {
				DebugOut (L"DeregisterDevice = %d, GetLastError = 0x%08x (%d)\n", DeregisterDevice (hDevice), GetLastError (), GetLastError ());
				RegDeleteValue (hk, L"btd_handle");
			}
			RegCloseKey (hk);
		}
		exit (0);
	}

	if ((argc == 3) && (wcsicmp (argv[1], L"console") == 0) && ((wcsicmp (argv[2], L"on") == 0) || (wcsicmp (argv[2], L"off") == 0))) {
		HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
									FILE_SHARE_READ | FILE_SHARE_WRITE,
									NULL, OPEN_EXISTING, 0, NULL);

		if (hDev == INVALID_HANDLE_VALUE) {
			DebugOut (L"Device not loaded!\n");
			exit (1);
		}

		int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_CONSOLE, argv[2], sizeof(WCHAR) * (wcslen (argv[2]) + 1), NULL, NULL, NULL, NULL);
		DebugOut (L"Result = %d\n", iErr);
		CloseHandle (hDev);
		exit (0);

	}

	if ((argc == 3) && (wcsicmp (argv[1], L"debugout") == 0) && ((wcsicmp (argv[2], L"console") == 0) || (wcsicmp (argv[2], L"serial") == 0) || (wcsicmp (argv[2], L"file") == 0) || (wcsicmp (argv[2], L"reopen") == 0) || (wcsicmp (argv[2], L"celog") == 0))) {
		HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
									FILE_SHARE_READ | FILE_SHARE_WRITE,
									NULL, OPEN_EXISTING, 0, NULL);

		if (hDev == INVALID_HANDLE_VALUE) {
			DebugOut (L"Device not loaded!\n");
			exit (1);
		}

		int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_DEBUG, argv[2], sizeof(WCHAR) * (wcslen (argv[2]) + 1), NULL, NULL, NULL, NULL);
		DebugOut (L"Result = %d\n", iErr);
		CloseHandle (hDev);
		exit (0);
	}

	if ((argc == 3) && (wcsicmp (argv[1], L"debug") == 0)) {
		WCHAR *p = argv[2];
		DWORD dw = 0;
		int fDwordArg = FALSE;

		if (GetUx (&p, &dw, 8))
			fDwordArg = TRUE;

		HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
									FILE_SHARE_READ | FILE_SHARE_WRITE,
									NULL, OPEN_EXISTING, 0, NULL);

		if (hDev == INVALID_HANDLE_VALUE) {
			DebugOut (L"Device not loaded!\n");
			exit (1);
		}

		int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_DEBUG, fDwordArg ? (void *)&dw : (void *)argv[2],
						fDwordArg ? sizeof(dw) : (wcslen (argv[2]) + 1) * sizeof(WCHAR), NULL,
						NULL, NULL, NULL);
		DebugOut (L"Result = %d\n", iErr);
		CloseHandle (hDev);
		exit (0);

	}

	if ((argc > 1) && ((wcsicmp (argv[1], APP_RUN_AFTER_WAKEUP) == 0) ||
			(wcsicmp (argv[1], L"refresh") == 0))) {
		HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
									FILE_SHARE_READ | FILE_SHARE_WRITE,
									NULL, OPEN_EXISTING, 0, NULL);

		if (hDev == INVALID_HANDLE_VALUE) {
			exit (1);
		}

		int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_REFRESH, NULL, 0, NULL, NULL, NULL, NULL);
		CloseHandle (hDev);
		exit (0);
	}

	if (((argc == 3) && (wcsicmp (argv[1], L"celog") == 0) && ((wcsicmp (argv[2], L"on") == 0) || (wcsicmp (argv[2], L"off") == 0)))) {
		HKEY hk;
		DWORD dwDisp;
		if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Bluetooth\\debug", 0, NULL, 0, 0, NULL, &hk, &dwDisp)) {
			DWORD dw = (wcsicmp (argv[2], L"on") == 0) ? TRUE : FALSE;
			RegSetValueEx (hk, L"celog", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
			RegCloseKey (hk);
		}
		exit (0);
	}


	if (((argc == 3) && (wcsicmp (argv[2], L"card") == 0) && ((wcsicmp (argv[1], L"start") == 0) || (wcsicmp (argv[1], L"stop") == 0)))) {
		DWORD ictl = 0;

		WCHAR *argPtr = argv[2];

		if (wcsicmp (argv[1], L"start") == 0)
			ictl = IOCTL_SERVICE_START;
		else
			ictl = IOCTL_SERVICE_STOP;

		HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE,
									FILE_SHARE_READ | FILE_SHARE_WRITE,
									NULL, OPEN_EXISTING, 0, NULL);

		if (hDev == INVALID_HANDLE_VALUE) {
			DebugOut (L"Device not loaded!\n");
			exit (1);
		}

		int iErr = DeviceIoControl (hDev, ictl, argPtr, sizeof(WCHAR) * (wcslen (argPtr) + 1), NULL, NULL, NULL, NULL);
		DebugOut (L"Result = %d\n", iErr);
		CloseHandle (hDev);
		exit (0);

	}

	DebugOut (L"Use:\n\t%s install\n", pPgmName);
	DebugOut (L"\t%s uninstall\n", pPgmName);
	DebugOut (L"\t%s load\n", pPgmName);
	DebugOut (L"\t%s unload\n", pPgmName);
	DebugOut (L"\t%s start card\n", pPgmName);
	DebugOut (L"\t%s stop card\n", pPgmName);
	DebugOut (L"\t%s console {on|off}\n", pPgmName);
	DebugOut (L"\t%s celog {on|off}\n", pPgmName);
	DebugOut (L"\t%s debugout {console|serial|file|reopen}\n", pPgmName);
	DebugOut (L"\t%s debug <hex mask>\n", pPgmName);

	return 0;
}

⌨️ 快捷键说明

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