📄 usb2com.devctrl.cpp
字号:
//********************************************************************
// created: 11:7:2008 21:31
// file: usb2com.devctrl.cpp
// author: tiamo
// purpose: device control
//********************************************************************
#include "stdafx.h"
//
// device control dispatch routine
//
NTSTATUS Usb2ComDeviceControl(__in PDEVICE_OBJECT DeviceObject,__in PIRP Irp)
{
PUSB2COM_DEVICE_EXTENSION DevExt = static_cast<PUSB2COM_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
//
// check pending remove
//
NTSTATUS Status = IoAcquireRemoveLock(&DevExt->RemoveLock,Irp);
if(!NT_SUCCESS(Status))
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Status;
}
ULONG InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Information = 0;
Status = STATUS_SUCCESS;
switch(IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SERIAL_CLEAR_STATS:
{
RtlZeroMemory(&DevExt->SerialStats,sizeof(SERIALPERF_STATS));
}
break;
case IOCTL_SERIAL_CLR_DTR:
{
Status = Usb2ComClearDTR(DevExt);
}
break;
case IOCTL_SERIAL_CLR_RTS:
{
Status = Usb2ComClearRTS(DevExt);
}
break;
case IOCTL_SERIAL_CONFIG_SIZE:
{
if(OutputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(ULONG);
*static_cast<PULONG>(SystemBuffer) = 0;
}
}
break;
case IOCTL_SERIAL_GET_BAUD_RATE:
{
if(OutputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(ULONG);
RtlCopyMemory(SystemBuffer,&DevExt->Baudrate,sizeof(ULONG));
}
}
break;
case IOCTL_SERIAL_GET_CHARS:
{
if(OutputLength < sizeof(SERIAL_CHARS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIAL_CHARS);
RtlCopyMemory(SystemBuffer,&DevExt->SerialChars,sizeof(SERIAL_CHARS));
}
}
break;
case IOCTL_SERIAL_GET_COMMSTATUS:
{
if(OutputLength < sizeof(SERIAL_STATUS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = Usb2ComUpdateSerialStatus(DevExt);
if(NT_SUCCESS(Status))
{
Information = sizeof(SERIAL_STATUS);
RtlCopyMemory(SystemBuffer,&DevExt->SerialStatus,sizeof(SERIAL_STATUS));
}
}
}
break;
case IOCTL_SERIAL_GET_HANDFLOW:
{
if(OutputLength < sizeof(SERIAL_HANDFLOW))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIAL_HANDFLOW);
RtlCopyMemory(SystemBuffer,&DevExt->SerialHandFlow,sizeof(SERIAL_HANDFLOW));
}
}
break;
case IOCTL_SERIAL_GET_LINE_CONTROL:
{
if(OutputLength < sizeof(SERIAL_LINE_CONTROL))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIAL_LINE_CONTROL);
RtlCopyMemory(SystemBuffer,&DevExt->SerialLineControl,sizeof(SERIAL_LINE_CONTROL));
}
}
break;
case IOCTL_SERIAL_GET_MODEM_CONTROL:
{
if(OutputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = Usb2ComGetModemControl(DevExt);
if(NT_SUCCESS(Status))
{
Information = sizeof(ULONG);
*static_cast<PULONG>(SystemBuffer) = DevExt->SerialModemControl;
}
}
}
break;
case IOCTL_SERIAL_GET_MODEMSTATUS:
{
if(OutputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(ULONG);
*static_cast<PULONG>(SystemBuffer) = DevExt->ModemStatus;
}
}
break;
case IOCTL_SERIAL_GET_PROPERTIES:
{
if(OutputLength < sizeof(SERIAL_COMMPROP))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIAL_COMMPROP);
RtlCopyMemory(SystemBuffer,&DevExt->SerialCommProp,sizeof(SERIAL_COMMPROP));
PSERIAL_COMMPROP Output = static_cast<PSERIAL_COMMPROP>(SystemBuffer);
Output->CurrentTxQueue = DevExt->PendingWriteCharsCount;
}
}
break;
case IOCTL_SERIAL_GET_STATS:
{
if(OutputLength < sizeof(SERIALPERF_STATS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIALPERF_STATS);
RtlCopyMemory(SystemBuffer,&DevExt->SerialStats,sizeof(SERIALPERF_STATS));
}
}
break;
case IOCTL_SERIAL_GET_TIMEOUTS:
{
if(OutputLength < sizeof(SERIAL_TIMEOUTS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(SERIAL_TIMEOUTS);
RtlCopyMemory(SystemBuffer,&DevExt->SerialTimeouts,sizeof(SERIAL_TIMEOUTS));
}
}
break;
case IOCTL_SERIAL_GET_WAIT_MASK:
{
if(OutputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Information = sizeof(ULONG);
*static_cast<PULONG>(SystemBuffer) = DevExt->CurrentWaitMask;
}
}
break;
case IOCTL_SERIAL_PURGE:
{
if(InputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
ULONG Mask = *static_cast<PULONG>(SystemBuffer);
Information = sizeof(ULONG);
if(Mask & SERIAL_PURGE_RXABORT)
{
Usb2ComCancelAllReadIrps(DevExt);
Usb2ComResetReadBufferInfo(DevExt);
}
if(Mask & SERIAL_PURGE_TXABORT)
{
Usb2ComCancelAllWriteIrps(DevExt);
DevExt->PendingWriteCharsCount = 0;
}
}
}
break;
case IOCTL_SERIAL_SET_BAUD_RATE:
{
if(InputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
DevExt->Baudrate = *static_cast<PULONG>(Irp->AssociatedIrp.SystemBuffer);
Status = Usb2ComSetBaudrate(DevExt);
}
}
break;
case IOCTL_SERIAL_SET_BREAK_OFF:
{
Status = Usb2ComSetBreakOff(DevExt);
}
break;
case IOCTL_SERIAL_SET_BREAK_ON:
{
Status = Usb2ComSetBreakOn(DevExt);
}
break;
case IOCTL_SERIAL_SET_CHARS:
{
if(InputLength < sizeof(SERIAL_CHARS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
PSERIAL_CHARS Input = static_cast<PSERIAL_CHARS>(SystemBuffer);
if(Input->XonChar == Input->XoffChar)
{
Status = STATUS_INVALID_PARAMETER;
}
else
{
RtlCopyMemory(&DevExt->SerialChars,SystemBuffer,sizeof(SERIAL_CHARS));
}
}
}
break;
case IOCTL_SERIAL_SET_DTR:
{
Status = Usb2ComSetDTR(DevExt);
}
break;
case IOCTL_SERIAL_SET_FIFO_CONTROL:
{
if(InputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
DevExt->SerialFIFOControl = *static_cast<PUCHAR>(SystemBuffer);
Status = Usb2ComSetFIFOControl(DevExt);
}
}
break;
case IOCTL_SERIAL_SET_HANDFLOW:
{
if(InputLength < sizeof(SERIAL_HANDFLOW))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
PSERIAL_HANDFLOW Input = static_cast<PSERIAL_HANDFLOW>(SystemBuffer);
if( (Input->ControlHandShake & SERIAL_CONTROL_INVALID) || (Input->FlowReplace & SERIAL_FLOW_INVALID) ||
(Input->ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK ||
Input->XonLimit < 0 || static_cast<ULONG>(Input->XonLimit) > DevExt->SerialQueueSize.InSize ||
Input->XoffLimit < 0 || static_cast<ULONG>(Input->XoffLimit) > DevExt->SerialQueueSize.OutSize)
{
Status = STATUS_INVALID_PARAMETER;
}
else
{
RtlCopyMemory(&DevExt->SerialHandFlow,SystemBuffer,sizeof(SERIAL_HANDFLOW));
}
}
}
break;
case IOCTL_SERIAL_SET_LINE_CONTROL:
{
if(InputLength < sizeof(SERIAL_LINE_CONTROL))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
RtlCopyMemory(&DevExt->SerialLineControl,SystemBuffer,sizeof(SERIAL_LINE_CONTROL));
Status = Usb2ComSetLineControl(DevExt);
}
}
break;
case IOCTL_SERIAL_SET_MODEM_CONTROL:
{
if(InputLength < sizeof(ULONG))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
DevExt->SerialModemControl = *static_cast<PUCHAR>(SystemBuffer);
Status = Usb2ComSetModemControl(DevExt);
}
}
break;
case IOCTL_SERIAL_SET_QUEUE_SIZE:
{
if(InputLength < sizeof(SERIAL_QUEUE_SIZE))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
RtlCopyMemory(&DevExt->SerialQueueSize,SystemBuffer,sizeof(SERIAL_QUEUE_SIZE));
}
}
break;
case IOCTL_SERIAL_SET_RTS:
{
Status = Usb2ComSetRTS(DevExt);
}
break;
case IOCTL_SERIAL_SET_TIMEOUTS:
{
if(InputLength < sizeof(SERIAL_TIMEOUTS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
PSERIAL_TIMEOUTS Input = static_cast<PSERIAL_TIMEOUTS>(SystemBuffer);
if(Input->ReadIntervalTimeout == MAXULONG && Input->ReadTotalTimeoutConstant == MAXULONG && Input->ReadTotalTimeoutConstant == MAXULONG)
Status = STATUS_INVALID_PARAMETER;
else
RtlCopyMemory(&DevExt->SerialTimeouts,SystemBuffer,sizeof(SERIAL_TIMEOUTS));
}
}
break;
//case IOCTL_SERIAL_SET_WAIT_MASK:
// break;
//case IOCTL_SERIAL_WAIT_ON_MASK:
// break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
if(Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
IoReleaseRemoveLock(&DevExt->RemoveLock,Irp);
}
return Status;
}
//
// updater serial status
//
NTSTATUS Usb2ComUpdateSerialStatus(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
DevExt->SerialStatus.AmountInInQueue = DevExt->ReadBufferCharsCount;
DevExt->SerialStatus.AmountInOutQueue = DevExt->PendingWriteCharsCount;
DevExt->SerialStatus.EofReceived = FALSE;
DevExt->SerialStatus.Errors = 0;
DevExt->SerialStatus.WaitForImmediate = FALSE;
DevExt->SerialStatus.HoldReasons = 0;
if(DevExt->TxHoldReason & SERIAL_TX_CTS)
DevExt->SerialStatus.HoldReasons |= SERIAL_TX_WAITING_FOR_CTS;
if(DevExt->TxHoldReason & SERIAL_TX_DSR)
DevExt->SerialStatus.HoldReasons |= SERIAL_TX_WAITING_FOR_DSR;
if(DevExt->TxHoldReason & SERIAL_TX_DCD)
DevExt->SerialStatus.HoldReasons |= SERIAL_TX_WAITING_FOR_DCD;
if(DevExt->RxHoldReason & SERIAL_RX_DSR)
DevExt->SerialStatus.HoldReasons |= SERIAL_RX_WAITING_FOR_DSR;
return STATUS_SUCCESS;
}
//
// process event
//
NTSTATUS Usb2ComProcessEvent(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in ULONG EventFlags)
{
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -