?? dispatch.cpp
字號:
#include "vcp4usb.h"
#include "ntddser.h"
//
VOID CancelRoutineRead(IN PDEVICE_OBJECT PDevObj, IN PIRP Irp)
{
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)PDevObj->DeviceExtension;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
DPrint(DBG_READ, ("CancelRoutineRead() @ %d\n", KeGetCurrentIrql()));
dx->irpReadPending = NULL;
dx->needLenRx = 0;
dx->bReadPending = FALSE;
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoReleaseCancelSpinLock(Irp->CancelIrql);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
CancelTimer(&dx->readIntervalTimer);
CancelTimer(&dx->readTotalTimer);
DPrint(DBG_READ, ("CancelRoutineRead() exit\n"));
}
VOID ApcRoutineRead(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
{
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)ApcContext;
KIRQL oldIrql;
KeAcquireSpinLock(&dx->spinLock, &oldIrql);
DPrint(DBG_READ, ("ApcRoutineRead() @ %d\n", KeGetCurrentIrql()));
if (!NT_SUCCESS(IoStatusBlock->Status))
{
IoStatusBlock->Information = 0;
DPrint(DBG_READ, ("ApcRoutineRead() status:0x%x\n", IoStatusBlock->Status));
}
DPrintHex(DBG_DATALOG, ("From usb to buffer"), (dx->pRxBuf + dx->curLenRx), IoStatusBlock->Information);
dx->curLenRx += IoStatusBlock->Information;
dx->bReadPending = FALSE;
DPrint(DBG_READ, ("ApcRoutineRead():dx->irpReadPending=0x%x,dx->curLenRx=%d\n",
dx->irpReadPending, dx->curLenRx));
if (dx->curLenRx < dx->needLenRx) // need continue read
{
KeSetEvent(&dx->eventReadEnd, 1, FALSE);
}
else if (dx->irpReadPending) // sometimes irpReadPending == NULL
{
PIRP Irp = dx->irpReadPending;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG readLen = IrpStack->Parameters.Read.Length;
//ASSERT(dx->needLenRx == readLen);
DPrint(DBG_READ, ("ApcRoutineRead():dx->curLenRx=0x%x,readLen=%d\n",
dx->curLenRx, readLen));
ULONG len = (dx->curLenRx > readLen) ? readLen : dx->curLenRx;
//ASSERT(len == readLen);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
dx->pRxBuf, len * sizeof(UCHAR));
DPrintHex(DBG_DATALOG, ("From buffer to app"), dx->pRxBuf, len);
IoAcquireCancelSpinLock(&Irp->CancelIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(Irp->CancelIrql);
dx->irpReadPending = NULL;
dx->needLenRx = 0;
dx->curLenRx -= len;
if (dx->curLenRx == 0)
{
RtlZeroMemory(dx->pRxBuf, RX_BUFFER_SIZE + 1);
}
else
{
RtlMoveMemory(dx->pRxBuf, dx->pRxBuf + len,
dx->curLenRx * sizeof(UCHAR));
}
Irp->IoStatus.Information = len;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPrint(DBG_READ, ("ApcRoutineRead() return, len = %d, dx->curLenRx = %d\n",
len, dx->curLenRx));
CancelTimer(&dx->readIntervalTimer);
CancelTimer(&dx->readTotalTimer);
}
// complete wait device control irp
if (dx->curLenRx)
{
ReportEvent(dx, SERIAL_EV_RXCHAR |
((dx->curLenRx >= (RX_BUFFER_SIZE * 8/10))? SERIAL_EV_RX80FULL: 0));
}
DPrint(DBG_READ, ("ApcRoutineRead() exit\n"));
KeReleaseSpinLock(&dx->spinLock, oldIrql);
}
NTSTATUS Vcp4usbRead(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
PVCP4USB_DEVICE_EXTENSION dx=(PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
LARGE_INTEGER intervalTimeout;
LARGE_INTEGER totalTimeout;
LONG filePointer = 0;//IrpStack->Parameters.Read.ByteOffset.QuadPart;
ULONG readLen = IrpStack->Parameters.Read.Length;
DPrint(DBG_READ, ("Vcp4usbRead() @ %d : readLen=0x%x\n", KeGetCurrentIrql(), readLen));
if (readLen > RX_BUFFER_SIZE)
readLen = RX_BUFFER_SIZE;
if (readLen == 0)
return Vcp4usbCompleteIrp(Irp, STATUS_SUCCESS, 0);
if ((filePointer < 0) || (dx->irpReadPending) || (readLen > RX_BUFFER_SIZE))
{
DPrint(DBG_READ, ("Vcp4usbRead() error:fp=0x%x,irpPending=0x%x,readLen=%d\n",
filePointer, dx->irpReadPending, readLen));
return Vcp4usbCompleteIrp(Irp, STATUS_INVALID_PARAMETER, 0);
}
if (!dx->bIsConnected) // don't connected
return Vcp4usbCompleteIrp(Irp, STATUS_SUCCESS, 0);
if (((dx->curLenRx >= 0) && (dx->eventMask & SERIAL_EV_RXCHAR))
|| (dx->curLenRx >= readLen))
{
ULONG len;
KIRQL oldIrql;
KeAcquireSpinLock(&dx->spinLock, &oldIrql);
len = (dx->curLenRx > readLen) ? readLen : dx->curLenRx;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
dx->pRxBuf, len * sizeof(UCHAR));
DPrintHex(DBG_DATALOG, ("direct read to app"), dx->pRxBuf, len);
// ASSERT(dx->irpReadPending == NULL);
Irp->IoStatus.Information = len;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
dx->curLenRx -= len;
if (dx->curLenRx == 0)
{
RtlZeroMemory(dx->pRxBuf, RX_BUFFER_SIZE + 1);
}
else
{
RtlMoveMemory(dx->pRxBuf, dx->pRxBuf + len,
dx->curLenRx * sizeof(UCHAR));
}
DPrint(DBG_READ, ("Vcp4usbRead() exit, success, len=%d @ %d\n",
len, KeGetCurrentIrql()));
KeReleaseSpinLock(&dx->spinLock, oldIrql);
return STATUS_SUCCESS;
}
else if ((dx->curLenRx == 0) || (dx->curLenRx < readLen)) // rx buf is NULL or need more
{
dx->needLenRx = readLen;
IoAcquireCancelSpinLock(&Irp->CancelIrql);
if (Irp->Cancel)
{
IoReleaseCancelSpinLock(Irp->CancelIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
return STATUS_CANCELLED;
}
IoSetCancelRoutine(Irp, CancelRoutineRead);
IoReleaseCancelSpinLock(Irp->CancelIrql);
KIRQL oldIrql;
KeAcquireSpinLock(&dx->spinLock, &oldIrql);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
// start read timer
if (!CalculateReadTimeouts(dx, readLen, TRUE, &intervalTimeout, &totalTimeout))
{
if (intervalTimeout.QuadPart != 0)
{
DPrint(DBG_READ, ("start timer intervalTimeout\n"));
StartTimer(&dx->readIntervalTimer, intervalTimeout);
}
if (totalTimeout.QuadPart != 0)
{
DPrint(DBG_READ, ("start timer totalTimeout\n"));
StartTimer(&dx->readTotalTimer, totalTimeout);
}
}
dx->irpReadPending = Irp;
KeSetEvent(&dx->eventReadEnd, 1, FALSE);
DPrint(DBG_DATALOG, ("Stage Read:len=0x%x\n",readLen));
DPrint(DBG_READ, ("Vcp4usbRead() exit, pending irp=0x%x, readLen = %d @ %d\n",
Irp, readLen, KeGetCurrentIrql()));
KeReleaseSpinLock(&dx->spinLock, oldIrql);
return STATUS_PENDING;
}
//
return Vcp4usbCompleteIrp(Irp, STATUS_SUCCESS, 0);
}
//
VOID CancelRoutineWrite(IN PDEVICE_OBJECT PDevObj, IN PIRP Irp)
{
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)PDevObj->DeviceExtension;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
DPrint(DBG_WRITE, ("CancelRoutineWrite() @ %d\n", KeGetCurrentIrql()));
dx->bWritePending = FALSE;
dx->irpWritePending = NULL;
dx->curLenTx = 0;
if (dx->pTxBuf)
{
//ExFreePool(dx->pTxBuf);
dx->pTxBuf = NULL;
}
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoReleaseCancelSpinLock(Irp->CancelIrql);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
CancelTimer(&dx->writeTotalTimer);
DPrint(DBG_WRITE, ("CancelRoutineWrite() exit\n"));
}
//
VOID ApcRoutineWrite(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
{
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)ApcContext;
KIRQL oldIrql;
KeAcquireSpinLock(&dx->spinLock, &oldIrql);
DPrint(DBG_WRITE, ("ApcRoutineWrite() @ %d\n", KeGetCurrentIrql()));
if (dx->irpWritePending)
{
PIRP Irp = dx->irpWritePending;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
IoAcquireCancelSpinLock(&Irp->CancelIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(Irp->CancelIrql);
DPrint(DBG_WRITE, ("ApcRoutineWrite() complete dx->irpWritePending=0x%x\n",
dx->irpWritePending));
dx->irpWritePending = NULL;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IoStatusBlock->Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
if (dx->pTxBuf)
{
//ExFreePool(dx->pTxBuf);
dx->pTxBuf = NULL;
}
dx->curLenTx = 0;
dx->bWritePending = FALSE;
CancelTimer(&dx->writeTotalTimer);
//DPrint(DBG_DATALOG, ("Complete Write:info=0x%x\n", IoStatusBlock->Information));
ReportEvent(dx, SERIAL_EV_TXEMPTY);
DPrint(DBG_WRITE, ("ApcRoutineWrite() exit\n"));
KeReleaseSpinLock(&dx->spinLock, oldIrql);
}
NTSTATUS Vcp4usbWrite(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
DPrint(DBG_WRITE, ("Vcp4usbWrite() @ %d\n", KeGetCurrentIrql()));
LONG filePointer = 0;//IrpStack->Parameters.Write.ByteOffset.QuadPart;
ULONG writeLen = IrpStack->Parameters.Write.Length;
if (writeLen == 0)
return Vcp4usbCompleteIrp(Irp, STATUS_SUCCESS, 0);
if ((filePointer < 0) || (writeLen > TX_BUFFER_SIZE))
{
DPrint(DBG_WRITE, ("Vcp4usbWrite() error: filePointer=0x%x, writeLen=%d\n",
filePointer, writeLen));
return Vcp4usbCompleteIrp(Irp, STATUS_INVALID_PARAMETER, 0);
}
if (!dx->bIsConnected) // don't connected
return Vcp4usbCompleteIrp(Irp, STATUS_SUCCESS, 0);
if (dx->pTxBuf) // tx buf not null
{
DPrint(DBG_WRITE, ("Vcp4usbWrite() error: pTxBuf=0x%x\n", dx->pTxBuf));
return Vcp4usbCompleteIrp(Irp, STATUS_INVALID_PARAMETER, 0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -