ReactOS  0.4.14-dev-1338-g0d187f7
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 
88  GlobalFree(pMemory);
89 }
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
START_TEST(AlignRpcPtr)
Definition: AlignRpcPtr.c:15
smooth NULL
Definition: ftsmooth.c:416
unsigned long DWORD
Definition: ntddk_ex.h:95
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define GMEM_FIXED
Definition: winbase.h:290
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:236
#define ok(value,...)
Definition: atltest.h:57
DWORD * PDWORD
Definition: pedump.c:68
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469