tony.jiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-17
  • 最后登录2011-08-04
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望53点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
阅读:4796回复:7

有人懂SCSI和u盘通信的吗?

楼主#
更多 发布于:2007-04-27 10:12
  我在做USB key ,遇到了一写麻烦,传输scsi遇到问题?

希望牛人能帮帮我呀?感激呀.
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-04-27 12:58
把问题贴出来看看
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
tony.jiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-17
  • 最后登录2011-08-04
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望53点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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驱动代码
tony.jiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-17
  • 最后登录2011-08-04
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望53点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
地板#
发布于: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
zhengv
驱动牛犊
驱动牛犊
  • 注册日期2004-12-06
  • 最后登录2008-03-06
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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;
}
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-04-30 13:36
你在做98吗?怎么驱动也出来了。可是98也不支持spti耶

说一下详细的错误代码和sese code,否则空口白话的,有什么好谈?
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
tony.jiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-17
  • 最后登录2011-08-04
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望53点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-05-08 09:10
xp下的驱动呀
tony.jiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-17
  • 最后登录2011-08-04
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望53点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-05-08 09:24
我做的是USBKEY, 我是用xpddk下的东西bulk only修改的,固件是fat16的,Bus Hound没有抓到什么东西,不知道是驱动还是固件的问题,用debugview执行到里面了,bulk only 的用文件读取也不行
游客

返回顶部