Pegas
Até duas partes na descrição da cadeia de caracteres de formato de um identificador de endereço de procedimento. A primeira parte é o campo handle_type<1> da descrição de um procedimento, usado para indicar alças implícitas. Esta parte está sempre presente. A segunda parte é uma descrição de parâmetros de qualquer identificador explícito no procedimento. Ambos são explicados nas seções a seguir, juntamente com uma discussão sobre o suporte adicional do compilador MIDL da estrutura do Descritor de Stub para problemas de identificador de vinculação.
Identificadores implícitos
Se um procedimento usa um identificador implícito para vinculação, o campo handle_type<1> da descrição do procedimento contém um dos três valores válidos diferentes de zero. O suporte do compilador MIDL para identificadores implícitos é encontrado no campo IMPLICIT_HANDLE_INFO da estrutura do descritor de 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 o procedimento usar um identificador automático, o membro do pAutoHandle conterá o endereço da variável de identificador automático definido pelo stub.
Se o procedimento usar um identificador primitivo implícito, o membro pPrimitiveHandle conterá o endereço da variável de identificador primitivo definido pelo stub.
Finalmente, se o procedimento usa um identificador genérico implícito, o membro pGenericBindingInfo mantém o endereço do ponteiro para a estrutura de GENERIC_BINDING_INFO correspondente. A estrutura de dados MIDL_STUB_DESC contém um ponteiro para uma coleção de estruturas GENERIC_BINDING_PAIR. A entrada na posição zero desta coleção é reservada para o bind e unbind rotinas correspondentes ao identificador de ligação genérico referenciado por pGenericBindingInfo em IMPLICIT_HANDLE_INFO. O tipo de identificador de ligação implícita é indicado na cadeia de caracteres de formato.
Alças explícitas
Existem três tipos possíveis de identificador explícito: contexto, genérico e primitivo. No caso de um identificador explícito (ou um identificador de contexto [out] apenas, que é tratado da mesma maneira), as informações do identificador de ligação aparecem como um dos parâmetros do procedimento. As três descrições possíveis são as seguintes.
Primitivo
FC_BIND_PRIMITIVE, flag<1>, offset<2>.
O sinalizador<1> indica se a alça é passada por um ponteiro.
O deslocamento<2> fornece o deslocamento do início da pilha para a alça primitiva.
Observação
Uma descrição de identificador primitivo na cadeia de caracteres de formato de tipo é reduzida a um único FC_IGNORE.
Genéricos
FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD
O flag_and _size<1> tem o nibble da bandeira superior e o nibble de tamanho inferior. O sinalizador indica se a alça é passada por um ponteiro. O campo tamanho fornece o tamanho do tipo de identificador genérico definido pelo usuário. Esse tamanho é limitado a 1, 2 ou 4 bytes em sistemas de 32 bits e 1, 2, 4 ou 8 bytes em sistemas de 64 bits.
O campo de deslocamento<2> fornece o deslocamento do início da pilha do ponteiro para os dados do tamanho fornecido.
O campo binding_routine_pair_index<1> fornece o índice no campo aGenericBindingRoutinePairs do Descritor de Stub para o ligar e desvincular ponteiros de função de rotina para o identificador genérico.
Observação
Uma descrição genérica do identificador no formato de tipo é apenas a descrição do tipo de dados relacionado.
Contexto
FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>
Os sinalizadores<1> indicam como a alça é passada e que tipo é. Os sinalizadores válidos são mostrados na tabela a seguir.
Hex | Bandeira |
---|---|
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 |
Os primeiros quatro sinalizadores sempre estiveram presentes, os últimos quatro foram adicionados no Windows 2000.
O campo de deslocamento<2> fornece o deslocamento do início da pilha para o identificador de contexto.
O> context_rundown_routine_index<1 fornece um índice no campo apfnNdrRundownRoutines do Descritor de Stub para a rotina de rundown usada para esse identificador de contexto. O compilador sempre gera um índice. Para rotinas que não têm uma rotina de rundown, este é um índice para uma posição de tabela que mantém null.
Para stubs construídos em –Oi2, o param_num<1> fornece a contagem ordinal, começando em zero, especificando qual identificador de contexto está no procedimento dado.
Para versões anteriores do interpretador, o param_num<1> fornece o número de parâmetro do identificador de contexto, começando em zero, em seu procedimento.
Observação
Uma descrição do identificador de contexto na cadeia de caracteres de formato de tipo não terá o deslocamento<2> na descrição.
O novo cabeçalho –OIF
Como mencionado anteriormente, o cabeçalho –Oif expande-se no cabeçalho –Oi. Por conveniência, todos os campos são mostrados aqui:
(O cabeçalho antigo)
handle_type<1>
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>
stack_size<2>
[explicit_handle_description<>]
(O –Oif extensões)
constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>
O> constant_client_buffer_size<2 fornece o tamanho do buffer de empacotamento que poderia ter sido pré-calculado pelo compilador. Isso pode ser apenas um tamanho parcial, pois o sinalizador ClientMustSize dispara o dimensionamento.
O constant_server_buffer_size<2> fornece o tamanho do buffer de marshaling conforme pré-calculado pelo compilador. Isso pode ser apenas um tamanho parcial, pois o sinalizador ServerMustSize dispara o dimensionamento.
Os INTERPRETER_OPT_FLAGS são definidos em 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;
- O bit ServerMustSize é definido se o servidor precisar executar uma passagem de dimensionamento de buffer.
- O bit ClientMustSize é definido se o cliente precisar executar um passo de dimensionamento de buffer.
- O bit HasReturn é definido se o procedimento tiver um valor de retorno.
- O bit HasPipes é definido se o pacote de pipe precisar ser usado para dar suporte a um argumento pipe.
- O bit HasAsyncUuid é definido se o procedimento for um procedimento DCOM assíncrono.
- O bit HasExtensions indica que o Windows 2000 e extensões posteriores são usados.
- O bit HasAsyncHandle indica um procedimento RPC assíncrono.
O bit HasAsyncHandle foi inicialmente usado para uma implementação DCOM diferente do suporte assíncrono e, portanto, não pôde ser usado para o suporte assíncrono de estilo atual no DCOM. O bit HasAsyncUuid atualmente indica isso.