首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

UsbStorage驱动开发(三)[原创]

UsbStorage驱动开发(三)[原创]

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); } (未完待续)
Gulf

UsbStorage驱动开发(二)

在UsbStorage驱动开发(二)文章结尾处有说处理IRP_MJ_DEVICE_CONTROL中的IOCTL_STORAGE_QUERY_PROPERTY,IOCTL_SCSI_PASS_THROUGH,IOCTL_SCSI_PASS_THROUGH_DIRECT,请问怎么处理,谢谢!![em02]
不断追求,坚持不懈,迎难而上。
能否把源代码一次性提供下载,边看边分析,这样看太急人了 ^^
满佩服的,再顶一顶
请帮我分析IOCTL_STORAGE_QUERY_PROPERTY,IOCTL_SCSI_PASS_THROUGH,IOCTL_SCSI_PASS_THROUGH_DIRECT,还有IRP_MJ_DEVICE_CONTROL要处理哪些。
不断追求,坚持不懈,迎难而上。
请问处理IOCTL_STORAGE_QUERY_PROPERTY是否有问题?

case IOCTL_STORAGE_QUERY_PROPERTY: //0x2d1400

query = (PSTORAGE_PROPERTY_QUERY)ioBuffer;
header = (PSTORAGE_DESCRIPTOR_HEADER)ioBuffer;

if ((query->PropertyId == StorageAdapterProperty) && (query->QueryType == PropertyStandardQuery))
{
if (outputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER))
{
header->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);//1
header->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
Irp->IoStatus.Information = outputBufferLength;//sizeof(STORAGE_DESCRIPTOR_HEADER);
ntStatus = STATUS_SUCCESS;
BulkUmss_DbgPrint(MidDbgLevel,("sizeof(STORAGE_DESCRIPTOR_HEADER)= %d\n",sizeof(STORAGE_DESCRIPTOR_HEADER)));
}

if (outputBufferLength >= sizeof(STORAGE_ADAPTER_DESCRIPTOR))
{
adapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)header;

adapterDescriptor->MaximumTransferLength = 0x10 * PAGE_SIZE;
adapterDescriptor->MaximumPhysicalPages = 0x10;
adapterDescriptor->AlignmentMask = 1;
adapterDescriptor->AdapterUsesPio = TRUE;
adapterDescriptor->AdapterScansDown = FALSE;
adapterDescriptor->CommandQueueing = FALSE;
adapterDescriptor->AcceleratedTransfer = FALSE;
adapterDescriptor->BusType = BusTypeUsb;//BusTypeScsi
adapterDescriptor->BusMajorVersion = 1;
adapterDescriptor->BusMinorVersion = 0;

Irp->IoStatus.Information = outputBufferLength;//sizeof(STORAGE_ADAPTER_DESCRIPTOR);
ntStatus = STATUS_SUCCESS;
BulkUmss_DbgPrint(MidDbgLevel,("sizeof(STORAGE_ADAPTER_DESCRIPTOR) = %d\n",sizeof(STORAGE_ADAPTER_DESCRIPTOR)));
}
}
else if ((query->PropertyId == StorageDeviceProperty) && (query->QueryType == PropertyStandardQuery))
{
if (outputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER))
{
header->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); //1
header->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);

Irp->IoStatus.Information = outputBufferLength;//sizeof(STORAGE_DESCRIPTOR_HEADER);
ntStatus = STATUS_SUCCESS;
BulkUmss_DbgPrint(MidDbgLevel,("sizeof(STORAGE_DESCRIPTOR_HEADER)= %d\n",sizeof(STORAGE_DESCRIPTOR_HEADER)));
}

if (outputBufferLength >= sizeof(STORAGE_DEVICE_DESCRIPTOR))
{
deviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)header;

deviceDescriptor->DeviceType = DIRECT_ACCESS_DEVICE;//FILE_DEVICE_MASS_STORAGE
deviceDescriptor->DeviceTypeModifier = 0;
deviceDescriptor->RemovableMedia = TRUE;
deviceDescriptor->CommandQueueing = FALSE;
deviceDescriptor->VendorIdOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,VendorIdOffset);
deviceDescriptor->ProductIdOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,ProductIdOffset);
deviceDescriptor->ProductRevisionOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,ProductRevisionOffset);
deviceDescriptor->SerialNumberOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,SerialNumberOffset);
deviceDescriptor->BusType = BusTypeUsb;
deviceDescriptor->RawPropertiesLength = 0;

/*
fdoExtension = (PDEVICE_EXTENSION)pdoExtension->ParentFdo->DeviceExtension;
pInquiryBuf = fdoExtension->InquiryData;

deviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)header;

deviceDescriptor->DeviceType = pInquiryBuf->DeviceType;//DIRECT_ACCESS_DEVICE;//FILE_DEVICE_MASS_STORAGE
deviceDescriptor->DeviceTypeModifier = pInquiryBuf->DeviceTypeModifier;//0;
deviceDescriptor->RemovableMedia = pInquiryBuf->RemovableMedia;//TRUE;
deviceDescriptor->CommandQueueing = pInquiryBuf->CommandQueue;//FALSE;
deviceDescriptor->VendorIdOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,VendorIdOffset);
deviceDescriptor->ProductIdOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,ProductIdOffset);
deviceDescriptor->ProductRevisionOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,ProductRevisionOffset);
deviceDescriptor->SerialNumberOffset = FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR,SerialNumberOffset);
deviceDescriptor->BusType = BusTypeUsb;
deviceDescriptor->RawPropertiesLength = 0;
*/

Irp->IoStatus.Information = outputBufferLength;
ntStatus = STATUS_SUCCESS;

BulkUmss_DbgPrint(MidDbgLevel,("sizeof(STORAGE_DEVICE_DESCRIPTOR)=%d\n",sizeof(STORAGE_DEVICE_DESCRIPTOR)));
BulkUmss_DbgPrint(MidDbgLevel,("sizeof(INQUIRYDATA)=%d\n",sizeof(INQUIRYDATA)));
}
}

break;
不断追求,坚持不懈,迎难而上。
请帮我分析要不要处理IOCTL_DISK_GET_DRIVE_GEOMETRY,分析其正确性。thanks

case IOCTL_DISK_GET_DRIVE_GEOMETRY: //0x70000 Include ntdddisk.h

if (outputBufferLength>= sizeof(DISK_GEOMETRY))
{
PDISK_GEOMETRY DiskGeometry;
ULONG NumberOfBlocks;

fdoExtension = (PDEVICE_EXTENSION)pdoExtension->ParentFdo->DeviceExtension;
pInquiryBuf = fdoExtension->InquiryData;

NumberOfBlocks = 123207168;//64 * 1024 * 1024; //64M

DiskGeometry = (PDISK_GEOMETRY)ioBuffer;

DiskGeometry->Cylinders.QuadPart = (LONGLONG)((NumberOfBlocks+1) / (0x3f * 0xff * 0x200));
DiskGeometry->MediaType = pInquiryBuf->RemovableMedia;//FixedMedia;
DiskGeometry->TracksPerCylinder = 0xff; //ULONG
DiskGeometry->SectorsPerTrack = 0x3f; //ULONG
DiskGeometry->BytesPerSector = 0x200; //512
//DiskGeometry->Cylinders.QuadPart = (LONGLONG)((NumberOfBlocks+1) / (DiskGeometry->SectorsPerTrack * DiskGeometry->TracksPerCylinder));

BulkUmss_DbgPrint(MaxDbgLevel,("Cylinders.QuadPart =0x%x,MediaType = 0x%x, TracksPerCylinder = 0x%x, SectorsPerTrack =0x%x,BytesPerSector = 0x%x\n", \
DiskGeometry->Cylinders.QuadPart,DiskGeometry->MediaType,DiskGeometry->TracksPerCylinder,\
DiskGeometry->SectorsPerTrack,DiskGeometry->BytesPerSector));

Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
ntStatus = STATUS_SUCCESS;
}
else
{
ntStatus = STATUS_BUFFER_TOO_SMALL;
}

BulkUmss_DbgPrint(MaxDbgLevel,("IOCTL_DISK_GET_DRIVE_GEOMETRY. \n"));
break;
不断追求,坚持不懈,迎难而上。
maingao.你好。
我是007blue,以前我们联系过,我刚学完单片机,现在开始做U 盘,选的芯片是AT89C51SND1C,8位,它最大能做多大容量的U盘。能否发点关U盘的资料给我,我的email --zouna214@yahoo.com.cn谢谢
很不错的资料。顶
返回列表