https://git.reactos.org/?p=reactos.git;a=commitdiff;h=22ffe5300b5882605b6790057b84010d8043fe53

commit 22ffe5300b5882605b6790057b84010d8043fe53
Author:     Colin Finck <co...@reactos.org>
AuthorDate: Wed Jan 17 12:52:12 2018 +0100
Commit:     Colin Finck <co...@reactos.org>
CommitDate: Wed Jan 17 12:52:12 2018 +0100

    [PRINTING] Replace all my custom marshalling code by calls to the newly 
implemented APIs, thereby significantly reducing the codebase and providing a 
sane template to implement more Printing APIs.
---
 .../apitests/spoolss/MarshallDownStructuresArray.c |   6 +-
 win32ss/printing/base/spoolsv/jobs.c               |  79 ++---------
 win32ss/printing/base/spoolsv/monitors.c           |  30 +---
 win32ss/printing/base/spoolsv/ports.c              |  42 +-----
 win32ss/printing/base/spoolsv/printers.c           | 124 ++--------------
 win32ss/printing/base/spoolsv/printprocessors.c    |  33 +----
 win32ss/printing/base/winspool/jobs.c              |  74 ++--------
 win32ss/printing/base/winspool/monitors.c          |  31 +---
 win32ss/printing/base/winspool/ports.c             |  31 +---
 win32ss/printing/base/winspool/printers.c          | 124 ++--------------
 win32ss/printing/base/winspool/printprocessors.c   |  41 ++----
 win32ss/printing/include/marshalling/jobs.h        |  71 ++++++++++
 win32ss/printing/include/marshalling/monitors.h    |  30 ++++
 win32ss/printing/include/marshalling/ports.h       |  10 +-
 win32ss/printing/include/marshalling/printers.h    | 157 +++++++++++++++++++++
 .../printing/include/marshalling/printprocessors.h |  22 +++
 16 files changed, 359 insertions(+), 546 deletions(-)

diff --git a/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c 
b/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c
index cd057074ec..7b7deba6f4 100644
--- a/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c
+++ b/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c
@@ -74,7 +74,7 @@ START_TEST(MarshallDownStructuresArray)
 
     // Marshall them down.
     SetLastError(0xDEADBEEF);
-    ok(MarshallDownStructuresArray(pPortInfo2, cElements, 
PortInfo2Marshalling.pInfo, PortInfo2Marshalling.cbStructureSize, TRUE), 
"MarshallDownStructuresArray returns FALSE!\n");
+    ok(MarshallDownStructuresArray(pPortInfo2, cElements, 
pPortInfoMarshalling[2]->pInfo, pPortInfoMarshalling[2]->cbStructureSize, 
TRUE), "MarshallDownStructuresArray returns FALSE!\n");
     ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", 
GetLastError());
 
     // DWORD values should be unchanged.
@@ -99,13 +99,13 @@ START_TEST(MarshallDownStructuresArray)
     // 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(!MarshallUpStructuresArray((DWORD)(&pPortInfo2[0])->pPortName, 
pPortInfo2Test, cElements, pPortInfoMarshalling[2]->pInfo, 
pPortInfoMarshalling[2]->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(MarshallUpStructuresArray((DWORD)(&pPortInfo2[0])->pPortName + 1, 
pPortInfo2, cElements, pPortInfoMarshalling[2]->pInfo, 
pPortInfoMarshalling[2]->cbStructureSize, TRUE), "MarshallUpStructuresArray 
returns FALSE!\n");
     ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", 
GetLastError());
 
     // pPortInfo2 should now be identical to the copy again.
diff --git a/win32ss/printing/base/spoolsv/jobs.c 
b/win32ss/printing/base/spoolsv/jobs.c
index 596cddbf35..3fe510e6c7 100644
--- a/win32ss/printing/base/spoolsv/jobs.c
+++ b/win32ss/printing/base/spoolsv/jobs.c
@@ -2,65 +2,11 @@
  * PROJECT:     ReactOS Print Spooler Service
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions for managing print jobs
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallDownAddJobInfo(PADDJOB_INFO_1W* ppAddJobInfo1)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    PADDJOB_INFO_1W pAddJobInfo1 = *ppAddJobInfo1;
-    pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path - 
(ULONG_PTR)pAddJobInfo1);
-
-    *ppAddJobInfo1 += sizeof(ADDJOB_INFO_1W);
-}
-
-static void
-_MarshallDownJobInfo(PBYTE* ppJobInfo, DWORD Level)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    if (Level == 1)
-    {
-        PJOB_INFO_1W pJobInfo1 = (PJOB_INFO_1W)(*ppJobInfo);
-
-        pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype - 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument - 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName - 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName - 
(ULONG_PTR)pJobInfo1);
-
-        if (pJobInfo1->pStatus)
-            pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus - 
(ULONG_PTR)pJobInfo1);
-
-        pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName - 
(ULONG_PTR)pJobInfo1);
-
-        *ppJobInfo += sizeof(JOB_INFO_1W);
-    }
-    else if (Level == 2)
-    {
-        PJOB_INFO_2W pJobInfo2 = (PJOB_INFO_2W)(*ppJobInfo);
-
-        pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName - 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pPrintProcessor = 
(PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor - (ULONG_PTR)pJobInfo2);
-
-        if (pJobInfo2->pParameters)
-            pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters 
- (ULONG_PTR)pJobInfo2);
-
-        if (pJobInfo2->pStatus)
-            pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus - 
(ULONG_PTR)pJobInfo2);
-
-        pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName - 
(ULONG_PTR)pJobInfo2);
-
-        *ppJobInfo += sizeof(JOB_INFO_2W);
-    }
-}
+#include <marshalling/jobs.h>
 
 DWORD
 _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD 
cbBuf, DWORD* pcbNeeded)
@@ -79,10 +25,8 @@ _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, 
BYTE* pAddJob, DWORD c
 
     if (AddJobW(hPrinter, Level, pAddJobAligned, cbBuf, pcbNeeded))
     {
-        PBYTE p = pAddJobAligned;
-
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        _MarshallDownAddJobInfo((PADDJOB_INFO_1W*)&p);
+        MarshallDownStructure(pAddJobAligned, AddJobInfo1Marshalling.pInfo, 
AddJobInfo1Marshalling.cbStructureSize, TRUE);
     }
     else
     {
@@ -112,12 +56,12 @@ _RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD 
FirstJob, DWORD NoJobs, DWO
 
     if (EnumJobsW(hPrinter, FirstJob, NoJobs, Level, pJobAligned, cbBuf, 
pcbNeeded, pcReturned))
     {
-        DWORD i;
-        PBYTE p = pJobAligned;
-
-        // Replace absolute pointer addresses in the output by relative 
offsets.
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownJobInfo(&p, Level);
+        // Replace absolute pointer addresses in the output by relative 
offsets for JOB_INFO_1W and JOB_INFO_2W.
+        if (Level <= 2)
+        {
+            ASSERT(Level >= 1);
+            MarshallDownStructuresArray(pJobAligned, *pcReturned, 
pJobInfoMarshalling[Level]->pInfo, pJobInfoMarshalling[Level]->cbStructureSize, 
TRUE);
+        }
     }
     else
     {
@@ -147,10 +91,9 @@ _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, 
DWORD Level, BYTE* pJo
 
     if (GetJobW(hPrinter, JobId, Level, pJobAligned, cbBuf, pcbNeeded))
     {
-        PBYTE p = pJobAligned;
-
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        _MarshallDownJobInfo(&p, Level);
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallDownStructure(pJobAligned, pJobInfoMarshalling[Level]->pInfo, 
pJobInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
     else
     {
diff --git a/win32ss/printing/base/spoolsv/monitors.c 
b/win32ss/printing/base/spoolsv/monitors.c
index 3e02902a38..0b83ccad00 100644
--- a/win32ss/printing/base/spoolsv/monitors.c
+++ b/win32ss/printing/base/spoolsv/monitors.c
@@ -2,30 +2,11 @@
  * PROJECT:     ReactOS Print Spooler Service
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Print Monitors
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallDownMonitorInfo(PBYTE* ppMonitorInfo, DWORD Level)
-{
-    PMONITOR_INFO_2W pMonitorInfo2 = (PMONITOR_INFO_2W)(*ppMonitorInfo);       
 // MONITOR_INFO_1W is a subset of MONITOR_INFO_2W
-
-    // Replace absolute pointer addresses in the output by relative offsets.
-    pMonitorInfo2->pName = (PWSTR)((ULONG_PTR)pMonitorInfo2->pName - 
(ULONG_PTR)pMonitorInfo2);
-
-    if (Level == 1)
-    {
-        *ppMonitorInfo += sizeof(MONITOR_INFO_1W);
-    }
-    else
-    {
-        pMonitorInfo2->pDLLName = (PWSTR)((ULONG_PTR)pMonitorInfo2->pDLLName - 
(ULONG_PTR)pMonitorInfo2);
-        pMonitorInfo2->pEnvironment = 
(PWSTR)((ULONG_PTR)pMonitorInfo2->pEnvironment - (ULONG_PTR)pMonitorInfo2);
-        *ppMonitorInfo += sizeof(MONITOR_INFO_2W);
-    }
-}
+#include <marshalling/monitors.h>
 
 DWORD
 _RpcAddMonitor(WINSPOOL_HANDLE pName, WINSPOOL_MONITOR_CONTAINER* 
pMonitorContainer)
@@ -59,11 +40,8 @@ _RpcEnumMonitors(WINSPOOL_HANDLE pName, DWORD Level, BYTE* 
pMonitor, DWORD cbBuf
     if(EnumMonitorsW(pName, Level, pMonitorAligned, cbBuf, pcbNeeded, 
pcReturned))
     {
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        DWORD i;
-        PBYTE p = pMonitorAligned;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownMonitorInfo(&p, Level);
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallDownStructuresArray(pMonitorAligned, *pcReturned, 
pMonitorInfoMarshalling[Level]->pInfo, 
pMonitorInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
     else
     {
diff --git a/win32ss/printing/base/spoolsv/ports.c 
b/win32ss/printing/base/spoolsv/ports.c
index d88a08cbd5..8b510d7ee0 100644
--- a/win32ss/printing/base/spoolsv/ports.c
+++ b/win32ss/printing/base/spoolsv/ports.c
@@ -2,42 +2,11 @@
  * PROJECT:     ReactOS Print Spooler Service
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Ports
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallDownPortInfo(PBYTE* ppPortInfo, DWORD Level)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    if (Level == 1)
-    {
-        PPORT_INFO_1W pPortInfo1 = (PPORT_INFO_1W)(*ppPortInfo);
-
-        pPortInfo1->pName = (PWSTR)((ULONG_PTR)pPortInfo1->pName - 
(ULONG_PTR)pPortInfo1);
-
-        *ppPortInfo += sizeof(PORT_INFO_1W);
-    }
-    else if (Level == 2)
-    {
-        PPORT_INFO_2W pPortInfo2 = (PPORT_INFO_2W)(*ppPortInfo);
-
-        pPortInfo2->pPortName = (PWSTR)((ULONG_PTR)pPortInfo2->pPortName - 
(ULONG_PTR)pPortInfo2);
-        pPortInfo2->pDescription = (PWSTR)((ULONG_PTR)pPortInfo2->pDescription 
- (ULONG_PTR)pPortInfo2);
-        pPortInfo2->pMonitorName = (PWSTR)((ULONG_PTR)pPortInfo2->pMonitorName 
- (ULONG_PTR)pPortInfo2);
-
-        *ppPortInfo += sizeof(PORT_INFO_2W);
-    }
-    else if (Level == 3)
-    {
-        PPORT_INFO_3W pPortInfo3 = (PPORT_INFO_3W)(*ppPortInfo);
-
-        pPortInfo3->pszStatus = (PWSTR)((ULONG_PTR)pPortInfo3->pszStatus - 
(ULONG_PTR)pPortInfo3);
-
-        *ppPortInfo += sizeof(PORT_INFO_3W);
-    }
-}
+#include <marshalling/ports.h>
 
 DWORD
 _RpcAddPort(WINSPOOL_HANDLE pName, ULONG_PTR hWnd, WCHAR* pMonitorName)
@@ -85,11 +54,8 @@ _RpcEnumPorts(WINSPOOL_HANDLE pName, DWORD Level, BYTE* 
pPort, DWORD cbBuf, DWOR
     if (EnumPortsW(pName, Level, pPortAligned, cbBuf, pcbNeeded, pcReturned))
     {
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        DWORD i;
-        PBYTE p = pPortAligned;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownPortInfo(&p, Level);
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallDownStructuresArray(pPortAligned, *pcReturned, 
pPortInfoMarshalling[Level]->pInfo, 
pPortInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
     else
     {
diff --git a/win32ss/printing/base/spoolsv/printers.c 
b/win32ss/printing/base/spoolsv/printers.c
index 881eec87d4..08eec5f071 100644
--- a/win32ss/printing/base/spoolsv/printers.c
+++ b/win32ss/printing/base/spoolsv/printers.c
@@ -2,118 +2,11 @@
  * PROJECT:     ReactOS Print Spooler Service
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Printers and printing
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallDownPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    if (Level == 0)
-    {
-        PPRINTER_INFO_STRESS pPrinterInfo0 = 
(PPRINTER_INFO_STRESS)(*ppPrinterInfo);
-
-        pPrinterInfo0->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo0->pPrinterName - (ULONG_PTR)pPrinterInfo0);
-
-        if (pPrinterInfo0->pServerName)
-            pPrinterInfo0->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo0->pServerName - (ULONG_PTR)pPrinterInfo0);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_STRESS);
-    }
-    else if (Level == 1)
-    {
-        PPRINTER_INFO_1W pPrinterInfo1 = (PPRINTER_INFO_1W)(*ppPrinterInfo);
-
-        pPrinterInfo1->pName = (PWSTR)((ULONG_PTR)pPrinterInfo1->pName - 
(ULONG_PTR)pPrinterInfo1);
-        pPrinterInfo1->pDescription = 
(PWSTR)((ULONG_PTR)pPrinterInfo1->pDescription - (ULONG_PTR)pPrinterInfo1);
-        pPrinterInfo1->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo1->pComment - 
(ULONG_PTR)pPrinterInfo1);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_1W);
-    }
-    else if (Level == 2)
-    {
-        PPRINTER_INFO_2W pPrinterInfo2 = (PPRINTER_INFO_2W)(*ppPrinterInfo);
-
-        pPrinterInfo2->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pPrinterName - (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pShareName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pShareName - (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPortName 
- (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDriverName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pDriverName - (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo2->pComment - 
(ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pLocation = (PWSTR)((ULONG_PTR)pPrinterInfo2->pLocation 
- (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo2->pDevMode - (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pSepFile = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSepFile - 
(ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pPrintProcessor = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pPrintProcessor - (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDatatype = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDatatype 
- (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pParameters = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pParameters - (ULONG_PTR)pPrinterInfo2);
-
-        if (pPrinterInfo2->pServerName)
-            pPrinterInfo2->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pServerName - (ULONG_PTR)pPrinterInfo2);
-
-        if (pPrinterInfo2->pSecurityDescriptor)
-            pPrinterInfo2->pSecurityDescriptor = 
(PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo2->pSecurityDescriptor - 
(ULONG_PTR)pPrinterInfo2);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_2W);
-    }
-    else if (Level == 3)
-    {
-        PPRINTER_INFO_3 pPrinterInfo3 = (PPRINTER_INFO_3)(*ppPrinterInfo);
-
-        pPrinterInfo3->pSecurityDescriptor = 
(PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo3->pSecurityDescriptor - 
(ULONG_PTR)pPrinterInfo3);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_3);
-    }
-    else if (Level == 4)
-    {
-        PPRINTER_INFO_4W pPrinterInfo4 = (PPRINTER_INFO_4W)(*ppPrinterInfo);
-
-        pPrinterInfo4->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo4->pPrinterName - (ULONG_PTR)pPrinterInfo4);
-
-        if (pPrinterInfo4->pServerName)
-            pPrinterInfo4->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo4->pServerName - (ULONG_PTR)pPrinterInfo4);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_4W);
-    }
-    else if (Level == 5)
-    {
-        PPRINTER_INFO_5W pPrinterInfo5 = (PPRINTER_INFO_5W)(*ppPrinterInfo);
-
-        pPrinterInfo5->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo5->pPrinterName - (ULONG_PTR)pPrinterInfo5);
-        pPrinterInfo5->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPortName 
- (ULONG_PTR)pPrinterInfo5);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_5W);
-    }
-    else if (Level == 6)
-    {
-        *ppPrinterInfo += sizeof(PRINTER_INFO_6);
-    }
-    else if (Level == 7)
-    {
-        PPRINTER_INFO_7W pPrinterInfo7 = (PPRINTER_INFO_7W)(*ppPrinterInfo);
-
-        if (pPrinterInfo7->pszObjectGUID)
-            pPrinterInfo7->pszObjectGUID = 
(PWSTR)((ULONG_PTR)pPrinterInfo7->pszObjectGUID - (ULONG_PTR)pPrinterInfo7);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_7W);
-    }
-    else if (Level == 8)
-    {
-        PPRINTER_INFO_8W pPrinterInfo8 = (PPRINTER_INFO_8W)(*ppPrinterInfo);
-
-        pPrinterInfo8->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo8->pDevMode - (ULONG_PTR)pPrinterInfo8);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_8W);
-    }
-    else if (Level == 9)
-    {
-        PPRINTER_INFO_9W pPrinterInfo9 = (PPRINTER_INFO_9W)(*ppPrinterInfo);
-
-        pPrinterInfo9->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo9->pDevMode - (ULONG_PTR)pPrinterInfo9);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_9W);
-    }
-}
+#include <marshalling/printers.h>
 
 DWORD
 _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
@@ -219,11 +112,9 @@ _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD 
Level, BYTE* pPrinterE
 
     if (EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, 
pcbNeeded, pcReturned))
     {
-        DWORD i;
-        PBYTE p = pPrinterEnumAligned;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownPrinterInfo(&p, Level);
+        // Replace absolute pointer addresses in the output by relative 
offsets.
+        ASSERT(Level <= 9);
+        MarshallDownStructuresArray(pPrinterEnumAligned, *pcReturned, 
pPrinterInfoMarshalling[Level]->pInfo, 
pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
     else
     {
@@ -260,8 +151,9 @@ _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD 
Level, BYTE* pPrinter, DW
 
     if (GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded))
     {
-        PBYTE p = pPrinterAligned;
-        _MarshallDownPrinterInfo(&p, Level);
+        // Replace absolute pointer addresses in the output by relative 
offsets.
+        ASSERT(Level <= 9);
+        MarshallDownStructure(pPrinterAligned, 
pPrinterInfoMarshalling[Level]->pInfo, 
pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
     else
     {
diff --git a/win32ss/printing/base/spoolsv/printprocessors.c 
b/win32ss/printing/base/spoolsv/printprocessors.c
index 0e949bbec8..fcdb7d50d4 100644
--- a/win32ss/printing/base/spoolsv/printprocessors.c
+++ b/win32ss/printing/base/spoolsv/printprocessors.c
@@ -2,28 +2,11 @@
  * PROJECT:     ReactOS Print Spooler Service
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Print Processors
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallDownDatatypesInfo(PDATATYPES_INFO_1W* ppDatatypesInfo1)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    PDATATYPES_INFO_1W pDatatypesInfo1 = *ppDatatypesInfo1;
-    pDatatypesInfo1->pName = (PWSTR)((ULONG_PTR)pDatatypesInfo1->pName - 
(ULONG_PTR)pDatatypesInfo1);
-    *ppDatatypesInfo1 += sizeof(DATATYPES_INFO_1W);
-}
-
-static void
-_MarshallDownPrintProcessorInfo(PPRINTPROCESSOR_INFO_1W* ppPrintProcessorInfo1)
-{
-    // Replace absolute pointer addresses in the output by relative offsets.
-    PPRINTPROCESSOR_INFO_1W pPrintProcessorInfo1 = *ppPrintProcessorInfo1;
-    pPrintProcessorInfo1->pName = 
(PWSTR)((ULONG_PTR)pPrintProcessorInfo1->pName - 
(ULONG_PTR)pPrintProcessorInfo1);
-    *ppPrintProcessorInfo1 += sizeof(PRINTPROCESSOR_INFO_1W);
-}
+#include <marshalling/printprocessors.h>
 
 DWORD
 _RpcAddPrintProcessor(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* 
pPathName, WCHAR* pPrintProcessorName)
@@ -57,11 +40,7 @@ _RpcEnumPrintProcessorDatatypes(WINSPOOL_HANDLE pName, 
WCHAR* pPrintProcessorNam
     if (EnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, 
pDatatypesAligned, cbBuf, pcbNeeded, pcReturned))
     {
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        DWORD i;
-        PDATATYPES_INFO_1W p = (PDATATYPES_INFO_1W)pDatatypesAligned;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownDatatypesInfo(&p);
+        MarshallDownStructuresArray(pDatatypesAligned, *pcReturned, 
DatatypesInfo1Marshalling.pInfo, DatatypesInfo1Marshalling.cbStructureSize, 
TRUE);
     }
     else
     {
@@ -92,11 +71,7 @@ _RpcEnumPrintProcessors(WINSPOOL_HANDLE pName, WCHAR* 
pEnvironment, DWORD Level,
     if (EnumPrintProcessorsW(pName, pEnvironment, Level, 
pPrintProcessorInfoAligned, cbBuf, pcbNeeded, pcReturned))
     {
         // Replace absolute pointer addresses in the output by relative 
offsets.
-        DWORD i;
-        PPRINTPROCESSOR_INFO_1W p = 
(PPRINTPROCESSOR_INFO_1W)pPrintProcessorInfoAligned;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallDownPrintProcessorInfo(&p);
+        MarshallDownStructuresArray(pPrintProcessorInfoAligned, *pcReturned, 
PrintProcessorInfo1Marshalling.pInfo, 
PrintProcessorInfo1Marshalling.cbStructureSize, TRUE);
     }
     else
     {
diff --git a/win32ss/printing/base/winspool/jobs.c 
b/win32ss/printing/base/winspool/jobs.c
index 7551a30b33..e3cea6500c 100644
--- a/win32ss/printing/base/winspool/jobs.c
+++ b/win32ss/printing/base/winspool/jobs.c
@@ -2,59 +2,11 @@
  * PROJECT:     ReactOS Spooler API
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions for managing print jobs
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallUpAddJobInfo(PADDJOB_INFO_1W pAddJobInfo1)
-{
-    // Replace relative offset addresses in the output by absolute pointers.
-    pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path + 
(ULONG_PTR)pAddJobInfo1);
-}
-
-static void
-_MarshallUpJobInfo(PBYTE pJobInfo, DWORD Level)
-{
-    PJOB_INFO_1W pJobInfo1;
-    PJOB_INFO_2W pJobInfo2;
-
-    // Replace relative offset addresses in the output by absolute pointers.
-    if (Level == 1)
-    {
-        pJobInfo1 = (PJOB_INFO_1W)pJobInfo;
-        pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype + 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument + 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName + 
(ULONG_PTR)pJobInfo1);
-        pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName + 
(ULONG_PTR)pJobInfo1);
-
-        if (pJobInfo1->pStatus)
-            pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus + 
(ULONG_PTR)pJobInfo1);
-
-        pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName + 
(ULONG_PTR)pJobInfo1);
-    }
-    else if (Level == 2)
-    {
-        pJobInfo2 = (PJOB_INFO_2W)pJobInfo;
-        pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName + 
(ULONG_PTR)pJobInfo2);
-        pJobInfo2->pPrintProcessor = 
(PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor + (ULONG_PTR)pJobInfo2);
-
-        if (pJobInfo2->pParameters)
-            pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters 
+ (ULONG_PTR)pJobInfo2);
-
-        if (pJobInfo2->pStatus)
-            pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus + 
(ULONG_PTR)pJobInfo2);
-
-        pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName + 
(ULONG_PTR)pJobInfo2);
-    }
-}
+#include <marshalling/jobs.h>
 
 BOOL WINAPI
 AddJobA(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD 
pcbNeeded)
@@ -91,7 +43,10 @@ AddJobW(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD 
cbBuf, PDWORD pcbNeeded
     RpcEndExcept;
 
     if (dwErrorCode == ERROR_SUCCESS)
-        _MarshallUpAddJobInfo((PADDJOB_INFO_1W)pData);
+    {
+        // Replace relative offset addresses in the output by absolute 
pointers.
+        MarshallUpStructure(cbBuf, pData, AddJobInfo1Marshalling.pInfo, 
AddJobInfo1Marshalling.cbStructureSize, TRUE);
+    }
 
 Cleanup:
     SetLastError(dwErrorCode);
@@ -110,8 +65,6 @@ BOOL WINAPI
 EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE 
pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
 {
     DWORD dwErrorCode;
-    DWORD i;
-    PBYTE p = pJob;
     PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
 
     TRACE("EnumJobsW(%p, %lu, %lu, %lu, %p, %lu, %p, %p)\n", hPrinter, 
FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
@@ -136,15 +89,11 @@ EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, 
DWORD Level, PBYTE pJob
 
     if (dwErrorCode == ERROR_SUCCESS)
     {
-        // Replace relative offset addresses in the output by absolute 
pointers.
-        for (i = 0; i < *pcReturned; i++)
+        // Replace relative offset addresses in the output by absolute 
pointers for JOB_INFO_1W and JOB_INFO_2W.
+        if (Level <= 2)
         {
-            _MarshallUpJobInfo(p, Level);
-
-            if (Level == 1)
-                p += sizeof(JOB_INFO_1W);
-            else if (Level == 2)
-                p += sizeof(JOB_INFO_2W);
+            ASSERT(Level >= 1);
+            MarshallUpStructuresArray(cbBuf, pJob, *pcReturned, 
pJobInfoMarshalling[Level]->pInfo, pJobInfoMarshalling[Level]->cbStructureSize, 
TRUE);
         }
     }
 
@@ -190,7 +139,8 @@ GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE 
pJob, DWORD cbBuf, PDWO
     if (dwErrorCode == ERROR_SUCCESS)
     {
         // Replace relative offset addresses in the output by absolute 
pointers.
-        _MarshallUpJobInfo(pJob, Level);
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallUpStructure(cbBuf, pJob, pJobInfoMarshalling[Level]->pInfo, 
pJobInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
 
 Cleanup:
diff --git a/win32ss/printing/base/winspool/monitors.c 
b/win32ss/printing/base/winspool/monitors.c
index 4a36895126..18c6fd1d69 100644
--- a/win32ss/printing/base/winspool/monitors.c
+++ b/win32ss/printing/base/winspool/monitors.c
@@ -2,25 +2,11 @@
  * PROJECT:     ReactOS Spooler API
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Print Monitors
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallUpMonitorInfo(PBYTE pMonitorInfo, DWORD Level)
-{
-    PMONITOR_INFO_2W pMonitorInfo2 = (PMONITOR_INFO_2W)pMonitorInfo;        // 
MONITOR_INFO_1W is a subset of MONITOR_INFO_2W
-
-    // Replace relative offset addresses in the output by absolute pointers.
-    pMonitorInfo2->pName = (PWSTR)((ULONG_PTR)pMonitorInfo2->pName + 
(ULONG_PTR)pMonitorInfo2);
-
-    if (Level == 2)
-    {
-        pMonitorInfo2->pDLLName = (PWSTR)((ULONG_PTR)pMonitorInfo2->pDLLName + 
(ULONG_PTR)pMonitorInfo2);
-        pMonitorInfo2->pEnvironment = 
(PWSTR)((ULONG_PTR)pMonitorInfo2->pEnvironment + (ULONG_PTR)pMonitorInfo2);
-    }
-}
+#include <marshalling/monitors.h>
 
 BOOL WINAPI
 AddMonitorA(PSTR pName, DWORD Level, PBYTE pMonitors)
@@ -66,8 +52,6 @@ BOOL WINAPI
 EnumMonitorsW(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD 
pcbNeeded, PDWORD pcReturned)
 {
     DWORD dwErrorCode;
-    DWORD i;
-    PBYTE p = pMonitors;
 
     TRACE("EnumMonitorsW(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, 
pMonitors, cbBuf, pcbNeeded, pcReturned);
 
@@ -86,15 +70,8 @@ EnumMonitorsW(PWSTR pName, DWORD Level, PBYTE pMonitors, 
DWORD cbBuf, PDWORD pcb
     if (dwErrorCode == ERROR_SUCCESS)
     {
         // Replace relative offset addresses in the output by absolute 
pointers.
-        for (i = 0; i < *pcReturned; i++)
-        {
-            _MarshallUpMonitorInfo(p, Level);
-
-            if (Level == 1)
-                p += sizeof(MONITOR_INFO_1W);
-            else if (Level == 2)
-                p += sizeof(MONITOR_INFO_2W);
-        }
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallUpStructuresArray(cbBuf, pMonitors, *pcReturned, 
pMonitorInfoMarshalling[Level]->pInfo, 
pMonitorInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
 
     SetLastError(dwErrorCode);
diff --git a/win32ss/printing/base/winspool/ports.c 
b/win32ss/printing/base/winspool/ports.c
index 28977bdaeb..f243567407 100644
--- a/win32ss/printing/base/winspool/ports.c
+++ b/win32ss/printing/base/winspool/ports.c
@@ -2,25 +2,11 @@
  * PROJECT:     ReactOS Spooler API
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Ports
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
-
-static void
-_MarshallUpPortInfo(PBYTE pPortInfo, DWORD Level)
-{
-    PPORT_INFO_2W pPortInfo2 = (PPORT_INFO_2W)pPortInfo;         // 
PORT_INFO_1W is a subset of PORT_INFO_2W
-
-    // Replace relative offset addresses in the output by absolute pointers.
-    pPortInfo2->pPortName = (PWSTR)((ULONG_PTR)pPortInfo2->pPortName + 
(ULONG_PTR)pPortInfo2);
-
-    if (Level == 2)
-    {
-        pPortInfo2->pDescription = (PWSTR)((ULONG_PTR)pPortInfo2->pDescription 
+ (ULONG_PTR)pPortInfo2);
-        pPortInfo2->pMonitorName = (PWSTR)((ULONG_PTR)pPortInfo2->pMonitorName 
+ (ULONG_PTR)pPortInfo2);
-    }
-}
+#include <marshalling/ports.h>
 
 BOOL WINAPI
 AddPortA(PSTR pName, HWND hWnd, PSTR pMonitorName)
@@ -98,8 +84,6 @@ BOOL WINAPI
 EnumPortsW(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD 
pcbNeeded, PDWORD pcReturned)
 {
     DWORD dwErrorCode;
-    DWORD i;
-    PBYTE p = pPorts;
 
     TRACE("EnumPortsW(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pPorts, 
cbBuf, pcbNeeded, pcReturned);
 
@@ -118,15 +102,8 @@ EnumPortsW(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD 
cbBuf, PDWORD pcbNeeded
     if (dwErrorCode == ERROR_SUCCESS)
     {
         // Replace relative offset addresses in the output by absolute 
pointers.
-        for (i = 0; i < *pcReturned; i++)
-        {
-            _MarshallUpPortInfo(p, Level);
-
-            if (Level == 1)
-                p += sizeof(PORT_INFO_1W);
-            else if (Level == 2)
-                p += sizeof(PORT_INFO_2W);
-        }
+        ASSERT(Level >= 1 && Level <= 2);
+        MarshallUpStructuresArray(cbBuf, pPorts, *pcReturned, 
pPortInfoMarshalling[Level]->pInfo, 
pPortInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
 
     SetLastError(dwErrorCode);
diff --git a/win32ss/printing/base/winspool/printers.c 
b/win32ss/printing/base/winspool/printers.c
index 471db1339e..9c2d12b31f 100644
--- a/win32ss/printing/base/winspool/printers.c
+++ b/win32ss/printing/base/winspool/printers.c
@@ -2,10 +2,11 @@
  * PROJECT:     ReactOS Spooler API
  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
  * PURPOSE:     Functions related to Printers and printing
- * COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
 #include "precomp.h"
+#include <marshalling/printers.h>
 
 // Local Constants
 
@@ -14,114 +15,6 @@
 static const WCHAR wszWindowsKey[] = L"Software\\Microsoft\\Windows 
NT\\CurrentVersion\\Windows";
 static const WCHAR wszDeviceValue[] = L"Device";
 
-static void
-_MarshallUpPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
-{
-    // Replace relative offset addresses in the output by absolute pointers 
and advance to the next structure.
-    if (Level == 0)
-    {
-        PPRINTER_INFO_STRESS pPrinterInfo0 = 
(PPRINTER_INFO_STRESS)(*ppPrinterInfo);
-
-        pPrinterInfo0->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo0->pPrinterName + (ULONG_PTR)pPrinterInfo0);
-
-        if (pPrinterInfo0->pServerName)
-            pPrinterInfo0->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo0->pServerName + (ULONG_PTR)pPrinterInfo0);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_STRESS);
-    }
-    else if (Level == 1)
-    {
-        PPRINTER_INFO_1W pPrinterInfo1 = (PPRINTER_INFO_1W)(*ppPrinterInfo);
-
-        pPrinterInfo1->pName = (PWSTR)((ULONG_PTR)pPrinterInfo1->pName + 
(ULONG_PTR)pPrinterInfo1);
-        pPrinterInfo1->pDescription = 
(PWSTR)((ULONG_PTR)pPrinterInfo1->pDescription + (ULONG_PTR)pPrinterInfo1);
-        pPrinterInfo1->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo1->pComment + 
(ULONG_PTR)pPrinterInfo1);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_1W);
-    }
-    else if (Level == 2)
-    {
-        PPRINTER_INFO_2W pPrinterInfo2 = (PPRINTER_INFO_2W)(*ppPrinterInfo);
-
-        pPrinterInfo2->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pPrinterName + (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pShareName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pShareName + (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPortName 
+ (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDriverName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pDriverName + (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo2->pComment + 
(ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pLocation = (PWSTR)((ULONG_PTR)pPrinterInfo2->pLocation 
+ (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo2->pDevMode + (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pSepFile = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSepFile + 
(ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pPrintProcessor = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pPrintProcessor + (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pDatatype = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDatatype 
+ (ULONG_PTR)pPrinterInfo2);
-        pPrinterInfo2->pParameters = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pParameters + (ULONG_PTR)pPrinterInfo2);
-
-        if (pPrinterInfo2->pServerName)
-            pPrinterInfo2->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo2->pServerName + (ULONG_PTR)pPrinterInfo2);
-
-        if (pPrinterInfo2->pSecurityDescriptor)
-            pPrinterInfo2->pSecurityDescriptor = 
(PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo2->pSecurityDescriptor + 
(ULONG_PTR)pPrinterInfo2);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_2W);
-    }
-    else if (Level == 3)
-    {
-        PPRINTER_INFO_3 pPrinterInfo3 = (PPRINTER_INFO_3)(*ppPrinterInfo);
-
-        pPrinterInfo3->pSecurityDescriptor = 
(PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo3->pSecurityDescriptor + 
(ULONG_PTR)pPrinterInfo3);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_3);
-    }
-    else if (Level == 4)
-    {
-        PPRINTER_INFO_4W pPrinterInfo4 = (PPRINTER_INFO_4W)(*ppPrinterInfo);
-
-        pPrinterInfo4->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo4->pPrinterName + (ULONG_PTR)pPrinterInfo4);
-
-        if (pPrinterInfo4->pServerName)
-            pPrinterInfo4->pServerName = 
(PWSTR)((ULONG_PTR)pPrinterInfo4->pServerName + (ULONG_PTR)pPrinterInfo4);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_4W);
-    }
-    else if (Level == 5)
-    {
-        PPRINTER_INFO_5W pPrinterInfo5 = (PPRINTER_INFO_5W)(*ppPrinterInfo);
-
-        pPrinterInfo5->pPrinterName = 
(PWSTR)((ULONG_PTR)pPrinterInfo5->pPrinterName + (ULONG_PTR)pPrinterInfo5);
-        pPrinterInfo5->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPortName 
+ (ULONG_PTR)pPrinterInfo5);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_5W);
-    }
-    else if (Level == 6)
-    {
-        *ppPrinterInfo += sizeof(PRINTER_INFO_6);
-    }
-    else if (Level == 7)
-    {
-        PPRINTER_INFO_7W pPrinterInfo7 = (PPRINTER_INFO_7W)(*ppPrinterInfo);
-
-        if (pPrinterInfo7->pszObjectGUID)
-            pPrinterInfo7->pszObjectGUID = 
(PWSTR)((ULONG_PTR)pPrinterInfo7->pszObjectGUID + (ULONG_PTR)pPrinterInfo7);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_7W);
-    }
-    else if (Level == 8)
-    {
-        PPRINTER_INFO_8W pPrinterInfo8 = (PPRINTER_INFO_8W)(*ppPrinterInfo);
-
-        pPrinterInfo8->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo8->pDevMode + (ULONG_PTR)pPrinterInfo8);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_8W);
-    }
-    else if (Level == 9)
-    {
-        PPRINTER_INFO_9W pPrinterInfo9 = (PPRINTER_INFO_9W)(*ppPrinterInfo);
-
-        pPrinterInfo9->pDevMode = 
(PDEVMODEW)((ULONG_PTR)pPrinterInfo9->pDevMode + (ULONG_PTR)pPrinterInfo9);
-
-        *ppPrinterInfo += sizeof(PRINTER_INFO_9W);
-    }
-}
-
 static DWORD
 _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, 
PADDJOB_INFO_1W pAddJobInfo1)
 {
@@ -448,11 +341,9 @@ EnumPrintersW(DWORD Flags, PWSTR Name, DWORD Level, PBYTE 
pPrinterEnum, DWORD cb
 
     if (dwErrorCode == ERROR_SUCCESS)
     {
-        DWORD i;
-        PBYTE p = pPrinterEnum;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallUpPrinterInfo(&p, Level);
+        // Replace relative offset addresses in the output by absolute 
pointers.
+        ASSERT(Level <= 9);
+        MarshallUpStructuresArray(cbBuf, pPrinterEnum, *pcReturned, 
pPrinterInfoMarshalling[Level]->pInfo, 
pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
 
 Cleanup:
@@ -665,8 +556,9 @@ GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, 
DWORD cbBuf, LPDWORD
 
     if (dwErrorCode == ERROR_SUCCESS)
     {
-        PBYTE p = pPrinter;
-        _MarshallUpPrinterInfo(&p, Level);
+        // Replace relative offset addresses in the output by absolute 
pointers.
+        ASSERT(Level <= 9);
+        MarshallUpStructure(cbBuf, pPrinter, 
pPrinterInfoMarshalling[Level]->pInfo, 
pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
     }
 
 Cleanup:
diff --git a/win32ss/printing/base/winspool/printprocessors.c 
b/win32ss/printing/base/winspool/printprocessors.c
index 406297de6f..9283eeb788 100644
--- a/win32ss/printing/base/winspool/printprocessors.c
+++ b/win32ss/printing/base/winspool/printprocessors.c
@@ -2,30 +2,13 @@
 * PROJECT:     ReactOS Spooler API
 * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
 * PURPOSE:     Functions related to Print Processors
-* COPYRIGHT:   Copyright 2015-2017 Colin Finck (co...@reactos.org)
+* COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
 */
 
 #include "precomp.h"
+#include <marshalling/printprocessors.h>
 #include <prtprocenv.h>
 
-static void
-_MarshallUpDatatypesInfo(PDATATYPES_INFO_1W* ppDatatypesInfo1)
-{
-    // Replace relative offset addresses in the output by absolute pointers.
-    PDATATYPES_INFO_1W pDatatypesInfo1 = *ppDatatypesInfo1;
-    pDatatypesInfo1->pName = (PWSTR)((ULONG_PTR)pDatatypesInfo1->pName + 
(ULONG_PTR)pDatatypesInfo1);
-    *ppDatatypesInfo1 += sizeof(DATATYPES_INFO_1W);
-}
-
-static void
-_MarshallUpPrintProcessorInfo(PPRINTPROCESSOR_INFO_1W* ppPrintProcessorInfo1)
-{
-    // Replace relative offset addresses in the output by absolute pointers.
-    PPRINTPROCESSOR_INFO_1W pPrintProcessorInfo1 = *ppPrintProcessorInfo1;
-    pPrintProcessorInfo1->pName = 
(PWSTR)((ULONG_PTR)pPrintProcessorInfo1->pName + 
(ULONG_PTR)pPrintProcessorInfo1);
-    *ppPrintProcessorInfo1 += sizeof(PRINTPROCESSOR_INFO_1W);
-}
-
 BOOL WINAPI
 AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR 
pPrintProcessorName)
 {
@@ -85,7 +68,7 @@ EnumPrintProcessorDatatypesW(PWSTR pName, LPWSTR 
pPrintProcessorName, DWORD Leve
     {
         dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, 
pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
     }
-        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
         dwErrorCode = RpcExceptionCode();
         ERR("_RpcEnumPrintProcessorDatatypes failed with exception code 
%lu!\n", dwErrorCode);
@@ -94,11 +77,8 @@ EnumPrintProcessorDatatypesW(PWSTR pName, LPWSTR 
pPrintProcessorName, DWORD Leve
 
     if (dwErrorCode == ERROR_SUCCESS)
     {
-        DWORD i;
-        PDATATYPES_INFO_1W p = (PDATATYPES_INFO_1W)pDatatypes;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallUpDatatypesInfo(&p);
+        // Replace relative offset addresses in the output by absolute 
pointers.
+        MarshallUpStructuresArray(cbBuf, pDatatypes, *pcReturned, 
DatatypesInfo1Marshalling.pInfo, DatatypesInfo1Marshalling.cbStructureSize, 
TRUE);
     }
 
 Cleanup:
@@ -130,7 +110,7 @@ EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD 
Level, PBYTE pPrintP
     {
         dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, 
pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
     }
-        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
         dwErrorCode = RpcExceptionCode();
     }
@@ -138,11 +118,8 @@ EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, 
DWORD Level, PBYTE pPrintP
 
     if (dwErrorCode == ERROR_SUCCESS)
     {
-        DWORD i;
-        PPRINTPROCESSOR_INFO_1W p = 
(PPRINTPROCESSOR_INFO_1W)pPrintProcessorInfo;
-
-        for (i = 0; i < *pcReturned; i++)
-            _MarshallUpPrintProcessorInfo(&p);
+        // Replace relative offset addresses in the output by absolute 
pointers.
+        MarshallUpStructuresArray(cbBuf, pPrintProcessorInfo, *pcReturned, 
PrintProcessorInfo1Marshalling.pInfo, 
PrintProcessorInfo1Marshalling.cbStructureSize, TRUE);
     }
 
     SetLastError(dwErrorCode);
@@ -250,7 +227,7 @@ GetPrintProcessorDirectoryW(PWSTR pName, PWSTR 
pEnvironment, DWORD Level, PBYTE
     {
         dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, 
Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
     }
-        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
         dwErrorCode = RpcExceptionCode();
     }
diff --git a/win32ss/printing/include/marshalling/jobs.h 
b/win32ss/printing/include/marshalling/jobs.h
new file mode 100644
index 0000000000..d38d4109e9
--- /dev/null
+++ b/win32ss/printing/include/marshalling/jobs.h
@@ -0,0 +1,71 @@
+/*
+ * PROJECT:     ReactOS Printing Stack Marshalling Functions
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Marshalling definitions for ADDJOB_INFO_* and JOB_INFO_*
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
+ */
+
+static const MARSHALLING AddJobInfo1Marshalling = {
+    sizeof(ADDJOB_INFO_1W),
+    {
+        { FIELD_OFFSET(ADDJOB_INFO_1W, Path), RTL_FIELD_SIZE(ADDJOB_INFO_1W, 
Path), RTL_FIELD_SIZE(ADDJOB_INFO_1W, Path), TRUE },
+        { FIELD_OFFSET(ADDJOB_INFO_1W, JobId), RTL_FIELD_SIZE(ADDJOB_INFO_1W, 
JobId), RTL_FIELD_SIZE(ADDJOB_INFO_1W, JobId), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING JobInfo1Marshalling = {
+    sizeof(JOB_INFO_1W),
+    {
+        { FIELD_OFFSET(JOB_INFO_1W, JobId), RTL_FIELD_SIZE(JOB_INFO_1W, 
JobId), RTL_FIELD_SIZE(JOB_INFO_1W, JobId), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, pPrinterName), RTL_FIELD_SIZE(JOB_INFO_1W, 
pPrinterName), RTL_FIELD_SIZE(JOB_INFO_1W, pPrinterName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, pMachineName), RTL_FIELD_SIZE(JOB_INFO_1W, 
pMachineName), RTL_FIELD_SIZE(JOB_INFO_1W, pMachineName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, pUserName), RTL_FIELD_SIZE(JOB_INFO_1W, 
pUserName), RTL_FIELD_SIZE(JOB_INFO_1W, pUserName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, pDocument), RTL_FIELD_SIZE(JOB_INFO_1W, 
pDocument), RTL_FIELD_SIZE(JOB_INFO_1W, pDocument), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, pDatatype), RTL_FIELD_SIZE(JOB_INFO_1W, 
pDatatype), RTL_FIELD_SIZE(JOB_INFO_1W, pDatatype), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, pStatus), RTL_FIELD_SIZE(JOB_INFO_1W, 
pStatus), RTL_FIELD_SIZE(JOB_INFO_1W, pStatus), TRUE },
+        { FIELD_OFFSET(JOB_INFO_1W, Status), RTL_FIELD_SIZE(JOB_INFO_1W, 
Status), RTL_FIELD_SIZE(JOB_INFO_1W, Status), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, Priority), RTL_FIELD_SIZE(JOB_INFO_1W, 
Priority), RTL_FIELD_SIZE(JOB_INFO_1W, Priority), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, Position), RTL_FIELD_SIZE(JOB_INFO_1W, 
Position), RTL_FIELD_SIZE(JOB_INFO_1W, Position), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, TotalPages), RTL_FIELD_SIZE(JOB_INFO_1W, 
TotalPages), RTL_FIELD_SIZE(JOB_INFO_1W, TotalPages), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, PagesPrinted), RTL_FIELD_SIZE(JOB_INFO_1W, 
PagesPrinted), RTL_FIELD_SIZE(JOB_INFO_1W, PagesPrinted), FALSE },
+        { FIELD_OFFSET(JOB_INFO_1W, Submitted), RTL_FIELD_SIZE(JOB_INFO_1W, 
Submitted), sizeof(WORD), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING JobInfo2Marshalling = {
+    sizeof(JOB_INFO_2W),
+    {
+        { FIELD_OFFSET(JOB_INFO_2W, JobId), RTL_FIELD_SIZE(JOB_INFO_2W, 
JobId), RTL_FIELD_SIZE(JOB_INFO_2W, JobId), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, pPrinterName), RTL_FIELD_SIZE(JOB_INFO_2W, 
pPrinterName), RTL_FIELD_SIZE(JOB_INFO_2W, pPrinterName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pMachineName), RTL_FIELD_SIZE(JOB_INFO_2W, 
pMachineName), RTL_FIELD_SIZE(JOB_INFO_2W, pMachineName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pUserName), RTL_FIELD_SIZE(JOB_INFO_2W, 
pUserName), RTL_FIELD_SIZE(JOB_INFO_2W, pUserName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pDocument), RTL_FIELD_SIZE(JOB_INFO_2W, 
pDocument), RTL_FIELD_SIZE(JOB_INFO_2W, pDocument), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pNotifyName), RTL_FIELD_SIZE(JOB_INFO_2W, 
pNotifyName), RTL_FIELD_SIZE(JOB_INFO_2W, pNotifyName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pDatatype), RTL_FIELD_SIZE(JOB_INFO_2W, 
pDatatype), RTL_FIELD_SIZE(JOB_INFO_2W, pDatatype), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pPrintProcessor), 
RTL_FIELD_SIZE(JOB_INFO_2W, pPrintProcessor), RTL_FIELD_SIZE(JOB_INFO_2W, 
pPrintProcessor), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pParameters), RTL_FIELD_SIZE(JOB_INFO_2W, 
pParameters), RTL_FIELD_SIZE(JOB_INFO_2W, pParameters), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pDriverName), RTL_FIELD_SIZE(JOB_INFO_2W, 
pDriverName), RTL_FIELD_SIZE(JOB_INFO_2W, pDriverName), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pDevMode), RTL_FIELD_SIZE(JOB_INFO_2W, 
pDevMode), RTL_FIELD_SIZE(JOB_INFO_2W, pDevMode), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pStatus), RTL_FIELD_SIZE(JOB_INFO_2W, 
pStatus), RTL_FIELD_SIZE(JOB_INFO_2W, pStatus), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, pSecurityDescriptor), 
RTL_FIELD_SIZE(JOB_INFO_2W, pSecurityDescriptor), RTL_FIELD_SIZE(JOB_INFO_2W, 
pSecurityDescriptor), TRUE },
+        { FIELD_OFFSET(JOB_INFO_2W, Status), RTL_FIELD_SIZE(JOB_INFO_2W, 
Status), RTL_FIELD_SIZE(JOB_INFO_2W, Status), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, Priority), RTL_FIELD_SIZE(JOB_INFO_2W, 
Priority), RTL_FIELD_SIZE(JOB_INFO_2W, Priority), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, Position), RTL_FIELD_SIZE(JOB_INFO_2W, 
Position), RTL_FIELD_SIZE(JOB_INFO_2W, Position), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, StartTime), RTL_FIELD_SIZE(JOB_INFO_2W, 
StartTime), RTL_FIELD_SIZE(JOB_INFO_2W, StartTime), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, UntilTime), RTL_FIELD_SIZE(JOB_INFO_2W, 
UntilTime), RTL_FIELD_SIZE(JOB_INFO_2W, UntilTime), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, TotalPages), RTL_FIELD_SIZE(JOB_INFO_2W, 
TotalPages), RTL_FIELD_SIZE(JOB_INFO_2W, TotalPages), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, Size), RTL_FIELD_SIZE(JOB_INFO_2W, Size), 
RTL_FIELD_SIZE(JOB_INFO_2W, Size), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, Submitted), RTL_FIELD_SIZE(JOB_INFO_2W, 
Submitted), sizeof(WORD), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, Time), RTL_FIELD_SIZE(JOB_INFO_2W, Time), 
RTL_FIELD_SIZE(JOB_INFO_2W, Time), FALSE },
+        { FIELD_OFFSET(JOB_INFO_2W, PagesPrinted), RTL_FIELD_SIZE(JOB_INFO_2W, 
PagesPrinted), RTL_FIELD_SIZE(JOB_INFO_2W, PagesPrinted), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING* pJobInfoMarshalling[] = {
+    NULL,
+    &JobInfo1Marshalling,
+    &JobInfo2Marshalling
+};
diff --git a/win32ss/printing/include/marshalling/monitors.h 
b/win32ss/printing/include/marshalling/monitors.h
new file mode 100644
index 0000000000..555272b9a6
--- /dev/null
+++ b/win32ss/printing/include/marshalling/monitors.h
@@ -0,0 +1,30 @@
+/*
+ * PROJECT:     ReactOS Printing Stack Marshalling Functions
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Marshalling definitions for MONITOR_INFO_*
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
+ */
+
+static const MARSHALLING MonitorInfo1Marshalling = {
+    sizeof(MONITOR_INFO_1W),
+    {
+        { FIELD_OFFSET(MONITOR_INFO_1W, pName), 
RTL_FIELD_SIZE(MONITOR_INFO_1W, pName), RTL_FIELD_SIZE(MONITOR_INFO_1W, pName), 
TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING MonitorInfo2Marshalling = {
+    sizeof(MONITOR_INFO_2W),
+    {
+        { FIELD_OFFSET(MONITOR_INFO_2W, pName), 
RTL_FIELD_SIZE(MONITOR_INFO_2W, pName), RTL_FIELD_SIZE(MONITOR_INFO_2W, pName), 
TRUE },
+        { FIELD_OFFSET(MONITOR_INFO_2W, pEnvironment), 
RTL_FIELD_SIZE(MONITOR_INFO_2W, pEnvironment), RTL_FIELD_SIZE(MONITOR_INFO_2W, 
pEnvironment), TRUE },
+        { FIELD_OFFSET(MONITOR_INFO_2W, pDLLName), 
RTL_FIELD_SIZE(MONITOR_INFO_2W, pDLLName), RTL_FIELD_SIZE(MONITOR_INFO_2W, 
pDLLName), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING* pMonitorInfoMarshalling[] = {
+    NULL,
+    &MonitorInfo1Marshalling,
+    &MonitorInfo2Marshalling
+};
diff --git a/win32ss/printing/include/marshalling/ports.h 
b/win32ss/printing/include/marshalling/ports.h
index b53eb31742..29f22273c8 100644
--- a/win32ss/printing/include/marshalling/ports.h
+++ b/win32ss/printing/include/marshalling/ports.h
@@ -5,7 +5,7 @@
  * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
  */
 
-const MARSHALLING PortInfo1Marshalling = {
+static 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 },
@@ -13,7 +13,7 @@ const MARSHALLING PortInfo1Marshalling = {
     }
 };
 
-const MARSHALLING PortInfo2Marshalling = {
+static 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 },
@@ -24,3 +24,9 @@ const MARSHALLING PortInfo2Marshalling = {
         { MAXDWORD, 0, 0, FALSE }
     }
 };
+
+static const MARSHALLING* pPortInfoMarshalling[] = {
+    NULL,
+    &PortInfo1Marshalling,
+    &PortInfo2Marshalling
+};
diff --git a/win32ss/printing/include/marshalling/printers.h 
b/win32ss/printing/include/marshalling/printers.h
new file mode 100644
index 0000000000..d4727434d6
--- /dev/null
+++ b/win32ss/printing/include/marshalling/printers.h
@@ -0,0 +1,157 @@
+/*
+ * PROJECT:     ReactOS Printing Stack Marshalling Functions
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Marshalling definitions for PRINTER_INFO_*
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
+ */
+
+static const MARSHALLING PrinterInfoStressMarshalling = {
+    sizeof(PRINTER_INFO_STRESS),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, pPrinterName), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, pPrinterName), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, pPrinterName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, pServerName), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, pServerName), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, pServerName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cJobs), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cJobs), RTL_FIELD_SIZE(PRINTER_INFO_STRESS, 
cJobs), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cTotalJobs), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalJobs), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalJobs), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cTotalBytes), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalBytes), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalBytes), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, stUpTime), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, stUpTime), sizeof(WORD), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, MaxcRef), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, MaxcRef), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, MaxcRef), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cTotalPagesPrinted), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalPagesPrinted), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cTotalPagesPrinted), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwGetVersion), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwGetVersion), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwGetVersion), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, fFreeBuild), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, fFreeBuild), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, fFreeBuild), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cSpooling), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cSpooling), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cSpooling), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cMaxSpooling), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cMaxSpooling), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cMaxSpooling), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cRef), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cRef), RTL_FIELD_SIZE(PRINTER_INFO_STRESS, 
cRef), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cErrorOutOfPaper), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cErrorOutOfPaper), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cErrorOutOfPaper), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cErrorNotReady), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cErrorNotReady), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cErrorNotReady), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cJobError), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cJobError), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cJobError), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwNumberOfProcessors), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwNumberOfProcessors), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwNumberOfProcessors), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwProcessorType), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwProcessorType), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwProcessorType), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwHighPartTotalBytes), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwHighPartTotalBytes), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwHighPartTotalBytes), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cChangeID), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cChangeID), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cChangeID), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwLastError), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwLastError), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwLastError), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, Status), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, Status), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, Status), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cEnumerateNetworkPrinters), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cEnumerateNetworkPrinters), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cEnumerateNetworkPrinters), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cAddNetPrinters), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cAddNetPrinters), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cAddNetPrinters), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, wProcessorArchitecture), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, wProcessorArchitecture), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, wProcessorArchitecture), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, wProcessorLevel), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, wProcessorLevel), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, wProcessorLevel), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, cRefIC), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cRefIC), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, cRefIC), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwReserved2), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwReserved2), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwReserved2), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_STRESS, dwReserved3), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwReserved3), 
RTL_FIELD_SIZE(PRINTER_INFO_STRESS, dwReserved3), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo1Marshalling = {
+    sizeof(PRINTER_INFO_1W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_1W, Flags), 
RTL_FIELD_SIZE(PRINTER_INFO_1W, Flags), RTL_FIELD_SIZE(PRINTER_INFO_1W, Flags), 
FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_1W, pDescription), 
RTL_FIELD_SIZE(PRINTER_INFO_1W, pDescription), RTL_FIELD_SIZE(PRINTER_INFO_1W, 
pDescription), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_1W, pName), 
RTL_FIELD_SIZE(PRINTER_INFO_1W, pName), RTL_FIELD_SIZE(PRINTER_INFO_1W, pName), 
TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_1W, pComment), 
RTL_FIELD_SIZE(PRINTER_INFO_1W, pComment), RTL_FIELD_SIZE(PRINTER_INFO_1W, 
pComment), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo2Marshalling = {
+    sizeof(PRINTER_INFO_2W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_2W, pServerName), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pServerName), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pServerName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pPrinterName), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pPrinterName), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pPrinterName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pShareName), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pShareName), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pShareName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pPortName), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pPortName), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pPortName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pDriverName), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pDriverName), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pDriverName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pComment), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pComment), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pComment), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pLocation), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pLocation), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pLocation), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pDevMode), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pDevMode), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pDevMode), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pSepFile), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pSepFile), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pSepFile), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pPrintProcessor), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pPrintProcessor), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pPrintProcessor), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pDatatype), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pDatatype), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pDatatype), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pParameters), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pParameters), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
pParameters), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, pSecurityDescriptor), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pSecurityDescriptor), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, pSecurityDescriptor), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, Attributes), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, Attributes), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
Attributes), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, Priority), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, Priority), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
Priority), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, DefaultPriority), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, DefaultPriority), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, DefaultPriority), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, StartTime), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, StartTime), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
StartTime), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, UntilTime), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, UntilTime), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
UntilTime), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, Status), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, Status), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
Status), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, cJobs), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, cJobs), RTL_FIELD_SIZE(PRINTER_INFO_2W, cJobs), 
FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_2W, AveragePPM), 
RTL_FIELD_SIZE(PRINTER_INFO_2W, AveragePPM), RTL_FIELD_SIZE(PRINTER_INFO_2W, 
AveragePPM), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo3Marshalling = {
+    sizeof(PRINTER_INFO_3),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_3, pSecurityDescriptor), 
RTL_FIELD_SIZE(PRINTER_INFO_3, pSecurityDescriptor), 
RTL_FIELD_SIZE(PRINTER_INFO_3, pSecurityDescriptor), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo4Marshalling = {
+    sizeof(PRINTER_INFO_4W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_4W, pPrinterName), 
RTL_FIELD_SIZE(PRINTER_INFO_4W, pPrinterName), RTL_FIELD_SIZE(PRINTER_INFO_4W, 
pPrinterName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_4W, pServerName), 
RTL_FIELD_SIZE(PRINTER_INFO_4W, pServerName), RTL_FIELD_SIZE(PRINTER_INFO_4W, 
pServerName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_4W, Attributes), 
RTL_FIELD_SIZE(PRINTER_INFO_4W, Attributes), RTL_FIELD_SIZE(PRINTER_INFO_4W, 
Attributes), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo5Marshalling = {
+    sizeof(PRINTER_INFO_5W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_5W, pPrinterName), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, pPrinterName), RTL_FIELD_SIZE(PRINTER_INFO_5W, 
pPrinterName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_5W, pPortName), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, pPortName), RTL_FIELD_SIZE(PRINTER_INFO_5W, 
pPortName), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_5W, Attributes), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, Attributes), RTL_FIELD_SIZE(PRINTER_INFO_5W, 
Attributes), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_5W, DeviceNotSelectedTimeout), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, DeviceNotSelectedTimeout), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, DeviceNotSelectedTimeout), FALSE },
+        { FIELD_OFFSET(PRINTER_INFO_5W, TransmissionRetryTimeout), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, TransmissionRetryTimeout), 
RTL_FIELD_SIZE(PRINTER_INFO_5W, TransmissionRetryTimeout), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo6Marshalling = {
+    sizeof(PRINTER_INFO_6),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_6, dwStatus), 
RTL_FIELD_SIZE(PRINTER_INFO_6, dwStatus), RTL_FIELD_SIZE(PRINTER_INFO_6, 
dwStatus), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo7Marshalling = {
+    sizeof(PRINTER_INFO_7W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_7W, pszObjectGUID), 
RTL_FIELD_SIZE(PRINTER_INFO_7W, pszObjectGUID), RTL_FIELD_SIZE(PRINTER_INFO_7W, 
pszObjectGUID), TRUE },
+        { FIELD_OFFSET(PRINTER_INFO_7W, dwAction), 
RTL_FIELD_SIZE(PRINTER_INFO_7W, dwAction), RTL_FIELD_SIZE(PRINTER_INFO_7W, 
dwAction), FALSE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo8Marshalling = {
+    sizeof(PRINTER_INFO_8W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_8W, pDevMode), 
RTL_FIELD_SIZE(PRINTER_INFO_8W, pDevMode), RTL_FIELD_SIZE(PRINTER_INFO_8W, 
pDevMode), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrinterInfo9Marshalling = {
+    sizeof(PRINTER_INFO_9W),
+    {
+        { FIELD_OFFSET(PRINTER_INFO_9W, pDevMode), 
RTL_FIELD_SIZE(PRINTER_INFO_9W, pDevMode), RTL_FIELD_SIZE(PRINTER_INFO_9W, 
pDevMode), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING* pPrinterInfoMarshalling[] = {
+    &PrinterInfoStressMarshalling,
+    &PrinterInfo1Marshalling,
+    &PrinterInfo2Marshalling,
+    &PrinterInfo3Marshalling,
+    &PrinterInfo4Marshalling,
+    &PrinterInfo5Marshalling,
+    &PrinterInfo6Marshalling,
+    &PrinterInfo7Marshalling,
+    &PrinterInfo8Marshalling,
+    &PrinterInfo9Marshalling
+};
diff --git a/win32ss/printing/include/marshalling/printprocessors.h 
b/win32ss/printing/include/marshalling/printprocessors.h
new file mode 100644
index 0000000000..6b20c7f3da
--- /dev/null
+++ b/win32ss/printing/include/marshalling/printprocessors.h
@@ -0,0 +1,22 @@
+/*
+ * PROJECT:     ReactOS Printing Stack Marshalling Functions
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Marshalling definitions for DATATYPES_INFO_* and 
PRINTPROCESSOR_INFO_*
+ * COPYRIGHT:   Copyright 2015-2018 Colin Finck (co...@reactos.org)
+ */
+
+static const MARSHALLING DatatypesInfo1Marshalling = {
+    sizeof(DATATYPES_INFO_1W),
+    {
+        { FIELD_OFFSET(DATATYPES_INFO_1W, pName), 
RTL_FIELD_SIZE(DATATYPES_INFO_1W, pName), RTL_FIELD_SIZE(DATATYPES_INFO_1W, 
pName), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};
+
+static const MARSHALLING PrintProcessorInfo1Marshalling = {
+    sizeof(PRINTPROCESSOR_INFO_1W),
+    {
+        { FIELD_OFFSET(PRINTPROCESSOR_INFO_1W, pName), 
RTL_FIELD_SIZE(PRINTPROCESSOR_INFO_1W, pName), 
RTL_FIELD_SIZE(PRINTPROCESSOR_INFO_1W, pName), TRUE },
+        { MAXDWORD, 0, 0, FALSE }
+    }
+};

Reply via email to