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 CHeapPtrList
5 * COPYRIGHT: Copyright 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 <atlcoll.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// We use the CComAllocator, so we can easily spy on it
24template <typename T>
25class CComHeapPtrList :
26 public CHeapPtrList<T, CComAllocator>
27{
28public:
29 CComHeapPtrList(_In_ UINT nBlockSize = 10) throw()
30 :CHeapPtrList<T, CComAllocator>(nBlockSize)
31 {
32 }
33};
34
35
36
37static LONG g_OpenAllocations = 0;
38static LONG g_Reallocations = 0;
39
40struct CHeapPtrListMallocSpy : public IMallocSpy
41{
42 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
43 {
44 if (IsEqualGUID(riid, IID_IMallocSpy))
45 {
46 *ppvObject = this;
47 }
48 return S_OK;
49 }
50
51 virtual ULONG STDMETHODCALLTYPE AddRef() { return 1; }
52 virtual ULONG STDMETHODCALLTYPE Release() { return 1; }
53 virtual SIZE_T STDMETHODCALLTYPE PreAlloc(SIZE_T cbRequest) { return cbRequest; }
54 virtual LPVOID STDMETHODCALLTYPE PostAlloc(LPVOID pActual)
55 {
56 InterlockedIncrement(&g_OpenAllocations);
57 return pActual;
58 }
59 virtual LPVOID STDMETHODCALLTYPE PreFree(LPVOID pRequest, BOOL) { return pRequest; }
60 virtual void STDMETHODCALLTYPE PostFree(BOOL fSpyed)
61 {
62 if (fSpyed)
63 InterlockedDecrement(&g_OpenAllocations);
64 }
65 virtual SIZE_T STDMETHODCALLTYPE PreRealloc(LPVOID pRequest, SIZE_T cbRequest, LPVOID *ppNewRequest, BOOL)
66 {
67 *ppNewRequest = pRequest;
68 return cbRequest;
69 }
70 virtual LPVOID STDMETHODCALLTYPE PostRealloc(LPVOID pActual, BOOL fSpyed)
71 {
72 if (fSpyed)
73 InterlockedIncrement(&g_Reallocations);
74 return pActual;
75 }
76 virtual LPVOID STDMETHODCALLTYPE PreGetSize(LPVOID pRequest, BOOL) { return pRequest; }
77 virtual SIZE_T STDMETHODCALLTYPE PostGetSize(SIZE_T cbActual, BOOL) { return cbActual; }
78 virtual LPVOID STDMETHODCALLTYPE PreDidAlloc(LPVOID pRequest, BOOL) { return pRequest; }
79 virtual int STDMETHODCALLTYPE PostDidAlloc(LPVOID, BOOL, int fActual) { return fActual; }
80 virtual void STDMETHODCALLTYPE PreHeapMinimize() {}
81 virtual void STDMETHODCALLTYPE PostHeapMinimize() {}
82};
83
84static CHeapPtrListMallocSpy g_Spy;
85
86
87START_TEST(CHeapPtrList)
88{
89 HRESULT hr = CoRegisterMallocSpy(&g_Spy);
90 ok(SUCCEEDED(hr), "Expected CoRegisterMallocSpy to succeed, but it failed: 0x%lx\n", hr);
91
92 {
93 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
94 CComHeapPtrList<DWORD> heapPtr1;
95 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
96 PDWORD Ptr = test_Alloc(0x11111111);
97 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
98 CComHeapPtr<DWORD> tmp(Ptr);
99 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
100 heapPtr1.AddTail(tmp);
101 ok(tmp.m_pData == NULL, "Expected m_pData to be transfered\n");
102 ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
103 Ptr = test_Alloc(0x22222222);
104 ok(g_OpenAllocations == 2, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
105#if defined(_MSC_VER) && !defined(__clang__)
106 heapPtr1.AddTail(CComHeapPtr<DWORD>(Ptr));
107#else
108 CComHeapPtr<DWORD> xxx(Ptr);
109 heapPtr1.AddTail(xxx);
110#endif
111 ok(g_OpenAllocations == 2, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations);
112 }
113 ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations);
114
115 hr = CoRevokeMallocSpy();
116 ok(SUCCEEDED(hr), "Expected CoRevokeMallocSpy to succeed, but it failed: 0x%lx\n", hr);
117}