Skip to content

Commit 80de096

Browse files
authored
Provide winrt_activation_handler to hook/mock activation (#477)
1 parent 1e3907d commit 80de096

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

strings/base_activation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ namespace winrt::impl
2121
template <typename Interface>
2222
hresult get_runtime_activation_factory(param::hstring const& name, void** result) noexcept
2323
{
24+
if (winrt_activation_handler)
25+
{
26+
return winrt_activation_handler(*(void**)(&name), guid_of<Interface>(), result);
27+
}
28+
2429
static int32_t(__stdcall * handler)(void* classId, guid const& iid, void** factory) noexcept;
2530

2631
impl::load_runtime_function("RoGetActivationFactory", handler,

strings/base_extern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
__declspec(selectany) int32_t(__stdcall* winrt_to_hresult_handler)(void* address) noexcept {};
33
__declspec(selectany) void(__stdcall* winrt_suspend_handler)(void const* token) noexcept {};
44
__declspec(selectany) void(__stdcall* winrt_resume_handler)(void const* token) noexcept {};
5+
__declspec(selectany) int32_t(__stdcall* winrt_activation_handler)(void* classId, winrt::guid const& iid, void** factory) noexcept {};
56

67
extern "C"
78
{

test/test/custom_activation.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "winrt/Windows.Foundation.Numerics.h"
2+
#include "catch.hpp"
3+
4+
using namespace winrt;
5+
using namespace Windows::Foundation;
6+
7+
namespace
8+
{
9+
struct custom_factory : implements<custom_factory, IUriRuntimeClassFactory>
10+
{
11+
inline static Uri mock_uri{ nullptr };
12+
13+
Uri CreateUri(hstring const& value) const
14+
{
15+
REQUIRE(value == L"http://ignored.com");
16+
return mock_uri;
17+
}
18+
19+
Uri CreateWithRelativeUri(hstring const&, hstring const&) const
20+
{
21+
throw hresult_not_implemented();
22+
}
23+
};
24+
25+
int32_t __stdcall handler(void* classId, winrt::guid const& iid, void** factory) noexcept
26+
{
27+
bool expected = reinterpret_cast<hstring const&>(classId) == L"Windows.Foundation.Uri";
28+
REQUIRE(expected);
29+
REQUIRE(iid == guid_of<IUriRuntimeClassFactory>());
30+
31+
*factory = detach_abi(make<custom_factory>());
32+
return 0;
33+
}
34+
}
35+
36+
TEST_CASE("custom_activation")
37+
{
38+
custom_factory::mock_uri = Uri(L"http://actual.com");
39+
clear_factory_cache();
40+
41+
// Set up global handler
42+
REQUIRE(!winrt_activation_handler);
43+
winrt_activation_handler = handler;
44+
45+
// Windows.Foundation.Uri activation factory now returns mock object
46+
auto uri = Uri(L"http://ignored.com");
47+
REQUIRE(uri.Domain() == L"actual.com");
48+
49+
// Remove global handler
50+
winrt_activation_handler = nullptr;
51+
clear_factory_cache();
52+
}

test/test/test.vcxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,16 @@
315315
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
316316
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
317317
</ClCompile>
318+
<ClCompile Include="custom_activation.cpp">
319+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
320+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
321+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
322+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
323+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
324+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
325+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
326+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
327+
</ClCompile>
318328
<ClCompile Include="custom_error.cpp" />
319329
<ClCompile Include="delegate.cpp" />
320330
<ClCompile Include="delegates.cpp" />

0 commit comments

Comments
 (0)