[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:
Colin Finck 2018-01-17 10:13:25 +01:00
parent 2ae756a4e5
commit f3ea8225cb
15 changed files with 445 additions and 55 deletions

View file

@ -3,6 +3,8 @@ include_directories(${REACTOS_SOURCE_DIR}/win32ss/printing/include)
list(APPEND SOURCE
AlignRpcPtr.c
MarshallDownStructuresArray.c
MarshallUpStructuresArray.c
PackStrings.c
ReallocSplStr.c
SplInitializeWinSpoolDrv.c

View file

@ -0,0 +1,118 @@
/*
* PROJECT: ReactOS Spooler Router API Tests
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Tests for MarshallDownStructuresArray
* COPYRIGHT: Copyright 2018 Colin Finck (colin@reactos.org)
*/
#include <apitest.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winspool.h>
#include <ndk/rtlfuncs.h>
#include <spoolss.h>
#include <marshalling/marshalling.h>
#include <marshalling/ports.h>
START_TEST(MarshallDownStructuresArray)
{
const DWORD cElements = 2;
const DWORD dwPortInfo2Offsets[] = {
FIELD_OFFSET(PORT_INFO_2W, pPortName),
FIELD_OFFSET(PORT_INFO_2W, pMonitorName),
FIELD_OFFSET(PORT_INFO_2W, pDescription),
MAXDWORD
};
PPORT_INFO_2W pPortInfo2;
PPORT_INFO_2W pPortInfo2Copy;
PPORT_INFO_2W pPortInfo2Test;
PBYTE pPortInfoEnd;
PWSTR pwszStrings[] = { L"PortName", L"MonitorName", L"Description" };
DWORD cbPortInfo2Size = cElements * (sizeof(PORT_INFO_2W) + (wcslen(pwszStrings[0]) + 1 + wcslen(pwszStrings[1]) + 1 + wcslen(pwszStrings[2]) + 1) * sizeof(WCHAR));
DWORD fPortType = 1337;
DWORD Reserved = 42;
// Setting cElements to zero should yield success.
SetLastError(0xDEADBEEF);
ok(MarshallDownStructuresArray(NULL, 0, NULL, 0, FALSE), "MarshallDownStructuresArray returns FALSE!\n");
ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
// Setting cElements non-zero should fail with ERROR_INVALID_PARAMETER.
SetLastError(0xDEADBEEF);
ok(!MarshallDownStructuresArray(NULL, 1, NULL, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
// This is triggered by both pStructuresArray and pInfo.
SetLastError(0xDEADBEEF);
ok(!MarshallDownStructuresArray((PVOID)0xDEADDEAD, 1, NULL, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
SetLastError(0xDEADBEEF);
ok(!MarshallDownStructuresArray(NULL, 1, (const MARSHALLING_INFO*)0xDEADDEAD, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
// Now create two PORT_INFO_2W structures.
pPortInfo2 = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
pPortInfoEnd = (PBYTE)pPortInfo2 + cbPortInfo2Size;
(&pPortInfo2[0])->fPortType = fPortType;
(&pPortInfo2[0])->Reserved = Reserved;
pPortInfoEnd = PackStrings(pwszStrings, (PBYTE)(&pPortInfo2[0]), dwPortInfo2Offsets, pPortInfoEnd);
(&pPortInfo2[1])->fPortType = fPortType + 1;
(&pPortInfo2[1])->Reserved = Reserved + 1;
pPortInfoEnd = PackStrings(pwszStrings, (PBYTE)(&pPortInfo2[1]), dwPortInfo2Offsets, pPortInfoEnd);
// Create a backup.
pPortInfo2Copy = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
CopyMemory(pPortInfo2Copy, pPortInfo2, cbPortInfo2Size);
// Marshall them down.
SetLastError(0xDEADBEEF);
ok(MarshallDownStructuresArray(pPortInfo2, cElements, PortInfo2Marshalling.pInfo, PortInfo2Marshalling.cbStructureSize, TRUE), "MarshallDownStructuresArray returns FALSE!\n");
ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
// DWORD values should be unchanged.
ok((&pPortInfo2[0])->fPortType == fPortType, "fPortType is %lu!\n", (&pPortInfo2[0])->fPortType);
ok((&pPortInfo2[0])->Reserved == Reserved, "Reserved is %lu!\n", (&pPortInfo2[0])->Reserved);
ok((&pPortInfo2[1])->fPortType == fPortType + 1, "fPortType is %lu!\n", (&pPortInfo2[1])->fPortType);
ok((&pPortInfo2[1])->Reserved == Reserved + 1, "Reserved is %lu!\n", (&pPortInfo2[1])->Reserved);
// Pointers should now contain relative offsets.
ok((ULONG_PTR)(&pPortInfo2[0])->pPortName == ((ULONG_PTR)(&pPortInfo2Copy[0])->pPortName - (ULONG_PTR)(&pPortInfo2[0])), "pPortName is %p!\n", (&pPortInfo2[0])->pPortName);
ok((ULONG_PTR)(&pPortInfo2[0])->pMonitorName == ((ULONG_PTR)(&pPortInfo2Copy[0])->pMonitorName - (ULONG_PTR)(&pPortInfo2[0])), "pMonitorName is %p!\n", (&pPortInfo2[0])->pMonitorName);
ok((ULONG_PTR)(&pPortInfo2[0])->pDescription == ((ULONG_PTR)(&pPortInfo2Copy[0])->pDescription - (ULONG_PTR)(&pPortInfo2[0])), "pDescription is %p!\n", (&pPortInfo2[0])->pDescription);
ok((ULONG_PTR)(&pPortInfo2[1])->pPortName == ((ULONG_PTR)(&pPortInfo2Copy[1])->pPortName - (ULONG_PTR)(&pPortInfo2[1])), "pPortName is %p!\n", (&pPortInfo2[1])->pPortName);
ok((ULONG_PTR)(&pPortInfo2[1])->pMonitorName == ((ULONG_PTR)(&pPortInfo2Copy[1])->pMonitorName - (ULONG_PTR)(&pPortInfo2[1])), "pMonitorName is %p!\n", (&pPortInfo2[1])->pMonitorName);
ok((ULONG_PTR)(&pPortInfo2[1])->pDescription == ((ULONG_PTR)(&pPortInfo2Copy[1])->pDescription - (ULONG_PTR)(&pPortInfo2[1])), "pDescription is %p!\n", (&pPortInfo2[1])->pDescription);
// Marshall them up again.
// We need a backup of the marshalled down array to experiment with MarshallUpStructuresArray.
pPortInfo2Test = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
CopyMemory(pPortInfo2Test, pPortInfo2, cbPortInfo2Size);
// Due to the implementation of PackStrings, (&pPortInfo2[0])->pPortName contains the highest offset.
// Show that MarshallUpStructuresArray checks the offsets and bails out with ERROR_INVALID_DATA if cbSize <= highest offset.
SetLastError(0xDEADBEEF);
ok(!MarshallUpStructuresArray((DWORD)(&pPortInfo2[0])->pPortName, pPortInfo2Test, cElements, PortInfo2Marshalling.pInfo, PortInfo2Marshalling.cbStructureSize, TRUE), "MarshallUpStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_DATA, "GetLastError returns %lu!\n", GetLastError());
// It works with cbSize > highest offset.
// In real world cases, we would use cbPortInfo2Size for cbSize.
SetLastError(0xDEADBEEF);
ok(MarshallUpStructuresArray((DWORD)(&pPortInfo2[0])->pPortName + 1, pPortInfo2, cElements, PortInfo2Marshalling.pInfo, PortInfo2Marshalling.cbStructureSize, TRUE), "MarshallUpStructuresArray returns FALSE!\n");
ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
// pPortInfo2 should now be identical to the copy again.
ok(RtlEqualMemory(pPortInfo2, pPortInfo2Copy, cbPortInfo2Size), "pPortInfo2 and pPortInfo2Copy are not equal after marshalling down and up!\n");
// Free all memory.
HeapFree(GetProcessHeap(), 0, pPortInfo2);
HeapFree(GetProcessHeap(), 0, pPortInfo2Copy);
HeapFree(GetProcessHeap(), 0, pPortInfo2Test);
}

View file

@ -0,0 +1,37 @@
/*
* PROJECT: ReactOS Spooler Router API Tests
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Tests for MarshallUpStructuresArray
* COPYRIGHT: Copyright 2018 Colin Finck (colin@reactos.org)
*/
#include <apitest.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <marshalling/marshalling.h>
START_TEST(MarshallUpStructuresArray)
{
// Setting cElements to zero should yield success.
SetLastError(0xDEADBEEF);
ok(MarshallUpStructuresArray(0, NULL, 0, NULL, 0, FALSE), "MarshallUpStructuresArray returns FALSE!\n");
ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
// Setting cElements non-zero should fail with ERROR_INVALID_PARAMETER.
SetLastError(0xDEADBEEF);
ok(!MarshallUpStructuresArray(0, NULL, 1, NULL, 0, FALSE), "MarshallUpStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
// This is triggered by both pStructuresArray and pInfo.
SetLastError(0xDEADBEEF);
ok(!MarshallUpStructuresArray(0, (PVOID)0xDEADDEAD, 1, NULL, 0, FALSE), "MarshallUpStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
SetLastError(0xDEADBEEF);
ok(!MarshallUpStructuresArray(0, NULL, 1, (const MARSHALLING_INFO*)0xDEADDEAD, 0, FALSE), "MarshallUpStructuresArray returns TRUE!\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
// More testing is conducted in the MarshallDownStructuresArray test.
}

View file

@ -2,7 +2,7 @@
* PROJECT: ReactOS Spooler Router API Tests
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Test list
* COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
* COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
*/
#define __ROS_LONG64__
@ -11,6 +11,8 @@
#include <apitest.h>
extern void func_AlignRpcPtr(void);
extern void func_MarshallDownStructuresArray(void);
extern void func_MarshallUpStructuresArray(void);
extern void func_PackStrings(void);
extern void func_ReallocSplStr(void);
extern void func_SplInitializeWinSpoolDrv(void);
@ -18,6 +20,8 @@ extern void func_SplInitializeWinSpoolDrv(void);
const struct test winetest_testlist[] =
{
{ "AlignRpcPtr", func_AlignRpcPtr },
{ "MarshallDownStructuresArray", func_MarshallDownStructuresArray },
{ "MarshallUpStructuresArray", func_MarshallUpStructuresArray },
{ "PackStrings", func_PackStrings },
{ "ReallocSplStr", func_ReallocSplStr },
{ "SplInitializeWinSpoolDrv", func_SplInitializeWinSpoolDrv },

View 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;
}

View file

@ -2,6 +2,7 @@
spec2def(spoolss.dll spoolss.spec ADD_IMPORTLIB)
list(APPEND SOURCE
../marshalling.c
context.c
jobs.c
main.c

View file

@ -18,6 +18,7 @@
#include <ndk/rtlfuncs.h>
#include <spoolss.h>
#include <marshalling/marshalling.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(spoolss);

View file

@ -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

View file

@ -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
*

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -0,0 +1,35 @@
/*
* PROJECT: ReactOS Printing Stack Marshalling Functions
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Marshalling definitions
* COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
*/
#ifndef _MARSHALLING_H
#define _MARSHALLING_H
typedef struct _MARSHALLING_INFO
{
DWORD dwOffset; /** Byte offset of this element within the structure or MAXDWORD to indicate the end of the array */
DWORD cbSize; /** Total size of this element in bytes under Windows. Unused here, I don't know what we need this number for. */
DWORD cbPerElementSize; /** If this element is a structure itself, this field gives the size in bytes of each element of the structure.
Otherwise, this is the same as cbTotalSize. E.g. for SYSTEMTIME, cbSize would be 16 and cbPerElementSize would be 2.
Unused here, I don't know what we need this number for. */
BOOL bAdjustAddress; /** TRUE if MarshallDownStructure shall adjust the address of this element, FALSE if it shall leave this element untouched. */
}
MARSHALLING_INFO;
typedef struct _MARSHALLING
{
DWORD cbStructureSize;
MARSHALLING_INFO pInfo[];
}
MARSHALLING;
BOOL WINAPI MarshallDownStructure(PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean);
BOOL WINAPI MarshallDownStructuresArray(PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean);
BOOL WINAPI MarshallUpStructure(DWORD cbSize, PVOID pStructure, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean);
BOOL WINAPI MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO* pInfo, DWORD cbStructureSize, BOOL bSomeBoolean);
#endif

View file

@ -0,0 +1,26 @@
/*
* PROJECT: ReactOS Printing Stack Marshalling Functions
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Marshalling definitions for PORT_INFO_*
* COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
*/
const MARSHALLING PortInfo1Marshalling = {
sizeof(PORT_INFO_1W),
{
{ FIELD_OFFSET(PORT_INFO_1W, pName), RTL_FIELD_SIZE(PORT_INFO_1W, pName), RTL_FIELD_SIZE(PORT_INFO_1W, pName), TRUE },
{ MAXDWORD, 0, 0, FALSE }
}
};
const MARSHALLING PortInfo2Marshalling = {
sizeof(PORT_INFO_2W),
{
{ FIELD_OFFSET(PORT_INFO_2W, pPortName), RTL_FIELD_SIZE(PORT_INFO_2W, pPortName), RTL_FIELD_SIZE(PORT_INFO_2W, pPortName), TRUE },
{ FIELD_OFFSET(PORT_INFO_2W, pMonitorName), RTL_FIELD_SIZE(PORT_INFO_2W, pMonitorName), RTL_FIELD_SIZE(PORT_INFO_2W, pMonitorName), TRUE },
{ FIELD_OFFSET(PORT_INFO_2W, pDescription), RTL_FIELD_SIZE(PORT_INFO_2W, pDescription), RTL_FIELD_SIZE(PORT_INFO_2W, pDescription), TRUE },
{ FIELD_OFFSET(PORT_INFO_2W, fPortType), RTL_FIELD_SIZE(PORT_INFO_2W, fPortType), RTL_FIELD_SIZE(PORT_INFO_2W, fPortType), FALSE },
{ FIELD_OFFSET(PORT_INFO_2W, Reserved), RTL_FIELD_SIZE(PORT_INFO_2W, Reserved), RTL_FIELD_SIZE(PORT_INFO_2W, Reserved), FALSE },
{ MAXDWORD, 0, 0, FALSE }
}
};

View file

@ -63,7 +63,6 @@ PVOID WINAPI DllAllocSplMem(DWORD dwBytes);
BOOL WINAPI DllFreeSplMem(PVOID pMem);
BOOL WINAPI DllFreeSplStr(PWSTR pwszString);
BOOL WINAPI InitializeRouter(HANDLE SpoolerStatusHandle);
BOOL WINAPI MarshallDownStructure(PVOID pStructure, PMARSHALL_DOWN_INFO pParameters, DWORD cbStructureSize, BOOL bSomeBoolean);
PBYTE WINAPI PackStrings(PWSTR* pSource, PBYTE pDest, const DWORD* DestOffsets, PBYTE pEnd);
PVOID WINAPI ReallocSplMem(PVOID pOldMem, DWORD cbOld, DWORD cbNew);
BOOL WINAPI ReallocSplStr(PWSTR* ppwszString, PCWSTR pwszInput);