ReactOS 0.4.15-dev-7924-g5949c20
AlignRpcPtr.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Spooler Router API Tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for AlignRpcPtr/UndoAlignRpcPtr
5 * COPYRIGHT: Copyright 2017 Colin Finck (colin@reactos.org)
6 */
7
8#include <apitest.h>
9
10#define WIN32_NO_STATUS
11#include <windef.h>
12#include <winbase.h>
13#include <spoolss.h>
14
16{
17 char* pMemory;
18 char* pInputBuffer;
19 char* pOutputBuffer;
20 DWORD cbBuffer;
21 PDWORD pcbBuffer;
22
23 // Allocate memory with GlobalAlloc. It is guaranteed to be aligned to a 8-byte boundary.
24 pMemory = (char*)GlobalAlloc(GMEM_FIXED, 16);
25
26 // First try AlignRpcPtr with already aligned memory and buffer size. It should leave everything unchanged.
27 pInputBuffer = pMemory;
28 cbBuffer = 8;
29 pOutputBuffer = (char*)AlignRpcPtr(pInputBuffer, &cbBuffer);
30 ok(pOutputBuffer == pInputBuffer, "pOutputBuffer != pInputBuffer\n");
31 ok(cbBuffer == 8, "cbBuffer is %lu\n", cbBuffer);
32
33 // Now try it with unaligned buffer size. The size should be aligned down while the buffer stays the same.
34 pInputBuffer = pMemory;
35 cbBuffer = 7;
36 pOutputBuffer = (char*)AlignRpcPtr(pInputBuffer, &cbBuffer);
37 ok(pOutputBuffer == pInputBuffer, "pOutputBuffer != pInputBuffer\n");
38 ok(cbBuffer == 4, "cbBuffer is %lu\n", cbBuffer);
39
40 // Now try with unaligned memory, but aligned buffer size. A new buffer is allocated while the size stays the same.
41 // The allocated buffer is then freed with UndoAlignRpcPtr. It is important to specify 0 as the size here, otherwise
42 // the NULL pointer for pDestinationBuffer is accessed.
43 pInputBuffer = pMemory + 1;
44 cbBuffer = 8;
45 pOutputBuffer = (char*)AlignRpcPtr(pInputBuffer, &cbBuffer);
46 ok(pOutputBuffer != pInputBuffer, "pOutputBuffer == pInputBuffer\n");
47 ok(cbBuffer == 8, "cbBuffer is %lu\n", cbBuffer);
48 ok(!UndoAlignRpcPtr(NULL, pOutputBuffer, 0, NULL), "UndoAlignRpcPtr returns something\n");
49
50 // Now try with memory and buffer size unaligned. A new buffer of the aligned down size is allocated.
51 pInputBuffer = pMemory + 1;
52 cbBuffer = 7;
53 pOutputBuffer = (char*)AlignRpcPtr(pInputBuffer, &cbBuffer);
54 ok(pOutputBuffer != pInputBuffer, "pOutputBuffer == pInputBuffer\n");
55 ok(cbBuffer == 4, "cbBuffer is %lu\n", cbBuffer);
56
57 // Prove that AlignRpcPtr also works with a NULL buffer. The size should be aligned down.
58 cbBuffer = 6;
59 ok(!AlignRpcPtr(NULL, &cbBuffer), "AlignRpcPtr returns something\n");
60 ok(cbBuffer == 4, "cbBuffer is %lu\n", cbBuffer);
61
62 // We can also test all parameters of UndoAlignRpcPtr here.
63 // Because pOutputBuffer != pInputBuffer, it copies the given 4 bytes from (aligned) pOutputBuffer to (unaligned) pInputBuffer
64 // while aligning up the given 7 bytes in our passed &cbBuffer.
65 // &cbBuffer is also returned.
66 strcpy(pOutputBuffer, "abc");
67 strcpy(pInputBuffer, "XXXXXXXXX");
68 cbBuffer = 5;
69 pcbBuffer = UndoAlignRpcPtr(pInputBuffer, pOutputBuffer, 4, &cbBuffer);
70 ok(strcmp(pInputBuffer, "abc") == 0, "pInputBuffer is %s\n", pInputBuffer);
71 ok(pcbBuffer == &cbBuffer, "pcbBuffer != &cbBuffer\n");
72 ok(cbBuffer == 8, "cbBuffer is %lu\n", cbBuffer);
73
74 // Prove that UndoAlignRpcPtr works without any parameters and doesn't try to copy data from NULL pointers.
75 ok(!UndoAlignRpcPtr(NULL, NULL, 0, NULL), "UndoAlignRpcPtr returns something\n");
76 ok(!UndoAlignRpcPtr(NULL, NULL, 6, NULL), "UndoAlignRpcPtr returns something\n");
77
78 // Prove that UndoAlignRpcPtr doesn't access source and destination memory at all when they are equal.
79 // If it did, it should crash here, because I'm giving invalid memory addresses.
80 ok(!UndoAlignRpcPtr((PVOID)1, (PVOID)1, 4, NULL), "UndoAlignRpcPtr returns something\n");
81
82 // Prove that the pcbNeeded parameter of UndoAlignRpcPtr works independently and aligns up to a DWORD.
83 cbBuffer = 0xFFFFFFFD;
84 pcbBuffer = UndoAlignRpcPtr(NULL, NULL, 0, &cbBuffer);
85 ok(pcbBuffer == &cbBuffer, "pcbBuffer != &cbBuffer\n");
86 ok(cbBuffer == 0, "cbBuffer is %lu\n", cbBuffer);
87
89}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
unsigned long DWORD
Definition: ntddk_ex.h:95
FxMemoryObject * pMemory
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
DWORD * PDWORD
Definition: pedump.c:68
PVOID WINAPI AlignRpcPtr(PVOID pBuffer, PDWORD pcbBuffer)
Definition: memory.c:29
PDWORD WINAPI UndoAlignRpcPtr(PVOID pDestinationBuffer, PVOID pSourceBuffer, DWORD cbBuffer, PDWORD pcbNeeded)
Definition: memory.c:239
#define GMEM_FIXED
Definition: winbase.h:293