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
12 #include <marshalling/marshalling.h>
15 * @name MarshallDownStructure
17 * Prepare a structure for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
20 * Pointer to the structure to operate on.
23 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
24 * See the documentation on MARSHALLING_INFO for more information.
25 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
27 * @param cbStructureSize
28 * Size in bytes of the structure.
29 * This parameter is unused in my implementation.
32 * Unknown boolean value, set to TRUE.
35 * TRUE if the structure was successfully adjusted, FALSE otherwise.
38 MarshallDownStructure(PVOID pStructure
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
41 if (!pStructure
|| !pInfo
)
43 SetLastError(ERROR_INVALID_PARAMETER
);
47 // Loop until we reach an element with offset set to MAXDWORD.
48 while (pInfo
->dwOffset
!= MAXDWORD
)
50 PULONG_PTR pCurrentField
= (PULONG_PTR
)((PBYTE
)pStructure
+ pInfo
->dwOffset
);
52 if (pInfo
->bAdjustAddress
&& *pCurrentField
)
54 // Make a relative offset out of the absolute pointer address.
55 *pCurrentField
-= (ULONG_PTR
)pStructure
;
58 // Advance to the next field description.
66 * @name MarshallDownStructuresArray
68 * Prepare an array of structures for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
70 * @param pStructuresArray
71 * Pointer to the array of structures to operate on.
74 * Number of array elements.
77 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
78 * See the documentation on MARSHALLING_INFO for more information.
79 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
81 * @param cbStructureSize
82 * Size in bytes of each structure array element.
85 * Unknown boolean value, set to TRUE.
88 * TRUE if the array was successfully adjusted, FALSE otherwise.
91 MarshallDownStructuresArray(PVOID pStructuresArray
, DWORD cElements
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
93 PBYTE pCurrentElement
= pStructuresArray
;
95 // Call MarshallDownStructure on all array elements given by cElements of cbStructureSize.
98 if (!MarshallDownStructure(pCurrentElement
, pInfo
, cbStructureSize
, bSomeBoolean
))
101 // Advance to the next array element.
102 pCurrentElement
+= cbStructureSize
;
109 * @name MarshallUpStructure
111 * Unmarshall/deserialize a structure previuosly marshalled by MarshallDownStructure by replacing relative offsets in its fields
112 * by absolute pointer addresses again.
115 * Size in bytes of the memory allocated for both the structure and its data.
116 * The function will check if all relative offsets are within the bounds given by this size.
119 * Pointer to the structure to operate on.
122 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
123 * See the documentation on MARSHALLING_INFO for more information.
124 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
126 * @param cbStructureSize
127 * Size in bytes of the structure.
128 * This parameter is unused in my implementation.
130 * @param bSomeBoolean
131 * Unknown boolean value, set to TRUE.
134 * TRUE if the structure was successfully adjusted, FALSE otherwise.
137 MarshallUpStructure(DWORD cbSize
, PVOID pStructure
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
140 if (!pStructure
|| !pInfo
)
142 SetLastError(ERROR_INVALID_PARAMETER
);
146 // Loop until we reach an element with offset set to MAXDWORD.
147 while (pInfo
->dwOffset
!= MAXDWORD
)
149 PULONG_PTR pCurrentField
= (PULONG_PTR
)((PBYTE
)pStructure
+ pInfo
->dwOffset
);
151 if (pInfo
->bAdjustAddress
&& *pCurrentField
)
153 // Verify that the offset in the current field is within the bounds given by cbSize.
154 if (cbSize
<= *pCurrentField
)
156 SetLastError(ERROR_INVALID_DATA
);
160 // Make an absolute pointer address out of the relative offset.
161 *pCurrentField
+= (ULONG_PTR
)pStructure
;
164 // Advance to the next field description.
172 * @name MarshallUpStructuresArray
174 * Unmarshall/deserialize an array of structures previuosly marshalled by MarshallDownStructuresArray by replacing relative offsets
175 * in its fields by absolute pointer addresses again.
178 * Size in bytes of the memory allocated for the entire structure array and its data.
179 * The function will check if all relative offsets are within the bounds given by this size.
181 * @param pStructuresArray
182 * Pointer to the array of structures to operate on.
185 * Number of array elements.
188 * Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
189 * See the documentation on MARSHALLING_INFO for more information.
190 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
192 * @param cbStructureSize
193 * Size in bytes of each structure array element.
195 * @param bSomeBoolean
196 * Unknown boolean value, set to TRUE.
199 * TRUE if the array was successfully adjusted, FALSE otherwise.
202 MarshallUpStructuresArray(DWORD cbSize
, PVOID pStructuresArray
, DWORD cElements
, const MARSHALLING_INFO
* pInfo
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
204 PBYTE pCurrentElement
= pStructuresArray
;
206 // Call MarshallUpStructure on all array elements given by cElements of cbStructureSize.
209 if (!MarshallUpStructure(cbSize
, pCurrentElement
, pInfo
, cbStructureSize
, bSomeBoolean
))
212 // Advance to the next array element.
213 pCurrentElement
+= cbStructureSize
;