首页
社区
课程
招聘
[旧帖] [求助]文件过滤驱动问题 0.00雪花
发表于: 2009-8-24 17:05 1379

[旧帖] [求助]文件过滤驱动问题 0.00雪花

2009-8-24 17:05
1379
     各位大牛,我最近在看过滤驱动,遇到点问题.......希望可以帮我看看

     在IRP_MJ_READ 例程中,获得文件内容,可是总蓝屏...调试信息是


kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

MULTIPLE_IRP_COMPLETE_REQUESTS (44)
A driver has requested that an IRP be completed (IoCompleteRequest()), but
the packet has already been completed.  This is a tough bug to find because
the easiest case, a driver actually attempted to complete its own packet
twice, is generally not what happened.  Rather, two separate drivers each
believe that they own the packet, and each attempts to complete it.  The
first actually works, and the second fails.  Tracking down which drivers
in the system actually did this is difficult, generally because the trails
of the first driver have been covered by the second.  However, the driver
stack for the current request can be found by examining the DeviceObject
fields in each of the stack locations.
Arguments:
Arg1: 8119b6d8, Address of the IRP
Arg2: 00001c13
Arg3: 00000000
Arg4: 00000000

      

IRP_MJ_READ 例程代码如下:

  NTSTATUS
      SfRead(
      IN PDEVICE_OBJECT  DeviceObject,
      IN PIRP  Irp
      )
    {     
        LARGE_INTEGER offset;
              PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
        offset.QuadPart = irpsp->Parameters.Read.ByteOffset.QuadPart;
        PFILE_OBJECT file_object = irpsp->FileObject;
        PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        
        //
        // 现在还没有对自己设备的控制设备进行读操作,所以要返回错误
        //
        if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
        {
          Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
          Irp->IoStatus.Information = 0;
          IoCompleteRequest(Irp,IO_NO_INCREMENT);
          return STATUS_INVALID_DEVICE_REQUEST;
        }

        if (devExt->StorageStackDeviceObject == NULL)
        {
          return SfPassThrough(DeviceObject,Irp);
        }

        //  对文件的读操作
      /*  switch (irpsp->MinorFunction)
        {
        case IRP_MN_NORMAL:
          {
            KEVENT waitEvent;
            void *buffer;
            ULONG Length;
            NTSTATUS status;
            
            

          KeInitializeEvent(&waitEvent,NotificationEvent,FALSE);
          IoCopyCurrentIrpStackLocationToNext(Irp);
          
          IoSetCompletionRoutine(Irp,SfReadCompletion,&waitEvent,true,true,true);
            status =  IoCallDriver(devExt->AttachedToDeviceObject,Irp);

          if (STATUS_PENDING == status)
          {
            status = KeWaitForSingleObject(&waitEvent,Executive,KernelMode,FALSE,NULL);
          }
          if (Irp->IoStatus.Status == STATUS_SUCCESS)
          {
          
            if (Irp->MdlAddress != NULL)
              buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
            else
              buffer = Irp->UserBuffer;

            Length = Irp->IoStatus.Information;
           }

          Irp->IoStatus.Information = Length;
          Irp->IoStatus.Status = STATUS_SUCCESS;

           //移动文件指针,防止读取相同的位置
          irpsp->FileObject->CurrentByteOffset.QuadPart = Length + offset.QuadPart; 

          IoCompleteRequest(Irp,IO_NO_INCREMENT);
          return STATUS_SUCCESS;
          }break;
          
        }
*/

        
      IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(((PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject,Irp);

    }

    NTSTATUS
      SfReadCompletion(
      IN PDEVICE_OBJECT  DeviceObject,
      IN PIRP  Irp,
      IN PVOID  Context
      )
    {

      ASSERT(Context != NULL);

      if (Irp->PendingReturned)
      {
        IoMarkIrpPending(Irp);
      }

      KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);

      return STATUS_MORE_PROCESSING_REQUIRED;
    

    }

取消注释就蓝屏,不知道什么原因~~~~~~,,希望各位大牛能帮我看看.给点提示也好.

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 57
活跃值: (105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
由于过滤驱动的异步工作模式,所以在卸载时需要做一些特殊处理。如果直接卸载的话,当时必然还有一个irp在键盘物理驱动中处于pending状态,一旦其返回就会找不到我们的过滤驱动,就会BIOS。因而一个比较直观的想法是在unload时需要人为的按键,使那个处于pending状态的IRP立即返回。

VOID DriverUnload(   
                              IN PDRIVER_OBJECT     DriverObject   
                              )   
{   
    KTIMER              kTimer;   
    LARGE_INTEGER       timeout;           
    PDEVICE_OBJECT      pDevObj = pdoGlobalDrvObj->DeviceObject;   
    PDEVICE_EXTENSION   pdx = (PDEVICE_EXTENSION) pDevObj->DeviceExtension;   
  
    // 解除过滤驱动,释放调用者设备对象与物理驱动之间的绑定关系   
    // 这样以后的IRP就不会经过这个过滤驱动,irp的挂起数目就不会增加   
    if ( pdx->bAttached )   
    {   
        IoDetachDevice ( pdx->pKeybdDevObject ) ;   
        pdx->bAttached = FALSE ;   
    }   
    //....
    //....
}
2009-8-24 17:41
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
读操作,是不是要在完成例程中才能得到内容?因为你拦截到的时候,如果还没交给底层文件驱动去做,其实还没读硬盘呢?
不一定正确,希望有帮助!
2009-8-24 18:04
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
是的,要获取读的内容是要等读完成后才能获得内容,所以设置了完成例程,等完成的时候出发事件,在派遣函数中从新获得IRP的操作权,  可是这样做蓝频啊~~
2009-8-25 08:55
0
游客
登录 | 注册 方可回帖
返回
//