标题:
UsbStorage驱动开发(三)[原创]
[打印本页]
作者:
maingao
时间:
2005-8-24 16:22
标题:
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); } (未完待续)
作者:
wwwwillis
时间:
2005-9-30 11:57
标题:
UsbStorage驱动开发(二)
在UsbStorage驱动开发(二)文章结尾处有说处理IRP_MJ_DEVICE_CONTROL中的IOCTL_STORAGE_QUERY_PROPERTY,IOCTL_SCSI_PASS_THROUGH,IOCTL_SCSI_PASS_THROUGH_DIRECT,请问怎么处理,谢谢!![em02]
作者:
luobing4365
时间:
2005-12-28 16:52
能否把源代码一次性提供下载,边看边分析,这样看太急人了 ^^
作者:
luobing4365
时间:
2005-12-28 16:53
满佩服的,再顶一顶
作者:
wwwwillis
时间:
2006-3-27 14:03
请帮我分析IOCTL_STORAGE_QUERY_PROPERTY,IOCTL_SCSI_PASS_THROUGH,IOCTL_SCSI_PASS_THROUGH_DIRECT,还有IRP_MJ_DEVICE_CONTROL要处理哪些。
作者:
wwwwillis
时间:
2006-3-27 14:06
请问处理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;
作者:
wwwwillis
时间:
2006-3-27 14:12
请帮我分析要不要处理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;
作者:
lantis
时间:
2006-6-4 18:39
maingao.你好。
我是007blue,以前我们联系过,我刚学完单片机,现在开始做U 盘,选的芯片是AT89C51SND1C,8位,它最大能做多大容量的U盘。能否发点关U盘的资料给我,我的email --zouna214@yahoo.com.cn谢谢
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0