Nui
implements.h
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
4 //
5 // Code in Details namespace is for internal usage within the library code
6 //
7 
8 #ifndef _WRL_IMPLEMENTS_H_
9 #define _WRL_IMPLEMENTS_H_
10 
11 #ifdef _MSC_VER
12 # pragma once
13 #endif // _MSC_VER
14 
15 #pragma region includes
16 
17 #include <inspectable.h>
18 #include <roapi.h>
19 #ifdef BUILD_WINDOWS
20 # include <winrt.h>
21 #endif
22 #include <activation.h>
23 #include <WinString.h>
24 
25 #include <new.h>
26 #include <weakreference.h>
27 #include <objbase.h> // IMarshal
28 #include <cguid.h> // CLSID_StdGlobalInterfaceTable
29 #include <intrin.h>
30 
31 #include <wrl\internal.h>
32 #include <wrl\def.h>
33 #include <wrl\client.h>
34 
35 // #if (NTDDI_VERSION >= NTDDI_WINBLUE)
36 // #define WRL_RO_ERROR_API_ENABLED
37 // #endif
38 
39 #ifdef WRL_RO_ERROR_API_ENABLED
40 # include "roerrorapi.h"
41 #endif
42 
43 // Set packing
44 #pragma pack(push, 8)
45 
46 #pragma endregion
47 
48 #ifdef _MSC_VER
49 # pragma region disable warnings
50 
51 # pragma warning(push)
52 # pragma warning(disable : 4584) // 'class1' : base-class 'class2' is already a base-class of 'class3'
53 # pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override'
54 
55 # pragma endregion // disable warnings
56 
57 # define WRT_NO_VTABLE __declspec(novtable)
58 #else
59 # define WRT_NO_VTABLE
60 #endif // _MSC_VER
61 
62 namespace Microsoft
63 {
64  namespace WRL
65  {
66 
67  // Indicator for RuntimeClass,Implements and ChainInterfaces that T interface
68  // will be not accessible on IID list
69  // Example:
70  // struct MyRuntimeClass : RuntimeClass<CloakedIid<IMyCloakedInterface>> {}
71  template <typename T>
72  struct CloakedIid : T
73  {
74  virtual ~CloakedIid() = default;
75  };
76 
78  {
79  WinRt = 0x0001,
80  ClassicCom = 0x0002,
84  InhibitFtmBase = 0x0008,
86  };
87 
88  template <unsigned int flags>
90  {
91  static const unsigned int value = flags;
92  };
93 
94  namespace Details
95  {
96  // Empty struct used for validating template parameter types in Implements
98  {};
99 
100  } // namespace Details
101 
102  // MixIn modifier allows to combine QI from
103  // a class that doesn't have default constructor on it
104  template <
105  typename Derived,
106  typename MixInType,
107  bool hasImplements = __is_base_of(Details::ImplementsBase, MixInType)>
108  struct MixIn
109  {};
110 
111  // ComposableBase template to allow deriving from a RuntimeClass
112  // Optionally allows specifying the base factory and statics interface
113  template <typename FactoryInterface = IInspectable>
115  {};
116  // Back-compat indicator for RuntimeClass to not support IWeakReferenceSource
118 
119  template <unsigned int RuntimeClassTypeT>
120  struct ErrorHelper
121  {
122  static void OriginateError(HRESULT hr, HSTRING message)
123  {
124 #ifdef WRL_RO_ERROR_API_ENABLED
125  ::RoOriginateError(hr, message);
126 #else
127  UNREFERENCED_PARAMETER(hr);
128  UNREFERENCED_PARAMETER(message);
129 #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
130  }
131  };
132 
133  template <>
135  {
136  static void OriginateError(HRESULT hr, HSTRING message)
137  {
138  UNREFERENCED_PARAMETER(hr);
139  UNREFERENCED_PARAMETER(message);
140  // No-Op
141  }
142  };
143 
144  namespace Details
145  {
146 
147  // Forward declaration
148  struct CreatorMap;
149 
150 #ifdef _MSC_VER
151 // Sections automatically generate a list of pointers to CreatorMap through the linker
152 // Sections a and z are used as a terminators
153 # pragma section("minATL$__a", read)
154 // Section f is used to put com objects to creator map
155 # pragma section("minATL$__f", read)
156 // Section m divides COM entries from WinRT entries
157 # pragma section("minATL$__m", read)
158 // Section r is used to put WinRT objects to creator map
159 # pragma section("minATL$__r", read)
160 # pragma section("minATL$__z", read)
161 #endif
162 
163  extern "C" {
164 // Location of the first and last entries for the linker generated list of pointers to CreatorMapEntry
165 #ifdef _MSC_VER
166  __declspec(selectany) __declspec(allocate("minATL$__a"))
167 #endif
168  const CreatorMap* __pobjectentryfirst = nullptr;
169  // Section m divides COM objects from WinRT objects
170  // - sections between a and m we store COM object info
171  // - sections between m+1 and z we store WinRT object info
172 #ifdef _MSC_VER
173  __declspec(selectany) __declspec(allocate("minATL$__m"))
174 #endif
175  const CreatorMap* __pobjectentrymid = nullptr;
176 #ifdef _MSC_VER
177  __declspec(selectany) __declspec(allocate("minATL$__z"))
178 #endif
179  const CreatorMap* __pobjectentrylast = nullptr;
180  }
181 
182  // Base class used by all module classes.
184  {
185  private:
186  // Lock that synchronize access and termination of factories
187  static void* moduleLock_;
188 
189  static_assert(sizeof(moduleLock_) == sizeof(SRWLOCK), "cacheLock must have the same size as SRWLOCK");
190 
191  protected:
192  static volatile unsigned long objectCount_;
193 
194  public:
196 
197  ModuleBase() throw()
198  {
199 #ifdef _DEBUG
200  // WRLs support for activatable classes requires there is only one instance of Module<>, this assert
201  // ensures there is only one. Since Module<> is templatized, using different template parameters
202  // will result in multiple instances, avoid this by making sure all code in a component uses the
203  // same parameters. Note that the C++ CX runtime creates an instance; Module<InProc,
204  // Platform::Details::InProcModule>, so mixing it with non CX code can result in this assert. WRL
205  // supports static and dynamically allocated Module<>, choose dynamic by defining
206  // __WRL_DISABLE_STATIC_INITIALIZE__ and allocate that instance with new but only once, for example
207  // in the main() entry point of an application.
209  ::InterlockedCompareExchangePointer(
210  reinterpret_cast<void* volatile*>(&module_), this, nullptr) == nullptr &&
211  "The module was already instantiated");
212 
213  [[maybe_unused]] SRWLOCK initSRWLOCK = SRWLOCK_INIT;
215  reinterpret_cast<SRWLOCK*>(&moduleLock_)->Ptr == initSRWLOCK.Ptr &&
216  "Different value for moduleLock_ than SRWLOCK_INIT");
217 #else
218  module_ = this;
219 #endif
220  }
221 
222  ModuleBase(const ModuleBase&) = delete;
223  ModuleBase& operator=(const ModuleBase&) = delete;
224 
225  virtual ~ModuleBase() throw()
226  {
227 #ifdef _DEBUG
229  ::InterlockedCompareExchangePointer(
230  reinterpret_cast<void* volatile*>(&module_), nullptr, this) == this &&
231  "The module was already instantiated");
232 #else
233  module_ = nullptr;
234 #endif
235  }
236 
237  // Number of active objects in the module
238  STDMETHOD_(unsigned long, IncrementObjectCount)() = 0;
239  STDMETHOD_(unsigned long, DecrementObjectCount)() = 0;
240 
241  STDMETHOD_(unsigned long, GetObjectCount)() const
242  {
243  return objectCount_;
244  }
245 
246  STDMETHOD_(const CreatorMap**, GetFirstEntryPointer)() const
247  {
248  return &__pobjectentryfirst;
249  }
250 
251  STDMETHOD_(const CreatorMap**, GetMidEntryPointer)() const
252  {
253  return &__pobjectentrymid;
254  }
255 
256  STDMETHOD_(const CreatorMap**, GetLastEntryPointer)() const
257  {
258  return &__pobjectentrylast;
259  }
260 
261  STDMETHOD_(SRWLOCK*, GetLock)() const
262  {
263  return reinterpret_cast<SRWLOCK*>(&moduleLock_);
264  }
265 
266  STDMETHOD(RegisterWinRTObject)
267  (_In_opt_z_ const wchar_t*,
268  _In_z_ const wchar_t** activatableClassIds,
269  _Inout_ RO_REGISTRATION_COOKIE* cookie,
270  unsigned int) = 0;
271  STDMETHOD(UnregisterWinRTObject)(_In_opt_z_ const wchar_t*, RO_REGISTRATION_COOKIE) = 0;
272  STDMETHOD(RegisterCOMObject)
273  (_In_opt_z_ const wchar_t*, IID*, IClassFactory**, _Inout_ DWORD*, unsigned int) = 0;
274  STDMETHOD(UnregisterCOMObject)(_In_opt_z_ const wchar_t*, _Inout_ DWORD*, unsigned int) = 0;
275  };
276 
277  __declspec(selectany) volatile unsigned long ModuleBase::objectCount_ = 0;
278  // moduleLock_ value must be equal SRWLOCK_INIT which is nullptr
279  __declspec(selectany) void* ModuleBase::moduleLock_ = nullptr;
280  __declspec(selectany) ModuleBase* ModuleBase::module_ = nullptr;
281 
282 #pragma region helper types
283  // Empty struct used as default template parameter
284  class Nil
285  {};
286 
287  // Used on RuntimeClass to protect it from being constructed with new
289  {
290  private:
291  void* operator new(size_t) throw()
292  {
293  __WRL_ASSERT__(false);
294  return 0;
295  }
296 
297  public:
298  void* operator new(size_t, void* placement) throw()
299  {
300  return placement;
301  }
302  };
303 
304  // RuntimeClassBase is used for detection of RuntimeClass in Make method
306  {};
307 
308  // RuntimeClassBaseT provides helper methods for QI and getting IIDs
309  template <unsigned int RuntimeClassTypeT>
311  {
312  protected:
313  template <typename T>
314  static HRESULT AsIID(T* implements, REFIID riid, void** ppvObject) throw()
315  {
316  *ppvObject = nullptr;
317 #ifdef _MSC_VER
318 # pragma warning(push)
319 // Conditional expression is constant
320 # pragma warning(disable : 4127)
321 // Potential comparison of a constant with another constant
322 # pragma warning(disable : 6326)
323 #endif
324  // Conditional check using template parameter is constant and can be used to optimize the code
325  bool isRefDelegated = false;
326  // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is
327  // almost always the case.
328  if (InlineIsEqualGUID(riid, __uuidof(IUnknown)) ||
329  ((RuntimeClassTypeT & WinRt) != 0 && InlineIsEqualGUID(riid, __uuidof(IInspectable))))
330 #ifdef _MSC_VER
331 # pragma warning(pop)
332 #endif
333  {
334  *ppvObject = implements->CastToUnknown();
335  static_cast<IUnknown*>(*ppvObject)->AddRef();
336  return S_OK;
337  }
338 
339  HRESULT hr = implements->CanCastTo(riid, ppvObject, &isRefDelegated);
340  if (SUCCEEDED(hr) && !isRefDelegated)
341  {
342  static_cast<IUnknown*>(*ppvObject)->AddRef();
343  }
344 
345 #ifdef _MSC_VER
346 # pragma warning(suppress : 6102) // '*ppvObject' is used but may not be initialized
347 #endif
348  _Analysis_assume_(SUCCEEDED(hr) || (*ppvObject == nullptr));
349 
350  return hr;
351  }
352  template <typename T>
353  static HRESULT GetImplementedIIDS(
354  T* implements,
355  ULONG* iidCount,
356  _When_(*iidCount == 0, _At_(*iids, _Post_null_)) _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
357  _Result_nullonfailure_ IID** iids) throw()
358  {
359  *iids = nullptr;
360  *iidCount = 0;
361  unsigned long count = implements->GetIidCount();
362 
363  // If there is no iids the CoTaskMemAlloc don't have to be called
364  if (count == 0)
365  {
366  return S_OK;
367  }
368 
369  IID* iidArray = reinterpret_cast<IID*>(::CoTaskMemAlloc(sizeof(IID) * count));
370  if (iidArray == nullptr)
371  {
372  return E_OUTOFMEMORY;
373  }
374 
375  unsigned long index = 0;
376 
377  // assign the IIDs to the array
378  implements->FillArrayWithIid(&index, iidArray);
379  __WRL_ASSERT__(index == count);
380 
381  // and return it
382  *iidCount = count;
383  *iids = iidArray;
384  return S_OK;
385  }
386 
387  public:
388  HRESULT RuntimeClassInitialize() throw()
389  {
390  return S_OK;
391  }
392  };
393 
394  // Base class required to mark FtmBase
396  {};
397 
398  // Verifies that I is derived from specified base
399  template <
400  unsigned int type,
401  typename I,
402  bool doStrictCheck = true,
403  bool isImplementsBased = __is_base_of(ImplementsBase, I)>
405 
406  // Specialization for ClassicCom interface
407  template <typename I, bool doStrictCheck>
408  struct VerifyInterfaceHelper<ClassicCom, I, doStrictCheck, false>
409  {
410  static void Verify() throw()
411  {
412 #ifdef __WRL_STRICT__
413  // Make sure that your interfaces inherit from IUnknown and are not IUnknown and/or IInspectable
414  // based The IUnknown is allowed only on RuntimeClass as first template parameter
415  static_assert(
416  __is_base_of(IUnknown, I) && !__is_base_of(IInspectable, I) &&
417  !(doStrictCheck && IsSame<IUnknown, I>::value),
418  "'I' has to derive from 'IUnknown' and not from 'IInspectable'. 'I' must not be IUnknown.");
419 #else
420  static_assert(__is_base_of(IUnknown, I), "'I' has to derive from 'IUnknown'.");
421 #endif
422  }
423  };
424 
425  // Specialization for WinRtClassicComMix interface
426  template <typename I, bool doStrictCheck>
427  struct VerifyInterfaceHelper<WinRtClassicComMix, I, doStrictCheck, false>
428  {
429  static void Verify() throw()
430  {
431 #ifdef __WRL_STRICT__
432  // Make sure that your interfaces inherit from IUnknown and are not IUnknown and/or IInspectable
433  // except when IInspectable is the first template parameter
434  static_assert(
435  __is_base_of(IUnknown, I) &&
437  : __is_base_of(IInspectable, I)),
438  "'I' has to derive from 'IUnknown' and must not be IUnknown and/or IInspectable.");
439 #else
440  static_assert(__is_base_of(IUnknown, I), "'I' has to derive from 'IUnknown'.");
441 #endif
442  }
443  };
444 
445  // Specialization for WinRt interface
446  template <typename I, bool doStrictCheck>
447  struct VerifyInterfaceHelper<WinRt, I, doStrictCheck, false>
448  {
449  static void Verify() throw()
450  {
451 #ifdef __WRL_STRICT__
452  // IWeakReferenceSource is exception for WinRt and can be used however it cannot be first templated
453  // interface Make sure that your interfaces inherit from IInspectable and are not IInspectable The
454  // IInspectable is allowed only on RuntimeClass as first template parameter
455  static_assert(
456  (__is_base_of(IWeakReferenceSource, I) && doStrictCheck) ||
457  (__is_base_of(IInspectable, I) && !(doStrictCheck && IsSame<IInspectable, I>::value)),
458  "'I' has to derive from 'IWeakReferenceSource' or 'IInspectable' and must not be IInspectable");
459 #else
460  // IWeakReference and IWeakReferneceSource are exceptions for WinRT
461  static_assert(
462  __is_base_of(IWeakReference, I) || __is_base_of(IWeakReferenceSource, I) ||
463  __is_base_of(IInspectable, I),
464  "'I' has to derive from 'IWeakReference', 'IWeakReferenceSource' or 'IInspectable'");
465 #endif
466  }
467  };
468 
469  // Specialization for Implements passed as template parameter
470  template <unsigned int type, typename I>
471  struct VerifyInterfaceHelper<type, I, true, true>
472  {
473  static void Verify() throw()
474  {
475 #ifdef __WRL_STRICT__
476  // Verifies if Implements has correct RuntimeClassFlags setting
477  // Allow using FtmBase on classes configured with RuntimeClassFlags<WinRt> (Default configuration)
478  static_assert(
479  I::ClassFlags::value == type || type == WinRtClassicComMix ||
480  __is_base_of(::Microsoft::WRL::Details::FtmBaseMarker, I),
481  "Implements class must have the same and/or compatibile flags configuration");
482 #endif
483  }
484  };
485 
486  // Specialization for Implements passed as first template parameter
487  template <unsigned int type, typename I>
488  struct VerifyInterfaceHelper<type, I, false, true>
489  {
490  static void Verify() throw()
491  {
492 #ifdef __WRL_STRICT__
493  // Verifies if Implements has correct RuntimeClassFlags setting
494  static_assert(
495  I::ClassFlags::value == type || type == WinRtClassicComMix,
496  "Implements class must have the same and/or compatible flags configuration."
497  "If you use WRL::FtmBase it cannot be specified as first template parameter on RuntimeClass");
498 
499  // Besides make sure that the first interface on Implements meet flags requirement
501 #endif
502  }
503  };
504 
505  // Interface traits provides casting and filling iids methods helpers
506  template <typename I0>
508  {
509  typedef I0 Base;
510  static const unsigned long IidCount = 1;
511 
512  template <unsigned int ClassType>
513  static void Verify() throw()
514  {
516  }
517 
518  template <typename T>
519  static Base* CastToBase(T* ptr) throw()
520  {
521  return static_cast<Base*>(ptr);
522  }
523 
524  template <typename T>
525  static IUnknown* CastToUnknown(T* ptr) throw()
526  {
527  return static_cast<IUnknown*>(static_cast<Base*>(ptr));
528  }
529 
530  template <typename T>
531  _Success_(return == true) static bool CanCastTo(T* ptr, REFIID riid, _Outptr_ void** ppv) throw()
532  {
533  // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is
534  // almost always the case.
535  if (InlineIsEqualGUID(riid, __uuidof(Base)))
536  {
537  *ppv = static_cast<Base*>(ptr);
538  return true;
539  }
540 
541  return false;
542  }
543 
544  static void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
545  {
546  *(iids + *index) = __uuidof(Base);
547  (*index)++;
548  }
549  };
550 
551  // Specialization of traits for cloaked interface
552  template <typename CloakedType>
554  {
555  typedef CloakedType Base;
556  static const unsigned long IidCount = 0;
557 
558  template <unsigned int ClassType>
559  static void Verify() throw()
560  {
562  }
563 
564  template <typename T>
565  static Base* CastToBase(T* ptr) throw()
566  {
567  return static_cast<Base*>(ptr);
568  }
569 
570  template <typename T>
571  static IUnknown* CastToUnknown(T* ptr) throw()
572  {
573  return static_cast<IUnknown*>(static_cast<Base*>(ptr));
574  }
575 
576  template <typename T>
577  _Success_(return == true) static bool CanCastTo(T* ptr, REFIID riid, _Outptr_ void** ppv) throw()
578  {
579  // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is
580  // almost always the case.
581  if (InlineIsEqualGUID(riid, __uuidof(Base)))
582  {
583  *ppv = static_cast<Base*>(ptr);
584  return true;
585  }
586 
587  return false;
588  }
589 
590  // Cloaked specialization makes it always IID list empty
591  static void FillArrayWithIid(_Inout_ unsigned long*, _Inout_ IID*) throw()
592  {}
593  };
594 
595  // Specialization for Nil parameter
596  template <>
598  {
599  typedef Nil Base;
600  static const unsigned long IidCount = 0;
601 
602  template <unsigned int ClassType>
603  static void Verify() throw()
604  {}
605 
606  static void FillArrayWithIid(_Inout_ unsigned long*, _Inout_ IID*) throw()
607  {}
608 
609  template <typename T>
610  _Success_(return == true) static bool CanCastTo(T*, REFIID, _Outptr_ void**) throw()
611  {
612  return false;
613  }
614  };
615 
616  // Verify inheritance
617  template <typename I, typename Base>
619  {
620  static void Verify() throw()
621  {
622  static_assert(
625  typename InterfaceTraits<I>::Base>::value,
626  "'I' needs to inherit from 'Base'.");
627  }
628  };
629 
630  template <typename I>
632  {
633  static void Verify() throw()
634  {}
635  };
636 
637 #pragma endregion // helper types
638 
639  } // namespace Details
640 
641  // note: Due to potential shutdown ordering issues, the results of GetModuleBase
642  // should always be checked for null on reference counting and cleanup operations.
644  {
646  }
647 
648  // ChainInterfaces - template allows specifying a derived COM interface along with its class hierarchy to allow
649  // QI for the base interfaces
650  template <
651  typename I0,
652  typename I1,
653  typename I2 = Details::Nil,
654  typename I3 = Details::Nil,
655  typename I4 = Details::Nil,
656  typename I5 = Details::Nil,
657  typename I6 = Details::Nil,
658  typename I7 = Details::Nil,
659  typename I8 = Details::Nil,
660  typename I9 = Details::Nil>
661  struct ChainInterfaces : I0
662  {
663  protected:
664  template <unsigned int ClassType>
665  static void Verify() throw()
666  {
667  Details::InterfaceTraits<I0>::template Verify<ClassType>();
668  Details::InterfaceTraits<I1>::template Verify<ClassType>();
669  Details::InterfaceTraits<I2>::template Verify<ClassType>();
670  Details::InterfaceTraits<I3>::template Verify<ClassType>();
671  Details::InterfaceTraits<I4>::template Verify<ClassType>();
672  Details::InterfaceTraits<I5>::template Verify<ClassType>();
673  Details::InterfaceTraits<I6>::template Verify<ClassType>();
674  Details::InterfaceTraits<I7>::template Verify<ClassType>();
675  Details::InterfaceTraits<I8>::template Verify<ClassType>();
676  Details::InterfaceTraits<I9>::template Verify<ClassType>();
677 
687  }
688 
689  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv) throw()
690  {
692 
693  return (Details::InterfaceTraits<I0>::CanCastTo(this, riid, ppv) ||
694  Details::InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
695  Details::InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
696  Details::InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
697  Details::InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
698  Details::InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
699  Details::InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
700  Details::InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
701  Details::InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
703  ? S_OK
704  : E_NOINTERFACE;
705  }
706 
707  IUnknown* CastToUnknown() throw()
708  {
710  }
711 
712  static const unsigned long IidCount = Details::InterfaceTraits<I0>::IidCount +
718 
719  static void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
720  {
731  }
732  };
733 
734  template <
735  typename DerivedType,
736  typename BaseType,
737  bool hasImplements,
738  typename I1,
739  typename I2,
740  typename I3,
741  typename I4,
742  typename I5,
743  typename I6,
744  typename I7,
745  typename I8,
746  typename I9>
747  struct ChainInterfaces<MixIn<DerivedType, BaseType, hasImplements>, I1, I2, I3, I4, I5, I6, I7, I8, I9>
748  {
749  static_assert(
750  !hasImplements,
751  "Cannot use ChainInterfaces<MixIn<...>> to Mix a class implementing interfaces using \"Implements\"");
752 
753  protected:
754  template <unsigned int ClassType>
755  static void Verify() throw()
756  {
758  Details::InterfaceTraits<I1>::template Verify<ClassType>();
759  Details::InterfaceTraits<I2>::template Verify<ClassType>();
760  Details::InterfaceTraits<I3>::template Verify<ClassType>();
761  Details::InterfaceTraits<I4>::template Verify<ClassType>();
762  Details::InterfaceTraits<I5>::template Verify<ClassType>();
763  Details::InterfaceTraits<I6>::template Verify<ClassType>();
764  Details::InterfaceTraits<I7>::template Verify<ClassType>();
765  Details::InterfaceTraits<I8>::template Verify<ClassType>();
766  Details::InterfaceTraits<I9>::template Verify<ClassType>();
767 
777  }
778 
779  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv) throw()
780  {
781  BaseType* ptr = static_cast<BaseType*>(static_cast<DerivedType*>(this));
782 
783  return (Details::InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
784  Details::InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
785  Details::InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
786  Details::InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
787  Details::InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
788  Details::InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
789  Details::InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
790  Details::InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
792  ? S_OK
793  : E_NOINTERFACE;
794  }
795 
796  // It's not possible to cast to IUnknown when Base interface inherit more interfaces
797  // The RuntimeClass is taking always the first interface as IUnknown thus it's required to
798  // list IInspectable or IUnknown class before MixIn<Derived, MixInType> parameter, such as:
799  // struct MyRuntimeClass : RuntimeClass<IInspectable,
800  // ChainInterfaces<MixIn<MyRuntimeClass,MyIndependentImplementation>, IFoo, IBar>,
801  // MyIndependentImplementation {}
802  IUnknown* CastToUnknown() throw() = delete;
803 
804  static const unsigned long IidCount = Details::InterfaceTraits<I1>::IidCount +
805  Details::InterfaceTraits<I2>::IidCount + Details::InterfaceTraits<I3>::IidCount +
806  Details::InterfaceTraits<I4>::IidCount + Details::InterfaceTraits<I5>::IidCount +
807  Details::InterfaceTraits<I6>::IidCount + Details::InterfaceTraits<I7>::IidCount +
808  Details::InterfaceTraits<I8>::IidCount + Details::InterfaceTraits<I9>::IidCount;
809 
810  static void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
811  {
821  }
822  };
823 
824  namespace Details
825  {
826 
827 #pragma region Implements helper templates
828 
829  // Helper template used by Implements. This template traverses a list of interfaces and adds them as base
830  // class and information to enable QI. doStrictCheck is typically false only for the first interface,
831  // allowing IInspectable to be explicitly specified only as the first interface.
832  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... TInterfaces>
834 
835  template <typename T>
837  {};
838 
839  template <typename I0, bool isImplements>
841 
842  template <typename I0>
843  struct WRT_NO_VTABLE MarkImplements<I0, false>
844  {
845  typedef I0 Type;
846  };
847 
848  template <typename I0>
849  struct WRT_NO_VTABLE MarkImplements<I0, true>
850  {
852  };
853 
854  template <typename I0>
856  {
857  // Cloaked Implements type will be handled in the nested processing.
858  // Applying the ImplementsMarker too early will bypass Cloaked behavior.
860  };
861 
862  template <typename DerivedType, typename BaseType, bool hasImplements>
863  struct WRT_NO_VTABLE MarkImplements<MixIn<DerivedType, BaseType, hasImplements>, true>
864  {
865  // Implements type in mix-ins will be handled in the nested processing.
867  };
868 
869  // AdjustImplements pre-processes the type list for more efficient builds.
870  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... Bases>
872 
873  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename... Bases>
874  struct WRT_NO_VTABLE AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0, Bases...>
875  {
876  typedef ImplementsHelper<
877  RuntimeClassFlagsT,
878  doStrictCheck,
879  typename MarkImplements<I0, __is_base_of(ImplementsBase, I0)>::Type,
880  Bases...>
882  };
883 
884  // Use AdjustImplements to remove instances of "Details::Nil" from the type list.
885  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... Bases>
886  struct WRT_NO_VTABLE AdjustImplements<RuntimeClassFlagsT, doStrictCheck, typename Details::Nil, Bases...>
887  {
888  typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, Bases...>::Type Type;
889  };
890 
891  template <typename RuntimeClassFlagsT, bool doStrictCheck>
892  struct WRT_NO_VTABLE AdjustImplements<RuntimeClassFlagsT, doStrictCheck>
893  {
895  };
896 
897  // Specialization handles unadorned interfaces
898  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename... TInterfaces>
899  struct WRT_NO_VTABLE ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, I0, TInterfaces...>
900  : I0
901  , AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
902  {
903  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
904  friend struct ImplementsHelper;
905  template <unsigned int RuntimeClassTypeT>
906  friend class RuntimeClassBaseT;
907 
908  protected:
909  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
910  {
912  // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is
913  // almost always the case.
914  if (InlineIsEqualGUID(riid, __uuidof(I0)))
915  {
916  *ppv = reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
917  return S_OK;
918  }
919  return AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::CanCastTo(
920  riid, ppv, pRefDelegated);
921  }
922 
923  virtual ~ImplementsHelper() = default;
924 
925  IUnknown* CastToUnknown() throw()
926  {
927  return reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
928  }
929 
930  unsigned long GetIidCount() throw()
931  {
932  return 1 + AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::GetIidCount();
933  }
934 
935  // FillArrayWithIid
936  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
937  {
938  *(iids + *index) = __uuidof(I0);
939  (*index)++;
940  AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::FillArrayWithIid(index, iids);
941  }
942  };
943 
944  // Selector is used to "tag" base interfaces to be used in casting, since a runtime class may indirectly
945  // derive from the same interface or Implements<> template multiple times
946  template <typename base, typename disciminator>
947  struct WRT_NO_VTABLE Selector : public base
948  {};
949 
950  // Specialization handles types that derive from ImplementsHelper (e.g. nested Implements).
951  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename... TInterfaces>
953  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>
954  : Selector<
955  I0,
956  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>
957  , Selector<
958  typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type,
959  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>
960  {
961  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
962  friend struct ImplementsHelper;
963  template <unsigned int RuntimeClassTypeT>
964  friend class RuntimeClassBaseT;
965 
966  protected:
967  typedef Selector<
968  I0,
969  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>
971  typedef Selector<
972  typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type,
973  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>
975 
976 #ifndef _MSC_VER
977  virtual ~ImplementsHelper() = default;
978 #endif
979 
980  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
981  {
983  HRESULT hr = CurrentType::CanCastTo(riid, ppv);
984  if (hr == E_NOINTERFACE)
985  {
986  hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
987  }
988  return hr;
989  }
990 
991  IUnknown* CastToUnknown() throw()
992  {
993  // First in list wins.
994  return CurrentType::CastToUnknown();
995  }
996 
997  unsigned long GetIidCount() throw()
998  {
999  return CurrentType::GetIidCount() + BaseType::GetIidCount();
1000  }
1001 
1002  // FillArrayWithIid
1003  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1004  {
1005  CurrentType::FillArrayWithIid(index, iids);
1006  BaseType::FillArrayWithIid(index, iids);
1007  }
1008  };
1009 
1010  // CloakedIid instance. Since the first "real" interface should be checked against doStrictCheck,
1011  // pass this through unchanged. Two specializations for cloaked prevent the need to use the Selector
1012  // used in the Implements<> case. The same can't be done there because some type ambiguities are
1013  // unavoidable.
1014  template <
1015  typename RuntimeClassFlagsT,
1016  bool doStrictCheck,
1017  typename I0,
1018  typename I1,
1019  typename... TInterfaces>
1020  struct WRT_NO_VTABLE ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, CloakedIid<I0>, I1, TInterfaces...>
1021  : AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type
1022  , AdjustImplements<RuntimeClassFlagsT, true, I1, TInterfaces...>::Type
1023  {
1024  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
1025  friend struct ImplementsHelper;
1026  template <unsigned int RuntimeClassTypeT>
1028 
1029  protected:
1030  typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type CurrentType;
1031  typedef typename AdjustImplements<RuntimeClassFlagsT, true, I1, TInterfaces...>::Type BaseType;
1032 
1033  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
1034  {
1036 
1037  HRESULT hr = CurrentType::CanCastTo(riid, ppv, pRefDelegated);
1038  if (SUCCEEDED(hr))
1039  {
1040  return S_OK;
1041  }
1042  return BaseType::CanCastTo(riid, ppv, pRefDelegated);
1043  }
1044 
1045  IUnknown* CastToUnknown() throw()
1046  {
1047  return CurrentType::CastToUnknown();
1048  }
1049 
1050  // Don't expose the cloaked IID(s), but continue processing the rest of the interfaces
1051  unsigned long GetIidCount() throw()
1052  {
1053  return BaseType::GetIidCount();
1054  }
1055 
1056  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1057  {
1058  BaseType::FillArrayWithIid(index, iids);
1059  }
1060  };
1061 
1062  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0>
1063  struct WRT_NO_VTABLE ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, CloakedIid<I0>>
1064  : AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type
1065  {
1066  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TInterfaces>
1067  friend struct ImplementsHelper;
1068  template <unsigned int RuntimeClassTypeT>
1070 
1071  protected:
1072  typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type CurrentType;
1073 
1074  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
1075  {
1077 
1078  return CurrentType::CanCastTo(riid, ppv, pRefDelegated);
1079  }
1080 
1081  IUnknown* CastToUnknown() throw()
1082  {
1083  return CurrentType::CastToUnknown();
1084  }
1085 
1086  // Don't expose the cloaked IID(s), but continue processing the rest of the interfaces
1087  unsigned long GetIidCount() throw()
1088  {
1089  return 0;
1090  }
1091 
1092  void FillArrayWithIid(_Inout_ unsigned long* /*index*/, _Inout_ IID* /*iids*/) throw()
1093  {
1094  // no-op
1095  }
1096  };
1097 
1098  // terminal case specialization.
1099  template <typename RuntimeClassFlagsT, bool doStrictCheck>
1100  struct WRT_NO_VTABLE ImplementsHelper<RuntimeClassFlagsT, doStrictCheck>
1101  {
1102  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TInterfaces>
1103  friend struct ImplementsHelper;
1104  template <unsigned int RuntimeClassTypeT>
1105  friend class RuntimeClassBaseT;
1106 
1107  protected:
1108  template <unsigned int RuntimeClassTypeT>
1110 
1111  HRESULT
1112  CanCastTo(REFIID /*riid*/, _Outptr_ void** /*ppv*/, bool* /*pRefDelegated*/ = nullptr) throw()
1113  {
1114  return E_NOINTERFACE;
1115  }
1116 
1117  // IUnknown* CastToUnknown() throw(); // not defined for terminal case.
1118 
1119  unsigned long GetIidCount() throw()
1120  {
1121  return 0;
1122  }
1123 
1124  void FillArrayWithIid(_Inout_ unsigned long* /*index*/, _Inout_ IID* /*iids*/) throw()
1125  {}
1126  };
1127 
1128  // Specialization handles chaining interfaces
1129  template <
1130  typename RuntimeClassFlagsT,
1131  bool doStrictCheck,
1132  typename C0,
1133  typename C1,
1134  typename C2,
1135  typename C3,
1136  typename C4,
1137  typename C5,
1138  typename C6,
1139  typename C7,
1140  typename C8,
1141  typename C9,
1142  typename... TInterfaces>
1144  RuntimeClassFlagsT,
1145  doStrictCheck,
1146  ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>,
1147  TInterfaces...>
1148  : ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>
1149  , AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
1150  {
1151  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
1152  friend struct ImplementsHelper;
1153  template <unsigned int RuntimeClassTypeT>
1154  friend class RuntimeClassBaseT;
1155 
1156  protected:
1157  template <unsigned int RuntimeClassTypeT>
1159  typedef typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type BaseType;
1160 
1161  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
1162  {
1164  RuntimeClassFlagsT::value>();
1165 
1167  if (FAILED(hr))
1168  {
1169  hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
1170  }
1171 
1172  return hr;
1173  }
1174 
1175  IUnknown* CastToUnknown() throw()
1176  {
1178  }
1179 
1180  unsigned long GetIidCount() throw()
1181  {
1183  }
1184 
1185  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1186  {
1188  BaseType::FillArrayWithIid(index, iids);
1189  }
1190  };
1191 
1192  // Mixin specialization
1193  template <
1194  typename RuntimeClassFlagsT,
1195  typename DerivedType,
1196  typename BaseMixInType,
1197  bool hasImplements,
1198  typename... TInterfaces,
1199  bool doStrictCheck>
1201  RuntimeClassFlagsT,
1202  doStrictCheck,
1203  MixIn<DerivedType, BaseMixInType, hasImplements>,
1204  TInterfaces...> : AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
1205  {
1206  static_assert(hasImplements, "Cannot use MixIn to with a class not deriving from \"Implements\"");
1207 
1208  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
1209  friend struct ImplementsHelper;
1210  template <unsigned int RuntimeClassTypeT>
1211  friend class RuntimeClassBaseT;
1212 
1213  protected:
1214  template <unsigned int RuntimeClassTypeT>
1216  typedef typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type BaseType;
1217 
1218  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
1219  {
1221  RuntimeClassFlagsT::value & WinRtClassicComMix,
1222  BaseMixInType,
1223  doStrictCheck>::Verify();
1224 
1225  HRESULT hr = static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->CanCastTo(riid, ppv);
1226  if (FAILED(hr))
1227  {
1228  hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
1229  }
1230 
1231  return hr;
1232  }
1233 
1234  IUnknown* CastToUnknown() throw()
1235  {
1236  return static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->CastToUnknown();
1237  }
1238 
1239  unsigned long GetIidCount() throw()
1240  {
1241  return static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->GetIidCount() +
1242  BaseType::GetIidCount();
1243  }
1244 
1245  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1246  {
1247  static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->FillArrayWithIid(index, iids);
1248  BaseType::FillArrayWithIid(index, iids);
1249  }
1250  };
1251 
1252  // Specialization handles inheriting COM objects. ComposableBase must be the last non-nil interface in the
1253  // list. Trailing nil's are allowed for compatibility with some tools that pad out the list.
1254  template <typename I0, typename...>
1255  struct AreAllNil
1256  {
1257  static const bool value = false;
1258  };
1259 
1260  template <typename... TInterfaces>
1261  struct AreAllNil<Microsoft::WRL::Details::Nil, TInterfaces...>
1262  {
1263  static const bool value = AreAllNil<TInterfaces...>::value;
1264  };
1265 
1266  template <>
1268  {
1269  static const bool value = true;
1270  };
1271 
1272  template <
1273  typename RuntimeClassFlagsT,
1274  typename FactoryInterface,
1275  bool doStrictCheck,
1276  typename... TInterfaces>
1278  ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ComposableBase<FactoryInterface>, TInterfaces...>
1279  : ImplementsHelper<RuntimeClassFlagsT, true, ComposableBase<FactoryInterface>>
1280  {
1281  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TOtherInterfaces>
1282  friend struct ImplementsHelper;
1283  template <unsigned int RuntimeClassTypeT>
1284  friend class RuntimeClassBaseT;
1285 
1286  protected:
1287  template <unsigned int RuntimeClassTypeT>
1289 
1290  typedef ImplementsHelper<RuntimeClassFlagsT, true, ComposableBase<FactoryInterface>> BaseType;
1291 
1292  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated = nullptr) throw()
1293  {
1294  static_assert(
1296  "ComposableBase should be the last template parameter to RuntimeClass");
1297  return BaseType::CanCastTo(riid, ppv, pRefDelegated);
1298  }
1299 
1300  IUnknown* CastToUnknown() throw()
1301  {
1302  static_assert(
1304  "ComposableBase should be the last template parameter to RuntimeClass");
1305  return BaseType::CastToUnknown();
1306  }
1307 
1308  unsigned long GetIidCount() throw()
1309  {
1310  static_assert(
1312  "ComposableBase should be the last template parameter to RuntimeClass");
1313  return BaseType::GetIidCount();
1314  }
1315 
1316  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1317  {
1318  static_assert(
1320  "ComposableBase should be the last template parameter to RuntimeClass");
1321  BaseType::FillArrayWithIid(index, iids);
1322  }
1323  };
1324 
1325  template <typename RuntimeClassFlagsT, typename FactoryInterface, bool doStrictCheck>
1326  struct WRT_NO_VTABLE ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ComposableBase<FactoryInterface>>
1327  {
1328  template <typename OtherRuntimeClassFlagsT, bool OtherDoStrictCheck, typename... TInterfaces>
1329  friend struct ImplementsHelper;
1330  template <unsigned int RuntimeClassTypeT>
1331  friend class RuntimeClassBaseT;
1332 
1333  protected:
1334  template <unsigned int RuntimeClassTypeT>
1336 
1337  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv, bool* pRefDelegated) throw()
1338  {
1339  *pRefDelegated = true;
1340  return composableBase_.CopyTo(riid, ppv);
1341  }
1342 
1343  IUnknown* CastToUnknown() throw()
1344  {
1345  return nullptr;
1346  }
1347 
1348  unsigned long GetIidCount() throw()
1349  {
1350  return iidCount_;
1351  }
1352 
1353  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1354  {
1355  for (unsigned long i = 0; i < iidCount_; i++)
1356  {
1357  *(iids + *index) = *(iidsCached_ + i);
1358  (*index)++;
1359  }
1360  }
1361 
1363  : iidsCached_(nullptr)
1364  , iidCount_(0)
1365  {}
1366 
1368  {
1369  ::CoTaskMemFree(iidsCached_);
1370  iidsCached_ = nullptr;
1371  iidCount_ = 0;
1372  }
1373 
1374  public:
1375  HRESULT
1376  SetComposableBasePointers(IInspectable* base, _In_opt_ FactoryInterface* baseFactory = nullptr) throw()
1377  {
1378  if (composableBase_ != nullptr)
1379  {
1380 #ifdef WRL_RO_ERROR_API_ENABLED
1382  E_UNEXPECTED, nullptr);
1383 #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
1384  return E_UNEXPECTED;
1385  }
1386 
1387  HRESULT hr = base->GetIids(&iidCount_, &iidsCached_);
1388  if (SUCCEEDED(hr))
1389  {
1390  composableBase_ = base;
1391  composableBaseFactory_ = baseFactory;
1392  }
1393  return hr;
1394  }
1395 
1397  {
1398  return composableBase_;
1399  }
1400 
1402  {
1403  return composableBaseFactory_;
1404  }
1405 
1406  private:
1407  ComPtr<IInspectable> composableBase_;
1408  ComPtr<FactoryInterface> composableBaseFactory_;
1409  IID* iidsCached_;
1410  unsigned long iidCount_;
1411  };
1412 
1413 #pragma endregion // Implements helper templates
1414 
1415  } // namespace Details
1416 
1417  // Implements - template implementing QI using the information provided through its template parameters
1418  // Each template parameter has to be one of the following:
1419  // * COM Interface
1420  // * A class that implements one or more COM interfaces
1421  // * ChainInterfaces template
1422  template <typename I0, typename... TInterfaces>
1424  : Details::AdjustImplements<RuntimeClassFlags<WinRt>, true, I0, TInterfaces...>::Type
1426  {
1427  public:
1429  typedef I0 FirstInterface;
1430 
1431 #ifndef _MSC_VER
1432  virtual ~Implements() = default;
1433 #endif
1434 
1435  protected:
1436  typedef
1437  typename Details::AdjustImplements<RuntimeClassFlags<WinRt>, true, I0, TInterfaces...>::Type BaseType;
1438  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... TOtherInterfaces>
1440  template <unsigned int RuntimeClassTypeT>
1442 
1443  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv) throw()
1444  {
1445  return BaseType::CanCastTo(riid, ppv);
1446  }
1447 
1448  IUnknown* CastToUnknown() throw()
1449  {
1450  return BaseType::CastToUnknown();
1451  }
1452 
1453  unsigned long GetIidCount() throw()
1454  {
1455  return BaseType::GetIidCount();
1456  }
1457 
1458  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1459  {
1460  BaseType::FillArrayWithIid(index, iids);
1461  }
1462  };
1463 
1464  template <int flags, typename I0, typename... TInterfaces>
1465  struct WRT_NO_VTABLE Implements<RuntimeClassFlags<flags>, I0, TInterfaces...>
1466  : Details::AdjustImplements<RuntimeClassFlags<flags>, true, I0, TInterfaces...>::Type
1468  {
1469  public:
1471  typedef I0 FirstInterface;
1472 
1473  protected:
1474  typedef
1475  typename Details::AdjustImplements<RuntimeClassFlags<flags>, true, I0, TInterfaces...>::Type BaseType;
1476  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... TOtherInterfaces>
1478  template <unsigned int RuntimeClassTypeT>
1480 
1481  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv) throw()
1482  {
1483  return BaseType::CanCastTo(riid, ppv);
1484  }
1485 
1486  IUnknown* CastToUnknown() throw()
1487  {
1488  return BaseType::CastToUnknown();
1489  }
1490 
1491  unsigned long GetIidCount() throw()
1492  {
1493  return BaseType::GetIidCount();
1494  }
1495 
1496  void FillArrayWithIid(_Inout_ unsigned long* index, _Inout_ IID* iids) throw()
1497  {
1498  BaseType::FillArrayWithIid(index, iids);
1499  }
1500  };
1501 
1502  class FtmBase
1503  : public Implements<
1504  ::Microsoft::WRL::RuntimeClassFlags<WinRtClassicComMix>,
1505  ::Microsoft::WRL::CloakedIid<::IMarshal>>
1506  ,
1507  // Inheriting from FtmBaseMarker allows using FtmBase on classes configured with RuntimeClassFlags<WinRt>
1508  // (Default configuration)
1510  {
1511  // defining type 'Super' for other compilers since '__super' is a VC++-specific language extension
1512  using Super = Implements<
1515 
1516  protected:
1517  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename... TInterfaces>
1519 
1520  HRESULT CanCastTo(REFIID riid, _Outptr_ void** ppv) throw()
1521  {
1522  // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is
1523  // almost always the case.
1524  if (InlineIsEqualGUID(riid, __uuidof(::IAgileObject)))
1525  {
1526 
1527  *ppv = Super::CastToUnknown();
1528  return S_OK;
1529  }
1530 
1531  return Super::CanCastTo(riid, ppv);
1532  }
1533 
1534  public:
1535  FtmBase() throw()
1536  {
1537  ComPtr<IUnknown> unknown;
1538  if (SUCCEEDED(::CoCreateFreeThreadedMarshaler(nullptr, &unknown)))
1539  {
1540  unknown.As(&marshaller_);
1541  }
1542  }
1543 
1544 #ifndef _MSC_VER
1545  virtual ~FtmBase() = default;
1546 #endif
1547 
1548 // IMarshal Methods
1549 #ifdef _MSC_VER
1550 # pragma warning(suppress : 6101) // PREFast cannot see through the smart-pointer invocation
1551 #endif
1552  STDMETHOD(GetUnmarshalClass)
1553  (REFIID riid,
1554  _In_opt_ void* pv,
1556  _Reserved_ void* pvDestContext,
1557  DWORD mshlflags,
1558  CLSID* pCid) override
1559  {
1560  if (marshaller_)
1561  {
1562  return marshaller_->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, mshlflags, pCid);
1563  }
1564  return E_OUTOFMEMORY;
1565  }
1566 
1567 #ifdef _MSC_VER
1568 # pragma warning(suppress : 6101) // PREFast cannot see through the smart-pointer invocation
1569 #endif
1570  STDMETHOD(GetMarshalSizeMax)
1571  (REFIID riid,
1572  _In_opt_ void* pv,
1573  DWORD dwDestContext,
1574  _Reserved_ void* pvDestContext,
1575  DWORD mshlflags,
1576  DWORD* pSize) override
1577  {
1578  if (marshaller_)
1579  {
1580  return marshaller_->GetMarshalSizeMax(riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
1581  }
1582  return E_OUTOFMEMORY;
1583  }
1584 
1585  STDMETHOD(MarshalInterface)
1586  (IStream* pStm,
1587  REFIID riid,
1588  _In_opt_ void* pv,
1590  _Reserved_ void* pvDestContext,
1591  DWORD mshlflags) override
1592  {
1593  if (marshaller_)
1594  {
1595  return marshaller_->MarshalInterface(pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
1596  }
1597  return E_OUTOFMEMORY;
1598  }
1599 
1600 #ifdef _MSC_VER
1601 # pragma warning(suppress : 6101) // PREFast cannot see through the smart-pointer invocation
1602 #endif
1603  STDMETHOD(UnmarshalInterface)(IStream* pStm, REFIID riid, _Outptr_ void** ppv) override
1604  {
1605  if (marshaller_)
1606  {
1607  return marshaller_->UnmarshalInterface(pStm, riid, ppv);
1608  }
1609  return E_OUTOFMEMORY;
1610  }
1611 
1612  STDMETHOD(ReleaseMarshalData)(IStream* pStm) override
1613  {
1614  if (marshaller_)
1615  {
1616  return marshaller_->ReleaseMarshalData(pStm);
1617  }
1618  return E_OUTOFMEMORY;
1619  }
1620 
1621  STDMETHOD(DisconnectObject)(DWORD dwReserved) override
1622  {
1623  if (marshaller_)
1624  {
1625  return marshaller_->DisconnectObject(dwReserved);
1626  }
1627  return E_OUTOFMEMORY;
1628  }
1629 
1630  static HRESULT CreateGlobalInterfaceTable(IGlobalInterfaceTable** git) throw()
1631  {
1632  *git = nullptr;
1633  return ::CoCreateInstance(
1634  CLSID_StdGlobalInterfaceTable,
1635  nullptr,
1636  CLSCTX_INPROC_SERVER,
1637  __uuidof(IGlobalInterfaceTable),
1638  reinterpret_cast<void**>(git));
1639  }
1640 
1641  ::Microsoft::WRL::ComPtr<IMarshal> marshaller_; // Holds a reference to the free threaded marshaler
1642  };
1643 
1644  namespace Details
1645  {
1646 
1647 #ifdef _PERF_COUNTERS
1648  class WRT_NO_VTABLE PerfCountersBase
1649  {
1650  public:
1651  ULONG GetAddRefCount() throw()
1652  {
1653  return addRefCount_;
1654  }
1655 
1656  ULONG GetReleaseCount() throw()
1657  {
1658  return releaseCount_;
1659  }
1660 
1661  ULONG GetQueryInterfaceCount() throw()
1662  {
1663  return queryInterfaceCount_;
1664  }
1665 
1666  void ResetPerfCounters() throw()
1667  {
1668  addRefCount_ = 0;
1669  releaseCount_ = 0;
1670  queryInterfaceCount_ = 0;
1671  }
1672 
1673  protected:
1674  PerfCountersBase() throw()
1675  : addRefCount_(0)
1676  , releaseCount_(0)
1677  , queryInterfaceCount_(0)
1678  {}
1679 
1680  void IncrementAddRefCount() throw()
1681  {
1682  InterlockedIncrement(&addRefCount_);
1683  }
1684 
1685  void IncrementReleaseCount() throw()
1686  {
1687  InterlockedIncrement(&releaseCount_);
1688  }
1689 
1690  void IncrementQueryInterfaceCount() throw()
1691  {
1692  InterlockedIncrement(&queryInterfaceCount_);
1693  }
1694 
1695  private:
1696  volatile unsigned long addRefCount_;
1697  volatile unsigned long releaseCount_;
1698  volatile unsigned long queryInterfaceCount_;
1699  };
1700 #endif
1701 
1702 #if defined(_X86_) || defined(_AMD64_)
1703 
1704 # define UnknownIncrementReference InterlockedIncrement
1705 # define UnknownDecrementReference InterlockedDecrement
1706 # define UnknownBarrierAfterInterlock()
1707 # define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
1708 # define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointer
1709 # define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointer
1710 # define UnknownInterlockedCompareExchangeForIncrement InterlockedCompareExchange
1711 # define UnknownInterlockedCompareExchangeForRelease InterlockedCompareExchange
1712 
1713 #elif defined(_ARM_)
1714 
1715 # define UnknownIncrementReference InterlockedIncrementNoFence
1716 # define UnknownDecrementReference InterlockedDecrementRelease
1717 # define UnknownBarrierAfterInterlock() __dmb(_ARM_BARRIER_ISH)
1718 # define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
1719 # define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointerNoFence
1720 # define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointerRelease
1721 # define UnknownInterlockedCompareExchangeForIncrement InterlockedCompareExchangeNoFence
1722 # define UnknownInterlockedCompareExchangeForRelease InterlockedCompareExchangeRelease
1723 
1724 #elif defined(_ARM64_)
1725 
1726 # define UnknownIncrementReference InterlockedIncrementNoFence
1727 # define UnknownDecrementReference InterlockedDecrementRelease
1728 # define UnknownBarrierAfterInterlock() __dmb(_ARM64_BARRIER_ISH)
1729 # define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
1730 # define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointerNoFence
1731 # define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointerRelease
1732 # define UnknownInterlockedCompareExchangeForIncrement InterlockedCompareExchangeNoFence
1733 # define UnknownInterlockedCompareExchangeForRelease InterlockedCompareExchangeRelease
1734 
1735 #else
1736 
1737 # error Unsupported architecture.
1738 
1739 #endif
1740 
1741 // Since variadic templates can't have a parameter pack after default arguments, provide a convenient helper for
1742 // defaults.
1743 #define DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlagsT) \
1744  RuntimeClassFlagsT, (RuntimeClassFlagsT::value & InhibitWeakReference) == 0, \
1745  (RuntimeClassFlagsT::value & WinRt) == WinRt, __WRL_IMPLEMENTS_FTM_BASE__(RuntimeClassFlagsT::value)
1746 
1747  template <
1748  class RuntimeClassFlagsT,
1749  bool implementsWeakReferenceSource,
1750  bool implementsInspectable,
1751  bool implementsFtmBase,
1752  typename... TInterfaces>
1754 
1755 #ifdef _MSC_VER
1756 # pragma warning(push)
1757 // PREFast cannot see through template instantiation for AsIID()
1758 # pragma warning(disable : 6388)
1759 #endif
1760 
1761  // Reference counting functions that check overflow. If overflow is detected, ref count value will stop at
1762  // LONG_MAX, and the object being reference-counted will be leaked.
1763  inline unsigned long SafeUnknownIncrementReference(long volatile& refcount) throw()
1764  {
1765  long oldValue = refcount;
1766  while (oldValue != LONG_MAX &&
1767  (UnknownInterlockedCompareExchangeForIncrement(&refcount, oldValue + 1, oldValue) != oldValue))
1768  {
1769  oldValue = refcount;
1770  }
1771 
1772  if (oldValue != LONG_MAX)
1773  {
1774  return static_cast<unsigned long>(oldValue + 1);
1775  }
1776  else
1777  {
1778  return static_cast<unsigned long>(LONG_MAX);
1779  }
1780  }
1781 
1782  inline unsigned long SafeUnknownDecrementReference(long volatile& refcount) throw()
1783  {
1784  long oldValue = refcount;
1785  while (oldValue != LONG_MAX &&
1786  (UnknownInterlockedCompareExchangeForRelease(&refcount, oldValue - 1, oldValue) != oldValue))
1787  {
1788  oldValue = refcount;
1789  }
1790 
1791  return static_cast<unsigned long>(oldValue - 1);
1792  }
1793 
1794  template <
1795  class RuntimeClassFlagsT,
1796  bool implementsWeakReferenceSource,
1797  bool implementsFtmBase,
1798  typename... TInterfaces>
1800  RuntimeClassFlagsT,
1801  implementsWeakReferenceSource,
1802  false,
1803  implementsFtmBase,
1804  TInterfaces...>
1805  : public Details::AdjustImplements<RuntimeClassFlagsT, false, TInterfaces...>::Type
1806  , public RuntimeClassBaseT<RuntimeClassFlagsT::value>
1807  , protected RuntimeClassFlags<InhibitWeakReference>
1808  , public DontUseNewUseMake
1809 #ifdef _PERF_COUNTERS
1810  , public PerfCountersBase
1811 #endif
1812  {
1813  public:
1814  typedef RuntimeClassFlagsT ClassFlags;
1815 
1816  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
1817  {
1818 #ifdef _PERF_COUNTERS
1819  IncrementQueryInterfaceCount();
1820 #endif
1821  return Super::AsIID(this, riid, ppvObject);
1822  }
1823 
1824  STDMETHOD_(ULONG, AddRef)()
1825  {
1826  return InternalAddRef();
1827  }
1828 
1829  STDMETHOD_(ULONG, Release)()
1830  {
1831  ULONG ref = InternalRelease();
1832  if (ref == 0)
1833  {
1834  delete this;
1835 
1836  auto modulePtr = ::Microsoft::WRL::GetModuleBase();
1837  if (modulePtr != nullptr)
1838  {
1839  modulePtr->DecrementObjectCount();
1840  }
1841  }
1842 
1843  return ref;
1844  }
1845 
1846  protected:
1848 
1850  : refcount_(1)
1851  {}
1852 
1853  virtual ~RuntimeClassImpl() throw()
1854  {
1855  // Set refcount_ to -(LONG_MAX/2) to protect destruction and
1856  // also catch mismatched Release in debug builds
1857  refcount_ = -(LONG_MAX / 2);
1858  }
1859 
1860  unsigned long InternalAddRef() throw()
1861  {
1862 #ifdef _PERF_COUNTERS
1863  IncrementAddRefCount();
1864 #endif
1865  return SafeUnknownIncrementReference(refcount_);
1866  }
1867 
1868  unsigned long InternalRelease() throw()
1869  {
1870 #ifdef _PERF_COUNTERS
1871  IncrementReleaseCount();
1872 #endif
1873  // A release fence is required to ensure all guarded memory accesses are
1874  // complete before any thread can begin destroying the object.
1875  unsigned long newValue = SafeUnknownDecrementReference(refcount_);
1876  if (newValue == 0)
1877  {
1878  // An acquire fence is required before object destruction to ensure
1879  // that the destructor cannot observe values changing on other threads.
1880  UnknownBarrierAfterInterlock();
1881  }
1882  return newValue;
1883  }
1884 
1885  unsigned long GetRefCount() const throw()
1886  {
1887  return refcount_;
1888  }
1889 
1890  friend class WeakReferenceImpl;
1891 
1892  private:
1893  volatile long refcount_;
1894  };
1895 
1896  template <typename I, bool isImplementsBased = __is_base_of(ImplementsBase, I)>
1898 
1899  template <typename I>
1900  struct HasIInspectable<I, false>
1901  {
1902  static const bool isIInspectable = __is_base_of(IInspectable, I);
1903  };
1904 
1905  template <typename I>
1906  struct HasIInspectable<I, true>
1907  {
1909  };
1910 
1911 #ifdef __WRL_STRICT__
1912  template <typename I0, bool isIInspectable = true>
1913 #else
1914  template <typename I0, bool isIInspectable = HasIInspectable<I0>::isIInspectable>
1915 #endif
1917 
1918  template <typename I0>
1919  struct IInspectableInjector<I0, true>
1920  {
1922  };
1923 
1924  template <typename I0>
1925  struct IInspectableInjector<I0, false>
1926  {
1927  typedef IInspectable InspectableIfNeeded;
1928  };
1929 
1930  // Implements IInspectable in ILst
1931  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
1932  class WRT_NO_VTABLE RuntimeClassImpl<RuntimeClassFlagsT, false, true, false, I0, TInterfaces...>
1933  : public Details::AdjustImplements<
1934  RuntimeClassFlagsT,
1935  false,
1936  typename IInspectableInjector<I0>::InspectableIfNeeded,
1937  I0,
1938  TInterfaces...>::Type
1939  , public RuntimeClassBaseT<RuntimeClassFlagsT::value>
1940  , protected RuntimeClassFlags<InhibitWeakReference>
1941  , public DontUseNewUseMake
1942 #ifdef _PERF_COUNTERS
1943  , public PerfCountersBase
1944 #endif
1945  {
1946  public:
1947  typedef RuntimeClassFlagsT ClassFlags;
1948 
1949  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
1950  {
1951 #ifdef _PERF_COUNTERS
1952  IncrementQueryInterfaceCount();
1953 #endif
1954  return Super::AsIID(this, riid, ppvObject);
1955  }
1956 
1957  STDMETHOD_(ULONG, AddRef)()
1958  {
1959  return InternalAddRef();
1960  }
1961 
1962  STDMETHOD_(ULONG, Release)()
1963  {
1964  ULONG ref = InternalRelease();
1965  if (ref == 0)
1966  {
1967  delete this;
1968 
1969  auto modulePtr = ::Microsoft::WRL::GetModuleBase();
1970  if (modulePtr != nullptr)
1971  {
1972  modulePtr->DecrementObjectCount();
1973  }
1974  }
1975 
1976  return ref;
1977  }
1978 
1979  // IInspectable methods
1980  STDMETHOD(GetIids)
1981  (ULONG* iidCount,
1982  _When_(*iidCount == 0, _At_(*iids, _Post_null_)) _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
1983  _Result_nullonfailure_ IID** iids)
1984  {
1985  return Super::GetImplementedIIDS(this, iidCount, iids);
1986  }
1987 
1988 #if !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
1989  STDMETHOD(GetRuntimeClassName)(HSTRING* runtimeClassName)
1990  {
1991  *runtimeClassName = nullptr;
1992 
1993  __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
1994 
1995 # ifdef WRL_RO_ERROR_API_ENABLED
1997  E_NOTIMPL, nullptr);
1998 # endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
1999  return E_NOTIMPL;
2000  }
2001 
2002  STDMETHOD(GetTrustLevel)(::TrustLevel*)
2003  {
2004  __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
2005 
2006 # ifdef WRL_RO_ERROR_API_ENABLED
2008  E_NOTIMPL, nullptr);
2009 # endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
2010  return E_NOTIMPL;
2011  }
2012 #endif // !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
2013 
2014  protected:
2016 
2018  : refcount_(1)
2019  {}
2020 
2021  virtual ~RuntimeClassImpl() throw()
2022  {
2023  // Set refcount_ to -(LONG_MAX/2) to protect destruction and
2024  // also catch mismatched Release in debug builds
2025  refcount_ = -(LONG_MAX / 2);
2026  }
2027 
2028  unsigned long InternalAddRef() throw()
2029  {
2030 #ifdef _PERF_COUNTERS
2031  IncrementAddRefCount();
2032 #endif
2033  return SafeUnknownIncrementReference(refcount_);
2034  }
2035 
2036  unsigned long InternalRelease() throw()
2037  {
2038 #ifdef _PERF_COUNTERS
2039  IncrementReleaseCount();
2040 #endif
2041  // A release fence is required to ensure all guarded memory accesses are
2042  // complete before any thread can begin destroying the object.
2043  unsigned long newValue = SafeUnknownDecrementReference(refcount_);
2044  if (newValue == 0)
2045  {
2046  // An acquire fence is required before object destruction to ensure
2047  // that the destructor cannot observe values changing on other threads.
2048  UnknownBarrierAfterInterlock();
2049  }
2050  return newValue;
2051  }
2052 
2053  unsigned long GetRefCount() const throw()
2054  {
2055  return refcount_;
2056  }
2057 
2058  private:
2059  volatile long refcount_;
2060  };
2061 
2063  {
2064  public:
2065  StrongReference(long refCount = 1) throw()
2066  : strongRefCount_(refCount)
2067  {}
2068 
2070  {
2071  // Set refcount_ to -(LONG_MAX/2) to protect destruction and
2072  // also catch mismatched Release in debug builds
2073  strongRefCount_ = -(LONG_MAX / 2);
2074  }
2075 
2076  unsigned long IncrementStrongReference() throw()
2077  {
2079  }
2080 
2081  unsigned long DecrementStrongReference() throw()
2082  {
2083  // A release fence is required to ensure all guarded memory accesses are
2084  // complete before any thread can begin destroying the object.
2085  unsigned long newValue = SafeUnknownDecrementReference(strongRefCount_);
2086  if (newValue == 0)
2087  {
2088  // An acquire fence is required before object destruction to ensure
2089  // that the destructor cannot observe values changing on other threads.
2090  UnknownBarrierAfterInterlock();
2091  }
2092  return newValue;
2093  }
2094 
2095  unsigned long GetStrongReferenceCount() throw()
2096  {
2097  return static_cast<unsigned long>(strongRefCount_);
2098  }
2099 
2100  void SetStrongReference(unsigned long value) throw()
2101  {
2102  strongRefCount_ = static_cast<long>(value);
2103  }
2104 
2106  };
2107 
2108  // To support storing, encoding and decoding reference-count/pointers regardless of the target platform.
2109  // In a RuntimeClass, the refCount_ member can mean either
2110  // 1. actual reference count
2111  // 2. pointer to the weak reference object which holds the strong count
2112  // The member
2113  // 1. If it is a count, the most significant bit will be OFF
2114  // 2. If it is an encoded pointer to the weak reference, the most significant bit will be turned ON
2115  // To test which mode it is
2116  // 1. Test for negative
2117  // 2. If it is, it is an encoded pointer to the weak reference
2118  // 3. If it is not, it is the actual reference count
2119  // To yield the encoded pointer
2120  // 1. Test the value for negative
2121  // 2. If it is, shift the value to the left and cast it to a WeakReferenceImpl*
2122  //
2123  const UINT_PTR EncodeWeakReferencePointerFlag = static_cast<UINT_PTR>(1) << ((sizeof(UINT_PTR) * 8) - 1);
2124 
2126  {
2127  // Represents the count when it is a count (in practice only the least significant 4 bytes)
2128  UINT_PTR refCount;
2129  // Pointer size, *signed* to help with ease of casting and such
2130  INT_PTR rawValue;
2131  // The hint that this could also be a pointer
2133  };
2134 
2135  // Helper methods to test, decode and decode the different representations of
2136  // ReferenceCountOrWeakReferencePointer
2137  inline bool IsValueAPointerToWeakReference(INT_PTR value)
2138  {
2139  return value < 0;
2140  }
2141 
2142  // Forward declaration
2143  class WeakReferenceImpl;
2146 
2147 // Helper functions, originally from winnt.h, needed to get the semantics right when fetching values
2148 // in multi-threaded scenarios. This is in order to guarantee the compiler emits exactly one read
2149 // (compiler may decide to re-fetch the value later on, which in some cases can break code)
2150 #if defined(_ARM_)
2151 
2152  FORCEINLINE
2153  LONG ReadULongPtrNoFence(DWORD const volatile* Source)
2154 
2155  {
2156  LONG Value;
2157 
2158  Value = __iso_volatile_load32((int*)Source);
2159  return Value;
2160  }
2161 
2162 #elif defined(_ARM64_)
2163 
2164  FORCEINLINE
2165  LONG64
2166  ReadULongPtrNoFence(DWORD64 const volatile* Source)
2167 
2168  {
2169  LONG64 Value;
2170 
2171  Value = __iso_volatile_load64((__int64*)Source);
2172  return Value;
2173  }
2174 
2175 #elif defined(_X86_)
2176 
2177  FORCEINLINE
2178  LONG ReadULongPtrNoFence(DWORD const volatile* Source)
2179 
2180  {
2181  LONG Value;
2182 
2183  Value = *Source;
2184  return Value;
2185  }
2186 
2187 #elif defined(_AMD64_)
2188 
2189  FORCEINLINE
2190  LONG64
2191  ReadULongPtrNoFence(DWORD64 const volatile* Source)
2192 
2193  {
2194  LONG64 Value;
2195 
2196  Value = static_cast<LONG64>(*Source);
2197  return Value;
2198  }
2199 
2200 #else
2201 
2202 # error Unsupported architecture.
2203 
2204 #endif
2205 
2206  template <typename T>
2207  inline T ReadValueFromPointerNoFence(const volatile T* value)
2208  {
2209  ULONG_PTR currentValue = ReadULongPtrNoFence(reinterpret_cast<const volatile ULONG_PTR*>(value));
2210  const T* currentPointerToValue = reinterpret_cast<T*>(&currentValue);
2211  return *currentPointerToValue;
2212  }
2213 
2214  inline WeakReferenceImpl* CreateWeakReference(IUnknown*);
2215 
2216  // Implementation of activatable class that implements IWeakReferenceSource
2217  // and delegates reference counting to WeakReferenceImpl object
2218  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2219  class WRT_NO_VTABLE RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>
2220  : public Details::AdjustImplements<
2221  RuntimeClassFlagsT,
2222  false,
2223  typename IInspectableInjector<I0>::InspectableIfNeeded,
2224  I0,
2225  IWeakReferenceSource,
2226  TInterfaces...>::Type
2227  , public RuntimeClassBaseT<RuntimeClassFlagsT::value>
2228  , public DontUseNewUseMake
2229 #ifdef _PERF_COUNTERS
2230  , public PerfCountersBase
2231 #endif
2232  {
2233  public:
2234  typedef RuntimeClassFlagsT ClassFlags;
2235 
2237  {
2238  refCount_.rawValue = 1;
2239  }
2240 
2241  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
2242  {
2243 #ifdef _PERF_COUNTERS
2244  IncrementQueryInterfaceCount();
2245 #endif
2246  return Super::AsIID(this, riid, ppvObject);
2247  }
2248 
2249  STDMETHOD_(ULONG, AddRef)()
2250  {
2251  return InternalAddRef();
2252  }
2253 
2254  STDMETHOD_(ULONG, Release)()
2255  {
2256  ULONG ref = InternalRelease();
2257  if (ref == 0)
2258  {
2259  delete this;
2260 
2261  auto modulePtr = ::Microsoft::WRL::GetModuleBase();
2262  if (modulePtr != nullptr)
2263  {
2264  modulePtr->DecrementObjectCount();
2265  }
2266  }
2267 
2268  return ref;
2269  }
2270 
2271  // IInspectable methods
2272  STDMETHOD(GetIids)
2273  (ULONG* iidCount,
2274  _When_(*iidCount == 0, _At_(*iids, _Post_null_)) _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
2275  _Result_nullonfailure_ IID** iids)
2276  {
2277  return Super::GetImplementedIIDS(this, iidCount, iids);
2278  }
2279 
2280 #if !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
2281  STDMETHOD(GetRuntimeClassName)(HSTRING* runtimeClassName)
2282  {
2283  *runtimeClassName = nullptr;
2284 
2285  __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
2286 
2287 # ifdef WRL_RO_ERROR_API_ENABLED
2289  E_NOTIMPL, nullptr);
2290 # endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
2291  return E_NOTIMPL;
2292  }
2293 
2294  STDMETHOD(GetTrustLevel)(::TrustLevel*)
2295  {
2296  __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
2297 # ifdef WRL_RO_ERROR_API_ENABLED
2299  E_NOTIMPL, nullptr);
2300 # endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
2301  return E_NOTIMPL;
2302  }
2303 #endif // !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
2304 
2305  STDMETHOD(GetWeakReference)(_Outptr_ IWeakReference** weakReference);
2306 
2307  virtual ~RuntimeClassImpl() throw();
2308 
2309  protected:
2310  template <unsigned int RuntimeClassTypeT>
2311  friend class Details::RuntimeClassBaseT;
2312  using ImplementsHelper = typename Details::AdjustImplements<
2313  RuntimeClassFlagsT,
2314  false,
2315  typename IInspectableInjector<I0>::InspectableIfNeeded,
2316  I0,
2318  TInterfaces...>::Type;
2319  using Super = RuntimeClassBaseT<RuntimeClassFlagsT::value>;
2320 
2321  unsigned long InternalAddRef() throw();
2322 
2323  unsigned long InternalRelease() throw();
2324 
2325  unsigned long GetRefCount() const throw();
2326 
2327  friend class WeakReferenceImpl;
2328 
2329 #ifdef __WRL_UNITTEST__
2330 
2331  protected:
2332 #else
2333 
2334  private:
2335 #endif
2337  };
2338 
2340  {
2341  return static_cast<INT_PTR>(
2342  (reinterpret_cast<INT_PTR>(value) >> static_cast<INT_PTR>(1)) |
2343  static_cast<INT_PTR>(EncodeWeakReferencePointerFlag));
2344  }
2345 
2347  {
2348  return reinterpret_cast<Microsoft::WRL::Details::WeakReferenceImpl*>(static_cast<UINT_PTR>(value) << 1);
2349  }
2350 
2351 #ifdef _MSC_VER
2352 # pragma warning(pop) // C6388
2353 #endif
2354 
2355  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2356  class WRT_NO_VTABLE RuntimeClassImpl<RuntimeClassFlagsT, false, true, true, I0, TInterfaces...>
2357  : public RuntimeClassImpl<RuntimeClassFlagsT, false, true, false, I0, TInterfaces...>
2358  {};
2359 
2360  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2361  class WRT_NO_VTABLE RuntimeClassImpl<RuntimeClassFlagsT, true, true, true, I0, TInterfaces...>
2362  : public RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, FtmBase, TInterfaces...>
2363  {};
2364 
2365  // To minimize breaks with code written against WRL before variadic support was added, this form is
2366  // maintained.
2367  template <typename... TInterfaces>
2369  {
2370  typedef InterfaceListHelper<TInterfaces...> TypeT;
2371  };
2372 
2373  template <
2374  typename ILst,
2375  class RuntimeClassFlagsT,
2376  bool implementsWeakReferenceSource = (RuntimeClassFlagsT::value & InhibitWeakReference) == 0,
2377  bool implementsInspectable = (RuntimeClassFlagsT::value & WinRt) == WinRt,
2378  bool implementsFtmBase = __WRL_IMPLEMENTS_FTM_BASE__(RuntimeClassFlagsT::value)>
2380 
2381  template <
2382  typename RuntimeClassFlagsT,
2383  bool implementsWeakReferenceSource,
2384  bool implementsInspectable,
2385  bool implementsFtmBase,
2386  typename... TInterfaces>
2388  InterfaceListHelper<TInterfaces...>,
2389  RuntimeClassFlagsT,
2390  implementsWeakReferenceSource,
2391  implementsInspectable,
2392  implementsFtmBase>
2393  : public RuntimeClassImpl<
2394  RuntimeClassFlagsT,
2395  implementsWeakReferenceSource,
2396  implementsInspectable,
2397  implementsFtmBase,
2398  TInterfaces...>
2399  {
2400  protected:
2401 #ifdef _MSC_VER
2402 # pragma warning(suppress : 6101) // Function only used internally and the value of 'ppvObject' is only used if
2403  // *handled is true
2404 #endif
2405  HRESULT
2406  CustomQueryInterface(REFIID /*riid*/, void** /*ppvObject*/, bool* handled)
2407  {
2408  *handled = false;
2409  return S_OK;
2410  }
2411  };
2412 
2413  } // namespace Details
2414 
2415  // The RuntimeClass IUnknown methods
2416  // It inherits from Details::RuntimeClass that provides helper methods for reference counting and
2417  // collecting IIDs
2418  template <typename... TInterfaces>
2420  : public Details::
2421  RuntimeClassImpl<DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlags<WinRt>), TInterfaces...>
2422  {
2423  RuntimeClass(const RuntimeClass&);
2424  RuntimeClass& operator=(const RuntimeClass&);
2425 
2426  protected:
2427 #ifdef _MSC_VER
2428 # pragma warning(suppress : 6101) // Function only used internally and the value of 'ppvObject' is only used if
2429  // *handled is true
2430 #endif
2431  HRESULT
2432  CustomQueryInterface(REFIID /*riid*/, void** /*ppvObject*/, bool* handled)
2433  {
2434  *handled = false;
2435  return S_OK;
2436  }
2437 
2438  public:
2439  RuntimeClass() throw()
2440  {
2441  auto modulePtr = ::Microsoft::WRL::GetModuleBase();
2442  if (modulePtr != nullptr)
2443  {
2444  modulePtr->IncrementObjectCount();
2445  }
2446  }
2448  };
2449 
2450  template <unsigned int classFlags, typename... TInterfaces>
2451  class RuntimeClass<RuntimeClassFlags<classFlags>, TInterfaces...>
2452  : public Details::
2453  RuntimeClassImpl<DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlags<classFlags>), TInterfaces...>
2454  {
2455  RuntimeClass(const RuntimeClass&);
2456  RuntimeClass& operator=(const RuntimeClass&);
2457 
2458  protected:
2459 #ifdef _MSC_VER
2460 # pragma warning(suppress : 6101) // Function only used internally and the value of 'ppvObject' is only used if
2461  // *handled is true
2462 #endif
2463  HRESULT
2464  CustomQueryInterface(REFIID /*riid*/, void** /*ppvObject*/, bool* handled)
2465  {
2466  *handled = false;
2467  return S_OK;
2468  }
2469 
2470  public:
2471  RuntimeClass() throw()
2472  {
2473  auto modulePtr = ::Microsoft::WRL::GetModuleBase();
2474  if (modulePtr != nullptr)
2475  {
2476  modulePtr->IncrementObjectCount();
2477  }
2478  }
2480  };
2481 
2482  namespace Details
2483  {
2484  // Weak reference implementation
2485  class WeakReferenceImpl final
2486  : public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<ClassicCom>, IWeakReference>
2487  , public StrongReference
2488  {
2489  public:
2490  WeakReferenceImpl(IUnknown* unk) throw()
2491  : StrongReference(LONG_MAX / 2)
2492  , unknown_(unk)
2493  {
2494  // Set ref count to 2 to avoid unnecessary interlocked increment operation while returning
2495  // WeakReferenceImpl from GetWeakReference method. One reference is hold by the object the second is
2496  // hold by the caller of GetWeakReference method.
2497  refcount_ = 2;
2498  }
2499 
2500  virtual ~WeakReferenceImpl() throw()
2501  {}
2502 
2503  STDMETHOD(Resolve)
2504  (REFIID riid, _Outptr_result_maybenull_ _Result_nullonfailure_ IInspectable** ppvObject)
2505  {
2506  *ppvObject = nullptr;
2507 
2508  for (;;)
2509  {
2510  long ref = this->strongRefCount_;
2511  if (ref == 0)
2512  {
2513  return S_OK;
2514  }
2515 
2516  // InterlockedCompareExchange calls _InterlockedCompareExchange intrinsic thus we call directly
2517  // _InterlockedCompareExchange to save the call
2518  if (::_InterlockedCompareExchange(&this->strongRefCount_, ref + 1, ref) == ref)
2519  {
2520 #ifdef _PERF_COUNTERS
2521  // This artificially manipulates the strong ref count via AddRef to account for the resolve
2522  // interlocked operation above when tallying reference counting operations.
2523  unknown_->AddRef();
2524  ::_InterlockedDecrement(&this->strongRefCount_);
2525 #endif
2526  break;
2527  }
2528  }
2529 
2530  HRESULT hr = unknown_->QueryInterface(riid, reinterpret_cast<void**>(ppvObject));
2531  unknown_->Release();
2532  return hr;
2533  }
2534 
2535  private:
2536  IUnknown* unknown_;
2537  };
2538 
2539  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2541  {
2542  if (IsValueAPointerToWeakReference(refCount_.rawValue))
2543  {
2544  WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(refCount_.rawValue);
2545  weakRef->Release();
2546  weakRef = nullptr;
2547  }
2548  }
2549 
2550  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2551  unsigned long
2553  {
2555  ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
2556 
2557  if (IsValueAPointerToWeakReference(currentValue.rawValue))
2558  {
2559  WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
2560  return weakRef->GetStrongReferenceCount();
2561  }
2562  else
2563  {
2564  return static_cast<unsigned long>(currentValue.refCount);
2565  }
2566  }
2567 
2568  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2569  unsigned long
2571  {
2572 #ifdef _PERF_COUNTERS
2573  IncrementAddRefCount();
2574 #endif
2575 
2577  ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
2578 
2579  for (;;)
2580  {
2581  if (!IsValueAPointerToWeakReference(currentValue.rawValue))
2582  {
2583  if (static_cast<long>(currentValue.refCount) == LONG_MAX)
2584  {
2585  return LONG_MAX;
2586  }
2587 
2588  UINT_PTR updateValue = currentValue.refCount + 1;
2589 
2590 #ifdef __WRL_UNITTEST__
2591  OnBeforeInternalAddRefIncrement();
2592 #endif
2593 
2594  INT_PTR previousValue =
2595  reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointerForIncrement(
2596  reinterpret_cast<PVOID*>(&(refCount_.refCount)),
2597  reinterpret_cast<PVOID>(updateValue),
2598  reinterpret_cast<PVOID>(currentValue.refCount)));
2599  if (previousValue == currentValue.rawValue)
2600  {
2601  return static_cast<unsigned long>(updateValue);
2602  }
2603 
2604  currentValue.rawValue = previousValue;
2605  }
2606  else
2607  {
2608  WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
2609  return weakRef->IncrementStrongReference();
2610  }
2611  }
2612  }
2613 
2614  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2615  unsigned long
2617  {
2618 #ifdef _PERF_COUNTERS
2619  IncrementReleaseCount();
2620 #endif
2621 
2623  ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
2624 
2625  for (;;)
2626  {
2627  if (!IsValueAPointerToWeakReference(currentValue.rawValue))
2628  {
2629  if (static_cast<long>(currentValue.refCount) == LONG_MAX)
2630  {
2631  return LONG_MAX - 1;
2632  }
2633 
2634  UINT_PTR updateValue = currentValue.refCount - 1;
2635 
2636 #ifdef __WRL_UNITTEST__
2637  OnBeforeInternalReleaseDecrement();
2638 #endif
2639 
2640  INT_PTR previousValue =
2641  reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointerForIncrement(
2642  reinterpret_cast<PVOID*>(&(refCount_.refCount)),
2643  reinterpret_cast<PVOID>(updateValue),
2644  reinterpret_cast<PVOID>(currentValue.refCount)));
2645  if (previousValue == currentValue.rawValue)
2646  {
2647  return static_cast<unsigned long>(updateValue);
2648  }
2649 
2650  currentValue.rawValue = previousValue;
2651  }
2652  else
2653  {
2654  WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
2655  return weakRef->DecrementStrongReference();
2656  }
2657  }
2658  }
2659 
2660  template <class RuntimeClassFlagsT, typename I0, typename... TInterfaces>
2661  COM_DECLSPEC_NOTHROW HRESULT
2663  _Outptr_ IWeakReference** weakReference)
2664  {
2665  WeakReferenceImpl* weakRef = nullptr;
2666  INT_PTR encodedWeakRef = 0;
2668  ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
2669 
2670  *weakReference = nullptr;
2671 
2672  if (IsValueAPointerToWeakReference(currentValue.rawValue))
2673  {
2674  weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
2675 
2676  weakRef->AddRef();
2677  *weakReference = weakRef;
2678  return S_OK;
2679  }
2680 
2681  // WeakReferenceImpl is created with ref count 2 to avoid interlocked increment
2682  weakRef = CreateWeakReference(ImplementsHelper::CastToUnknown());
2683  if (weakRef == nullptr)
2684  {
2685  return E_OUTOFMEMORY;
2686  }
2687 
2688  encodedWeakRef = EncodeWeakReferencePointer(weakRef);
2689 
2690  for (;;)
2691  {
2692  INT_PTR previousValue = 0;
2693 
2694  weakRef->SetStrongReference(static_cast<unsigned long>(currentValue.refCount));
2695 
2696 #ifdef __WRL_UNITTEST__
2697  OnBeforeGetWeakReferenceSwap();
2698 #endif
2699 
2700  previousValue = reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointer(
2701  reinterpret_cast<PVOID*>(
2702  &(this->refCount_.ifHighBitIsSetThenShiftLeftToYieldPointerToWeakReference)),
2703  reinterpret_cast<PVOID>(encodedWeakRef),
2705  if (previousValue == currentValue.rawValue)
2706  {
2707  // No need to call AddRef in this case, WeakReferenceImpl is created with ref count 2 to avoid
2708  // interlocked increment
2709  *weakReference = weakRef;
2710  return S_OK;
2711  }
2712  else if (IsValueAPointerToWeakReference(previousValue))
2713  {
2714  // Another thread beat this call to create the weak reference.
2715 
2716  delete weakRef;
2717 
2718  weakRef = DecodeWeakReferencePointer(previousValue);
2719  weakRef->AddRef();
2720  *weakReference = weakRef;
2721  return S_OK;
2722  }
2723 
2724  // Another thread won via an AddRef or Release.
2725  // Let's try again
2726  currentValue.rawValue = previousValue;
2727  }
2728  }
2729 
2730  // Memory allocation for object that doesn't support weak references
2731  // It only allocates memory
2732  template <typename T>
2734  {
2735  public:
2736  MakeAllocator() throw()
2737  : buffer_(nullptr)
2738  {}
2739 
2740  ~MakeAllocator() throw()
2741  {
2742  if (buffer_ != nullptr)
2743  {
2744  delete buffer_;
2745  }
2746  }
2747 
2748  void* Allocate() throw()
2749  {
2750  __WRL_ASSERT__(buffer_ == nullptr);
2751  // Allocate memory with operator new(size, nothrow) only
2752  // This will allow developer to override one operator only
2753  // to enable different memory allocation model
2754 #ifdef __cpp_aligned_new
2755  if constexpr (alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
2756  {
2757  return buffer_ = reinterpret_cast<char*>(operator new(
2758  sizeof(T), static_cast<std::align_val_t>(alignof(T)), ::std::nothrow));
2759  }
2760 #endif // /std:c++17 or later
2761  return buffer_ = reinterpret_cast<char*>(operator new(sizeof(T), ::std::nothrow));
2762  }
2763 
2764  void Detach() throw()
2765  {
2766  buffer_ = nullptr;
2767  }
2768 
2769  private:
2770  char* buffer_;
2771  };
2772 
2773  } // Details
2774 
2775 #ifdef _MSC_VER
2776 # pragma region make overloads
2777 #endif
2778 
2779  namespace Details
2780  {
2781 
2782  // Make and MakeAndInitialize functions must not be marked as throw() as the constructor is allowed to throw
2783  // exceptions.
2784  template <typename T, typename... TArgs>
2785  ComPtr<T> Make(TArgs&&... args)
2786  {
2787  static_assert(
2788  __is_base_of(Details::RuntimeClassBase, T),
2789  "Make can only instantiate types that derive from RuntimeClass");
2790  ComPtr<T> object;
2791  Details::MakeAllocator<T> allocator;
2792  void* buffer = allocator.Allocate();
2793  if (buffer != nullptr)
2794  {
2795  auto ptr = new (buffer) T(Details::Forward<TArgs>(args)...);
2796  object.Attach(ptr);
2797  allocator.Detach();
2798  }
2799  return object;
2800  }
2801 
2802 #ifdef _MSC_VER
2803 # pragma warning(push)
2804 # pragma warning(disable : 6387 6388 28196) // PREFast does not understand call to ComPtr<T>::CopyTo() is safe here
2805 #endif
2806 
2807  template <typename T, typename I, typename... TArgs>
2808  HRESULT MakeAndInitialize(I** result, TArgs&&... args)
2809  {
2810  static_assert(
2811  __is_base_of(Details::RuntimeClassBase, T),
2812  "Make can only instantiate types that derive from RuntimeClass");
2813  static_assert(__is_base_of(I, T), "The 'T' runtime class doesn't implement 'I' interface");
2814  *result = nullptr;
2815  Details::MakeAllocator<T> allocator;
2816  void* buffer = allocator.Allocate();
2817  if (buffer == nullptr)
2818  {
2819  return E_OUTOFMEMORY;
2820  }
2821  auto ptr = new (buffer) T;
2822  ComPtr<T> object;
2823  object.Attach(ptr);
2824  allocator.Detach();
2825  HRESULT hr = object->RuntimeClassInitialize(Details::Forward<TArgs>(args)...);
2826  if (FAILED(hr))
2827  {
2828  return hr;
2829  }
2830  return object.CopyTo(result);
2831  }
2832 
2833 #ifdef _MSC_VER
2834 # pragma warning(pop) // C6387 C6388 C28196
2835 #endif
2836 
2837  template <typename T, typename I, typename... TArgs>
2838  HRESULT MakeAndInitialize(_Inout_ ComPtrRef<ComPtr<I>> ppvObject, TArgs&&... args)
2839  {
2840  return MakeAndInitialize<T>(ppvObject.ReleaseAndGetAddressOf(), Details::Forward<TArgs>(args)...);
2841  }
2842 
2843  } // end of Details
2844 
2846  using Details::Make;
2847 
2848 #ifdef _MSC_VER
2849 # pragma endregion // make overloads
2850 #endif
2851 
2852  namespace Details
2853  {
2855  {
2856  return Make<WeakReferenceImpl>(unk).Detach();
2857  }
2858  }
2859 
2860 #define InspectableClass(runtimeClassName, trustLevel) \
2861 \
2862  public: \
2863  static _Null_terminated_ const wchar_t* STDMETHODCALLTYPE InternalGetRuntimeClassName() throw() \
2864  { \
2865  static_assert( \
2866  (RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRtClassicComMix) == ::Microsoft::WRL::WinRt || \
2867  (RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRtClassicComMix) == \
2868  ::Microsoft::WRL::WinRtClassicComMix, \
2869  "'InspectableClass' macro must not be used with ClassicCom clasess."); \
2870  static_assert( \
2871  __is_base_of(::Microsoft::WRL::Details::RuntimeClassBase, RuntimeClassT), \
2872  "'InspectableClass' macro can only be used with ::Windows::WRL::RuntimeClass types"); \
2873  static_assert( \
2874  !__is_base_of(IActivationFactory, RuntimeClassT), \
2875  "Incorrect usage of IActivationFactory interface. Make sure that your RuntimeClass doesn't implement " \
2876  "IActivationFactory interface use ::Windows::WRL::ActivationFactory instead or 'InspectableClass' macro " \
2877  "is not used on ::Windows::WRL::ActivationFactory"); \
2878  return runtimeClassName; \
2879  } \
2880  static ::TrustLevel STDMETHODCALLTYPE InternalGetTrustLevel() throw() \
2881  { \
2882  return trustLevel; \
2883  } \
2884  STDMETHOD(GetRuntimeClassName)(HSTRING * runtimeName) override \
2885  { \
2886  *runtimeName = nullptr; \
2887  HRESULT hr = S_OK; \
2888  auto name = InternalGetRuntimeClassName(); \
2889  if (name != nullptr) \
2890  { \
2891  hr = ::WindowsCreateString(name, static_cast<UINT32>(::wcslen(name)), runtimeName); \
2892  } \
2893  return hr; \
2894  } \
2895  STDMETHOD(GetTrustLevel)(::TrustLevel * trustLvl) override \
2896  { \
2897  *trustLvl = trustLevel; \
2898  return S_OK; \
2899  } \
2900  STDMETHOD(GetIids) \
2901  (ULONG * iidCount, \
2902  _When_(*iidCount == 0, _At_(*iids, _Post_null_)) _When_(*iidCount > 0, _At_(*iids, _Post_notnull_)) \
2903  _Result_nullonfailure_ IID * \
2904  *iids) override \
2905  { \
2906  return RuntimeClassT::GetIids(iidCount, iids); \
2907  } \
2908  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) override \
2909  { \
2910  bool handled = false; \
2911  HRESULT hr = this->CustomQueryInterface(riid, ppvObject, &handled); \
2912  if (FAILED(hr) || handled) \
2913  return hr; \
2914  return RuntimeClassT::QueryInterface(riid, ppvObject); \
2915  } \
2916  STDMETHOD_(ULONG, Release)() override \
2917  { \
2918  return RuntimeClassT::Release(); \
2919  } \
2920  STDMETHOD_(ULONG, AddRef)() override \
2921  { \
2922  return RuntimeClassT::AddRef(); \
2923  } \
2924 \
2925  private:
2926 
2927 #define MixInHelper() \
2928 \
2929  public: \
2930  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) \
2931  { \
2932  static_assert( \
2933  (RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRt) == 0, \
2934  "'MixInClass' macro must not be used with WinRt clasess."); \
2935  static_assert( \
2936  __is_base_of(::Microsoft::WRL::Details::RuntimeClassBase, RuntimeClassT), \
2937  "'MixInHelper' macro can only be used with ::Windows::WRL::RuntimeClass types"); \
2938  static_assert( \
2939  !__is_base_of(IClassFactory, RuntimeClassT), \
2940  "Incorrect usage of IClassFactory interface. Make sure that your RuntimeClass doesn't implement " \
2941  "IClassFactory interface use ::Windows::WRL::ClassFactory instead or 'MixInHelper' macro is not used on " \
2942  "::Windows::WRL::ClassFactory"); \
2943  return RuntimeClassT::QueryInterface(riid, ppvObject); \
2944  } \
2945  STDMETHOD_(ULONG, Release)() \
2946  { \
2947  return RuntimeClassT::Release(); \
2948  } \
2949  STDMETHOD_(ULONG, AddRef)() \
2950  { \
2951  return RuntimeClassT::AddRef(); \
2952  } \
2953 \
2954  private:
2955 
2956 // Please make sure that those macros are in sync with those ones from 'wrl/module.h'
2957 #ifndef WrlCreatorMapIncludePragmaEx
2958 # define WrlCreatorMapIncludePragmaEx(className, group) \
2959  static_assert( \
2960  false, "It's required to include 'wrl/module.h' to be able to use 'WrlCreatorMapIncludePragmaEx' macro");
2961 #endif
2962 
2963 #ifndef WrlCreatorMapIncludePragma
2964 # define WrlCreatorMapIncludePragma(className) \
2965  static_assert( \
2966  false, "It's required to include 'wrl/module.h' to be able to use 'WrlCreatorMapIncludePragma' macro");
2967 #endif
2968 
2969 #ifndef ActivatableClassWithFactoryEx
2970 # define ActivatableClassWithFactoryEx(className, factory, groupId) \
2971  static_assert( \
2972  false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClassWithFactoryEx' macro");
2973 #endif
2974 
2975 #ifndef ActivatableClassWithFactory
2976 # define ActivatableClassWithFactory(className, factory) \
2977  static_assert( \
2978  false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClassWithFactory' macro");
2979 #endif
2980 
2981 #ifndef ActivatableClass
2982 # define ActivatableClass(className) \
2983  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClass' macro");
2984 #endif
2985 
2986 #ifndef ActivatableStaticOnlyFactoryEx
2987 # define ActivatableStaticOnlyFactoryEx(factory, serverName) \
2988  static_assert( \
2989  false, \
2990  "It's required to include 'wrl/module.h' to be able to use 'ActivatableStaticOnlyFactoryEx' macro");
2991 #endif
2992 
2993 #ifndef ActivatableStaticOnlyFactory
2994 # define ActivatableStaticOnlyFactory(factory) \
2995  static_assert( \
2996  false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableStaticOnlyFactory' macro");
2997 #endif
2998 
2999 #ifndef CoCreatableClassWithFactoryEx
3000 # define CoCreatableClassWithFactoryEx(className, factory, groupId) \
3001  static_assert( \
3002  false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWithFactory' macro");
3003 #endif
3004 
3005 #ifndef CoCreatableClassWithFactory
3006 # define CoCreatableClassWithFactory(className, factory) \
3007  static_assert( \
3008  false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWithFactory' macro");
3009 #endif
3010 
3011 #ifndef CoCreatableClass
3012 # define CoCreatableClass(className) \
3013  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClass' macro");
3014 #endif
3015 
3016 #ifndef CoCreatableClassWrlCreatorMapInclude
3017 # define CoCreatableClassWrlCreatorMapInclude(className) \
3018  static_assert( \
3019  false, \
3020  "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWrlCreatorMapInclude' macro");
3021 #endif
3022 
3023 #ifndef CoCreatableClassWrlCreatorMapIncludeEx
3024 # define CoCreatableClassWrlCreatorMapIncludeEx(className, groupId) \
3025  static_assert( \
3026  false, \
3027  "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWrlCreatorMapInclude' macro");
3028 #endif
3029 
3030 #undef UnknownIncrementReference
3031 #undef UnknownDecrementReference
3032 #undef UnknownBarrierAfterInterlock
3033 #undef UnknownInterlockedCompareExchangePointer
3034 #undef UnknownInterlockedCompareExchangePointerForIncrement
3035 #undef UnknownInterlockedCompareExchangePointerForRelease
3036 
3037  }
3038 } // namespace Microsoft::WRL
3039 
3040 #ifdef _MSC_VER
3041 # pragma warning(pop)
3042 #endif
3043 
3044 // Restore packing
3045 #pragma pack(pop)
3046 
3047 #endif // _WRL_IMPLEMENTS_H_
HRESULT As(Details::ComPtrRef< ComPtr< U >> p) const
Definition: client.h:300
void Attach(InterfaceType *other)
Definition: client.h:266
Definition: implements.h:115
Definition: client.h:57
Definition: implements.h:289
Definition: implements.h:396
Definition: implements.h:2734
void * Allocate()
Definition: implements.h:2748
void Detach()
Definition: implements.h:2764
~MakeAllocator()
Definition: implements.h:2740
MakeAllocator()
Definition: implements.h:2736
Definition: implements.h:184
_In_opt_z_ const wchar_t _In_z_ const wchar_t _Inout_ RO_REGISTRATION_COOKIE * cookie
Definition: implements.h:269
_In_opt_z_ const wchar_t _In_z_ const wchar_t _Inout_ RO_REGISTRATION_COOKIE unsigned int
Definition: implements.h:270
static volatile unsigned long objectCount_
Definition: implements.h:189
STDMETHOD_(const CreatorMap **, GetLastEntryPointer)() const
Definition: implements.h:256
_In_opt_z_ const wchar_t IID IClassFactory _Inout_ DWORD unsigned int
Definition: implements.h:273
virtual ~ModuleBase()
Definition: implements.h:225
STDMETHOD_(unsigned long, IncrementObjectCount)()=0
STDMETHOD_(SRWLOCK *, GetLock)() const
Definition: implements.h:261
ModuleBase & operator=(const ModuleBase &)=delete
STDMETHOD_(unsigned long, DecrementObjectCount)()=0
STDMETHOD_(const CreatorMap **, GetFirstEntryPointer)() const
Definition: implements.h:246
STDMETHOD_(unsigned long, GetObjectCount)() const
Definition: implements.h:241
ModuleBase()
Definition: implements.h:197
ModuleBase(const ModuleBase &)=delete
STDMETHOD_(const CreatorMap **, GetMidEntryPointer)() const
Definition: implements.h:251
_In_opt_z_ const wchar_t _In_z_ const wchar_t ** activatableClassIds
Definition: implements.h:267
static ModuleBase * module_
Definition: implements.h:195
Definition: implements.h:285
Definition: implements.h:311
HRESULT RuntimeClassInitialize()
Definition: implements.h:388
static HRESULT AsIID(T *implements, REFIID riid, void **ppvObject)
Definition: implements.h:314
static HRESULT GetImplementedIIDS(T *implements, ULONG *iidCount, _When_(*iidCount==0, _At_(*iids, _Post_null_)) _When_(*iidCount > 0, _At_(*iids, _Post_notnull_)) _Result_nullonfailure_ IID **iids)
Definition: implements.h:353
Definition: implements.h:306
STDMETHOD() GetWeakReference(_Outptr_ IWeakReference **weakReference)
Definition: implements.h:2662
typename Details::AdjustImplements< RuntimeClassFlagsT, false, typename IInspectableInjector< I0 >::InspectableIfNeeded, I0, IWeakReferenceSource, TInterfaces... >::Type ImplementsHelper
Definition: implements.h:2318
Definition: implements.h:2379
Definition: implements.h:2063
unsigned long IncrementStrongReference()
Definition: implements.h:2076
unsigned long GetStrongReferenceCount()
Definition: implements.h:2095
unsigned long DecrementStrongReference()
Definition: implements.h:2081
StrongReference(long refCount=1)
Definition: implements.h:2065
~StrongReference()
Definition: implements.h:2069
long strongRefCount_
Definition: implements.h:2105
void SetStrongReference(unsigned long value)
Definition: implements.h:2100
Definition: implements.h:2488
REFIID riid
Definition: implements.h:2504
virtual ~WeakReferenceImpl()
Definition: implements.h:2500
WeakReferenceImpl(IUnknown *unk)
Definition: implements.h:2490
return hr
Definition: implements.h:2532
REFIID _Outptr_result_maybenull_ _Result_nullonfailure_ IInspectable ** ppvObject
Definition: implements.h:2505
HRESULT hr
Definition: implements.h:2530
Definition: implements.h:1510
IStream REFIID riid
Definition: implements.h:1587
IStream REFIID _In_opt_ void * pv
Definition: implements.h:1588
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv)
Definition: implements.h:1520
REFIID riid
Definition: implements.h:1553
REFIID _In_opt_ void * pv
Definition: implements.h:1554
IStream REFIID _In_opt_ void DWORD _Reserved_ void * pvDestContext
Definition: implements.h:1590
FtmBase()
Definition: implements.h:1535
REFIID _In_opt_ void DWORD _Reserved_ void DWORD mshlflags
Definition: implements.h:1557
static HRESULT CreateGlobalInterfaceTable(IGlobalInterfaceTable **git)
Definition: implements.h:1630
virtual ~FtmBase()=default
STDMETHOD() ReleaseMarshalData(IStream *pStm) override
Definition: implements.h:1612
::Microsoft::WRL::ComPtr< IMarshal > marshaller_
Definition: implements.h:1641
STDMETHOD() UnmarshalInterface(IStream *pStm, REFIID riid, _Outptr_ void **ppv) override
Definition: implements.h:1603
STDMETHOD() DisconnectObject(DWORD dwReserved) override
Definition: implements.h:1621
IStream REFIID _In_opt_ void DWORD dwDestContext
Definition: implements.h:1589
REFIID _In_opt_ void DWORD _Reserved_ void * pvDestContext
Definition: implements.h:1556
IStream * pStm
Definition: implements.h:1586
REFIID _In_opt_ void DWORD dwDestContext
Definition: implements.h:1555
HRESULT CustomQueryInterface(REFIID, void **, bool *handled)
Definition: implements.h:2464
Definition: implements.h:2422
HRESULT CustomQueryInterface(REFIID, void **, bool *handled)
Definition: implements.h:2432
RuntimeClass RuntimeClassT
Definition: implements.h:2447
RuntimeClass()
Definition: implements.h:2439
#define WRT_NO_VTABLE
Definition: implements.h:59
#define __WRL_IMPLEMENTS_FTM_BASE__(flags)
Definition: internal.h:21
#define __WRL_ASSERT__(cond)
Definition: internal.h:13
ComPtr< T > Make(TArgs &&... args)
Definition: implements.h:2785
bool IsValueAPointerToWeakReference(INT_PTR value)
Definition: implements.h:2137
WeakReferenceImpl * CreateWeakReference(IUnknown *)
Definition: implements.h:2854
const UINT_PTR EncodeWeakReferencePointerFlag
Definition: implements.h:2123
const CreatorMap * __pobjectentryfirst
Definition: implements.h:168
INT_PTR EncodeWeakReferencePointer(Microsoft::WRL::Details::WeakReferenceImpl *value)
Definition: implements.h:2339
const CreatorMap * __pobjectentrylast
Definition: implements.h:179
struct WRT_NO_VTABLE MarkImplements
Definition: implements.h:840
T ReadValueFromPointerNoFence(const volatile T *value)
Definition: implements.h:2207
unsigned long SafeUnknownDecrementReference(long volatile &refcount)
Definition: implements.h:1782
HRESULT MakeAndInitialize(I **result, TArgs &&... args)
Definition: implements.h:2808
struct WRT_NO_VTABLE AdjustImplements
Definition: implements.h:871
class WRT_NO_VTABLE RuntimeClassImpl
Definition: implements.h:1753
Microsoft::WRL::Details::WeakReferenceImpl * DecodeWeakReferencePointer(INT_PTR value)
Definition: implements.h:2346
struct WRT_NO_VTABLE ImplementsHelper
Definition: implements.h:833
unsigned long SafeUnknownIncrementReference(long volatile &refcount)
Definition: implements.h:1763
const CreatorMap * __pobjectentrymid
Definition: implements.h:175
Details::ModuleBase * GetModuleBase()
Definition: implements.h:643
__declspec(selectany) const DelegateCheckMode DefaultDelegateCheckMode
RuntimeClassType
Definition: implements.h:78
@ InhibitWeakReference
Definition: implements.h:82
@ WinRt
Definition: implements.h:79
@ InhibitRoOriginateError
Definition: implements.h:85
@ InhibitFtmBase
Definition: implements.h:84
@ WinRtClassicComMix
Definition: implements.h:81
@ Delegate
Definition: implements.h:83
@ ClassicCom
Definition: implements.h:80
RuntimeClassFlags< WinRt|InhibitWeakReference > InhibitWeakReferencePolicy
Definition: implements.h:117
This file has no copyright assigned and is placed in the Public Domain.
Definition: client.h:26
Definition: implements.h:662
static const unsigned long IidCount
Definition: implements.h:712
static void Verify()
Definition: implements.h:665
static void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:719
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv)
Definition: implements.h:689
IUnknown * CastToUnknown()
Definition: implements.h:707
Definition: implements.h:73
virtual ~CloakedIid()=default
ImplementsHelper< RuntimeClassFlagsT, doStrictCheck, typename MarkImplements< I0, __is_base_of(ImplementsBase, I0)>::Type, Bases... > Type
Definition: implements.h:881
ImplementsHelper< RuntimeClassFlagsT, doStrictCheck > Type
Definition: implements.h:894
AdjustImplements< RuntimeClassFlagsT, doStrictCheck, Bases... >::Type Type
Definition: implements.h:888
Definition: implements.h:1256
static const bool value
Definition: implements.h:1257
Definition: implements.h:1897
IInspectable InspectableIfNeeded
Definition: implements.h:1927
Details::Nil InspectableIfNeeded
Definition: implements.h:1921
Definition: implements.h:98
void FillArrayWithIid(_Inout_ unsigned long *, _Inout_ IID *)
Definition: implements.h:1124
HRESULT CanCastTo(REFIID, _Outptr_ void **, bool *=nullptr)
Definition: implements.h:1112
HRESULT SetComposableBasePointers(IInspectable *base, _In_opt_ FactoryInterface *baseFactory=nullptr)
Definition: implements.h:1376
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated)
Definition: implements.h:1337
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1353
AdjustImplements< RuntimeClassFlagsT, true, TInterfaces... >::Type BaseType
Definition: implements.h:1216
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:1218
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:1292
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1316
ImplementsHelper< RuntimeClassFlagsT, true, ComposableBase< FactoryInterface > > BaseType
Definition: implements.h:1290
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:936
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:909
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:980
Selector< I0, ImplementsHelper< RuntimeClassFlagsT, doStrictCheck, ImplementsMarker< I0 >, TInterfaces... > > CurrentType
Definition: implements.h:970
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1003
Selector< typename AdjustImplements< RuntimeClassFlagsT, true, TInterfaces... >::Type, ImplementsHelper< RuntimeClassFlagsT, doStrictCheck, ImplementsMarker< I0 >, TInterfaces... > > BaseType
Definition: implements.h:974
void FillArrayWithIid(_Inout_ unsigned long *, _Inout_ IID *)
Definition: implements.h:1092
AdjustImplements< RuntimeClassFlagsT, doStrictCheck, I0 >::Type CurrentType
Definition: implements.h:1072
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:1074
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated=nullptr)
Definition: implements.h:1033
AdjustImplements< RuntimeClassFlagsT, doStrictCheck, I0 >::Type CurrentType
Definition: implements.h:1030
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1056
AdjustImplements< RuntimeClassFlagsT, true, I1, TInterfaces... >::Type BaseType
Definition: implements.h:1031
Definition: implements.h:837
InterfaceListHelper< TInterfaces... > TypeT
Definition: implements.h:2370
static void FillArrayWithIid(_Inout_ unsigned long *, _Inout_ IID *)
Definition: implements.h:591
static Base * CastToBase(T *ptr)
Definition: implements.h:565
static IUnknown * CastToUnknown(T *ptr)
Definition: implements.h:571
static void FillArrayWithIid(_Inout_ unsigned long *, _Inout_ IID *)
Definition: implements.h:606
_Success_(return==true) static bool CanCastTo(T *
static void Verify()
Definition: implements.h:603
Nil Base
Definition: implements.h:599
Definition: implements.h:508
I0 Base
Definition: implements.h:509
static void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:544
static IUnknown * CastToUnknown(T *ptr)
Definition: implements.h:525
static void Verify()
Definition: implements.h:513
_Success_(return==true) static bool CanCastTo(T *ptr
static Base * CastToBase(T *ptr)
Definition: implements.h:519
Definition: internal.h:125
Definition: internal.h:66
CloakedIid< I0 > Type
Definition: implements.h:859
ImplementsMarker< I0 > Type
Definition: implements.h:851
MixIn< DerivedType, BaseType, hasImplements > Type
Definition: implements.h:866
Definition: implements.h:948
static void Verify()
Definition: implements.h:633
static void Verify()
Definition: implements.h:620
static void OriginateError(HRESULT hr, HSTRING message)
Definition: implements.h:136
Definition: implements.h:121
static void OriginateError(HRESULT hr, HSTRING message)
Definition: implements.h:122
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv)
Definition: implements.h:1481
RuntimeClassFlags< flags > ClassFlags
Definition: implements.h:1470
Details::AdjustImplements< RuntimeClassFlags< flags >, true, I0, TInterfaces... >::Type BaseType
Definition: implements.h:1475
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1496
Definition: implements.h:1426
HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv)
Definition: implements.h:1443
I0 FirstInterface
Definition: implements.h:1429
Details::AdjustImplements< RuntimeClassFlags< WinRt >, true, I0, TInterfaces... >::Type BaseType
Definition: implements.h:1437
RuntimeClassFlags< WinRt > ClassFlags
Definition: implements.h:1428
unsigned long GetIidCount()
Definition: implements.h:1453
virtual ~Implements()=default
void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID *iids)
Definition: implements.h:1458
IUnknown * CastToUnknown()
Definition: implements.h:1448
Definition: implements.h:109
Definition: implements.h:90
static const unsigned int value
Definition: implements.h:91
void * ifHighBitIsSetThenShiftLeftToYieldPointerToWeakReference
Definition: implements.h:2132
interface IWeakReferenceSource IWeakReferenceSource
Definition: weakreference.h:49
interface IWeakReference IWeakReference
Definition: weakreference.h:43