2.2.2 Custom-Marshaled Data Types

This section specifies data structures that are custom-marshaled, including those that contain "_INFO" in their names. All custom-marshaled INFO data structures MUST be completely ignored on input, and validation of their contents MUST NOT take place.

Custom-marshaled INFO data structures consist of single Fixed_Portion blocks for methods accepting or returning a single structure, and arrays of one or more Fixed_Portion blocks for methods accepting or returning an array of structures. The size of the Fixed_Portion data is the size of a single Fixed_Portion block multiplied by the number of Fixed_Portion blocks returned. The Fixed_Portion data is followed by a single Variable_Data block, which contains variable-length fields. The size of the Variable_Data block is the size specified by the caller in the cbBuf parameter of the call minus the size of the Fixed_Portion data.

For each field in a 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 Fixed_Portion block in which that offset is defined.

This generic structure of custom-marshaled INFO data structures is represented by the following diagram.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Fixed_Portion (variable)

...

Variable_Data (variable)

...

Fixed_Portion (variable): An array of one or more Fixed_Portion blocks, each consisting of one or more fixed-length fields. The specific structure of the Fixed_Portion block is defined for each INFO structure.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Fixed_Portion_Block_1 (variable)

...

Fixed_Portion_Block_2 (variable)

...

Fixed_Portion_Block_1 (variable): Fixed_Portion block 1.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Fixed_Portion_Block_1_Field_1

Fixed_Portion_Block_1_Field_2

Fixed_Portion_Block_1_Field_1 (4 bytes): Fixed-length field 1 of Fixed_Portion block 1. Although the length of this field is shown as 4 bytes, its actual length is indeterminate in this generic structure.

Fixed_Portion_Block_1_Field_2 (4 bytes): Fixed-length field 2 of Fixed_Portion block 1. This field contains an offset to Variable_Data_Field_1, which is relative to the start of Fixed_Portion block 1.

Fixed_Portion_Block_2 (variable): Optional Fixed_Portion block 2.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Fixed_Portion_Block_2_Field_1

Fixed_Portion_Block_2_Field_2

Fixed_Portion_Block_2_Field_1 (4 bytes): Fixed-length field 1 of Fixed_Portion block 2. Although the length of this field is shown as 4 bytes, its actual length is indeterminate in this generic structure.

Fixed_Portion_Block_2_Field_2 (4 bytes): Fixed-length field 2 of Fixed_Portion block 2. This field contains an offset to Variable_Data_Field_2, which is relative to the start of Fixed_Portion block 2.

Variable_Data (variable): A data block of variable length. Because the data is not necessarily aligned on 16-bit boundaries, it is specified as an array of bytes of arbitrary length; however, data fields in the Variable_Data block MUST be aligned on natural boundaries matching their data type. That is, WCHAR fields MUST be aligned on 2-byte boundaries, DWORD fields MUST be aligned on 4-byte boundaries, and so on.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Variable_Data_Field_1 (variable)

...

Variable_Data_Field_2 (variable)

...

Variable_Data_Field_1 (variable): Variable-length field 1 of the Variable_Data block.

Variable_Data_Field_2 (variable): Variable-length field 2 of the Variable_Data block.

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

  • The start of the Fixed_Portion block MUST be 32-bit aligned.

  • The order of fields in the Fixed_Portion block is defined by the specific INFO 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, filling the Variable_Data block from the end toward the beginning, such that, if the cbBuf parameter specified by the caller is larger than the sum of all Fixed_Portion blocks and all Variable_Data fields, the unused space in the [out] buffer receiving the custom-marshaled INFO structure forms a gap between the end of the last Fixed_Portion block and the beginning of the first Variable_Data field; however, client-side unmarshaling code that processes a custom-marshaled INFO structure SHOULD be prepared to correctly handle data that does not fill the Variable_Data block from the end toward the beginning, or is not tightly packed and includes unused space in arbitrary positions of the Variable_Data block.<92>