📄 ocrw.c
字号:
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
ocrw.c
Abstract:
read/write io test code
Environment:
kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
Revision History:
5-4-96 : created
--*/
#define DRIVER
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "D12.h"
#include "d12irp.h"
//******************************************************************************
//
// D12_CompletionStop()
//
// IO Completion Routine which just stops further completion of the Irp
//
//******************************************************************************
NTSTATUS
D12_CompletionStop (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
//******************************************************************************
//
// D12_GetCurrentFrame()
//
//******************************************************************************
ULONG
D12_GetCurrentFrame (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION nextStack;
NTSTATUS ntStatus;
struct _URB_GET_CURRENT_FRAME_NUMBER urb;
deviceExtension = DeviceObject->DeviceExtension;
// Initialize the URB
//
urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
urb.Hdr.Length = sizeof(urb);
urb.FrameNumber = (ULONG)-1;
// Set the IRP parameters to pass the URB down the stack
//
nextStack = IoGetNextIrpStackLocation(Irp);
nextStack->Parameters.Others.Argument1 = &urb;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
// Since this Irp is borrowed for URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
// before it is passed down later for the real URB request after this
// routine returns, set a completion routine which stop further completion
// of the Irp.
//
IoSetCompletionRoutine(
Irp,
D12_CompletionStop,
NULL, // Context
TRUE, // InvokeOnSuccess
TRUE, // InvokeOnError
TRUE // InvokeOnCancel
);
// Now pass the Irp down the stack
//
ntStatus = IoCallDriver(
deviceExtension->TopOfStackDeviceObject,
Irp
);
// Don't need to wait for completion because JD guarantees that
// URB_FUNCTION_GET_CURRENT_FRAME_NUMBER will never return STATUS_PENDING
return urb.FrameNumber;
}
//******************************************************************************
//
// D12_BuildIsoRequest()
//
//******************************************************************************
PURB
D12_BuildIsoRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PD12_PIPE PipeHandle,
IN BOOLEAN Read
)
/*++
Routine Description:
Arguments:
DeviceObject - pointer to the device extension for this instance of the
82930 device.
Irp -
PipeHandle -
Return Value:
initialized async urb.
--*/
{
ULONG siz;
ULONG length, packetSize, numPackets, i;
PURB urb = NULL;
PIO_STACK_LOCATION irpSp;
LARGE_INTEGER byteOffset;
irpSp = IoGetCurrentIrpStackLocation(Irp);
D12_KdPrint (("D12TEST.SYS: handle = 0x%x\n", PipeHandle));
length = MmGetMdlByteCount(Irp->MdlAddress);
D12_KdPrint (("D12TEST.SYS: length = 0x%x\n", length));
byteOffset = irpSp->Parameters.Read.ByteOffset;
D12_KdPrint (("D12TEST.SYS: offset = 0x%08X.%08X\n",
byteOffset.HighPart,
byteOffset.LowPart));
packetSize = PipeHandle->PipeInfo->MaximumPacketSize;
numPackets = length/packetSize;
if (numPackets*packetSize < length) {
numPackets++;
}
siz = GET_ISO_URB_SIZE(numPackets);
urb = ExAllocatePool(NonPagedPool, siz);
D12_KdPrint (("D12TEST.SYS: siz = 0x%x urb 0x%x\n", siz, urb));
if (urb) {
RtlZeroMemory(urb, siz);
urb->UrbIsochronousTransfer.Hdr.Length = (USHORT) siz;
urb->UrbIsochronousTransfer.Hdr.Function =
URB_FUNCTION_ISOCH_TRANSFER;
urb->UrbIsochronousTransfer.PipeHandle =
PipeHandle->PipeInfo->PipeHandle;
urb->UrbIsochronousTransfer.TransferFlags =
Read ? USBD_TRANSFER_DIRECTION_IN : 0;
urb->UrbIsochronousTransfer.TransferBufferMDL =
Irp->MdlAddress;
urb->UrbIsochronousTransfer.TransferBufferLength =
length;
if (byteOffset.HighPart)
{
urb->UrbIsochronousTransfer.StartFrame =
D12_GetCurrentFrame(DeviceObject, Irp) +
byteOffset.LowPart;
}
else
{
// start sending/receiving right away
urb->UrbIsochronousTransfer.TransferFlags |=
USBD_START_ISO_TRANSFER_ASAP;
}
urb->UrbIsochronousTransfer.NumberOfPackets = numPackets;
urb->UrbIsochronousTransfer.UrbLink = NULL;
for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++) {
urb->UrbIsochronousTransfer.IsoPacket[i].Offset
= i * packetSize;
}
D12_KdPrint (("D12TEST.SYS: Init iso urb Length = 0x%x buf = 0x%x\n",
urb->UrbIsochronousTransfer.TransferBufferLength,
urb->UrbIsochronousTransfer.TransferBuffer));
}
D12_KdPrint (("D12TEST.SYS: exit D12_BuildIsoRequest\n"));
return urb;
}
PURB
D12_BuildAsyncRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PD12_PIPE PipeHandle,
IN BOOLEAN Read
)
/*++
Routine Description:
Arguments:
DeviceObject - pointer to the device extension for this instance of the
82930 device.
Irp -
PipeHandle -
Return Value:
initialized async urb.
--*/
{
ULONG siz;
ULONG length;
PURB urb = NULL;
D12_KdPrint (("D12TEST.SYS: handle = 0x%x\n", PipeHandle));
length = MmGetMdlByteCount(Irp->MdlAddress);
D12_KdPrint (("D12TEST.SYS: length = 0x%x\n", length));
siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
urb = ExAllocatePool(NonPagedPool, siz);
D12_KdPrint (("D12TEST.SYS: siz = 0x%x urb 0x%x\n", siz, urb));
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->PipeInfo->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;
//
// no linkage for now
//
urb->UrbBulkOrInterruptTransfer.UrbLink = NULL;
urb->UrbBulkOrInterruptTransfer.TransferBufferMDL =
Irp->MdlAddress;
urb->UrbBulkOrInterruptTransfer.TransferBufferLength =
length;
D12_KdPrint (("D12TEST.SYS: Init async urb Length = 0x%x buf = 0x%x\n",
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbBulkOrInterruptTransfer.TransferBuffer));
}
D12_KdPrint (("D12TEST.SYS: exit D12_BuildAsyncRequest\n"));
return urb;
}
NTSTATUS
D12_AsyncReadWrite_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Arguments:
DeviceObject - Pointer to the device object for the D12 device.
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;
PD12_RW_CONTEXT context = Context;
PD12_PIPE pipeHandle;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT deviceObject;
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
urb = context->Urb;
deviceObject = context->DeviceObject;
D12_RemovePendingIrp(deviceObject, Irp);
D12_KdPrint (("D12TEST.SYS: Async Completion: Length 0x%08X, Status 0x%08X\n",
urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
urb->UrbHeader.Status));
//
// set the length based on the TransferBufferLength
// value in the URB
//
Irp->IoStatus.Information =
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
// get pipe handle
pipeHandle = fileObject->FsContext;
D12_DecrementIoCount(deviceObject);
ExFreePool(context);
ExFreePool(urb);
return ntStatus;
}
NTSTATUS
D12_IsoReadWrite_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Arguments:
DeviceObject - Pointer to the device object for the D12 device.
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 = Context;
PD12_PIPE pipeHandle;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
ULONG i;
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
//
// BUGBUG check here for interesting iso error conditions
//
D12_KdPrint (("D12TEST.SYS: Iso Completion: StartFrame 0x%08X, Status 0x%08X\n",
urb->UrbIsochronousTransfer.StartFrame,
urb->UrbHeader.Status));
for (i=0; i< urb->UrbIsochronousTransfer.NumberOfPackets; i++)
{
D12_KdPrint (("D12TEST.SYS: [%02d] Length 0x%08X, Status 0x%08X\n",
i,
urb->UrbIsochronousTransfer.IsoPacket[i].Length,
urb->UrbIsochronousTransfer.IsoPacket[i].Status
));
}
//
// set the length based on the TransferBufferLength
// value in the URB
//
Irp->IoStatus.Information =
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
// get pipe handle
pipeHandle = fileObject->FsContext;
D12_DecrementIoCount(DeviceObject);
ExFreePool(urb);
return ntStatus;
}
NTSTATUS
D12_Read(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
Return Value:
NT status code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -