mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 20:22:08 +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;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
spec2def(spoolss.dll spoolss.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
../marshalling.c
|
||||
context.c
|
||||
jobs.c
|
||||
main.c
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#include <spoolss.h>
|
||||
#include <marshalling/marshalling.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(spoolss);
|
||||
|
|
|
@ -97,9 +97,9 @@
|
|||
@ stub LoadDriverWithVersion
|
||||
@ stub LogWmiTraceEvent
|
||||
@ stdcall MarshallDownStructure(ptr ptr long long)
|
||||
@ stub MarshallDownStructuresArray
|
||||
@ stub MarshallUpStructure
|
||||
@ stub MarshallUpStructuresArray
|
||||
@ stdcall MarshallDownStructuresArray(ptr long ptr long long)
|
||||
@ stdcall MarshallUpStructure(long ptr ptr long long)
|
||||
@ stdcall MarshallUpStructuresArray(long ptr long ptr long long)
|
||||
@ stub MIDL_user_allocate1
|
||||
@ stub MIDL_user_free1
|
||||
@ stub OldGetPrinterDriverW
|
||||
|
|
|
@ -8,56 +8,6 @@
|
|||
#include "precomp.h"
|
||||
|
||||
|
||||
/**
|
||||
* @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 pParameters
|
||||
* Array of MARSHALL_DOWN_INFO elements containing information about the fields of the structure as well as how to modify them.
|
||||
* See the documentation on MARSHALL_DOWN_INFO for more information.
|
||||
* You have to indicate the end of the array by setting the dwOffset field to MAXDWORD.
|
||||
*
|
||||
* @param cbStructureSize
|
||||
* Apparently, this is the size in bytes of the structure given through pStructure under Windows.
|
||||
* This parameter is unused in my implementation.
|
||||
*
|
||||
* @param bSomeBoolean
|
||||
* Unknown boolean value
|
||||
*
|
||||
* @return
|
||||
* TRUE if the structure was successfully adjusted, FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
MarshallDownStructure(PVOID pStructure, PMARSHALL_DOWN_INFO pParameters, DWORD cbStructureSize, BOOL bSomeBoolean)
|
||||
{
|
||||
// Sanity checks
|
||||
if (!pStructure || !pParameters)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Loop until we reach an element with offset set to MAXDWORD.
|
||||
while (pParameters->dwOffset != MAXDWORD)
|
||||
{
|
||||
if (pParameters->bAdjustAddress)
|
||||
{
|
||||
// Apply the byte offset on pStructure. There must be a pointer at this position, whose address we're adjusting
|
||||
// by subtracting the address of pStructure from it.
|
||||
*((PULONG_PTR)((PBYTE)pStructure + pParameters->dwOffset)) -= (ULONG_PTR)pStructure;
|
||||
}
|
||||
|
||||
// Advance to the next element description.
|
||||
pParameters++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name PackStrings
|
||||
*
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
#include <winspool.h>
|
||||
#include <winsplp.h>
|
||||
#include <winspool_s.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#include <spoolss.h>
|
||||
#include <marshalling/marshalling.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
|
||||
|
|
|
@ -4,6 +4,7 @@ add_rpc_files(client ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/winspool.idl)
|
|||
spec2def(winspool.drv winspool.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
../marshalling.c
|
||||
devmode.c
|
||||
forms.c
|
||||
jobs.c
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
#include <winreg.h>
|
||||
#include <winspool.h>
|
||||
#include <winspool_c.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#include <spoolss.h>
|
||||
#include <marshalling/marshalling.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winspool);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue