Заголовок
Следующий заголовок представляет один из стилей заголовков, которые можно создать с помощью текущей версии MIDL. Для удобства представлен полный список полей заголовка.
( заголовок–Oif)
handle_type<1>
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>
stack_size<2>
[explicit_handle_description<>]
constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>
Расширения, начиная с Windows 2000: <8> для 32-разрядной версии <12> для 64-разрядной версии)
extension_version<1>
INTERPRETER_OPT_FLAGS2<1>
ClientCorrHint<2>
ServerCorrHint<2>
NotifyIndex<2>
[ FloatDoubleMask<2> ]
Extension_version<1> предоставляет размер раздела расширения в байтах. Это позволяет текущему обработчику NDR правильно переходить по разделу расширения, даже если раздел был получен из более поздней версии компилятора с большими полями, чем текущий модуль понимает.
INTERPRETER_OPT_FLAGS2 определяются следующим образом:
typedef struct
{
unsigned char HasNewCorrDesc : 1; // 0x01
unsigned char ClientCorrCheck : 1; // 0x02
unsigned char ServerCorrCheck : 1; // 0x04
unsigned char HasNotify : 1; // 0x08
unsigned char HasNotify2 : 1; // 0x10
unsigned char Unused : 3;
} INTERPRETER_OPT_FLAGS2, *PINTERPRETER_OPT_FLAGS2;
Элемент HasNewCorrDesc указывает, используются ли новые дескрипторы корреляции в строках формата, созданных компилятором. Новый дескриптор корреляции связан с функциональностью отказа в атаке. ClientCorrCheck и ServerCorrCheck задаются, если подпрограмма нуждается в проверке корреляции на указанной стороне.
Флаги HasNotify и HasNotify2 указывают, что подпрограмма использует функцию уведомления в соответствии с [уведомление] и атрибутами [notify_flag].
Элемент ClientCorrHint — это указание размера кэша на стороне клиента, а ServerCorrHint — это указание на стороне сервера. Если размер выходит как нулевой, следует использовать размер по умолчанию.
Элемент NotifyIndex является индексом подпрограммы уведомления, если он используется.
Элемент FloatDoubleMask устраняет проблему аргумента с плавающей запятой для 64-разрядной Ос Windows. Это поле создается только для 64-разрядных заглушки. Маска необходима для подпрограмм сборки, которые загружают и отправляют регистры из или в виртуальный стек для правильной обработки аргументов с плавающей запятой и регистров. Маска состоит из 2 битов на аргумент или, скорее, на регистр с плавающей запятой. Кодирование выглядит следующим образом: наименее значимые биты соответствуют первому регистру FP, следующие 2 бита соответствуют второму регистру и т. д.
Заметка
Для подпрограмм объектов первый аргумент заканчивается во втором регистре из-за первого указателя. Для каждого регистра значение битов, как показано в следующей таблице.
Биты | Значение |
---|---|
01 | Значение с плавающей запятой должно быть загружено в регистр. |
10 | Двойное значение должно быть загружено в регистр. |
00 и 11 являются недопустимыми значениями для битов.
В настоящее время существует восемь регистров FP в 64-разрядном процессоре Intel, поэтому маска может иметь только 16b наименьших битов. Размер маски был установлен в общей сложности 16 бит на основе маски C-компилятора, оставшейся без изменений.
Оптимизация заголовка для повышения производительности
Чтобы упростить код и повысить производительность, компилятор пытается создать заголовок фиксированного размера по возможности. В частности, для асинхронного DCOM используется следующий заголовок:
typedef struct _NDR_DCOM_OI2_PROC_HEADER
{
unsigned char HandleType; // The Oi header
INTERPRETER_FLAGS OldOiFlags; //
unsigned short RpcFlagsLow; //
unsigned short RpcFlagsHi; //
unsigned short ProcNum; //
unsigned short StackSize; //
// expl handle descr is never generated //
unsigned short ClientBufferSize; // The Oi2 header
unsigned short ServerBufferSize; //
INTERPRETER_OPT_FLAGS Oi2Flags; //
unsigned char NumberParams; //
} NDR_DCOM_OI2_PROC_HEADER, *PNDR_DCOM_OI2_PROC_HEADER;