mikeche6361
驱动牛犊
驱动牛犊
  • 注册日期2008-06-25
  • 最后登录2011-12-23
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望32点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1887回复:1

一个关于在DISPATCH_LEVEL上,分页,非分页内存的问题

楼主#
更多 发布于:2011-12-22 19:53

  IoSetCompletionRoutine(,,context,)例程在DDK文档中明确要求第三个参数必须是在非分页内存中分配的内存区域,这是因为IoSetCompletionRoutine例程会提升IRQL到DISPATCH_LEVEL。我在DDK自带的例子tobaster的busenum.sys -> pnp.c ->Bus_SendIrpSynchronously()函数中看到,传递给IoSetCompletionRoutine的变量event却是在分页内存中分配的程序运行不会有任何错误或蓝屏发生,代码片段如下:
   KEVENT   event;
    NTSTATUS status;
    PAGED_CODE();
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(Irp,
                           Bus_CompletionRoutine,
                           &event,
                           TRUE,
                           TRUE,
                           TRUE
                           );
    status = IoCallDriver(DeviceObject, Irp);
    
    if (status == STATUS_PENDING) {
       KeWaitForSingleObject(&event,
                             Executive,
                             KernelMode,
                             FALSE,
                             NULL
                             );
       status = Irp->IoStatus.Status;
    }
    return status;
  请问这种情况该如何解释,在DISPATCH_LEVEL级访问非分页内存唯一方法是访问前必须先锁定,但在该函数中明显没有锁定,为什么?
mikeche6361
驱动牛犊
驱动牛犊
  • 注册日期2008-06-25
  • 最后登录2011-12-23
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望32点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2011-12-23 01:40
:o:找到答案了,原来event占用的内存是在内核栈中分配的,当然没有分页的问题了,看来我还是菜啊 连内核栈都不知道
驱动程序肯定是在CPU的RING 0层运行,使用的堆栈是内核栈(Kernel Stack),而内核栈中的变量是不会被分页的,而如何判断内核栈是不是被用光了?要确定是否存在足够的堆栈空间来调用函数或执行任务,驱动程序可以调用 IoGetStackLimits 和 IoGetRemainingStackSize 例程。如果没有足够的堆栈空间可用,那么驱动程序可以将任务排队到一个工作项(在单独的线程中运行,因此拥有其自身的内核模式堆栈)。但是,请记住,工作项将以 PASSIVE_LEVEL 级别在系统工作线程中运行。请记住,在原始版本的 Windows Server 2003 RTM 和早期版本的 Windows 中,必须以 IRQL PASSIVE_LEVEL 或 IRQL APC_LEVEL 调用 IoGetStackLimits 和 IoGetRemainingStackSize,因此不能以 DISPATCH_LEVEL 或更高级别(例如 DPC 例程)从任何例程调用它们。从 Windows Server 2003 SP1 开始,可以以任何 IRQL 调用 IoGetStackLimits 和 IoGetRemainingStackSize。
重要:驱动程序不应该另外分配内存并将其作为内核模式堆栈使用。这绝不是任何平台的建议实践,因为它会影响操作系统的稳定性和可靠性。在基于 x64 的系统上,如果操作系统检测到未经授权的内核模式堆栈,那么它将生成一个错误检查并关闭系统。

游客

返回顶部