Дескрипторы корреляции

Дескриптор корреляции — это строка формата, описывающая выражение на основе одного аргумента, связанного с другим аргументом. Дескриптор корреляции необходим для обработки семантики, связанной с такими атрибутами, как [size_is()], [length_is()], [switch_is()] и [iid_is()]. Дескрипторы корреляции используются с массивами, указателями размера, объединениями и указателями интерфейса. Конечным значением выражения может быть размер, длина, дискриминант объединения или указатель на IID соответственно. С точки зрения строк формата дескрипторы корреляции используются с массивами, объединениями и указателями интерфейса. Указатель размера описывается в строке форматирования как указатель на массив.

Существуют две подпрограммы, выполняющие основные вычисления выражений: NdrpComputeConformance используется для размеров, переключателей и IID*, а NdrpComputeVariance — для длины. Существует также одна подпрограмма для выполнения проверки значения корреляции для функциональности типа "отказ в атаке".

Дескрипторы корреляции предназначены для поддержки только очень ограниченных выражений. В сложных ситуациях компилятор создает подпрограмму вычисления выражений, которая будет вызываться подсистемой при необходимости.

Дескриптор корреляции имеет следующий формат:

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

Дескриптор корреляции correlation_type<1> состоит из двух прерывов: верхние 4 бита описывают, где можно найти выражение, а нижние 4 бита — тип значения выражения.

Верхний перо может иметь одно из следующих пяти значений:

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

Нормальный случай соответствия, например описанный в поле структуры.

FC_POINTER_CONFORMANCE

Для указателей с атрибутами (size_is()length_is()), которые являются полями в структуре. Это влияет на способ установки указателя базовой памяти.

FC_TOP_LEVEL_CONFORMANCE

Для соответствия верхнего уровня, описанного другим параметром.

FC_TOP_LEVEL_MULTID_CONFORMANCE

Для соответствия верхнего уровня многомерного массива, описанного другим параметром.

Примечание

Массивы и указатели многомерного размера активируют переключение на –Oicf.

 

FC_CONSTANT_CONFORMANCE

Для константного значения. Компилятор предварительно вычисляет значение из константного выражения, предоставленного пользователем. В этом случае последующие 3 байта в описании соответствия содержат более низкие 3 байта длинного описания соответствия. Дальнейшие вычисления не требуются.

Нижний значок задает тип значения, которое необходимо извлечь из памяти:

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

Примечание

64-разрядные выражения не поддерживаются. FC_HYPER используется только для iid_is() на 64-разрядных платформах для извлечения значения указателя для IID*.

Компилятор задает тип nibble равным нулю в следующих случаях: константное выражение, упомянутое выше, и когда необходимо вызвать подпрограмму выражения вычисления, например при использовании FC_CONSTANT_CONFORMANCE и FC_CALLBACK.

 

Поле size_is_op<1> позволяет применить к переменной соответствия одну из следующих операций:

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

Константная FC_DEREFERENCE используется для корреляции в качестве указателя, например для [size_is(*pL)]. Арифметические операторы используют только указанную константу. Константой FC_CALLBACK указывает, что необходимо вызвать подпрограмму вычисления выражений.

Поле смещения<2> обычно является относительным смещением памяти к переменной аргумента выражения. Это также может быть индекс обычной оценки выражения. Как упоминалось ранее в этом документе, для константных выражений это часть фактического, конечного значения выражения.

Интерпретация поля смещения<2> как смещения памяти зависит от сложности выражения, расположения переменной выражения и, в случае массива, является ли массив фактически указателем с атрибутом.

Если массив является указателем с атрибутами, а переменная соответствия является полем в структуре, поле смещения содержит смещение от начала структуры к полю описания соответствия. Если массив не является указателем с атрибутами, а переменная соответствия является полем в структуре, поле смещения содержит смещение от конца несоответствующей части структуры к полю описания соответствия. Как правило, соответствующий массив находится в конце структуры.

Для соответствия верхнего уровня поле смещения содержит смещение от расположения первого параметра заглушки в стеке до параметра, описывающего соответствие. Этот параметр не используется в режиме –Os . Существуют и другие исключения из интерпретации поля смещения; такие исключения описаны в описании этих типов.

Если используется смещение<2> с FC_CALLBACK, оно содержит индекс в таблице подпрограмм вычисления выражений, созданной компилятором. Сообщение-заглушка передается в подпрограмму оценки, которая затем вычисляет значение соответствия и назначает его полю MaxCount сообщения-заглушки.

Поле robust_flags<2> было добавлено для Windows 2000 для поддержки /robust, например функции "отказ в атаках". В первом байте определяются следующие флаги:

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;

Флаг Ранний указывает раннюю и позднюю корреляцию. Ранняя корреляция — это когда аргумент выражения предшествует описанному аргументу, например аргумент size находится перед аргументом указателя размера. Поздняя корреляция — это когда аргумент выражения появляется после связанного аргумента. Подсистема выполняет проверку ранних значений корреляции сразу же, а поздние значения корреляции сохраняются для проверки после отмены размежевывания.

Флаг Split указывает на асинхронное разделение аргументов [in] и [out]. Например, аргумент size может иметь значение [in], а указатель размера — [out]. В асинхронном контексте DCOM эти аргументы могут находиться в разных стеках, поэтому обработчик должен знать об этом.

Флаг IsIidIs указывает на корреляцию iid_is(). Подпрограмма NdrComputeConformance используется для получения указателя на IID в качестве значения выражения, но подпрограмма проверки не может сравнивать такие значения (они будут указателями), поэтому флаг указывает на необходимость сравнения фактических идентификаторов IID.

Описание дисперсии и другие атрибуты массива

Формат поля описания дисперсии идентичен полю описания соответствия. Разница заключается в том, что в качестве временной переменной обработчик NDR использует другое поле сообщения-заглушки. В случае описания дисперсии вычисляется длина, а соответствующее поле называется ActualLength.

При дисперсии начальная смещение обычно равна нулю, и подсистема настраивается соответствующим образом. Если атрибут first_is() применяется к соответствующему переменному массиву, принудительный вызов подпрограммы вычисления выражений выполняется принудительно.