| 1 | /** | 
 
 
 
 
 | 2 | * This file has no copyright assigned and is placed in the Public Domain. | 
 
 
 
 
 | 3 | * This file is part of the mingw-w64 runtime package. | 
 
 
 
 
 | 4 | * No warranty is given; refer to the file DISCLAIMER.PD within this package. | 
 
 
 
 
 | 5 | */ | 
 
 
 
 
 | 6 |  | 
 
 
 
 
 | 7 | #ifndef _WRL_CLIENT_H_ | 
 
 
 
 
 | 8 | #define _WRL_CLIENT_H_ | 
 
 
 
 
 | 9 |  | 
 
 
 
 
 | 10 | #include <stddef.h> | 
 
 
 
 
 | 11 | #include <unknwn.h> | 
 
 
 
 
 | 12 | /* #include <weakreference.h> */ | 
 
 
 
 
 | 13 | #include <roapi.h> | 
 
 
 
 
 | 14 |  | 
 
 
 
 
 | 15 | /* #include <wrl/def.h> */ | 
 
 
 
 
 | 16 | #include <wrl/internal.h> | 
 
 
 
 
 | 17 |  | 
 
 
 
 
 | 18 | namespace Microsoft { | 
 
 
 
 
 | 19 | namespace WRL { | 
 
 
 
 
 | 20 | namespace Details { | 
 
 
 
 
 | 21 | template <typename T> class ComPtrRefBase { | 
 
 
 
 
 | 22 | protected: | 
 
 
 
 
 | 23 | T* ptr_; | 
 
 
 
 
 | 24 |  | 
 
 
 
 
 | 25 | public: | 
 
 
 
 
 | 26 | typedef typename T::InterfaceType InterfaceType; | 
 
 
 
 
 | 27 |  | 
 
 
 
 
 | 28 | #ifndef __WRL_CLASSIC_COM__ | 
 
 
 
 
 | 29 | operator IInspectable**() const throw()  { | 
 
 
 
 
 | 30 | static_assert(__is_base_of(IInspectable, InterfaceType), "Invalid cast"); | 
 
 
 
 
 | 31 | return reinterpret_cast<IInspectable**>(ptr_->ReleaseAndGetAddressOf()); | 
 
 
 
 
 | 32 | } | 
 
 
 
 
 | 33 | #endif | 
 
 
 
 
 | 34 |  | 
 
 
 
 
 | 35 | operator IUnknown**() const throw() { | 
 
 
 
 
 | 36 | static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast"); | 
 
 
 
 
 | 37 | return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf()); | 
 
 
 
 
 | 38 | } | 
 
 
 
 
 | 39 | }; | 
 
 
 
 
 | 40 |  | 
 
 
 
 
 | 41 | template <typename T> class ComPtrRef : public Details::ComPtrRefBase<T> { | 
 
 
 
 
 | 42 | public: | 
 
 
 
 
 | 43 | ComPtrRef(T *ptr) throw() { | 
 
 
 
 
 | 44 | ComPtrRefBase<T>::ptr_ = ptr; | 
 
 
 
 
 | 45 | } | 
 
 
 
 
 | 46 |  | 
 
 
 
 
 | 47 | operator void**() const throw() { | 
 
 
 
 
 | 48 | return reinterpret_cast<void**>(ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf()); | 
 
 
 
 
 | 49 | } | 
 
 
 
 
 | 50 |  | 
 
 
 
 
 | 51 | operator T*() throw() { | 
 
 
 
 
 | 52 | *ComPtrRefBase<T>::ptr_ = nullptr; | 
 
 
 
 
 | 53 | return ComPtrRefBase<T>::ptr_; | 
 
 
 
 
 | 54 | } | 
 
 
 
 
 | 55 |  | 
 
 
 
 
 | 56 | operator typename ComPtrRefBase<T>::InterfaceType**() throw() { | 
 
 
 
 
 | 57 | return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf(); | 
 
 
 
 
 | 58 | } | 
 
 
 
 
 | 59 |  | 
 
 
 
 
 | 60 | typename ComPtrRefBase<T>::InterfaceType *operator*() throw() { | 
 
 
 
 
 | 61 | return ComPtrRefBase<T>::ptr_->Get(); | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | typename ComPtrRefBase<T>::InterfaceType *const *GetAddressOf() const throw() { | 
 
 
 
 
 | 65 | return ComPtrRefBase<T>::ptr_->GetAddressOf(); | 
 
 
 
 
 | 66 | } | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | typename ComPtrRefBase<T>::InterfaceType **ReleaseAndGetAddressOf() throw() { | 
 
 
 
 
 | 69 | return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf(); | 
 
 
 
 
 | 70 | } | 
 
 
 
 
 | 71 | }; | 
 
 
 
 
 | 72 |  | 
 
 
 
 
 | 73 | } | 
 
 
 
 
 | 74 |  | 
 
 
 
 
 | 75 | template<typename T> class ComPtr { | 
 
 
 
 
 | 76 | public: | 
 
 
 
 
 | 77 | typedef T InterfaceType; | 
 
 
 
 
 | 78 |  | 
 
 
 
 
 | 79 | ComPtr() throw() : ptr_(nullptr) {} | 
 
 
 
 
 | 80 | ComPtr(decltype(nullptr)) throw() : ptr_(nullptr) {} | 
 
 
 
 
 | 81 |  | 
 
 
 
 
 | 82 | template<class U> ComPtr(U *other) throw() : ptr_(other) { | 
 
 
 
 
 | 83 | InternalAddRef(); | 
 
 
 
 
 | 84 | } | 
 
 
 
 
 | 85 |  | 
 
 
 
 
 | 86 | ComPtr(const ComPtr &other) throw() : ptr_(other.ptr_) { | 
 
 
 
 
 | 87 | InternalAddRef(); | 
 
 
 
 
 | 88 | } | 
 
 
 
 
 | 89 |  | 
 
 
 
 
 | 90 | template<class U> | 
 
 
 
 
 | 91 | ComPtr(const ComPtr<U> &other) throw() : ptr_(other.Get()) { | 
 
 
 
 
 | 92 | InternalAddRef(); | 
 
 
 
 
 | 93 | } | 
 
 
 
 
 | 94 |  | 
 
 
 
 
 | 95 | ComPtr(ComPtr &&other) throw() : ptr_(nullptr) { | 
 
 
 
 
 | 96 | if(this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other))) | 
 
 
 
 
 | 97 | Swap(other); | 
 
 
 
 
 | 98 | } | 
 
 
 
 
 | 99 |  | 
 
 
 
 
 | 100 | template<class U> | 
 
 
 
 
 | 101 | ComPtr(ComPtr<U>&& other) throw() : ptr_(other.Detach()) {} | 
 
 
 
 
 | 102 |  | 
 
 
 
 
 | 103 | ~ComPtr() throw() { | 
 
 
 
 
 | 104 | InternalRelease(); | 
 
 
 
 
 | 105 | } | 
 
 
 
 
 | 106 |  | 
 
 
 
 
 | 107 | ComPtr &operator=(decltype(nullptr)) throw() { | 
 
 
 
 
 | 108 | InternalRelease(); | 
 
 
 
 
 | 109 | return *this; | 
 
 
 
 
 | 110 | } | 
 
 
 
 
 | 111 |  | 
 
 
 
 
 | 112 | ComPtr &operator=(InterfaceType *other) throw() { | 
 
 
 
 
 | 113 | if (ptr_ != other) { | 
 
 
 
 
 | 114 | InternalRelease(); | 
 
 
 
 
 | 115 | ptr_ = other; | 
 
 
 
 
 | 116 | InternalAddRef(); | 
 
 
 
 
 | 117 | } | 
 
 
 
 
 | 118 | return *this; | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 |  | 
 
 
 
 
 | 121 | template<typename U> | 
 
 
 
 
 | 122 | ComPtr &operator=(U *other) throw()  { | 
 
 
 
 
 | 123 | if (ptr_ != other) { | 
 
 
 
 
 | 124 | InternalRelease(); | 
 
 
 
 
 | 125 | ptr_ = other; | 
 
 
 
 
 | 126 | InternalAddRef(); | 
 
 
 
 
 | 127 | } | 
 
 
 
 
 | 128 | return *this; | 
 
 
 
 
 | 129 | } | 
 
 
 
 
 | 130 |  | 
 
 
 
 
 | 131 | ComPtr& operator=(const ComPtr &other) throw() { | 
 
 
 
 
 | 132 | if (ptr_ != other.ptr_) | 
 
 
 
 
 | 133 | ComPtr(other).Swap(*this); | 
 
 
 
 
 | 134 | return *this; | 
 
 
 
 
 | 135 | } | 
 
 
 
 
 | 136 |  | 
 
 
 
 
 | 137 | template<class U> | 
 
 
 
 
 | 138 | ComPtr &operator=(const ComPtr<U> &other) throw() { | 
 
 
 
 
 | 139 | ComPtr(other).Swap(*this); | 
 
 
 
 
 | 140 | return *this; | 
 
 
 
 
 | 141 | } | 
 
 
 
 
 | 142 |  | 
 
 
 
 
 | 143 | ComPtr& operator=(ComPtr &&other) throw() { | 
 
 
 
 
 | 144 | ComPtr(other).Swap(*this); | 
 
 
 
 
 | 145 | return *this; | 
 
 
 
 
 | 146 | } | 
 
 
 
 
 | 147 |  | 
 
 
 
 
 | 148 | template<class U> | 
 
 
 
 
 | 149 | ComPtr& operator=(ComPtr<U> &&other) throw() { | 
 
 
 
 
 | 150 | ComPtr(other).Swap(*this); | 
 
 
 
 
 | 151 | return *this; | 
 
 
 
 
 | 152 | } | 
 
 
 
 
 | 153 |  | 
 
 
 
 
 | 154 | void Swap(ComPtr &&r) throw() { | 
 
 
 
 
 | 155 | InterfaceType *tmp = ptr_; | 
 
 
 
 
 | 156 | ptr_ = r.ptr_; | 
 
 
 
 
 | 157 | r.ptr_ = tmp; | 
 
 
 
 
 | 158 | } | 
 
 
 
 
 | 159 |  | 
 
 
 
 
 | 160 | void Swap(ComPtr &r) throw() { | 
 
 
 
 
 | 161 | InterfaceType *tmp = ptr_; | 
 
 
 
 
 | 162 | ptr_ = r.ptr_; | 
 
 
 
 
 | 163 | r.ptr_ = tmp; | 
 
 
 
 
 | 164 | } | 
 
 
 
 
 | 165 |  | 
 
 
 
 
 | 166 | operator Details::BoolType() const throw() { | 
 
 
 
 
 | 167 | return Get() != nullptr ? &Details::BoolStruct::Member : nullptr; | 
 
 
 
 
 | 168 | } | 
 
 
 
 
 | 169 |  | 
 
 
 
 
 | 170 | InterfaceType *Get() const throw()  { | 
 
 
 
 
 | 171 | return ptr_; | 
 
 
 
 
 | 172 | } | 
 
 
 
 
 | 173 |  | 
 
 
 
 
 | 174 | InterfaceType *operator->() const throw() { | 
 
 
 
 
 | 175 | return ptr_; | 
 
 
 
 
 | 176 | } | 
 
 
 
 
 | 177 |  | 
 
 
 
 
 | 178 | Details::ComPtrRef<ComPtr<T>> operator&() throw()  { | 
 
 
 
 
 | 179 | return Details::ComPtrRef<ComPtr<T>>(this); | 
 
 
 
 
 | 180 | } | 
 
 
 
 
 | 181 |  | 
 
 
 
 
 | 182 | const Details::ComPtrRef<const ComPtr<T>> operator&() const throw() { | 
 
 
 
 
 | 183 | return Details::ComPtrRef<const ComPtr<T>>(this); | 
 
 
 
 
 | 184 | } | 
 
 
 
 
 | 185 |  | 
 
 
 
 
 | 186 | InterfaceType *const *GetAddressOf() const throw() { | 
 
 
 
 
 | 187 | return &ptr_; | 
 
 
 
 
 | 188 | } | 
 
 
 
 
 | 189 |  | 
 
 
 
 
 | 190 | InterfaceType **GetAddressOf() throw() { | 
 
 
 
 
 | 191 | return &ptr_; | 
 
 
 
 
 | 192 | } | 
 
 
 
 
 | 193 |  | 
 
 
 
 
 | 194 | InterfaceType **ReleaseAndGetAddressOf() throw() { | 
 
 
 
 
 | 195 | InternalRelease(); | 
 
 
 
 
 | 196 | return &ptr_; | 
 
 
 
 
 | 197 | } | 
 
 
 
 
 | 198 |  | 
 
 
 
 
 | 199 | InterfaceType *Detach() throw() { | 
 
 
 
 
 | 200 | T* ptr = ptr_; | 
 
 
 
 
 | 201 | ptr_ = nullptr; | 
 
 
 
 
 | 202 | return ptr; | 
 
 
 
 
 | 203 | } | 
 
 
 
 
 | 204 |  | 
 
 
 
 
 | 205 | void Attach(InterfaceType *other) throw() { | 
 
 
 
 
 | 206 | if (ptr_ != other) { | 
 
 
 
 
 | 207 | InternalRelease(); | 
 
 
 
 
 | 208 | ptr_ = other; | 
 
 
 
 
 | 209 | InternalAddRef(); | 
 
 
 
 
 | 210 | } | 
 
 
 
 
 | 211 | } | 
 
 
 
 
 | 212 |  | 
 
 
 
 
 | 213 | unsigned long Reset() { | 
 
 
 
 
 | 214 | return InternalRelease(); | 
 
 
 
 
 | 215 | } | 
 
 
 
 
 | 216 |  | 
 
 
 
 
 | 217 | HRESULT CopyTo(InterfaceType **ptr) const throw() { | 
 
 
 
 
 | 218 | InternalAddRef(); | 
 
 
 
 
 | 219 | *ptr = ptr_; | 
 
 
 
 
 | 220 | return S_OK; | 
 
 
 
 
 | 221 | } | 
 
 
 
 
 | 222 |  | 
 
 
 
 
 | 223 | HRESULT CopyTo(REFIID riid, void **ptr) const throw() { | 
 
 
 
 
 | 224 | return ptr_->QueryInterface(riid, ptr); | 
 
 
 
 
 | 225 | } | 
 
 
 
 
 | 226 |  | 
 
 
 
 
 | 227 | template<typename U> | 
 
 
 
 
 | 228 | HRESULT CopyTo(U **ptr) const throw() { | 
 
 
 
 
 | 229 | return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(ptr)); | 
 
 
 
 
 | 230 | } | 
 
 
 
 
 | 231 |  | 
 
 
 
 
 | 232 | template<typename U> | 
 
 
 
 
 | 233 | HRESULT As(Details::ComPtrRef<ComPtr<U>> p) const throw() { | 
 
 
 
 
 | 234 | return ptr_->QueryInterface(__uuidof(U), p); | 
 
 
 
 
 | 235 | } | 
 
 
 
 
 | 236 |  | 
 
 
 
 
 | 237 | template<typename U> | 
 
 
 
 
 | 238 | HRESULT As(ComPtr<U> *p) const throw() { | 
 
 
 
 
 | 239 | return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf())); | 
 
 
 
 
 | 240 | } | 
 
 
 
 
 | 241 |  | 
 
 
 
 
 | 242 | HRESULT AsIID(REFIID riid, ComPtr<IUnknown> *p) const throw() { | 
 
 
 
 
 | 243 | return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf())); | 
 
 
 
 
 | 244 | } | 
 
 
 
 
 | 245 |  | 
 
 
 
 
 | 246 | /* | 
 
 
 
 
 | 247 | HRESULT AsWeak(WeakRef *pWeakRef) const throw() { | 
 
 
 
 
 | 248 | return ::Microsoft::WRL::AsWeak(ptr_, pWeakRef); | 
 
 
 
 
 | 249 | } | 
 
 
 
 
 | 250 | */ | 
 
 
 
 
 | 251 | protected: | 
 
 
 
 
 | 252 | InterfaceType *ptr_; | 
 
 
 
 
 | 253 |  | 
 
 
 
 
 | 254 | void InternalAddRef() const throw() { | 
 
 
 
 
 | 255 | if(ptr_) | 
 
 
 
 
 | 256 | ptr_->AddRef(); | 
 
 
 
 
 | 257 | } | 
 
 
 
 
 | 258 |  | 
 
 
 
 
 | 259 | unsigned long InternalRelease() throw() { | 
 
 
 
 
 | 260 | InterfaceType *tmp = ptr_; | 
 
 
 
 
 | 261 | if(!tmp) | 
 
 
 
 
 | 262 | return 0; | 
 
 
 
 
 | 263 | ptr_ = nullptr; | 
 
 
 
 
 | 264 | return tmp->Release(); | 
 
 
 
 
 | 265 | } | 
 
 
 
 
 | 266 | }; | 
 
 
 
 
 | 267 | } | 
 
 
 
 
 | 268 | } | 
 
 
 
 
 | 269 |  | 
 
 
 
 
 | 270 | template<typename T> | 
 
 
 
 
 | 271 | void **IID_PPV_ARGS_Helper(::Microsoft::WRL::Details::ComPtrRef<T> pp) throw() { | 
 
 
 
 
 | 272 | static_assert(__is_base_of(IUnknown, typename T::InterfaceType), "Expected COM interface"); | 
 
 
 
 
 | 273 | return pp; | 
 
 
 
 
 | 274 | } | 
 
 
 
 
 | 275 |  | 
 
 
 
 
 | 276 | namespace Windows { | 
 
 
 
 
 | 277 | namespace Foundation { | 
 
 
 
 
 | 278 | template<typename T> | 
 
 
 
 
 | 279 | inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() { | 
 
 
 
 
 | 280 | return ActivateInstance(classid, instance.ReleaseAndGetAddressOf()); | 
 
 
 
 
 | 281 | } | 
 
 
 
 
 | 282 |  | 
 
 
 
 
 | 283 | template<typename T> | 
 
 
 
 
 | 284 | inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() { | 
 
 
 
 
 | 285 | return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf())); | 
 
 
 
 
 | 286 | } | 
 
 
 
 
 | 287 | } | 
 
 
 
 
 | 288 | } | 
 
 
 
 
 | 289 |  | 
 
 
 
 
 | 290 | namespace ABI { | 
 
 
 
 
 | 291 | namespace Windows { | 
 
 
 
 
 | 292 | namespace Foundation { | 
 
 
 
 
 | 293 | template<typename T> | 
 
 
 
 
 | 294 | inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() { | 
 
 
 
 
 | 295 | return ActivateInstance(classid, instance.ReleaseAndGetAddressOf()); | 
 
 
 
 
 | 296 | } | 
 
 
 
 
 | 297 |  | 
 
 
 
 
 | 298 | template<typename T> | 
 
 
 
 
 | 299 | inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() { | 
 
 
 
 
 | 300 | return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf())); | 
 
 
 
 
 | 301 | } | 
 
 
 
 
 | 302 | } | 
 
 
 
 
 | 303 | } | 
 
 
 
 
 | 304 | } | 
 
 
 
 
 | 305 |  | 
 
 
 
 
 | 306 | #endif |