📄 btloader.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 + -