Poignées

Deux parties dans la description de chaîne de format d’un handles 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 les handles implicites. Cette partie est toujours présente. La deuxième partie est une description de paramètre de tout handle explicite dans la procédure. Les deux sont expliquées 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 valides non nulles. 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 stub defined-auto handle.

Si la procédure utilise un handle primitif implicite, le membre pPrimitiveHandle contient l’adresse de la variable stub defined-primitive handle.

Enfin, si la procédure utilise un handle générique implicite, le membre pGenericBindingInfo contient l’adresse du pointeur vers la structure 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 routines bind et unbind 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 : contexte, générique et primitif. Dans le cas d’un handle explicite (ou d’un handle de contexte [out] uniquement, qui est géré de la même manière), les informations de handle de liaison apparaissent comme l’un des paramètres de la procédure. Les trois descriptions possibles sont les suivantes.

Primitives

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.

Notes

Une description de handle primitive 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 d’indicateur supérieur et le nibble de taille inférieure. L’indicateur indique si le handle est passé par un pointeur. Le champ taille fournit la taille du type de handle défini par l’utilisateur-générique. 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 décalage<2> fournit le décalage entre le début de la pile du pointeur et 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 aux pointeurs de la fonction de routine bind et unbind pour le handle générique.

Notes

Une description de handle générique au format de type est la description du type de données associé uniquement.

 

Context

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.

Hex Indicateur
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 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, l’param_num<1> fournit le nombre ordinal, en commençant à zéro, en spécifiant le contexte qui le gère dans la procédure donnée.

Pour les versions précédentes de l’interpréteur, le param_num<1> fournit le numéro de paramètre du handle de contexte, commençant à zéro, dans sa procédure.

Notes

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>

Le constant_client_buffer_size<2> fournit la taille de la mémoire tampon de marshaling qui aurait pu être calculée au préalable par le compilateur. Il peut s’agir d’une taille partielle, car l’indicateur ClientMustSize déclenche le dimensionnement.

Le constant_server_buffer_size<2> fournit la taille de la mémoire tampon de marshaling telle que précalculée par le compilateur. Il peut s’agir d’une taille partielle, car l’indicateur ServerMustSize déclenche le dimensionnement.

Les INTERPRETER_OPT_FLAGS sont définis 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 un passage de dimensionnement de la mémoire tampon.
  • Le bit ClientMustSize est défini si le client doit effectuer un passage de dimensionnement de la 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 par conséquent, il n’a pas pu être utilisé pour la prise en charge asynchrone de style actuel dans DCOM. Le bit HasAsyncUuid l’indique actuellement.