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