Skip to content

Commit a346936

Browse files
committed
cppwinrt should not call LoadLibrary anywhere unless new WINRT_REG_FREE define is defined, re-activating regfree behavior
1 parent e53db0f commit a346936

File tree

7 files changed

+37
-11
lines changed

7 files changed

+37
-11
lines changed

strings/base_activation.h

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
{

strings/base_agile_ref.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@ namespace winrt::impl
7171

7272
using update_module_lock = module_lock_updater<true>;
7373

74+
#ifdef WINRT_REG_FREE
7475
inline void* load_library(wchar_t const* library) noexcept
7576
{
7677
return WINRT_IMPL_LoadLibraryExW(library, nullptr, 0x00001000 /* LOAD_LIBRARY_SEARCH_DEFAULT_DIRS */);
7778
}
79+
#endif // WINRT_REG_FREE
7880

7981
inline hresult get_agile_reference(winrt::guid const& iid, void* object, void** reference) noexcept
8082
{

strings/base_extern.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ extern "C"
3535
int32_t __stdcall WINRT_IMPL_GetRestrictedErrorInfo(void**) noexcept WINRT_IMPL_LINK(GetRestrictedErrorInfo, 4);
3636
int32_t __stdcall WINRT_IMPL_SetRestrictedErrorInfo(void*) noexcept WINRT_IMPL_LINK(SetRestrictedErrorInfo, 4);
3737

38+
#ifdef WINRT_REG_FREE
3839
void* __stdcall WINRT_IMPL_LoadLibraryExW(wchar_t const* name, void* unused, uint32_t flags) noexcept WINRT_IMPL_LINK(LoadLibraryExW, 12);
40+
#endif // WINRT_REG_FREE
3941
int32_t __stdcall WINRT_IMPL_FreeLibrary(void* library) noexcept WINRT_IMPL_LINK(FreeLibrary, 4);
4042
void* __stdcall WINRT_IMPL_GetProcAddress(void* library, char const* name) noexcept WINRT_IMPL_LINK(GetProcAddress, 8);
4143

4244
int32_t __stdcall WINRT_IMPL_SetErrorInfo(uint32_t reserved, void* info) noexcept WINRT_IMPL_LINK(SetErrorInfo, 8);
4345
int32_t __stdcall WINRT_IMPL_GetErrorInfo(uint32_t reserved, void** info) noexcept WINRT_IMPL_LINK(GetErrorInfo, 8);
4446
int32_t __stdcall WINRT_IMPL_CoInitializeEx(void*, uint32_t type) noexcept WINRT_IMPL_LINK(CoInitializeEx, 8);
4547
void __stdcall WINRT_IMPL_CoUninitialize() noexcept WINRT_IMPL_LINK(CoUninitialize, 0);
48+
int32_t __stdcall WINRT_IMPL_CoIncrementMTAUsage(void** cookie) noexcept WINRT_IMPL_LINK(CoIncrementMTAUsage, 4);
4649

4750
int32_t __stdcall WINRT_IMPL_CoCreateFreeThreadedMarshaler(void* outer, void** marshaler) noexcept WINRT_IMPL_LINK(CoCreateFreeThreadedMarshaler, 8);
4851
int32_t __stdcall WINRT_IMPL_CoCreateInstance(winrt::guid const& clsid, void* outer, uint32_t context, winrt::guid const& iid, void** object) noexcept WINRT_IMPL_LINK(CoCreateInstance, 20);

test/old_tests/UnitTests/pch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

3-
#define WIN32_LEAN_AND_MEAN
3+
#define WIN32_LEAN_AND_MEAN
4+
#define WINRT_REG_FREE
45
#define WINRT_NATVIS
56
#define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
67

test/test/pch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "mingw_com_support.h"
66

77
#define WINRT_LEAN_AND_MEAN
8+
#define WINRT_REG_FREE
89
#include <unknwn.h>
910
#include "winrt/Windows.Foundation.Collections.h"
1011
#include "winrt/Windows.Foundation.Numerics.h"

test/test_fast/pch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#define WINRT_REG_FREE
34
#include "catch.hpp"
45
#include "winrt/Windows.Foundation.Collections.h"
56

test/test_slow/pch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#define WINRT_REG_FREE
34
#include "catch.hpp"
45
#include "winrt/Windows.Foundation.Collections.h"
56

0 commit comments

Comments
 (0)