mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:23:01 +00:00
[PRINTING] Implement the undocumented MarshallDownStructure, MarshallDownStructuresArray, MarshallUpStructure, and MarshallUpStructuresArray to the extent I need and could find out through black-box testing.
PDBs reveal that these functions are also used in winspool.drv, but not imported from spoolss.dll to retain the client/server architecture. As winspool.drv highly benefits from the MarshallUp* functions, I put them in a source file shared between spoolss.dll and winspool.drv. The added API Tests cover my testing and all implemented features. One more item done from https://reactos.org/wiki/Printing !
This commit is contained in:
parent
2ae756a4e5
commit
f3ea8225cb
15 changed files with 445 additions and 55 deletions
212
win32ss/printing/base/marshalling.c
Normal file
212
win32ss/printing/base/marshalling.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Printing Stack Marshalling Functions
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Marshalling functions
|
||||
* COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @name MarshallDownStructure
|
||||
*
|
||||
* Prepare a structure for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
|
||||
*
|
||||
* @param pStructure
|
||||
* Pointer to the structure to operate on.
|
||||
*
|
||||
* @param pInfo
|
||||
* Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
|
||||
* See the documentation on MARSHALLING_INFO for more information.
|
||||
* You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
|
||||
*
|
||||
* @param cbStructureSize
|
||||
* Size in bytes of the structure.
|
||||
* This parameter is unused in my implementation.
|
||||
*
|
||||
* @param bSomeBoolean
|
||||
* Unknown boolean value, set to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the structure was successfully adjusted, FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
MarshallDownStructure(PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
|
||||
{
|
||||
// Sanity checks
|
||||
if (!pStructure || !pInfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Loop until we reach an element with offset set to MAXDWORD.
|
||||
while (pInfo->dwOffset != MAXDWORD)
|
||||
{
|
||||
PULONG_PTR pCurrentField = (PULONG_PTR)((PBYTE)pStructure + pInfo->dwOffset);
|
||||
|
||||
if (pInfo->bAdjustAddress && *pCurrentField)
|
||||
{
|
||||
// Make a relative offset out of the absolute pointer address.
|
||||
*pCurrentField -= (ULONG_PTR)pStructure;
|
||||
}
|
||||
|
||||
// Advance to the next field description.
|
||||
pInfo++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name MarshallDownStructuresArray
|
||||
*
|
||||
* Prepare an array of structures for marshalling/serialization by replacing absolute pointer addresses in its fields by relative offsets.
|
||||
*
|
||||
* @param pStructuresArray
|
||||
* Pointer to the array of structures to operate on.
|
||||
*
|
||||
* @param cElements
|
||||
* Number of array elements.
|
||||
*
|
||||
* @param pInfo
|
||||
* Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
|
||||
* See the documentation on MARSHALLING_INFO for more information.
|
||||
* You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
|
||||
*
|
||||
* @param cbStructureSize
|
||||
* Size in bytes of each structure array element.
|
||||
*
|
||||
* @param bSomeBoolean
|
||||
* Unknown boolean value, set to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the array was successfully adjusted, FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
MarshallDownStructuresArray(PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
|
||||
{
|
||||
PBYTE pCurrentElement = pStructuresArray;
|
||||
|
||||
// Call MarshallDownStructure on all array elements given by cElements of cbStructureSize.
|
||||
while (cElements--)
|
||||
{
|
||||
if (!MarshallDownStructure(pCurrentElement, pInfo, cbStructureSize, bSomeBoolean))
|
||||
return FALSE;
|
||||
|
||||
// Advance to the next array element.
|
||||
pCurrentElement += cbStructureSize;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name MarshallUpStructure
|
||||
*
|
||||
* Unmarshall/deserialize a structure previuosly marshalled by MarshallDownStructure by replacing relative offsets in its fields
|
||||
* by absolute pointer addresses again.
|
||||
*
|
||||
* @param cbSize
|
||||
* Size in bytes of the memory allocated for both the structure and its data.
|
||||
* The function will check if all relative offsets are within the bounds given by this size.
|
||||
*
|
||||
* @param pStructure
|
||||
* Pointer to the structure to operate on.
|
||||
*
|
||||
* @param pInfo
|
||||
* Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
|
||||
* See the documentation on MARSHALLING_INFO for more information.
|
||||
* You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
|
||||
*
|
||||
* @param cbStructureSize
|
||||
* Size in bytes of the structure.
|
||||
* This parameter is unused in my implementation.
|
||||
*
|
||||
* @param bSomeBoolean
|
||||
* Unknown boolean value, set to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the structure was successfully adjusted, FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
MarshallUpStructure(DWORD cbSize, PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
|
||||
{
|
||||
// Sanity checks
|
||||
if (!pStructure || !pInfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Loop until we reach an element with offset set to MAXDWORD.
|
||||
while (pInfo->dwOffset != MAXDWORD)
|
||||
{
|
||||
PULONG_PTR pCurrentField = (PULONG_PTR)((PBYTE)pStructure + pInfo->dwOffset);
|
||||
|
||||
if (pInfo->bAdjustAddress && *pCurrentField)
|
||||
{
|
||||
// Verify that the offset in the current field is within the bounds given by cbSize.
|
||||
if (cbSize <= *pCurrentField)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Make an absolute pointer address out of the relative offset.
|
||||
*pCurrentField += (ULONG_PTR)pStructure;
|
||||
}
|
||||
|
||||
// Advance to the next field description.
|
||||
pInfo++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name MarshallUpStructuresArray
|
||||
*
|
||||
* Unmarshall/deserialize an array of structures previuosly marshalled by MarshallDownStructuresArray by replacing relative offsets
|
||||
* in its fields by absolute pointer addresses again.
|
||||
*
|
||||
* @param cbSize
|
||||
* Size in bytes of the memory allocated for the entire structure array and its data.
|
||||
* The function will check if all relative offsets are within the bounds given by this size.
|
||||
*
|
||||
* @param pStructuresArray
|
||||
* Pointer to the array of structures to operate on.
|
||||
*
|
||||
* @param cElements
|
||||
* Number of array elements.
|
||||
*
|
||||
* @param pInfo
|
||||
* Array of MARSHALLING_INFO elements containing information about the fields of the structure as well as how to modify them.
|
||||
* See the documentation on MARSHALLING_INFO for more information.
|
||||
* You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
|
||||
*
|
||||
* @param cbStructureSize
|
||||
* Size in bytes of each structure array element.
|
||||
*
|
||||
* @param bSomeBoolean
|
||||
* Unknown boolean value, set to TRUE.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the array was successfully adjusted, FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
|
||||
{
|
||||
PBYTE pCurrentElement = pStructuresArray;
|
||||
|
||||
// Call MarshallUpStructure on all array elements given by cElements of cbStructureSize.
|
||||
while (cElements--)
|
||||
{
|
||||
if (!MarshallUpStructure(cbSize, pCurrentElement, pInfo, cbStructureSize, bSomeBoolean))
|
||||
return FALSE;
|
||||
|
||||
// Advance to the next array element.
|
||||
pCurrentElement += cbStructureSize;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue