840f88a96761052ee2a5e8089800d370fb38ca3d
[reactos.git] / modules / rostests / apitests / atl / CComObject.cpp
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 __REACTOS__
13 #include <apitest.h>
14 #else
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <stdarg.h>
18 int g_tests_executed = 0;
19 int g_tests_failed = 0;
20 void ok_func(const char *file, int line, BOOL value, const char *fmt, ...)
21 {
22 va_list va;
23 va_start(va, fmt);
24 if (!value)
25 {
26 printf("%s (%d): ", file, line);
27 vprintf(fmt, va);
28 g_tests_failed++;
29 }
30 g_tests_executed++;
31 va_end(va);
32 }
33 #undef ok
34 #define ok(value, ...) ok_func(__FILE__, __LINE__, value, __VA_ARGS__)
35 #define START_TEST(x) int main(void)
36 #endif
37
38
39 static LONG g_CTOR = 0;
40 static LONG g_DTOR = 0;
41 static LONG g_BLIND = 0;
42
43 class CTestObject :
44 public CComObjectRootEx<CComMultiThreadModelNoCS>,
45 public IPersist,
46 public IStdMarshalInfo
47 {
48 public:
49 CTestObject()
50 {
51 InterlockedIncrement(&g_CTOR);
52 }
53 ~CTestObject()
54 {
55 InterlockedIncrement(&g_DTOR);
56 }
57
58 // *** IPersist methods ***
59 virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
60 {
61 return E_NOTIMPL;
62 }
63
64 // *** IStdMarshalInfo methods ***
65 virtual HRESULT STDMETHODCALLTYPE GetClassForHandler(DWORD dwDestContext, void *pvDestContext, CLSID *pClsid)
66 {
67 return E_NOTIMPL;
68 }
69
70 static HRESULT WINAPI FuncBlind(void* pv, REFIID riid, LPVOID* ppv, DWORD dw)
71 {
72 InterlockedIncrement(&g_BLIND);
73 return E_FAIL;
74 }
75
76 DECLARE_NOT_AGGREGATABLE(CTestObject)
77 DECLARE_PROTECT_FINAL_CONSTRUCT()
78
79 BEGIN_COM_MAP(CTestObject)
80 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) /* First entry has to be a simple entry, otherwise ATL asserts */
81 COM_INTERFACE_ENTRY_FUNC_BLIND(0, FuncBlind) /* Showing that even after a Blind func, entryies can be found */
82 COM_INTERFACE_ENTRY_IID(IID_IStdMarshalInfo, IStdMarshalInfo)
83 END_COM_MAP()
84 };
85
86
87 class CDumExe: public CAtlExeModuleT<CDumExe>
88 {
89
90 };
91 CDumExe dum;
92
93
94 START_TEST(CComObject)
95 {
96 g_CTOR = g_DTOR = g_BLIND = 0;
97
98 CComObject<CTestObject>* pTest;
99 HRESULT hr = CComObject<CTestObject>::CreateInstance(&pTest);
100
101 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
102
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 if (hr == S_OK)
108 {
109 ULONG ref = pTest->AddRef();
110 ok(ref == 1, "Expected 1, got %lu\n", ref);
111
112 {
113 CComPtr<IUnknown> ppv;
114 hr = pTest->QueryInterface(IID_IUnknown, (void **) &ppv);
115 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
116 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
117 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
118 ok(g_BLIND == 0, "Expected 0, got %lu\n", g_BLIND);
119
120 CComPtr<IPersist> ppersist;
121 hr = pTest->QueryInterface(IID_IPersist, (void **)&ppersist);
122 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
123 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
124 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
125 ok(g_BLIND == 0, "Expected 0, got %lu\n", g_BLIND);
126
127 }
128
129 {
130 CComPtr<IStdMarshalInfo> pstd;
131 hr = pTest->QueryInterface(IID_IStdMarshalInfo, (void **)&pstd);
132 ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
133 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
134 ok(g_DTOR == 0, "Expected 0, got %lu\n", g_DTOR);
135 ok(g_BLIND == 1, "Expected 1, got %lu\n", g_BLIND);
136 }
137
138 ref = pTest->Release();
139 ok(ref == 0, "Expected 0, got %lu\n", ref);
140 ok(g_CTOR == 1, "Expected 1, got %lu\n", g_CTOR);
141 ok(g_DTOR == 1, "Expected 1, got %lu\n", g_DTOR);
142 ok(g_BLIND == 1, "Expected 1, got %lu\n", g_BLIND);
143 }
144
145 #ifndef __REACTOS__
146 printf("CComObject: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed);
147 return g_tests_failed;
148 #endif
149 }