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
19 static LONG g_CTOR = 0;
20 static LONG g_DTOR = 0;
21 static LONG g_BLIND = 0;
22
23 class CTestObject :
24 public CComObjectRootEx<CComMultiThreadModelNoCS>,
25 public IPersist,
26 public IStdMarshalInfo
27 {
28 public:
CTestObject()29 CTestObject()
30 {
31 InterlockedIncrement(&g_CTOR);
32 }
~CTestObject()33 ~CTestObject()
34 {
35 InterlockedIncrement(&g_DTOR);
36 }
37
38 // *** IPersist methods ***
GetClassID(CLSID * pClassID)39 virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
40 {
41 return E_NOTIMPL;
42 }
43
44 // *** IStdMarshalInfo methods ***
GetClassForHandler(DWORD dwDestContext,void * pvDestContext,CLSID * pClsid)45 virtual HRESULT STDMETHODCALLTYPE GetClassForHandler(DWORD dwDestContext, void *pvDestContext, CLSID *pClsid)
46 {
47 return E_NOTIMPL;
48 }
49
FuncBlind(void * pv,REFIID riid,LPVOID * ppv,DWORD_PTR dw)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)
67 class CDumExe: public CAtlExeModuleT<CDumExe>
68 {
69
70 };
71 CDumExe dum;
72 #endif
73
START_TEST(CComObject)74 START_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 }
125