📄 ircomm.c
字号:
SocketsCreated = FALSE;
// make Rx/TxThread exit
SetEvent(hRxEvent);
SetEvent(hTxEvent);
if (bClose) {
CloseHandle(hTxEvent);
CloseHandle(hRxEvent);
VirtualFree(pMemBase, 0, MEM_RELEASE);
} else {
CreateSockets();
}
} else {
DEBUGMSG (1, (TEXT("IRCOMM:Shutdown called and State == IRCOMM_CLOSED\r\n")));
DEBUGMSG (1, (TEXT("IRCOMM:ListenSock=%d\r\n"), ListenSock));
DEBUGMSG (1, (TEXT("IRCOMM:ConnectSock=%d\r\n"), ConnectSock));
DEBUGMSG (1, (TEXT("IRCOMM:DataSock=%d\r\n"), DataSock));
}
LeaveCriticalSection(&IrcommCs);
}
// -----------------------------------------------------------------------------
// Function to read the thread priority from the registry.
// If it is not in the registry then a default value is returned.
// -----------------------------------------------------------------------------
static DWORD
GetRegistryThreadPriority(
LPWSTR lpszActiveKey
)
{
HKEY hDevKey;
DWORD dwValType;
DWORD dwValLen;
DWORD dwPrio;
dwPrio = DEFAULT_THREAD_PRIORITY;
hDevKey = OpenDeviceKey(lpszActiveKey);
if (hDevKey) {
dwValLen = sizeof(DWORD);
RegQueryValueEx(
hDevKey,
REGISTRY_PRIORITY_VALUE,
NULL,
&dwValType,
(PUCHAR)&dwPrio,
&dwValLen);
RegCloseKey(hDevKey);
}
return dwPrio;
}
// @func PVOID | ttt_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. "ttt" is the string passed
// in as lpszType in RegisterDevice
DWORD
COM_Init(DWORD Index)
{
DWORD i;
WORD WsaVer = WINSOCK_VERSION;
WSADATA WsaData;
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Init(%d)\r\n"), Index));
i = WSAStartup(WsaVer, &WsaData);
if (i) {
DEBUGMSG(1, (L"IRCOMM:-COM_Init:WSAStartup failed %d!!\n", i));
return 0;
}
// Retrieve higher thread priority from registry
g_dwHighThreadPrio = GetRegistryThreadPriority((LPWSTR)Index);
InitializeCriticalSection(&IrcommCs);
for (i = 0; i < MAX_OPENS; i++) {
g_Opens[i] = NULL;
}
SocketsCreated = FALSE;
DataSock = INVALID_SOCKET;
vAccessOwner = NULL;
NewState(IRCOMM_CLOSED);
DEBUGMSG (ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Init: return 1\r\n")));
return 1;
}
// @func PVOID | ttt_Deinit | Device deinitialization routine
// @parm DWORD | dwData | value returned from ttt_Init call
// @rdesc Returns TRUE for success, FALSE for failure.
// @remark Routine exported by a device driver. "ttt" is the string
// passed in as lpszType in RegisterDevice
BOOL
COM_Deinit(DWORD dwData)
{
DEBUGMSG(ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:COM_Deinit(0x%X)\r\n"), dwData));
DeleteCriticalSection(&IrcommCs);
WSACleanup();
return TRUE;
}
// @func PVOID | ttt_Open | Device open routine
// @parm DWORD | dwData | value returned from ttt_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. "ttt" is the string passed
// in as lpszType in RegisterDevice
DWORD
COM_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
DWORD dwThisOpen;
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Open(0x%X, 0x%X, 0x%X)\r\n"),
dwData, dwAccess, dwShareMode));
EnterCriticalSection(&IrcommCs);
if ((dwAccess & (GENERIC_READ|GENERIC_WRITE)) && vAccessOwner) {
LeaveCriticalSection(&IrcommCs);
SetLastError(ERROR_INVALID_ACCESS);
return 0;
}
if ((dwThisOpen = NewOpen(dwAccess)) == MAX_OPENS+1) {
LeaveCriticalSection(&IrcommCs);
SetLastError(ERROR_OPEN_FAILED);
return 0;
}
if (State != IRCOMM_CLOSED)
{
LeaveCriticalSection(&IrcommCs);
return dwThisOpen;
}
hTxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hTxEvent || !hRxEvent)
{
DEBUGMSG(ZONE_INTERFACE|ZONE_ERROR, (TEXT("IRCOMM:-COM_Open failed to create event\r\n")));
if (hTxEvent) {
CloseHandle(hTxEvent);
}
if (hRxEvent) {
CloseHandle(hRxEvent);
}
DerefOpen(dwThisOpen);
LeaveCriticalSection(&IrcommCs);
SetLastError(ERROR_OPEN_FAILED);
return 0;
}
pMemBase = (BYTE *) VirtualAlloc(NULL,
IRCOMM_TX_RING_SIZE +
IRCOMM_RX_RING_SIZE +
IRCOMM_TX_BUF_SIZE,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pMemBase == NULL)
{
DEBUGMSG(ZONE_INTERFACE|ZONE_ERROR, (TEXT("IRCOMM:-COM_Open failed to create event\r\n")));
CloseHandle(hTxEvent);
CloseHandle(hRxEvent);
DerefOpen(dwThisOpen);
LeaveCriticalSection(&IrcommCs);
SetLastError(ERROR_OPEN_FAILED);
return 0;
}
TxRing = pMemBase;
RxRing = pMemBase + IRCOMM_TX_RING_SIZE;
TxBuf = RxRing + IRCOMM_RX_RING_SIZE;
pTxRingRead = pTxRingWrite = TxRing;
pTxRingMax = TxRing + IRCOMM_TX_RING_SIZE;
pRxRingRead = pRxRingWrite = RxRing;
pRxRingMax = RxRing + IRCOMM_RX_RING_SIZE;
vEventMask = 0;
NewState(IRCOMM_OPENED);
LeaveCriticalSection(&IrcommCs);
DEBUGMSG(ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Open: Success\r\n")));
return dwThisOpen;
}
// @func BOOL | ttt_Close | Device close routine
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @rdesc Returns TRUE for success, FALSE for failure
// @remark Routine exported by a device driver. "ttt" is the string passed
// in as lpszType in RegisterDevice
BOOL
COM_Close(DWORD dwData)
{
BOOL bShutdown;
PIRCOMM_OPEN pOpen;
DWORD i;
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION | ZONE_CONN, (TEXT("IRCOMM:+COM_Close(0x%X)\r\n"), dwData));
EnterCriticalSection(&IrcommCs);
if (NULL == (pOpen = IsValidOpen(dwData))) {
SetLastError(ERROR_INVALID_HANDLE);
LeaveCriticalSection(&IrcommCs);
return FALSE;
}
for (i = pOpen->dwRefCnt; i; i--) {
SetEvent(pOpen->hCommEvent);
}
LeaveCriticalSection(&IrcommCs);
DerefOpen(dwData); // once for IsValidOpen
DerefOpen(dwData); // once to delete
EnterCriticalSection(&IrcommCs);
//
// If there are no open handles, then we need to shutdown
//
bShutdown = TRUE;
for (dwData = 0; dwData < MAX_OPENS; dwData++) {
if (g_Opens[dwData]) {
bShutdown = FALSE;
break;
}
}
if (bShutdown) {
Shutdown(TRUE); // TRUE => Close
} else {
ComputeEventMaskOR();
}
LeaveCriticalSection(&IrcommCs);
DEBUGMSG(ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Close: Success\r\n")));
return TRUE;
}
#define BIND_RETRIES 5
#define BIND_RETRY_SLEEP 500
BOOL
CreateSockets()
{
// max attribute size 6
BYTE IASSetBuff[sizeof(IAS_SET) - 3 + 6];
int IASSetLen = sizeof(IASSetBuff);
PIAS_SET pIASSet = (PIAS_SET) &IASSetBuff;
HANDLE hAcceptThread;
int Enable9WireMode = 1;
BOOL Status = FALSE;
int cBindRetry;
DEBUGMSG(ZONE_FUNCTION|ZONE_CONN, (TEXT("IRCOMM:+CreateSockets\r\n")));
EnterCriticalSection(&IrcommCs);
if (SocketsCreated)
{
Status = TRUE;
goto done;
}
if (State == IRCOMM_CLOSED)
goto done;
if ((ConnectSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets ConnectSock=socket() failed %s\n\r"), GetLastErrorText()));
goto done;
}
if ((ListenSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets ListenSock=socket() failed %s\n\r"), GetLastErrorText()));
goto done;
}
if (setsockopt(ListenSock, SOL_IRLMP, IRLMP_9WIRE_MODE,
(const char *) &Enable9WireMode, sizeof(int))
== SOCKET_ERROR)
{
goto done;
}
cBindRetry = BIND_RETRIES;
while (cBindRetry) {
if (bind(ListenSock, (const struct sockaddr *) &SockAddr, sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR) {
if (GetLastError() == WSAEADDRINUSE) {
Sleep(BIND_RETRY_SLEEP);
} else {
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets bind(ListenSock) failed %s\n\r"), GetLastErrorText()));
goto done;
}
} else {
break;
}
cBindRetry--;
}
ASSERT(cBindRetry);
if (0 == cBindRetry) {
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets bind(ListenSock) failed %s\n\r"), GetLastErrorText()));
goto done;
}
if (listen(ListenSock, 1) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets listen() failed %s\n\r"), GetLastErrorText()));
goto done;
}
/*
memset ((char *) CommTimeouts, 0, sizeof(COMMTIMEOUTS));
*/
// add IrCOMM IAS attributes
memcpy(&pIASSet->irdaClassName[0], "IrDA:IrCOMM", 12);
memcpy(&pIASSet->irdaAttribName[0], "Parameters", 11);
pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ;
pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = 6;
memcpy(&pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq[0],
"\000\001\006\001\001\001", 6);
if (setsockopt(ListenSock, SOL_IRLMP, IRLMP_IAS_SET,
(const char *) pIASSet, IASSetLen) == SOCKET_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets setsockopt(,,IRLMP_IAS_SET,,) %s\n\r"), GetLastErrorText()));
goto done;
}
if ((hAcceptThread = CreateThread(NULL, 0, AcceptThread, (PVOID)g_dwListenInstance, 0, NULL))
== 0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:CreateSockets CreateThread() failed\r\n")));
goto done;
}
CloseHandle(hAcceptThread);
SocketsCreated = TRUE;
NewState(IRCOMM_DISCOVERY_PENDING);
Status = TRUE;
done:
if (!SocketsCreated) {
if (ListenSock != INVALID_SOCKET) {
closesocket(ListenSock);
ListenSock = INVALID_SOCKET;
}
if (ConnectSock != INVALID_SOCKET) {
closesocket(ConnectSock);
ConnectSock = INVALID_SOCKET;
}
}
LeaveCriticalSection(&IrcommCs);
DEBUGMSG(ZONE_FUNCTION|ZONE_CONN, (TEXT("IRCOMM:-CreateSockets %s\r\n"), Status ? L"TRUE" : L"FALSE"));
return Status;
}
// @func DWORD | ttt_Read | Device read routine
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm LPVOID | pBuf | buffer to receive data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -