2 * PROJECT: ReactOS Spooler Router
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
4 * PURPOSE: Miscellaneous tool functions
5 * COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
12 * @name MarshallDownStructure
14 * Prepare a structure for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
17 * Pointer to the structure to operate on.
20 * Array of MARSHALL_DOWN_INFO elements containing information about the fields of the structure as well as how to modify them.
21 * See the documentation on MARSHALL_DOWN_INFO for more information.
22 * You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
24 * @param cbStructureSize
25 * Apparently, this is the size in bytes of the structure given through pStructure under Windows.
26 * This parameter is unused in my implementation.
29 * Unknown boolean value
32 * TRUE if the structure was successfully adjusted, FALSE otherwise.
35 MarshallDownStructure(PVOID pStructure
, PMARSHALL_DOWN_INFO pParameters
, DWORD cbStructureSize
, BOOL bSomeBoolean
)
38 if (!pStructure
|| !pParameters
)
40 SetLastError(ERROR_INVALID_PARAMETER
);
44 // Loop until we reach an element with offset set to MAXDWORD.
45 while (pParameters
->dwOffset
!= MAXDWORD
)
47 if (pParameters
->bAdjustAddress
)
49 // Apply the byte offset on pStructure. There must be a pointer at this position, whose address we're adjusting
50 // by subtracting the address of pStructure from it.
51 *((PULONG_PTR
)((PBYTE
)pStructure
+ pParameters
->dwOffset
)) -= (ULONG_PTR
)pStructure
;
54 // Advance to the next element description.
64 * Takes an array of Unicode strings and fills an output buffer with these strings at the end and pointers to each string at specific offsets.
65 * Useful helper for functions that copy an information structure including strings into a given buffer (like PRINTER_INFO_1).
68 * The array of Unicode strings to copy. Needs to have at least as many elements as the DestOffsets array.
71 * Pointer to the beginning of the output buffer.
72 * The caller is responsible for verifying that this buffer is large enough to hold all strings and pointers.
75 * Array of byte offsets in the output buffer. For each element of DestOffsets, the function will copy the address of the corresponding copied
76 * string of pSource to this location in the output buffer. If a string in pSource is NULL, the function will set the pointer address to NULL
77 * in the output buffer.
78 * Use macros like FIELD_OFFSET to calculate the offsets for this array.
79 * The last element of the array must have the value MAXDWORD to let the function detect the end of the array.
82 * Pointer to the end of the output buffer. That means the first element outside of the buffer given in pDest.
85 * Returns a pointer to the beginning of the strings in pDest.
86 * The strings are copied in reverse order, so this pointer will point to the last copied string of pSource.
89 PackStrings(PCWSTR
* pSource
, PBYTE pDest
, PDWORD DestOffsets
, PBYTE pEnd
)
92 ULONG_PTR StringAddress
;
94 // Loop until we reach an element with offset set to MAXDWORD.
95 while (*DestOffsets
!= MAXDWORD
)
101 // Determine the length of the source string.
102 cbString
= (wcslen(*pSource
) + 1) * sizeof(WCHAR
);
104 // Copy it before the last string.
106 StringAddress
= (ULONG_PTR
)pEnd
;
107 CopyMemory(pEnd
, *pSource
, cbString
);
110 // Copy the address of the copied string to the location given by the offset.
111 CopyMemory(&pDest
[*DestOffsets
], &StringAddress
, sizeof(ULONG_PTR
));
113 // Advance to the next source string and destination offset.
118 // pEnd is now at the last string we copied. Return this value as a pointer to the beginning of all strings in the output buffer.