wrladapter.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. // Copyright (c) Microsoft Corporation.
  2. // Licensed under the MIT License.
  3. #pragma once
  4. #include "winadapter.h"
  5. // defined by winadapter.h and needed by some windows headers, but conflicts
  6. // with some libc++ implementation headers
  7. #ifdef __in
  8. #undef __in
  9. #endif
  10. #ifdef __out
  11. #undef __out
  12. #endif
  13. #include <type_traits>
  14. #include <atomic>
  15. #include <memory>
  16. #include <new>
  17. #include <climits>
  18. #include <cassert>
  19. namespace Microsoft
  20. {
  21. namespace WRL
  22. {
  23. namespace Details
  24. {
  25. struct BoolStruct { int Member; };
  26. typedef int BoolStruct::* BoolType;
  27. template <typename T> // T should be the ComPtr<T> or a derived type of it, not just the interface
  28. class ComPtrRefBase
  29. {
  30. public:
  31. typedef typename T::InterfaceType InterfaceType;
  32. operator IUnknown**() const throw()
  33. {
  34. static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast: InterfaceType does not derive from IUnknown");
  35. return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf());
  36. }
  37. protected:
  38. T* ptr_;
  39. };
  40. template <typename T>
  41. class ComPtrRef : public Details::ComPtrRefBase<T> // T should be the ComPtr<T> or a derived type of it, not just the interface
  42. {
  43. using Super = Details::ComPtrRefBase<T>;
  44. using InterfaceType = typename Super::InterfaceType;
  45. public:
  46. ComPtrRef(_In_opt_ T* ptr) throw()
  47. {
  48. this->ptr_ = ptr;
  49. }
  50. // Conversion operators
  51. operator void**() const throw()
  52. {
  53. return reinterpret_cast<void**>(this->ptr_->ReleaseAndGetAddressOf());
  54. }
  55. // This is our operator ComPtr<U> (or the latest derived class from ComPtr (e.g. WeakRef))
  56. operator T*() throw()
  57. {
  58. *this->ptr_ = nullptr;
  59. return this->ptr_;
  60. }
  61. // We define operator InterfaceType**() here instead of on ComPtrRefBase<T>, since
  62. // if InterfaceType is IUnknown or IInspectable, having it on the base will collide.
  63. operator InterfaceType**() throw()
  64. {
  65. return this->ptr_->ReleaseAndGetAddressOf();
  66. }
  67. // This is used for IID_PPV_ARGS in order to do __uuidof(**(ppType)).
  68. // It does not need to clear ptr_ at this point, it is done at IID_PPV_ARGS_Helper(ComPtrRef&) later in this file.
  69. InterfaceType* operator *() throw()
  70. {
  71. return this->ptr_->Get();
  72. }
  73. // Explicit functions
  74. InterfaceType* const * GetAddressOf() const throw()
  75. {
  76. return this->ptr_->GetAddressOf();
  77. }
  78. InterfaceType** ReleaseAndGetAddressOf() throw()
  79. {
  80. return this->ptr_->ReleaseAndGetAddressOf();
  81. }
  82. };
  83. }
  84. template <typename T>
  85. class ComPtr
  86. {
  87. public:
  88. typedef T InterfaceType;
  89. protected:
  90. InterfaceType *ptr_;
  91. template<class U> friend class ComPtr;
  92. void InternalAddRef() const throw()
  93. {
  94. if (ptr_ != nullptr)
  95. {
  96. ptr_->AddRef();
  97. }
  98. }
  99. unsigned long InternalRelease() throw()
  100. {
  101. unsigned long ref = 0;
  102. T* temp = ptr_;
  103. if (temp != nullptr)
  104. {
  105. ptr_ = nullptr;
  106. ref = temp->Release();
  107. }
  108. return ref;
  109. }
  110. public:
  111. ComPtr() throw() : ptr_(nullptr)
  112. {
  113. }
  114. ComPtr(decltype(nullptr)) throw() : ptr_(nullptr)
  115. {
  116. }
  117. template<class U>
  118. ComPtr(_In_opt_ U *other) throw() : ptr_(other)
  119. {
  120. InternalAddRef();
  121. }
  122. ComPtr(const ComPtr& other) throw() : ptr_(other.ptr_)
  123. {
  124. InternalAddRef();
  125. }
  126. // copy constructor that allows to instantiate class when U* is convertible to T*
  127. template<class U>
  128. ComPtr(const ComPtr<U> &other, typename std::enable_if<std::is_convertible<U*, T*>::value, void *>::type * = 0) throw() :
  129. ptr_(other.ptr_)
  130. {
  131. InternalAddRef();
  132. }
  133. ComPtr(_Inout_ ComPtr &&other) throw() : ptr_(nullptr)
  134. {
  135. if (this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other)))
  136. {
  137. Swap(other);
  138. }
  139. }
  140. // Move constructor that allows instantiation of a class when U* is convertible to T*
  141. template<class U>
  142. ComPtr(_Inout_ ComPtr<U>&& other, typename std::enable_if<std::is_convertible<U*, T*>::value, void *>::type * = 0) throw() :
  143. ptr_(other.ptr_)
  144. {
  145. other.ptr_ = nullptr;
  146. }
  147. ~ComPtr() throw()
  148. {
  149. InternalRelease();
  150. }
  151. ComPtr& operator=(decltype(nullptr)) throw()
  152. {
  153. InternalRelease();
  154. return *this;
  155. }
  156. ComPtr& operator=(_In_opt_ T *other) throw()
  157. {
  158. if (ptr_ != other)
  159. {
  160. ComPtr(other).Swap(*this);
  161. }
  162. return *this;
  163. }
  164. template <typename U>
  165. ComPtr& operator=(_In_opt_ U *other) throw()
  166. {
  167. ComPtr(other).Swap(*this);
  168. return *this;
  169. }
  170. ComPtr& operator=(const ComPtr &other) throw()
  171. {
  172. if (ptr_ != other.ptr_)
  173. {
  174. ComPtr(other).Swap(*this);
  175. }
  176. return *this;
  177. }
  178. template<class U>
  179. ComPtr& operator=(const ComPtr<U>& other) throw()
  180. {
  181. ComPtr(other).Swap(*this);
  182. return *this;
  183. }
  184. ComPtr& operator=(_Inout_ ComPtr &&other) throw()
  185. {
  186. ComPtr(static_cast<ComPtr&&>(other)).Swap(*this);
  187. return *this;
  188. }
  189. template<class U>
  190. ComPtr& operator=(_Inout_ ComPtr<U>&& other) throw()
  191. {
  192. ComPtr(static_cast<ComPtr<U>&&>(other)).Swap(*this);
  193. return *this;
  194. }
  195. void Swap(_Inout_ ComPtr&& r) throw()
  196. {
  197. T* tmp = ptr_;
  198. ptr_ = r.ptr_;
  199. r.ptr_ = tmp;
  200. }
  201. void Swap(_Inout_ ComPtr& r) throw()
  202. {
  203. T* tmp = ptr_;
  204. ptr_ = r.ptr_;
  205. r.ptr_ = tmp;
  206. }
  207. operator Details::BoolType() const throw()
  208. {
  209. return Get() != nullptr ? &Details::BoolStruct::Member : nullptr;
  210. }
  211. T* Get() const throw()
  212. {
  213. return ptr_;
  214. }
  215. InterfaceType* operator->() const throw()
  216. {
  217. return ptr_;
  218. }
  219. Details::ComPtrRef<ComPtr<T>> operator&() throw()
  220. {
  221. return Details::ComPtrRef<ComPtr<T>>(this);
  222. }
  223. const Details::ComPtrRef<const ComPtr<T>> operator&() const throw()
  224. {
  225. return Details::ComPtrRef<const ComPtr<T>>(this);
  226. }
  227. T* const* GetAddressOf() const throw()
  228. {
  229. return &ptr_;
  230. }
  231. T** GetAddressOf() throw()
  232. {
  233. return &ptr_;
  234. }
  235. T** ReleaseAndGetAddressOf() throw()
  236. {
  237. InternalRelease();
  238. return &ptr_;
  239. }
  240. T* Detach() throw()
  241. {
  242. T* ptr = ptr_;
  243. ptr_ = nullptr;
  244. return ptr;
  245. }
  246. void Attach(_In_opt_ InterfaceType* other) throw()
  247. {
  248. if (ptr_ != nullptr)
  249. {
  250. auto ref = ptr_->Release();
  251. // DBG_UNREFERENCED_LOCAL_VARIABLE(ref);
  252. // Attaching to the same object only works if duplicate references are being coalesced. Otherwise
  253. // re-attaching will cause the pointer to be released and may cause a crash on a subsequent dereference.
  254. assert(ref != 0 || ptr_ != other);
  255. }
  256. ptr_ = other;
  257. }
  258. unsigned long Reset()
  259. {
  260. return InternalRelease();
  261. }
  262. // Previously, unsafe behavior could be triggered when 'this' is ComPtr<IInspectable> or ComPtr<IUnknown> and CopyTo is used to copy to another type U.
  263. // The user will use operator& to convert the destination into a ComPtrRef, which can then implicit cast to IInspectable** and IUnknown**.
  264. // If this overload of CopyTo is not present, it will implicitly cast to IInspectable or IUnknown and match CopyTo(InterfaceType**) instead.
  265. // A valid polymoprhic downcast requires run-time type checking via QueryInterface, so CopyTo(InterfaceType**) will break type safety.
  266. // This overload matches ComPtrRef before the implicit cast takes place, preventing the unsafe downcast.
  267. template <typename U>
  268. HRESULT CopyTo(Details::ComPtrRef<ComPtr<U>> ptr, typename std::enable_if<
  269. (std::is_same<T, IUnknown>::value)
  270. && !std::is_same<U*, T*>::value, void *>::type * = 0) const throw()
  271. {
  272. return ptr_->QueryInterface(__uuidof(U), ptr);
  273. }
  274. HRESULT CopyTo(_Outptr_result_maybenull_ InterfaceType** ptr) const throw()
  275. {
  276. InternalAddRef();
  277. *ptr = ptr_;
  278. return S_OK;
  279. }
  280. HRESULT CopyTo(REFIID riid, _Outptr_result_nullonfailure_ void** ptr) const throw()
  281. {
  282. return ptr_->QueryInterface(riid, ptr);
  283. }
  284. template<typename U>
  285. HRESULT CopyTo(_Outptr_result_nullonfailure_ U** ptr) const throw()
  286. {
  287. return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(ptr));
  288. }
  289. // query for U interface
  290. template<typename U>
  291. HRESULT As(_Inout_ Details::ComPtrRef<ComPtr<U>> p) const throw()
  292. {
  293. return ptr_->QueryInterface(__uuidof(U), p);
  294. }
  295. // query for U interface
  296. template<typename U>
  297. HRESULT As(_Out_ ComPtr<U>* p) const throw()
  298. {
  299. return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
  300. }
  301. // query for riid interface and return as IUnknown
  302. HRESULT AsIID(REFIID riid, _Out_ ComPtr<IUnknown>* p) const throw()
  303. {
  304. return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
  305. }
  306. }; // ComPtr
  307. namespace Details
  308. {
  309. // Empty struct used as default template parameter
  310. class Nil
  311. {
  312. };
  313. // Empty struct used for validating template parameter types in Implements
  314. struct ImplementsBase
  315. {
  316. };
  317. class RuntimeClassBase
  318. {
  319. protected:
  320. template<typename T>
  321. static HRESULT AsIID(_In_ T* implements, REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) noexcept
  322. {
  323. *ppvObject = nullptr;
  324. bool isRefDelegated = false;
  325. // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
  326. if (InlineIsEqualGUID(riid, __uuidof(IUnknown)))
  327. {
  328. *ppvObject = implements->CastToUnknown();
  329. static_cast<IUnknown*>(*ppvObject)->AddRef();
  330. return S_OK;
  331. }
  332. HRESULT hr = implements->CanCastTo(riid, ppvObject, &isRefDelegated);
  333. if (SUCCEEDED(hr) && !isRefDelegated)
  334. {
  335. static_cast<IUnknown*>(*ppvObject)->AddRef();
  336. }
  337. #ifdef _MSC_VER
  338. #pragma warning(push)
  339. #pragma warning(disable: 6102) // '*ppvObject' is used but may not be initialized
  340. #endif
  341. _Analysis_assume_(SUCCEEDED(hr) || (*ppvObject == nullptr));
  342. #ifdef _MSC_VER
  343. #pragma warning(pop)
  344. #endif
  345. return hr;
  346. }
  347. public:
  348. HRESULT RuntimeClassInitialize() noexcept
  349. {
  350. return S_OK;
  351. }
  352. };
  353. // Interface traits provides casting and filling iids methods helpers
  354. template<typename I0>
  355. struct InterfaceTraits
  356. {
  357. typedef I0 Base;
  358. template<typename T>
  359. static Base* CastToBase(_In_ T* ptr) noexcept
  360. {
  361. return static_cast<Base*>(ptr);
  362. }
  363. template<typename T>
  364. static IUnknown* CastToUnknown(_In_ T* ptr) noexcept
  365. {
  366. return static_cast<IUnknown*>(static_cast<Base*>(ptr));
  367. }
  368. template <typename T>
  369. _Success_(return == true)
  370. static bool CanCastTo(_In_ T* ptr, REFIID riid, _Outptr_ void **ppv) noexcept
  371. {
  372. // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
  373. if (InlineIsEqualGUID(riid, __uuidof(Base)))
  374. {
  375. *ppv = static_cast<Base*>(ptr);
  376. return true;
  377. }
  378. return false;
  379. }
  380. };
  381. // Specialization for Nil parameter
  382. template<>
  383. struct InterfaceTraits<Nil>
  384. {
  385. typedef Nil Base;
  386. template <typename T>
  387. _Success_(return == true)
  388. static bool CanCastTo(_In_ T*, REFIID, _Outptr_ void **) noexcept
  389. {
  390. return false;
  391. }
  392. };
  393. // ChainInterfaces - template allows specifying a derived COM interface along with its class hierarchy to allow QI for the base interfaces
  394. template <typename I0, typename I1, typename I2 = Nil, typename I3 = Nil,
  395. typename I4 = Nil, typename I5 = Nil, typename I6 = Nil,
  396. typename I7 = Nil, typename I8 = Nil, typename I9 = Nil>
  397. struct ChainInterfaces : I0
  398. {
  399. protected:
  400. HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
  401. {
  402. typename InterfaceTraits<I0>::Base* ptr = InterfaceTraits<I0>::CastToBase(this);
  403. return (InterfaceTraits<I0>::CanCastTo(this, riid, ppv) ||
  404. InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
  405. InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
  406. InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
  407. InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
  408. InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
  409. InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
  410. InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
  411. InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
  412. InterfaceTraits<I9>::CanCastTo(ptr, riid, ppv)) ? S_OK : E_NOINTERFACE;
  413. }
  414. IUnknown* CastToUnknown() throw()
  415. {
  416. return InterfaceTraits<I0>::CastToUnknown(this);
  417. }
  418. };
  419. // Helper template used by Implements. This template traverses a list of interfaces and adds them as base class and information
  420. // to enable QI.
  421. template <typename ...TInterfaces>
  422. struct ImplementsHelper;
  423. template <typename T>
  424. struct ImplementsMarker
  425. {};
  426. template <typename I0, bool isImplements>
  427. struct MarkImplements;
  428. template <typename I0>
  429. struct MarkImplements<I0, false>
  430. {
  431. typedef I0 Type;
  432. };
  433. template <typename I0>
  434. struct MarkImplements<I0, true>
  435. {
  436. typedef ImplementsMarker<I0> Type;
  437. };
  438. // AdjustImplements pre-processes the type list for more efficient builds.
  439. template <typename ...Bases>
  440. struct AdjustImplements;
  441. template <typename I0, typename ...Bases>
  442. struct AdjustImplements<I0, Bases...>
  443. {
  444. typedef ImplementsHelper<typename MarkImplements<I0, std::is_base_of<ImplementsBase, I0>::value>::Type, Bases...> Type;
  445. };
  446. // Use AdjustImplements to remove instances of "Nil" from the type list.
  447. template <typename ...Bases>
  448. struct AdjustImplements<Nil, Bases...>
  449. {
  450. typedef typename AdjustImplements<Bases...>::Type Type;
  451. };
  452. template <>
  453. struct AdjustImplements<>
  454. {
  455. typedef ImplementsHelper<> Type;
  456. };
  457. // Specialization handles unadorned interfaces
  458. template <typename I0, typename ...TInterfaces>
  459. struct ImplementsHelper<I0, TInterfaces...> :
  460. I0,
  461. AdjustImplements<TInterfaces...>::Type
  462. {
  463. template <typename ...> friend struct ImplementsHelper;
  464. friend class RuntimeClassBase;
  465. protected:
  466. HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
  467. {
  468. // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
  469. if (InlineIsEqualGUID(riid, __uuidof(I0)))
  470. {
  471. *ppv = reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
  472. return S_OK;
  473. }
  474. return AdjustImplements<TInterfaces...>::Type::CanCastTo(riid, ppv, pRefDelegated);
  475. }
  476. IUnknown* CastToUnknown() noexcept
  477. {
  478. return reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
  479. }
  480. };
  481. // Selector is used to "tag" base interfaces to be used in casting, since a runtime class may indirectly derive from
  482. // the same interface or Implements<> template multiple times
  483. template <typename base, typename disciminator>
  484. struct Selector : public base
  485. {
  486. };
  487. // Specialization handles types that derive from ImplementsHelper (e.g. nested Implements).
  488. template <typename I0, typename ...TInterfaces>
  489. struct ImplementsHelper<ImplementsMarker<I0>, TInterfaces...> :
  490. Selector<I0, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>>,
  491. Selector<typename AdjustImplements<TInterfaces...>::Type, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>>
  492. {
  493. template <typename ...> friend struct ImplementsHelper;
  494. friend class RuntimeClassBase;
  495. protected:
  496. typedef Selector<I0, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>> CurrentType;
  497. typedef Selector<typename AdjustImplements<TInterfaces...>::Type, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>> BaseType;
  498. HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
  499. {
  500. HRESULT hr = CurrentType::CanCastTo(riid, ppv);
  501. if (hr == E_NOINTERFACE)
  502. {
  503. hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
  504. }
  505. return hr;
  506. }
  507. IUnknown* CastToUnknown() noexcept
  508. {
  509. // First in list wins.
  510. return CurrentType::CastToUnknown();
  511. }
  512. };
  513. // terminal case specialization.
  514. template <>
  515. struct ImplementsHelper<>
  516. {
  517. template <typename ...> friend struct ImplementsHelper;
  518. friend class RuntimeClassBase;
  519. protected:
  520. HRESULT CanCastTo(_In_ REFIID /*riid*/, _Outptr_ void ** /*ppv*/, bool * /*pRefDelegated*/ = nullptr) noexcept
  521. {
  522. return E_NOINTERFACE;
  523. }
  524. // IUnknown* CastToUnknown() noexcept; // not defined for terminal case.
  525. };
  526. // Specialization handles chaining interfaces
  527. template <typename C0, typename C1, typename C2, typename C3, typename C4, typename C5, typename C6, typename C7, typename C8, typename C9, typename ...TInterfaces>
  528. struct ImplementsHelper<ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>, TInterfaces...> :
  529. ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>,
  530. AdjustImplements<TInterfaces...>::Type
  531. {
  532. template <typename ...> friend struct ImplementsHelper;
  533. friend class RuntimeClassBase;
  534. protected:
  535. typedef typename AdjustImplements<TInterfaces...>::Type BaseType;
  536. HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
  537. {
  538. HRESULT hr = ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CanCastTo(riid, ppv);
  539. if (FAILED(hr))
  540. {
  541. hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
  542. }
  543. return hr;
  544. }
  545. IUnknown* CastToUnknown() noexcept
  546. {
  547. return ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CastToUnknown();
  548. }
  549. };
  550. // Implements - template implementing QI using the information provided through its template parameters
  551. // Each template parameter has to be one of the following:
  552. // * COM Interface
  553. // * A class that implements one or more COM interfaces
  554. // * ChainInterfaces template
  555. template <typename I0, typename ...TInterfaces>
  556. struct Implements :
  557. AdjustImplements<I0, TInterfaces...>::Type,
  558. ImplementsBase
  559. {
  560. public:
  561. typedef I0 FirstInterface;
  562. protected:
  563. typedef typename AdjustImplements<I0, TInterfaces...>::Type BaseType;
  564. template <typename ...> friend struct ImplementsHelper;
  565. friend class RuntimeClassBase;
  566. HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) noexcept
  567. {
  568. return BaseType::CanCastTo(riid, ppv);
  569. }
  570. IUnknown* CastToUnknown() noexcept
  571. {
  572. return BaseType::CastToUnknown();
  573. }
  574. };
  575. // Used on RuntimeClass to protect it from being constructed with new
  576. class DontUseNewUseMake
  577. {
  578. private:
  579. void* operator new(size_t) noexcept
  580. {
  581. assert(false);
  582. return 0;
  583. }
  584. public:
  585. void* operator new(size_t, _In_ void* placement) noexcept
  586. {
  587. return placement;
  588. }
  589. };
  590. template <typename ...TInterfaces>
  591. class RuntimeClassImpl :
  592. public AdjustImplements<TInterfaces...>::Type,
  593. public RuntimeClassBase,
  594. public DontUseNewUseMake
  595. {
  596. public:
  597. STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject)
  598. {
  599. return Super::AsIID(this, riid, ppvObject);
  600. }
  601. STDMETHOD_(ULONG, AddRef)()
  602. {
  603. return InternalAddRef();
  604. }
  605. STDMETHOD_(ULONG, Release)()
  606. {
  607. ULONG ref = InternalRelease();
  608. if (ref == 0)
  609. {
  610. this->~RuntimeClassImpl();
  611. delete[] reinterpret_cast<char*>(this);
  612. }
  613. return ref;
  614. }
  615. protected:
  616. using Super = RuntimeClassBase;
  617. static const LONG c_lProtectDestruction = -(LONG_MAX / 2);
  618. RuntimeClassImpl() noexcept = default;
  619. virtual ~RuntimeClassImpl() noexcept
  620. {
  621. // Set refcount_ to -(LONG_MAX/2) to protect destruction and
  622. // also catch mismatched Release in debug builds
  623. refcount_ = static_cast<ULONG>(c_lProtectDestruction);
  624. }
  625. ULONG InternalAddRef() noexcept
  626. {
  627. return ++refcount_;
  628. }
  629. ULONG InternalRelease() noexcept
  630. {
  631. return --refcount_;
  632. }
  633. unsigned long GetRefCount() const noexcept
  634. {
  635. return refcount_;
  636. }
  637. std::atomic<ULONG> refcount_{1};
  638. };
  639. }
  640. template <typename ...TInterfaces>
  641. class Base : public Details::RuntimeClassImpl<TInterfaces...>
  642. {
  643. Base(const Base&) = delete;
  644. Base& operator=(const Base&) = delete;
  645. protected:
  646. HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled)
  647. {
  648. *handled = false;
  649. return S_OK;
  650. }
  651. public:
  652. Base() throw() = default;
  653. typedef Base RuntimeClassT;
  654. };
  655. // Creates a Nano-COM object wrapped in a smart pointer.
  656. template <typename T, typename ...TArgs>
  657. ComPtr<T> Make(TArgs&&... args)
  658. {
  659. std::unique_ptr<char[]> buffer(new(std::nothrow) char[sizeof(T)]);
  660. ComPtr<T> object;
  661. if (buffer)
  662. {
  663. T* ptr = new (buffer.get())T(std::forward<TArgs>(args)...);
  664. object.Attach(ptr);
  665. buffer.release();
  666. }
  667. return object;
  668. }
  669. using Details::ChainInterfaces;
  670. }
  671. }
  672. // Overloaded global function to provide to IID_PPV_ARGS that support Details::ComPtrRef
  673. template<typename T>
  674. void** IID_PPV_ARGS_Helper(Microsoft::WRL::Details::ComPtrRef<T> pp) throw()
  675. {
  676. return pp;
  677. }