3a7ac9e27043fd0e43130be1ecefd6f85492f318
2 * PROJECT: ReactOS Printing Stack Marshalling Functions
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Marshalling functions
5 * COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
8 #define WIN32_NO_STATUS
13 * @name MarshallDownStructure
15 * Prepare a structure for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
18 * Pointer to the structure to operate on.
21 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
22 * See the documentation on MARSHALLING_INFO for more information.
23 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
25 * @param cbStructureSize
26 * Size in bytes of the structure.
27 * This parameter is unused in my implementation.
30 * Unknown boolean value, set to TRUE.
33 * TRUE if the structure was successfully adjusted, FALSE otherwise.
36 MarshallDownStructure(PVOID pStructure
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
39 if (!pStructure
|| !pInfo
)
41 SetLastError(ERROR_INVALID_PARAMETER
);
45 // Loop until we reach an element with offset set to MAXDWORD.
46 while (pInfo
->dwOffset
!= MAXDWORD
)
48 PULONG_PTR pCurrentField
= (PULONG_PTR
)((PBYTE
)pStructure
+ pInfo
->dwOffset
);
50 if (pInfo
->bAdjustAddress
&& *pCurrentField
)
52 // Make a relative offset out of the absolute pointer address.
53 *pCurrentField
-= (ULONG_PTR
)pStructure
;
56 // Advance to the next field description.
64 * @name MarshallDownStructuresArray
66 * Prepare an array of structures for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
68 * @param pStructuresArray
69 * Pointer to the array of structures to operate on.
72 * Number of array elements.
75 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
76 * See the documentation on MARSHALLING_INFO for more information.
77 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
79 * @param cbStructureSize
80 * Size in bytes of each structure array element.
83 * Unknown boolean value, set to TRUE.
86 * TRUE if the array was successfully adjusted, FALSE otherwise.
89 MarshallDownStructuresArray(PVOID pStructuresArray
, DWORD cElements
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
91 PBYTE pCurrentElement
= pStructuresArray
;
93 // Call MarshallDownStructure on all array elements given by cElements of cbStructureSize.
96 if (!MarshallDownStructure(pCurrentElement
, pInfo
, cbStructureSize
, bSomeBoolean
))
99 // Advance to the next array element.
100 pCurrentElement
+= cbStructureSize
;
107 * @name MarshallUpStructure
109 * Unmarshall/deserialize a structure previuosly marshalled by MarshallDownStructure by replacing relative offsets in its fields
110 * by absolute pointer addresses again.
113 * Size in bytes of the memory allocated for both the structure and its data.
114 * The function will check if all relative offsets are within the bounds given by this size.
117 * Pointer to the structure to operate on.
120 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
121 * See the documentation on MARSHALLING_INFO for more information.
122 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
124 * @param cbStructureSize
125 * Size in bytes of the structure.
126 * This parameter is unused in my implementation.
128 * @param bSomeBoolean
129 * Unknown boolean value, set to TRUE.
132 * TRUE if the structure was successfully adjusted, FALSE otherwise.
135 MarshallUpStructure(DWORD cbSize
, PVOID pStructure
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
138 if (!pStructure
|| !pInfo
)
140 SetLastError(ERROR_INVALID_PARAMETER
);
144 // Loop until we reach an element with offset set to MAXDWORD.
145 while (pInfo
->dwOffset
!= MAXDWORD
)
147 PULONG_PTR pCurrentField
= (PULONG_PTR
)((PBYTE
)pStructure
+ pInfo
->dwOffset
);
149 if (pInfo
->bAdjustAddress
&& *pCurrentField
)
151 // Verify that the offset in the current field is within the bounds given by cbSize.
152 if (cbSize
<= *pCurrentField
)
154 SetLastError(ERROR_INVALID_DATA
);
158 // Make an absolute pointer address out of the relative offset.
159 *pCurrentField
+= (ULONG_PTR
)pStructure
;
162 // Advance to the next field description.
170 * @name MarshallUpStructuresArray
172 * Unmarshall/deserialize an array of structures previuosly marshalled by MarshallDownStructuresArray by replacing relative offsets
173 * in its fields by absolute pointer addresses again.
176 * Size in bytes of the memory allocated for the entire structure array and its data.
177 * The function will check if all relative offsets are within the bounds given by this size.
179 * @param pStructuresArray
180 * Pointer to the array of structures to operate on.
183 * Number of array elements.
186 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
187 * See the documentation on MARSHALLING_INFO for more information.
188 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
190 * @param cbStructureSize
191 * Size in bytes of each structure array element.
193 * @param bSomeBoolean
194 * Unknown boolean value, set to TRUE.
197 * TRUE if the array was successfully adjusted, FALSE otherwise.
200 MarshallUpStructuresArray(DWORD cbSize
, PVOID pStructuresArray
, DWORD cElements
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
202 PBYTE pCurrentElement
= pStructuresArray
;
204 // Call MarshallUpStructure on all array elements given by cElements of cbStructureSize.
207 if (!MarshallUpStructure(cbSize
, pCurrentElement
, pInfo
, cbStructureSize
, bSomeBoolean
))
210 // Advance to the next array element.
211 pCurrentElement
+= cbStructureSize
;