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>
14 * 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.
15 * Useful helper for functions that copy an information structure including strings into a given buffer (like PRINTER_INFO_1).
18 * The array of Unicode strings to copy. Needs to have at least as many elements as the DestOffsets array.
21 * Pointer to the beginning of the output buffer.
22 * The caller is responsible for verifying that this buffer is large enough to hold all strings and pointers.
25 * Array of byte offsets in the output buffer. For each element of DestOffsets, the function will copy the address of the corresponding copied
26 * 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
27 * in the output buffer.
28 * Use macros like FIELD_OFFSET to calculate the offsets for this array.
29 * The last element of the array must have the value MAXDWORD to let the function detect the end of the array.
32 * Pointer to the end of the output buffer. That means the first element outside of the buffer given in pDest.
35 * Returns a pointer to the beginning of the strings in pDest.
36 * The strings are copied in reverse order, so this pointer will point to the last copied string of pSource.
39 PackStrings(PCWSTR
* pSource
, PBYTE pDest
, PDWORD DestOffsets
, PBYTE pEnd
)
42 ULONG_PTR StringAddress
;
44 // Loop until we reach an element with offset set to MAXDWORD.
45 while (*DestOffsets
!= MAXDWORD
)
51 // Determine the length of the source string.
52 cbString
= (wcslen(*pSource
) + 1) * sizeof(WCHAR
);
54 // Copy it before the last string.
56 StringAddress
= (ULONG_PTR
)pEnd
;
57 CopyMemory(pEnd
, *pSource
, cbString
);
60 // Copy the address of the copied string to the location given by the offset.
61 CopyMemory(&pDest
[*DestOffsets
], &StringAddress
, sizeof(ULONG_PTR
));
63 // Advance to the next source string and destination offset.
68 // 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.