?? ocrwblk.c
字號:
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;
PURB urb = NULL;
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;
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;
// 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;
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 ));
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;
}
NTSTATUS
BulkUsb_Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch table routine for IRP_MJ_CLOSE.
It handles user mode CloseHandle() calls for a pipe
It closes the File Object for the pipe handle it represents.
Arguments:
DeviceObject - pointer to our FDO (Functional Device Object )
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus;
NTSTATUS actStat;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
PUSBD_PIPE_INFORMATION pipeHandle = NULL;
BULKUSB_KdPrint( DBGLVL_DEFAULT,("entering BulkUsb_Close\n"));
BulkUsb_IncrementIoCount(DeviceObject);
deviceExtension = DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
if (fileObject->FsContext) {
// closing pipe handle
pipeHandle = fileObject->FsContext;
// roms: reset USB pipes (for flushing them)
//BulkUsb_ResetPipe(DeviceObject, pipeHandle );
if ( pipeHandle->PipeFlags ) { // set if opneed
// may have been aborted
BULKUSB_KdPrint( DBGLVL_DEFAULT,("closing pipe %x\n", pipeHandle));
deviceExtension->OpenPipeCount--;
pipeHandle->PipeFlags = 0;
}
else {
// pipe was already closed; this can only be if we got a sudden REMOVE_DEVICE
BULKUSB_ASSERT( deviceExtension->DeviceRemoved );
BULKUSB_KdPrint( DBGLVL_DEFAULT,("Pipe %x was already closed \n", pipeHandle));
}
}
BulkUsb_DecrementIoCount(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
// try to power down device if this is the last pipe
actStat = BulkUsb_SelfSuspendOrActivate( DeviceObject, TRUE );
BULKUSB_KdPrint( DBGLVL_DEFAULT,("exit BulkUsb_Close OpenPipeCount = decimal %d, status %x\n",deviceExtension->OpenPipeCount, ntStatus));
return ntStatus;
}
NTSTATUS
BulkUsb_Create(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch table routine for IRP_MJ_CREATE.
It's the entry point for CreateFile() calls
user mode apps may open "<name genned fron GUID>.\yy"
where yy is the internal pipe id
Arguments:
DeviceObject - pointer to our FDO ( Functional Device Object )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -