010513
驱动牛犊
驱动牛犊
  • 注册日期2010-11-26
  • 最后登录2011-05-13
  • 粉丝1
  • 关注2
  • 积分36分
  • 威望231点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2606回复:1

自定义IRP读写文件问题

楼主#
更多 发布于:2011-01-28 15:24
我想从某文件提取数据然后简单加密后写入另一文件,我写的程序是采取分组提取的,每次提取256字节的数据,因为在自定义读和写文件时感觉我自己分配的堆读出或写入后总是出问题,所以我每次都重新分配它一次,当在最后释放时(已经标注红色部分),报错了,我想知道为什么我没有移动自己分配的堆的指针,但在最后释放时也会报错的?
部分代码如下:
#define CF_FILE_ENCYPT_SIZE 256
#define CF_FILE_HEADER_SIZE 4096

NTSTATUS miniEncyptDocToTma(
        IN PFLT_VOLUME Volume,
        IN PFILE_OBJECT fsrc, //doc文件指针
        IN PFILE_OBJECT fdes, //tma文件指针
        IN LARGE_INTEGER fsrclen //doc文件长度
        )
{
    NTSTATUS ntstatus;
    ULONG status;
    //读缓冲区
    WCHAR *rbuf=NULL;
    //偏移
    LARGE_INTEGER offset={0};
    //控制读写次数
    ULONG i;
    //最后一组加密的长度
    ULONG taillen=fsrclen.QuadPart%CF_FILE_ENCYPT_SIZE;
    //控制加密缓冲区字节
    ULONG j;
    //读文件标志
    ULONG rflags=IRP_READ_OPERATION|IRP_NOCACHE|IRP_DEFER_IO_COMPLETION;
    //写文件标志
    ULONG wflags=IRP_WRITE_OPERATION|IRP_NOCACHE|IRP_DEFER_IO_COMPLETION;

    rbuf=ExAllocatePoolWithTag(NonPagedPool,CF_FILE_ENCYPT_SIZE,'zwD');
    if(rbuf==NULL)
    {
        KdPrint(("miniEncyptDocToTma:分配内存失败"));
        return STATUS_UNSUCCESSFUL;
    }
    for(i=0;i<fsrclen.QuadPart/CF_FILE_ENCYPT_SIZE;i++)
    {
        //分组从DOC文件读出数据
        rbuf=ExAllocatePoolWithTag(NonPagedPool,CF_FILE_ENCYPT_SIZE,'zwD');
        if(rbuf==NULL)
        {
        KdPrint(("miniEncyptDocToTma:分配内存失败"));
        return STATUS_UNSUCCESSFUL;
        }
        offset.QuadPart=i*CF_FILE_ENCYPT_SIZE;
        ntstatus=sfReadWriteIrp(
                            Volume,
                            fsrc,
                            TRUE,//True表示读文件
                            rflags,
                            rbuf,
                            CF_FILE_ENCYPT_SIZE,
                            offset
                            );
        if(!NT_SUCCESS(ntstatus))
        {
            KdPrint(("miniEncyptDocToTma:读取数据失败"));
            goto MINI_LAST;
        }
        //进行简单的字节流加密,即与操作
        for(j=0;j<CF_FILE_ENCYPT_SIZE;j++)
                rbuf[j]^=0x22;
        
                                //把数据写入TMA文件
        //注意:写入数据的最原始偏移为一个文件头偏移4K
        offset.QuadPart=i*CF_FILE_ENCYPT_SIZE+CF_FILE_HEADER_SIZE;
        ntstatus=sfReadWriteIrp(
                            Volume,
                            fdes,
                            FALSE,//FALSE为写文件
                            wflags,
                            rbuf,
                            CF_FILE_ENCYPT_SIZE,
                            offset
                            );
        if(!NT_SUCCESS(ntstatus))
        {
            status=ntstatus;
            KdPrint(("miniEncyptDocToTma:写入数据失败"));
            goto MINI_LAST;
        }
        ////每次均清空一次堆        
                        if(rbuf!=NULL)
            ExFreePoolWithTag(rbuf,'zwD');
   
}


sfReadWriteIrp代码如下:
//自定义读写文件头
NTSTATUS sfReadWriteIrp(
             IN PFLT_VOLUME Volume,
             IN PFILE_OBJECT fileobj,
             IN BOOLEAN isrw,//读或写, 读为TRUE,写为FALSE
             IN ULONG Flags,
             IN OUT PVOID buf,
             IN ULONG buf_size,
             IN LARGE_INTEGER offset)
{
    
    NTSTATUS status;
    KEVENT kevent;
    PIRP Irp=NULL;
    PIO_STACK_LOCATION pstack=NULL;
    IO_STATUS_BLOCK statblock;
    PDEVICE_OBJECT pdev;

    status=FltGetDeviceObject(Volume,&pdev);
    if(!NT_SUCCESS(status))
        return status;

    KeInitializeEvent(&kevent,NotificationEvent,FALSE);
    Irp=IoAllocateIrp(pdev->StackSize,FALSE);
    Irp->UserIosb=&statblock;
    Irp->Tail.Overlay.Thread=PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject=fileobj;
    Irp->Flags=0;
    Irp->RequestorMode=KernelMode;
    Irp->AssociatedIrp.SystemBuffer=NULL;
    Irp->MdlAddress=NULL;
    Irp->UserBuffer=buf;
    Irp->Flags=Flags;

    pstack=IoGetNextIrpStackLocation(Irp);
    if(isrw)
    {
        pstack->MajorFunction=IRP_MJ_READ;
        pstack->Parameters.Read.Length=buf_size;
        pstack->Parameters.Read.ByteOffset=offset;
        if(pdev->Flags&DO_BUFFERED_IO)
        {
            Irp->AssociatedIrp.SystemBuffer=buf;
            Irp->UserBuffer=NULL;
        }
    }
    else
    {
        pstack->MajorFunction=IRP_MJ_WRITE;
        pstack->Parameters.Write.Length=buf_size;
        pstack->Parameters.Write.ByteOffset=offset;
        if(pdev->Flags&DO_BUFFERED_IO)
        {
            Irp->AssociatedIrp.SystemBuffer=buf;
            Irp->UserBuffer=NULL;
        }
        else if(pdev->Flags&DO_DIRECT_IO)
        {
            Irp->MdlAddress=IoAllocateMdl(
                        buf,
                        buf_size,
                        FALSE,
                        FALSE,
                        (PIRP)NULL);
            if(Irp->MdlAddress=NULL)
            {
                IoFreeIrp(Irp);
                return STATUS_UNSUCCESSFUL;
            }
        }

    }
    pstack->DeviceObject=pdev;
    pstack->FileObject=fileobj;
    pstack->MinorFunction=IRP_MN_NORMAL;

    IoSetCompletionRoutine(Irp,sfReadWriteIrpCompletion,(PVOID)&kevent,TRUE,TRUE,TRUE);
    status=IoCallDriver(pdev,Irp);
    if(status==STATUS_PENDING)
        KeWaitForSingleObject(&kevent,Executive,KernelMode ,FALSE,NULL);
    status=Irp->IoStatus.Status;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
    return status;
}
010513
驱动牛犊
驱动牛犊
  • 注册日期2010-11-26
  • 最后登录2011-05-13
  • 粉丝1
  • 关注2
  • 积分36分
  • 威望231点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2011-01-31 13:44
终于解决了~一切都是自定义写文件时,标志的设置问题~害我弄了那么多天..............
游客

返回顶部