dswei
驱动牛犊
驱动牛犊
  • 注册日期2003-03-19
  • 最后登录2010-06-13
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1714回复:3

IRP_MJ_READ例程里使用Parameters.Read.ByteOffset.QuadPart是否意味着一个ReadFile可能多次启动该例程?

楼主#
更多 发布于:2004-01-15 22:40
书里有个例子如下:
NTSTATUS Wdm1Read(IN PDEVICE_OBJECT fdo,
 IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
LONG BytesTxd = 0;

// Get call parameters
LONGLONG FilePointer = IrpStack->Parameters.Read.ByteOffset.QuadPart;
ULONG ReadLen = IrpStack->Parameters.Read.Length;
DebugPrint(\"Read %d bytes from file pointer %d\",(int)ReadLen,(int)FilePointer);

// Get access to the shared buffer
KIRQL irql;
KeAcquireSpinLock(&BufferLock,&irql);

// Check file pointer
if( FilePointer<0)
status = STATUS_INVALID_PARAMETER;
if( FilePointer>=(LONGLONG)BufferSize)
status = STATUS_END_OF_FILE;

if( status==STATUS_SUCCESS)
{
// Get transfer count
if( ((ULONG)FilePointer)+ReadLen>BufferSize)
{
BytesTxd = BufferSize - (ULONG)FilePointer;
if( BytesTxd<0) BytesTxd = 0;
}
else
BytesTxd = ReadLen;

// Read from shared buffer
if( BytesTxd>0 && Buffer!=NULL)
RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, Buffer+FilePointer, BytesTxd);
}

// Release shared buffer
KeReleaseSpinLock(&BufferLock,irql);

DebugPrint(\"Read: %d bytes returned\",(int)BytesTxd);

// Complete IRP
return CompleteIrp(Irp,status,BytesTxd);
}
1、能详细点说明如何运作吗?
2、Parameters.Read.ByteOffset.QuadPart的值应该是系统赋值的吧?
3、在论坛看到这句话“取文件的当前位置,因W2K中,一个文件理论一可以达2^64byte大小,而内存不可能有这么大,需要一批批地读,因此在读的过程中需要更新当前的读取位置”,一批一批的读,是否意味着一个ReadFile多次执行IRP_MY_READ例程?


[编辑 -  1/15/04 by  dswei]
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-01-16 16:10
>> 1、能详细点说明如何运作吗?
觉得程序已经写得很明白了, 主要是判断能不能读,能读就读,读不了返回错误.

>> 2、Parameters.Read.ByteOffset.QuadPart的值应该是系统赋值的吧?
是的.

>> 3、在论坛看到这句话“取文件的当前位置,因W2K中,一个文件理论一可以达2^64byte大小
正确的理论值应该是 (2^63)-1 Bytes

>> 而内存不可能有这么大,需要一批批地读,因此在读的过程中需要更新当前的读取位置”,
就是说文件指针.

>> 一批一批的读,是否意味着一个ReadFile多次执行IRP_MY_READ例程?
通常而言,是的,但如果读的数据较少,一次就够了;同时,在不同的驱动层次,处理是不一样的.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
dswei
驱动牛犊
驱动牛犊
  • 注册日期2003-03-19
  • 最后登录2010-06-13
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-01-16 16:24
假如文件非常非常大,parameters.Read.ByteOffset.QuadPart是应该多次改变的吧?每次改变对应一次例程调用?
是不是这样:
1、开始时parameters.Read.ByteOffset.QuadPart=0,
2、调用Read/Write例程,parameters.Read.ByteOffset.QuadPart并相应改变
3、如果parameters.Read.ByteOffset.QuadPart没到达文件末尾,进行2,否则结束

我的问题在于:parameters.Read.ByteOffset.QuadPart一开始应该指向文件头,也就是0,那么他的例子使用parameters.Read.ByteOffset.QuadPart根本无意义。我想parameters.Read.ByteOffset.QuadPart的用处在于它会变化,可是我不清楚这个变化如何发生。

[编辑 -  1/16/04 by  dswei]
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-01-16 16:35
>> 假如文件非常非常大,parameters.Read.ByteOffset.QuadPart
>> 是应该多次改变的吧?每次改变对应一次例程调用?
是的.

>> 是不是这样:
>> 1、开始时parameters.Read.ByteOffset.QuadPart=0,
>> 2、调用Read/Write例程,parameters.Read.ByteOffset.QuadPart并相应改变
>> 3、如果parameters.Read.ByteOffset.QuadPart没到达文件末尾,进行2,否则结束
还有一个Length你没注意到吗?如果是连续读,Offset的新值是上次Offset的值加上次的length.

>> 我的问题在于:parameters.Read.ByteOffset.QuadPart一开始
>> 应该指向文件头,也就是0,那么他的例子使用
>> parameters.Read.ByteOffset.QuadPart根本无意义。
为什么?你难道不考虑随机访问的情况吗?

>> 我想parameters.Read.ByteOffset.QuadPart的用处在于它会
>> 变化,可是我不清楚这个变化如何发生。
变化是上层吧一个大块的操作分解成一个个小块操作时发生的.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
游客

返回顶部