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

请高手帮我分析下原因~~~~拜托

楼主#
更多 发布于:2009-08-25 16:20
         这是调试时候蓝屏的代码:
                             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(&Context, IO_NO_INCREMENT, FALSE);

      return STATUS_MORE_PROCESSING_REQUIRED;
 
    }

调试后蓝屏的分析信息是MULTIPLE_IRP_COMPLETE_REQUESTS (44).

我把代码改成在完成例程中执行就不会蓝屏.我一直不知道原因是什么.....

这个是改过的代码:
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;
        
        }

这样改以后就不蓝屏了~~郁闷啊.....


michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
沙发#
发布于:2009-08-25 17:47
One problem is:

    KeSetEvent(&Context, IO_NO_INCREMENT, FALSE);

Should it be:
    
    KeSetEvent(Context, IO_NO_INCREMENT, FALSE);
kumingderen
驱动牛犊
驱动牛犊
  • 注册日期2009-08-24
  • 最后登录2010-01-14
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望161点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-08-27 13:38
谢谢前辈
sqpcd
驱动牛犊
驱动牛犊
  • 注册日期2008-10-24
  • 最后登录2010-05-12
  • 粉丝0
  • 关注0
  • 积分24分
  • 威望171点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-11-17 16:04
读取文件应该在完成以后才计算偏移和长度吧。
游客

返回顶部