Reactos
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Test for CComObject
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8
9#include <atlbase.h>
10#include <atlcom.h>
11
12#ifdef HAVE_APITEST
13 #include <apitest.h>
14#else
15 #include "atltest.h"
16#endif
17
18
19static LONG g_CTOR = 0;
20static LONG g_DTOR = 0;
21static LONG g_BLIND = 0;
22
23class CTestObject :
24 public CComObjectRootEx<CComMultiThreadModelNoCS>,
25 public IPersist,
26 public IStdMarshalInfo
27{
28public:
29 CTestObject()
30 {
31 InterlockedIncrement(&g_CTOR);
32 }
33 ~CTestObject()
34 {
35 InterlockedIncrement(&g_DTOR);
36 }
37
38 // *** IPersist methods ***
39 virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
40 {
41 return E_NOTIMPL;
42 }
43
44 // *** IStdMarshalInfo methods ***
45 virtual HRESULT STDMETHODCALLTYPE GetClassForHandler(DWORD dwDestContext, void *pvDestContext, CLSID *pClsid)
46 {
47 return E_NOTIMPL;
48 }
49
50 static HRESULT WINAPI FuncBlind(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw)
51 {
52 InterlockedIncrement(&g_BLIND);
53 return E_FAIL;
54 }
55
56 DECLARE_NOT_AGGREGATABLE(CTestObject)
57 DECLARE_PROTECT_FINAL_CONSTRUCT()
58
59 BEGIN_COM_MAP(CTestObject)
60 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) /* First entry has to be a simple entry, otherwise ATL asserts */
61 COM_INTERFACE_ENTRY_FUNC_BLIND(0, FuncBlind) /* Showing that even after a Blind func, entryies can be found */
62 COM_INTERFACE_ENTRY_IID(IID_IStdMarshalInfo, IStdMarshalInfo)
63 END_COM_MAP()
64};
65
66#ifndef __RATL__ // Avoid conflict (causing assertion at CAtlModule::CAtlModule)
67class CDumExe: public CAtlExeModuleT<CDumExe>
68{
69
70};
71CDumExe dum;
72#endif
73
74START_TEST(CComObject)
75{
76 g_CTOR = g_DTOR = g_BLIND = 0;
77
78 CComObject<CTestObject>* pTest;
79 HRESULT hr = CComObject<CTestObject>::CreateInstance(&pTest);
80
81 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
82
83 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
84 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
85 ok(g_BLIND == 0, "Expected 0, got %lu\n", g_BLIND);
86
87 if (hr == S_OK)
88 {
89 ULONG ref = pTest->AddRef();
90 ok(ref == 1, "Expected 1, got %lu\n", ref);
91
92 {
93 CComPtr<IUnknown> ppv;
94 hr = pTest->QueryInterface(IID_IUnknown, (void **) &ppv);
95 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
96 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
97 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
98 ok(g_BLIND == 0, "Expected 0, got %lu\n", g_BLIND);
99
100 CComPtr<IPersist> ppersist;
101 hr = pTest->QueryInterface(IID_IPersist, (void **)&ppersist);
102 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
103 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
104 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
105 ok(g_BLIND == 0, "Expected 0, got %lu\n", g_BLIND);
106
107 }
108
109 {
110 CComPtr<IStdMarshalInfo> pstd;
111 hr = pTest->QueryInterface(IID_IStdMarshalInfo, (void **)&pstd);
112 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
113 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
114 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
115 ok(g_BLIND == 1, "Expected 1, got %lu\n", g_BLIND);
116 }
117
118 ref = pTest->Release();
119 ok(ref == 0, "Expected 0, got %lu\n", ref);
120 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
121 ok(g_DTOR == 1, "Expected 1, got %lu\n", g_DTOR);
122 ok(g_BLIND == 1, "Expected 1, got %lu\n", g_BLIND);
123 }
124}