関連付け記述子

相関記述子は、別の引数に関連する 1 つの引数に基づいて式を記述する書式指定文字列です。 関連付け記述子は、[size_is()]、[length_is()]、[switch_is()]、[iid_is()] などの属性に関連するセマンティクスを処理するために必要です。 相関記述子は、配列、サイズ設定されたポインター、共用体、およびインターフェイス ポインターと共に使用されます。 最終的な式の値には、それぞれサイズ、長さ、共用体判別式、または IID へのポインターを指定できます。 書式指定文字列の観点では、相関記述子は配列、共用体、およびインターフェイス ポインターと共に使用されます。 サイズ設定されたポインターは、配列へのポインターとして書式指定文字列で記述されます。

基本的な式の計算を実行するルーチンは 2 つあります。NdrpComputeConformance はサイズ、スイッチ、IID* に使用され、NdrpComputeVariance は長さに使用されます。 また、攻撃拒否機能の相関値検証を実行する 1 つのルーチンもあります。

関連付け記述子は、非常に限られた式のみをサポートするように設計されています。 複雑な状況では、コンパイラは必要に応じ、エンジンによって呼び出される式評価ルーチンを生成します。

関連付け記述子の形式は次のとおりです。

correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]

相関記述子correlation_type<1> は 2 つのニブルで構成されます。上位 4 ビットは式が見つかる場所を表し、下位 4 ビットは式値の型を表します。

上のニブルには、次の 5 つの値のいずれかを指定できます。

00  FC_NORMAL_CONFORMANCE
10  FC_POINTER_CONFORMANCE
20  FC_TOP_LEVEL_CONFORMANCE
80  FC_TOP_LEVEL_MULTID_CONFORMANCE
40  FC_CONSTANT_CONFORMANCE

FC_NORMAL_CONFORMANCE

構造体のフィールドで説明されているような、通常の準拠のケース。

FC_POINTER_CONFORMANCE

属性付きポインター (size_is()、構造体内のフィールドである length_is()) の場合。 これは、ベース メモリ ポインターの設定方法に影響します。

FC_TOP_LEVEL_CONFORMANCE

別のパラメーターによって記述された最上位の準拠の場合。

FC_TOP_LEVEL_MULTID_CONFORMANCE

別のパラメーターで記述された多次元配列の最上位の準拠。

Note

多次元サイズの配列とポインターは 、–Oicf への切り替えをトリガーします。

 

FC_CONSTANT_CONFORMANCE

定数値の場合。 コンパイラは、ユーザーが指定した定数式から値を事前に計算します。 この場合、準拠の説明の後続の 3 バイトには、準拠サイズを記述する long の下位 3 バイトが含まれます。 それ以上の計算は必要ありません。

下位のニブルは、メモリから抽出する必要がある値の型を示します。

FC_LONG | FC_ULONG | 
FC_SHORT | FC_USHORT | 
FC_SMALL | FC_USMALL | 
FC_HYPER

Note

64 ビット式はサポートされていません。 FC_HYPERは、IID* のポインター値を抽出するために、64 ビット プラットフォームの iid_is() にのみ使用されます。

コンパイラは、上記の定数式と、評価式ルーチンを呼び出す必要がある場合 (たとえば、FC_CONSTANT_CONFORMANCEとFC_CALLBACKを使用する場合) の場合に、型 nibble を 0 に設定します。

 

size_is_op<1> フィールドを使用すると、次のいずれかの操作を準拠変数に適用できます。

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

FC_DEREFERENCE定数は、[ size_is(*pL)]のように、ポイント先の関連付けに使用されます。 算術演算子は、指定された定数を使用するだけです。 FC_CALLBACK定数は、式評価ルーチンを呼び出す必要があることを示します。

オフセット<2> フィールドは、通常、式引数変数に対する相対メモリ オフセットです。 式の評価ルーチン インデックスにすることもできます。 このドキュメントで既に説明したように、定数式の場合は、実際の最終的な式値の一部です。

オフセット<2> フィールドをメモリ オフセットとして解釈するかどうかは、式の複雑さ、式変数の場所、配列の場合、配列が実際に属性付きポインターであるかどうかによって異なります。

配列が属性付きポインターであり、準拠変数が構造体内のフィールドである場合、オフセット フィールドには、構造体の先頭から準拠を記述するフィールドまでのオフセットが含まれます。 配列が属性付きポインターではなく、準拠変数が構造体内のフィールドである場合、オフセット フィールドには、構造体の不適合部分の末尾から準拠を記述するフィールドまでのオフセットが含まれます。 通常、準拠する配列は構造体の末尾にあります。

最上位レベルの準拠の場合、offset フィールドには、スタック上のスタブの最初のパラメーターの位置から、準拠を記述するパラメーターまでのオフセットが含まれます。 これは –Os モードでは使用されません。 オフセット フィールドの解釈には、他にも例外があります。このような例外については、これらの型の説明で説明されています。

オフセット<2> をFC_CALLBACKと共に使用すると、コンパイラによって生成された式評価ルーチン テーブルにインデックスが含まれます。 スタブ メッセージは評価ルーチンに渡され、準拠値が計算され、スタブ メッセージの MaxCount フィールドに割り当てられます。

Windows 2000 では、攻撃拒否機能などの /robust をサポートするために、robust_flags<2> フィールドが追加されました。 最初のバイトには、次のフラグが定義されています。

typedef  struct  _NDR_CORRELATION_FLAGS
  {
  unsigned char   Early     : 1;
  unsigned char   Split     : 1;
  unsigned char   IsIidIs   : 1;
  unsigned char   DontCheck : 1;
  unsigned char   Unused    : 4;
  } NDR_CORRELATION_FLAGS;

Early フラグは、早期と遅延の相関関係を示します。 早い相関関係は、式引数が記述された引数の前にある場合です。たとえば、size 引数が size ポインター引数の前にある場合です。 遅延相関は、式引数が関連する引数の後に来る場合です。 エンジンはすぐに早期相関値の検証を実行し、マーシャリング解除が行われた後のチェックのために遅延相関値が格納されます。

Split フラグは、[in] 引数と [out] 引数間の非同期分割を示します。 たとえば、size 引数は [in] で、サイズ設定されたポインターは [out] にすることができます。 DCOM 非同期コンテキストでは、これらの引数は異なるスタック上に存在するため、エンジンはこれを認識する必要があります。

IsIidIs フラグは 、iid_is() の相関関係を示します。 NdrComputeConformance ルーチンは、式の値として IID へのポインターを取得するためにだまされますが、検証ルーチンはそのような値 (ポインター) を比較できないため、フラグは実際の IID を比較する必要があることを示します。

分散の説明とその他の配列属性

差異記述フィールドの形式は、準拠説明フィールドと同じです。 違いは、NDR エンジンによって別のスタブ メッセージ フィールドが一時変数として使用される点です。 分散の説明の場合は、評価される長さであり、対応するフィールドは ActualLength と呼ばれます。

分散を使用すると、通常、開始オフセットは 0 になり、それに応じてエンジンがチューニングされます。 first_is() 属性が準拠する可変配列に適用される場合、式評価ルーチンへのコールバックが強制されます。