首页
社区
课程
招聘
[求助]请问在文件系统过滤驱动要加载一个新的卷设备的时候怎么读这个卷?
发表于: 2010-4-16 13:23 3732

[求助]请问在文件系统过滤驱动要加载一个新的卷设备的时候怎么读这个卷?

2010-4-16 13:23
3732
我在sfilter里面的SfFsControlMountVolume要挂载U盘的时候我想读U盘的一个扇区,也就是vpb->RealDevice,对它构造IRP_MJ_READ然后发给他,结果IoCallDriver返回STATUS_INVALID_PARAMETER,我就想是不是U盘要构造SCSI命令然后发给他呢,后来就把机器狗的代码用过来试试,结果却读不到任何数据,还把电脑弄得没响应了,奇怪[s:39]
各位指点一下吧,代码如下:

NTSTATUS
SfFsControlMountVolumeComplete (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_OBJECT NewDeviceObject
    )
{
PVPB vpb;
PSFILTER_DEVICE_EXTENSION newDevExt;
...
vpb = newDevExt->StorageStackDeviceObject->Vpb;
...
status = SfAttachToMountedDevice( vpb->DeviceObject,
                                              NewDeviceObject );
...
ReadMbr(vpb->RealDevice); //--->里面的IoCallDriver返回STATUS_INVALID_PARAMETER
}

NTSTATUS ReadMbr(PDEVICE_OBJECT pDeviceObject)
{
    //试试在IRP完成的时候读取

    NTSTATUS            status;
    PIRP                pIrp;
    KEVENT                Event;
    IO_STATUS_BLOCK        IoStatus;
    LARGE_INTEGER        Offset;
    PVOID                pBuffer;
    PIO_STACK_LOCATION    pStackLocation;

    __asm int 3;

    Offset.QuadPart = (LONGLONG)0;

    KeInitializeEvent(&Event,NotificationEvent,FALSE);
    pBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(MBR), MY_USB_TAG);
    if (pBuffer == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
   
    pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,pDeviceObject,pBuffer,sizeof(MBR),&Offset,&Event,&IoStatus);

//     pIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,pDeviceObject,pBuffer,sizeof(MBR),&Offset,&IoStatus);
//     pIrp->UserEvent = &Event;

    status = IoCallDriver(pDeviceObject,pIrp);

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
        status = IoStatus.Status;
    }
    if (!NT_SUCCESS(status))
    {
        KdPrint(("Irp Faild! IRP = %p, status = 0x%x\n",pIrp,status));
    }

//    ExFreePoolWithTag(pBuffer,MY_USB_TAG);
    return status;
}
这里适用IRP_MJ_READ读取失败的代码,后来我换成IRP_SCSI的也就是机器狗的代码

ULONG  AtapiReadWriteDisk(PDEVICE_OBJECT dev_object,ULONG MajorFunction, PVOID buffer,ULONG DiskPos, int BlockCount)
{
    NTSTATUS status;
    PSCSI_REQUEST_BLOCK srb;
    PSENSE_DATA sense;
    KEVENT Event;
    PIRP irp;
    PMDL mdl;
    IO_STATUS_BLOCK isb;
    PIO_STACK_LOCATION isl;
    PVOID psense;
    int count=8;

    __asm int 3;

    while(1)
    {
        srb=ExAllocatePool(0,sizeof(SCSI_REQUEST_BLOCK));
        if(!srb)
            break;
        sense=ExAllocatePool(0,sizeof(SENSE_DATA));
        psense=sense;
        if(!sense)
            break;
        memset(srb,0,sizeof(SCSI_REQUEST_BLOCK));
        memset(sense,0,sizeof(SENSE_DATA));

        srb->Length=sizeof(SCSI_REQUEST_BLOCK);
        srb->Function=0;
        srb->DataBuffer=buffer;
        srb->DataTransferLength=BlockCount<<9;                //读写的扇区数
        srb->QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE;
        srb->SrbStatus=0;
        srb->ScsiStatus=0;
        srb->NextSrb=0;
        srb->SenseInfoBuffer=sense;
        srb->SenseInfoBufferLength=sizeof(SENSE_DATA);

        if(MajorFunction==IRP_MJ_READ)
        {
            srb->SrbFlags=SRB_FLAGS_DATA_IN;
            srb->SrbFlags|=SRB_FLAGS_ADAPTER_CACHE_ENABLE;
        }
        else
            srb->SrbFlags=SRB_FLAGS_DATA_OUT;

        srb->SrbFlags|=SRB_FLAGS_DISABLE_AUTOSENSE;
        srb->TimeOutValue=(srb->DataTransferLength>>10)+1;
        srb->QueueSortKey=DiskPos;
        srb->CdbLength=10;
        srb->Cdb[0]=2*((UCHAR)MajorFunction+ 17);            //OperationCode,28h表示SCSIOP_READ,2Ah表示SCSIOP_WRITE
        srb->Cdb[1]=srb->Cdb[1] & 0x1F | 0x80;
        srb->Cdb[2]=(unsigned char)(DiskPos>>0x18)&0xFF;    //CDB[2]到CDB[5]描述的是扇区位置
        srb->Cdb[3]=(unsigned char)(DiskPos>>0x10)&0xFF;    //依次为dwSectorLowPos 从高字节到低字节的值
        srb->Cdb[4]=(unsigned char)(DiskPos>>0x08)&0xFF;    //
        srb->Cdb[5]=(UCHAR)DiskPos;                            //填写sector位置
        srb->Cdb[7]=(UCHAR)BlockCount>>0x08;                //CDB[7]和CDB[8]描述了要读写的扇区数
        srb->Cdb[8]=(UCHAR)BlockCount;

        KeInitializeEvent(&Event, 0, 0);
        irp=IoAllocateIrp(dev_object->StackSize,0);
        mdl=IoAllocateMdl(buffer, BlockCount<<9, 0, 0, irp);
        irp->MdlAddress=mdl;
        if(!mdl)
        {
            ExFreePool(srb);
            ExFreePool(psense);
            IoFreeIrp(irp);
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        MmProbeAndLockPages(mdl, 0 , (MajorFunction == IRP_MJ_READ?0:1));

        srb->OriginalRequest=irp;
        irp->UserIosb=&isb;
        irp->UserEvent=&Event;
        irp->IoStatus.Status=0;
        irp->IoStatus.Information=0;
        irp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
        irp->AssociatedIrp.SystemBuffer=0;
        irp->Cancel=0;
        irp->RequestorMode=0;
        irp->CancelRoutine=0;
        irp->Tail.Overlay.Thread=PsGetCurrentThread();
        isl=IoGetNextIrpStackLocation(irp);
        isl->DeviceObject=dev_object;
        isl->MajorFunction=IRP_MJ_SCSI;
        isl->Parameters.Scsi.Srb=srb;
        isl->CompletionRoutine=IrpCompletionRoutine_0;
        isl->Context=srb;
        isl->Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
        status=MyIoCallDriver(dev_object,irp);
        KeWaitForSingleObject(&Event, 0, 0, 0, 0);

        if(srb->SenseInfoBuffer!=psense&&srb->SenseInfoBuffer)
            ExFreePool(srb->SenseInfoBuffer);

        ExFreePool(srb);
        ExFreePool(psense);

        if ( status >= 0 || !count )
            return status;

        DbgPrint("Send XXX Failed..%08x\r\n", status);
        KeStallExecutionProcessor(1u);
        --count;
    }
    return STATUS_INSUFFICIENT_RESOURCES;
}

这个IoCallDriver倒是能成功,但是buffer里面什么都没有,都是0

请问是怎么回事啊?是不是不能在这里发送IRP进行读写呢?弄不明白,各位就指点一下吧,谢谢~

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册