Deskryptory korelacji
Deskryptor korelacji to ciąg formatu, który opisuje wyrażenie na podstawie jednego argumentu powiązanego z innym argumentem. Deskryptor korelacji jest wymagany do obsługi semantyki powiązanych z atrybutami takimi jak [size_is()], [length_is()], [switch_is()] i [iid_is()]. Deskryptory korelacji są używane z tablicami, wskaźnikami wielkości, związkami i wskaźnikami interfejsu. Ostateczna wartość wyrażenia może być odpowiednio rozmiarem, długością, dyskryminatorem unii lub wskaźnikiem identyfikatora IID. Jeśli chodzi o ciągi formatu, deskryptory korelacji są używane z tablicami, związkami i wskaźnikami interfejsu. Wskaźnik wielkości jest opisany w ciągach formatu jako wskaźnik do tablicy.
Istnieją dwie procedury wykonujące podstawowe obliczenia wyrażeń: NdrpComputeConformance jest używana dla rozmiarów, przełączników i identyfikatorów IID* podczas gdy parametr NdrpComputeVariance jest używany dla długości. Istnieje również jedna rutynowa weryfikacja wartości korelacji dla funkcji odmowy ataku.
Deskryptory korelacji zostały zaprojektowane tak, aby obsługiwały tylko bardzo ograniczone wyrażenia. W przypadku skomplikowanych sytuacji kompilator generuje procedurę obliczania wyrażeń wywoływaną przez aparat w razie potrzeby.
Deskryptor korelacji ma następujący format:
correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]
Deskryptor korelacji correlation_type<1> składa się z dwóch nibbles: górne 4 bity opisują, gdzie można znaleźć wyrażenie, a dolne 4 bity opisują typ wartości wyrażenia.
Górny nibble może mieć jedną z tych pięciu wartości:
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
-
Normalny przypadek zgodności, taki jak opisany w polu struktury.
-
FC_POINTER_CONFORMANCE
-
W przypadku wskaźników przypisanych (size_is()length_is()), które są polami w strukturze. Ma to wpływ na sposób ustawiania wskaźnika pamięci podstawowej.
-
FC_TOP_LEVEL_CONFORMANCE
-
W przypadku zgodności najwyższego poziomu opisanej przez inny parametr.
-
FC_TOP_LEVEL_MULTID_CONFORMANCE
-
W przypadku zgodności najwyższego poziomu tablicy wielowymiarowej opisanej przez inny parametr.
Nuta
Tablice o wymiarach wielowymiarowych i wskaźniki wyzwalają przełącznik do –Oicf.
-
FC_CONSTANT_CONFORMANCE
-
Dla wartości stałej. Kompilator oblicza wstępnie wartość z wyrażenia stałego dostarczonego przez użytkownika. W takim przypadku kolejne 3 bajty w opisie zgodności zawierają mniejsze 3 bajty długiej opisującej rozmiar zgodności. Nie jest wymagane żadne dalsze obliczenia.
Dolna nibble daje typ wartości, która musi zostać wyodrębniona z pamięci:
FC_LONG | FC_ULONG |
FC_SHORT | FC_USHORT |
FC_SMALL | FC_USMALL |
FC_HYPER
Nuta
Wyrażenia 64-bitowe nie są obsługiwane. FC_HYPER jest używana tylko dla iid_is() na platformach 64-bitowych w celu wyodrębnienia wartości wskaźnika dla identyfikatora IID*.
Kompilator ustawia typ nibble na zero dla następujących przypadków: wyrażenie stałe wymienione powyżej i gdy należy wywołać procedurę wyrażenia oceny, na przykład w przypadku użycia FC_CONSTANT_CONFORMANCE i FC_CALLBACK.
Pole size_is_op<1> umożliwia zastosowanie jednej z następujących operacji do zmiennej zgodności:
FC_DEREFERENCE |
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 |
FC_CALLBACK
Stała FC_DEREFERENCE jest używana do korelacji będącej wskaźnikiem, na przykład dla [size_is(*pL)]. Operatory arytmetyczne używają tylko wskazanej stałej. Stała FC_CALLBACK wskazuje, że należy wywołać procedurę obliczania wyrażenia.
Przesunięcie<2> pole jest zwykle względnym przesunięciem pamięci do zmiennej argumentu wyrażenia. Może to być również indeks warunkowy oceny wyrażeń. Jak wspomniano wcześniej w tym dokumencie, w przypadku wyrażeń stałych jest to część rzeczywistej, końcowej wartości wyrażenia.
Interpretacja pola przesunięcia<2> w miarę przesunięcia pamięci zależy od złożoności wyrażenia, lokalizacji zmiennej wyrażenia i w przypadku tablicy, czy tablica jest rzeczywiście wskaźnikiem przypisanym.
Jeśli tablica jest wskaźnikiem przypisanym, a zmienna zgodności jest polem w strukturze, pole przesunięcia zawiera przesunięcie od początku struktury do pola opisującego zgodność. Jeśli tablica nie jest wskaźnikiem przypisanym, a zmienna zgodności jest polem w strukturze, pole przesunięcia zawiera przesunięcie od końca niekonformantnej części struktury do pola opisującego zgodność. Zazwyczaj zgodna tablica znajduje się na końcu struktury.
W przypadku zgodności najwyższego poziomu pole przesunięcia zawiera przesunięcie z lokalizacji pierwszego parametru wycinku na stosie do parametru opisującego zgodność. Nie jest on używany w trybie –Os. Istnieją inne wyjątki od interpretacji pola przesunięcia; takie wyjątki są opisane w opisie tych typów.
Gdy<przesunięcia 2> jest używana z FC_CALLBACK, zawiera ona indeks w tabeli procedury obliczania wyrażeń wygenerowanej przez kompilator. Komunikat wycinkowy jest przekazywany do procedury oceny, która następnie oblicza wartość zgodności i przypisuje ją do pola MaxCount komunikatu wycinkowego.
Dodano pole robust_flags<2> dla systemu Windows 2000 w celu obsługi /robust, takich jak funkcja odmowy ataków. Następujące flagi są definiowane w pierwszym bajtzie:
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;
Flaga Wczesna wskazuje wczesną lub opóźnioną korelację. Wczesna korelacja polega na tym, że argument wyrażenia poprzedza opisany argument, na przykład argument rozmiaru jest przed argumentem wskaźnika wielkości. Późna korelacja polega na tym, że argument wyrażenia pojawia się po powiązanym argumencie. Aparat przeprowadza walidację wczesnych wartości korelacji od razu. Opóźnione wartości korelacji są przechowywane do sprawdzania po zakończeniu unmarshaling.
Flaga Podziału wskazuje asynchroniczny podział między argumenty [in] i [out]. Na przykład argument rozmiaru może być [in], a wskaźnik rozmiaru może być [out]. W kontekście asynchronicznego modelu DCOM te argumenty występują na różnych stosach, więc aparat musi wiedzieć o tym.
Flaga IsIidIs wskazuje korelację iid_is(). Procedury NdrComputeConformance są podstępne, aby uzyskać wskaźnik do identyfikatora IID jako wartość wyrażenia, ale procedury weryfikacji nie mogą porównać takich wartości (byłyby wskaźniki), a więc flaga wskazuje, że rzeczywiste identyfikatory IID muszą być porównywane.
Opis wariancji i inne atrybuty tablicy
Format pola opisu wariancji jest identyczny z polem opisu zgodności. Różnica polega na tym, że inne pole komunikatu wycinkowego jest używane przez aparat NDR jako zmienną tymczasową. W przypadku opisu wariancji jest to długość, która jest obliczana, a odpowiednie pole nosi nazwę ActualLength.
Z wariancją przesunięcie początkowe zwykle wynosi zero, a silnik jest odpowiednio dostrojony. Jeśli atrybut first_is() jest stosowany do zgodnej tablicy, wywołanie zwrotne do procedury obliczania wyrażeń jest wymuszane.