📄 mdd.c
字号:
while ( pHWIHead->OpenCnt ) {
// Read and clear any event bits
EnterCriticalSection(&(pOpenHead->CommEvents.EventCS));
ResetEvent(pOpenHead->CommEvents.hCommEvent);
dwEventData = InterlockedExchange( &(pOpenHead->CommEvents.fEventData), 0 );
DEBUGMSG (ZONE_EVENTS, (TEXT(" WaitCommEvent - Events 0x%X, Mask 0x%X, Abort %X\r\n"),
dwEventData,
pOpenHead->CommEvents.fEventMask,
pOpenHead->CommEvents.fAbort ));
// See if we got any events of interest.
if ( dwEventData & pOpenHead->CommEvents.fEventMask ) {
*pfdwEventMask = dwEventData & pOpenHead->CommEvents.fEventMask;
LeaveCriticalSection(&(pOpenHead->CommEvents.EventCS));
break;
} else {
LeaveCriticalSection(&(pOpenHead->CommEvents.EventCS));
}
// Wait for an event from PDD, or from SetCommMask
WaitForSingleObject(pOpenHead->CommEvents.hCommEvent,
(ULONG)-1);
// We should return immediately if mask was set via SetCommMask.
if ( pOpenHead->CommEvents.fAbort ) {
// We must have been terminated by SetCommMask()
// Return TRUE with a mask of 0.
DEBUGMSG (ZONE_ERROR|ZONE_EVENTS, (TEXT(" WaitCommEvent - Mask was cleared\r\n")));
*pfdwEventMask = 0;
break;
}
}
COM_DEC_USAGE_CNT(pOpenHead);
// Check and see if device was closed while we were waiting
if ( !pHWIHead->OpenCnt ) {
// Device was closed. Get out of here.
DEBUGMSG (ZONE_EVENTS|ZONE_ERROR,
(TEXT("-WaitCommEvent - device was closed\r\n")));
*pfdwEventMask = 0;
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
} else {
// We either got an event or a SetCommMask 0.
DEBUGMSG (ZONE_EVENTS,
(TEXT("-WaitCommEvent - *pfdwEventMask 0x%X\r\n"),
*pfdwEventMask));
return TRUE;
}
}
// ****************************************************************
//
// @func BOOL | SERDMA_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from SERDMA_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. "COM" is the string
// passed in as lpszType in RegisterDevice
BOOL
SERDMA_IOControl(PHW_OPEN_INFO pOpenHead,
DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
PHW_INDEP_INFO pHWIHead = pOpenHead->pSerialHead;
PHWOBJ pHWObj = NULL;
PVOID pHWHead = NULL;
PHW_VTBL pFuncTbl = NULL;
DWORD dwFlags;
PLIST_ENTRY pEntry;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION,
(TEXT("+SERDMA_IOControl(0x%X, %d, 0x%X, %d, 0x%X, %d, 0x%X)\r\n"),
pOpenHead, dwCode, pBufIn, dwLenIn, pBufOut,
dwLenOut, pdwActualOut));
if ( pHWIHead ) {
pHWObj = (PHWOBJ)pHWIHead->pHWObj;
pFuncTbl = pHWObj->pFuncTbl;
pHWHead = pHWIHead->pHWHead;
} else {
return FALSE;
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION|(ZONE_ERROR && (RetVal == FALSE)),
(TEXT("-SERDMA_IOControl %s Ecode=%d (len=%d)\r\n"),
(RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
GetLastError(), (NULL == pdwActualOut) ? 0 : *pdwActualOut));
if ( !pHWIHead->OpenCnt ) {
DEBUGMSG (ZONE_IOCTL|ZONE_ERROR,
(TEXT("SERDMA_IOControl - device was closed\r\n")));
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
if ( dwCode == IOCTL_PSL_NOTIFY ) {
PDEVICE_PSL_NOTIFY pPslPacket = (PDEVICE_PSL_NOTIFY)pBufIn;
if ( (pPslPacket->dwSize == sizeof(DEVICE_PSL_NOTIFY)) && (pPslPacket->dwFlags == DLL_PROCESS_EXITING) ) {
DEBUGMSG(ZONE_IOCTL, (TEXT("Process is exiting.\r\n")));
ProcessExiting(pOpenHead);
}
return TRUE;
}
// Make sure the caller has access permissions
// NOTE : Pay attention here. I hate to make this check repeatedly
// below, so I'll optimize it here. But as you add new ioctl's be
// sure to account for them in this if check.
if ( !( (dwCode == IOCTL_SERIAL_GET_WAIT_MASK) ||
(dwCode == IOCTL_SERIAL_SET_WAIT_MASK) ||
(dwCode == IOCTL_SERIAL_WAIT_ON_MASK) ||
(dwCode == IOCTL_SERIAL_GET_MODEMSTATUS) ||
(dwCode == IOCTL_SERIAL_GET_PROPERTIES) ||
(dwCode == IOCTL_SERIAL_GET_TIMEOUTS) ||
(dwCode == IOCTL_POWER_CAPABILITIES) ||
(dwCode == IOCTL_POWER_QUERY) ||
(dwCode == IOCTL_POWER_SET)) ) {
// If not one of the above operations, then read or write
// access permissions are required.
if ( !(pOpenHead->AccessCode & (GENERIC_READ | GENERIC_WRITE) ) ) {
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR,
(TEXT("SERDMA_Ioctl: Ioctl %x access permission failure x%X\n\r"),
dwCode, pOpenHead->AccessCode));
SetLastError (ERROR_INVALID_ACCESS);
return FALSE;
}
}
COM_INC_USAGE_CNT(pOpenHead);
switch ( dwCode ) {
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_SET_BREAK_ON |
// Device IO control routine to set the break state.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_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_IOCTL,
(TEXT(" IOCTL_SERIAL_SET_BREAK_ON\r\n")));
// A no-op for SERDMA
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_SET_BREAK_OFF |
// Device IO control routine to clear the break state.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_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_IOCTL, (TEXT(" IOCTL_SERIAL_SET_BREAK_OFF\r\n")));
// A no-op for SERDMA
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_SET_DTR |
// Device IO control routine to set DTR high.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_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_IOCTL, (TEXT(" IOCTL_SERIAL_SET_DTR\r\n")));
/* It's an error to call this if DCB uses DTR_CONTROL_HANDSHAKE.
*/
if ( pHWIHead->DCB.fDtrControl != DTR_CONTROL_HANDSHAKE ) {
// HWSetDTR is a no-op for SERDMA
} else {
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = FALSE;
}
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_CLR_DTR |
// Device IO control routine to set DTR low.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_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_IOCTL, (TEXT(" IOCTL_SERIAL_CLR_DTR\r\n")));
/* It's an error to call this if DCB uses DTR_CONTROL_HANDSHAKE.
*/
if ( pHWIHead->DCB.fDtrControl != DTR_CONTROL_HANDSHAKE ) {
// HWClearDTR is a no-op for SERDMA
} else {
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = FALSE;
}
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_SET_RTS |
// Device IO control routine to set RTS high.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_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>
//
case IOCTL_SERIAL_SET_RTS :
DEBUGMSG (ZONE_IOCTL, (TEXT(" IOCTL_SERIAL_SET_RTS\r\n")));
/* It's an error to call this if DCB uses RTS_CONTROL_HANDSHAKE.
*/
if ( pHWIHead->DCB.fRtsControl != RTS_CONTROL_HANDSHAKE ) {
// HWSetRTS is a no-op for SERDMA
} else {
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = FALSE;
}
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_CLR_RTS |
// Device IO control routine to set RTS low.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_CLR_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_SET_RTS>
//
case IOCTL_SERIAL_CLR_RTS :
DEBUGMSG (ZONE_IOCTL, (TEXT(" IOCTL_SERIAL_CLR_RTS\r\n")));
/* It's an error to call this if DCB uses RTS_CONTROL_HANDSHAKE.
*/
if ( pHWIHead->DCB.fRtsControl != RTS_CONTROL_HANDSHAKE ) {
// HWClearRTS is a no-op for SERDMA
} else {
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = FALSE;
}
break;
// ****************************************************************
//
// @func BOOL | IOCTL_SERIAL_SET_XOFF |
// Device IO control routine to cause transmission
// to act as if an XOFF character has been received.
//
// @parm DWORD | dwOpenData | value returned from SERDMA_Open call
// @parm DWORD | dwCode | IOCTL_SERIAL_SET_XOFF
// @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 threa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -