[SHELL32_APITEST] -Add some tests for SHParseDisplayName for CORE-12882.
[reactos.git] / rostests / apitests / spoolss / AlignRpcPtr.c
1 /*
2 * PROJECT: ReactOS Spooler Router API Tests
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
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
15 START_TEST(AlignRpcPtr)
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 }