Descripteurs de corrélation
Un descripteur de corrélation est une chaîne de format qui décrit une expression basée sur un argument lié à un autre argument. Un descripteur de corrélation est nécessaire pour gérer la sémantique liée aux attributs tels que [size_is()], [length_is()], [switch_is()] et [iid_is()]. Les descripteurs de corrélation sont utilisés avec des tableaux, des pointeurs dimensionnés, des unions et des pointeurs d’interface. La valeur d’expression éventuelle peut être une taille, une longueur, une discrimination d’union ou un pointeur vers un IID, respectivement. En termes de chaînes de format, les descripteurs de corrélation sont utilisés avec des tableaux, des unions et des pointeurs d’interface. Un pointeur dimensionné est décrit dans les chaînes de format comme pointeur vers un tableau.
Il existe deux routines effectuant des calculs d’expression de base : NdrpComputeConformance est utilisé pour les tailles, les commutateurs et IID* tandis que NdrpComputeVariance est utilisé pour les longueurs. Il existe également une seule routine pour effectuer une validation de valeur de corrélation pour les fonctionnalités de déni d’attaque.
Les descripteurs de corrélation ont été conçus pour prendre en charge uniquement des expressions très limitées. Pour les situations complexes, le compilateur génère une routine d’évaluation d’expression à appeler par le moteur si nécessaire.
Un descripteur de corrélation a le format suivant :
correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]
Le descripteur de corrélation correlation_type<1> se compose de deux nibbles : les 4 bits supérieurs décrivent où l’expression est trouvée et les 4 bits inférieurs décrivent le type de la valeur d’expression.
Le nibble supérieur peut avoir l’une des cinq valeurs suivantes :
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
-
Un cas normal de conformité, tel que celui décrit dans un champ d’une structure.
-
FC_POINTER_CONFORMANCE
-
Pour les pointeurs attributs (size_is(), length_is()) qui sont des champs dans une structure. Cela affecte la façon dont le pointeur de mémoire de base est défini.
-
FC_TOP_LEVEL_CONFORMANCE
-
Pour la conformité de niveau supérieur décrite par un autre paramètre.
-
FC_TOP_LEVEL_MULTID_CONFORMANCE
-
Pour la conformité de niveau supérieur d’un tableau multidimensionnel décrit par un autre paramètre.
Note
Les tableaux et pointeurs dimensionnés multidimensionnels déclenchent un commutateur vers –De l’Ociée.
-
FC_CONSTANT_CONFORMANCE
-
Pour une valeur constante. Le compilateur précalcule la valeur d’une expression constante fournie par l’utilisateur. Lorsqu’il s’agit du cas, les 3 octets suivants dans la description de la conformité contiennent les 3 octets inférieurs d’une longue décrivant la taille de conformité. Aucun autre calcul n’est nécessaire.
Le nibble inférieur donne le type de la valeur qui doit être extraite de la mémoire :
FC_LONG | FC_ULONG |
FC_SHORT | FC_USHORT |
FC_SMALL | FC_USMALL |
FC_HYPER
Note
Les expressions 64 bits ne sont pas prises en charge. FC_HYPER est utilisé uniquement pour iid_is() sur les plateformes 64 bits pour extraire la valeur du pointeur pour IID*.
Le compilateur définit la valeur zéro du type pour les cas suivants : expression constante mentionnée ci-dessus et quand la routine d’expression d’évaluation doit être appelée, par exemple, quand FC_CONSTANT_CONFORMANCE et FC_CALLBACK sont utilisées.
Le champ size_is_op<1> permet d’appliquer l’une des opérations suivantes à la variable de conformité :
FC_DEREFERENCE |
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 |
FC_CALLBACK
La constante FC_DEREFERENCE est utilisée pour la corrélation étant une pointe, comme pour [size_is(*pL)]. Les opérateurs arithmétiques utilisent simplement la constante indiquée. La constante FC_CALLBACK indique qu’une routine d’évaluation d’expression doit être appelée.
Le champ de décalage<2> est généralement un décalage de mémoire relatif à la variable d’argument d’expression. Il peut également s’agir d’un index de routine d’évaluation d’expression. Comme mentionné précédemment dans ce document, pour les expressions constantes, il fait partie de la valeur d’expression finale réelle.
L’interprétation du décalage<2> champ en tant que décalage de mémoire dépend de la complexité de l’expression, de l’emplacement de la variable d’expression et, dans le cas d’un tableau, si le tableau est réellement un pointeur attribué.
Si le tableau est un pointeur attribué et que la variable de conformité est un champ dans une structure, le champ offset contient le décalage du début de la structure au champ de conformité décrivant la conformité. Si le tableau n’est pas un pointeur attributé et que la variable de conformité est un champ dans une structure, le champ de décalage contient le décalage de la fin de la partie non conforme de la structure au champ décrivant la conformité. En règle générale, le tableau conforme se trouve à la fin de la structure.
Pour la conformité de niveau supérieur, le champ offset contient le décalage entre l’emplacement du premier paramètre du stub sur la pile et le paramètre qui décrit la conformité. Cela n’est pas utilisé en mode –Os. Il existe d’autres exceptions à l’interprétation du champ de décalage ; ces exceptions sont décrites dans la description de ces types.
Lorsque le décalage<2> est utilisé avec FC_CALLBACK, il contient un index dans la table de routine d’évaluation d’expression générée par le compilateur. Le message stub est transmis à la routine d’évaluation, qui calcule ensuite la valeur de conformité et l’affecte au champ MaxCount du message stub.
Le champ robust_flags<2> a été ajouté pour Windows 2000 pour prendre en charge /robuste, comme la fonctionnalité de déni d’attaques. Les indicateurs suivants sont définis sur le premier octet :
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;
L’indicateur précoce indique la corrélation précoce et tardive. Une corrélation précoce est lorsque l’argument d’expression précède l’argument décrit, par exemple un argument de taille est avant un argument de pointeur dimensionné. Une corrélation tardive est lorsque l’argument d’expression vient après l’argument associé. Le moteur effectue immédiatement la validation des valeurs de corrélation précoces, les valeurs de corrélation tardives sont stockées pour vérifier une fois la démarshalation effectuée.
L’indicateur Fractionner indique un fractionnement asynchrone entre les arguments [in] et [out]. Par exemple, un argument de taille peut être [in] tandis que le pointeur dimensionné peut être [out]. Dans le contexte asynchrone DCOM, ces arguments se trouvent sur différentes piles. Le moteur doit donc être conscient de cela.
L’indicateur IsIidIs indique une corrélation iid_is(). La routine NdrComputeConformance est astuce pour obtenir un pointeur vers IID comme valeur d’expression, mais la routine de validation ne peut pas comparer ces valeurs (elles seraient des pointeurs) et l’indicateur indique donc que les IID réels doivent être comparés.
Description de la variance et autres attributs de tableau
Le format du champ description de variance est identique au champ de description de conformité. La différence est qu’un champ de message stub différent est utilisé par le moteur de remise en tant que variable temporaire. Dans le cas d’une description de variance, il s’agit de la longueur évaluée et le champ correspondant est appelé ActualLength.
Avec variance, le décalage de départ est généralement égal à zéro et le moteur est réglé en conséquence. Si l’attribut first_is() est appliqué à un tableau variable conforme, un rappel à une routine d’évaluation d’expression est forcé.