nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:1270回复:16

关于IRP

楼主#
更多 发布于:2003-06-23 11:59
I/O堆栈单元数据结构中的
IrpStack->Parameters.Read.ByteOffset.QuadPart是个什么东西啊?有什么意义?哪位大侠指点一下。 :)

最新喜欢:

baoyibao99baoyib...
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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里也没找到,帮个忙啊,看不下去了! :( :( :(
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2003-06-23 17:48
LONGLONG FilePointer =
IrpStack->Parameters.Write.ByteOffset.QuadPart
是指指向所要读写文件的文件指针
if( ((ULONG)FilePointer)+WriteLen>BufferSize)
缓冲区空间不够,分配内存.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2003-06-23 18:56
是偏移值。不是“是指指向所要读写文件的文件指针”!

/*这个QuadPart是什么类型的数据?有什么意义?*/
就是LONGLONG(int64)啊,偏移值就可以很大,可以处理很大的文件。

if( ((ULONG)FilePointer)+WriteLen>BufferSize)
/*不明白这句话,是判断什么?*/

这个example实际上是把数据写到在driver分配的一个buffer里面。当然数据和开始写的偏移不能超出buffer。如果超出了,就再分配。
这样应该可以明白些了吧?

灌水灌的太多了。 :D
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-25 10:35

两位的意思是不是这样:
写分发例程向共享内存缓冲区中的指定偏移位置(即FilePointer)开始写数据,那这里的BufferSize和NewBufferSize就不是缓冲区的大小,而是缓冲区中的偏移位置。不知这样理解对不对?

另外,我还有一点不明白:既然FilePointer是偏移量,那基地址是什么呢?
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
CX利刃
驱动小牛
驱动小牛
  • 注册日期2001-11-21
  • 最后登录2003-09-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-25 12:28
这本书上的例子很多的关键语句调用都没有注释,有一些很关键的宏调用等等,你的这段代码里就有,我看了2 遍觉得很不明白(代码)

这不是给初学者编写的,我想当初作者写此书的初衷估计是不惜望这本书被读者早早仍掉,so 他写的书深不深,潜不浅,迷迷糊糊,初学者估计看上3遍估计业不会名白(象我)呵呵,高手哪?又看不上这本书,因为太理论太简单了,劝兄台看看win2000驱动设计和wdm模型,但是如果你有基础的话,函数,ddk 宏等都有基础,这本书的代码是非常好的,很简单,很说明问题
win2000driver太理论,不适和初学者,但是你要是有点基础的,看这本书没错,书不错,代码业很好,wdm模型很好,但也要有基础,什么是基础?总是就是多看多想,我是初学者中的才鸟,希望多多切磋,hohoho,别嫌我烦,only you ............ :D :D :D
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-06-25 12:49
Walter Oney那本书我觉得更难 :(理论讲的很透彻,但是偶基础太差,比如第三章基本编程技术和第四章同步就没看懂,云里雾里的,不仅是驱动的基础差,而是整个计算机的基础都差!愁啊!愁的我一个劲去灌水,都灌成中级会员了 :(可知识一点没学到。
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2003-06-25 14:37

两位的意思是不是这样:
写分发例程向共享内存缓冲区中的指定偏移位置(即FilePointer)开始写数据,那这里的BufferSize和NewBufferSize就不是缓冲区的大小,而是缓冲区中的偏移位置。不知这样理解对不对?

另外,我还有一点不明白:既然FilePointer是偏移量,那基地址是什么呢?

buffersize就是buffer的size啊 :P
地址?在分配内存的时候,就得到地址了啊。
PVOID NewBuffer=ExAllocatePool((UNLONG)FilePiointer+WriteLen);
Buffer = (PUCHAR)NewBuffer;
BufferSize = NewBufferSize;
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-06-25 15:44
如果BufferSize就是buffer的大小,那么为什么要分配一个大小为FilePionter+WriteLen的缓冲区?而不是分配一个大小为WriteLen的缓冲区?
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
windyguy
驱动牛犊
驱动牛犊
  • 注册日期2003-05-07
  • 最后登录2004-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-06-25 18:59
nlq_new兄,buffer size是当前缓冲区的大小,而WriteLen是要写入的数据的长度,所以FilePointer+WriteLen才是需要的新缓冲区大小,如果只申请WriteLen大小的缓冲区,那原来可能存在与缓冲区的数据你要怎么办?覆盖掉?!所以FilePointer+WriteLen的意思是在原来已经存在的内容的基础上增加WriteLen的空间来保存新写入的内容。

注意:buffer确切地说是硬件模拟作用的一块内存地址,不是一般意义上的缓冲区。

Chris Cant的书只要大概看看就好,实在有些浅,不过如果不是这本书,我实在不可能在半个月内从一窍不通到能完成论文。如果是像我一样对windows内核完全不了解的人,看完Chris Cant的书,只能说基本上对wdm的架构能有个了解而已。
CX利刃
驱动小牛
驱动小牛
  • 注册日期2001-11-21
  • 最后登录2003-09-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-06-26 15:30
no
楼上的阿兄说得不对哦,如果你能完全看懂wdm开发指南,那么你也是高手了,hohoho
godhuntress
驱动小牛
驱动小牛
  • 注册日期2002-12-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-06-26 15:44
初学用chris cant的书还是稍微难了点。但是看完以后,也不能说就很明白,所以,这本书有些尴尬
武汉新手前来报道! 请不佞赐教!
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-06-26 16:31
可是如果你要分配新内存缓冲区NewBuffer,不用保留原来存在于这段内存中的内容,直接分配就好了吧?保留它有什么用呢?另外,我觉得,FilePointer是偏移量,WriteLen是一个ULONG型变量,我觉得:偏移量+ULONG=偏移量,所以NewBufferSize应该是一个偏移量,不知这样想对不对?错在哪里?
windyguy的回答看不明白,想了半天,“注意:buffer确切地说是硬件模拟作用的一块内存地址,不是一般意义上的缓冲区。”这句话的意思是不是说在这种分配方式下,每次都是从一个固定的位置开始分配新的内存的,所以新分配的缓冲区中包括以前的旧缓冲区。而不是一般情况下,每次新分配的缓冲区都不会和以前分配的旧缓冲区有重叠的部分。说的很拗口 :)没办法,太菜了。各位大侠见笑,但是笑之余还请指点一二,谢谢了 :)。
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
windyguy
驱动牛犊
驱动牛犊
  • 注册日期2003-05-07
  • 最后登录2004-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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是硬件模拟作用。
nlq_new
驱动老牛
驱动老牛
  • 注册日期2003-04-11
  • 最后登录2012-04-28
  • 粉丝0
  • 关注0
  • 积分102分
  • 威望12点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-06-27 09:41
现在明白了buffer size是当前缓冲区的大小。 :)
那我说的第二段话对不对呀?
还是不明白为什么要保留原来可能存在与缓冲区的数据,这些数据有什么用呢?不懂啊!指点指点
 :(
[b][color=green]我庄严宣誓我没干好事[/color] [/b]
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
15楼#
发布于:2003-06-27 14:32
不是有没有用,而是你应该这样做。
不能捡了西瓜,就不要冬瓜了啊 :D
windyguy
驱动牛犊
驱动牛犊
  • 注册日期2003-05-07
  • 最后登录2004-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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);
游客

返回顶部