📄 serioct.cpp
字号:
// serioct.cpp - implementation of serial IOCTL functions
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060 USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================
#include <vdw.h>
#include "serdev.h"
#include "glbtrace.h"
/////////////////////////////////////////////////////////////////////////////
//
// This module contains dispatch routine DeviceControl and most of
// overridable functions that implement the IOCTL interface of the
// serial device
//
/////////////////////////////////////////////////////////////////////////////
// DeviceControl
//
NTSTATUS SerialDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
I.Information() = 0;
switch (I.IoctlCode())
{
///////////////////////////////////////////////////////////////////
// Set Baud Rate
case IOCTL_SERIAL_SET_BAUD_RATE:
{
PSERIAL_BAUD_RATE pBR;
pBR = PSERIAL_BAUD_RATE(I.IoctlBuffer());
GTRACE( (TLEVEL,"--IOCTL_SERIAL_SET_BAUD_RATE, rate=%d\n", pBR->BaudRate) );
if (I.IoctlInputBufferSize() < sizeof(SERIAL_BAUD_RATE) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlSetBaudRate( *pBR );
status = STATUS_SUCCESS;
}
break;
}
///////////////////////////////////////////////////////////////////
// Get Baud Rate
case IOCTL_SERIAL_GET_BAUD_RATE:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_BAUD_RATE\n"));
if (I.IoctlOutputBufferSize() < sizeof(SERIAL_BAUD_RATE) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlGetBaudRate(*(SERIAL_BAUD_RATE*)I.IoctlBuffer());
I.Information() = sizeof(SERIAL_BAUD_RATE);
status = STATUS_SUCCESS;
}
break;
///////////////////////////////////////////////////////////////////
// Set Line Control (parity, data bits, stop bits)
case IOCTL_SERIAL_SET_LINE_CONTROL:
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_LINE_CONTROL: %x\n", *(UCHAR*)I.IoctlBuffer()));
if (I.IoctlInputBufferSize() < sizeof(SERIAL_LINE_CONTROL) )
status = STATUS_BUFFER_TOO_SMALL;
else
status = IoctlSetLineControl(*(SERIAL_LINE_CONTROL*)I.IoctlBuffer());
break;
///////////////////////////////////////////////////////////////////
// Get Line Control (parity, data bits, stop bits)
case IOCTL_SERIAL_GET_LINE_CONTROL:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_LINE_CONTROL\n"));
if (I.IoctlOutputBufferSize() < sizeof(SERIAL_LINE_CONTROL) )
status = STATUS_INVALID_PARAMETER;
else
{
IoctlGetLineControl(*(SERIAL_LINE_CONTROL*)I.IoctlBuffer());
I.Information() = sizeof (SERIAL_LINE_CONTROL);
status = STATUS_SUCCESS;
}
break;
///////////////////////////////////////////////////////////////////
// Reset device
//
case IOCTL_SERIAL_RESET_DEVICE:
GTRACE((TLEVEL,"--IOCTL_SERIAL_RESET_DEVICE\n"));
IoctlReset();
status = STATUS_SUCCESS;
break;
///////////////////////////////////////////////////////////////////
// Set Handshake / Flow control
//
case IOCTL_SERIAL_GET_HANDFLOW:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_HANDFLOW\n"));
if (I.IoctlOutputBufferSize() < sizeof SERIAL_HANDFLOW)
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlGetHandFlow(*(SERIAL_HANDFLOW*)I.IoctlBuffer());
I.Information() = sizeof(SERIAL_HANDFLOW);
status = STATUS_SUCCESS;
}
break;
///////////////////////////////////////////////////////////////////
// Set Handshake / Flow control
//
case IOCTL_SERIAL_SET_HANDFLOW:
{
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_HANDFLOW\n");)
SERIAL_HANDFLOW& hf = *(SERIAL_HANDFLOW*)I.IoctlBuffer();
GTRACE((TLEVEL,"- Handshake=%x, FlowReplace=%x", hf.ControlHandShake, hf.FlowReplace));
// Validate parameters
if (I.IoctlInputBufferSize() < sizeof(SERIAL_HANDFLOW) )
status = STATUS_BUFFER_TOO_SMALL;
else if ( (hf.ControlHandShake & SERIAL_CONTROL_INVALID) ||
(hf.FlowReplace & SERIAL_FLOW_INVALID) ||
((hf.ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK) ||
(hf.XonLimit < 0) ||
(hf.XoffLimit < 0)
)
status = STATUS_INVALID_PARAMETER;
else
status = IoctlSetHandFlow(hf);
break;
}
///////////////////////////////////////////////////////////////////
// Set DTR
//
case IOCTL_SERIAL_SET_DTR:
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_DTR\n");)
IoctlSetDTR(TRUE);
status = STATUS_SUCCESS;
break;
///////////////////////////////////////////////////////////////////
// Clear DTR
//
case IOCTL_SERIAL_CLR_DTR:
GTRACE((TLEVEL,"--IOCTL_SERIAL_CLR_DTR\n");)
IoctlSetDTR(FALSE);
status = STATUS_SUCCESS;
break;
///////////////////////////////////////////////////////////////////
// Set RTS
//
case IOCTL_SERIAL_SET_RTS:
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_RTS\n");)
IoctlSetRTS(TRUE);
status = STATUS_SUCCESS;
break;
///////////////////////////////////////////////////////////////////
// Clear RTS
//
case IOCTL_SERIAL_CLR_RTS:
GTRACE((TLEVEL,"--IOCTL_SERIAL_CLR_RTS\n");)
IoctlSetRTS(FALSE);
break;
///////////////////////////////////////////////////////////////////
// Get Special Characters
//
case IOCTL_SERIAL_GET_CHARS:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_CHARS\n");)
if (I.IoctlOutputBufferSize() < sizeof(SERIAL_CHARS) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlGetSpecialCharacters( *(SERIAL_CHARS*)I.IoctlBuffer());
I.Information() = sizeof(SERIAL_CHARS);
status = STATUS_SUCCESS;
}
break;
///////////////////////////////////////////////////////////////////
// Set Special Characters
//
case IOCTL_SERIAL_SET_CHARS:
{
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_CHARS\n");)
SERIAL_CHARS* p = (SERIAL_CHARS*)I.IoctlBuffer();
GTRACE((TLEVEL," --event char=%c\n", p->EventChar));
GTRACE((TLEVEL," -- eof char=%x\n", p->EofChar));
GTRACE((TLEVEL," --error char=%x\n", p->ErrorChar));
GTRACE((TLEVEL," --break char=%x\n", p->BreakChar));
GTRACE((TLEVEL," -- xon char=%x\n", p->XonChar));
GTRACE((TLEVEL," -- xoff char=%x\n", p->XoffChar));
if (I.IoctlInputBufferSize() < sizeof(SERIAL_CHARS) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlSetSpecialCharacters( *(SERIAL_CHARS*)I.IoctlBuffer());
status = STATUS_SUCCESS;
}
break;
}
///////////////////////////////////////////////////////////////////
// Set Timeouts
//
case IOCTL_SERIAL_SET_TIMEOUTS:
{
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_TIMEOUTS\n");)
SERIAL_TIMEOUTS* p=(SERIAL_TIMEOUTS*)I.IoctlBuffer();
GTRACE((TLEVEL," ReadTotalConst=%x\n", p->ReadTotalTimeoutConstant));
GTRACE((TLEVEL," ReadTotalMulti=%x\n", p->ReadTotalTimeoutMultiplier));
GTRACE((TLEVEL," ReadInterval=%x\n", p->ReadIntervalTimeout));
GTRACE((TLEVEL," WriteTotalConst=%x\n", p->WriteTotalTimeoutConstant));
GTRACE((TLEVEL," WriteTotalMulti=%x\n", p->WriteTotalTimeoutMultiplier));
if (I.IoctlInputBufferSize() < sizeof(SERIAL_TIMEOUTS) )
return STATUS_BUFFER_TOO_SMALL;
else
{
IoctlSetTimeOuts( *(SERIAL_TIMEOUTS*)I.IoctlBuffer());
status = STATUS_SUCCESS;
}
break;
}
///////////////////////////////////////////////////////////////////
// Get Timeouts
//
case IOCTL_SERIAL_GET_TIMEOUTS:
{
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_TIMEOUTS\n");)
if (I.IoctlOutputBufferSize() < sizeof(SERIAL_TIMEOUTS) )
return STATUS_BUFFER_TOO_SMALL;
else
{
IoctlGetTimeOuts( *(SERIAL_TIMEOUTS*)I.IoctlBuffer());
I.Information() = sizeof(SERIAL_TIMEOUTS);
status = STATUS_SUCCESS;
SERIAL_TIMEOUTS* p=(SERIAL_TIMEOUTS*)I.IoctlBuffer();
GTRACE((TLEVEL," ReadTotalConst=%x\n", p->ReadTotalTimeoutConstant));
GTRACE((TLEVEL," ReadTotalMulti=%x\n", p->ReadTotalTimeoutMultiplier));
GTRACE((TLEVEL," ReadInterval=%x\n", p->ReadIntervalTimeout));
GTRACE((TLEVEL," WriteTotalConst=%x\n", p->WriteTotalTimeoutConstant));
GTRACE((TLEVEL," WriteTotalMulti=%x\n", p->WriteTotalTimeoutMultiplier));
}
break;
}
#if NTVERSION > 351
///////////////////////////////////////////////////////////////////
// Get Statistics
//
case IOCTL_SERIAL_GET_STATS:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_STATS\n"));
if (I.IoctlOutputBufferSize() < sizeof (SERIALPERF_STATS) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
IoctlGetStatistics(*(SERIALPERF_STATS*)I.IoctlBuffer());
I.Information() = sizeof(SERIALPERF_STATS);
status = STATUS_SUCCESS;
}
break;
#endif
#if NTVERSION > 351
///////////////////////////////////////////////////////////////////
// Clear Statistics
//
case IOCTL_SERIAL_CLEAR_STATS:
GTRACE((TLEVEL,"--IOCTL_SERIAL_CLEAR_STATS\n");)
IoctlClearStatistics();
status = STATUS_SUCCESS;
break;
#endif
///////////////////////////////////////////////////////////////////
// Get Wait Mask
//
case IOCTL_SERIAL_GET_WAIT_MASK:
GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_WAIT_MASK\n"));
if (I.IoctlOutputBufferSize() < sizeof(ULONG) )
status = STATUS_BUFFER_TOO_SMALL;
else
{
*(ULONG*)I.IoctlBuffer() = IoctlGetWaitMask();
I.Information() = sizeof(ULONG);
status = STATUS_SUCCESS;
}
break;
///////////////////////////////////////////////////////////////////
// Set Wait Mask
//
case IOCTL_SERIAL_SET_WAIT_MASK:
GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_WAIT_MASK\n"));
GTRACE((TLEVEL,"Set wait mask to %x\n", *(ULONG*)I.IoctlBuffer()));
if (I.IoctlInputBufferSize() < sizeof(ULONG) )
status = STATUS_BUFFER_TOO_SMALL;
else if ( ~m_SupportedEvents & *(ULONG*)I.IoctlBuffer() )
status = STATUS_INVALID_PARAMETER;
else
status = m_WaitIrpQueue.QueueIrp(I);
break;
///////////////////////////////////////////////////////////////////
// Wait on Mask
//
case IOCTL_SERIAL_WAIT_ON_MASK:
GTRACE((TLEVEL,"--IOCTL_SERIAL_WAIT_ON_MASK\n"));
if (I.IoctlOutputBufferSize() < sizeof(ULONG) )
status = STATUS_BUFFER_TOO_SMALL;
else if (m_WaitMask == 0)
status = STATUS_INVALID_PARAMETER;
else
status = m_WaitIrpQueue.QueueIrp(I);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -