[LOCALUI] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / win32ss / printing / base / marshalling.c
1 /*
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)
6 */
7
8 #define WIN32_NO_STATUS
9 #include <windef.h>
10 #include <winbase.h>
11
12 #include <marshalling/marshalling.h>
13
14 /**
15 * @name MarshallDownStructure
16 *
17 * Prepare a structure for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
18 *
19 * @param pStructure
20 * Pointer to the structure to operate on.
21 *
22 * @param pInfo
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.
26 *
27 * @param cbStructureSize
28 * Size in bytes of the structure.
29 * This parameter is unused in my implementation.
30 *
31 * @param bSomeBoolean
32 * Unknown boolean value, set to TRUE.
33 *
34 * @return
35 * TRUE if the structure was successfully adjusted, FALSE otherwise.
36 */
37 BOOL WINAPI
38 MarshallDownStructure(PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
39 {
40 // Sanity checks
41 if (!pStructure || !pInfo)
42 {
43 SetLastError(ERROR_INVALID_PARAMETER);
44 return FALSE;
45 }
46
47 // Loop until we reach an element with offset set to MAXDWORD.
48 while (pInfo->dwOffset != MAXDWORD)
49 {
50 PULONG_PTR pCurrentField = (PULONG_PTR)((PBYTE)pStructure + pInfo->dwOffset);
51
52 if (pInfo->bAdjustAddress && *pCurrentField)
53 {
54 // Make a relative offset out of the absolute pointer address.
55 *pCurrentField -= (ULONG_PTR)pStructure;
56 }
57
58 // Advance to the next field description.
59 pInfo++;
60 }
61
62 return TRUE;
63 }
64
65 /**
66 * @name MarshallDownStructuresArray
67 *
68 * Prepare an array of structures for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
69 *
70 * @param pStructuresArray
71 * Pointer to the array of structures to operate on.
72 *
73 * @param cElements
74 * Number of array elements.
75 *
76 * @param pInfo
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.
80 *
81 * @param cbStructureSize
82 * Size in bytes of each structure array element.
83 *
84 * @param bSomeBoolean
85 * Unknown boolean value, set to TRUE.
86 *
87 * @return
88 * TRUE if the array was successfully adjusted, FALSE otherwise.
89 */
90 BOOL WINAPI
91 MarshallDownStructuresArray(PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
92 {
93 PBYTE pCurrentElement = pStructuresArray;
94
95 // Call MarshallDownStructure on all array elements given by cElements of cbStructureSize.
96 while (cElements--)
97 {
98 if (!MarshallDownStructure(pCurrentElement, pInfo, cbStructureSize, bSomeBoolean))
99 return FALSE;
100
101 // Advance to the next array element.
102 pCurrentElement += cbStructureSize;
103 }
104
105 return TRUE;
106 }
107
108 /**
109 * @name MarshallUpStructure
110 *
111 * Unmarshall/deserialize a structure previuosly marshalled by MarshallDownStructure by replacing relative offsets in its fields
112 * by absolute pointer addresses again.
113 *
114 * @param cbSize
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.
117 *
118 * @param pStructure
119 * Pointer to the structure to operate on.
120 *
121 * @param pInfo
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.
125 *
126 * @param cbStructureSize
127 * Size in bytes of the structure.
128 * This parameter is unused in my implementation.
129 *
130 * @param bSomeBoolean
131 * Unknown boolean value, set to TRUE.
132 *
133 * @return
134 * TRUE if the structure was successfully adjusted, FALSE otherwise.
135 */
136 BOOL WINAPI
137 MarshallUpStructure(DWORD cbSize, PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
138 {
139 // Sanity checks
140 if (!pStructure || !pInfo)
141 {
142 SetLastError(ERROR_INVALID_PARAMETER);
143 return FALSE;
144 }
145
146 // Loop until we reach an element with offset set to MAXDWORD.
147 while (pInfo->dwOffset != MAXDWORD)
148 {
149 PULONG_PTR pCurrentField = (PULONG_PTR)((PBYTE)pStructure + pInfo->dwOffset);
150
151 if (pInfo->bAdjustAddress && *pCurrentField)
152 {
153 // Verify that the offset in the current field is within the bounds given by cbSize.
154 if (cbSize <= *pCurrentField)
155 {
156 SetLastError(ERROR_INVALID_DATA);
157 return FALSE;
158 }
159
160 // Make an absolute pointer address out of the relative offset.
161 *pCurrentField += (ULONG_PTR)pStructure;
162 }
163
164 // Advance to the next field description.
165 pInfo++;
166 }
167
168 return TRUE;
169 }
170
171 /**
172 * @name MarshallUpStructuresArray
173 *
174 * Unmarshall/deserialize an array of structures previuosly marshalled by MarshallDownStructuresArray by replacing relative offsets
175 * in its fields by absolute pointer addresses again.
176 *
177 * @param cbSize
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.
180 *
181 * @param pStructuresArray
182 * Pointer to the array of structures to operate on.
183 *
184 * @param cElements
185 * Number of array elements.
186 *
187 * @param pInfo
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.
191 *
192 * @param cbStructureSize
193 * Size in bytes of each structure array element.
194 *
195 * @param bSomeBoolean
196 * Unknown boolean value, set to TRUE.
197 *
198 * @return
199 * TRUE if the array was successfully adjusted, FALSE otherwise.
200 */
201 BOOL WINAPI
202 MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
203 {
204 PBYTE pCurrentElement = pStructuresArray;
205
206 // Call MarshallUpStructure on all array elements given by cElements of cbStructureSize.
207 while (cElements--)
208 {
209 if (!MarshallUpStructure(cbSize, pCurrentElement, pInfo, cbStructureSize, bSomeBoolean))
210 return FALSE;
211
212 // Advance to the next array element.
213 pCurrentElement += cbStructureSize;
214 }
215
216 return TRUE;
217 }