阅读:1270回复:16
关于IRP
I/O堆栈单元数据结构中的
IrpStack->Parameters.Read.ByteOffset.QuadPart是个什么东西啊?有什么意义?哪位大侠指点一下。 :) |
|
最新喜欢:baoyib...
|
沙发#
发布于:2003-06-23 17:34
我好像没有说明白,是这样的,在Chris Cant的书里的例子WDM1中的Dispatch.cpp的WDM1write函数里:
NTSTATUS Wdm1Write( 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.Write.ByteOffset.QuadPart; /*这个QuadPart是什么类型的数据?有什么意义?*/ :) ULONG WriteLen = IrpStack->Parameters.Write.Length; DebugPrint(\"Write %d bytes from file pointer %d\", (int)WriteLen,(int)FilePointer); if( FilePointer<0) status = STATUS_INVALID_PARAMETER; else { // Get access to the shared buffer KIRQL irql; KeAcquireSpinLock(&BufferLock,&irql); BytesTxd = WriteLen; // (Re)allocate buffer if necessary if( ((ULONG)FilePointer)+WriteLen>BufferSize) /*不明白这句话,是判断什么?*/ :) { ULONG NewBufferSize = ((ULONG)FilePointer)+WriteLen; PVOID NewBuffer= ExAllocatePool((UNLONG)FilePiointer+WriteLen; if( NewBuffer==NULL) { BytesTxd = BufferSize - (ULONG)FilePointer; /*这句话是最不明白的*/ if( BytesTxd<0) BytesTxd = 0; } else { RtlZeroMemory(NewBuffer,NewBufferSize); if( Buffer!=NULL) { RtlCopyMemory(NewBuffer,Buffer,BufferSize); ExFreePool(Buffer); } Buffer = (PUCHAR)NewBuffer; BufferSize = NewBufferSize; } } // Write to shared memory if( BytesTxd>0 && Buffer!=NULL) RtlCopyMemory( Buffer+FilePointer, Irp->AssociatedIrp.SystemBuffer, BytesTxd); // Release shared buffer KeReleaseSpinLock(&BufferLock,irql); } DebugPrint(\"Write: %d bytes written\",(int)BytesTxd); // Complete IRP return CompleteIrp(Irp,status,BytesTxd); } 不知大家看明白了没有?关键的问题还是这句话: LONGLONG FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart; 我不知道这个QuadPart的意义是什么?导致无法理解该函数的算法。书上介绍的不详细,也没讲QuadPart,我在DDK的help里也没找到,帮个忙啊,看不下去了! :( :( :( |
|
|
板凳#
发布于:2003-06-23 17:48
LONGLONG FilePointer =
IrpStack->Parameters.Write.ByteOffset.QuadPart 是指指向所要读写文件的文件指针 if( ((ULONG)FilePointer)+WriteLen>BufferSize) 缓冲区空间不够,分配内存. |
|
|
地板#
发布于:2003-06-23 18:56
是偏移值。不是“是指指向所要读写文件的文件指针”!
/*这个QuadPart是什么类型的数据?有什么意义?*/ 就是LONGLONG(int64)啊,偏移值就可以很大,可以处理很大的文件。 if( ((ULONG)FilePointer)+WriteLen>BufferSize) /*不明白这句话,是判断什么?*/ 这个example实际上是把数据写到在driver分配的一个buffer里面。当然数据和开始写的偏移不能超出buffer。如果超出了,就再分配。 这样应该可以明白些了吧? 灌水灌的太多了。 :D |
|
地下室#
发布于:2003-06-25 10:35
两位的意思是不是这样: 写分发例程向共享内存缓冲区中的指定偏移位置(即FilePointer)开始写数据,那这里的BufferSize和NewBufferSize就不是缓冲区的大小,而是缓冲区中的偏移位置。不知这样理解对不对? 另外,我还有一点不明白:既然FilePointer是偏移量,那基地址是什么呢? |
|
|
5楼#
发布于:2003-06-25 12:28
这本书上的例子很多的关键语句调用都没有注释,有一些很关键的宏调用等等,你的这段代码里就有,我看了2 遍觉得很不明白(代码)
这不是给初学者编写的,我想当初作者写此书的初衷估计是不惜望这本书被读者早早仍掉,so 他写的书深不深,潜不浅,迷迷糊糊,初学者估计看上3遍估计业不会名白(象我)呵呵,高手哪?又看不上这本书,因为太理论太简单了,劝兄台看看win2000驱动设计和wdm模型,但是如果你有基础的话,函数,ddk 宏等都有基础,这本书的代码是非常好的,很简单,很说明问题 win2000driver太理论,不适和初学者,但是你要是有点基础的,看这本书没错,书不错,代码业很好,wdm模型很好,但也要有基础,什么是基础?总是就是多看多想,我是初学者中的才鸟,希望多多切磋,hohoho,别嫌我烦,only you ............ :D :D :D |
|
6楼#
发布于:2003-06-25 12:49
Walter Oney那本书我觉得更难 :(理论讲的很透彻,但是偶基础太差,比如第三章基本编程技术和第四章同步就没看懂,云里雾里的,不仅是驱动的基础差,而是整个计算机的基础都差!愁啊!愁的我一个劲去灌水,都灌成中级会员了 :(可知识一点没学到。
|
|
|
7楼#
发布于:2003-06-25 14:37
buffersize就是buffer的size啊 :P 地址?在分配内存的时候,就得到地址了啊。 PVOID NewBuffer=ExAllocatePool((UNLONG)FilePiointer+WriteLen); Buffer = (PUCHAR)NewBuffer; BufferSize = NewBufferSize; |
|
8楼#
发布于:2003-06-25 15:44
如果BufferSize就是buffer的大小,那么为什么要分配一个大小为FilePionter+WriteLen的缓冲区?而不是分配一个大小为WriteLen的缓冲区?
|
|
|
9楼#
发布于:2003-06-25 18:59
nlq_new兄,buffer size是当前缓冲区的大小,而WriteLen是要写入的数据的长度,所以FilePointer+WriteLen才是需要的新缓冲区大小,如果只申请WriteLen大小的缓冲区,那原来可能存在与缓冲区的数据你要怎么办?覆盖掉?!所以FilePointer+WriteLen的意思是在原来已经存在的内容的基础上增加WriteLen的空间来保存新写入的内容。
注意:buffer确切地说是硬件模拟作用的一块内存地址,不是一般意义上的缓冲区。 Chris Cant的书只要大概看看就好,实在有些浅,不过如果不是这本书,我实在不可能在半个月内从一窍不通到能完成论文。如果是像我一样对windows内核完全不了解的人,看完Chris Cant的书,只能说基本上对wdm的架构能有个了解而已。 |
|
10楼#
发布于:2003-06-26 15:30
no
楼上的阿兄说得不对哦,如果你能完全看懂wdm开发指南,那么你也是高手了,hohoho |
|
11楼#
发布于:2003-06-26 15:44
初学用chris cant的书还是稍微难了点。但是看完以后,也不能说就很明白,所以,这本书有些尴尬
|
|
|
12楼#
发布于:2003-06-26 16:31
可是如果你要分配新内存缓冲区NewBuffer,不用保留原来存在于这段内存中的内容,直接分配就好了吧?保留它有什么用呢?另外,我觉得,FilePointer是偏移量,WriteLen是一个ULONG型变量,我觉得:偏移量+ULONG=偏移量,所以NewBufferSize应该是一个偏移量,不知这样想对不对?错在哪里?
windyguy的回答看不明白,想了半天,“注意:buffer确切地说是硬件模拟作用的一块内存地址,不是一般意义上的缓冲区。”这句话的意思是不是说在这种分配方式下,每次都是从一个固定的位置开始分配新的内存的,所以新分配的缓冲区中包括以前的旧缓冲区。而不是一般情况下,每次新分配的缓冲区都不会和以前分配的旧缓冲区有重叠的部分。说的很拗口 :)没办法,太菜了。各位大侠见笑,但是笑之余还请指点一二,谢谢了 :)。 |
|
|
13楼#
发布于:2003-06-26 21:35
呵呵,我之所以看Chris Cant的书完全是为了毕业设计,所以也没有细看,不过的确是没有Walt Oney的书讲得深入,并且把必要的地方都有讲到,也许结合着看是个好办法。
nlq_new兄,如果我说,一个缓冲区的大小是BufferSize,实际这个BufferSize也是一个偏移量,而且是这个缓冲区能拥有的最大偏移量(应该减1的样子)。所以NewBufferSize也是一个偏移量了。 比如char offset[7] = \"Offset\" \'s\'的偏移量是3,*(offset+3)就是\'s\',也就是offset[3]。 “注意:buffer确切地说是硬件模拟作用的一块内存地址,不是一般意义上的缓冲区。” 上面这句话的意思是因为该例子中没有实际硬件,所以当驱动收到一个ReadIRP时,从Buffer中取相应内容来Complete,如果收到WriteIrp时,就往Buffer里面写东西,并没有实际的硬件来完成这些IRP,所以Buffer是硬件模拟作用。 |
|
14楼#
发布于:2003-06-27 09:41
现在明白了buffer size是当前缓冲区的大小。 :)
那我说的第二段话对不对呀? 还是不明白为什么要保留原来可能存在与缓冲区的数据,这些数据有什么用呢?不懂啊!指点指点 :( |
|
|
15楼#
发布于:2003-06-27 14:32
不是有没有用,而是你应该这样做。
不能捡了西瓜,就不要冬瓜了啊 :D |
|
16楼#
发布于:2003-06-27 14:37
“这句话的意思是不是说在这种分配方式下,每次都是从一个固定的位置开始分配新的内存的,所以新分配的缓冲区中包括以前的旧缓冲区。而不是一般情况下,每次新分配的缓冲区都不会和以前分配的旧缓冲区有重叠的部分。”
你是说上面这段么?ExAllocatePool分配的空间并不固定在一个位置,所以后面有用RtlCopyMemory把老的东西Copy过去。 至于保留数据有什么用,呵呵,比如你用的是WDM1那个例子,你运行过WDM1TEST么?下面这些代码就属于WDM1TEST,Write了0x12345678后,SetFilePointer到3实际就是使偏移量等于3,接着ReadFile,你说会读取到什么呢?从什么地方读取呢?自然是从那个Buffer里面,因为已经写入了0x12345678,这时对应偏移量3的地方就是0x12。 这样应该知道保留数据的作用了吧,因为TEST时你要把它读出的。 ///////////////////////////////////////////////////////////////////////// // Write 0x12345678 printf(\"\\nTest %d\\n\",TestNo++); ULONG Wvalue = 0x12345678; if( !WriteFile( hWdm1, &Wvalue, 4, &TxdBytes, NULL)) printf(\"XXX Could not write %X\\n\",Wvalue); else if( TxdBytes==4) printf(\" Write 0x12345678 succeeded\\n\"); else printf(\"XXX Wrong number of bytes written: %d\\n\",TxdBytes); ///////////////////////////////////////////////////////////////////////// // Set file pointer printf(\"\\nTest %d\\n\",TestNo++); DWORD dwNewPtr = SetFilePointer( hWdm1, 3, NULL, FILE_BEGIN); if( dwNewPtr==0xFFFFFFFF) printf(\"XXX SetFilePointer failed %d\\n\",GetLastError()); else printf(\" SetFilePointer worked\\n\"); ///////////////////////////////////////////////////////////////////////// // Read printf(\"\\nTest %d\\n\",TestNo++); Rvalue = 0; if( !ReadFile( hWdm1, &Rvalue, 1, &TxdBytes, NULL)) printf(\"XXX Could not read value\\n\"); else if( TxdBytes==1) printf(\" Read successfully read stored value of 0x%X\\n\",Rvalue); else printf(\"XXX Wrong number of bytes read: %d\\n\",TxdBytes); |
|