@@ -18,6 +18,10 @@ namespace winrt::impl
1818
1919 using library_handle = handle_type<library_traits>;
2020
21+ // This function pointer will be null unless one or more translation units in a binary define WINRT_REG_FREE before
22+ // including winrt/base.h. If that is defined then the overall binary will support regfree COM activation.
23+ inline hresult (*reg_free_factory_getter)(param::hstring const &, bool , guid const &, void **) = nullptr;
24+
2125 template <bool isSameInterfaceAsIActivationFactory>
2226 WINRT_IMPL_NOINLINE hresult get_runtime_activation_factory_impl (param::hstring const & name, winrt::guid const & guid, void ** result) noexcept
2327 {
@@ -30,15 +34,8 @@ namespace winrt::impl
3034
3135 if (hr == impl::error_not_initialized)
3236 {
33- auto usage = reinterpret_cast <int32_t (__stdcall*)(void ** cookie) noexcept >(WINRT_IMPL_GetProcAddress (load_library (L" combase.dll" ), " CoIncrementMTAUsage" ));
34-
35- if (!usage)
36- {
37- return hr;
38- }
39-
4037 void * cookie;
41- usage (&cookie);
38+ WINRT_IMPL_CoIncrementMTAUsage (&cookie);
4239 hr = WINRT_IMPL_RoGetActivationFactory (*(void **)(&name), guid, result);
4340 }
4441
@@ -47,6 +44,17 @@ namespace winrt::impl
4744 return 0 ;
4845 }
4946
47+ if (reg_free_factory_getter)
48+ {
49+ return reg_free_factory_getter (name, isSameInterfaceAsIActivationFactory, guid, result);
50+ }
51+
52+ return hr;
53+ }
54+
55+ #ifdef WINRT_REG_FREE
56+ WINRT_IMPL_NOINLINE hresult reg_free_get_activation_factory (param::hstring const & name, bool isSameInterfaceAsIActivationFactory, winrt::guid const & guid, void ** result) noexcept
57+ {
5058 com_ptr<IErrorInfo> error_info;
5159 WINRT_IMPL_GetErrorInfo (0 , error_info.put_void ());
5260
@@ -79,7 +87,7 @@ namespace winrt::impl
7987 continue ;
8088 }
8189
82- if constexpr (isSameInterfaceAsIActivationFactory)
90+ if (isSameInterfaceAsIActivationFactory)
8391 {
8492 *result = library_factory.detach ();
8593 library.detach ();
@@ -93,9 +101,18 @@ namespace winrt::impl
93101 }
94102
95103 WINRT_IMPL_SetErrorInfo (0 , error_info.get ());
96- return hr ;
104+ return error_class_not_registered ;
97105 }
98106
107+ // This file has been compiled by a translation unit with WINRT_REG_FREE defined. Fill in the reg_free_factory_getter function
108+ // pointer so that regfree behavior is activated.
109+ inline unsigned int reg_free_init = []() {
110+ reg_free_factory_getter = reg_free_get_activation_factory;
111+ return 0U ;
112+ }();
113+
114+ #endif // WINRT_REG_FREE
115+
99116 template <typename Interface>
100117 hresult get_runtime_activation_factory (param::hstring const & name, void ** result) noexcept
101118 {
0 commit comments