zzyheart
驱动牛犊
驱动牛犊
  • 注册日期2007-03-15
  • 最后登录2008-07-04
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
阅读:1978回复:1

自己创建的异步IRP_MJ_READ完成历程中读取信息的问题...

楼主#
更多 发布于:2007-04-09 21:28
  我在自己的驱动里面创建异步的IRP_MJ_READ,设置完成历程 然后发送下去...为什么在完成例程里面不能获得 读取的数据长度 内容等信息呢?用读取上面传下来的IRP_MJ_READ数据都可以,自己创建的为什么就不行呢...?
部分代码如下...:

//write分发历程 在这个里面创建IRP_MJ_READ,设置IRP_MJ_READ的完成例程并传递下去
NTSTATUS FilterDispatchWrite(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
    NTSTATUS orgIrpStatus;
    PDEVICE_EXTENSION   deviceExtension;
    PIO_STACK_LOCATION  pIrpStackLocation;
    NTSTATUS status;
    
    KEVENT event;

    ULONG Length;
    ULONGLONG ByteIndex;
    ULONG  SectorIndex;
    PDEVICE_OBJECT TargetDeviceObject;

    PVOID buffer;
    IO_STATUS_BLOCK IoStatusBlock;
    PIRP shReadIrp;
    LARGE_INTEGER StartingOffset;
    NTSTATUS readStatus;
    PIO_STACK_LOCATION  pISL;

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    pIrpStackLocation = IoGetCurrentIrpStackLocation(Irp);

    Length = pIrpStackLocation->Parameters.Write.Length;

    ByteIndex = pIrpStackLocation->Parameters.Write.ByteOffset.QuadPart;
    
    ////////////////////////////////////////
    status = IoAcquireRemoveLock(&deviceExtension->RemoveLock,NULL);
    if (!NT_SUCCESS(status)){
        DebugPrint((0,"Filter DispatchWrite:IoAcquireRemoveLock Failed.\n"));
    }

    TargetDeviceObject = deviceExtension->TargetDeviceObject;

    StartingOffset.QuadPart = pIrpStackLocation->Parameters.Write.ByteOffset.QuadPart;

    if(KeGetCurrentIrql() > PASSIVE_LEVEL){
        DebugPrint((0,"Current IRQL > PASSIVE_LEVEL.\n"));
    }else{

        buffer = ExAllocatePool(NonPagedPool, Length);


        KeInitializeEvent(&event,NotificationEvent, FALSE);


        shReadIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,TargetDeviceObject,buffer,Length,&StartingOffset,&IoStatusBlock);

        if(NULL != shReadIrp){
            
            DebugPrint((0,"shReadIrp created.\n"));
            
    
            IoSetCompletionRoutine(shReadIrp,FilterReadCompletion,&event,TRUE,FALSE,FALSE);
            
            readStatus = IoCallDriver(TargetDeviceObject, shReadIrp);
            
            if (readStatus == STATUS_PENDING){
                
                KeWaitForSingleObject(&event, Executive, KernelMode,FALSE, NULL);
                DebugPrint((0,"shReadIrp completed.\n"));
                status = IoStatusBlock.Status;
                
            }
        }
    }
    //////////////////////////////////////////

    
    DebugPrint((0,
        "FilterDispatchWrite write:Length::%u,ByteIndex::%u\n",Length,ByteIndex));

    IoSkipCurrentIrpStackLocation(Irp);
    orgIrpStatus = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);

    IoReleaseRemoveLock(&deviceExtension->RemoveLock, NULL);
    DebugPrint((0,"///////////////////////\n"));
    return orgIrpStatus;

}


NTSTATUS NsFilterDispatchRead(PDEVICE_OBJECT DeviceObject,PIRP Irp){
    PIO_STACK_LOCATION pIrpStackLocation;
    PDEVICE_EXTENSION deviceExtension;
    deviceExtension =DeviceObject->DeviceExtension;
    
    pIrpStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    IoCopyCurrentIrpStackLocationToNext(Irp);

        DebugPrint((0,
        DRIVERNAME " Enter NsFilterDispatchRead Irp = %p Data Length = %I32u Data offset = %I64d.\n",
        Irp,
        pIrpStackLocation->Parameters.Read.Length,
        pIrpStackLocation->Parameters.Read.ByteOffset.QuadPart));
    
    IoSetCompletionRoutine(Irp,NsFilterReadCompletion,NULL,TRUE,TRUE,TRUE);
    
    return IoCallDriver(deviceExtension->TargetDeviceObject,Irp);
}



//IRP_MJ_READ的完成例程
NTSTATUS FilterReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT pev)
{
    PIO_STACK_LOCATION pIrpStackLocation;
    ULONG Length;
    LARGE_INTEGER StartingOffset;
    ULONGLONG ByteIndex;
    PVOID pOrgBuf;
    ULONG uSrcLength;    

    if (Irp->PendingReturned){
        KeSetEvent(pev, EVENT_INCREMENT, FALSE);

    }
    pIrpStackLocation = IoGetCurrentIrpStackLocation(Irp);

    ByteIndex = pIrpStackLocation->Parameters.Read.ByteOffset.QuadPart;
    Length = pIrpStackLocation->Parameters.Read.Length;
    DebugPrint((0,"FilterReadCompletion CurrentSL:Length::%u,ByteIndex::%u\n",Length,ByteIndex));
    
    pOrgBuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
    uSrcLength = MmGetMdlByteCount(Irp->MdlAddress);
    
    if(pOrgBuf!= NULL){
        DebugPrint((0,"pOrgBuf: %x\n",pOrgBuf));    
    }else{
        DebugPrint((0,"pOrgBuf:Faild.\n"));
    }
    IoFreeIrp(Irp);
    return STATUS_MORE_PROCESSING_REQUIRED;

}

最新喜欢:

rhpengrhpeng
aqiuzaizai
驱动牛犊
驱动牛犊
  • 注册日期2007-02-02
  • 最后登录2008-04-02
  • 粉丝0
  • 关注0
  • 积分180分
  • 威望69点
  • 贡献值0点
  • 好评度68点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-04-30 18:04
一点参考意见:

PIRP
IoBuildAsynchronousFsdRequest(
    IN ULONG MajorFunction,
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PVOID Buffer OPTIONAL,
    IN ULONG Length OPTIONAL,
    IN PLARGE_INTEGER StartingOffset OPTIONAL,
    IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL
    )

/*++

Routine Description:

    This routine builds an I/O Request Packet (IRP) suitable for a File System
    Driver (FSD) to use in requesting an I/O operation from a device driver.
    The request must be one of the following request codes:

        IRP_MJ_READ
        IRP_MJ_WRITE
        IRP_MJ_FLUSH_BUFFERS
        IRP_MJ_SHUTDOWN
        IRP_MJ_POWER

    This routine provides a simple, fast interface to the device driver w/o
    having to put the knowledge of how to build an IRP into all of the FSDs
    (and device drivers) in the system.

Arguments:

    MajorFunction - Function to be performed;  see previous list.

    DeviceObject - Pointer to device object on which the I/O will be performed.

    Buffer - Pointer to buffer to get data from or write data into.  This
        parameter is required for read/write, but not for flush or shutdown
        functions.

    Length - Length of buffer in bytes.  This parameter is required for
        read/write, but not for flush or shutdown functions.

    StartingOffset - Pointer to the offset on the disk to read/write from/to.
        This parameter is required for read/write, but not for flush or
        shutdown functions.

    IoStatusBlock - Pointer to the I/O status block for completion status
        information.  This parameter is optional since most asynchronous FSD
        requests will be synchronized by using completion routines, and so the
        I/O status block will not be written.

Return Value:

    The function value is a pointer to the IRP representing the specified
    request.

--*/
注意你创建的IRP中参数4 Length 是 Length of buffer in bytes;
而你每次读或写的字节数需要另外指定:
Irp->IoStatus.Status.Information = 你读写的值;

over
竹密何妨流水过 山高岂碍野云飞
游客

返回顶部