Freigeben über


IDL-Techniken für ein besseres Schnittstellen- und Methodendesign

Erwägen Sie die folgenden IDL-spezifischen Techniken, um die Sicherheit und Leistung zu verbessern, wenn Sie RPC-Schnittstellen und -Methoden entwickeln, die sowohl konforme als auch Variantendaten verarbeiten. Die in diesem Thema genannten Attribute sind die IDL-Attribute, die für Methodenparameter festgelegt sind, die entweder konforme Daten verarbeiten (z. B. die Attribute [size_is] und [max_is] oder Variantendaten (z. B. die Attribute [length_is] und [Zeichenfolge] Attribute).

Verwenden des [range]-Attributs mit konformen Datenparametern

Das Attribut [Bereich] weist die RPC-Laufzeit an, während des Datenzusammenfassungsprozesses eine zusätzliche Größenüberprüfung durchzuführen. Insbesondere wird überprüft, ob die angegebene Größe der als zugeordneten Parameter übergebenen Daten innerhalb des angegebenen Bereichs liegt.

Das Attribut [Bereich] wirkt sich nicht auf das Drahtformat aus.

Wenn sich der Wert für Draht außerhalb des zulässigen Bereichs befindet, löst RPC eine RPC_X_INVALID_BOUND- oder RPC_X_BAD_STUB_DATA Ausnahme aus. Dies bietet eine zusätzliche Datenüberprüfungsebene und kann häufige Sicherheitsfehler wie Pufferüberläufe verhindern. Ebenso kann die Verwendung von [Bereich] die Anwendungsleistung verbessern, da mit ihr gekennzeichnete konforme Daten klar definierte Einschränkungen für die Prüfung durch den RPC-Dienst zur Verfügung stehen.

Rpc Server Stub Speicherverwaltungsregeln

Beim Erstellen der IDL-Dateien für eine RPC-fähige Anwendung ist es wichtig, die Regeln für die VERWALTUNG des RPC-Servers zu verstehen. Anwendungen können die Serverressourcenauslastung verbessern, indem [Bereich] in Verbindung mit konformen Daten verwendet wird, wie oben angegeben, sowie bewusst die Anwendung von Daten-IDL-Attributen mit variabler Länge wie [length_is] auf konforme Daten zu vermeiden.

Die Anwendung von [length_is] auf Datenstrukturfelder, die in einer IDL-Datei definiert sind, wird nicht empfohlen.

Bewährte Methoden für Datenparameter mit variabler Länge

Im Folgenden werden verschiedene bewährte Methoden zum Definieren der IDL-Attribute für Datenstrukturen mit variabler Größe, Methodenparameter und Felder beschrieben.

  • Verwenden Sie frühe Korrelation. Es ist in der Regel besser, den Parameter der variablen Größe oder des Felds so zu definieren, dass er unmittelbar nach dem steuernden integralen Typ auftritt.

    Zum Beispiel

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

    ist besser als

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

    wobei earlyCorr den Größenparameter unmittelbar vor dem Datenparameter mit variabler Länge deklariert, und lateCorr den Größenparameter danach deklariert. Die Verwendung frühzeitiger Korrespondenz verbessert die Leistung insgesamt, insbesondere in Fällen, in denen die Methode häufig aufgerufen wird.

  • Bei Parametern, die mit dem [out, size_is] Attribut-Tupel gekennzeichnet sind und die Datenlänge auf der Clientseite bekannt ist oder wenn der Client über eine angemessene obere Grenze verfügt, sollte die Methodendefinition in Bezug auf die Parameterzuordnung und -sequenz ähnlich sein:

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

    In diesem Fall stellt der Client einen Puffer mit fester Größe für pArrbereit, sodass der serverseitige RPC-Dienst einen puffer mit einer angemessenen Größe mit einem guten Maß an Sicherheit zuweist. Beachten Sie, dass im Beispiel die Daten vom Server empfangen werden ([]). Die Definition ist ähnlich für daten, die an den Server übergeben werden ([in]).

  • In Situationen, in denen die serverseitige Komponente einer RPC-Anwendung die Datenlänge entscheidet, sollte die Methodendefinition wie folgt aussehen:

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

    RANGED_LONG ist ein Typ, der sowohl für den Client als auch für Server-Stubs definiert ist, und eine angegebene Größe, die der Client ordnungsgemäß antizipieren kann. Im Beispiel übergibt der Client ppArr- als NULL-, und die RPC-Serveranwendungskomponente weist die richtige Speichermenge zu. Bei Rückgabe weist der RPC-Dienst auf clientseitiger Seite den Speicher für die zurückgegebenen Daten zu.

  • Wenn der Client eine Teilmenge eines großen konformen Arrays an den Server senden möchte, kann die Anwendung die Größe der Teilmenge angeben, wie im folgenden Beispiel gezeigt:

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

    Auf diese Weise überträgt RPC nur lLength Elemente des Arrays über das Netzwerk. Diese Definition erzwingt jedoch, dass der RPC-Dienst Arbeitsspeicher lSize- auf serverseitiger Seite zuweist.

  • Wenn die Clientanwendungskomponente die maximale Größe eines Arrays bestimmt, das der Server zurückgeben kann, aber dem Server die Übertragung einer Teilmenge dieses Arrays zulässt, kann die Anwendung ein solches Verhalten angeben, indem die IDL ähnlich dem folgenden Beispiel definiert wird:

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

    Die Clientanwendungskomponente gibt die maximale Größe des Arrays an, und der Server gibt an, wie viele Elemente sie an den Client übertragen.

  • Wenn die Serveranwendungskomponente eine Zeichenfolge an die Clientanwendungskomponente zurückgeben muss und der Client die maximale Größe kennt, die vom Server zurückgegeben werden soll, kann die Anwendung einen konformen Zeichenfolgentyp verwenden, wie im folgenden Beispiel gezeigt:

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • Wenn die Clientanwendungskomponente die Größe der Zeichenfolge nicht steuern soll, kann der RPC-Dienst den Speicher zuweisen, wie im folgenden Beispiel gezeigt:

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    Die Clientanwendungskomponente muss ppStr- auf NULL- beim Aufrufen der RPC-Methode festlegen.