joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
阅读:1384回复:9

关于文件读写偏移以及长度的问题

楼主#
更多 发布于:2005-03-02 16:12
本人最进从事过滤驱动的开发,希望在读写例程当中修改文件的偏移量和长度,从而达到自主控制文件内容的目的。下面是我的读例程和完成例程的部分代码,请各位大侠看看为什么会出问题:

读例程:
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;

}

请问各位大侠,为什么我将读取的内容拷贝回用户缓冲区会出现页异常呢?我的做法有什么问题吗?
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-03-02 16:34
对了,在读例程当中向用户缓冲区copymemory也会出现页异常,难道此时的用户缓冲区是不可写的?那么低层驱动是怎么把磁盘数据写到这个缓冲区中的呢?
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-03-02 16:35
系统缓冲区是在I/O manage 自己的Zone中,它自己知道如何用,你硬塞给它一个buffer,不太适合它的口味
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-03-02 16:46
可是如果进行加解密或者为文件添加头等行为,不修改系统缓冲区该怎么做呢?谢谢大侠指点!

另外,为什么这个缓冲区无法写呢?

[编辑 -  3/2/05 by  joshua_yu]
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-03-03 09:16
高手都哪里去了?

自己顶一个先
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-03-03 09:18
可是如果进行加解密或者为文件添加头等行为,不修改系统缓冲区该怎么做呢?谢谢大侠指点!

另外,为什么这个缓冲区无法写呢?

[编辑 -  3/2/05 by  joshua_yu]

DDK上说,必须将这个缓冲区的内容全部拷贝到自己驱动分配的内存中去
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-03-03 09:28
没错啊,我就是将这个缓冲区的内容全部拷贝到自己分配的缓冲区中去的,但是从底层驱动返回以后总要将读取到的内容拷贝回用户缓冲区的,要不然用户怎么能够读取到文件内容呢?可就是在拷贝的时候出现问题的,现在我发现好像是缓冲区长度的问题,但是长度是从上面传下来的啊,我没有修改啊?
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-03-03 10:07
没错啊,我就是将这个缓冲区的内容全部拷贝到自己分配的缓冲区中去的,但是从底层驱动返回以后总要将读取到的内容拷贝回用户缓冲区的,要不然用户怎么能够读取到文件内容呢?可就是在拷贝的时候出现问题的,现在我发现好像是缓冲区长度的问题,但是长度是从上面传下来的啊,我没有修改啊?

你上面说“因为我修改了读长度”,所以长度和缓冲区是匹配的,所以不能改长度,个人私下以为改小估计可以,改大恐怕不行
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-03-03 11:03
对啊,长度是和缓冲区匹配的,所以如果想要修改读取内容的长度,不但要修改Read.Length同时要根据这个长度创建一个新的缓冲区,替换原来的缓冲区啊,这两者就是一致的,关于这个问题我已经试验过了,能够读取想要的长度。

刚才我又修改了一下程序,将返回的内容拷贝回用户缓冲区时不是拷贝缓冲区原来的长度,而是拷贝 原长-1个字节,就不会出问题了,而且读取出来的内容也是正确的,感到十分困惑。
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-03-03 15:40
看来是不能改大
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
游客

返回顶部