X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fwin32ss%2Fprinting%2Fbase%2Fspoolss%2Fmemory.c;h=07be553b3084c8a180593d1f55c03f66fb8f5bac;hp=96a7fd1fd27aef3da9748a0889a1746b43cbb7c6;hb=a737c007e802ee94140db714aff3573dd6e262c2;hpb=6790e320bd9378275bbb300552fb82e20a39929a diff --git a/reactos/win32ss/printing/base/spoolss/memory.c b/reactos/win32ss/printing/base/spoolss/memory.c index 96a7fd1fd27..07be553b308 100644 --- a/reactos/win32ss/printing/base/spoolss/memory.c +++ b/reactos/win32ss/printing/base/spoolss/memory.c @@ -2,12 +2,42 @@ * PROJECT: ReactOS Spooler Router * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation * PURPOSE: Functions for allocating and freeing memory - * COPYRIGHT: Copyright 2015 Colin Finck + * COPYRIGHT: Copyright 2015-2017 Colin Finck */ #include "precomp.h" +/** + * @name AlignRpcPtr + * + * Checks if the input buffer and buffer size are 4-byte aligned. + * If the buffer size is not 4-byte aligned, it is aligned down. + * If the input buffer is not 4-byte aligned, a 4-byte aligned buffer of the aligned down buffer size is allocated and returned. + * + * @param pBuffer + * The buffer to check. + * + * @param pcbBuffer + * Pointer to the buffer size to check. Its value is aligned down if needed. + * + * @return + * pBuffer if pBuffer is already 4-byte aligned, or a newly allocated 4-byte aligned buffer of the aligned down buffer size otherwise. + * If a buffer was allocated, you have to free it using UndoAlignRpcPtr. + */ +PVOID WINAPI +AlignRpcPtr(PVOID pBuffer, PDWORD pcbBuffer) +{ + // Align down the buffer size in pcbBuffer to a 4-byte boundary. + *pcbBuffer -= *pcbBuffer % sizeof(DWORD); + + // Check if pBuffer is 4-byte aligned. If not, allocate a 4-byte aligned buffer. + if ((ULONG_PTR)pBuffer % sizeof(DWORD)) + pBuffer = DllAllocSplMem(*pcbBuffer); + + return pBuffer; +} + /** * @name AllocSplStr * @@ -163,6 +193,59 @@ ReallocSplStr(PWSTR* ppwszString, PCWSTR pwszInput) DllFreeSplStr(*ppwszString); *ppwszString = AllocSplStr(pwszInput); - + return TRUE; } + +/** + * @name UndoAlignRpcPtr + * + * Copies the data from the aligned buffer previously allocated by AlignRpcPtr back to the original unaligned buffer. + * The aligned buffer is freed. + * + * Also aligns up the returned required buffer size of a function to a 4-byte boundary. + * + * @param pDestinationBuffer + * The original unaligned buffer, which you input as pBuffer to AlignRpcPtr. + * The data from pSourceBuffer is copied into this buffer before pSourceBuffer is freed. + * If AlignRpcPtr did not allocate a buffer, pDestinationBuffer equals pSourceBuffer and no memory is copied or freed. + * This parameter may be NULL if pSourceBuffer is NULL. + * + * @param pSourceBuffer + * The aligned buffer, which is returned by AlignRpcPtr. + * Its data is copied into pDestinationBuffer and then pSourceBuffer is freed. + * If AlignRpcPtr did not allocate a buffer, pDestinationBuffer equals pSourceBuffer and no memory is copied or freed. + * This parameter may be NULL. + * + * @param cbBuffer + * Number of bytes to copy. + * Set this to the size returned by AlignRpcPtr's pcbBuffer or less. + * + * @param pcbNeeded + * Let this parameter point to your variable calculating the needed bytes for a buffer and returning this value to the user. + * It is then aligned up to a 4-byte boundary, so that the user supplies a large enough buffer in the next call. + * Otherwise, AlignRpcPtr would align down the buffer size in the next call and your buffer would be smaller than intended. + * This parameter may be NULL. + * + * @return + * pcbNeeded + */ +PDWORD WINAPI +UndoAlignRpcPtr(PVOID pDestinationBuffer, PVOID pSourceBuffer, DWORD cbBuffer, PDWORD pcbNeeded) +{ + // If pSourceBuffer is given, and source and destination pointers don't match, + // we assume that pSourceBuffer is the buffer allocated by AlignRpcPtr. + if (pSourceBuffer && pSourceBuffer != pDestinationBuffer) + { + // Copy back the buffer data to the (usually unaligned) destination buffer + // and free the buffer allocated by AlignRpcPtr. + CopyMemory(pDestinationBuffer, pSourceBuffer, cbBuffer); + DllFreeSplMem(pSourceBuffer); + } + + // If pcbNeeded is given, align it up to a 4-byte boundary. + if (pcbNeeded && *pcbNeeded % sizeof(DWORD)) + *pcbNeeded += sizeof(DWORD) - *pcbNeeded % sizeof(DWORD); + + return pcbNeeded; +}