Korrelationsdeskriptoren
Ein Korrelationsdeskriptor ist eine Formatzeichenfolge, die einen Ausdruck basierend auf einem Argument beschreibt, das mit einem anderen Argument verknüpft ist. Ein Korrelationsdeskriptor ist für die Behandlung von Semantik im Zusammenhang mit Attributen wie [size_is()], [length_is()], [switch_is()] und [iid_is()] erforderlich. Korrelationsdeskriptoren werden mit Arrays, Größenzeigern, Unions und Schnittstellenzeigern verwendet. Der letztliche Ausdruckswert kann eine Größe, eine Länge, ein Union-Unterscheidungszeichen oder ein Zeiger auf eine IID sein. In Bezug auf Formatzeichenfolgen werden Korrelationsdeskriptoren mit Arrays, Unions und Schnittstellenzeigern verwendet. Ein Zeiger der Größe wird in Formatzeichenfolgen als Zeiger auf ein Array beschrieben.
Es gibt zwei Routinen, die grundlegende Ausdrücke berechnen: NdrpComputeConformance wird für Größen, Schalter und IID* verwendet, während NdrpComputeVariance für Längen verwendet wird. Es gibt auch eine einzelne Routine, um eine Korrelationswertüberprüfung für die Denial-of-Attack-Funktionalität durchzuführen.
Korrelationsdeskriptoren wurden entwickelt, um nur sehr begrenzte Ausdrücke zu unterstützen. In komplizierten Situationen generiert der Compiler eine Ausdrucksauswertungsroutine, die bei Bedarf von der Engine aufgerufen werden soll.
Ein Korrelationsdeskriptor hat das folgende Format:
correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]
Der Korrelationsdeskriptor correlation_type<1> besteht aus zwei Nibbles: Die oberen 4 Bits beschreiben, wo der Ausdruck gefunden werden kann, und die unteren 4 Bits beschreiben den Typ des Ausdruckswerts.
Das obere Nibble kann einen der folgenden fünf Werte aufweisen:
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
-
Ein normaler Konformitätsfall, z. B. der in einem Feld einer Struktur beschriebene.
-
FC_POINTER_CONFORMANCE
-
Für attributierte Zeiger (size_is()length_is()), die Felder in einer -Struktur sind. Dies wirkt sich auf die Art und Weise aus, wie der Basisspeicherzeiger festgelegt wird.
-
FC_TOP_LEVEL_CONFORMANCE
-
Für konformität auf oberster Ebene, die von einem anderen Parameter beschrieben wird.
-
FC_TOP_LEVEL_MULTID_CONFORMANCE
-
Zur Konformität eines mehrdimensionalen Arrays auf oberster Ebene, das von einem anderen Parameter beschrieben wird.
Hinweis
Arrays und Zeiger mit mehrdimensionaler Größe lösen einen Wechsel zu –Oicf aus.
-
FC_CONSTANT_CONFORMANCE
-
Für einen konstanten Wert. Der Compiler berechnet den Wert aus einem konstanten Ausdruck, der vom Benutzer bereitgestellt wird. Wenn dies der Fall ist, enthalten die nachfolgenden 3 Bytes in der Konformitätsbeschreibung die unteren 3 Byte einer langen, die die Konformitätsgröße beschreibt. Es ist keine weitere Berechnung erforderlich.
Das untere Nibble gibt den Typ des Werts an, der aus dem Arbeitsspeicher extrahiert werden muss:
FC_LONG | FC_ULONG |
FC_SHORT | FC_USHORT |
FC_SMALL | FC_USMALL |
FC_HYPER
Hinweis
64-Bit-Ausdrücke werden nicht unterstützt. FC_HYPER wird nur für iid_is() auf 64-Bit-Plattformen verwendet, um den Zeigerwert für IID* zu extrahieren.
Der Compiler legt den Typ nibble für die folgenden Fälle auf Null fest: konstanter Ausdruck, der oben erwähnt wurde und wenn die Auswertungsausdrucksroutine aufgerufen werden muss, z. B. wenn FC_CONSTANT_CONFORMANCE und FC_CALLBACK verwendet werden.
Im Feld size_is_op<1> kann eine der folgenden Vorgänge auf die Konformitätsvariable angewendet werden:
FC_DEREFERENCE |
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 |
FC_CALLBACK
Die FC_DEREFERENCE-Konstante wird für Korrelation als Zeiger verwendet, z. B. für [size_is(*pL)]. Arithmetische Operatoren verwenden nur die angegebene Konstante. Die FC_CALLBACK-Konstante gibt an, dass eine Ausdrucksauswertungsroutine aufgerufen werden muss.
Das Feld offset<2> ist in der Regel ein relativer Speicheroffset zur Ausdrucksargumentvariablen. Es kann sich auch um einen Ausdrucksauswertungs-Routineindex handeln. Wie bereits in diesem Dokument erwähnt, ist dies bei konstanten Ausdrücken ein Teil des tatsächlichen, endgültigen Ausdruckswerts.
Die Interpretation des Offset-2-Felds<> als Speicheroffset hängt von der Komplexität des Ausdrucks, der Position der Ausdrucksvariablen und im Fall eines Arrays davon ab, ob das Array tatsächlich ein attributiertes Zeiger ist.
Wenn es sich bei dem Array um einen attributierten Zeiger handelt und die Konformitätsvariable ein Feld in einer Struktur ist, enthält das Offsetfeld den Offset vom Anfang der Struktur bis zum konformitätsbeschreibenden Feld. Wenn das Array kein attributiertes Zeiger ist und die Konformitätsvariable ein Feld in einer Struktur ist, enthält das Offsetfeld den Offset vom Ende des ungleichkonformanten Teils der Struktur zum konformitätsbeschreibenden Feld. In der Regel befindet sich das konforme Array am Ende der -Struktur.
Für die Konformität auf oberster Ebene enthält das Offsetfeld den Offset von der Position des ersten Stubparameters im Stapel zu dem Parameter, der die Konformität beschreibt. Dies wird nicht im -Os-Modus verwendet. Es gibt weitere Ausnahmen bei der Interpretation des Offsetfelds; diese Ausnahmen werden in der Beschreibung dieser Typen beschrieben.
Wenn Offset<2> mit FC_CALLBACK verwendet wird, enthält es einen Index in der vom Compiler generierten Routinetabelle für die Ausdrucksauswertung. Die Stubmeldung wird an die Auswertungsroutine übergeben, die dann den Konformitätswert berechnet und dem Feld MaxCount der Stubnachricht zuweist.
Das Feld robust_flags<2> wurde für Windows 2000 hinzugefügt, um /robust zu unterstützen, z. B. das Feature "Denial-of-Attacks". Die folgenden Flags werden für das erste Byte definiert:
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;
Das Flag Early gibt eine frühe und eine späte Korrelation an. Eine frühe Korrelation ist, wenn das Ausdrucksargument dem beschriebenen Argument vorangestellt wird, z. B. ein Größenargument vor einem Größenzeigerargument. Eine späte Korrelation ist, wenn das Ausdrucksargument nach dem verknüpften Argument kommt. Die Engine führt sofort die Validierung von frühen Korrelationswerten durch. Die Werte für die späte Korrelation werden zur Überprüfung gespeichert, nachdem die Entmarsung abgeschlossen ist.
Das Split-Flag gibt eine asynchrone Aufteilung zwischen den Argumenten [in] und [out] an. Beispielsweise kann ein Größenargument [in] sein, während der Zeiger [out] lautet. Im asynchronen DCOM-Kontext befinden sich diese Argumente in verschiedenen Stapeln, sodass die Engine dies beachten muss.
Das IsIidIs-Flag gibt eine iid_is() -Korrelation an. Die NdrComputeConformance-Routine wird getrickst, um einen Zeiger auf IID als Ausdruckswert zu erhalten, aber die Validierungsroutine kann solche Werte nicht vergleichen (sie wären Zeiger), sodass das Flag angibt, dass die tatsächlichen IIDs verglichen werden müssen.
Varianzbeschreibung und andere Arrayattribute
Das Format des Varianzbeschreibungsfelds ist identisch mit dem Konformitätsbeschreibungsfeld. Der Unterschied besteht darin, dass ein anderes Stubnachrichtenfeld von der NDR-Engine als temporäre Variable verwendet wird. Bei der Varianzbeschreibung wird die Länge ausgewertet, und das entsprechende Feld heißt ActualLength.
Bei Varianz ist der Startoffset in der Regel null, und der Motor wird entsprechend optimiert. Wenn das first_is() -Attribut auf ein konformes array angewendet wird, wird ein Rückruf für eine Ausdrucksauswertungsroutine erzwungen.