Descritores de correlação

Um descritor de correlação é uma cadeia de caracteres de formato que descreve uma expressão com base em um argumento relacionado a outro argumento. Um descritor de correlação é necessário para lidar com semântica relacionada a atributos como [size_is()], [length_is()], [switch_is()] e [iid_is()]. Os descritores de correlação são usados com matrizes, ponteiros dimensionados, uniões e ponteiros de interface. O valor da expressão eventual pode ser um tamanho, um comprimento, um discriminador de união ou um ponteiro para um IID, respectivamente. Em termos de cadeias de caracteres de formato, os descritores de correlação são usados com matrizes, uniões e ponteiros de interface. Um ponteiro de tamanho é descrito em cadeias de caracteres de formato como um ponteiro para uma matriz.

Há duas rotinas executando cálculos básicos de expressão: NdrpComputeConformance é usado para tamanhos, comutadores e IID* enquanto NdrpComputeVariance é usado para comprimentos. Há também uma única rotina para executar uma validação de valor de correlação para a funcionalidade de negação de ataque.

Os descritores de correlação foram projetados para dar suporte apenas a expressões muito limitadas. Para situações complicadas, o compilador gera uma rotina de avaliação de expressão a ser chamada pelo mecanismo quando necessário.

Um descritor de correlação tem o seguinte formato:

correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]

O descritor de correlação correlation_type<1> consiste em dois nibbles: os 4 bits superiores descrevem onde a expressão pode ser encontrada e os 4 bits inferiores descrevem o tipo do valor da expressão.

A mordisca superior pode ter um destes cinco valores:

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

Um caso normal de conformidade, como o descrito em um campo de uma estrutura.

FC_POINTER_CONFORMANCE

Para ponteiros atribuídos (size_is(), length_is()) que são campos em uma estrutura. Isso afeta a maneira como o ponteiro de memória base é definido.

FC_TOP_LEVEL_CONFORMANCE

Para conformidade de nível superior descrito por outro parâmetro.

FC_TOP_LEVEL_MULTID_CONFORMANCE

Para conformidade de nível superior de uma matriz multidimensional descrita por outro parâmetro.

Observação

Matrizes e ponteiros de tamanho multidimensional disparam uma opção para –Oicf.

 

FC_CONSTANT_CONFORMANCE

Para um valor constante. O compilador precalcula o valor de uma expressão constante fornecida pelo usuário. Quando esse for o caso, os 3 bytes subsequentes na descrição de conformidade contêm os 3 bytes inferiores de um longo que descreve o tamanho da conformidade. Nenhuma computação adicional é necessária.

A mordisca inferior fornece o tipo do valor que precisa ser extraído da memória:

FC_LONG | FC_ULONG | 
FC_SHORT | FC_USHORT | 
FC_SMALL | FC_USMALL | 
FC_HYPER

Observação

Não há suporte para expressões de 64 bits. FC_HYPER é usado apenas para iid_is() em plataformas de 64 bits para extrair o valor do ponteiro para IID*.

O compilador define a mordisca de tipo como zero para os seguintes casos: expressão constante mencionada acima e quando a rotina de expressão de avaliação precisa ser chamada, por exemplo, quando FC_CONSTANT_CONFORMANCE e FC_CALLBACK são usados.

 

O campo size_is_op<1> permite que uma das seguintes operações seja aplicada à variável de conformidade:

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

A constante FC_DEREFERENCE é usada para correlação sendo um ponto, como para [size_is(*pL)]. Os operadores aritméticos usam apenas a constante indicada. A constante FC_CALLBACK indica que uma rotina de avaliação de expressão precisa ser chamada.

O campo deslocamento<2> normalmente é um deslocamento de memória relativa para a variável de argumento de expressão. Também pode ser um índice de avaliação de expressão–rotina. Conforme mencionado anteriormente neste documento, para expressões constantes, ele faz parte do valor real da expressão final.

A interpretação do campo deslocamento<2> como deslocamento de memória depende da complexidade da expressão, do local da variável de expressão e, no caso de uma matriz, se a matriz é realmente um ponteiro atribuído.

Se a matriz for um ponteiro atribuído e a variável de conformidade for um campo em uma estrutura, o campo de deslocamento conterá o deslocamento do início da estrutura para o campo que descreve a conformidade. Se a matriz não for um ponteiro atribuído e a variável de conformidade for um campo em uma estrutura, o campo de deslocamento conterá o deslocamento do final da parte não conformante da estrutura para o campo que descreve a conformidade. Normalmente, a matriz de conformidade está no final da estrutura.

Para conformidade de nível superior, o campo de deslocamento contém o deslocamento do local do primeiro parâmetro do stub na pilha para o parâmetro que descreve a conformidade. Isso não é usado no modo –Os . Há outras exceções à interpretação do campo de deslocamento; essas exceções são descritas na descrição desses tipos.

Quando o deslocamento<2> é usado com FC_CALLBACK, ele contém um índice na tabela de rotina de avaliação de expressão gerada pelo compilador. A mensagem stub é passada para a rotina de avaliação, que calcula o valor de conformidade e a atribui ao campo MaxCount da mensagem stub.

O campo robust_flags<2> foi adicionado para o Windows 2000 dar suporte a /robust, como o recurso negação de ataques. Os seguintes sinalizadores são definidos no primeiro byte:

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;

O sinalizador Early indica correlação precoce versus tardia. Uma correlação inicial é quando o argumento expression precede o argumento descrito, por exemplo, um argumento size é antes de um argumento de ponteiro dimensionado. Uma correlação tardia é quando o argumento expression vem após o argumento relacionado. O mecanismo executa a validação de valores de correlação iniciais imediatamente, os valores de correlação tardia são armazenados para verificação após a conclusão da unmarshaling.

O sinalizador Split indica uma divisão assíncrona entre os argumentos [in] e [out]. Por exemplo, um argumento de tamanho pode ser [in] enquanto o ponteiro dimensionado pode ser [out]. No contexto assíncrono do DCOM, esses argumentos estão em pilhas diferentes, portanto, o mecanismo deve estar ciente disso.

O sinalizador IsIidIs indica uma correlação iid_is(). A rotina NdrComputeConformance é complicada para obter um ponteiro para IID como um valor de expressão, mas a rotina de validação não pode comparar esses valores (seriam ponteiros) e, portanto, o sinalizador indica que os IIDs reais precisam ser comparados.

Descrição da variação e outros atributos de matriz

O formato do campo de descrição de variação é idêntico ao campo de descrição de conformidade. A diferença é que um campo de mensagem stub diferente é usado pelo mecanismo NDR como uma variável temporária. No caso da descrição da variação, é o comprimento que é avaliado e o campo correspondente é chamado ActualLength.

Com a variação, o deslocamento inicial normalmente é zero e o mecanismo é ajustado adequadamente. Se o atributo first_is() for aplicado a uma matriz variável de conformidade, um retorno de chamada para uma rotina de avaliação de expressão será forçado.