Reactos
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Test for CComHeapPtr
5 * COPYRIGHT: Copyright 2015-2020 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#ifdef HAVE_APITEST
9#include <apitest.h>
10#else
11#include "atltest.h"
12#endif
13#include <atlbase.h>
14
15static PDWORD
16test_Alloc(DWORD value)
17{
18 PDWORD ptr = (PDWORD)::CoTaskMemAlloc(sizeof(DWORD));
19 *ptr = value;
20 return ptr;
21}
22
23
24static LONG g_OpenAllocations = 0;
25static LONG g_Reallocations = 0;
26
27struct CMallocSpy : public IMallocSpy
28{
29 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
30 {
31 if (IsEqualGUID(riid, IID_IMallocSpy))
32 {
33 *ppvObject = this;
34 }
35 return S_OK;
36 }
37
38 virtual ULONG STDMETHODCALLTYPE AddRef() { return 1; }
39 virtual ULONG STDMETHODCALLTYPE Release() { return 1; }
40 virtual SIZE_T STDMETHODCALLTYPE PreAlloc(SIZE_T cbRequest) { return cbRequest; }
41 virtual LPVOID STDMETHODCALLTYPE PostAlloc(LPVOID pActual)
42 {
43 InterlockedIncrement(&g_OpenAllocations);
44 return pActual;
45 }
46 virtual LPVOID STDMETHODCALLTYPE PreFree(LPVOID pRequest, BOOL) { return pRequest; }
47 virtual void STDMETHODCALLTYPE PostFree(BOOL fSpyed)
48 {
49 if (fSpyed)
50 InterlockedDecrement(&g_OpenAllocations);
51 }
52 virtual SIZE_T STDMETHODCALLTYPE PreRealloc(LPVOID pRequest, SIZE_T cbRequest, LPVOID *ppNewRequest, BOOL)
53 {
54 *ppNewRequest = pRequest;
55 return cbRequest;
56 }
57 virtual LPVOID STDMETHODCALLTYPE PostRealloc(LPVOID pActual, BOOL fSpyed)
58 {
59 if (fSpyed)
60 InterlockedIncrement(&g_Reallocations);
61 return pActual;
62 }
63 virtual LPVOID STDMETHODCALLTYPE PreGetSize(LPVOID pRequest, BOOL) { return pRequest; }
64 virtual SIZE_T STDMETHODCALLTYPE PostGetSize(SIZE_T cbActual, BOOL) { return cbActual; }
65 virtual LPVOID STDMETHODCALLTYPE PreDidAlloc(LPVOID pRequest, BOOL) { return pRequest; }
66 virtual int STDMETHODCALLTYPE PostDidAlloc(LPVOID, BOOL, int fActual) { return fActual; }
67 virtual void STDMETHODCALLTYPE PreHeapMinimize() {}
68 virtual void STDMETHODCALLTYPE PostHeapMinimize() {}
69};
70
71static CMallocSpy g_Spy;
72
73
74START_TEST(CComHeapPtr)
75{
76 HRESULT hr = CoRegisterMallocSpy(&g_Spy);
77 ok(SUCCEEDED(hr), "Expected CoRegisterMallocSpy to succeed, but it failed: 0x%lx\n", hr);
78
79 {
80 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
81 CComHeapPtr<DWORD> heapPtr1;
82 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
83 CComHeapPtr<DWORD> heapPtr2(test_Alloc(0x11111111));
84 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
85
86 ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1);
87 ok((PDWORD)heapPtr2 != NULL, "Expected heapPtr2 to not be NULL\n");
88 ok(*heapPtr2 == 0x11111111, "Expected *heapPtr2 to be 0x11111111, but was: 0x%lx\n", *heapPtr2);
89
90 {
91 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
92 CComHeapPtr<DWORD> heapPtrSteal1(heapPtr1);
93 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
94 ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1);
95 ok((PDWORD)heapPtrSteal1 == NULL, "Expected heapPtrSteal1 to be NULL, was: 0x%p\n", (PDWORD)heapPtrSteal1);
96 CComHeapPtr<DWORD> heapPtrSteal2(heapPtr2);
97 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
98 ok((PDWORD)heapPtr2 == NULL, "Expected heapPtr2 to be NULL, was: 0x%p\n", (PDWORD)heapPtr2);
99 ok((PDWORD)heapPtrSteal2 != NULL, "Expected heapPtrSteal2 to not be NULL\n");
100 ok(*heapPtrSteal2 == 0x11111111, "Expected *heapPtrSteal2 to be 0x11111111, but was: 0x%lx\n", *heapPtrSteal2);
101 }
102 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
103
104 ok(heapPtr1.Allocate(1), "Expected Allocate to succeed\n");
105 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
106 ok(g_Reallocations == 0, "Expected there to be 0 reallocations, was: %ld\n", g_Reallocations);
107
108 *heapPtr1 = 0x22222222;
109 ok(*heapPtr1 == 0x22222222, "Expected *heapPtr1 to be 0x22222222, but was: 0x%lx\n", *heapPtr1);
110
111 ok(heapPtr1.Reallocate(2), "Expected Reallocate to succeed\n");
112 heapPtr1[1] = 0x33333333;
113 ok(*heapPtr1 == 0x22222222, "Expected *heapPtr1 to be 0x22222222, but was: 0x%lx\n", *heapPtr1);
114 ok(g_Reallocations == 1, "Expected there to be 1 reallocations, was: %ld\n", g_Reallocations);
115 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
116
117 heapPtr2 = heapPtr1;
118 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
119 ok(*heapPtr2 == 0x22222222, "Expected *heapPtr2 to be 0x33333333, but was: 0x%lx\n", *heapPtr2);
120 ok(heapPtr2[1] == 0x33333333, "Expected heapPtr2[1] to be 0x33333333, but was: 0x%lx\n", heapPtr2[1]);
121 ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1);
122 }
123 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
124
125 hr = CoRevokeMallocSpy();
126 ok(SUCCEEDED(hr), "Expected CoRevokeMallocSpy to succeed, but it failed: 0x%lx\n", hr);
127}