オーディオのプロパティのハンドラー
ミニポート ドライバーは、PCPROPERTY_ITEM 構造体でサポートされている各プロパティに関する情報を格納します。 この構造体には、プロパティに関する次の情報が含まれています。
プロパティ セット GUID とプロパティ ID (またはインデックス)
プロパティのハンドラー ルーチンへの関数ポインター
ハンドラーがサポートするプロパティ操作を指定するフラグ
ミニポート ドライバーは、フィルターの自動化テーブル (PCAUTOMATION_TABLE 構造体で指定) を提供します。 ドライバーは、フィルターのピンの種類とノードの種類に関する追加の自動化テーブルを提供します。ピンまたはノードの種類にはそれぞれ、独自のテーブルがあります。 各自動化テーブルには、PCPROPERTY_ITEM 構造体の配列 (空の可能性があります) が含まれており、これらの各構造体は、フィルター、ピン、またはノードの 1 つのプロパティを記述します。 クライアントがプロパティ要求をフィルター、ピン、またはノードに送信すると、ポート ドライバーは自動化テーブルを介して適切なプロパティ ハンドラーに要求をルーティングします。
ミニポート ドライバーは、各プロパティの一意のプロパティ ハンドラー ルーチンを指定できます。 ただし、ドライバーがいくつかの類似したプロパティを処理する場合は、便宜上、これらを 1 つのハンドラー ルーチンにまとめることができます。 プロパティごとに一意のハンドラーを提供するか、複数のプロパティを 1 つのハンドラーにまとめるかは、ドライバー作成者が行う実装の決定であり、プロパティ要求を送信するクライアントに対して透過的である必要があります。
ユーザー モード クライアントは、dwIoControlCode 呼び出しパラメーターを IOCTL_KS_PROPERTY に設定して、Microsoft Win32 関数 DeviceIoControl を呼び出すことによって、get、set、または basic-support プロパティ要求を送信することができます。 オペレーティング システムは、この呼び出しを IRP に変換し、クラス ドライバーにディスパッチします。 詳細については、「KS のプロパティ」を参照してください。
クライアントが KS プロパティ要求 (つまり、IOCTL_KS_PROPERTY I/O コントロール IRP) をフィルター ハンドルまたはピン ハンドルに送信すると、KS システム ドライバー (Ks.sys) は、フィルター オブジェクトまたはピン オブジェクトのポート ドライバーに要求を配信します。 ミニポート ドライバーがプロパティのハンドラーを提供する場合、ポート ドライバーはハンドラーに要求を転送します。 要求を転送する前に、ポート ドライバーは、プロパティ要求から PCPROPERTY_REQUEST 構造体で指定された形式に情報を変換します。 ポート ドライバーは、ミニポート ドライバーのハンドラーにこの構造体を渡します。
PCPROPERTY_REQUEST の MajorTarget メンバーは、オーディオ デバイスのプライマリ ミニポート ドライバー インターフェイスを指します。 たとえば、WavePci デバイスの場合、これはミニポート ドライバー オブジェクトの IMiniportWavePci インターフェイスへのポインターです。
フィルター ハンドルに送信された KS プロパティ要求の場合は、PCPROPERTY_REQUESTの MinorTarget メンバーは NULL です。 要求がピン ハンドルに送信された場合は、MinorTarget はピンのストリーム インターフェイスを指します。 たとえば、WavePci デバイスの場合、これはストリーム オブジェクトの IMiniportWavePciStream インターフェイスへのポインターです。
PCPROPERTY_REQUESTの Instance メンバーと Value メンバーは、それぞれ KS プロパティ要求の入力バッファーと出力バッファーを指します。 (バッファーは、DeviceIoControl 関数の lpInBuffer パラメーターと lpOutBuffer パラメーターによって指定されます)。これらのバッファーには、「オーディオ ドライバーのプロパティ セット」で説明されているように、プロパティ記述子 (インスタンス データ) とプロパティ値 (操作データ) がそれぞれ含まれます。 Value メンバーは出力バッファーの先頭を指しますが、インスタンス ポインターは入力バッファーの先頭からのオフセットです。
入力バッファーは、KSPROPERTY 構造体、または KSNODEPROPERTY 構造体で始まります。 ポート ドライバーは、この構造体から、PCPROPERTY_REQUEST 構造体の Node、PropertyItem、および Verb メンバーに情報をコピーします。 バッファー内に KSPROPERTY または KSNODEPROPERTY 構造体に続くデータがある場合、ポート ドライバーは、このデータへのポインターを持つ Instance メンバーを読み込みます。 それ以外の場合は、Instance を NULL に設定します。
入力バッファーがノード情報を含まない KSPROPERTY 構造体で始まる場合、ポート ドライバーは、PCPROPERTY_REQUEST 構造体の Node メンバーを ULONG(-1) に設定します。 この場合、ポート ドライバーは、プロパティ要求のターゲットがフィルター ハンドルまたはピン ハンドルで指定されているかどうかに応じて、フィルターまたはピンのミニポート ドライバーの自動化テーブルから適切なハンドラーを呼び出します。 (テーブルでプロパティのハンドラーが指定されていない場合、ポート ドライバーが代わりに要求を処理します)。
入力バッファーが KSNODEPROPERTY 構造体で始まる場合は、ポート ドライバーはこの構造体のノード ID を PCPROPERTY_REQUEST 構造体の Node メンバーにコピーし、ノードのミニポート ドライバーの自動化テーブルから適切なハンドラーを呼び出します。 (ここでも、テーブルでプロパティのハンドラーが指定されていない場合は、ポート ドライバーが代わりに要求を処理します)。
ポート ドライバーは、プロパティ要求の操作フラグで KSPROPERTY_TYPE_TOPOLOGY ビットをチェックして、2 つの構造体、KSPROPERTY または KSNODEPROPERTY のうちどちらが入力バッファーの先頭に存在するかを判断します。
このビットが設定されている場合、要求はノード プロパティに対するものであり、入力バッファーは KSNODEPROPERTY 構造体で始まります。
それ以外の場合、入力バッファーは KSPROPERTY 構造体で始まります。
KSPROPERTY_TYPE_TOPOLOGY の詳細については、「KSPROPERTY」を参照してください。
PCPROPERTY_REQUEST 構造体の InstanceSize メンバーと ValueSize メンバーは、Instance メンバーと Value メンバーが指すバッファーのサイズを指定します。 ValueSize はプロパティ要求の出力バッファーのサイズと同じですが、InstanceSize は入力バッファー内の KSPROPERTY または KSNODEPROPERTY 構造体に続くデータのサイズです。 つまり、InstanceSize は、入力バッファーのサイズから KSPROPERTY または KSNODEPROPERTY 構造体のサイズを引いた値です。 この構造体の後に続く追加のデータがない場合、ポート ドライバーは InstanceSize を 0 (および Instance を NULL) に設定します。
たとえば、クライアントが入力バッファー内のインスタンス データとして KSNODEPROPERTY_AUDIO_CHANNEL 構造体を指定する場合、ポート ドライバーは、Instance メンバーが KSNODEPROPERTY_AUDIO_CHANNEL 構造体の Channel メンバーを指し、InstanceSize メンバーに値が含まれている PCPROPERTY_REQUEST 構造体をハンドラーに渡します。
sizeof(KSNODEPROPERTY_AUDIO_CHANNEL) - sizeof(KSNODEPROPERTY)
プロパティ値を取得する get プロパティ要求を送信する前に、クライアントは、ミニポート ドライバーのプロパティ ハンドラーがプロパティ値を書き込むことができる出力バッファーを割り当てる必要があります。 一部のプロパティでは、出力バッファーのサイズはデバイスに依存するため、クライアントは必要なバッファー サイズについてプロパティ ハンドラーにクエリを実行する必要があります。 このような場合、クライアントは、出力バッファー ポインターが nullptr で、出力バッファーの長さが 0 の初期プロパティ要求を送信します。 ハンドラーは、必要なバッファー サイズと状態コード STATUS_BUFFER_OVERFLOW を返すことで応答します。 次に、クライアントは、指定したサイズの出力バッファーを割り当て、2 番目の get-property 要求でこのバッファーを送信することによって、プロパティ値を取得します。
指定したバッファー サイズが小さすぎて要求された情報を受信することができない場合、メソッドは STATUS_BUFFER_TOO_SMALL を返します。
場合によっては、PortCls ポート ドライバーは、0 以外の出力バッファー アドレスとサイズを持つプロパティ要求に応答して、STATUS_BUFFER_OVERFLOW ではなく、STATUS_BUFFER_TOO_SMALL を返します。 このような場合、必要なバッファー サイズは返されません。
詳細については、「NTSTATUS 値」の使用、および以下のブログ記事を参照してください。