3

Windows デバイス ドライバーのプログラミングは初めてです。特定の操作は IRQL でのみ実行できることを知っていPASSIVE_LEVELます。たとえば、Microsoft には、カーネル ドライバーからファイルに書き込む方法の次のサンプル コードがあります。

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-)完了ルーチンはで呼び出される可能性がある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 の 2 つがあります。高速ミューテックスなどを使用して、これらのレベルの出入りを制御します。スレッドへのコンテキスト スイッチにより、常に以前のレベルに戻ります。その上には、「プロセッサ固有の」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 に答える