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.
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
|
3 |
|
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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
91
0
1
2
3
4
5
6
7
8
92
0
1
2
3
4
5
6
7
8
93
0
1Fixed_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
91
0
1
2
3
4
5
6
7
8
92
0
1
2
3
4
5
6
7
8
93
0
1Fixed_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
91
0
1
2
3
4
5
6
7
8
92
0
1
2
3
4
5
6
7
8
93
0
1Fixed_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
91
0
1
2
3
4
5
6
7
8
92
0
1
2
3
4
5
6
7
8
93
0
1Variable_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>