Skip to content

Commit 2306d08

Browse files
authored
WinRT activation shim for Microsoft.Management.Deployment (#4709)
## Change Modeled after the similar project for `Microsoft.Management.Configuration`, this new project enables WinRT standard activation via `DllGetActivationFactory` and `IActivationFactory`. The major change required was to add support for multiple classes.
1 parent b74d599 commit 2306d08

File tree

11 files changed

+857
-210
lines changed

11 files changed

+857
-210
lines changed

src/AppInstallerCLI.sln

Lines changed: 30 additions & 210 deletions
Large diffs are not rendered by default.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
#include "pch.h"
4+
#include "Factory.h"
5+
#include <winrt/Microsoft.Management.Deployment.h>
6+
#include <winget/Runtime.h>
7+
#include <WinGetServerManualActivation_Client.h>
8+
9+
using namespace std::string_view_literals;
10+
11+
namespace Microsoft::Management::Deployment::OutOfProc
12+
{
13+
namespace
14+
{
15+
#if USE_PROD_CLSIDS
16+
constexpr CLSID CLSID_PackageManager = { 0xC53A4F16, 0x787E, 0x42A4, { 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 } }; //C53A4F16-787E-42A4-B304-29EFFB4BF597
17+
constexpr CLSID CLSID_InstallOptions = { 0x1095f097, 0xEB96, 0x453B, { 0xB4, 0xE6, 0x16, 0x13, 0x63, 0x7F, 0x3B, 0x14 } }; //1095F097-EB96-453B-B4E6-1613637F3B14
18+
constexpr CLSID CLSID_UninstallOptions = { 0xE1D9A11E, 0x9F85, 0x4D87, { 0x9C, 0x17, 0x2B, 0x93, 0x14, 0x3A, 0xDB, 0x8D } }; //E1D9A11E-9F85-4D87-9C17-2B93143ADB8D
19+
constexpr CLSID CLSID_FindPackagesOptions = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A
20+
constexpr CLSID CLSID_PackageMatchFilter = { 0xD02C9DAF, 0x99DC, 0x429C, { 0xB5, 0x03, 0x4E, 0x50, 0x4E, 0x4A, 0xB0, 0x00 } }; //D02C9DAF-99DC-429C-B503-4E504E4AB000
21+
constexpr CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x526534B8, 0x7E46, 0x47C8, { 0x84, 0x16, 0xB1, 0x68, 0x5C, 0x32, 0x7D, 0x37 } }; //526534B8-7E46-47C8-8416-B1685C327D37
22+
constexpr CLSID CLSID_DownloadOptions = { 0x4CBABE76, 0x7322, 0x4BE4, { 0x9C, 0xEA, 0x25, 0x89, 0xA8, 0x06, 0x82, 0xDC } }; //4CBABE76-7322-4BE4-9CEA-2589A80682DC
23+
constexpr CLSID CLSID_AuthenticationArguments = { 0xBA580786, 0xBDE3, 0x4F6C, { 0xB8, 0xF3, 0x44, 0x69, 0x8A, 0xC8, 0x71, 0x1A } }; //BA580786-BDE3-4F6C-B8F3-44698AC8711A
24+
#else
25+
constexpr CLSID CLSID_PackageManager = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C
26+
constexpr CLSID CLSID_InstallOptions = { 0x44FE0580, 0x62F7, 0x44D4, { 0x9E, 0x91, 0xAA, 0x96, 0x14, 0xAB, 0x3E, 0x86 } }; //44FE0580-62F7-44D4-9E91-AA9614AB3E86
27+
constexpr CLSID CLSID_UninstallOptions = { 0xAA2A5C04, 0x1AD9, 0x46C4, { 0xB7, 0x4F, 0x6B, 0x33, 0x4A, 0xD7, 0xEB, 0x8C } }; //AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C
28+
constexpr CLSID CLSID_FindPackagesOptions = { 0x1BD8FF3A, 0xEC50, 0x4F69, { 0xAE, 0xEE, 0xDF, 0x4C, 0x9D, 0x3B, 0xAA, 0x96 } }; //1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96
29+
constexpr CLSID CLSID_PackageMatchFilter = { 0x3F85B9F4, 0x487A, 0x4C48, { 0x90, 0x35, 0x29, 0x03, 0xF8, 0xA6, 0xD9, 0xE8 } }; //3F85B9F4-487A-4C48-9035-2903F8A6D9E8
30+
constexpr CLSID CLSID_CreateCompositePackageCatalogOptions = { 0xEE160901, 0xB317, 0x4EA7, { 0x9C, 0xC6, 0x53, 0x55, 0xC6, 0xD7, 0xD8, 0xA7 } }; //EE160901-B317-4EA7-9CC6-5355C6D7D8A7
31+
constexpr CLSID CLSID_DownloadOptions = { 0x8EF324ED, 0x367C, 0x4880, { 0x83, 0xE5, 0xBB, 0x2A, 0xBD, 0x0B, 0x72, 0xF6 } }; //8EF324ED-367C-4880-83E5-BB2ABD0B72F6
32+
constexpr CLSID CLSID_AuthenticationArguments = { 0x6484A61D, 0x50FA, 0x41F0, { 0xB7, 0x1E, 0xF4, 0x37, 0x0C, 0x6E, 0xB3, 0x7C } }; //6484A61D-50FA-41F0-B71E-F4370C6EB37C
33+
#endif
34+
35+
struct NameCLSIDPair
36+
{
37+
std::wstring_view Name;
38+
GUID CLSID;
39+
};
40+
41+
constexpr std::array<NameCLSIDPair, 8> s_nameCLSIDPairs
42+
{
43+
NameCLSIDPair{ L"Microsoft.Management.Deployment.PackageManager"sv, CLSID_PackageManager },
44+
NameCLSIDPair{ L"Microsoft.Management.Deployment.InstallOptions"sv, CLSID_InstallOptions },
45+
NameCLSIDPair{ L"Microsoft.Management.Deployment.UninstallOptions"sv, CLSID_UninstallOptions },
46+
NameCLSIDPair{ L"Microsoft.Management.Deployment.FindPackagesOptions"sv, CLSID_FindPackagesOptions },
47+
NameCLSIDPair{ L"Microsoft.Management.Deployment.PackageMatchFilter"sv, CLSID_PackageMatchFilter },
48+
NameCLSIDPair{ L"Microsoft.Management.Deployment.CreateCompositePackageCatalogOptions"sv, CLSID_CreateCompositePackageCatalogOptions },
49+
NameCLSIDPair{ L"Microsoft.Management.Deployment.DownloadOptions"sv, CLSID_DownloadOptions },
50+
NameCLSIDPair{ L"Microsoft.Management.Deployment.AuthenticationArguments"sv, CLSID_AuthenticationArguments },
51+
};
52+
53+
bool IsCLSIDPresent(const GUID& clsid)
54+
{
55+
for (const auto& pair : s_nameCLSIDPairs)
56+
{
57+
if (pair.CLSID == clsid)
58+
{
59+
return true;
60+
}
61+
}
62+
63+
return false;
64+
}
65+
66+
const GUID* GetCLSIDFor(HSTRING clsid)
67+
{
68+
UINT32 length = 0;
69+
PCWSTR buffer = WindowsGetStringRawBuffer(clsid, &length);
70+
std::wstring_view clsidView{ buffer, length };
71+
72+
for (const auto& pair : s_nameCLSIDPairs)
73+
{
74+
if (pair.Name == clsidView)
75+
{
76+
return &pair.CLSID;
77+
}
78+
}
79+
80+
return nullptr;
81+
}
82+
83+
winrt::Windows::Foundation::IInspectable CreateOOPObject(const GUID& clsid)
84+
{
85+
bool isAdmin = AppInstaller::Runtime::IsRunningAsAdmin();
86+
87+
try
88+
{
89+
return winrt::create_instance<winrt::Windows::Foundation::IInspectable>(clsid, CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD);
90+
}
91+
catch (const winrt::hresult_error& hre)
92+
{
93+
// We only want to fall through to trying the manual activation if we are running as admin and couldn't find the registration.
94+
if (!(isAdmin && hre.code() == REGDB_E_CLASSNOTREG))
95+
{
96+
throw;
97+
}
98+
}
99+
100+
winrt::com_ptr<::IUnknown> result;
101+
THROW_IF_FAILED(WinGetServerManualActivation_CreateInstance(clsid, winrt::guid_of<winrt::Windows::Foundation::IInspectable>(), 0, result.put_void()));
102+
return result.as<winrt::Windows::Foundation::IInspectable>();
103+
}
104+
}
105+
106+
Factory::Factory(const GUID& clsid) : m_clsid(clsid)
107+
{
108+
IncrementRefCount();
109+
}
110+
111+
Factory::Factory(HSTRING clsid) : m_clsid(*GetCLSIDFor(clsid))
112+
{
113+
IncrementRefCount();
114+
}
115+
116+
Factory::~Factory()
117+
{
118+
DecrementRefCount();
119+
}
120+
121+
bool Factory::HasReferences()
122+
{
123+
return s_referenceCount.load() != 0;
124+
}
125+
126+
void Factory::Terminate()
127+
{
128+
WinGetServerManualActivation_Terminate();
129+
}
130+
131+
bool Factory::IsCLSID(const GUID& clsid)
132+
{
133+
return IsCLSIDPresent(clsid);
134+
}
135+
136+
bool Factory::IsCLSID(HSTRING clsid)
137+
{
138+
return GetCLSIDFor(clsid) != nullptr;
139+
}
140+
141+
winrt::Windows::Foundation::IInspectable Factory::ActivateInstance()
142+
{
143+
return CreateOOPObject(m_clsid);
144+
}
145+
146+
HRESULT STDMETHODCALLTYPE Factory::CreateInstance(::IUnknown* pUnkOuter, REFIID riid, void** ppvObject) try
147+
{
148+
RETURN_HR_IF(E_POINTER, !ppvObject);
149+
*ppvObject = nullptr;
150+
RETURN_HR_IF(CLASS_E_NOAGGREGATION, pUnkOuter != nullptr);
151+
152+
return CreateOOPObject(m_clsid).as(riid, ppvObject);
153+
}
154+
CATCH_RETURN();
155+
156+
HRESULT STDMETHODCALLTYPE Factory::LockServer(BOOL fLock)
157+
{
158+
if (fLock)
159+
{
160+
IncrementRefCount();
161+
}
162+
else
163+
{
164+
DecrementRefCount();
165+
}
166+
167+
return S_OK;
168+
}
169+
170+
void Factory::IncrementRefCount()
171+
{
172+
++s_referenceCount;
173+
}
174+
175+
void Factory::DecrementRefCount()
176+
{
177+
--s_referenceCount;
178+
}
179+
180+
std::atomic<int32_t> Factory::s_referenceCount = ATOMIC_VAR_INIT(0);
181+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
#pragma once
4+
#include <hstring.h>
5+
#include <inspectable.h>
6+
#include <winrt/Windows.Foundation.h>
7+
#include <atomic>
8+
9+
namespace Microsoft::Management::Deployment::OutOfProc
10+
{
11+
struct Factory : winrt::implements<Factory, IClassFactory, winrt::Windows::Foundation::IActivationFactory>
12+
{
13+
Factory(const GUID& clsid);
14+
Factory(HSTRING clsid);
15+
~Factory();
16+
17+
// Returns true if the reference count is not 0; false if it is.
18+
static bool HasReferences();
19+
20+
// Forcibly destroys any static objects.
21+
static void Terminate();
22+
23+
// Determines if the given CLSID is the CLSID for the factory.
24+
static bool IsCLSID(const GUID& clsid);
25+
26+
// Determines if the given CLSID is the CLSID for the factory.
27+
static bool IsCLSID(HSTRING clsid);
28+
29+
// IActivationFactory
30+
winrt::Windows::Foundation::IInspectable ActivateInstance();
31+
32+
// IClassFactory
33+
HRESULT STDMETHODCALLTYPE CreateInstance(::IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
34+
HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock);
35+
36+
private:
37+
static void IncrementRefCount();
38+
static void DecrementRefCount();
39+
40+
static std::atomic<int32_t> s_referenceCount;
41+
42+
GUID m_clsid;
43+
};
44+
}

0 commit comments

Comments
 (0)