2.2.1 Common Custom-Marshaling Rules

A custom-marshaled data type is represented as a single Fixed_Portion block followed by a single Variable_Data block. For each field in the Variable_Data block, a corresponding offset value is specified in a field of the Fixed_Portion block. A Variable_Data field is located by adding that offset value to the address of the start of the Fixed_Portion block.

An array of custom-marshaled data types is represented as a sequence of Fixed_Portion blocks followed by a single Variable_Data block. For each field in the Variable_Data block, a corresponding offset value is specified in a field of a Fixed_Portion block. A Variable_Data field is located by adding that offset value to the address of the start of the first Fixed_Portion block.

The following rules apply to the fields in custom-marshaled data structures:

  • Each Fixed_Portion block MUST be aligned to an 8-byte boundary; and the padding bytes, when present, SHOULD be filled with values of zero.

  • Each Variable_Data block MUST be aligned to an 8-byte boundary; and the padding bytes, when present, SHOULD be filled with values of zero.

  • The order of fields in the Fixed_Portion block is defined by the specific structure layout.

  • Data fields in the Variable_Data block can appear in arbitrary order.

  • One or more offsets in Fixed_Portion blocks can locate the same field in the Variable_Data block; or there can be a one-to-one correspondence between offsets and Variable_Data fields.

  • The Variable_Data fields SHOULD be packed tightly in the Variable_Data block; however, code that processes a custom-marshaled structure MUST be prepared to correctly handle data that is not tightly packed and that includes unused space.

  • The Variable_Data block SHOULD be empty if no offset fields reference Variable_Data fields.

  • The offset values in the Fixed_Portion block, and all other fields in the Fixed_Portion and Variable_Data blocks greater than 1 byte in size are marshaled in little-endian byte order.

  • A NULL pointer field in the original structure is marshaled as an offset value of zero in the Fixed_Portion block, and the respective optional field in the Variable_Data block is not present unless specifically noted.

  • All enumeration fields are custom marshaled as 32-bit (DWORD ([MS-DTYP] section 2.2.9)) fields.

The following subsections describe the arrangement of the Fixed_Portion and Variable_Data blocks used when marshaling a data type or array of data types in a single byte-array buffer passed as an argument to a method call.