Condividi tramite


Descrittori di correlazione

Un descrittore di correlazione è una stringa di formato che descrive un'espressione in base a un argomento correlato a un altro argomento. È necessario un descrittore di correlazione per la gestione della semantica correlata agli attributi come [size_is()], [length_is()], [switch_is()] e [iid_is()]. I descrittori di correlazione vengono usati con matrici, puntatori di dimensioni, unioni e puntatori di interfaccia. Il valore dell'espressione finale può essere una dimensione, una lunghezza, una discriminazione dell'unione o un puntatore a un IID, rispettivamente. In termini di stringhe di formato, i descrittori di correlazione vengono usati con matrici, unioni e puntatori di interfaccia. Un puntatore di dimensioni viene descritto in stringhe di formato come puntatore a una matrice.

Esistono due routine che eseguono calcoli di espressione di base: NdrpComputeConformance viene usato per dimensioni, commutatori e IID* mentre NdrpComputeVariance viene usato per le lunghezze. Esiste anche una singola routine per eseguire una convalida del valore di correlazione per la funzionalità denial-of-attack.

I descrittori di correlazione sono stati progettati per supportare solo espressioni molto limitate. Per situazioni complesse, il compilatore genera una routine di valutazione delle espressioni da chiamare dal motore quando necessario.

Un descrittore di correlazione ha il formato seguente:

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

Il descrittore di correlazione correlation_type<1> è costituito da due nibbles: i 4 bit superiori descrivono dove è possibile trovare l'espressione e i 4 bit inferiori descrivono il tipo del valore dell'espressione.

Il nibble superiore può avere uno di questi cinque valori:

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

Un normale caso di conformità, ad esempio quello descritto in un campo di una struttura.

FC_POINTER_CONFORMANCE

Per i puntatori attributi (size_is(), length_is()) che sono campi in una struttura. Ciò influisce sul modo in cui viene impostato il puntatore alla memoria di base.

FC_TOP_LEVEL_CONFORMANCE

Per la conformità di primo livello descritta da un altro parametro.

FC_TOP_LEVEL_MULTID_CONFORMANCE

Per la conformità di primo livello di una matrice multidimensionale descritta da un altro parametro.

Nota

Matrici e puntatori di dimensioni multidimensionali attivano un commutatore a –Oicf.

 

FC_CONSTANT_CONFORMANCE

Per un valore costante. Il compilatore precalcula il valore da un'espressione costante fornita dall'utente. Quando si tratta del caso, i 3 byte successivi nella descrizione della conformità contengono i 3 byte inferiori di una lunga descrizione delle dimensioni della conformità. Non è necessario un ulteriore calcolo.

La nibble inferiore fornisce il tipo del valore che deve essere estratto dalla memoria:

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

Nota

Le espressioni a 64 bit non sono supportate. FC_HYPER viene usato solo per iid_is() su piattaforme a 64 bit per estrarre il valore del puntatore per IID*.

Il compilatore imposta il tipo nibble su zero per i casi seguenti: espressione costante menzionata in precedenza e quando è necessario chiamare la routine dell'espressione di valutazione, ad esempio quando vengono usati FC_CONSTANT_CONFORMANCE e FC_CALLBACK.

 

Il campo size_is_op<1> consente di applicare una delle operazioni seguenti alla variabile di conformità:

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

La costante FC_DEREFERENCE viene usata per la correlazione come puntatore, ad esempio per [size_is(*pL)]. Gli operatori aritmetici usano solo la costante indicata. La costante FC_CALLBACK indica che è necessario chiamare una routine di valutazione delle espressioni.

Il campo offset<2> è in genere un offset di memoria relativo alla variabile di argomento dell'espressione. Può anche essere un indice di valutazione delle espressioni- routine. Come accennato in precedenza in questo documento, per le espressioni costanti fa parte del valore effettivo dell'espressione finale.

L'interpretazione del campo offset 2> come offset<di memoria dipende dalla complessità dell'espressione, dalla posizione della variabile di espressione e, nel caso di una matrice, se la matrice è effettivamente un puntatore con attributi.

Se la matrice è un puntatore con attributi e la variabile di conformità è un campo in una struttura, il campo offset contiene l'offset dall'inizio della struttura al campo di descrizione della conformità. Se la matrice non è un puntatore con attributi e la variabile di conformità è un campo in una struttura, il campo offset contiene l'offset dalla fine della parte non conforme della struttura al campo di descrizione della conformità. In genere, la matrice conforme è alla fine della struttura.

Per la conformità di primo livello, il campo offset contiene l'offset dalla posizione del primo parametro dello stub nello stack al parametro che descrive la conformità. Questa operazione non viene usata in modalità -Os . Esistono altre eccezioni all'interpretazione del campo di offset; tali eccezioni sono descritte nella descrizione di tali tipi.

Quando l'offset<2> viene usato con FC_CALLBACK, contiene un indice nella tabella di routine di valutazione dell'espressione generata dal compilatore. Il messaggio stub viene passato alla routine di valutazione, che calcola quindi il valore di conformità e lo assegna al campo MaxCount del messaggio stub.

Il campo robust_flags<2> è stato aggiunto per Windows 2000 per supportare /robuste, ad esempio la funzionalità denial-of-attacks. I flag seguenti sono definiti nel primo 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;

Il flag Early indica la correlazione anticipata rispetto a tardiva. Una correlazione anticipata è quando l'argomento espressione precede l'argomento descritto, ad esempio un argomento di dimensioni è prima di un argomento puntatore di dimensioni. Una correlazione tardiva è quando l'argomento dell'espressione viene dopo l'argomento correlato. Il motore esegue la convalida dei valori di correlazione iniziali immediatamente, i valori di correlazione tardiva vengono archiviati per il controllo dopo l'annullamento delmarshaling.

Il flag Split indica una suddivisione asincrona tra gli argomenti [in] e [out]. Ad esempio, un argomento di dimensioni può essere [in] mentre il puntatore di dimensioni può essere [out]. Nel contesto asincrono DCOM, questi argomenti si trovano in stack diversi, pertanto il motore deve essere consapevole di questo.

Il flag IsIidIs indica una correlazione iid_is(). La routine NdrComputeConformance è trucco per ottenere un puntatore all'IID come valore di espressione, ma la routine di convalida non può confrontare tali valori (sarebbero puntatori) e quindi il flag indica che è necessario confrontare gli ID effettivi.

Descrizione della varianza e altri attributi di matrice

Il formato del campo di descrizione della varianza è identico al campo descrizione conformità. La differenza è che un campo di messaggio stub diverso viene usato dal motore NDR come variabile temporanea. Nel caso della descrizione della varianza, è la lunghezza valutata e il campo corrispondente è denominato ActualLength.

Con la varianza, l'offset iniziale è in genere zero e il motore viene ottimizzato di conseguenza. Se l'attributo first_is() viene applicato a una matrice diversa conforme, viene forzato un callback a una routine di valutazione delle espressioni.