Popisovače korelace
Popisovač korelace je formátovací řetězec, který popisuje výraz založený na jednom argumentu souvisejícím s jiným argumentem. Pro zpracování sémantiky souvisejících s atributy, jako jsou [size_is()], [length_is()], [switch_is()] a [iid_is()]. Popisovače korelace se používají s poli, ukazateli velikosti, sjednoceními a ukazateli rozhraní. Hodnota konečného výrazu může být velikost, délka, sjednocení diskriminant nebo ukazatel na identifikátor IID. Z hlediska formátovacích řetězců se popisovače korelace používají s poli, sjednoceními a ukazateli rozhraní. Ukazatel velikosti je popsán ve formátovaných řetězcích jako ukazatel na pole.
Existují dvě rutiny provádějící základní výpočty výrazů: NdrpComputeConformance se používá pro velikosti, přepínače a IID* zatímco NdrpComputeVariance se používá pro délky. Existuje také jedna rutina, která provádí ověření hodnoty korelace pro funkci útoku do útoku do útoku.
Popisovače korelace byly navrženy tak, aby podporovaly pouze velmi omezené výrazy. V případě složitých situací kompilátor vygeneruje rutinu vyhodnocení výrazu, která se v případě potřeby volá modulem.
Popisovač korelace má následující formát:
correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]
Popisovač korelace correlation_type<1> se skládá ze dvou bradavek: horních 4 bitů popisuje, kde lze výraz najít, a nižší 4 bity popisují typ hodnoty výrazu.
Horní nibble může mít jednu z těchto pěti hodnot:
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
-
Normální případ shody, například popisovaný v poli struktury.
-
FC_POINTER_CONFORMANCE
-
Pro atributy ukazatele (size_is(), length_is()) jsou pole ve struktuře. To má vliv na způsob nastavení základního ukazatele paměti.
-
FC_TOP_LEVEL_CONFORMANCE
-
Pro shodu nejvyšší úrovně popsanou jiným parametrem.
-
FC_TOP_LEVEL_MULTID_CONFORMANCE
-
Pro shodu s vícerozměrným polem nejvyšší úrovně, které popisuje jiný parametr.
Poznámka
Pole a ukazatele s multidimenzionální velikostí aktivují přepínač na –Oicf.
-
FC_CONSTANT_CONFORMANCE
-
Pro konstantní hodnotu. Kompilátor předem přepočítá hodnotu z konstantního výrazu zadaného uživatelem. V takovém případě následující tři bajty v popisu shody obsahují nižší 3 bajty dlouhé popisující velikost shody. Nevyžaduje se žádné další výpočty.
Nižší nibble dává typ hodnoty, kterou je potřeba extrahovat z paměti:
FC_LONG | FC_ULONG |
FC_SHORT | FC_USHORT |
FC_SMALL | FC_USMALL |
FC_HYPER
Poznámka
64bitové výrazy nejsou podporovány. FC_HYPER se používá pouze pro iid_is() na 64bitových platformách k extrahování hodnoty ukazatele pro IID*.
Kompilátor nastaví typ nibble na nulu pro následující případy: konstantní výraz uvedený výše a při volání rutiny výrazu vyhodnocení, například při použití FC_CONSTANT_CONFORMANCE a FC_CALLBACK.
Pole size_is_op<1> umožňuje použít pro proměnnou shody jednu z následujících operací:
FC_DEREFERENCE |
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 |
FC_CALLBACK
Konstanta FC_DEREFERENCE se používá pro korelaci, například pro [size_is(*pL)]. Aritmetické operátory používají pouze uvedenou konstantu. Konstanta FC_CALLBACK označuje, že je potřeba volat rutinu vyhodnocení výrazu.
Posun<2> pole je obvykle relativní posun paměti na proměnnou argumentu výrazu. Může to být také index vyhodnocení výrazu – rutina. Jak jsme zmínili dříve v tomto dokumentu, pro konstantní výrazy je součástí skutečné hodnoty konečného výrazu.
Interpretace posunu<2> pole jako posun paměti závisí na složitosti výrazu, umístění proměnné výrazu a v případě pole, zda je pole skutečně atributem ukazatele.
Pokud je pole atributem ukazatele a proměnná shody je pole ve struktuře, pole posunu obsahuje posun od začátku struktury na pole popisující shodu. Pokud pole není atributem ukazatele a proměnná shody je pole ve struktuře, pole posunu obsahuje posun od konce nekonformní části struktury na pole popisující shodu. Odpovídající pole je obvykle na konci struktury.
V případě shody nejvyšší úrovně pole posunu obsahuje posun od umístění prvního parametru zástupných procedur v zásobníku na parametr, který popisuje shodu. Nepoužívá se v režimu –Os. Existují další výjimky interpretace posunového pole; tyto výjimky jsou popsány v popisu těchto typů.
Při posunu<2> se používá s FC_CALLBACK, obsahuje index v tabulce rutiny vyhodnocení výrazu generované kompilátorem. Zpráva s zástupnými procedurami se předá rutině vyhodnocení, která pak vypočítá hodnotu shody a přiřadí ji k poli MaxCount zprávy s zástupnými procedurami.
Pole robust_flags<2> bylo přidáno pro Systém Windows 2000 pro podporu /robustních, jako je například funkce odepření útoků. Na prvním bajtu jsou definovány následující příznaky:
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;
Příznak Early označuje časnou a pozdní korelaci. Počáteční korelace spočívá v tom, že argument výrazu předchází popsanému argumentu, například argument velikosti je před argumentem ukazatele velikosti. Pozdní korelace je, když je argument výrazu po souvisejícím argumentu. Modul provádí ověření počátečních korelačních hodnot okamžitě, hodnoty pozdní korelace se ukládají pro kontrolu po zrušení ohraničení.
Příznak Split označuje asynchronní rozdělení mezi argumenty [in] a [out]. Například argument velikosti může být [in] a ukazatel velikosti může být [out]. V asynchronním kontextu modelu DCOM dochází k těmto argumentům v různých zásobníkech, takže o tom musí modul vědět.
Příznak IsIidIs označuje korelaci iid_is(). Rutina NdrComputeConformance je zkomplikovaná k získání ukazatele na IID jako hodnotu výrazu, ale ověřovací rutina nemůže takové hodnoty porovnat (jsou ukazateli) a příznak označuje, že je potřeba porovnat skutečné identifikátory IID.
Popis odchylky a další atributy pole
Formát pole popisu odchylky je shodný s polem popisu shody. Rozdíl je v tom, že modul oznámení o nedoručení používá jiné pole zprávy s zástupnými procedurami jako dočasnou proměnnou. V případě popisu odchylky se jedná o délku, která se vyhodnotí, a odpovídající pole se nazývá ActualLength.
Při rozptylu je počáteční odsazení obvykle nula a motor je odpovídajícím způsobem vyladěn. Pokud je atribut first_is() použit u vyhovujícího pole, je vynuceno zpětné volání do rutiny vyhodnocení výrazu.