📄 ircomm.c
字号:
// @parm DWORD | len | maximum length to read
// @rdesc Returns 0 for end of file, -1 for error, otherwise the number of
// bytes read. The length returned is guaranteed to be the length
// requested unless end of file or an error condition occurs.
// @remark Routine exported by a device driver. "ttt" is the string passed
// in as lpszType in RegisterDevice
DWORD
COM_Read(DWORD dwData, LPVOID pBuf, DWORD Len)
{
DWORD RxLen = 0;
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION, (TEXT("IRCOMM:+COM_Read %d\r\n"), Len));
if (!IsValidOpen(dwData)) {
SetLastError(ERROR_INVALID_HANDLE);
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR,(TEXT("IRCOMM:-COM_Read: Invalid handle\r\n")));
return -1;
}
if (!SocketsCreated)
{
if (CreateSockets() == FALSE) {
SetLastError(ERROR_GEN_FAILURE);
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR, (TEXT("IRCOMM:-COM_Read: CreateSockets failed\r\n")));
DerefOpen(dwData);
return -1;
}
}
EnterCriticalSection(&IrcommCs); // protect ring
if (State == IRCOMM_CLOSED) {
SetLastError(ERROR_GEN_FAILURE);
RxLen = -1;
goto exit;
}
if (pRxRingRead == pRxRingWrite &&
CommTimeouts.ReadTotalTimeoutConstant == MAXDWORD)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:COM_Read waiting...\r\n")));
LeaveCriticalSection(&IrcommCs);
WaitForSingleObject(hRxEvent, INFINITE);
EnterCriticalSection(&IrcommCs);
}
if (State == IRCOMM_CLOSED) {
SetLastError(ERROR_GEN_FAILURE);
goto exit;
}
for (RxLen = 0; RxLen < Len && pRxRingRead != pRxRingWrite;
RxLen++)
{
((BYTE *)pBuf)[RxLen] = *pRxRingRead++;
if (pRxRingRead == pRxRingMax)
pRxRingRead = RxRing;
}
exit:
DerefOpen(dwData);
LeaveCriticalSection(&IrcommCs);
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION, (TEXT("IRCOMM:-COM_Read: Returning %d\r\n"), RxLen));
return RxLen;
}
// @func DWORD | ttt_Write | Device write routine
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm LPCVOID | pBuf | buffer containing data
// @parm DWORD | len | maximum length to write
// @rdesc Returns -1 for error, otherwise the number of bytes written. The
// length returned is guaranteed to be the length requested unless an
// error condition occurs.
// @remark Routine exported by a device driver. "ttt" is the string passed
// in as lpszType in RegisterDevice
DWORD
COM_Write(DWORD dwData, LPCVOID pBuf, DWORD Len)
{
DWORD BytesSent = 0;
BYTE *pLast, *pRead;
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION, (TEXT("IRCOMM:+COM_Write len %d\r\n"),Len));
if (!IsValidOpen(dwData)) {
SetLastError(ERROR_INVALID_HANDLE);
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR,(TEXT("IRCOMM:-COM_Write: Invalid handle\r\n")));
return -1;
}
if (!SocketsCreated)
{
if (CreateSockets() == FALSE) {
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR, (TEXT("IRCOMM:-COM_Write: CreateSockets failed\r\n")));
DerefOpen(dwData);
SetLastError(ERROR_INTERNAL_ERROR);
return (DWORD)-1;
}
}
if (State != IRCOMM_CONNECTED)
{
if (IrCOMMConnect() == -1) {
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR, (TEXT("IRCOMM:-COM_Write: IrCOMMConnect failed\r\n")));
DerefOpen(dwData);
SetLastError(ERROR_INTERNAL_ERROR);
return (DWORD)-1;
}
}
EnterCriticalSection(&IrcommCs);
if (State == IRCOMM_CLOSED) {
BytesSent = -1;
goto exit;
}
pRead = pTxRingRead;
pLast = pRead == TxRing ? pTxRingMax-1 : pRead-1;
while (BytesSent < Len && pTxRingWrite != pLast)
{
*pTxRingWrite++ = *((BYTE *) pBuf)++;
BytesSent++;
if (pTxRingWrite == pTxRingMax)
pTxRingWrite = TxRing;
pRead = pTxRingRead;
pLast = pRead == TxRing ? pTxRingMax-1 : pRead-1;
}
if (BytesSent < Len)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IRCOMM:COM_Write TxRing overflow Sent %d, Total %d\n"), BytesSent, Len));
}
SetEvent(hTxEvent);
exit:
DerefOpen(dwData);
LeaveCriticalSection(&IrcommCs);
DEBUGMSG(ZONE_INTERFACE, (TEXT("IRCOMM:-COM_Write: returning %d\r\n"), BytesSent));
return BytesSent;
}
// @func DWORD | ttt_Seek | Device seek routine
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm long | pos | position to seek to (relative to type)
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END
// @rdesc Returns current position relative to start of file, or -1 on error
// @remark Routine exported by a device driver. "ttt" is the string passed
// in as lpszType in RegisterDevice
DWORD
COM_Seek (DWORD dwData, long pos, DWORD type)
{
return((DWORD)-1);
}
// @func void | COM_PowerUp | Device powerup routine
// @comm Called to restore device from suspend mode. You cannot call any
// routines aside from those in your dll in this call.
BOOL
COM_PowerUp(void)
{
return 0;
}
// @func void | ttt_PowerDown | Device powerdown routine
// @comm Called to suspend device. You cannot call any routines aside from
// those in your dll in this call.
void
COM_PowerDown(void)
{
}
BOOL
WaitEvent(PIRCOMM_OPEN pOpen, PULONG pEventMask)
{
DWORD Priority256 = CeGetThreadPriority(GetCurrentThread());
EnterCriticalSection(&IrcommCs);
if (State == IRCOMM_CLOSED) {
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:WaitEvent state==IRCOMM_CLOSED\r\n")));
*pEventMask = 0;
LeaveCriticalSection(&IrcommCs);
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
/* We should return immediately if mask is 0
*/
if ((vEventMask == 0) || (pOpen->dwEventMask == 0))
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:WaitEvent, empty event mask\r\n")));
*pEventMask = 0;
LeaveCriticalSection(&IrcommCs);
return FALSE;
}
CeSetThreadPriority(GetCurrentThread(), g_dwHighThreadPrio);
/* Do we need to wait?
*/
if (pOpen->dwEventMask & pOpen->dwEventData) {
goto we_gotit;
}
if (!SocketsCreated)
{
if (CreateSockets() == FALSE) {
LeaveCriticalSection(&IrcommCs);
CeSetThreadPriority(GetCurrentThread(), Priority256);
DEBUGMSG(ZONE_INTERFACE | ZONE_FUNCTION| ZONE_ERROR, (TEXT("IRCOMM:WaitEvent: CreateSockets failed\r\n")));
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:WaitEvent: Waiting for CommEvent\r\n")));
pOpen->dwWaitThds++;
WaitForSingleObject(pOpen->hCommEvent, (ULONG)0);
LeaveCriticalSection(&IrcommCs);
WaitForSingleObject(pOpen->hCommEvent, (ULONG)-1);
/* Get the critical section protecting the data
*/
EnterCriticalSection(&IrcommCs);
pOpen->dwWaitThds--;
we_gotit:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM:WaitEvent Got event %x\r\n"), pOpen->dwEventData));
/* Get the data.
*/
*pEventMask = pOpen->dwEventData;
/* Clear the events that we just handled
*/
pOpen->dwEventData = 0;
LeaveCriticalSection(&IrcommCs);
CeSetThreadPriority(GetCurrentThread(), Priority256);
return TRUE;
}
// @func BOOL | ttt_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
// @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_IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
DWORD Priority256;
PIRCOMM_OPEN pOpen;
DEBUGMSG(ZONE_INTERFACE,
(TEXT("IRCOMM:+COM_IOControl(0x%X, %d, 0x%X, %d, 0x%X, %d, 0x%X)\r\n"),
dwOpenData, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut));
if (NULL == (pOpen = IsValidOpen(dwOpenData))) {
SetLastError(ERROR_INVALID_HANDLE);
DEBUGMSG(ZONE_INTERFACE | ZONE_ERROR,(TEXT("IRCOMM:-COM_IOControl: Invalid handle\r\n")));
return -1;
}
switch (dwCode)
{
// @func BOOL | IOCTL_SERIAL_SET_BREAK_ON |
// Device IO control routine to set the break state.
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_BREAK_ON
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @remark Sets the transmission line in a break state until
// <f IOCTL_SERIAL_SET_BREAK_OFF> is called.
//
case IOCTL_SERIAL_SET_BREAK_ON:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_SET_BREAK_ON\r\n")));
break;
// @func BOOL | IOCTL_SERIAL_SET_BREAK_OFF |
// Device IO control routine to clear the break state.
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_BREAK_OFF
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @remark Restores character transmission for the communications
// device and places the transmission line in a nonbreak state
// (called after <f IOCTL_SERIAL_SET_BREAK_ON>).
//
case IOCTL_SERIAL_SET_BREAK_OFF:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_SET_BREAK_OFF\r\n")));
break;
// @func BOOL | IOCTL_SERIAL_SET_DTR |
// Device IO control routine to set DTR high.
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_DTR
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @xref <f IOCTL_SERIAL_CLR_DTR>
//
case IOCTL_SERIAL_SET_DTR:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_SET_DTR\r\n")));
break;
// @func BOOL | IOCTL_SERIAL_CLR_DTR |
// Device IO control routine to set DTR low.
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_CLR_DTR
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @xref <f IOCTL_SERIAL_SET_DTR>
//
case IOCTL_SERIAL_CLR_DTR:
DEBUGMSG(ZONE_FUNCTION, (TEXT("IRCOMM: IOCTL_SERIAL_CLR_DTR\r\n")));
break;
// @func BOOL | IOCTL_SERIAL_SET_RTS |
// Device IO control routine to set RTS high.
//
// @parm DWORD | dwOpenData | value returned from ttt_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_RTS
// @parm PBYTE | pBufIn | Ignored
// @parm DWORD | dwLenIn | Ignored
// @parm PBYTE | pBufOut | Ignored
// @parm DWORD | dwLenOut | Ignored
// @parm PDWORD | pdwActualOut | Ignored
//
// @rdesc Returns TRUE for success, FALSE for failure (and
// sets thread error code)
//
// @xref <f IOCTL_SERIAL_CLR_RTS>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -