驱动开发之四 --- 过滤驱动之二 【译文】

驱动开发之四 --- 过滤驱动之二 【译文】

在驱动中处理irp

一旦你得到IRP,你就拥有了这个IRP. 你就能够使用它做任何你想要的事情。 如果你处理它,当你处理完时你就必须要么完成它,要么把它向下传给另外的驱动。如果你把它传给其他的驱动,你就必须忘记它。你传递给的驱动现在负责完成它。

这个例子过滤驱动,我们地实现有些不同,在我们提供irp给例子驱动后,它想要处理参数。

这样,我们必须要捕获完成时并停止它。因为我们知道底层驱动将会完成它。所以,我们设置我们自己的completion routine, 我们就能停止它。下面就是我们的实现代码。

pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(Irp,  

       PIO_COMPLETION_ROUTINE) ExampleFilter_CompletionRoutine, NULL,  

       TRUE, TRUE, TRUE);

/*

* IoCallDriver() simply calls the  

* appropriate entry point in the driver object associated

* with the device object.   This is  

* how drivers are basically "chained" together, they must know

* that there are lower driver so they  

* can perform the appropriate action and send down the IRP.

*

* They do not have to send the IRP down  

* they could simply process it completely themselves if they wish.

*/

NtStatus = IoCallDriver(

           pExampleFilterDeviceContext->pNextDeviceInChain, Irp);

/*

* Please note that our  

* implementation here is a simple one.   We do not take into account  

* PENDING IRP's oranything complicated.   We assume that once we get   

* to this locaiton the IRP has alreadybeen completed and our completetion   

* routine was called or it wasn't completed and we are still able  

* to complete it here.

* Our completetion routine makes sure that the IRP is still valid here.

*

*/

if(NT_SUCCESS(NtStatus)

{       /*

          * Data was read?

          */

     if(Irp->IoStatus.Information)

     {

       /*

        * Our filter device is dependent upon the compliation settings of  

        * how we compiled example.sys

        * That means we need to dynamically figure out if we're  

        * using Direct, Buffered or Neither.

        */

       if(DeviceObject->Flags & DO_BUFFERED_IO)

       {

          DbgPrint("ExampleFilter_Read - Use Buffered I/O \r\n");

          /*

           * Implementation for Buffered I/O

           */

          pReadDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;

                 

          if(pReadDataBuffer  

              && pIoStackIrp->Parameters.Read.Length > 0)

          {                              

              ExampleFilter_FixNullString(pReadDataBuffer,  

                            (UINT)Irp->IoStatus.Information);

          }

        }

        else

        {

           if(DeviceObject->Flags  

                & DO_DIRECT_IO)

           {

               DbgPrint("ExampleFilter_Read - Use Direct I/O \r\n");

                /*

                 * Implementation for Direct I/O

                 */

                if(pIoStackIrp && Irp->MdlAddress)

                {

                  pReadDataBuffer = MmGetSystemAddressForMdlSafe(

                          Irp->MdlAddress, NormalPagePriority);    

                  if(pReadDataBuffer &&  

                      pIoStackIrp->Parameters.Read.Length)

                  {                              

                      ExampleFilter_FixNullString(pReadDataBuffer,

                                      (UINT)Irp->IoStatus.Information);

                  }

                 }

            }

            else

            {

               DbgPrint("ExampleFilter_Read - Use Neither I/O \r\n");

               /* Implementation for Neither I/O

                */

               __try {

         

                       if(pIoStackIrp->Parameters.Read.Length >  

                                                 0 && Irp->UserBuffer)

                       {

                     

                         ProbeForWrite(Irp->UserBuffer,

                              IoStackIrp->Parameters.Read.Length,  

                              TYPE_ALIGNMENT(char));

                         pReadDataBuffer = Irp->UserBuffer;

                     

                         ExampleFilter_FixNullString(pReadDataBuffer,

                                        (UINT)Irp->IoStatus.Information);

                        }

                     

                } __except( EXCEPTION_EXECUTE_HANDLER ) {

                     

                     NtStatus = GetExceptionCode();      

                }

            }

        }

      

     }

}

你可能感兴趣的:(驱动开发学习)