📄 dunport.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
**/
//
// Registry configuration:
//
// [HKEY_LOCAL_MACHINE\Software\microsoft\bluetooth\btdun]
// "PortName"="COM8:" ; Index of real COM port
//
// [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\comspy]
// "DeviceArrayIndex"=dword:0
// "Prefix"="COM"
// "Order"=dword:0
// "Priority"=dword:0
// "Dll"="comspy.dll"
// "Index"=dword:6 ; Index of filter COM port
//
//
#include <windows.h>
#include <windev.h>
#include <pegdser.h>
#include <svsutil.hxx>
#define BTDUN_TRACE 0
#define BTDUN_FULLTRACE 0
CRITICAL_SECTION gcs;
FixedMemDescr *gpfm;
struct Handle {
Handle *pNext;
HANDLE h;
int fConnected : 1;
int fGotConnect : 1;
};
Handle *ghlist;
#define DISCONNECTED 1
#define CONNECTED 2
static Handle *GetHandle (DWORD dw, Handle **ppParent = NULL) {
Handle *pp = NULL;
Handle *ph = ghlist;
while (ph && ((DWORD)ph != dw)) {
pp = ph;
ph = ph->pNext;
}
if (ppParent)
*ppParent = pp;
return ph;
}
static BOOL WriteCommPort (HANDLE hFile, unsigned char *pBuffer, unsigned int cSize) {
DWORD dwFilledSoFar = 0;
while ((int)dwFilledSoFar < cSize) {
DWORD dwWrit = 0;
if ((! WriteFile (hFile, &(pBuffer[dwFilledSoFar]), cSize - dwFilledSoFar, &dwWrit, NULL)) &&
(dwWrit == 0)) {
DEBUGMSG(BTDUN_TRACE, (L"Error writing COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
return FALSE;
}
dwFilledSoFar += dwWrit;
}
return TRUE;
}
extern "C" BOOL WINAPI DllMain( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved) {
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
InitializeCriticalSection (&gcs);
svsutil_Initialize ();
gpfm = svsutil_AllocFixedMemDescr (sizeof(Handle), 10);
ghlist = NULL;
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection (&gcs);
if (gpfm)
svsutil_ReleaseFixedEmpty (gpfm);
svsutil_DeInitialize ();
break;
}
return TRUE;
}
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// EXECUTION THREAD: Client-application!
// These functions are only executed on the caller's thread
// i.e. the thread belongs to the client application
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// @func PVOID | COM_Init | Device initialization routine
// @parm DWORD | dwInfo | Info passed to RegisterDevice
// @rdesc Returns a DWORD which will be passed to Open & Deinit or NULL if
// unable to initialize the device.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" DWORD COM_Init (DWORD dwInfo) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Init+++/--- %d\n", dwInfo));
return (DWORD)dwInfo;
}
// @func PVOID | COM_Deinit | Device deinitialization routine
// @parm DWORD | dwData | value returned from CON_Init call
// @rdesc Returns TRUE for success, FALSE for failure.
// @remark Routine exported by a device driver. "PRF" is the string
// passed in as lpszType in RegisterDevice
extern "C" BOOL COM_Deinit(DWORD dwData) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Deinit+++/---\n"));
return TRUE;
}
// @func PVOID | COM_Open | Device open routine
// @parm DWORD | dwData | value returned from CON_Init call
// @parm DWORD | dwAccess | requested access (combination of GENERIC_READ
// and GENERIC_WRITE)
// @parm DWORD | dwShareMode | requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE)
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" DWORD COM_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Open+++ 0x%08x\n", dwData));
WCHAR szPortName[_MAX_PATH];
wsprintf (szPortName, L"COM%d:", dwData);
HANDLE h = CreateFile (szPortName, dwAccess, dwShareMode, NULL, OPEN_EXISTING, 0, NULL);
if (h == INVALID_HANDLE_VALUE) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Open--- : could not open %s, GLE = %d\n", szPortName, GetLastError ()));
return 0;
}
EnterCriticalSection (&gcs);
Handle *ph = gpfm ? (Handle *)svsutil_GetFixed (gpfm) : NULL;
if (ph) {
ph->fConnected = FALSE;
ph->fGotConnect = FALSE;
ph->h = h;
ph->pNext = ghlist;
ghlist = ph;
}
LeaveCriticalSection (&gcs);
DEBUGMSG(BTDUN_TRACE, (L"COM_Open--- : successfully opened %s, h = 0x%08x\n", szPortName, h));
return (DWORD)ph;
}
// @func BOOL | COM_Close | Device close routine
// @parm DWORD | dwOpenData | value returned from BTD_Open call
// @rdesc Returns TRUE for success, FALSE for failure
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
extern "C" BOOL COM_Close (DWORD dwData) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Close+++ 0x%08x\n", dwData));
EnterCriticalSection (&gcs);
Handle *pParent = NULL;
Handle *ph = GetHandle (dwData, &pParent);
HANDLE h = NULL;
if (ph) {
h = ph->h;
if (pParent)
pParent->pNext = ph->pNext;
else
ghlist = ph->pNext;
svsutil_FreeFixed (ph, gpfm);
}
LeaveCriticalSection (&gcs);
if (CloseHandle (h)) {
DEBUGMSG(BTDUN_TRACE, (L"COM_Close--- : successfully closed 0x%08x\n", dwData));
return TRUE;
}
DEBUGMSG(BTDUN_TRACE, (L"COM_Close--- : error closing 0x%08x, GLE = %d\n", dwData, GetLastError ()));
return FALSE;
}
#if BTDUN_FULLTRACE
#define BPR 8
void DumpBuff (WCHAR *szLineHeader, unsigned char *lpBuffer, unsigned int cBuffer) {
WCHAR szLine[5 + 7 + 2 + 4 * BPR];
for (int i = 0 ; i < (int)cBuffer ; i += BPR) {
int bpr = cBuffer - i;
if (bpr > BPR)
bpr = BPR;
wsprintf (szLine, L"%04x ", i);
WCHAR *p = szLine + wcslen (szLine);
for (int j = 0 ; j < bpr ; ++j) {
WCHAR c = (lpBuffer[i + j] >> 4) & 0xf;
if (c > 9) c += L'a' - 10; else c += L'0';
*p++ = c;
c = lpBuffer[i + j] & 0xf;
if (c > 9) c += L'a' - 10; else c += L'0';
*p++ = c;
*p++ = L' ';
}
for ( ; j < BPR ; ++j) {
*p++ = L' ';
*p++ = L' ';
*p++ = L' ';
}
*p++ = L' ';
*p++ = L' ';
*p++ = L' ';
*p++ = L'|';
*p++ = L' ';
*p++ = L' ';
*p++ = L' ';
for (j = 0 ; j < bpr ; ++j) {
WCHAR c = lpBuffer[i + j];
if ((c < L' ') || (c >= 127))
c = L'.';
*p++ = c;
}
for ( ; j < BPR ; ++j) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -