IRP_MN_CHANGE_SINGLE_ITEM
WMI をサポートするすべてのドライバーは、この IRP を処理する必要があります。 ドライバーは、「WMI 要求の処理」で説明されているように、WmiSystemControl を呼び出すか、ドライバー自身で IRP を処理することによって、WMI IRP を処理できます。
ドライバーが IRP_MN_CHANGE_SINGLE_ITEM 要求を処理するための WmiSystemControl を呼び出すと、WMI はそのドライバーの DpWmiSetDataItem ルーチンを呼び出します。
主要なコード
送信時
WMI は、この IRP を送信して、データ ブロックの 1 つのインスタンス内の 1 つのデータ項目を変更します。
WMI は任意のスレッド コンテキストで、IRQL = PASSIVE_LEVEL でこの IRP を送信します。
入力パラメーター
Parameters.WMI.ProviderId は、要求に応答する必要があるドライバーのデバイス オブジェクトを指します。 このポインターは、IRP のドライバーの I/O スタックの場所にあります。
Parameters.WMI.DataPath は、設定するデータ ブロックを識別する GUID を指します。
Parameters.WMI.BufferSize は、Parameters.WMI.Buffer の非ページ バッファーのサイズを示します。
Parameters.WMI.Buffer は、データ ブロックのインスタンス、設定する項目の ID、および新しいデータ値を識別する WNODE_SINGLE_ITEM 構造体を指します。
出力パラメーター
なし。
I/O 状態ブロック
ドライバーが WmiSystemControl を呼び出して IRP を処理する場合、WMI は I/O 状態ブロックで Irp->IoStatus.Status と Irp->IoStatus.Information を設定します。
それ以外の場合、ドライバーは Irp->IoStatus.Status を STATUS_SUCCESS または次のような適切なエラー状態に設定します。
STATUS_WMI_INSTANCE_NOT_FOUND
STATUS_WMI_ITEMID_NOT_FOUND
STATUS_WMI_GUID_NOT_FOUND
STATUS_WMI_READ_ONLY
STATUS_WMI_SET_FAILURE
成功した場合、ドライバーは Irp->IoStatus.Information を 0 に設定します。
操作
ドライバーが WMI IRP を処理するために WmiSystemControl を呼び出すと、そのルーチンはドライバーの DpWmiSetDataItem ルーチンを呼び出すか、ドライバーがこのルーチンを定義していない場合は STATUS_WMI_READ_ONLY を返します。
ドライバー自身が IRP_MN_CHANGE_SINGLE_ITEM 要求を処理する場合は、Parameters.WMI.ProviderId が、ドライバーが IoWMIRegistrationControl に渡したポインターと同じデバイス オブジェクトを指している場合にのみ、ドライバー自身がこの処理を行う必要があります。 それ以外の場合、ドライバーは、次の下位ドライバーに要求を転送する必要があります。
システム提供のユーザー モード コンポーネントでこの機能が必要である場合を除き、IRP_MN_CHANGE_SINGLE_ITEM のサポートを実装しないでください。
要求を処理する前に、ドライバーは、Parameters.WMI.DataPath がドライバーがサポートしている GUID を指しているかどうかを判断する必要があります。 指してない場合は、ドライバーは IRP に失敗し、STATUS_WMI_GUID_NOT_FOUND を返す必要があります。
ドライバーは、データ ブロックをサポートしている場合、Parameters.WMI.Buffer を指している入力 WNODE_SINGLE_ITEM 構造体を、インスタンス名について次のようにチェックする必要があります。
WNODE_FLAG_STATIC_INSTANCE_NAMES が WnodeHeader.Flags で設定されている場合は、ドライバーは、そのブロックの静的インスタンス名のドライバーのリストにインデックスとして InstanceIndex を使用します。 WMI は、ブロックを登録したときにドライバーによって提供される登録データからインデックスを取得します。
WnodeHeader.Flags で WNODE_FLAG_STATIC_INSTANCE_NAMES がクリアされている場合、ドライバーは OffsetInstanceName のオフセットを使用して、入力 WNODE_METHOD_ITEM 構造体内のインスタンス名の文字列を検索します。 OffsetInstanceName は、構造体の先頭からインスタンス名文字列の USHORT サイズの長さまでのバイト単位 (文字ではありません) のオフセットです。 この長さには、NULL 終端 (存在する場合) と、Unicode のインスタンス名文字列が含まれます。
ドライバーは、すべての入力値の検証を担当します。 具体的には、ドライバーは IRP 要求自体を処理する場合に、次の操作を行う必要があります。
静的な名前の場合は、WNODE_METHOD_ITEM 構造体の InstanceIndex メンバーが、データ ブロックのドライバーでサポートされているインスタンス インデックスの範囲内にあることを確認します。
動的な名前の場合は、インスタンス名の文字列が、ドライバーでサポートされているデータ ブロック インスタンスを識別することを確認します。
WNODE_SINGLE_ITEM 構造体の ItemId メンバーが、データ ブロックのドライバーでサポートされている項目識別子の範囲内にあることを確認します。
WNODE_SINGLE_ITEM 構造体の DataBlockOffset メンバーと SizeDataItem メンバーが有効なサイズのデータ ブロックを記述していること、およびバッファーの内容がデータ項目に対して有効であることを確認します。
指定したデータ項目が、呼び出し元によって開始された変更をドライバーが許可しているデータ項目であることを確認します。 言い換えれば、ドライバーは、読み取り専用とすることを意図したデータ項目の変更を許可しないようにする必要があります。
スレッド コンテキストが、開始したユーザー モード アプリケーションのコンテキストであると想定しないでください。上位レベルのドライバーによって変更されている可能性があります。
ドライバーは、指定したインスタンスを見つけることができない場合、IRP に失敗して、STATUS_WMI_INSTANCE_NOT_FOUND を返す必要があります。 動的インスタンス名を持つインスタンスの場合、この状態はドライバーがインスタンスをサポートしていないことを示します。 そのため、WMI は他のデータ プロバイダーに対してクエリを実行し続けることができ、別のプロバイダーがインスタンスを見つけたが何らかの理由で要求を処理できない場合は、データ コンシューマーに適切なエラーを返すことができます。
ドライバーは、インスタンスを見つけ、要求を処理できる場合、インスタンス内のデータ項目を WNODE_SINGLE_ITEM の値に設定します。 データ項目が読み取り専用の場合は、ドライバーは項目を変更せず、IRP に失敗し、STATUS_WMI_READ_ONLY を返します。
インスタンスが有効であっても、ドライバーが要求を処理できない場合は、適切なエラー状態を返すことができます。
要件
ヘッダー |
Wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む) |