次の方法で共有


関連付け記述子

関連付け記述子は、別の引数に関連する 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

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

手記

多次元サイズの配列とポインターによって、-Oicfへの切り替えがトリガーされます。

 

FC_CONSTANT_CONFORMANCE

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

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

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

手記

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

コンパイラは、上記の定数式、および評価式ルーチンを呼び出す必要がある場合 (たとえば、FC_CONSTANT_CONFORMANCEとFC_CALLBACKを使用する場合) の場合に、ニブル型を 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> フィールドの解釈は、式の複雑さ、式変数の場所、配列の場合、配列が実際に属性付きポインターであるかどうかによって異なります。

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

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

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

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

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;

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

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

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

差異の説明とその他の配列属性

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

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