Selettori
Fino a due parti nella descrizione della stringa di formato di un handle di indirizzi della routine. La prima parte è il campo handle_type<1> della descrizione di una routine, usato per indicare handle impliciti. Questa parte è sempre presente. La seconda parte è una descrizione dei parametri di qualsiasi handle esplicito nella procedura. Entrambe sono illustrate nelle sezioni seguenti, insieme a una discussione sul supporto aggiuntivo del compilatore MIDL della struttura descrittore Stub per gestire i problemi di associazione.
Se una procedura usa un handle implicito per l'associazione, il campo handle_type<1> della descrizione della procedura contiene uno dei tre valori non zero validi. Il supporto del compilatore MIDL per gli handle impliciti si trova nel campo IMPLICIT_HANDLE_INFO della struttura descrittore 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;
Se la procedura usa un handle automatico, il membro pAutoHandle contiene l'indirizzo della variabile di gestione automatica definita dallo stub.
Se la procedura usa un handle primitivo implicito, il membro pPrimitiveHandle contiene l'indirizzo della variabile di handle stub definita-primitiva.
Infine, se la procedura usa un handle generico implicito, il membro pGenericBindingInfo contiene l'indirizzo del puntatore alla struttura di GENERIC_BINDING_INFO corrispondente. La struttura dei dati MIDL_STUB_DESC contiene un puntatore a una raccolta di strutture GENERIC_BINDING_PAIR . La voce nella posizione zero di questa raccolta è riservata alle routine di associazione e senza associazione corrispondenti all'handle di associazione generico a cui fa riferimento pGenericBindingInfo in IMPLICIT_HANDLE_INFO. Il tipo di handle di associazione implicita è indicato nella stringa di formato.
Esistono tre possibili tipi di handle espliciti: contesto, generico e primitivo. Nel caso di un handle esplicito (o di un handle di contesto [out] solo, gestito nello stesso modo), le informazioni sull'handle di associazione vengono visualizzate come uno dei parametri della routine. Le tre possibili descrizioni sono le seguenti.
Primitiva
FC_BIND_PRIMITIVE, flag<1>, offset<2>.
Il flag<1> indica se l'handle viene passato da un puntatore.
L'offset 2> fornisce l'offset<dall'inizio dello stack all'handle primitivo.
Nota
Una descrizione di handle primitiva nella stringa di formato di tipo viene ridotta a una singola FC_IGNORE.
Generico
FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD
L'flag_and _size<1> ha la nibble di bandiera superiore e il nibble di dimensioni inferiori. Il flag indica se l'handle viene passato da un puntatore. Il campo dimensioni fornisce le dimensioni del tipo di handle definito dall'utente. Questa dimensione è limitata a 1, 2 o 4 byte su sistemi a 32 bit e 1, 2, 4 o 8 byte in sistemi a 64 bit.
Il campo offset 2> fornisce l'offset<dall'inizio dello stack del puntatore ai dati delle dimensioni specificate.
Il campo binding_routine_pair_index<1> fornisce l'indice nel campo aGenericBindingRoutinePairs del descrittore Stub ai puntatori di funzione di associazione esenza associazione per l'handle generico.
Nota
Una descrizione di handle generica nel formato di tipo è la descrizione solo del tipo di dati correlato.
Contesto
FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>
I flag<1> indicano come viene passato l'handle e quale tipo è. I flag validi vengono visualizzati nella tabella seguente.
Hex | Flag |
---|---|
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 |
I primi quattro flag sono sempre stati presenti, gli ultimi quattro sono stati aggiunti in Windows 2000.
Il campo offset 2> fornisce l'offset<dall'inizio dello stack all'handle di contesto.
Il context_rundown_routine_index<1> fornisce un indice nel campo apfnNdrRundownRoutines del descrittore Stub alla routine di rundown usata per questo handle di contesto. Il compilatore genera sempre un indice. Per le routine che non hanno una routine di rundown, si tratta di un indice in una posizione di tabella che contiene Null.
Per gli stub compilati in –Oi2, il param_num<1> fornisce il conteggio ordinale, a partire da zero, specificando quale handle di contesto si trova nella procedura specificata.
Per le versioni precedenti dell'interprete, il param_num<1> fornisce il numero di parametro dell'handle di contesto, a partire da zero, nella relativa procedura.
Nota
Una descrizione dell'handle di contesto nella stringa di formato di tipo non avrà l'offset<2> nella descrizione.
Come accennato in precedenza, l'intestazione –Oif si espande sull'intestazione –Oi . Per praticità, tutti i campi sono visualizzati qui:
(Intestazione precedente)
handle_type<1>
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>
stack_size<2>
[explicit_handle_description<>]
(Estensioni -Oif )
constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>
Il constant_client_buffer_size<2> fornisce le dimensioni del buffer di marshalling che potrebbero essere state pre-calcolate dal compilatore. Questa può essere solo una dimensione parziale, poiché il flag ClientMustSize attiva il ridimensionamento.
Il constant_server_buffer_size<2> fornisce le dimensioni del buffer di marshalling come precompilate dal compilatore. Questa può essere solo una dimensione parziale, poiché il flag ServerMustSize attiva il ridimensionamento.
La INTERPRETER_OPT_FLAGS è definita in 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;
- Il bit ServerMustSize è impostato se il server deve eseguire un passaggio di ridimensionamento del buffer.
- Il bit ClientMustSize è impostato se il client deve eseguire un passaggio di ridimensionamento del buffer.
- Il bit HasReturn è impostato se la procedura ha un valore restituito.
- Il bit HasPipes viene impostato se il pacchetto della pipe deve essere usato per supportare un argomento pipe.
- Il bit HasAsyncUuid è impostato se la procedura è una procedura DCOM asincrona.
- Il bit HasExtensions indica che vengono usate le estensioni di Windows 2000 e versioni successive.
- Il bit HasAsyncHandle indica una procedura RPC asincrona.
Il bit HasAsyncHandle è stato inizialmente usato per un'implementazione DCOM diversa del supporto asincrono e quindi non è stato possibile usare per il supporto asincrono dello stile corrente in DCOM. Il bit HasAsyncUuid indica attualmente questo.