ReactOS  0.4.15-dev-2144-g2282205
MarshallDownStructuresArray.c File Reference
#include <apitest.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winspool.h>
#include <ndk/rtlfuncs.h>
#include <spoolss.h>
#include <marshalling/marshalling.h>
#include <marshalling/ports.h>
Include dependency graph for MarshallDownStructuresArray.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define INVALID_POINTER   ((PVOID)(ULONG_PTR)0xdeadbeefdeadbeefULL)
 

Functions

 START_TEST (MarshallDownStructuresArray)
 

Macro Definition Documentation

◆ INVALID_POINTER

#define INVALID_POINTER   ((PVOID)(ULONG_PTR)0xdeadbeefdeadbeefULL)

Definition at line 21 of file MarshallDownStructuresArray.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 10 of file MarshallDownStructuresArray.c.

Function Documentation

◆ START_TEST()

START_TEST ( MarshallDownStructuresArray  )

Definition at line 23 of file MarshallDownStructuresArray.c.

24 {
25  const DWORD cElements = 2;
26  const DWORD dwPortInfo2Offsets[] = {
27  FIELD_OFFSET(PORT_INFO_2W, pPortName),
28  FIELD_OFFSET(PORT_INFO_2W, pMonitorName),
29  FIELD_OFFSET(PORT_INFO_2W, pDescription),
30  MAXDWORD
31  };
32 
33  PPORT_INFO_2W pPortInfo2;
34  PPORT_INFO_2W pPortInfo2Copy;
35  PPORT_INFO_2W pPortInfo2Test;
36  PBYTE pPortInfoEnd;
37  PCWSTR pwszStrings[] = { L"PortName", L"MonitorName", L"Description" };
38  SIZE_T cbPortInfo2Size = cElements * (sizeof(PORT_INFO_2W) + (wcslen(pwszStrings[0]) + 1 + wcslen(pwszStrings[1]) + 1 + wcslen(pwszStrings[2]) + 1) * sizeof(WCHAR));
39  DWORD fPortType = 1337;
40  DWORD Reserved = 42;
41 
42  // Setting cElements to zero should yield success.
43  SetLastError(0xDEADBEEF);
44  ok(MarshallDownStructuresArray(NULL, 0, NULL, 0, FALSE), "MarshallDownStructuresArray returns FALSE!\n");
45  ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
46 
47  // Setting cElements non-zero should fail with ERROR_INVALID_PARAMETER.
48  SetLastError(0xDEADBEEF);
49  ok(!MarshallDownStructuresArray(NULL, 1, NULL, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
50  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
51 
52  // This is triggered by both pStructuresArray and pInfo.
53  SetLastError(0xDEADBEEF);
54  ok(!MarshallDownStructuresArray(INVALID_POINTER, 1, NULL, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
55  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
56 
57  SetLastError(0xDEADBEEF);
58  ok(!MarshallDownStructuresArray(NULL, 1, (const MARSHALLING_INFO*)INVALID_POINTER, 0, FALSE), "MarshallDownStructuresArray returns TRUE!\n");
59  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returns %lu!\n", GetLastError());
60 
61  // Now create two PORT_INFO_2W structures.
62  pPortInfo2 = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
63  pPortInfoEnd = (PBYTE)pPortInfo2 + cbPortInfo2Size;
64 
65  (&pPortInfo2[0])->fPortType = fPortType;
66  (&pPortInfo2[0])->Reserved = Reserved;
67  pPortInfoEnd = PackStrings(pwszStrings, (PBYTE)(&pPortInfo2[0]), dwPortInfo2Offsets, pPortInfoEnd);
68 
69  (&pPortInfo2[1])->fPortType = fPortType + 1;
70  (&pPortInfo2[1])->Reserved = Reserved + 1;
71  pPortInfoEnd = PackStrings(pwszStrings, (PBYTE)(&pPortInfo2[1]), dwPortInfo2Offsets, pPortInfoEnd);
72 
73  // Create a backup.
74  pPortInfo2Copy = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
75  CopyMemory(pPortInfo2Copy, pPortInfo2, cbPortInfo2Size);
76 
77  // Marshall them down.
78  SetLastError(0xDEADBEEF);
79  ok(MarshallDownStructuresArray(pPortInfo2, cElements, pPortInfoMarshalling[2]->pInfo, pPortInfoMarshalling[2]->cbStructureSize, TRUE), "MarshallDownStructuresArray returns FALSE!\n");
80  ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
81 
82  // DWORD values should be unchanged.
83  ok((&pPortInfo2[0])->fPortType == fPortType, "fPortType is %lu!\n", (&pPortInfo2[0])->fPortType);
84  ok((&pPortInfo2[0])->Reserved == Reserved, "Reserved is %lu!\n", (&pPortInfo2[0])->Reserved);
85  ok((&pPortInfo2[1])->fPortType == fPortType + 1, "fPortType is %lu!\n", (&pPortInfo2[1])->fPortType);
86  ok((&pPortInfo2[1])->Reserved == Reserved + 1, "Reserved is %lu!\n", (&pPortInfo2[1])->Reserved);
87 
88  // Pointers should now contain relative offsets.
89  ok((ULONG_PTR)(&pPortInfo2[0])->pPortName == ((ULONG_PTR)(&pPortInfo2Copy[0])->pPortName - (ULONG_PTR)(&pPortInfo2[0])), "pPortName is %p!\n", (&pPortInfo2[0])->pPortName);
90  ok((ULONG_PTR)(&pPortInfo2[0])->pMonitorName == ((ULONG_PTR)(&pPortInfo2Copy[0])->pMonitorName - (ULONG_PTR)(&pPortInfo2[0])), "pMonitorName is %p!\n", (&pPortInfo2[0])->pMonitorName);
91  ok((ULONG_PTR)(&pPortInfo2[0])->pDescription == ((ULONG_PTR)(&pPortInfo2Copy[0])->pDescription - (ULONG_PTR)(&pPortInfo2[0])), "pDescription is %p!\n", (&pPortInfo2[0])->pDescription);
92  ok((ULONG_PTR)(&pPortInfo2[1])->pPortName == ((ULONG_PTR)(&pPortInfo2Copy[1])->pPortName - (ULONG_PTR)(&pPortInfo2[1])), "pPortName is %p!\n", (&pPortInfo2[1])->pPortName);
93  ok((ULONG_PTR)(&pPortInfo2[1])->pMonitorName == ((ULONG_PTR)(&pPortInfo2Copy[1])->pMonitorName - (ULONG_PTR)(&pPortInfo2[1])), "pMonitorName is %p!\n", (&pPortInfo2[1])->pMonitorName);
94  ok((ULONG_PTR)(&pPortInfo2[1])->pDescription == ((ULONG_PTR)(&pPortInfo2Copy[1])->pDescription - (ULONG_PTR)(&pPortInfo2[1])), "pDescription is %p!\n", (&pPortInfo2[1])->pDescription);
95 
96  // Marshall them up again.
97  // We need a backup of the marshalled down array to experiment with MarshallUpStructuresArray.
98  pPortInfo2Test = (PPORT_INFO_2W)HeapAlloc(GetProcessHeap(), 0, cbPortInfo2Size);
99  CopyMemory(pPortInfo2Test, pPortInfo2, cbPortInfo2Size);
100 
101  // Due to the implementation of PackStrings, (&pPortInfo2[0])->pPortName contains the highest offset.
102  // Show that MarshallUpStructuresArray checks the offsets and bails out with ERROR_INVALID_DATA if cbSize <= highest offset.
103  SetLastError(0xDEADBEEF);
104  ok(!MarshallUpStructuresArray((DWORD_PTR)(&pPortInfo2[0])->pPortName, pPortInfo2Test, cElements, pPortInfoMarshalling[2]->pInfo, pPortInfoMarshalling[2]->cbStructureSize, TRUE), "MarshallUpStructuresArray returns TRUE!\n");
105  ok(GetLastError() == ERROR_INVALID_DATA, "GetLastError returns %lu!\n", GetLastError());
106 
107  // It works with cbSize > highest offset.
108  // In real world cases, we would use cbPortInfo2Size for cbSize.
109  SetLastError(0xDEADBEEF);
110  ok(MarshallUpStructuresArray((DWORD_PTR)(&pPortInfo2[0])->pPortName + 1, pPortInfo2, cElements, pPortInfoMarshalling[2]->pInfo, pPortInfoMarshalling[2]->cbStructureSize, TRUE), "MarshallUpStructuresArray returns FALSE!\n");
111  ok(GetLastError() == 0xDEADBEEF, "GetLastError returns %lu!\n", GetLastError());
112 
113  // pPortInfo2 should now be identical to the copy again.
114  ok(RtlEqualMemory(pPortInfo2, pPortInfo2Copy, cbPortInfo2Size), "pPortInfo2 and pPortInfo2Copy are not equal after marshalling down and up!\n");
115 
116  // Free all memory.
117  HeapFree(GetProcessHeap(), 0, pPortInfo2);
118  HeapFree(GetProcessHeap(), 0, pPortInfo2Copy);
119  HeapFree(GetProcessHeap(), 0, pPortInfo2Test);
120 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define INVALID_POINTER
static const MARSHALLING * pPortInfoMarshalling[]
Definition: ports.h:28
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
struct _PORT_INFO_2W * PPORT_INFO_2W
static DWORD dwPortInfo2Offsets[]
Definition: ports.c:19
#define MAXDWORD
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
__wchar_t WCHAR
Definition: xmlstorage.h:180
PBYTE WINAPI PackStrings(PCWSTR *pSource, PBYTE pDest, const DWORD *DestOffsets, PBYTE pEnd)
Definition: tools.c:39
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _PORT_INFO_2W PORT_INFO_2W
#define SetLastError(x)
Definition: compat.h:611
static const WCHAR L[]
Definition: oid.c:1250
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define ERROR_INVALID_DATA
Definition: winerror.h:116
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define ok(value,...)
Definition: atltest.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI MarshallDownStructuresArray(PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO *pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
Definition: marshalling.c:91
#define HeapFree(x, y, z)
Definition: compat.h:594
BOOL WINAPI MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO *pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
Definition: marshalling.c:202