📄 usb2com.create.cpp
字号:
//********************************************************************
// created: 11:7:2008 21:27
// file: usb2com.create.cpp
// author: tiamo
// purpose: create
//********************************************************************
#include "stdafx.h"
//
// create dispatch routine
//
NTSTATUS Usb2ComCreate(__in PDEVICE_OBJECT DeviceObject,__in PIRP Irp)
{
PUSB2COM_DEVICE_EXTENSION DevExt = static_cast<PUSB2COM_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
//
// acquire remove lock
//
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;
}
//
// already opened
//
if(TRUE == InterlockedCompareExchange(&DevExt->DeviceIsOpened,TRUE,FALSE))
{
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
IoReleaseRemoveLock(&DevExt->RemoveLock,Irp);
return STATUS_ACCESS_DENIED;
}
DevExt->TxHoldReason = 0;
DevExt->RxHoldReason = 0;
DevExt->Baudrate = 115200;
DevExt->SerialLineControl.Parity = 0;
DevExt->SerialLineControl.StopBits = 1;
DevExt->SerialLineControl.WordLength = 8;
DevExt->ReadBufferCharsCount = 0;
DevExt->FirstReadCharSlot = 0;
InterlockedIncrement(&DevExt->CurrentWriteIrpSignature);
DevExt->WriteBuffer = 0;
DevExt->WriteBufferLength = 0;
DevExt->WriteBufferOffset = 0;
DevExt->ForceBulkInUrbStop = FALSE;
DevExt->ForceBulkOutUrbStop = FALSE;
DevExt->ForceInterruptUrbStop = FALSE;
Usb2ComSetBaudrate(DevExt);
Usb2ComSetLineControl(DevExt);
Usb2ComClearDTR(DevExt);
Usb2ComClearRTS(DevExt);
Usb2ComSetDTR(DevExt);
Usb2ComSetRTS(DevExt);
Usb2ComRecvVendorRequest(DevExt,0x06,&DevExt->ModemStatus);
DevExt->ModemStatus &= 0xf0;
Usb2ComStartBulkInUrb(DevExt,FALSE,0);
Usb2ComStartInterruptUrb(DevExt,FALSE,0);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
IoReleaseRemoveLock(&DevExt->RemoveLock,Irp);
return STATUS_SUCCESS;
}
//
// interrupt urb complete routine
//
NTSTATUS Usb2ComInterruptUrbComplete(__in PDEVICE_OBJECT DeviceObject,__in PIRP Irp,__in PVOID Context)
{
PUSB2COM_DEVICE_EXTENSION DevExt = static_cast<PUSB2COM_DEVICE_EXTENSION>(Context);
NTSTATUS Status = Irp->IoStatus.Status;
PURB Urb = DevExt->InterruptUrb;
PUCHAR Buffer = static_cast<PUCHAR>(Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
ULONG EventFlags = 0;
KIRQL SavedIrql;
KeAcquireSpinLock(&DevExt->InterruptLock,&SavedIrql);
//
// current interrupt urb is finished
//
DevExt->InterruptUrbIsRunning = FALSE;
if(NT_SUCCESS(Status))
{
if(Buffer[0] == 0xe8)
{
UCHAR ModemStatus = Buffer[3] & 0xf0;
if((DevExt->SerialHandFlow.ControlHandShake & SERIAL_CTS_HANDSHAKE) && !(ModemStatus & 0x10))
DevExt->TxHoldReason |= SERIAL_TX_CTS;
else
DevExt->TxHoldReason &= ~SERIAL_TX_CTS;
if((DevExt->SerialHandFlow.ControlHandShake & SERIAL_DSR_HANDSHAKE) && !(ModemStatus & 0x20))
DevExt->TxHoldReason |= SERIAL_TX_DSR;
else
DevExt->TxHoldReason &= ~SERIAL_TX_DSR;
if((DevExt->SerialHandFlow.ControlHandShake & SERIAL_DCD_HANDSHAKE) && !(ModemStatus & 0x80))
DevExt->TxHoldReason |= SERIAL_TX_DCD;
else
DevExt->TxHoldReason &= ~SERIAL_TX_DCD;
if((DevExt->SerialHandFlow.ControlHandShake & SERIAL_DSR_SENSITIVITY) && !(ModemStatus & 0x20))
DevExt->RxHoldReason |= SERIAL_RX_DSR;
else
DevExt->RxHoldReason &= ~SERIAL_RX_DSR;
DevExt->ModemStatus = ModemStatus;
ModemStatus = Buffer[3];
if(ModemStatus & 0x01)
EventFlags |= SERIAL_EV_CTS;
if(ModemStatus & 0x02)
EventFlags |= SERIAL_EV_DSR;
if(ModemStatus & 0x04)
EventFlags |= SERIAL_EV_RING;
if(ModemStatus & 0x08)
EventFlags |= SERIAL_EV_RLSD;
}
}
Usb2ComStartInterruptUrb(DevExt,TRUE,SavedIrql);
Usb2ComStartBulkInUrb(DevExt,FALSE,0);
Usb2ComStartBulkOutUrb(DevExt,FALSE,0);
if(EventFlags)
Usb2ComProcessEvent(DevExt,EventFlags);
return STATUS_MORE_PROCESSING_REQUIRED;
}
//
// send interrupt urb
//
VOID Usb2ComStartInterruptUrb(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in BOOLEAN AlreadyLocked,__in KIRQL SavedIrql)
{
BOOLEAN ReleaseLock = TRUE;
__try
{
//
// acquire interrupt lock
//
if(!AlreadyLocked)
KeAcquireSpinLock(&DevExt->InterruptLock,&SavedIrql);
//
// check interrupt urb is running
//
if(!DevExt->InterruptUrbIsRunning)
{
//
// reuse interrupt irp
//
IoReuseIrp(DevExt->InterruptIrp,STATUS_SUCCESS);
//
// short ok?
//
UsbBuildInterruptOrBulkTransferRequest(DevExt->InterruptUrb,sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER),DevExt->UsbInterfaceInfo->Pipes[0].PipeHandle,
DevExt->InterruptBuffer,0,0x04,USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,0);
PIO_STACK_LOCATION NextIrpSp = IoGetNextIrpStackLocation(DevExt->InterruptIrp);
NextIrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextIrpSp->Parameters.Others.Argument1 = DevExt->InterruptUrb;
NextIrpSp->Parameters.Others.Argument2 = 0;
NextIrpSp->Parameters.Others.Argument3 = reinterpret_cast<PVOID>(IOCTL_INTERNAL_USB_SUBMIT_URB);
NextIrpSp->Parameters.Others.Argument4 = 0;
IoSetCompletionRoutine(DevExt->InterruptIrp,&Usb2ComInterruptUrbComplete,DevExt,TRUE,TRUE,TRUE);
if(!DevExt->ForceInterruptUrbStop)
{
DevExt->InterruptUrbIsRunning = TRUE;
KeResetEvent(&DevExt->InterruptUrbStopEvent);
KeReleaseSpinLock(&DevExt->InterruptLock,SavedIrql);
ReleaseLock = FALSE;
IoCallDriver(DevExt->LowerDeviceObject,DevExt->InterruptIrp);
}
}
}
__finally
{
if(ReleaseLock)
{
BOOLEAN SetEvent = !DevExt->InterruptUrbIsRunning;
KeReleaseSpinLock(&DevExt->InterruptLock,SavedIrql);
if(SetEvent)
KeSetEvent(&DevExt->InterruptUrbStopEvent,IO_NO_INCREMENT,FALSE);
}
}
}
//
// stop interrupt urb
//
VOID Usb2ComStopInterruptUrb(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
KIRQL SavedIrql;
KeAcquireSpinLock(&DevExt->InterruptLock,&SavedIrql);
DevExt->ForceInterruptUrbStop = TRUE;
KeReleaseSpinLock(&DevExt->InterruptLock,SavedIrql);
IoCancelIrp(DevExt->InterruptIrp);
}
//
// wait interrupt urb stop
//
VOID Usb2ComWaitInterruptUrbStopped(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
KeWaitForSingleObject(&DevExt->InterruptUrbStopEvent,Executive,KernelMode,FALSE,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -