11
2- WINRT_EXPORT namespace winrt
2+ namespace winrt ::impl
33{
4- template <typename Interface = Windows::Foundation::IActivationFactory>
5- impl::com_ref<Interface> get_activation_factory (param::hstring const & name)
4+ struct library_traits
65 {
7- void * result{};
8- hresult hr = WINRT_RoGetActivationFactory (*(void **)(&name), guid_of<Interface>(), &result);
6+ using type = void *;
7+
8+ static void close (type value) noexcept
9+ {
10+ WINRT_FreeLibrary (value);
11+ }
12+
13+ static constexpr type invalid () noexcept
14+ {
15+ return nullptr ;
16+ }
17+ };
18+
19+ using library_handle = handle_type<library_traits>;
20+
21+ template <typename Interface>
22+ hresult get_runtime_activation_factory (param::hstring const & name, void ** result) noexcept
23+ {
24+ static int32_t (__stdcall * handler)(void * classId, guid const & iid, void ** factory) noexcept ;
25+
26+ impl::load_runtime_function (" RoGetActivationFactory" , handler,
27+ [](void *, guid const &, void ** factory) noexcept -> int32_t
28+ {
29+ *factory = nullptr ;
30+ return error_class_not_available;
31+ });
32+
33+ hresult hr = handler (*(void **)(&name), guid_of<Interface>(), result);
934
1035 if (hr == impl::error_not_initialized)
1136 {
1237 void * cookie;
1338 WINRT_CoIncrementMTAUsage (&cookie);
14- hr = WINRT_RoGetActivationFactory (*(void **)(&name), guid_of<Interface>(), &result);
39+ hr = handler (*(void **)(&name), guid_of<Interface>(), result);
40+ }
41+
42+ if (hr == 0 )
43+ {
44+ return 0 ;
45+ }
46+
47+ std::wstring path{ static_cast <hstring const &>(name) };
48+ std::size_t count{};
49+
50+ while (-1 != (count = path.rfind (' .' )))
51+ {
52+ path.resize (count);
53+ path += L" .dll" ;
54+ library_handle library (WINRT_LoadLibraryW (path.c_str ()));
55+ path.resize (path.size () - 4 );
56+
57+ if (!library)
58+ {
59+ continue ;
60+ }
61+
62+ auto library_call = reinterpret_cast <int32_t (__stdcall*)(void * classId, void ** factory)>(WINRT_GetProcAddress (library.get (), " DllGetActivationFactory" ));
63+
64+ if (!library_call)
65+ {
66+ continue ;
67+ }
68+
69+ com_ptr<abi_t <Windows::Foundation::IActivationFactory>> library_factory;
70+
71+ if (0 != library_call (*(void **)(&name), library_factory.put_void ()))
72+ {
73+ continue ;
74+ }
75+
76+ if constexpr (std::is_same_v< Interface, Windows::Foundation::IActivationFactory>)
77+ {
78+ *result = library_factory.detach ();
79+ library.detach ();
80+ return 0 ;
81+ }
82+ else if (0 == library_factory.as (guid_of<Interface>(), result))
83+ {
84+ library.detach ();
85+ return 0 ;
86+ }
1587 }
1688
17- check_hresult (hr);
89+ return error_class_not_available;
90+ }
91+ }
92+
93+ WINRT_EXPORT namespace winrt
94+ {
95+ template <typename Interface = Windows::Foundation::IActivationFactory>
96+ impl::com_ref<Interface> get_activation_factory (param::hstring const & name)
97+ {
98+ void * result{};
99+ check_hresult (impl::get_runtime_activation_factory<Interface>(name, &result));
18100 return { result, take_ownership_from_abi };
19101 }
20102}
@@ -304,11 +386,11 @@ namespace winrt::impl
304386 }
305387
306388 template <typename Class, typename Interface = Windows::Foundation::IActivationFactory>
307- impl:: com_ref<Interface> try_get_activation_factory (hresult_error* exception = nullptr ) noexcept
389+ com_ref<Interface> try_get_activation_factory (hresult_error* exception = nullptr ) noexcept
308390 {
309391 param::hstring const name{ name_of<Class>() };
310392 void * result{};
311- hresult const hr = WINRT_RoGetActivationFactory ( get_abi (name), guid_of <Interface>() , &result);
393+ hresult const hr = get_runtime_activation_factory <Interface>(name , &result);
312394
313395 if (hr < 0 )
314396 {
@@ -342,13 +424,13 @@ WINRT_EXPORT namespace winrt
342424{
343425 enum class apartment_type : int32_t
344426 {
345- single_threaded ,
346- multi_threaded
427+ multi_threaded = 0 ,
428+ single_threaded = 2 ,
347429 };
348430
349431 inline void init_apartment (apartment_type const type = apartment_type::multi_threaded)
350432 {
351- hresult const result = WINRT_RoInitialize ( static_cast <uint32_t >(type));
433+ hresult const result = WINRT_CoInitializeEx ( nullptr , static_cast <uint32_t >(type));
352434
353435 if (result < 0 )
354436 {
@@ -358,7 +440,7 @@ WINRT_EXPORT namespace winrt
358440
359441 inline void uninit_apartment () noexcept
360442 {
361- WINRT_RoUninitialize ();
443+ WINRT_CoUninitialize ();
362444 }
363445
364446 template <typename Class, typename Interface = Windows::Foundation::IActivationFactory>
0 commit comments