阅读:1714回复:3
IRP_MJ_READ例程里使用Parameters.Read.ByteOffset.QuadPart是否意味着一个ReadFile可能多次启动该例程?
书里有个例子如下:
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] |
|
沙发#
发布于:2004-01-16 16:10
>> 1、能详细点说明如何运作吗?
觉得程序已经写得很明白了, 主要是判断能不能读,能读就读,读不了返回错误. >> 2、Parameters.Read.ByteOffset.QuadPart的值应该是系统赋值的吧? 是的. >> 3、在论坛看到这句话“取文件的当前位置,因W2K中,一个文件理论一可以达2^64byte大小 正确的理论值应该是 (2^63)-1 Bytes >> 而内存不可能有这么大,需要一批批地读,因此在读的过程中需要更新当前的读取位置”, 就是说文件指针. >> 一批一批的读,是否意味着一个ReadFile多次执行IRP_MY_READ例程? 通常而言,是的,但如果读的数据较少,一次就够了;同时,在不同的驱动层次,处理是不一样的. |
|
|
板凳#
发布于: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] |
|
地板#
发布于: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的用处在于它会 >> 变化,可是我不清楚这个变化如何发生。 变化是上层吧一个大块的操作分解成一个个小块操作时发生的. |
|
|