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 #else 84 #define DECLARE_QIPTR(type) CComQIPtr<type> 85 #endif 86 87 START_TEST(CComQIPtr) 88 { 89 CQITestObject testObject; 90 IUnknown* unk = static_cast<IPersist*>(&testObject); 91 ok_long(testObject.m_dwRef, 1); 92 ok_long(g_QI, 0); 93 94 { 95 DECLARE_QIPTR(IPersist) ppPersist(unk); 96 ok_long(testObject.m_dwRef, 2); 97 ok_long(g_QI, 1); 98 99 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal(ppPersist); 100 ok_long(testObject.m_dwRef, 3); 101 ok_long(g_QI, 2); 102 } 103 ok_long(testObject.m_dwRef, 1); 104 { 105 DECLARE_QIPTR(IStdMarshalInfo) ppMarshal; 106 ok_long(testObject.m_dwRef, 1); 107 ok_long(g_QI, 2); 108 109 ppMarshal = unk; 110 ok_long(testObject.m_dwRef, 2); 111 ok_long(g_QI, 3); 112 113 ppMarshal = static_cast<IUnknown*>(NULL); 114 ok_long(testObject.m_dwRef, 1); 115 ok_long(g_QI, 3); 116 117 CComPtr<IUnknown> spUnk(unk); 118 ok_long(testObject.m_dwRef, 2); 119 ok_long(g_QI, 3); 120 121 ppMarshal = spUnk; 122 ok_long(testObject.m_dwRef, 3); 123 ok_long(g_QI, 4); 124 125 spUnk.Release(); 126 ok_long(testObject.m_dwRef, 2); 127 ok_long(g_QI, 4); 128 129 spUnk = ppMarshal; 130 ok_long(testObject.m_dwRef, 3); 131 #ifdef __REACTOS__ 132 // CORE-12710 133 todo_if(1) 134 #endif 135 ok_long(g_QI, 5); 136 } 137 } 138