我不了解Windows IRQL

时间:2014-11-16 04:34:43

标签: windows kernel driver

http://msdn.microsoft.com/en-us/library/windows/hardware/ff553079(v=vs.85).aspx

MSDN说必须使用KeRaiseIrql(newIrql, &oldIrql)调用newIrql,其中> = currentIrql

  

“如果新的IRQL小于当前的IRQL,则进行错误检查   发生。“

但是在下面的代码中KeRaiseIrql()适用于newIrql< {1}} currentIrql。 (此外,加载和卸载此驱动程序都运行良好。)

有没有人解释这个?

测试环境:WinXp(32位,Vmware播放器),Win7(32位,Vmware播放器)

#include <ntddk.h>

VOID DriverUnload
(
    IN PDRIVER_OBJECT DriverObject
)
{
    DbgPrint("BYE!\n");
}

NTSTATUS DriverEntry
(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
)
{
    KIRQL oldIrql;

    DriverObject->DriverUnload = DriverUnload;

    DbgPrint("Hello!\n");

    KeRaiseIrql(3, &oldIrql);

    DbgPrint("%d\n", KeGetCurrentIrql()); // 3

    KeRaiseIrqlToDpcLevel();

    DbgPrint("%d\n", KeGetCurrentIrql()); // 2

    KeRaiseIrql(1, &oldIrql);

    DbgPrint("%d\n", KeGetCurrentIrql()); // 1

    KeRaiseIrql(0, &oldIrql);

    DbgPrint("%d\n", KeGetCurrentIrql()); // 0

    DbgPrint("Yo!\n");

    return STATUS_SUCCESS;
}

1 个答案:

答案 0 :(得分:1)

如上所述,这取决于给定的操作系统实现。 如果您遇到这样的问题,最好使用调试器。

E.g。在win xp sp2发布i386我有:

    hal!KfRaiseIrql:
    806e43b8 0fb6d1          movzx   edx,cl
    806e43bb 0fb68a98436e80  movzx   ecx,byte ptr hal!HalpIRQLtoTPR (806e4398)[edx]
    806e43c2 a18000feff      mov     eax,dword ptr ds:[FFFE0080h]
    806e43c7 890d8000feff    mov     dword ptr ds:[0FFFE0080h],ecx
    806e43cd c1e804          shr     eax,4
    806e43d0 0fb68018f26e80  movzx   eax,byte ptr hal!HalpVectorToIRQL (806ef218)[eax]
    806e43d7 c3              ret

正如您所看到的那样,以前没有irql检查。如果你查看wrk源代码,你会发现KfRaiseIrql的版本在哪里被检查,同时请记住有检查和免费的Windows版本。最有可能在检查版本中你会有错误检查。

如果你想在你的代码上看到bsod,请使用Driver Verifier :) afair它正在检查是否正确使用了提升/降低irql。