📄 ocrwblk.c
字号:
BULKUSB_KdPrint ( DBGLVL_DEFAULT, ("BulkUsb_StagedReadWrite() FAILED, ntStatus = 0x%x\n", ntStatus));
// try to reset the pipe on error ( unless device has been suddenly removed )
if ( pipeHandle && BulkUsb_CanAcceptIoRequests( DeviceObject ) ) {
resetPipeStatus = BulkUsb_ResetPipe(DeviceObject, pipeHandle );
BULKUSB_KdPrint( DBGLVL_DEFAULT, ("BulkUsb_StagedReadWrite() Tried to reset pipe 0x%x, Status = 0x%x\n", pipeHandle, resetPipeStatus));
BULKUSB_KdPrintCond ( DBGLVL_DEFAULT, (!NT_SUCCESS(resetPipeStatus)), ("BulkUsb_StagedReadWrite() BulkUsb_ResetPipe() FAILED\n"));
if( !NT_SUCCESS(resetPipeStatus) ) {
// if can't reset pipe, try to reset device ( parent port )
BULKUSB_KdPrint( DBGLVL_DEFAULT, ("Will try to reset device \n"));
resetPipeStatus = BulkUsb_ResetDevice(DeviceObject);
BULKUSB_KdPrintCond ( DBGLVL_DEFAULT, (!NT_SUCCESS(resetPipeStatus)), ("BulkUsb_StagedReadWrite() BulkUsb_ResetDevice() FAILED\n"));
}
}
} // end, if !NT_SUCCESS( ntStatus )
if ( 0 == nIrps ) {
// only complete the request here if we created no staged irps
BULKUSB_KdPrint ( DBGLVL_HIGH, ("BulkUsb_StagedReadWrite() 0 irps staged, completing base IRP now!\n"));
IoCompleteRequest (Irp, IO_NO_INCREMENT );
} else {
BULKUSB_KdPrint ( DBGLVL_HIGH, ("BulkUsb_StagedReadWrite() %d irps staged\n", nIrps));
// We need to protect the below test with the spinlock because it is possible for
// BulkUsb_AsynReadWriteComplete() to fire off while we are in this code
KeAcquireSpinLock(&deviceExtension->FastCompleteSpinlock, &OldIrql);
if ( deviceExtension->BaseIrp ) {
//
// Mark the original input Irp pending; it will be completed when the last staged irp
// is handled ( in BulkUsb_AsyncReadWrite_Complete() ).
//
BULKUSB_KdPrint ( DBGLVL_HIGH, ("BulkUsb_StagedReadWrite(),marking base IRP 0x%x pending!\n", Irp));
BULKUSB_ASSERT( Irp == deviceExtension->BaseIrp );
ntStatus = STATUS_PENDING;
Irp->IoStatus.Status = ntStatus;
IoMarkIrpPending(Irp);
} else {
// It is possible for BulkUsb_AsyncReadWrite_Complete() to have completed the
// original irp before we even get here!
// If this happens, it will have NULLED-out deviceExtension->BaseIrp.
ntStatus = STATUS_SUCCESS;
}
KeReleaseSpinLock (&deviceExtension->FastCompleteSpinlock, OldIrql);
}
BULKUSB_KdPrint ( DBGLVL_HIGH, ("BulkUsb_StagedReadWrite() StagedReadWrite ntStatus = 0x%x decimal %d\n", ntStatus, ntStatus));
BULKUSB_KdPrint ( DBGLVL_HIGH, ("EXIT BulkUsb_StagedReadWrite() gExAllocCount = dec %d\n", gExAllocCount ));
return ntStatus;
}
PURB
BulkUsb_BuildAsyncRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PUSBD_PIPE_INFORMATION PipeHandle,
IN BOOLEAN Read
)
/*++
Routine Description:
Called from BulkUsb_StageReadWrite() for IRP_MJ_READ or IRP_MJ_WRITE
Arguments:
DeviceObject - pointer to the FDO ( Functional Device Object )
Irp - A staged IRP allocated and mapped by this driver in BulkUsb_StageReadWrite()
to perform a single deviceExtension->MaximumTransferSize IO request
PipeHandle - handle to the endpoint we're reading or writing
Read - TRUE for reads, FALSE for writes
Return Value:
ptr to initialized async urb. ( USB Request Block )
--*/
{
ULONG siz;
ULONG length = 0;
PURB urb = NULL;
if (Irp->MdlAddress) { // could be NULL for 0-len request
length = MmGetMdlByteCount(Irp->MdlAddress);
}
siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
urb = BULKUSB_ExAllocatePool(NonPagedPool, siz);
BULKUSB_KdPrint( DBGLVL_MAXIMUM,("Enter BulkUsb_BuildAsyncRequest() len = 0x%x decimal %d \n siz = 0x%x urb 0x%x\n Pipehandle 0x%x\n", length, length, siz, urb, PipeHandle));
if (urb) {
RtlZeroMemory(urb, siz);
urb->UrbBulkOrInterruptTransfer.Hdr.Length = (USHORT) siz;
urb->UrbBulkOrInterruptTransfer.Hdr.Function =
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
urb->UrbBulkOrInterruptTransfer.PipeHandle =
PipeHandle->PipeHandle;
urb->UrbBulkOrInterruptTransfer.TransferFlags =
Read ? USBD_TRANSFER_DIRECTION_IN : 0;
// short packet is not treated as an error.
urb->UrbBulkOrInterruptTransfer.TransferFlags |=
USBD_SHORT_TRANSFER_OK;
//
// not using linked urb's
//
urb->UrbBulkOrInterruptTransfer.UrbLink = NULL;
urb->UrbBulkOrInterruptTransfer.TransferBufferMDL =
Irp->MdlAddress;
urb->UrbBulkOrInterruptTransfer.TransferBufferLength =
length;
BULKUSB_KdPrint( DBGLVL_MAXIMUM,("BulkUsb_BuildAsyncRequest() Init async urb Length = 0x%x decimal %d, buf = 0x%x\n",
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbBulkOrInterruptTransfer.TransferBuffer));
}
BULKUSB_KdPrint( DBGLVL_MAXIMUM,("exit BulkUsb_BuildAsyncRequest\n"));
return urb;
}
NTSTATUS
BulkUsb_AsyncReadWrite_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Completion routine for our staged read/write Irps
Arguments:
DeviceObject - Pointer to the device object for next lower device
in the driver stack;
Irp - Irp completed.
Context - Driver defined context.
Return Value:
The function value is the final status from the operation.
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
KIRQL OldIrql;
PBULKUSB_RW_CONTEXT context = Context;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExtension;
// We have to get the deviceObject from the context, since the DeviceObject passed in
// here belongs to the next lower driver in the stack because we were invoked via
// IoCallDriver in BulkUsb_StagedReadWrite()
deviceObject = context->DeviceObject;
deviceExtension = deviceObject->DeviceExtension;
// prevent BulkUsb_StagedReadWrite() from testing deviceExtension->BaseIrp while this routine is running
KeAcquireSpinLock(&deviceExtension->FastCompleteSpinlock, &OldIrql);
// Since we own the irp, the current stack location is invalid and calling IoMarkIrpPending will
// corrupt pool.
// If the lower driver returned PENDING, mark our stack location as pending also.
//if ( Irp->PendingReturned ) {
// IoMarkIrpPending(Irp);
//}
BULKUSB_ASSERT( deviceExtension->PendingIoIrps );
BULKUSB_ASSERT( deviceExtension->BaseIrp );
BULKUSB_ASSERT( context->Irp == Irp );
urb = context->Urb;
BULKUSB_KdPrint( DBGLVL_MAXIMUM, ("\n\n ENTER BulkUsb_AsyncReadWrite_Complete(): Length 0x%08X decimal %d\n Status 0x%08X\n",
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbHeader.Status));
// decrement count of staged pending irps
deviceExtension->StagedPendingIrpCount--;
// decrement the driver's overall pending irp count
BulkUsb_DecrementIoCount(deviceObject);
//
// IoCallDriver has been called on this Irp;
// Set the length based on the TransferBufferLength
// value in the URB
//
Irp->IoStatus.Information =
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
deviceExtension->StagedBytesTransferred +=
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
BULKUSB_KdPrint ( DBGLVL_MAXIMUM,("BulkUsb_AsyncReadWrite_Complete(): Staged Async Completion %d, bytes = %d\n",
deviceExtension->StagedPendingIrpCount,
deviceExtension->StagedBytesTransferred));
IoFreeIrp(context->Irp);
context->Irp = NULL;
IoFreeMdl(context->Mdl);
context->Mdl = NULL;
if (deviceExtension->StagedPendingIrpCount == 0) {
BULKUSB_KdPrint ( DBGLVL_HIGH,("BulkUsb_AsyncReadWrite_Complete(): StagedPendingIrpCount == 0, completeting BaseIrp 0x%x\n Total bytes xferred = 0x%x, decimal %d\n", deviceExtension->BaseIrp, deviceExtension->StagedBytesTransferred, deviceExtension->StagedBytesTransferred));
deviceExtension->BaseIrp->IoStatus.Status = STATUS_SUCCESS;
deviceExtension->BaseIrp->IoStatus.Information =
deviceExtension->StagedBytesTransferred;
IoCompleteRequest(deviceExtension->BaseIrp,
IO_NO_INCREMENT);
BULKUSB_ExFreePool( deviceExtension->PendingIoIrps );
deviceExtension->PendingIoIrps = NULL;
deviceExtension->BaseIrp = NULL;
// the event is only waited on if BulkUsb_CancelPendingIo() has been called
KeSetEvent(&deviceExtension->StagingDoneEvent, 1, FALSE);
}
BULKUSB_ExFreePool(urb);
BULKUSB_KdPrint ( DBGLVL_HIGH, ("Exit BulkUsb_AsyncReadWrite_Complete() gExAllocCount = dec %d\n", gExAllocCount ));
BULKUSB_KdPrint ( DBGLVL_MAXIMUM,("Exit BulkUsb_AsyncReadWrite_Complete(), ntStatus = 0x%x\n\n",ntStatus ));
KeReleaseSpinLock (&deviceExtension->FastCompleteSpinlock, OldIrql);
return ntStatus;
}
NTSTATUS
BulkUsb_SimpleReadWrite_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Completion routine for our single-urb short read/write transfers
Arguments:
DeviceObject - Pointer to the device object for next lower device
in the driver stack;
Irp - Irp completed.
Context - our FDO.
Return Value:
The function value is the final status from the operation.
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExtension;
// We have to get the deviceObject from the context, since the DeviceObject passed in
// here belongs to the next lower driver in the stack because we were invoked via
// IoCallDriver in BulkUsb_SingleUrbReadWrite(); we want OUR device object
deviceObject = (PDEVICE_OBJECT) Context;
deviceExtension = deviceObject->DeviceExtension;
urb = deviceExtension->BaseUrb; //get the urb we alloced for this xfer
// If the lower driver returned PENDING, mark our stack location as pending also.
if ( Irp->PendingReturned ) {
IoMarkIrpPending(Irp);
}
BULKUSB_KdPrint( DBGLVL_MAXIMUM, ("\n\n ENTER BulkUsb_SimpleReadWrite_Complete(): Length 0x%08X decimal %d\n Status 0x%08X\n",
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbHeader.Status));
// decrement the driver's overall pending irp count
BulkUsb_DecrementIoCount(deviceObject);
//
// IoCallDriver has been called on this Irp;
// Set the length based on the TransferBufferLength
// value in the URB
//
Irp->IoStatus.Information =
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( Irp,
IO_NO_INCREMENT);
deviceExtension->BaseUrb = NULL;
BULKUSB_ExFreePool(urb);
BULKUSB_KdPrint ( DBGLVL_MAXIMUM,("Exit BulkUsb_SimpleReadWrite_Complete(), ntStatus = 0x%x\n\n",ntStatus ));
return ntStatus;
}
NTSTATUS
BulkUsb_Read(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the IRP_MJ_READ routine set in our dispatch table;
ReadFile() calls from user mode ultimately land here
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
device.
IRP - pointer to the IRP_MJ_READ
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = BulkUsb_StagedReadWrite(DeviceObject,
Irp,
TRUE); // false to write, true to read
return ntStatus;
}
NTSTATUS
BulkUsb_Write(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the IRP_MJ_WRITE routine set in our dispatch table;
WriteFile() calls from user mode ultimately land here
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
device.
IRP - pointer to the IRP_MJ_WRITE
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = BulkUsb_StagedReadWrite(DeviceObject,
Irp,
FALSE); // false to write, true to read
return ntStatus;
}
PBULKUSB_PIPEINFO BulkUsb_PipeWithName(
IN PDEVICE_OBJECT DeviceObject,
IN PUNICODE_STRING FileName
)
/*++
Routine Description:
Given a PUSBD_PIPE_INFORMATION, return our device extension pipe info struct
that has this hanndle, else NULL
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PBULKUSB_PIPEINFO pipeInfo = NULL;
ULONG i, nameLen, ix, uval , umultiplier;
nameLen = FileName->Length;
if (nameLen != 0) {
BULKUSB_KdPrint( DBGLVL_DEFAULT,("BulkUsb_PipeWithName FileName = %ws\n", FileName->Buffer ));
// Get pipe# to open
ix = nameLen -1; // index last char of pipe name
// if last char isn't digit, decrement till it is
while( ( (FileName->Buffer[ ix ] < (WCHAR) '0') ||
(FileName->Buffer[ ix ] > (WCHAR) '9') ) && ix )
ix--;
if ( ix ) { // filename better have had at least one ascii digit!
//
// A name was specified, convert it to a pipe id.
// Parse the ansi ascii decimal 0-based pipe number
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -