3

我是 Windows 设备驱动程序编程的新手。我知道某些操作只能在 IRQL 执行PASSIVE_LEVEL。例如,微软有这个如何从内核驱动程序写入文件的示例代码:

if (KeGetCurrentIrql() != PASSIVE_LEVEL)
    return STATUS_INVALID_DEVICE_STATE; 

Status = ZwCreateFile(...);

我的问题是:是什么阻止了在上述KeGetCurrentIrql()检查后提出 IRQL?假设发生上下文或线程切换,当它返回到我的驱动程序时,IRQL 会不会突然出现,DISPATCH_LEVEL这会导致系统崩溃?

如果这是不可能的,那么为什么不只检查DriverEntry函数中的 IRQL 并一劳永逸地完成它呢?

4

3 回答 3

2

线程的 irql 只能由自己引发。

因为你是从上/下驱动调用的,所以当前运行上下文的irql可能不同。并且有几个函数可以提高/降低 irql。

几个例子:

IRP_MJ_READ

   NTSTATUS DispatchRead(
    __in struct _DEVICE_OBJECT  *DeviceObject,
    __in struct _IRP  *Irp
    )
  {
     // this will be called at irql == PASSIVE_LEVEL
     ...
     // we have acquire a spinlock
     KSSPIN_LOCK lck;
     KeInititializeSpinLock( &lck );
     KIRQL prev_irql;
     KeAcquireSpinLock( &lck,&prev_irql );

     // KeGetCurrentIrql() == DISPATCH_LEVEL 

     KeReleaseSpinLock( &lck, prev_irql );
     // KeGetCurrentIrql() == PASSIVE_LEVEL 
     ...
  }

(Io-)Completion 例程可能会被调用,DISPATCH_LEVEL因此应该有相应的行为。

NTSTATUS CompleteSth(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)
{
    // KeGetCurrentIrql() >= PASSIVE_LEVEL
}
于 2010-02-22T13:33:38.410 回答
2

IRQL 只能通过设置在您的控制下以任何有意义的方式更改。有两个“线程特定”的 IRQL - PASSIVE_LEVEL 和 APC_LEVEL。您可以使用诸如快速互斥锁之类的东西控制进出这些级别,并且到您的线程的上下文切换将始终使您处于以前的级别。上面是“特定于处理器的”IRQL。即 DISPATCH_LEVEL 或以上。在这些级别中,不会发生上下文切换。您可以使用自旋锁等进入这些级别。ISR 将在您的线程上较高的 IRQL 处发生,但您看不到它们。当他们将控制权交还给您时,您的 IRQL 就会恢复。

于 2010-04-03T12:17:55.630 回答
0

DriverEntry 也在 PASSIVE_LEVEL 调用。

如果您想在 PASSIVE_LEVEL 完成工作,请使用IoQueueWorkItem 之类的函数

于 2010-03-31T17:44:57.477 回答