阅读:1384回复:9
关于文件读写偏移以及长度的问题
本人最进从事过滤驱动的开发,希望在读写例程当中修改文件的偏移量和长度,从而达到自主控制文件内容的目的。下面是我的读例程和完成例程的部分代码,请各位大侠看看为什么会出问题:
读例程: case IRP_MJ_READ: DownTransfer = ExAllocatePool(NonPagedPool, sizeof(DOWN_TRANSFER)); if(DownTransfer == NULL) { Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; break; } //将原有用户缓冲区记录下来,而用我自己创建的缓冲区进行替换,因为我修改了读长度,所以需要替换缓冲区。 DownTransfer->MdlAddress = Irp->MdlAddress; DownTransfer->UserBuffer = Irp->UserBuffer; DownTransfer->ReadWriteBytes = currentIrpStack->Parameters.Read.Length; DownTransfer->MemLock = FALSE; if(Irp->MdlAddress){ SysBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority ); BufferSize = currentIrpStack->Parameters.Read.Length; break; } } else{ SysBuffer = Irp->UserBuffer; BufferSize = currentIrpStack->Parameters.Read.Length; } //这里我将每次读取的长度增加一点 currentIrpStack->Parameters.Read.Length += LENGTH; BufferSize = currentIrpStack->Parameters.Read.Length; MyBuffer = ExAllocatePool(NonPagedPool, BufferSize); RtlZeroMemory(MyBuffer, BufferSize); DbgPrint((\"read length is %d\\n\", BufferSize)); DownTransfer->MyBuffer = MyBuffer; //下面将新生成的缓冲区替换原来的缓冲区,向下传递 } IoSetCompletionRoutine( Irp, FileMonReadCompleted, (PVOID)DownTransfer ,TRUE ,TRUE ,TRUE ); IoCallDriver(hookExt->FileSystem, Irp); 读完成例程: NTSTATUS FileMonReadWriteCompleted( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PDOWN_TRANSFER DownTransfer = (PDOWN_TRANSFER)Context; DataByteLength = Irp->IoStatus.Information; //注:这里的TempBuffer就是原来的缓冲区 assert(TempBuffer); DataByteLength = DownTransfer->ReadWriteBytes; //这里观查确实读到了比用户要求要多的数据 DbgPrint((\"Read %d bytes\\n\", DataByteLength)); //这里产生页异常,Page Fault (0Eh). Fault=0002 RtlZeroMemory(TempBuffer, DataByteLength); RtlCopyMemory(TempBuffer, SysBuffer, DataByteLength); if( Irp->PendingReturned ) IoMarkIrpPending( Irp ); return Irp->IoStatus.Status; } 请问各位大侠,为什么我将读取的内容拷贝回用户缓冲区会出现页异常呢?我的做法有什么问题吗? |
|
沙发#
发布于:2005-03-02 16:34
对了,在读例程当中向用户缓冲区copymemory也会出现页异常,难道此时的用户缓冲区是不可写的?那么低层驱动是怎么把磁盘数据写到这个缓冲区中的呢?
|
|
板凳#
发布于:2005-03-02 16:35
系统缓冲区是在I/O manage 自己的Zone中,它自己知道如何用,你硬塞给它一个buffer,不太适合它的口味
|
|
|
地板#
发布于:2005-03-02 16:46
可是如果进行加解密或者为文件添加头等行为,不修改系统缓冲区该怎么做呢?谢谢大侠指点!
另外,为什么这个缓冲区无法写呢? [编辑 - 3/2/05 by joshua_yu] |
|
地下室#
发布于:2005-03-03 09:16
高手都哪里去了?
自己顶一个先 |
|
5楼#
发布于:2005-03-03 09:18
可是如果进行加解密或者为文件添加头等行为,不修改系统缓冲区该怎么做呢?谢谢大侠指点! DDK上说,必须将这个缓冲区的内容全部拷贝到自己驱动分配的内存中去 |
|
|
6楼#
发布于:2005-03-03 09:28
没错啊,我就是将这个缓冲区的内容全部拷贝到自己分配的缓冲区中去的,但是从底层驱动返回以后总要将读取到的内容拷贝回用户缓冲区的,要不然用户怎么能够读取到文件内容呢?可就是在拷贝的时候出现问题的,现在我发现好像是缓冲区长度的问题,但是长度是从上面传下来的啊,我没有修改啊?
|
|
7楼#
发布于:2005-03-03 10:07
没错啊,我就是将这个缓冲区的内容全部拷贝到自己分配的缓冲区中去的,但是从底层驱动返回以后总要将读取到的内容拷贝回用户缓冲区的,要不然用户怎么能够读取到文件内容呢?可就是在拷贝的时候出现问题的,现在我发现好像是缓冲区长度的问题,但是长度是从上面传下来的啊,我没有修改啊? 你上面说“因为我修改了读长度”,所以长度和缓冲区是匹配的,所以不能改长度,个人私下以为改小估计可以,改大恐怕不行 |
|
|
8楼#
发布于:2005-03-03 11:03
对啊,长度是和缓冲区匹配的,所以如果想要修改读取内容的长度,不但要修改Read.Length同时要根据这个长度创建一个新的缓冲区,替换原来的缓冲区啊,这两者就是一致的,关于这个问题我已经试验过了,能够读取想要的长度。
刚才我又修改了一下程序,将返回的内容拷贝回用户缓冲区时不是拷贝缓冲区原来的长度,而是拷贝 原长-1个字节,就不会出问题了,而且读取出来的内容也是正确的,感到十分困惑。 |
|
9楼#
发布于:2005-03-03 15:40
看来是不能改大
|
|
|