diff --git a/modules/rostests/apitests/spoolss/CMakeLists.txt b/modules/rostests/apitests/spoolss/CMakeLists.txt index f838489dc4f..d746573b247 100644 --- a/modules/rostests/apitests/spoolss/CMakeLists.txt +++ b/modules/rostests/apitests/spoolss/CMakeLists.txt @@ -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 diff --git a/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c b/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c new file mode 100644 index 00000000000..cd057074ecc --- /dev/null +++ b/modules/rostests/apitests/spoolss/MarshallDownStructuresArray.c @@ -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 + +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include + +#include +#include +#include + +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); +} diff --git a/modules/rostests/apitests/spoolss/MarshallUpStructuresArray.c b/modules/rostests/apitests/spoolss/MarshallUpStructuresArray.c new file mode 100644 index 00000000000..d47c8b21dd7 --- /dev/null +++ b/modules/rostests/apitests/spoolss/MarshallUpStructuresArray.c @@ -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 + +#define WIN32_NO_STATUS +#include +#include +#include + +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. +} diff --git a/modules/rostests/apitests/spoolss/testlist.c b/modules/rostests/apitests/spoolss/testlist.c index 67b885cbd67..f37cc351df0 100644 --- a/modules/rostests/apitests/spoolss/testlist.c +++ b/modules/rostests/apitests/spoolss/testlist.c @@ -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 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 }, diff --git a/win32ss/printing/base/marshalling.c b/win32ss/printing/base/marshalling.c new file mode 100644 index 00000000000..bdca0250760 --- /dev/null +++ b/win32ss/printing/base/marshalling.c @@ -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; +} diff --git a/win32ss/printing/base/spoolss/CMakeLists.txt b/win32ss/printing/base/spoolss/CMakeLists.txt index f7ef3f273d7..12d6649e63f 100644 --- a/win32ss/printing/base/spoolss/CMakeLists.txt +++ b/win32ss/printing/base/spoolss/CMakeLists.txt @@ -2,6 +2,7 @@ spec2def(spoolss.dll spoolss.spec ADD_IMPORTLIB) list(APPEND SOURCE + ../marshalling.c context.c jobs.c main.c diff --git a/win32ss/printing/base/spoolss/precomp.h b/win32ss/printing/base/spoolss/precomp.h index 6ec7633c2ba..3a859aa2d7c 100644 --- a/win32ss/printing/base/spoolss/precomp.h +++ b/win32ss/printing/base/spoolss/precomp.h @@ -18,6 +18,7 @@ #include #include +#include #include WINE_DEFAULT_DEBUG_CHANNEL(spoolss); diff --git a/win32ss/printing/base/spoolss/spoolss.spec b/win32ss/printing/base/spoolss/spoolss.spec index 172ab0b151c..87e136c9a41 100644 --- a/win32ss/printing/base/spoolss/spoolss.spec +++ b/win32ss/printing/base/spoolss/spoolss.spec @@ -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 diff --git a/win32ss/printing/base/spoolss/tools.c b/win32ss/printing/base/spoolss/tools.c index e6545bdf283..7b8410a41a1 100644 --- a/win32ss/printing/base/spoolss/tools.c +++ b/win32ss/printing/base/spoolss/tools.c @@ -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 * diff --git a/win32ss/printing/base/spoolsv/precomp.h b/win32ss/printing/base/spoolsv/precomp.h index f7d09e1e3df..5ab518a43c6 100644 --- a/win32ss/printing/base/spoolsv/precomp.h +++ b/win32ss/printing/base/spoolsv/precomp.h @@ -17,8 +17,10 @@ #include #include #include +#include #include +#include #include WINE_DEFAULT_DEBUG_CHANNEL(spoolsv); diff --git a/win32ss/printing/base/winspool/CMakeLists.txt b/win32ss/printing/base/winspool/CMakeLists.txt index b4dcf8a163b..aea2d85f3de 100644 --- a/win32ss/printing/base/winspool/CMakeLists.txt +++ b/win32ss/printing/base/winspool/CMakeLists.txt @@ -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 diff --git a/win32ss/printing/base/winspool/precomp.h b/win32ss/printing/base/winspool/precomp.h index 9cf5be3e905..cbfaac933ca 100644 --- a/win32ss/printing/base/winspool/precomp.h +++ b/win32ss/printing/base/winspool/precomp.h @@ -15,8 +15,10 @@ #include #include #include +#include #include +#include #include WINE_DEFAULT_DEBUG_CHANNEL(winspool); diff --git a/win32ss/printing/include/marshalling/marshalling.h b/win32ss/printing/include/marshalling/marshalling.h new file mode 100644 index 00000000000..d82db43a2b0 --- /dev/null +++ b/win32ss/printing/include/marshalling/marshalling.h @@ -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 diff --git a/win32ss/printing/include/marshalling/ports.h b/win32ss/printing/include/marshalling/ports.h new file mode 100644 index 00000000000..b53eb317420 --- /dev/null +++ b/win32ss/printing/include/marshalling/ports.h @@ -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 } + } +}; diff --git a/win32ss/printing/include/spoolss.h b/win32ss/printing/include/spoolss.h index a841fb29e02..7e1c132dcfe 100644 --- a/win32ss/printing/include/spoolss.h +++ b/win32ss/printing/include/spoolss.h @@ -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);