The Header

The following header represents one of the header styles that can be generated by the current version of MIDL. For convenience, the full list of header fields is provided here.

(–Oif header)

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>

Extensions starting with Windows 2000: <8> for 32-bit, <12> for 64-bit)

extension_version<1>
INTERPRETER_OPT_FLAGS2<1>
ClientCorrHint<2>
ServerCorrHint<2>
NotifyIndex<2>
[ FloatDoubleMask<2> ]

The extension_version<1> provides the size of the extension section, in bytes. Doing so makes it possible for the current NDR engine to step over the extension section correctly even if the section were to come from a later compiler version with more fields than the current engine understands.

The INTERPRETER_OPT_FLAGS2 are defined as follow:

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;

The HasNewCorrDesc member indicates whether new correlation descriptors are used in the format strings generated by the compiler. The new correlation descriptor is related to the denial-of-attack functionality. The ClientCorrCheck and ServerCorrCheck members are set when the routine needs the correlation check on the indicated side.

The HasNotify and HasNotify2 flags indicate that the routine uses the notify feature as defined by the [notify] and [notify_flag] attributes, respectively.

The ClientCorrCheck member is a cache size hint on the client side and ServerCorrCheck is a hint on the server side. When the size comes out as zero, a default size should be used.

The NotifyIndex element is an index to a notify routine, if one is used.

The FloatDoubleMask element addresses the issue of a floating point argument for 64-bit Windows. This field is generated only for 64-bit stubs. The mask is needed for the assembly routines that download/upload registers from/to the virtual stack to handle floating-point arguments and registers properly. The mask consist of 2 bits per argument, or rather per floating-point register. The coding is as follows: The least significant bits correspond to the first FP register, the next 2 bits correspond to the second register, and so on.

Note

For object routines, the first argument ends up in the second register due to this pointer being first. For each register the meaning of bits is as shown in the following table.

 

Bits Meaning
01 A float value should be loaded to the register.
10 A double value should be loaded to the register.

 

00 and 11 are invalid values for the bits.

Currently there are eight FP registers in an Intel Architecture 64-bit processor, hence the mask can have only 16b lowest bits set. The mask size has been set to a total of 16 bits based on the C-compiler mask remaining unchanged.

Header Streamlining for Performance

To simplify code and improve performance, the compiler attempts to generate a fixed size header whenever possible. In particular, the following header is used for async 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;