Poignées
Autant de deux parties dans la description de chaîne de mise en forme d’un handle d’adresse de procédure. La première partie est le champ handle_type<1> de la description d’une procédure, utilisé pour indiquer des handles implicites. Cette partie est toujours présente. La deuxième partie est une description de paramètre de n’importe quel handle explicite dans la procédure. Les deux sont expliqués dans les sections suivantes, ainsi qu’une discussion sur la prise en charge supplémentaire du compilateur MIDL de la structure de descripteur Stub pour les problèmes de gestion de liaison.
Handles implicites
Si une procédure utilise un handle implicite pour la liaison, le champ handle_type<1> de la description de la procédure contient l’une des trois valeurs non nulles valides. La prise en charge du compilateur MIDL pour les handles implicites se trouve dans le champ IMPLICIT_HANDLE_INFO de la structure de descripteur Stub :
typedef (__RPC_FAR * GENERIC_BINDING_ROUTINE)();
typedef struct
{
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_BINDING_ROUTINE pfnUnbind;
} GENERIC_BINDING_ROUTINE_PAIR;
typedef struct __GENERIC_BINDING_INFO
{
void __RPC_FAR* pObj;
unsigned char Size;
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_BINDING_ROUTINE pfnUnbind;
} GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO;
union
{
handle_t* pAutoHandle;
handle_t* pPrimitiveHandle;
PGENERIC_BINDING_INFO pGenericBindingInfo;
} IMPLICIT_HANDLE_INFO;
Si la procédure utilise un handle automatique, le membre pAutoHandle contient l’adresse de la variable de handle automatique définie par stub.
Si la procédure utilise un handle primitif implicite, le membre pPrimitiveHandle contient l’adresse de la variable de handle de la primitive définie par stub.
Enfin, si la procédure utilise un handle générique implicite, le membre pGenericBindingInfo contient l’adresse du pointeur vers la structure de GENERIC_BINDING_INFO correspondante. La structure de données MIDL_STUB_DESC contient un pointeur vers une collection de structures GENERIC_BINDING_PAIR. L’entrée à la position zéro de cette collection est réservée aux de liaison et routines non liées correspondant au handle de liaison générique référencé par pGenericBindingInfo dans IMPLICIT_HANDLE_INFO. Le type de handle de liaison implicite est indiqué dans la chaîne de format.
Handles explicites
Il existe trois types de handle explicites possibles : le contexte, le générique et la primitive. Dans le cas d’un handle explicite (ou d’un handle de contexte [out] uniquement, qui est géré de la même façon), les informations de handle de liaison apparaissent comme l’un des paramètres de la procédure. Les trois descriptions possibles sont les suivantes.
Primitif
FC_BIND_PRIMITIVE, flag<1>, offset<2>.
L’indicateur<1> indique si le handle est passé par un pointeur.
Le décalage<2> fournit le décalage entre le début de la pile et le handle primitif.
Note
Une description de handle primitif dans la chaîne de format de type est réduite à une seule FC_IGNORE.
Générique
FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD
Le flag_and _size<1> a le nibble de l’indicateur supérieur et la taille inférieure. L’indicateur indique si le handle est passé par un pointeur. Le champ taille fournit la taille du type de handle générique défini par l’utilisateur. Cette taille est limitée à 1, 2 ou 4 octets sur les systèmes 32 bits et 1, 2, 4 ou 8 octets sur les systèmes 64 bits.
Le champ de décalage<2> fournit le décalage du début de la pile du pointeur vers les données de la taille donnée.
Le champ binding_routine_pair_index<1> donne l’index dans le champ aGenericBindingRoutinePairs du descripteur Stub à la liaison et pointeurs de fonction de routine non liés pour le handle générique.
Note
Une description de handle générique au format de type est la description du type de données associé uniquement.
Contexte
FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>
Les indicateurs<1> indiquent comment le handle est passé et quel type il s’agit. Les indicateurs valides sont indiqués dans le tableau suivant.
Sortilège | Drapeau |
---|---|
80 | HANDLE_PARAM_IS_VIA_PTR |
40 | HANDLE_PARAM_IS_IN |
20 | HANDLE_PARAM_IS_OUT |
21 | HANDLE_PARAM_IS_RETURN |
08 | NDR_STRICT_CONTEXT_HANDLE |
04 | NDR_CONTEXT_HANDLE_NO_SERIALIZE |
02 | NDR_CONTEXT_HANDLE_SERIALIZE |
01 | NDR_CONTEXT_HANDLE_CANNOT_BE_NULL |
Les quatre premiers indicateurs ont toujours été présents, les quatre derniers ont été ajoutés dans Windows 2000.
Le champ de décalage<2> fournit le décalage entre le début de la pile et le handle de contexte.
Le context_rundown_routine_index<1> fournit un index dans le champ apfnNdrRundownRoutines du descripteur Stub à la routine d’exécution utilisée pour ce handle de contexte. Le compilateur génère toujours un index. Pour les routines qui n’ont pas de routine d’exécution, il s’agit d’un index vers une position de table qui contient null.
Pour les stubs intégrés –Oi2, le param_num<1> fournit le nombre ordinal, en commençant à zéro, en spécifiant le handle de contexte dans la procédure donnée.
Pour les versions précédentes de l’interpréteur, la param_num<1> fournit le numéro de paramètre du handle de contexte, en commençant à zéro, dans sa procédure.
Note
Une description de handle de contexte dans la chaîne de format de type n’aura pas le décalage<2> dans la description.
Nouvel en-tête –Oif
Comme mentionné précédemment, l’en-tête –Oif se développe sur l’en-tête –Oi. Pour plus de commodité, tous les champs sont affichés ici :
(L’ancien en-tête)
handle_type<1>
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>
stack_size<2>
[explicit_handle_description<>]
(Extensions –Oif)
constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>
La constant_client_buffer_size<2> fournit la taille de la mémoire tampon de marshaling qui aurait pu être précalquée par le compilateur. Il ne peut s’agir que d’une taille partielle, car l’indicateur ClientMustSize déclenche le dimensionnement.
La constant_server_buffer_size<2> fournit la taille de la mémoire tampon de marshaling comme précomputée par le compilateur. Il ne peut s’agir que d’une taille partielle, car l’indicateur ServerMustSize déclenche le dimensionnement.
Les INTERPRETER_OPT_FLAGS sont définies dans Ndrtypes.h :
typedef struct
{
unsigned char ServerMustSize : 1; // 0x01
unsigned char ClientMustSize : 1; // 0x02
unsigned char HasReturn : 1; // 0x04
unsigned char HasPipes : 1; // 0x08
unsigned char Unused : 1;
unsigned char HasAsyncUuid : 1; // 0x20
unsigned char HasExtensions : 1; // 0x40
unsigned char HasAsyncHandle : 1; // 0x80
} INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS;
- Le bit ServerMustSize est défini si le serveur doit effectuer une passe de dimensionnement de mémoire tampon.
- Le bit ClientMustSize est défini si le client doit effectuer une passe de dimensionnement de mémoire tampon.
- Le bit HasReturn est défini si la procédure a une valeur de retour.
- Le bit HasPipes est défini si le package de canal doit être utilisé pour prendre en charge un argument de canal.
- Le bit HasAsyncUuid est défini si la procédure est une procédure DCOM asynchrone.
- Le bit HasExtensions indique que les extensions Windows 2000 et ultérieures sont utilisées.
- Le bit HasAsyncHandle indique une procédure RPC asynchrone.
Le bit HasAsyncHandle a été initialement utilisé pour une implémentation DCOM différente de la prise en charge asynchrone, et ne peut donc pas être utilisé pour la prise en charge asynchrone du style actuel dans DCOM. Le bit HasAsyncUuid indique actuellement cela.