1 /* 2 ReactOS Kernel-Mode COM 3 IUnknown implementations 4 5 This file is in the public domain. 6 7 AUTHORS 8 Andrew Greenwood 9 */ 10 11 #ifndef STDUNK_H 12 #define STDUNK_H 13 14 #include <punknown.h> 15 16 /* =============================================================== 17 INonDelegatingUnknown interface 18 */ 19 20 DECLARE_INTERFACE(INonDelegatingUnknown) 21 { 22 STDMETHOD_(NTSTATUS, NonDelegatingQueryInterface)( THIS_ 23 IN REFIID, 24 OUT PVOID*) PURE; 25 26 STDMETHOD_(ULONG, NonDelegatingAddRef)( THIS ) PURE; 27 STDMETHOD_(ULONG, NonDelegatingRelease)( THIS ) PURE; 28 }; 29 30 typedef INonDelegatingUnknown *PNONDELEGATINGUNKNOWN; 31 32 33 /* =============================================================== 34 CUnknown declaration / definition 35 36 There are 2 variants for this, and I'm not sure if the C 37 version is correct. 38 */ 39 40 #ifdef __cplusplus 41 42 class CUnknown : public INonDelegatingUnknown 43 { 44 private : 45 LONG m_ref_count; 46 PUNKNOWN m_outer_unknown; 47 48 public : 49 /* CUnknown */ 50 CUnknown(PUNKNOWN pUnknownOuter); 51 virtual ~CUnknown(); 52 53 PUNKNOWN GetOuterUnknown() 54 { return m_outer_unknown; } 55 56 /* INonDelegatingUnknown */ 57 STDMETHODIMP_(ULONG) NonDelegatingAddRef(); 58 STDMETHODIMP_(ULONG) NonDelegatingRelease(); 59 60 STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( 61 REFIID rIID, 62 PVOID* ppVoid); 63 }; 64 65 #define DECLARE_STD_UNKNOWN() \ 66 STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( \ 67 REFIID iid, \ 68 PVOID* ppvObject); \ 69 \ 70 STDMETHODIMP_(NTSTATUS) QueryInterface( \ 71 REFIID riid, \ 72 void** ppv) \ 73 { \ 74 return GetOuterUnknown()->QueryInterface(riid, ppv); \ 75 } \ 76 \ 77 STDMETHODIMP_(ULONG) AddRef() \ 78 { \ 79 return GetOuterUnknown()->AddRef(); \ 80 } \ 81 \ 82 STDMETHODIMP_(ULONG) Release() \ 83 { \ 84 return GetOuterUnknown()->Release(); \ 85 } 86 87 #define DEFINE_STD_CONSTRUCTOR(classname) \ 88 classname(PUNKNOWN outer_unknown) \ 89 : CUnknown(outer_unknown) \ 90 { } 91 92 #else /* Not C++ - this is probably very buggy... */ 93 94 NTSTATUS 95 STDMETHODCALLTYPE 96 Unknown_QueryInterface( 97 IUnknown* this, 98 IN REFIID refiid, 99 OUT PVOID* output); 100 101 ULONG 102 STDMETHODCALLTYPE 103 Unknown_AddRef( 104 IUnknown* unknown_this); 105 106 ULONG 107 STDMETHODCALLTYPE 108 Unknown_Release( 109 IUnknown* unknown_this); 110 111 typedef struct CUnknown 112 { 113 __GNU_EXTENSION union 114 { 115 IUnknown IUnknown; 116 INonDelegatingUnknown INonDelegatingUnknown; 117 }; 118 119 LONG m_ref_count; 120 PUNKNOWN m_outer_unknown; 121 } CUnknown; 122 123 #endif /* __cplusplus */ 124 125 126 127 #ifdef __cplusplus 128 129 130 /* =============================================================== 131 Construction helpers 132 */ 133 134 #define QICAST(typename) \ 135 PVOID( (typename) (this) ) 136 137 #define QICASTUNKNOWN(typename) \ 138 PVOID( PUNKNOWN( (typename) (this) ) ) 139 140 #define STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, base) \ 141 classname *new_ptr = new(pool_type, tag) classname(outer_unknown); \ 142 \ 143 if ( ! new_ptr ) \ 144 return STATUS_INSUFFICIENT_RESOURCES; \ 145 \ 146 *unknown = PUNKNOWN((base)(new_ptr)); \ 147 (*unknown)->AddRef(); \ 148 return STATUS_SUCCESS 149 150 #define STD_CREATE_BODY_WITH_TAG(classname, unknown, outer_unknown, pool_type, tag, base) \ 151 STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, PUNKNOWN) 152 153 #define STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, base) \ 154 STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, 'rCcP', base) 155 156 #define STD_CREATE_BODY(classname, unknown, outer_unknown, pool_type) \ 157 STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, PUNKNOWN) 158 159 160 /* =============================================================== 161 Custom "new" and "delete" C++ operators 162 */ 163 164 #ifndef _NEW_DELETE_OPERATORS_ 165 #define _NEW_DELETE_OPERATORS_ 166 167 inline PVOID 168 KCOM_New( 169 size_t size, 170 POOL_TYPE pool_type, 171 ULONG tag) 172 { 173 PVOID result; 174 175 result = ExAllocatePoolWithTag(pool_type, size, tag); 176 177 if ( result ) 178 RtlZeroMemory(result, size); 179 180 return result; 181 } 182 183 inline PVOID 184 operator new ( 185 size_t size, 186 POOL_TYPE pool_type) 187 { 188 return KCOM_New(size, pool_type, 'wNcP'); 189 } 190 191 inline PVOID 192 operator new ( 193 size_t size, 194 POOL_TYPE pool_type, 195 ULONG tag) 196 { 197 return KCOM_New(size, pool_type, tag); 198 } 199 200 inline void __cdecl 201 operator delete( 202 PVOID ptr) 203 { 204 ExFreePool(ptr); 205 } 206 207 inline void __cdecl 208 operator delete( 209 PVOID ptr, UINT_PTR) 210 { 211 ExFreePool(ptr); 212 } 213 214 #endif /* _NEW_DELETE_OPERATORS_ */ 215 216 217 #else /* Being compiled with C */ 218 219 220 #endif /* __cplusplus */ 221 222 #endif /* include guard */ 223