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