kumingderen
驱动牛犊
驱动牛犊
  • 注册日期2009-08-24
  • 最后登录2010-01-14
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望161点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1462回复:8

文件过滤蓝屏,请前辈看看是什么原因

楼主#
更多 发布于:2009-08-24 17:40

各位大牛,我最近在看过滤驱动,遇到点问题.......希望可以帮我看看

     在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;
    



    }



取消注释就蓝屏,不知道什么原因~~~~~~,,希望各位大牛能帮我看看.给点提示也好.
JeTus
驱动牛犊
驱动牛犊
  • 注册日期2007-09-22
  • 最后登录2010-01-17
  • 粉丝3
  • 关注0
  • 积分84分
  • 威望781点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-08-24 21:32
KEVENT ?
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于:2009-08-24 22:23
检查你的irp完成函数
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
地板#
发布于:2009-08-24 22:37
interesting
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
地下室#
发布于:2009-08-24 22:42
引用第2楼znsoft于2009-08-24 22:23发表的 :
检查你的irp完成函数

没看过你的代码,不过从dump上看,是因为某个irp被重复完成导致的。看一下流程
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
JeTus
驱动牛犊
驱动牛犊
  • 注册日期2007-09-22
  • 最后登录2010-01-17
  • 粉丝3
  • 关注0
  • 积分84分
  • 威望781点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2009-08-24 23:45
KEVENT 被释放了
JeTus
驱动牛犊
驱动牛犊
  • 注册日期2007-09-22
  • 最后登录2010-01-17
  • 粉丝3
  • 关注0
  • 积分84分
  • 威望781点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2009-08-24 23:48
应该ExAllocatePool 一个KEVENT,然后返回在释放它。
JeTus
驱动牛犊
驱动牛犊
  • 注册日期2007-09-22
  • 最后登录2010-01-17
  • 粉丝3
  • 关注0
  • 积分84分
  • 威望781点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2009-08-24 23:56
感觉是KEVENT的问题,错了请指正,不晓得是不是。
kumingderen
驱动牛犊
驱动牛犊
  • 注册日期2009-08-24
  • 最后登录2010-01-14
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望161点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2009-08-25 14:25
谢谢各位了,我尝试了一下你们说的方法就是在堆上声请个内存保存KEVENT 不过好像没什么用,我把代码该成在完成例程中处理就不会蓝屏了..
      虽然这样改没什么问题,但我还是不明白是为什么.......
修改后的代码是::NTSTATUS
            SfRead(
            IN PDEVICE_OBJECT  DeviceObject,
            IN PIRP  Irp
            )
        {    
            
              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);
              }

                          IoCopyCurrentIrpStackLocationToNext(Irp);
                    
              IoSetCompletionRoutine(Irp,SfReadCompletion,NULL,true,true,true);
              return IoCallDriver(devExt->AttachedToDeviceObject,Irp);

        
        
        
        }


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

            

    
              PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
              PFILE_OBJECT file_object = irpsp->FileObject;

              KdPrint(("Read file name : %ws\n",file_object->FileName.Buffer));

              void *buffer;

               switch (irpsp->MinorFunction)
               {
               case IRP_MN_NORMAL:
                   {
                  
                      if (Irp->MdlAddress != NULL)
                          buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
                      else
                          buffer = Irp->UserBuffer;
                  
                   }break;
              
               }
            

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


            return Irp->IoStatus.Status;
        



        }
游客

返回顶部