Reactos
at listview 222 lines 4.7 kB view raw
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 20DECLARE_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 30typedef 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 42class 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 94NTSTATUS 95STDMETHODCALLTYPE 96Unknown_QueryInterface( 97 IUnknown* this, 98 IN REFIID refiid, 99 OUT PVOID* output); 100 101ULONG 102STDMETHODCALLTYPE 103Unknown_AddRef( 104 IUnknown* unknown_this); 105 106ULONG 107STDMETHODCALLTYPE 108Unknown_Release( 109 IUnknown* unknown_this); 110 111typedef 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 167inline PVOID 168KCOM_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 183inline PVOID 184operator new ( 185 size_t size, 186 POOL_TYPE pool_type) 187{ 188 return KCOM_New(size, pool_type, 'wNcP'); 189} 190 191inline PVOID 192operator new ( 193 size_t size, 194 POOL_TYPE pool_type, 195 ULONG tag) 196{ 197 return KCOM_New(size, pool_type, tag); 198} 199 200inline void __cdecl 201operator delete( 202 PVOID ptr) 203{ 204 ExFreePool(ptr); 205} 206 207inline void __cdecl 208operator 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 */