1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Test for CComQIPtr 5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <atlbase.h> 9 #include <atlcom.h> 10 11 #ifdef __REACTOS__ 12 #include <apitest.h> 13 #else 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <stdarg.h> 17 int g_tests_executed = 0; 18 int g_tests_failed = 0; 19 void ok_func(const char *file, int line, BOOL value, const char *fmt, ...) 20 { 21 va_list va; 22 va_start(va, fmt); 23 if (!value) 24 { 25 printf("%s (%d): ", file, line); 26 vprintf(fmt, va); 27 g_tests_failed++; 28 } 29 g_tests_executed++; 30 va_end(va); 31 } 32 #undef ok 33 #define ok(value, ...) ok_func(__FILE__, __LINE__, value, __VA_ARGS__) 34 #define START_TEST(x) int main(void) 35 #endif 36 37 38 static LONG g_QI = 0; 39 40 class CQITestObject : 41 public IPersist, 42 public IStdMarshalInfo 43 { 44 public: 45 LONG m_dwRef; 46 47 CQITestObject() 48 :m_dwRef(1) 49 { 50 } 51 ~CQITestObject() 52 { 53 } 54 55 STDMETHOD_(ULONG, AddRef)() 56 { 57 InterlockedIncrement(&m_dwRef); 58 return 2; 59 } 60 61 STDMETHOD_(ULONG, Release)() 62 { 63 InterlockedDecrement(&m_dwRef); 64 return 1; 65 } 66 67 STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) 68 { 69 InterlockedIncrement(&g_QI); 70 if (iid == IID_IUnknown || iid == IID_IPersist) 71 { 72 AddRef(); 73 *ppvObject = static_cast<IPersist*>(this); 74 return S_OK; 75 } 76 else if (iid == IID_IStdMarshalInfo) 77 { 78 AddRef(); 79 *ppvObject = static_cast<IStdMarshalInfo*>(this); 80 return S_OK; 81 } 82 return E_NOINTERFACE; 83 } 84 85 // *** IPersist methods *** 86 STDMETHOD(GetClassID)(CLSID *pClassID) 87 { 88 return E_NOTIMPL; 89 } 90 91 // *** IStdMarshalInfo methods *** 92 STDMETHOD(GetClassForHandler)(DWORD dwDestContext, void *pvDestContext, CLSID *pClsid) 93 { 94 return E_NOTIMPL; 95 } 96 }; 97 98 // Yes this sucks, but we have to support GCC. (CORE-12710) 99 #ifdef __REACTOS__ 100 #define DECLARE_QIPTR(type) CComQIIDPtr<I_ID(type)> 101 #else 102 #define DECLARE_QIPTR(type) CComQIPtr<type> 103 #endif 104 105 START_TEST(CComQIPtr) 106 { 107 CQITestObject testObject; 108 IUnknown* unk = static_cast<IPersist*>(&testObject); 109 ok(testObject.m_dwRef == 1, "Expected m_dwRef 1, got %lu\n", testObject.m_dwRef); 110 ok(g_QI == 0, "Expected g_QI 0, got %lu\n", g_QI); 111 112 { 113 DECLARE_QIPTR(IPersist) ppPersist(unk); 114 ok(testObject.m_dwRef == 2, "Expected m_dwRef 2, got %lu\n", testObject.m_dwRef); 115 ok(g_QI == 1, "Expected g_QI 1, got %lu\n", g_QI); 116 117 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal(ppPersist); 118 ok(testObject.m_dwRef == 3, "Expected m_dwRef 3, got %lu\n", testObject.m_dwRef); 119 ok(g_QI == 2, "Expected g_QI 2, got %lu\n", g_QI); 120 } 121 ok(testObject.m_dwRef == 1, "Expected m_dwRef 1, got %lu\n", testObject.m_dwRef); 122 { 123 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal; 124 ok(testObject.m_dwRef == 1, "Expected m_dwRef 1, got %lu\n", testObject.m_dwRef); 125 ok(g_QI == 2, "Expected g_QI 2, got %lu\n", g_QI); 126 127 ppMarshal = unk; 128 ok(testObject.m_dwRef == 2, "Expected m_dwRef 2, got %lu\n", testObject.m_dwRef); 129 ok(g_QI == 3, "Expected g_QI 3, got %lu\n", g_QI); 130 131 ppMarshal = static_cast<IUnknown*>(NULL); 132 ok(testObject.m_dwRef == 1, "Expected m_dwRef 1, got %lu\n", testObject.m_dwRef); 133 ok(g_QI == 3, "Expected g_QI 3, got %lu\n", g_QI); 134 135 CComPtr<IUnknown> spUnk(unk); 136 ok(testObject.m_dwRef == 2, "Expected m_dwRef 2, got %lu\n", testObject.m_dwRef); 137 ok(g_QI == 3, "Expected g_QI 3, got %lu\n", g_QI); 138 139 ppMarshal = spUnk; 140 ok(testObject.m_dwRef == 3, "Expected m_dwRef 3, got %lu\n", testObject.m_dwRef); 141 ok(g_QI == 4, "Expected g_QI 4, got %lu\n", g_QI); 142 143 spUnk.Release(); 144 ok(testObject.m_dwRef == 2, "Expected m_dwRef 2, got %lu\n", testObject.m_dwRef); 145 ok(g_QI == 4, "Expected g_QI 4, got %lu\n", g_QI); 146 147 spUnk = ppMarshal; 148 ok(testObject.m_dwRef == 3, "Expected m_dwRef 3, got %lu\n", testObject.m_dwRef); 149 #ifdef __REACTOS__ 150 // CORE-12710 151 todo_if(1) 152 #endif 153 ok(g_QI == 5, "Expected g_QI 5, got %lu\n", g_QI); 154 } 155 156 #ifndef __REACTOS__ 157 printf("CComQIPtr: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); 158 return g_tests_failed; 159 #endif 160 } 161