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 HAVE_APITEST 12 #include <apitest.h> 13 #else 14 #include "atltest.h" 15 #endif 16 17 18 static LONG g_QI = 0; 19 20 class CQITestObject : 21 public IPersist, 22 public IStdMarshalInfo 23 { 24 public: 25 LONG m_dwRef; 26 27 CQITestObject() 28 :m_dwRef(1) 29 { 30 } 31 ~CQITestObject() 32 { 33 } 34 35 STDMETHOD_(ULONG, AddRef)() 36 { 37 InterlockedIncrement(&m_dwRef); 38 return 2; 39 } 40 41 STDMETHOD_(ULONG, Release)() 42 { 43 InterlockedDecrement(&m_dwRef); 44 return 1; 45 } 46 47 STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) 48 { 49 InterlockedIncrement(&g_QI); 50 if (iid == IID_IUnknown || iid == IID_IPersist) 51 { 52 AddRef(); 53 *ppvObject = static_cast<IPersist*>(this); 54 return S_OK; 55 } 56 else if (iid == IID_IStdMarshalInfo) 57 { 58 AddRef(); 59 *ppvObject = static_cast<IStdMarshalInfo*>(this); 60 return S_OK; 61 } 62 return E_NOINTERFACE; 63 } 64 65 // *** IPersist methods *** 66 STDMETHOD(GetClassID)(CLSID *pClassID) 67 { 68 return E_NOTIMPL; 69 } 70 71 // *** IStdMarshalInfo methods *** 72 STDMETHOD(GetClassForHandler)(DWORD dwDestContext, void *pvDestContext, CLSID *pClsid) 73 { 74 return E_NOTIMPL; 75 } 76 }; 77 78 // Yes this sucks, but we have to support GCC. (CORE-12710) 79 #ifdef __REACTOS__ 80 #define DECLARE_QIPTR(type) CComQIIDPtr<I_ID(type)> 81 #elif defined(__GNUC__) 82 #define DECLARE_QIPTR(type) CComQIIDPtr<I_ID(type)> 83 #elif defined(__RATL__) 84 #define DECLARE_QIPTR(type) CComQIIDPtr<I_ID(type)> 85 #else 86 #define DECLARE_QIPTR(type) CComQIPtr<type> 87 #endif 88 89 START_TEST(CComQIPtr) 90 { 91 CQITestObject testObject; 92 IUnknown* unk = static_cast<IPersist*>(&testObject); 93 ok_long(testObject.m_dwRef, 1); 94 ok_long(g_QI, 0); 95 96 { 97 DECLARE_QIPTR(IPersist) ppPersist(unk); 98 ok_long(testObject.m_dwRef, 2); 99 ok_long(g_QI, 1); 100 101 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal(ppPersist); 102 ok_long(testObject.m_dwRef, 3); 103 ok_long(g_QI, 2); 104 } 105 ok_long(testObject.m_dwRef, 1); 106 { 107 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal; 108 ok_long(testObject.m_dwRef, 1); 109 ok_long(g_QI, 2); 110 111 ppMarshal = unk; 112 ok_long(testObject.m_dwRef, 2); 113 ok_long(g_QI, 3); 114 115 ppMarshal = static_cast<IUnknown*>(NULL); 116 ok_long(testObject.m_dwRef, 1); 117 ok_long(g_QI, 3); 118 119 CComPtr<IUnknown> spUnk(unk); 120 ok_long(testObject.m_dwRef, 2); 121 ok_long(g_QI, 3); 122 123 ppMarshal = spUnk; 124 ok_long(testObject.m_dwRef, 3); 125 ok_long(g_QI, 4); 126 127 spUnk.Release(); 128 ok_long(testObject.m_dwRef, 2); 129 ok_long(g_QI, 4); 130 131 spUnk = ppMarshal; 132 ok_long(testObject.m_dwRef, 3); 133 #ifdef __REACTOS__ 134 // CORE-12710 135 todo_if(1) 136 #endif 137 ok_long(g_QI, 5); 138 } 139 } 140