Parameter Descriptors

As mentioned previously, –Oi and –Oif style parameter descriptors exist.

The –Oi Parameter Descriptors

Fully interpreted stubs require additional information for each of the parameters in an RPC call. The parameter descriptions of a procedure follow immediately after the description of the procedure.

Simple –Oi

Parameter Descriptors

The format for the description of an [in] or return simple type parameter is:

FC_IN_PARAM_BASETYPE 
simple_type<1>

–or–

FC_RETURN_PARAM_BASETYPE 
simple_type<1>

Where simple_type<1> is the FC token indicating the simple type. The codes are as follows:

4e  FC_IN_PARAM_BASETYPE 
53  FC_RETURN_PARAM_BASETYPE

Other –Oi

Parameter Descriptors

The format for the description for all other parameter types is:

param_direction<1> 
stack_size<1> 
type_offset<2>

Where the param_direction<1> field for each of these descriptions must be one of those shown in the following table.

Hex Flag Meaning
4d FC_IN_PARAM An in parameter.
50 FC_IN_OUT_PARAM An in/out parameter.
51 FC_OUT_PARAM An out parameter.
52 FC_RETURN_PARAM A procedure return value.
4f FC_IN_PARAM_NO_FREE_INST An in xmit/rep as a parameter for which no freeing is made.

 

The stack_size<1> is the size of the parameter on the stack, expressed as the number of integers the parameter occupies on the stack.

Note

The –Oi mode is not supported on 64-bit platforms.

 

The type_offset<2> field is the offset in the type format string table, indicating the type descriptor for the argument.

The –Oif Parameter Descriptors

There are two possible formats for a parameter description, one for base types, another for all other types.

Base types:

PARAM_ATTRIBUTES<2> 
stack_offset<2> 
type_format_char<1> 
unused<1>

Other:

PARAM_ATTRIBUTES<2> 
stack_offset<2> 
type_offset<2>

In both stack_offset<2> indicates the offset on the virtual argument stack, in bytes. For base types, the argument type is given directly by the format character corresponding to the type. For other types, the type_offset<2> field gives the offset in the type format string table where the type descriptor for the argument is located.

The parameter attribute field is defined as follows:

typedef struct
  {
  unsigned short  MustSize            : 1;    // 0x0001
  unsigned short  MustFree            : 1;    // 0x0002
  unsigned short  IsPipe              : 1;    // 0x0004
  unsigned short  IsIn                : 1;    // 0x0008
  unsigned short  IsOut               : 1;    // 0x0010
  unsigned short  IsReturn            : 1;    // 0x0020
  unsigned short  IsBasetype          : 1;    // 0x0040
  unsigned short  IsByValue           : 1;    // 0x0080
  unsigned short  IsSimpleRef         : 1;    // 0x0100
  unsigned short  IsDontCallFreeInst  : 1;    // 0x0200
  unsigned short  SaveForAsyncFinish  : 1;    // 0x0400
  unsigned short  Unused              : 2;
  unsigned short  ServerAllocSize     : 3;    // 0xe000
  } PARAM_ATTRIBUTES, *PPARAM_ATTRIBUTES;
  • The MustSize bit is set only if the parameter must be sized.
  • The MustFree bit is set if the server must call the parameter's NdrFree* routine.
  • The IsSimpleRef bit is set for a parameter that is a reference pointer to anything other than another pointer, and which has no allocate attributes. For such a type, the parameter description's type_offset<> field, except for a reference pointer to a base type, provides the offset to the referent's type; the reference pointer is simply skipped.
  • The IsDontCallFreeInst bit is set for certain represent_as parameters whose free instance routines should not be called.
  • The ServerAllocSize bits are nonzero if the parameter is [out], [in], or [in,out] pointer to pointer, or pointer to enum16, and will be initialized on the server interpreter's stack, rather than using a call to I_RpcAllocate. If nonzero, this value is multiplied by 8 to get the number of bytes for the parameter. Note that doing so means at least 8 bytes are always allocated for a pointer.
  • The IsBasetype bit is set for simple types that are being marshaled by the main –Oif interpreter loop. In particular, a simple type with a range attribute on it is not flagged as a base type in order to force the range routine marshaling through dispatching using an FC_RANGE token.
  • The IsByValue bit is set for compound types being sent by value, but is not set for simple types, regardless of whether the argument is a pointer. The compound types for which it is set are structures, unions, transmit_as, represent_as, wire_marshal and SAFEARRAY. In general, the bit was introduced for the benefit of the main interpreter loop in the –Oicf interpreter, to ensure the nonsimple arguments (referred to as compound type arguments) are properly dereferenced. This bit was never used in previous versions of the interpreter.