阅读:4906回复:7
有人懂SCSI和u盘通信的吗?
我在做USB key ,遇到了一写麻烦,传输scsi遇到问题?
希望牛人能帮帮我呀?感激呀. |
|
沙发#
发布于:2007-05-08 09:24
我做的是USBKEY, 我是用xpddk下的东西bulk only修改的,固件是fat16的,Bus Hound没有抓到什么东西,不知道是驱动还是固件的问题,用debugview执行到里面了,bulk only 的用文件读取也不行
|
|
板凳#
发布于:2007-05-08 09:10
xp下的驱动呀
|
|
地板#
发布于:2007-04-30 13:36
你在做98吗?怎么驱动也出来了。可是98也不支持spti耶
说一下详细的错误代码和sese code,否则空口白话的,有什么好谈? |
|
|
地下室#
发布于:2007-04-29 13:30
你可以参考一下,这是我项目里面的代码,可以向U盘发送scsi指令,U盘98以上不需要驱动。
typedef struct _SDSK_CMD { UCHAR CdbLength; UCHAR Cdb[16]; UCHAR DataIn; int DataBufferLength; PUCHAR DataBuffer; }SdskCmd; bool SendCommand(HANDLE handle, SdskCmd& cmd) { if(handle==INVALID_HANDLE_VALUE) return false; ULONG length = 0, returned = 0; BOOL status; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)); sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); sptdwb.sptd.PathId = 0; sptdwb.sptd.TargetId = 1; sptdwb.sptd.Lun = 0; sptdwb.sptd.SenseInfoLength = 24; sptdwb.sptd.TimeOutValue = 2; sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); sptdwb.sptd.DataIn= cmd.DataIn; sptdwb.sptd.DataBuffer = cmd.DataBuffer; sptdwb.sptd.CdbLength = cmd.CdbLength; memcpy(sptdwb.sptd.Cdb,cmd.Cdb,cmd.CdbLength); sptdwb.sptd.DataTransferLength = cmd.DataBufferLength; status = DeviceIoControl(handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, length, &sptdwb, length, &returned, FALSE); return status; } |
|
5楼#
发布于:2007-04-27 14:30
测试程序不能得到结果,
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; ZeroMemory(&sptdwb,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)); ULONG sectorSize=512; sptdwb.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); sptdwb.spt.PathId = 0; sptdwb.spt.TargetId = 1; sptdwb.spt.Lun = 0; sptdwb.spt.CdbLength = 10; sptdwb.spt.SenseInfoLength = 24; sptdwb.spt.DataIn = SCSI_IOCTL_DATA_OUT; sptdwb.spt.DataTransferLength = 512;//扇区大小 sptdwb.spt.TimeOutValue = 4; sptdwb.spt.DataBuffer = dataBuffer; sptdwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf); sptdwb.spt.Cdb[0] = 0x3B; sptdwb.spt.Cdb[1] = 2; // Data mode sptdwb.spt.Cdb[7] = (UCHAR)(sectorSize >> 8); // Parameter List length sptdwb.spt.Cdb[8] = 0; length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); status = DeviceIoControl(hdevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, length, &sptdwb, length, &returned, FALSE); if (!status ) { ::AfxMessageBox("IOCTL_SCSI_PASS_THROUGH not ok"); } str.Format("Data buffer length: %d",returned); ::AfxMessageBox(str); 返回的 IOCTL_SCSI_PASS_THROUGH not ok Data buffer length :0 |
|
6楼#
发布于:2007-04-27 14:27
NTSTATUS
BulkUsb_Scsi( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS status; PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(Irp); PSCSI_REQUEST_BLOCK pSrb = pIrpSp->Parameters.Scsi.Srb; BOOLEAN bComplete = TRUE; DbgPrint("BulkUsb_Scsi\n"); switch(pSrb->Function) { case SRB_FUNCTION_EXECUTE_SCSI: { status = STATUS_INVALID_PARAMETER; // validate irp if(!ValidateIrp(Irp)) break; pSrb->SrbStatus = SRB_STATUS_PENDING; pSrb->SrbStatus = SRB_STATUS_PENDING; status = InsertDeviceQueue(&deviceExtension->m_devQueue,Irp); bComplete = FALSE; } break; case SRB_FUNCTION_CLAIM_DEVICE: DbgPrint("SRB_FUNCTION_CLAIM_DEVICE %p\n",pSrb); if(!deviceExtension->m_bClaimed) { deviceExtension->m_bClaimed = TRUE; // classpnp.sys has an ASSERT on it pSrb->DataBuffer = DeviceObject; pSrb->SrbStatus = SRB_STATUS_SUCCESS; status = STATUS_SUCCESS; } else { status = STATUS_DEVICE_BUSY; pSrb->SrbStatus = SRB_STATUS_BUSY; } break; case SRB_FUNCTION_RELEASE_DEVICE: DbgPrint("SRB_FUNCTION_CLAIM_DEVICE %p\n",pSrb); deviceExtension->m_bClaimed = FALSE; pSrb->SrbStatus = SRB_STATUS_SUCCESS; status = STATUS_SUCCESS; break; case SRB_FUNCTION_FLUSH: { DbgPrint("SRB_FUNCTION_FLUSH %p\n",pSrb); pSrb->SrbStatus = SRB_STATUS_SUCCESS; status = STATUS_SUCCESS; } break; default: { DbgPrint("Unhandled srb %p,%d\n",pSrb, pSrb->Function); pSrb->SrbStatus = SRB_STATUS_ERROR; status = STATUS_NOT_SUPPORTED; break; } if(bComplete) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp,IO_NO_INCREMENT); } } return status; } // NTSTATUS PdoPassThrough( IN PDEVICE_OBJECT pPdo, IN PIRP pIrp ) { PDEVICE_EXTENSION pPdoExt; PIO_STACK_LOCATION pIrpSp; NTSTATUS status; PSCSI_PASS_THROUGH pInput; PIO_STACK_LOCATION nextStack = NULL; pPdoExt=(PDEVICE_EXTENSION)(pPdo->DeviceExtension); pIrpSp = IoGetCurrentIrpStackLocation(pIrp); DbgPrint("enter scsi PdoPassThrough scsi \n"); pInput=(PSCSI_PASS_THROUGH)pIrp->AssociatedIrp.SystemBuffer; DbgPrint("pIrpSp->Parameters.DeviceIoControl.InputBufferLength=%d\n", pIrpSp->Parameters.DeviceIoControl.InputBufferLength);//输入的问什么是长度是0 呢 DbgPrint("pInput->Length=%d\n",pInput->Length); DbgPrint("CdbLength=%d\n",pInput->CdbLength); DbgPrint("pInput->SenseInfoLength=%d\n",pInput->SenseInfoLength); DbgPrint("pInput->DataBufferOffset=%d\n",pInput->DataBufferOffset); DbgPrint("pInput->DataTransferLength=%d\n",pInput->DataTransferLength); // DbgPrint("SCSI_PASS_THROUGH=%d \n",sizeof(SCSI_PASS_THROUGH)); DbgPrint("pInput->Cdb=%d \n",sizeof(pInput->Cdb)); DbgPrint(" pInput->TimeOutValue=%d\n",pInput->TimeOutValue); if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH) || pInput->Length < sizeof(SCSI_PASS_THROUGH) || pInput->CdbLength > sizeof(pInput->Cdb) || ( pInput->SenseInfoLength && ( pInput->DataBufferOffset < sizeof(SCSI_PASS_THROUGH) || ( pInput->DataTransferLength && (LONG)pInput->TimeOutValue < 0) ) ) ) { DbgPrint("if pdopassthrouth \n"); pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp,IO_NO_INCREMENT); } else { DbgPrint("else pdopassthrouth \n"); IoCopyCurrentIrpStackLocationToNext(pIrp); nextStack = IoGetNextIrpStackLocation(pIrp); nextStack->MinorFunction = 1; // status = Umss_BulkReadWrite(pPdoExt->TopOfStackDeviceObject, pIrp); status = STATUS_NOT_IMPLEMENTED; } return status; // return STATUS_SUCCESS; } VOID StartIo( IN PDEVICE_OBJECT pFdo, IN PIRP pIrp ) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION pIrpSp; deviceExtension = pFdo->DeviceExtension; DbgPrint("enter StartIo protol \n"); pIrpSp= IoGetCurrentIrpStackLocation(pIrp); ASSERT(pIrpSp->MajorFunction == IRP_MJ_SCSI); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); // check state if( deviceExtension->CurrentDevicePowerState != PowerDeviceD0 ) { pIrp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; pIrp->IoStatus.Information = 0; pIrpSp->Parameters.Scsi.Srb->SrbStatus = SRB_STATUS_NO_DEVICE; IoCompleteRequest(pIrp,IO_NO_INCREMENT); QueueStartNext(&deviceExtension->m_devQueue); } // save the srb for request sense logic deviceExtension->Srb = pIrpSp->Parameters.Scsi.Srb; //传输cbw,对应的cbw一定要正确 CbwTransfer(pFdo,pIrp); } NTSTATUS CbwTransfer(PDEVICE_OBJECT pFdo, PIRP pIrp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; KIRQL oldIrql; PIO_STACK_LOCATION pIrpSp; CCOMMAND_BLOCK_WRAPPER* pCBW; deviceExtension = pFdo->DeviceExtension; pIrpSp=IoGetCurrentIrpStackLocation(pIrp); pCBW = &deviceExtension->m_cmd.cbw; pCBW->m_ulSig = CBW_SIGNATURE; //标志 pCBW->m_ulTag = PtrToUlong(pIrp);//标号 pCBW->m_ulDataTransferLen = pIrpSp->Parameters.Scsi.Srb->DataTransferLength;//传输长度 pCBW->m_bLun = 0; //对应的什么 pCBW->m_bCbLength = pIrpSp->Parameters.Scsi.Srb->CdbLength; RtlCopyMemory(pCBW->m_cbd,pIrpSp->Parameters.Scsi.Srb->Cdb,sizeof(pCBW->m_cbd)); pCBW->m_bFlags = (UCHAR)(pIrpSp->Parameters.Scsi.Srb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) << 1; status = SubmitBulkTransfer(pFdo,pIrp,USBD_TRANSFER_DIRECTION_OUT, pCBW,sizeof(COMMAND_BLOCK_WRAPPER), 0,CbwTransferComplete,0); return status; } NTSTATUS SubmitBulkTransfer(IN PDEVICE_OBJECT pFdo, IN PIRP pIrp, IN ULONG ulFlags, IN PVOID pTransferBuffer OPTIONAL, IN ULONG ulTransferLength OPTIONAL, IN PMDL pTransferMdl OPTIONAL, IN PIO_COMPLETION_ROUTINE pCompleteRoutine OPTIONAL, IN PVOID pCompleteContext OPTIONAL) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PURB pUrb; PIO_STACK_LOCATION pIrpSp; deviceExtension = pFdo->DeviceExtension; pUrb= deviceExtension->BaseUrb; RtlZeroMemory(pUrb,sizeof(deviceExtension->BaseUrb)); pUrb->UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER; pUrb->UrbHeader.Length = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); pUrb->UrbBulkOrInterruptTransfer.TransferBuffer = pTransferBuffer; pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength = ulTransferLength; pUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL = pTransferMdl; pUrb->UrbBulkOrInterruptTransfer.UrbLink = 0; pUrb->UrbBulkOrInterruptTransfer.TransferFlags = ulFlags; //两个通道句柄 if(USBD_TRANSFER_DIRECTION_FLAG(ulFlags) == USBD_TRANSFER_DIRECTION_OUT) { pUrb->UrbBulkOrInterruptTransfer.PipeHandle = deviceExtension->m_pBulkOutPipeInfo->PipeHandle; } else { pUrb->UrbBulkOrInterruptTransfer.PipeHandle = deviceExtension->m_pBulkInPipeInfo->PipeHandle; } pIrpSp= IoGetNextIrpStackLocation(pIrp); pIrpSp->Parameters.Others.Argument1 = pUrb; pIrpSp->Parameters.Others.Argument3 = LongToPtr(IOCTL_INTERNAL_USB_SUBMIT_URB); pIrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; if(pCompleteRoutine) IoSetCompletionRoutine( pIrp, pCompleteRoutine, pCompleteContext, TRUE, TRUE, TRUE ); status = IoCallDriver(deviceExtension->TopOfStackDeviceObject,pIrp); return status; } NTSTATUS CbwTransferComplete(IN PDEVICE_OBJECT pPdo, IN PIRP pIrp, IN PVOID pContext) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PSCSI_REQUEST_BLOCK pSrb; PIO_STACK_LOCATION pIrpSp; deviceExtension = pPdo->DeviceExtension; pIrpSp = IoGetCurrentIrpStackLocation(pIrp); pSrb= pIrpSp->Parameters.Scsi.Srb; status = pIrp->IoStatus.Status; __try { if(status != STATUS_SUCCESS) __leave; if(!pIrp->MdlAddress && pSrb == deviceExtension->Srb) { DbgPrint("transfer cbw is success!!!"); ASSERT(!pSrb->DataTransferLength); pSrb->SrbStatus = SRB_STATUS_SUCCESS; status = CswTransfer(deviceExtension->PhysicalDeviceObject,pIrp);//回传csw字节 } else { ASSERT(pSrb->DataTransferLength); //传输 status = DataTransfer(deviceExtension->PhysicalDeviceObject,pIrp); } } __finally { } return status; } NTSTATUS CswTransfer(IN PDEVICE_OBJECT pFdo, IN PIRP pIrp) { PDEVICE_EXTENSION deviceExtension; ULONG ulLength; ULONG ulFlags; PIO_STACK_LOCATION pIrpSp; KIRQL oldIrql; deviceExtension = pFdo->DeviceExtension; ulLength= sizeof(COMMAND_STATUS_WRAPPER_SMALL); ulFlags= USBD_TRANSFER_DIRECTION_IN; if( deviceExtension->m_pBulkOutPipeInfo->MaximumPacketSize == sizeof(COMMAND_STATUS_WRAPPER_BIG)) { ulLength = sizeof(COMMAND_STATUS_WRAPPER_BIG); ulFlags |= USBD_SHORT_TRANSFER_OK; } pIrpSp = IoGetCurrentIrpStackLocation(pIrp); return SubmitBulkTransfer(pFdo,pIrp,ulFlags, &deviceExtension->m_cmd.csw,ulLength,0, CswTransferComplete,0); } NTSTATUS DataTransfer(IN PDEVICE_OBJECT pFdo, IN PIRP pIrp) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION pIrpSp; PSCSI_REQUEST_BLOCK pSrb ; NTSTATUS status; PVOID pBuffer; PMDL pMdl; KIRQL oldIrql; deviceExtension = pFdo->DeviceExtension; pIrpSp = IoGetCurrentIrpStackLocation(pIrp); pSrb= pIrpSp->Parameters.Scsi.Srb; __try { ULONG ulDir = pSrb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION; ULONG ulFlags; // build urb flags if(ulDir == SRB_FLAGS_DATA_IN) ulFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK; else if(ulDir == SRB_FLAGS_DATA_OUT) ulFlags = USBD_TRANSFER_DIRECTION_OUT; else { status = STATUS_INVALID_PARAMETER; __leave; } // for request sense srb,we need usbport.sys to build an mdl if(pSrb != deviceExtension->Srb) { pMdl = 0; pBuffer = pSrb->DataBuffer; ASSERT(pBuffer); } else { // for org srb,we use pIrp->MdlAddress if(MmGetMdlVirtualAddress(pIrp->MdlAddress) == pSrb->DataBuffer) { pMdl = pIrp->MdlAddress; } else { pMdl = IoAllocateMdl(pSrb->DataBuffer,pSrb->DataTransferLength, 0,0,0); if(!pMdl) { status = STATUS_INSUFFICIENT_RESOURCES; __leave; } IoBuildPartialMdl(pIrp->MdlAddress,pMdl,pSrb->DataBuffer, pSrb->DataTransferLength); } pBuffer = 0; } status = SubmitBulkTransfer(deviceExtension->PhysicalDeviceObject,pIrp,ulFlags, pBuffer,pSrb->DataTransferLength, pMdl,DataTransferComplete,0); } __finally { // do nothing // caller will take care of it } return status; } NTSTATUS CswTransferComplete(PDEVICE_OBJECT pPdo,PIRP pIrp,PVOID pContext) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION pIrpSp; PSCSI_REQUEST_BLOCK pSrb; UCHAR uCswStatus; deviceExtension = pPdo->DeviceExtension; pIrpSp= IoGetCurrentIrpStackLocation(pIrp); pSrb= pIrpSp->Parameters.Scsi.Srb; status = pIrp->IoStatus.Status; __try { if(status != STATUS_SUCCESS) { // not pipe stall,rety > 2,then reset device if( deviceExtension->BaseUrb->UrbHeader.Status != USBD_STATUS_STALL_PID || deviceExtension->m_ulRetiesCount > 2) { // set irp status,info status = pIrp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; pIrp->IoStatus.Information = 0; // restore saved srb pIrpSp->Parameters.Scsi.Srb = deviceExtension->Srb; // set srb status pIrpSp->Parameters.Scsi.Srb->SrbStatus = SRB_STATUS_BUS_RESET; // queue reset device BulkUsb_ResetDevice(pPdo); // let IoCompleteRequest to continue the completion operation } else { // clear the stalled pipe deviceExtension->m_ulRetiesCount ++; BulkUsb_ResetDevice(pPdo); // reset pipe will use the irp to restart a csw transfer status = STATUS_MORE_PROCESSING_REQUIRED; } __leave; } // check status uCswStatus= deviceExtension->m_cmd.csw.m_ucStatus; // successfully finished if(!uCswStatus) { // current processed srb is a request sense srb for the org srb if(pSrb != deviceExtension->Srb) { // so restore the org srb in irp // and set SRB_STATUS_AUTOSENSE_VALID PSCSI_REQUEST_BLOCK pSrbUser = deviceExtension->Srb; pSrbUser->SenseInfoBufferLength = (UCHAR)(pSrb->DataTransferLength); pIrpSp->Parameters.Scsi.Srb = pSrbUser; pSrbUser->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID; pSrb = pSrbUser; } // let IoCompleteRequest to continue pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = pSrb->DataTransferLength; // start next irp QueueStartNext(&deviceExtension->m_devQueue); } else if(uCswStatus == 1 && pSrb == deviceExtension->Srb) { // transfer failed,and the sense data is availiable,so get it pSrb->DataTransferLength = 0; // explicitly disable request sense ? if( !(pSrb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE) && pSrb->SenseInfoBufferLength && pSrb->SenseInfoBuffer) { RequestSense(deviceExtension->PhysicalDeviceObject,pIrp); // we will use the irp to get sense data status = STATUS_MORE_PROCESSING_REQUIRED; } else { // let IoCompleteRequest to continue pIrp->IoStatus.Information = 0; status = pIrp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; // start next QueueStartNext(&deviceExtension->m_devQueue); } } else { status = pIrp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; pIrp->IoStatus.Information = 0; pIrpSp->Parameters.Scsi.Srb = deviceExtension->Srb; pIrpSp->Parameters.Scsi.Srb->SrbStatus = SRB_STATUS_BUS_RESET; // queue reset device BulkUsb_ResetDevice(pPdo); } } __finally { } return status; } NTSTATUS DataTransferComplete(IN PDEVICE_OBJECT pPdo, IN PIRP pIrp, IN PVOID pContext) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION pIrpSp; PSCSI_REQUEST_BLOCK pSrb; deviceExtension = pPdo->DeviceExtension; pIrpSp = IoGetCurrentIrpStackLocation(pIrp); pSrb = pIrpSp->Parameters.Scsi.Srb; status= pIrp->IoStatus.Status; __try { // free the mdl that we allocated in data transfer if( pSrb == deviceExtension->Srb && pIrp->MdlAddress != deviceExtension->BaseUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL) { IoFreeMdl(deviceExtension->BaseUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL); } if(status != STATUS_SUCCESS) __leave; if( pSrb->DataTransferLength != deviceExtension->BaseUrb->UrbBulkOrInterruptTransfer.TransferBufferLength) { pSrb->SrbStatus = SRB_STATUS_DATA_OVERRUN; } else { pSrb->SrbStatus = SRB_STATUS_SUCCESS; } CswTransfer(deviceExtension->PhysicalDeviceObject,pIrp); status = STATUS_MORE_PROCESSING_REQUIRED; } __finally { } return status; } NTSTATUS Umss_BulkReadWrite( PDEVICE_OBJECT DeviceObject, IN PIRP irp ) { PDEVICE_EXTENSION deviceExtension; PURB urb = NULL; ULONG urbSize = 0; ULONG transferFlags = 0; NTSTATUS ntStatus=STATUS_SUCCESS; ULONG bufferLength; PIO_STACK_LOCATION irpStack; irpStack= IoGetCurrentIrpStackLocation (irp); bufferLength= irpStack->Parameters.DeviceIoControl.OutputBufferLength; urbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); urb = ExAllocatePool(NonPagedPool,urbSize); if (!urb) { DbgPrint("STATUS_NO_MEMORY \n"); return STATUS_NO_MEMORY; } deviceExtension = DeviceObject->DeviceExtension; DbgPrint("begin UsbBuildInterruptOrBulkTransferRequest \n"); UsbBuildInterruptOrBulkTransferRequest(urb, (USHORT) urbSize, deviceExtension->m_pBulkInPipeInfo->PipeHandle, NULL, irp->MdlAddress, bufferLength, transferFlags, NULL); ntStatus = BulkUsb_CallUSBD(DeviceObject, urb); if (NT_SUCCESS(ntStatus)) { irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; DbgPrint("urb->UrbBulkOrInterruptTransfer.TransferBufferLength=%h \n",urb->UrbBulkOrInterruptTransfer.TransferBufferLength); } ExFreePool(urb); return ntStatus; } BOOLEAN ValidateIrp(IN PIRP pIrp) { PIO_STACK_LOCATION pIrpSp; PSCSI_REQUEST_BLOCK pSrb; ULONG ulDir; pIrpSp= IoGetCurrentIrpStackLocation(pIrp); pSrb= pIrpSp->Parameters.Scsi.Srb; ulDir = pSrb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION; if(!ulDir) { if(pSrb->DataBuffer || pSrb->DataTransferLength || pIrp->MdlAddress) { DbgPrint("Invalide Irp %p,no data transfer needed" "but pSrb->DataBuffer != 0 || pSrb->DataTransferLength != 0" "|| pIrp->MdlAddress != 0\n",pIrp); return FALSE; } return TRUE; } else if(ulDir == SRB_FLAGS_UNSPECIFIED_DIRECTION) { DbgPrint("Invalide Irp %p,transfer direction isn't set\n",pIrp); return FALSE; } else { if( !pSrb->DataTransferLength || pSrb->DataTransferLength > DEFAULT_MAX_TRANSFER_SIZE || !pIrp->MdlAddress) { DbgPrint("Invalide Irp %p,data transfer needed" "but pSrb->DataBuffer == 0 || " "pSrb->DataTransferLength > DEFAULT_MAX_TRANSFER_SIZE ||" "pIrp->MdlAddress == 0\n",pIrp); return FALSE; } } return TRUE; } NTSTATUS RequestSense(IN PDEVICE_OBJECT pFdo, IN OUT PIRP pIrp) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION pIrpSp; PSCSI_REQUEST_BLOCK pSrbSense; deviceExtension = pFdo->DeviceExtension; pIrpSp= IoGetCurrentIrpStackLocation(pIrp); pIrpSp->Parameters.Scsi.Srb = &deviceExtension->m_srbRequestSense; pSrbSense= &deviceExtension->m_srbRequestSense; RtlZeroMemory(pSrbSense,sizeof(SCSI_REQUEST_BLOCK)); pSrbSense->Length = sizeof(SCSI_REQUEST_BLOCK); // zero memory will do it //pSrbSense->Function = SRB_FUNCTION_EXECUTE_SCSI; pSrbSense->CdbLength = CDB12GENERIC_LENGTH; // disable sense for this srb pSrbSense->SrbFlags = SRB_FLAGS_DISABLE_AUTOSENSE | SRB_FLAGS_DATA_IN; pSrbSense->DataBuffer = deviceExtension->m_pUserSubmittedSrb->SenseInfoBuffer; pSrbSense->DataTransferLength = deviceExtension->m_pUserSubmittedSrb->SenseInfoBufferLength; pSrbSense->Cdb[0] = SCSIOP_REQUEST_SENSE; pSrbSense->Cdb[4] = deviceExtension->m_pUserSubmittedSrb->SenseInfoBufferLength; // do a cbw-data-csw transfer return CbwTransfer(pFdo,pIrp); } 这是写的SCSI驱动代码 |
|
7楼#
发布于:2007-04-27 12:58
把问题贴出来看看
|
|
|