- UID
- 104868
- 性别
- 男
|
NTSTATUS
UsbStore_Pnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
PUSB_DEVICE_EXTENSION pUsbDeviceExtension;
PIO_STACK_LOCATION irpStackLocation;
irpStackLocation = IoGetCurrentIrpStackLocation(Irp);
pUsbDeviceExtension = DeviceObject->DeviceExtension;
if(pUsbDeviceExtension->DeviceType == USBSTORE_FDO)
{
switch(irpStackLocation->MinorFunction)
{
case IRP_MN_STOP_DEVICE:
status = UsbStore_UsbFdoStopDevice(DeviceObject,Irp);
break;
case IRP_MN_START_DEVICE:
status = UsbStore_UsbFdoStartDevice(DeviceObject,Irp);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_QUERY_STOP_DEVICE:
status = UsbStore_UsbFdoQueryRemoveDevice(DeviceObject,Irp);
break;
case IRP_MN_REMOVE_DEVICE:
status = UsbStore_UsbFdoRemoveDevice(DeviceObject,Irp);
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
status = UsbStore_UsbFdoCancelRemoveDevice(DeviceObject,Irp);
break;
case IRP_MN_QUERY_DEVICE_RELATIONS:
status = UsbStore_UsbFdoQueryDeviceRelations(DeviceObject,Irp);
break;
case IRP_MN_SURPRISE_REMOVAL:
Irp->IoStatus.Status = STATUS_SUCCESS;
default:
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pUsbDeviceExtension->UsbStore_TopOfStackDeviceObject,Irp);
return status;
}
}
else
{
switch(irpStackLocation->MinorFunction)
{
case IRP_MN_QUERY_CAPABILITIES:
status = UsbStore_StorePdoQueryCapabilities(DeviceObject,Irp);
return status;
case IRP_MN_START_DEVICE:
status = UsbStore_StorePdoStartDevice(DeviceObject,Irp);
return status;
case IRP_MN_REMOVE_DEVICE:
status = UsbStore_StoreRemoveDevice(DeviceObject,Irp);
return status;
case IRP_MN_QUERY_DEVICE_RELATIONS:
status = UsbStore_StoreQueryDeviceRelations(DeviceObject,Irp);
return status;
case IRP_MN_QUERY_DEVICE_TEXT:
status = UsbStore_StoreQueryDeviceText(DeviceObject,Irp);
return status;
case IRP_MN_QUERY_ID:
status = UsbStore_StoreQueryID(DeviceObject,Irp);
return status;
default:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;
}
}
return status;
}
本文以BULK ONLY为例来说明USB STORAGE DRIVER的传输过程。
VOID
UsbStore_BulkOnly(IN PDEVICE_OBJECT UsbStorePdo,
IN PIRP Irp)
{
PUSBSTORE_DEVICE_EXTENSION pUsbStoreDeviceExtension = UsbStorePdo->DeviceExtension;
PUSB_DEVICE_EXTENSION pUsbDeviceExtension = pUsbStoreDeviceExtension->pUsbDeviceExtension;
PIO_STACK_LOCATION nextirpst,irpst,irpStackLocation = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Srb = irpStackLocation->Parameters.Scsi.Srb;
PUCHAR pCdb = &Srb->Cdb[0];
PBULKONLY_CBW pBulkOnly_Cbw = &pUsbStoreDeviceExtension->BulkOnly_Cbw;
pUsbStoreDeviceExtension->ResaetpipeTimes = 0;
pBulkOnly_Cbw->dCbwSignature = BULKONLY_CBWSIG;
pBulkOnly_Cbw->dCbwTag = (ULONG_PTR)Irp;
pBulkOnly_Cbw->dCbwDataTransferLength = Srb->DataTransferLength;
pBulkOnly_Cbw->bmCbwFlags = ((UCHAR)Srb->SrbFlags&0xC0)<<1;
pBulkOnly_Cbw->bCbwLun = 0;
pBulkOnly_Cbw->bCbwCBLength = Srb->CdbLength;
RtlCopyMemory(pBulkOnly_Cbw->CbwCDB,pCdb,sizeof(CDB));
UsbStore_TransferData(UsbStorePdo,Irp,pUsbDeviceExtension->pBulkOutPipeInfo->PipeHandle,0,0x1F,pBulkOnly_Cbw,NULL,(PIO_COMPLETION_ROUTINE)UsbStore_BulkOnlySendCbwCompleteRoutine,0);
return;
}
根据BULK ONLY规范定义了一个结构:
typedef struct _BULKONLY_CBW{
ULONG dCbwSignature;
ULONG_PTR dCbwTag;
ULONG dCbwDataTransferLength;
UCHAR bmCbwFlags;
UCHAR bCbwLun :4;
UCHAR Reserved0:4;
UCHAR bCbwCBLength:5;
UCHAR Reserved1:3;
UCHAR CbwCDB[16];
}BULKONLY_CBW, *PBULKONLY_CBW;
注意:这个结构的长度在BULKONLY规范里是0X1F,而不是SIZEOF(BULKONLY_CBW),此值传递给UsbStore_TransferData
UsbStore_TransferData负责USB数据传输
VOID
UsbStore_TransferData(
IN PDEVICE_OBJECT UsbStorePdo,
IN PIRP Irp,
IN USBD_PIPE_HANDLE PipeHandle,
IN ULONG TransferFlags,
IN ULONG DataTransferBufferLength,
IN PVOID DataTransferBuffer,
IN PMDL DataTransferBufferMDL,
IN PIO_COMPLETION_ROUTINE CompleteRoutine,
IN PVOID Context
)
{
PUSBSTORE_DEVICE_EXTENSION pUsbStoreDeviceExtension = UsbStorePdo->DeviceExtension;
PUSB_DEVICE_EXTENSION pUsbDeviceExtension = pUsbStoreDeviceExtension->pUsbDeviceExtension;
PURB purb = &pUsbStoreDeviceExtension->CurrentUrb;
PIO_STACK_LOCATION irpStackLocation = IoGetNextIrpStackLocation(Irp);
KIRQL Irql;
RtlZeroMemory(purb,sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
UsbBuildInterruptOrBulkTransferRequest(
purb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
DataTransferBuffer,
DataTransferBufferMDL,
DataTransferBufferLength,
TransferFlags,
NULL
);
irpStackLocation->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
irpStackLocation->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
irpStackLocation->Parameters.Others.Argument1 = purb;
IoSetCompletionRoutine(Irp, CompleteRoutine, Context, TRUE, TRUE, TRUE);
KeAcquireSpinLock(&pUsbStoreDeviceExtension->SpinLock, &Irql);
pUsbStoreDeviceExtension->DeviceFlags |= TRANSFER_FINISHED;
pUsbStoreDeviceExtension->CurrentIrp = Irp;
KeReleaseSpinLock(&pUsbStoreDeviceExtension->SpinLock, Irql);
IoCallDriver(pUsbDeviceExtension->UsbStore_TopOfStackDeviceObject, Irp);
}
(未完待续) |
|