次の方法で共有


インターフェイスとメソッドの設計を改善するための IDL 手法

準拠データとバリアント データの両方を処理する RPC インターフェイスとメソッドを開発する場合は、次の IDL 固有の手法を使用してセキュリティとパフォーマンスを向上することを検討してください。 このトピックで参照する属性は、準拠データ ([size_is] 属性や [max_is] 属性など) またはバリアント データ ([length_is] 属性や [文字列] 属性など) を処理するメソッド パラメーターに設定される IDL 属性です。

[range] 属性と準拠データ パラメーターの使用

[範囲] 属性は、データのマーシャリング解除プロセス中に追加のサイズ検証を実行するように RPC ランタイムに指示します。 具体的には、関連付けられたパラメーターとして渡されるデータの指定されたサイズが指定された範囲内にあることを確認します。

[範囲] 属性は、ワイヤ形式には影響しません。

ネットワーク上の値が許容範囲外の場合、RPC はRPC_X_INVALID_BOUNDまたはRPC_X_BAD_STUB_DATA例外をスローします。 これにより、追加のレベルのデータ検証が提供され、バッファー オーバーランなどの一般的なセキュリティ エラーを防ぐことができます。 同様に、[範囲] を使用すると、マークされた準拠データに RPC サービスで考慮できる明確に定義された制約があるため、アプリケーションのパフォーマンスを向上させることができます。

RPC サーバー スタブ メモリ管理規則

RPC 対応アプリケーションの IDL ファイルを作成するときは、RPC サーバー スタブ メモリ管理規則を理解することが重要です。 アプリケーションは、[範囲] を上記の準拠データと組み合わせて使用し、[length_is] のような可変長データ IDL 属性を準拠データに意図的に適用しないようにすることで、サーバー リソースの使用率を向上させることができます。

IDL ファイルで定義されているデータ構造フィールドへの [length_is] の適用はお勧めしません。

可変長データ パラメーターのベスト プラクティス

変数サイズのデータ構造、メソッド パラメーター、およびフィールドの IDL 属性を定義する際に考慮すべきベスト プラクティスをいくつか次に示します。

  • 早期相関を使用します。 一般に、可変サイズのパラメーターまたはフィールドは、制御する整数型の直後に発生するように定義することをお勧めします。

    例えば

    earlyCorr
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long size, 
    [in,size_is(size)] char *pv
    );
    

    より優れています

    lateCorr
    (
    [in,size_is(size)] char *pv, 
    [in, range(MIN_COUNT, MAX_COUNT)] long size)
    );
    

    ここで、earlyCorr は可変長データ パラメーターの直前に size パラメーターを宣言し、lateCorr その後に size パラメーターを宣言します。 早期対応を使用すると、特にメソッドが頻繁に呼び出される場合に、全体的なパフォーマンスが向上します。

  • [出力、size_is] 属性タプルでマークされたパラメーター、およびクライアント側でデータ長がわかっている場合、またはクライアントが適切な上限を持っている場合、メソッド定義はパラメーターの属性とシーケンスの点で次のようになります。

    outKnownSize
    (
    [in,range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out,size_is(lSize)] UserDataType * pArr
    );
    

    この場合、クライアントは pArr 固定サイズのバッファーを提供します。これにより、サーバー側の RPC サービスは、十分な程度の保証で適切なサイズのバッファーを割り当てることができます。 この例では、データはサーバーから受信されることに注意してください ([出力])。 定義は、サーバーに渡されるデータに似ています ([]の)。

  • RPC アプリケーションのサーバー側コンポーネントがデータの長さを決定する場合、メソッド定義は次のようになります。

    typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG;
    
    outUnknownSize
    (
    [out] RANGED_LONG *pSize,
    [out,size_is(,*pSize)] UserDataType **ppArr
    );
    

    RANGED_LONG は、クライアントスタブとサーバースタブの両方に対して定義された型であり、指定されたサイズのクライアントが正しく予測できます。 この例では、クライアントは ppArr NULLとして渡し、RPC サーバー アプリケーション コンポーネントは適切なメモリ量を割り当てます。 返されると、クライアント側の RPC サービスは、返されたデータのメモリを割り当てます。

  • クライアントが大きな準拠配列のサブセットをサーバーに送信する場合、アプリケーションは次の例に示すようにサブセットのサイズを指定できます。

    inConformantVaryingArray
    (
    [in,range(MIN_COUNT,MAX_COUNT)] long lSize,
    [in] long lLength, 
    [in,size_is(lSize), length_is(lLength)] UserDataType *pArr
    );
    

    これにより、RPC は、lLength 配列の要素のみをネットワーク経由で送信します。 ただし、この定義により、RPC サービスは、サーバー側で lSize サイズのメモリを割り当てます。

  • クライアント アプリケーション コンポーネントが、サーバーが返すことができる配列の最大サイズを決定し、サーバーがその配列のサブセットを送信できるようにする場合、アプリケーションは次の例のように IDL を定義することで、このような動作を指定できます。

    inMaxSizeOutLength
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out] long *pLength,
    [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr
    );
    

    クライアント アプリケーション コンポーネントは配列の最大サイズを指定し、サーバーはクライアントに送信する要素の数を指定します。

  • サーバー アプリケーション コンポーネントがクライアント アプリケーション コンポーネントに文字列を返す必要があり、クライアントがサーバーから返される最大サイズを認識している場合、アプリケーションは次の例に示すように、準拠する文字列型を使用できます。

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • クライアント アプリケーション コンポーネントが文字列のサイズを制御しない場合、RPC サービスは、次の例に示すようにメモリを明示的に割り当てることができます。

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    クライアント アプリケーション コンポーネントは、RPC メソッド 呼び出すときに、ppStr を NULL するように設定する必要があります。