aboutsummaryrefslogtreecommitdiff
path: root/src/dnchost
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-04-29 19:28:50 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-04-29 19:53:29 +1000
commit39e930d9aaff250e0fd5019eeedaa40717a6c6fe (patch)
treebc0865bc6c9ced1b4a06b408ff60cb83ef73cad3 /src/dnchost
parentf4b14ff16f78435285bb20f16d5d62b902e6ba17 (diff)
downloadwix-39e930d9aaff250e0fd5019eeedaa40717a6c6fe.tar.gz
wix-39e930d9aaff250e0fd5019eeedaa40717a6c6fe.tar.bz2
wix-39e930d9aaff250e0fd5019eeedaa40717a6c6fe.zip
Add DotNetCoreBootstrapperApplicationHost for an SCD-style .NET Core BA.
Diffstat (limited to 'src/dnchost')
-rw-r--r--src/dnchost/coreclrhost.h137
-rw-r--r--src/dnchost/dnchost.cpp229
-rw-r--r--src/dnchost/dnchost.def6
-rw-r--r--src/dnchost/dnchost.h19
-rw-r--r--src/dnchost/dnchost.vcxproj77
-rw-r--r--src/dnchost/dncutil.cpp359
-rw-r--r--src/dnchost/dncutil.h36
-rw-r--r--src/dnchost/hostfxr.h96
-rw-r--r--src/dnchost/packages.config8
-rw-r--r--src/dnchost/precomp.cpp3
-rw-r--r--src/dnchost/precomp.h29
11 files changed, 999 insertions, 0 deletions
diff --git a/src/dnchost/coreclrhost.h b/src/dnchost/coreclrhost.h
new file mode 100644
index 00000000..07f28735
--- /dev/null
+++ b/src/dnchost/coreclrhost.h
@@ -0,0 +1,137 @@
1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5
6
7// ***** ABOUT THIS HEADER *****
8// **************************************************************************************
9//
10// This is the version on 2019-12-22 from
11// https://github.com/dotnet/runtime/blob/master/src/coreclr/src/coreclr/hosts/inc/coreclrhost.h
12//
13// **************************************************************************************
14// ****************************
15
16
17//
18// APIs for hosting CoreCLR
19//
20
21#ifndef __CORECLR_HOST_H__
22#define __CORECLR_HOST_H__
23
24#if defined(_WIN32) && defined(_M_IX86)
25#define CORECLR_CALLING_CONVENTION __stdcall
26#else
27#define CORECLR_CALLING_CONVENTION
28#endif
29
30// For each hosting API, we define a function prototype and a function pointer
31// The prototype is useful for implicit linking against the dynamic coreclr
32// library and the pointer for explicit dynamic loading (dlopen, LoadLibrary)
33#define CORECLR_HOSTING_API(function, ...) \
34 extern "C" int CORECLR_CALLING_CONVENTION function(__VA_ARGS__); \
35 typedef int (CORECLR_CALLING_CONVENTION *function##_ptr)(__VA_ARGS__)
36
37//
38// Initialize the CoreCLR. Creates and starts CoreCLR host and creates an app domain
39//
40// Parameters:
41// exePath - Absolute path of the executable that invoked the ExecuteAssembly (the native host application)
42// appDomainFriendlyName - Friendly name of the app domain that will be created to execute the assembly
43// propertyCount - Number of properties (elements of the following two arguments)
44// propertyKeys - Keys of properties of the app domain
45// propertyValues - Values of properties of the app domain
46// hostHandle - Output parameter, handle of the created host
47// domainId - Output parameter, id of the created app domain
48//
49// Returns:
50// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
51//
52CORECLR_HOSTING_API(coreclr_initialize,
53 const char* exePath,
54 const char* appDomainFriendlyName,
55 int propertyCount,
56 const char** propertyKeys,
57 const char** propertyValues,
58 void** hostHandle,
59 unsigned int* domainId);
60
61//
62// Shutdown CoreCLR. It unloads the app domain and stops the CoreCLR host.
63//
64// Parameters:
65// hostHandle - Handle of the host
66// domainId - Id of the domain
67//
68// Returns:
69// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
70//
71CORECLR_HOSTING_API(coreclr_shutdown,
72 void* hostHandle,
73 unsigned int domainId);
74
75//
76// Shutdown CoreCLR. It unloads the app domain and stops the CoreCLR host.
77//
78// Parameters:
79// hostHandle - Handle of the host
80// domainId - Id of the domain
81// latchedExitCode - Latched exit code after domain unloaded
82//
83// Returns:
84// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
85//
86CORECLR_HOSTING_API(coreclr_shutdown_2,
87 void* hostHandle,
88 unsigned int domainId,
89 int* latchedExitCode);
90
91//
92// Create a native callable function pointer for a managed method.
93//
94// Parameters:
95// hostHandle - Handle of the host
96// domainId - Id of the domain
97// entryPointAssemblyName - Name of the assembly which holds the custom entry point
98// entryPointTypeName - Name of the type which holds the custom entry point
99// entryPointMethodName - Name of the method which is the custom entry point
100// delegate - Output parameter, the function stores a native callable function pointer to the delegate at the specified address
101//
102// Returns:
103// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
104//
105CORECLR_HOSTING_API(coreclr_create_delegate,
106 void* hostHandle,
107 unsigned int domainId,
108 const char* entryPointAssemblyName,
109 const char* entryPointTypeName,
110 const char* entryPointMethodName,
111 void** delegate);
112
113//
114// Execute a managed assembly with given arguments
115//
116// Parameters:
117// hostHandle - Handle of the host
118// domainId - Id of the domain
119// argc - Number of arguments passed to the executed assembly
120// argv - Array of arguments passed to the executed assembly
121// managedAssemblyPath - Path of the managed assembly to execute (or NULL if using a custom entrypoint).
122// exitCode - Exit code returned by the executed assembly
123//
124// Returns:
125// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
126//
127CORECLR_HOSTING_API(coreclr_execute_assembly,
128 void* hostHandle,
129 unsigned int domainId,
130 int argc,
131 const char** argv,
132 const char* managedAssemblyPath,
133 unsigned int* exitCode);
134
135#undef CORECLR_HOSTING_API
136
137#endif // __CORECLR_HOST_H__ \ No newline at end of file
diff --git a/src/dnchost/dnchost.cpp b/src/dnchost/dnchost.cpp
new file mode 100644
index 00000000..c4b0d222
--- /dev/null
+++ b/src/dnchost/dnchost.cpp
@@ -0,0 +1,229 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5static DNCSTATE vstate = { };
6
7
8// internal function declarations
9
10static HRESULT LoadModulePaths(
11 __in DNCSTATE* pState
12 );
13static HRESULT LoadDncConfiguration(
14 __in DNCSTATE* pState,
15 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs
16 );
17static HRESULT LoadRuntime(
18 __in DNCSTATE* pState
19 );
20static HRESULT LoadManagedBootstrapperApplicationFactory(
21 __in DNCSTATE* pState
22 );
23
24
25// function definitions
26
27extern "C" BOOL WINAPI DllMain(
28 IN HINSTANCE hInstance,
29 IN DWORD dwReason,
30 IN LPVOID /* pvReserved */
31 )
32{
33 switch (dwReason)
34 {
35 case DLL_PROCESS_ATTACH:
36 ::DisableThreadLibraryCalls(hInstance);
37 vstate.hInstance = hInstance;
38 break;
39
40 case DLL_PROCESS_DETACH:
41 vstate.hInstance = NULL;
42 break;
43 }
44
45 return TRUE;
46}
47
48extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
49 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
50 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
51 )
52{
53 HRESULT hr = S_OK;
54 IBootstrapperEngine* pEngine = NULL;
55
56 // coreclr.dll doesn't support unloading, so the rest of the .NET Core hosting stack doesn't support it either.
57 // This means we also can't unload.
58 pResults->fDisableUnloading = TRUE;
59
60 hr = BalInitializeFromCreateArgs(pArgs, &pEngine);
61 ExitOnFailure(hr, "Failed to initialize Bal.");
62
63 if (!vstate.fInitialized)
64 {
65 hr = XmlInitialize();
66 BalExitOnFailure(hr, "Failed to initialize XML.");
67
68 hr = LoadModulePaths(&vstate);
69 BalExitOnFailure(hr, "Failed to get the host base path.");
70
71 hr = LoadDncConfiguration(&vstate, pArgs);
72 BalExitOnFailure(hr, "Failed to get the dnc configuration.");
73
74 vstate.fInitialized = TRUE;
75 }
76
77 if (!vstate.fInitializedRuntime)
78 {
79 hr = LoadRuntime(&vstate);
80 BalExitOnFailure(hr, "Failed to load .NET Core runtime.");
81
82 vstate.fInitializedRuntime = TRUE;
83
84 hr = LoadManagedBootstrapperApplicationFactory(&vstate);
85 BalExitOnFailure(hr, "Failed to create the .NET Core bootstrapper application factory.");
86 }
87
88 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading .NET Core SCD bootstrapper application.");
89
90 hr = vstate.pAppFactory->Create(pArgs, pResults);
91 BalExitOnFailure(hr, "Failed to create the .NET Core bootstrapper application.");
92
93LExit:
94 ReleaseNullObject(pEngine);
95
96 return hr;
97}
98
99extern "C" void WINAPI BootstrapperApplicationDestroy()
100{
101 BalUninitialize();
102}
103
104static HRESULT LoadModulePaths(
105 __in DNCSTATE* pState
106 )
107{
108 HRESULT hr = S_OK;
109
110 hr = PathForCurrentProcess(&pState->sczModuleFullPath, pState->hInstance);
111 BalExitOnFailure(hr, "Failed to get the full host path.");
112
113 hr = PathGetDirectory(pState->sczModuleFullPath, &pState->sczAppBase);
114 BalExitOnFailure(hr, "Failed to get the directory of the full process path.");
115
116 hr = PathConcat(pState->sczAppBase, DNC_ASSEMBLY_FILE_NAME, &pState->sczManagedHostPath);
117 BalExitOnFailure(hr, "Failed to create managed host path.");
118
119LExit:
120 return hr;
121}
122
123static HRESULT LoadDncConfiguration(
124 __in DNCSTATE* pState,
125 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs
126 )
127{
128 HRESULT hr = S_OK;
129 IXMLDOMDocument* pixdManifest = NULL;
130 IXMLDOMNode* pixnHost = NULL;
131 IXMLDOMNode* pixnPayload = NULL;
132 LPWSTR sczPayloadId = NULL;
133 LPWSTR sczPayloadXPath = NULL;
134 LPWSTR sczPayloadName = NULL;
135
136 hr = XmlLoadDocumentFromFile(pArgs->pCommand->wzBootstrapperApplicationDataPath, &pixdManifest);
137 BalExitOnFailure(hr, "Failed to load BalManifest '%ls'", pArgs->pCommand->wzBootstrapperApplicationDataPath);
138
139 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBalBAFactoryAssembly", &pixnHost);
140 BalExitOnFailure(hr, "Failed to get WixBalBAFactoryAssembly element.");
141
142 if (S_FALSE == hr)
143 {
144 hr = E_NOTFOUND;
145 BalExitOnRootFailure(hr, "Failed to find WixBalBAFactoryAssembly element in bootstrapper application config.");
146 }
147
148 hr = XmlGetAttributeEx(pixnHost, L"PayloadId", &sczPayloadId);
149 BalExitOnFailure(hr, "Failed to get WixBalBAFactoryAssembly/@PayloadId.");
150
151 hr = StrAllocFormatted(&sczPayloadXPath, L"/BootstrapperApplicationData/WixPayloadProperties[@Payload='%ls']", sczPayloadId);
152 BalExitOnFailure(hr, "Failed to format BAFactoryAssembly payload XPath.");
153
154 hr = XmlSelectSingleNode(pixdManifest, sczPayloadXPath, &pixnPayload);
155 if (S_FALSE == hr)
156 {
157 hr = E_NOTFOUND;
158 }
159 BalExitOnFailure(hr, "Failed to find WixPayloadProperties node for BAFactoryAssembly PayloadId: %ls.", sczPayloadId);
160
161 hr = XmlGetAttributeEx(pixnPayload, L"Name", &sczPayloadName);
162 BalExitOnFailure(hr, "Failed to get BAFactoryAssembly payload Name.");
163
164 hr = PathConcat(pArgs->pCommand->wzBootstrapperWorkingFolder, sczPayloadName, &pState->sczBaFactoryAssemblyPath);
165 BalExitOnFailure(hr, "Failed to create BaFactoryAssemblyPath.");
166
167 LPCWSTR wzFileName = PathFile(pState->sczBaFactoryAssemblyPath);
168 LPCWSTR wzExtension = PathExtension(pState->sczBaFactoryAssemblyPath);
169 if (!wzExtension)
170 {
171 BalExitOnFailure(hr = E_FAIL, "BaFactoryAssemblyPath has no extension.");
172 }
173
174 hr = StrAllocString(&pState->sczBaFactoryAssemblyName, wzFileName, wzExtension - wzFileName);
175 BalExitOnFailure(hr, "Failed to copy BAFactoryAssembly payload Name.");
176
177 hr = StrAllocString(&pState->sczBaFactoryDepsJsonPath, pState->sczBaFactoryAssemblyPath, wzExtension - pState->sczBaFactoryAssemblyPath);
178 BalExitOnFailure(hr, "Failed to initialize deps json path.");
179
180 hr = StrAllocString(&pState->sczBaFactoryRuntimeConfigPath, pState->sczBaFactoryDepsJsonPath, 0);
181 BalExitOnFailure(hr, "Failed to initialize runtime config path.");
182
183 hr = StrAllocConcat(&pState->sczBaFactoryDepsJsonPath, L".deps.json", 0);
184 BalExitOnFailure(hr, "Failed to concat extension to deps json path.");
185
186 hr = StrAllocConcat(&pState->sczBaFactoryRuntimeConfigPath, L".runtimeconfig.json", 0);
187 BalExitOnFailure(hr, "Failed to concat extension to runtime config path.");
188
189LExit:
190 ReleaseStr(sczPayloadName);
191 ReleaseObject(pixnPayload);
192 ReleaseStr(sczPayloadXPath);
193 ReleaseStr(sczPayloadId);
194 ReleaseObject(pixnHost);
195 ReleaseObject(pixdManifest);
196
197 return hr;
198}
199
200static HRESULT LoadRuntime(
201 __in DNCSTATE* pState
202 )
203{
204 HRESULT hr = S_OK;
205
206 hr = DnchostLoadRuntime(
207 &pState->hostfxrState,
208 pState->sczModuleFullPath,
209 pState->sczManagedHostPath,
210 pState->sczBaFactoryDepsJsonPath,
211 pState->sczBaFactoryRuntimeConfigPath);
212
213 return hr;
214}
215
216static HRESULT LoadManagedBootstrapperApplicationFactory(
217 __in DNCSTATE* pState
218 )
219{
220 HRESULT hr = S_OK;
221
222 hr = DnchostCreateFactory(
223 &pState->hostfxrState,
224 pState->sczBaFactoryAssemblyName,
225 pState->sczBaFactoryAssemblyPath,
226 &pState->pAppFactory);
227
228 return hr;
229}
diff --git a/src/dnchost/dnchost.def b/src/dnchost/dnchost.def
new file mode 100644
index 00000000..4488df94
--- /dev/null
+++ b/src/dnchost/dnchost.def
@@ -0,0 +1,6 @@
1; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
4EXPORTS
5 BootstrapperApplicationCreate
6 BootstrapperApplicationDestroy
diff --git a/src/dnchost/dnchost.h b/src/dnchost/dnchost.h
new file mode 100644
index 00000000..e498edaf
--- /dev/null
+++ b/src/dnchost/dnchost.h
@@ -0,0 +1,19 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5struct DNCSTATE
6{
7 BOOL fInitialized;
8 BOOL fInitializedRuntime;
9 HINSTANCE hInstance;
10 LPWSTR sczModuleFullPath;
11 LPWSTR sczAppBase;
12 LPWSTR sczManagedHostPath;
13 LPWSTR sczBaFactoryAssemblyName;
14 LPWSTR sczBaFactoryAssemblyPath;
15 LPWSTR sczBaFactoryDepsJsonPath;
16 LPWSTR sczBaFactoryRuntimeConfigPath;
17 HOSTFXR_STATE hostfxrState;
18 IBootstrapperApplicationFactory* pAppFactory;
19};
diff --git a/src/dnchost/dnchost.vcxproj b/src/dnchost/dnchost.vcxproj
new file mode 100644
index 00000000..e2b8b529
--- /dev/null
+++ b/src/dnchost/dnchost.vcxproj
@@ -0,0 +1,77 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
4 <Import Project="..\..\packages\WixToolset.BalUtil.4.0.19\build\WixToolset.BalUtil.props" Condition="Exists('..\..\packages\WixToolset.BalUtil.4.0.19\build\WixToolset.BalUtil.props')" />
5 <Import Project="..\..\packages\WixToolset.BootstrapperCore.Native.4.0.15\build\WixToolset.BootstrapperCore.Native.props" Condition="Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.15\build\WixToolset.BootstrapperCore.Native.props')" />
6 <Import Project="..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" />
7 <ItemGroup Label="ProjectConfigurations">
8 <ProjectConfiguration Include="Debug|Win32">
9 <Configuration>Debug</Configuration>
10 <Platform>Win32</Platform>
11 </ProjectConfiguration>
12 <ProjectConfiguration Include="Release|Win32">
13 <Configuration>Release</Configuration>
14 <Platform>Win32</Platform>
15 </ProjectConfiguration>
16 </ItemGroup>
17 <PropertyGroup Label="Globals">
18 <ProjectGuid>{B6F70281-6583-4138-BB7F-AABFEBBB3CA2}</ProjectGuid>
19 <ConfigurationType>DynamicLibrary</ConfigurationType>
20 <PlatformToolset>v141</PlatformToolset>
21 <CharacterSet>Unicode</CharacterSet>
22 <TargetName>dnchost</TargetName>
23 <ProjectModuleDefinitionFile>dnchost.def</ProjectModuleDefinitionFile>
24 </PropertyGroup>
25 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
26 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
27 <PropertyGroup>
28 <NetHostPath>..\..\packages\runtime.win-x86.Microsoft.NETCore.DotNetAppHost.3.1.3\runtimes\win-x86\native\</NetHostPath>
29 <ProjectAdditionalLinkLibraries>shlwapi.lib;$(NetHostPath)nethost.lib</ProjectAdditionalLinkLibraries>
30 </PropertyGroup>
31 <ItemGroup>
32 <ClCompile Include="dnchost.cpp" />
33 <ClCompile Include="dncutil.cpp" />
34 <ClCompile Include="precomp.cpp">
35 <PrecompiledHeader>Create</PrecompiledHeader>
36 </ClCompile>
37 </ItemGroup>
38 <ItemGroup>
39 <ClInclude Include="coreclrhost.h" />
40 <ClInclude Include="dnchost.h" />
41 <ClInclude Include="dncutil.h" />
42 <ClInclude Include="hostfxr.h" />
43 <ClInclude Include="precomp.h" />
44 </ItemGroup>
45 <ItemGroup>
46 <None Include="dnchost.def" />
47 </ItemGroup>
48 <ItemGroup>
49 <None Include="packages.config" />
50 <Content Include="$(NetHostPath)nethost.dll">
51 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
52 <Visible>False</Visible>
53 </Content>
54 </ItemGroup>
55 <ItemDefinitionGroup>
56 <ClCompile>
57 <AdditionalIncludeDirectories>$(BaseOutputPath)obj;$(NetHostPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
58 </ClCompile>
59 </ItemDefinitionGroup>
60 <ItemGroup>
61 <ProjectReference Include="..\WixToolset.Dnc.Host\WixToolset.Dnc.Host.csproj">
62 <Project>{0D780900-C2FF-4FA2-8CB5-8A19768724C5}</Project>
63 <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
64 </ProjectReference>
65 </ItemGroup>
66 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
67 <Import Project="..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets" Condition="Exists('..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets')" />
68 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
69 <PropertyGroup>
70 <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
71 </PropertyGroup>
72 <Error Condition="!Exists('..\..\packages\WixToolset.BalUtil.4.0.19\build\WixToolset.BalUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.BalUtil.4.0.19\build\WixToolset.BalUtil.props'))" />
73 <Error Condition="!Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.15\build\WixToolset.BootstrapperCore.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.BootstrapperCore.Native.4.0.15\build\WixToolset.BootstrapperCore.Native.props'))" />
74 <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props'))" />
75 <Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets'))" />
76 </Target>
77</Project> \ No newline at end of file
diff --git a/src/dnchost/dncutil.cpp b/src/dnchost/dncutil.cpp
new file mode 100644
index 00000000..996bf086
--- /dev/null
+++ b/src/dnchost/dncutil.cpp
@@ -0,0 +1,359 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5// https://github.com/dotnet/runtime/blob/master/src/installer/corehost/error_codes.h
6#define HostApiBufferTooSmall 0x80008098
7
8// internal function declarations
9
10static HRESULT GetHostfxrPath(
11 __in HOSTFXR_STATE* pState,
12 __in LPCWSTR wzNativeHostPath
13 );
14static HRESULT LoadHostfxr(
15 __in HOSTFXR_STATE* pState
16 );
17static HRESULT InitializeHostfxr(
18 __in HOSTFXR_STATE* pState,
19 __in LPCWSTR wzManagedHostPath,
20 __in LPCWSTR wzDepsJsonPath,
21 __in LPCWSTR wzRuntimeConfigPath
22 );
23static HRESULT InitializeCoreClr(
24 __in HOSTFXR_STATE* pState,
25 __in LPCWSTR wzNativeHostPath
26 );
27static HRESULT LoadCoreClr(
28 __in HOSTFXR_STATE* pState,
29 __in LPCWSTR wzCoreClrPath
30 );
31static HRESULT StartCoreClr(
32 __in HOSTFXR_STATE* pState,
33 __in LPCWSTR wzNativeHostPath,
34 __in size_t cProperties,
35 __in LPCWSTR* propertyKeys,
36 __in LPCWSTR* propertyValues
37 );
38
39
40// function definitions
41
42HRESULT DnchostLoadRuntime(
43 __in HOSTFXR_STATE* pState,
44 __in LPCWSTR wzNativeHostPath,
45 __in LPCWSTR wzManagedHostPath,
46 __in LPCWSTR wzDepsJsonPath,
47 __in LPCWSTR wzRuntimeConfigPath
48 )
49{
50 HRESULT hr = S_OK;
51
52 hr = GetHostfxrPath(pState, wzNativeHostPath);
53 BalExitOnFailure(hr, "Failed to find hostfxr.");
54
55 hr = LoadHostfxr(pState);
56 BalExitOnFailure(hr, "Failed to load hostfxr.");
57
58 hr = InitializeHostfxr(pState, wzManagedHostPath, wzDepsJsonPath, wzRuntimeConfigPath);
59 BalExitOnFailure(hr, "Failed to initialize hostfxr.");
60
61 hr = InitializeCoreClr(pState, wzNativeHostPath);
62 BalExitOnFailure(hr, "Failed to initialize coreclr.");
63
64LExit:
65 return hr;
66}
67
68HRESULT DnchostCreateFactory(
69 __in HOSTFXR_STATE* pState,
70 __in LPCWSTR wzBaFactoryAssemblyName,
71 __in LPCWSTR wzBaFactoryAssemblyPath,
72 __out IBootstrapperApplicationFactory** ppAppFactory
73 )
74{
75 HRESULT hr = S_OK;
76 PFNCREATEBAFACTORY pfnCreateBAFactory = NULL;
77
78 hr = pState->pfnCoreclrCreateDelegate(
79 pState->pClrHandle,
80 pState->dwDomainId,
81 DNC_ASSEMBLY_FULL_NAME,
82 DNC_ENTRY_TYPE,
83 DNC_STATIC_ENTRY_METHOD,
84 reinterpret_cast<void**>(&pfnCreateBAFactory));
85 BalExitOnFailure(hr, "Failed to create delegate in app domain.");
86
87 *ppAppFactory = pfnCreateBAFactory(wzBaFactoryAssemblyName, wzBaFactoryAssemblyPath);
88
89LExit:
90 return hr;
91}
92
93static HRESULT GetHostfxrPath(
94 __in HOSTFXR_STATE* pState,
95 __in LPCWSTR wzNativeHostPath
96 )
97{
98 HRESULT hr = S_OK;
99 get_hostfxr_parameters getHostfxrParameters = { };
100 int nrc = 0;
101 size_t cchHostFxrPath = MAX_PATH;
102
103 getHostfxrParameters.size = sizeof(get_hostfxr_parameters);
104 getHostfxrParameters.assembly_path = wzNativeHostPath;
105
106 // get_hostfxr_path does a full search on every call, so
107 // minimize the number of calls
108 // need to loop
109 for (;;)
110 {
111 cchHostFxrPath *= 2;
112 hr = StrAlloc(&pState->sczHostfxrPath, cchHostFxrPath);
113 BalExitOnFailure(hr, "Failed to allocate hostFxrPath.");
114
115 nrc = get_hostfxr_path(pState->sczHostfxrPath, &cchHostFxrPath, &getHostfxrParameters);
116 if (HostApiBufferTooSmall != nrc)
117 {
118 break;
119 }
120 }
121 if (0 != nrc)
122 {
123 BalExitOnFailure(hr = nrc, "GetHostfxrPath failed");
124 }
125
126LExit:
127 return hr;
128}
129
130static HRESULT LoadHostfxr(
131 __in HOSTFXR_STATE* pState
132 )
133{
134 HRESULT hr = S_OK;
135 HMODULE hHostfxr;
136
137 hHostfxr = ::LoadLibraryExW(pState->sczHostfxrPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
138 BalExitOnNullWithLastError(hHostfxr, hr, "Failed to load hostfxr from '%ls'.", pState->sczHostfxrPath);
139
140 pState->pfnHostfxrInitializeForApp = reinterpret_cast<hostfxr_initialize_for_dotnet_command_line_fn>(::GetProcAddress(hHostfxr, "hostfxr_initialize_for_dotnet_command_line"));
141 BalExitOnNullWithLastError(pState->pfnHostfxrInitializeForApp, hr, "Failed to get procedure address for hostfxr_initialize_for_dotnet_command_line.");
142
143 pState->pfnHostfxrGetRuntimeProperties = reinterpret_cast<hostfxr_get_runtime_properties_fn>(::GetProcAddress(hHostfxr, "hostfxr_get_runtime_properties"));
144 BalExitOnNullWithLastError(pState->pfnHostfxrGetRuntimeProperties, hr, "Failed to get procedure address for hostfxr_get_runtime_properties.");
145
146 pState->pfnHostfxrSetErrorWriter = reinterpret_cast<hostfxr_set_error_writer_fn>(::GetProcAddress(hHostfxr, "hostfxr_set_error_writer"));
147 BalExitOnNullWithLastError(pState->pfnHostfxrSetErrorWriter, hr, "Failed to get procedure address for hostfxr_set_error_writer.");
148
149 pState->pfnHostfxrClose = reinterpret_cast<hostfxr_close_fn>(::GetProcAddress(hHostfxr, "hostfxr_close"));
150 BalExitOnNullWithLastError(pState->pfnHostfxrClose, hr, "Failed to get procedure address for hostfxr_close.");
151
152LExit:
153 // Never unload the module since it isn't meant to be unloaded.
154
155 return hr;
156}
157
158static void HOSTFXR_CALLTYPE DnchostErrorWriter(
159 __in LPCWSTR wzMessage
160 )
161{
162 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "error from hostfxr: %ls", wzMessage);
163}
164
165static HRESULT InitializeHostfxr(
166 __in HOSTFXR_STATE* pState,
167 __in LPCWSTR wzManagedHostPath,
168 __in LPCWSTR wzDepsJsonPath,
169 __in LPCWSTR wzRuntimeConfigPath
170 )
171{
172 HRESULT hr = S_OK;
173
174 pState->pfnHostfxrSetErrorWriter(static_cast<hostfxr_error_writer_fn>(&DnchostErrorWriter));
175
176 LPCWSTR argv[] = {
177 L"exec",
178 L"--depsfile",
179 wzDepsJsonPath,
180 L"--runtimeconfig",
181 wzRuntimeConfigPath,
182 wzManagedHostPath,
183 };
184 hr = pState->pfnHostfxrInitializeForApp(sizeof(argv)/sizeof(LPWSTR), argv, NULL, &pState->hostContextHandle);
185 BalExitOnFailure(hr, "HostfxrInitializeForApp failed");
186
187LExit:
188 return hr;
189}
190
191static HRESULT InitializeCoreClr(
192 __in HOSTFXR_STATE* pState,
193 __in LPCWSTR wzNativeHostPath
194 )
195{
196 HRESULT hr = S_OK;
197 int32_t rc = 0;
198 LPCWSTR* rgPropertyKeys = NULL;
199 LPCWSTR* rgPropertyValues = NULL;
200 size_t cProperties = 0;
201 LPWSTR* rgDirectories = NULL;
202 UINT cDirectories = 0;
203 LPWSTR sczCoreClrPath = NULL;
204
205 // We are not using hostfxr as it was intended to be used. We need to initialize hostfxr so that it properly initializes hostpolicy -
206 // there are pieces of the framework such as AssemblyDependencyResolver that won't work without that. We also need hostfxr to find a
207 // compatible framework for framework-dependent deployed BAs. We had to use hostfxr_initialize_for_dotnet_command_line since
208 // hostfxr_initialize_for_runtime_config doesn't currently (3.x) support self-contained deployed BAs. That means we're supposed to
209 // start the runtime through hostfxr_run_app, but that method shuts down the runtime before returning. We actually want to call
210 // hostfxr_get_runtime_delegate, but that method currently requires hostfxr to be initialized through
211 // hostfxr_initialize_for_runtime_config. So we're forced to locate coreclr.dll and manually load the runtime ourselves.
212
213 // Unfortunately, that's not the only problem. hostfxr has global state that tracks whether it started the runtime. While we keep our
214 // hostfxr_handle open, everyone that calls the hostfxr_initialize_* methods will block until we have started the runtime through
215 // hostfxr or closed our handle. If we close the handle, then hostfxr could potentially try to load a second runtime into the
216 // process, which is not supported. We're going to just keep our handle open since no one else in the process should be trying to
217 // start the runtime anyway.
218
219 rc = pState->pfnHostfxrGetRuntimeProperties(pState->hostContextHandle, &cProperties, rgPropertyKeys, rgPropertyValues);
220 if (HostApiBufferTooSmall != rc)
221 {
222 BalExitOnFailure(hr = rc, "HostfxrGetRuntimeProperties failed to return required size.");
223 }
224
225 rgPropertyKeys = static_cast<LPCWSTR*>(MemAlloc(sizeof(LPWSTR) * cProperties, TRUE));
226 rgPropertyValues = static_cast<LPCWSTR*>(MemAlloc(sizeof(LPWSTR) * cProperties, TRUE));
227 if (!rgPropertyKeys || !rgPropertyValues)
228 {
229 BalExitOnFailure(hr = E_OUTOFMEMORY, "Failed to allocate buffers for runtime properties.");
230 }
231
232 hr = pState->pfnHostfxrGetRuntimeProperties(pState->hostContextHandle, &cProperties, rgPropertyKeys, rgPropertyValues);
233 BalExitOnFailure(hr, "HostfxrGetRuntimeProperties failed.");
234
235 for (DWORD i = 0; i < cProperties; ++i)
236 {
237 if (CSTR_EQUAL == ::CompareString(LOCALE_INVARIANT, 0, rgPropertyKeys[i], -1, L"NATIVE_DLL_SEARCH_DIRECTORIES", -1))
238 {
239 hr = StrSplitAllocArray(&rgDirectories, &cDirectories, rgPropertyValues[i], L";");
240 BalExitOnFailure(hr, "Failed to split NATIVE_DLL_SEARCH_DIRECTORIES '%ls'", rgPropertyValues[i]);
241 }
242 }
243
244 for (DWORD i = 0; i < cDirectories; ++i)
245 {
246 hr = PathConcat(rgDirectories[i], L"coreclr.dll", &sczCoreClrPath);
247 BalExitOnFailure(hr, "Failed to allocate path to coreclr.");
248
249 if (::PathFileExists(sczCoreClrPath))
250 {
251 break;
252 }
253 else
254 {
255 ReleaseNullStr(sczCoreClrPath);
256 }
257 }
258
259 if (!sczCoreClrPath)
260 {
261 for (DWORD i = 0; i < cProperties; ++i)
262 {
263 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "%ls: %ls", rgPropertyKeys[i], rgPropertyValues[i]);
264 }
265 BalExitOnFailure(hr = E_FILENOTFOUND, "Failed to locate coreclr.dll.");
266 }
267
268 hr = LoadCoreClr(pState, sczCoreClrPath);
269 BalExitOnFailure(hr, "Failed to load coreclr.");
270
271 hr = StartCoreClr(pState, wzNativeHostPath, cProperties, rgPropertyKeys, rgPropertyValues);
272 BalExitOnFailure(hr, "Failed to start coreclr.");
273
274LExit:
275 MemFree(rgDirectories);
276 MemFree(rgPropertyValues);
277 MemFree(rgPropertyKeys);
278 ReleaseStr(sczCoreClrPath);
279
280 return hr;
281}
282
283static HRESULT LoadCoreClr(
284 __in HOSTFXR_STATE* pState,
285 __in LPCWSTR wzCoreClrPath
286 )
287{
288 HRESULT hr = S_OK;
289 HMODULE hModule = NULL;
290
291 hModule = ::LoadLibraryExW(wzCoreClrPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
292 BalExitOnNullWithLastError(hModule, hr, "Failed to load coreclr.dll from '%ls'.", wzCoreClrPath);
293
294 pState->pfnCoreclrInitialize = reinterpret_cast<coreclr_initialize_ptr>(::GetProcAddress(hModule, "coreclr_initialize"));
295 BalExitOnNullWithLastError(pState->pfnCoreclrInitialize, hr, "Failed to get procedure address for coreclr_initialize.");
296
297 pState->pfnCoreclrCreateDelegate = reinterpret_cast<coreclr_create_delegate_ptr>(::GetProcAddress(hModule, "coreclr_create_delegate"));
298 BalExitOnNullWithLastError(pState->pfnCoreclrCreateDelegate, hr, "Failed to get procedure address for coreclr_create_delegate.");
299
300LExit:
301 // Never unload the module since coreclr doesn't support it.
302
303 return hr;
304}
305
306static HRESULT StartCoreClr(
307 __in HOSTFXR_STATE* pState,
308 __in LPCWSTR wzNativeHostPath,
309 __in size_t cProperties,
310 __in LPCWSTR* propertyKeys,
311 __in LPCWSTR* propertyValues
312 )
313{
314 HRESULT hr = S_OK;
315 LPSTR szNativeHostPath = NULL;
316 LPSTR* rgPropertyKeys = NULL;
317 LPSTR* rgPropertyValues = NULL;
318
319 rgPropertyKeys = static_cast<LPSTR*>(MemAlloc(sizeof(LPSTR) * cProperties, TRUE));
320 rgPropertyValues = static_cast<LPSTR*>(MemAlloc(sizeof(LPSTR) * cProperties, TRUE));
321 if (!rgPropertyKeys || !rgPropertyValues)
322 {
323 BalExitOnFailure(hr = E_OUTOFMEMORY, "Failed to allocate buffers for runtime properties.");
324 }
325
326 hr = StrAnsiAllocString(&szNativeHostPath, wzNativeHostPath, 0, CP_UTF8);
327 BalExitOnFailure(hr, "Failed to convert module path to UTF8: %ls", wzNativeHostPath);
328
329 for (DWORD i = 0; i < cProperties; ++i)
330 {
331 hr = StrAnsiAllocString(&rgPropertyKeys[i], propertyKeys[i], 0, CP_UTF8);
332 BalExitOnFailure(hr, "Failed to convert property key to UTF8: %ls", propertyKeys[i]);
333
334 hr = StrAnsiAllocString(&rgPropertyValues[i], propertyValues[i], 0, CP_UTF8);
335 BalExitOnFailure(hr, "Failed to convert property value to UTF8: %ls", propertyValues[i]);
336 }
337
338 hr = pState->pfnCoreclrInitialize(szNativeHostPath, "MBA", cProperties, (LPCSTR*)rgPropertyKeys, (LPCSTR*)rgPropertyValues, &pState->pClrHandle, &pState->dwDomainId);
339 BalExitOnFailure(hr, "CoreclrInitialize failed.");
340
341LExit:
342 for (DWORD i = 0; i < cProperties; ++i)
343 {
344 if (rgPropertyKeys)
345 {
346 ReleaseStr(rgPropertyKeys[i]);
347 }
348
349 if (rgPropertyValues)
350 {
351 ReleaseStr(rgPropertyValues[i]);
352 }
353 }
354 ReleaseMem(rgPropertyValues);
355 ReleaseMem(rgPropertyKeys);
356 ReleaseStr(szNativeHostPath);
357
358 return hr;
359}
diff --git a/src/dnchost/dncutil.h b/src/dnchost/dncutil.h
new file mode 100644
index 00000000..1a7c16e3
--- /dev/null
+++ b/src/dnchost/dncutil.h
@@ -0,0 +1,36 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4typedef IBootstrapperApplicationFactory* (STDMETHODCALLTYPE* PFNCREATEBAFACTORY)(
5 __in LPCWSTR wzBaFactoryAssemblyName,
6 __in LPCWSTR wzBaFactoryAssemblyPath
7 );
8
9struct HOSTFXR_STATE
10{
11 LPWSTR sczHostfxrPath;
12 hostfxr_handle hostContextHandle;
13 hostfxr_initialize_for_dotnet_command_line_fn pfnHostfxrInitializeForApp;
14 hostfxr_get_runtime_properties_fn pfnHostfxrGetRuntimeProperties;
15 hostfxr_set_error_writer_fn pfnHostfxrSetErrorWriter;
16 hostfxr_close_fn pfnHostfxrClose;
17 coreclr_initialize_ptr pfnCoreclrInitialize;
18 coreclr_create_delegate_ptr pfnCoreclrCreateDelegate;
19 void* pClrHandle;
20 UINT dwDomainId;
21};
22
23HRESULT DnchostLoadRuntime(
24 __in HOSTFXR_STATE* pState,
25 __in LPCWSTR wzNativeHostPath,
26 __in LPCWSTR wzManagedHostPath,
27 __in LPCWSTR wzDepsJsonPath,
28 __in LPCWSTR wzRuntimeConfigPath
29 );
30
31HRESULT DnchostCreateFactory(
32 __in HOSTFXR_STATE* pState,
33 __in LPCWSTR wzBaFactoryAssemblyName,
34 __in LPCWSTR wzBaFactoryAssemblyPath,
35 __out IBootstrapperApplicationFactory** ppAppFactory
36 );
diff --git a/src/dnchost/hostfxr.h b/src/dnchost/hostfxr.h
new file mode 100644
index 00000000..85e6e0ab
--- /dev/null
+++ b/src/dnchost/hostfxr.h
@@ -0,0 +1,96 @@
1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5
6
7// ***** ABOUT THIS HEADER *****
8// **************************************************************************************
9//
10// This is the version on 2019-12-22 from
11// https://github.com/dotnet/runtime/blob/master/src/installer/corehost/cli/hostfxr.h
12//
13// **************************************************************************************
14// ****************************
15
16
17#ifndef __HOSTFXR_H__
18#define __HOSTFXR_H__
19
20#include <stddef.h>
21#include <stdint.h>
22
23#if defined(_WIN32)
24 #define HOSTFXR_CALLTYPE __cdecl
25 #ifdef _WCHAR_T_DEFINED
26 typedef wchar_t char_t;
27 #else
28 typedef unsigned short char_t;
29 #endif
30#else
31 #define HOSTFXR_CALLTYPE
32 typedef char char_t;
33#endif
34
35enum hostfxr_delegate_type
36{
37 hdt_com_activation,
38 hdt_load_in_memory_assembly,
39 hdt_winrt_activation,
40 hdt_com_register,
41 hdt_com_unregister,
42 hdt_load_assembly_and_get_function_pointer
43};
44
45typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_fn)(const int argc, const char_t **argv);
46typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_startupinfo_fn)(
47 const int argc,
48 const char_t **argv,
49 const char_t *host_path,
50 const char_t *dotnet_root,
51 const char_t *app_path);
52
53typedef void(HOSTFXR_CALLTYPE *hostfxr_error_writer_fn)(const char_t *message);
54typedef hostfxr_error_writer_fn(HOSTFXR_CALLTYPE *hostfxr_set_error_writer_fn)(hostfxr_error_writer_fn error_writer);
55
56typedef void* hostfxr_handle;
57struct hostfxr_initialize_parameters
58{
59 size_t size;
60 const char_t *host_path;
61 const char_t *dotnet_root;
62};
63
64typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_dotnet_command_line_fn)(
65 int argc,
66 const char_t **argv,
67 const struct hostfxr_initialize_parameters *parameters,
68 /*out*/ hostfxr_handle *host_context_handle);
69typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_runtime_config_fn)(
70 const char_t *runtime_config_path,
71 const struct hostfxr_initialize_parameters *parameters,
72 /*out*/ hostfxr_handle *host_context_handle);
73
74typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_property_value_fn)(
75 const hostfxr_handle host_context_handle,
76 const char_t *name,
77 /*out*/ const char_t **value);
78typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_set_runtime_property_value_fn)(
79 const hostfxr_handle host_context_handle,
80 const char_t *name,
81 const char_t *value);
82typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_properties_fn)(
83 const hostfxr_handle host_context_handle,
84 /*inout*/ size_t * count,
85 /*out*/ const char_t **keys,
86 /*out*/ const char_t **values);
87
88typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_run_app_fn)(const hostfxr_handle host_context_handle);
89typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_delegate_fn)(
90 const hostfxr_handle host_context_handle,
91 enum hostfxr_delegate_type type,
92 /*out*/ void **delegate);
93
94typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_close_fn)(const hostfxr_handle host_context_handle);
95
96#endif //__HOSTFXR_H__ \ No newline at end of file
diff --git a/src/dnchost/packages.config b/src/dnchost/packages.config
new file mode 100644
index 00000000..c8911ea5
--- /dev/null
+++ b/src/dnchost/packages.config
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="utf-8"?>
2<packages>
3 <package id="runtime.win-x86.Microsoft.NETCore.DotNetAppHost" version="3.1.3" targetFramework="native" />
4 <package id="Nerdbank.GitVersioning" version="2.1.65" targetFramework="native" developmentDependency="true" />
5 <package id="WixToolset.BootstrapperCore.Native" version="4.0.15" targetFramework="native" />
6 <package id="WixToolset.BalUtil" version="4.0.19" targetFramework="native" />
7 <package id="WixToolset.DUtil" version="4.0.18" targetFramework="native" />
8</packages> \ No newline at end of file
diff --git a/src/dnchost/precomp.cpp b/src/dnchost/precomp.cpp
new file mode 100644
index 00000000..37664a1c
--- /dev/null
+++ b/src/dnchost/precomp.cpp
@@ -0,0 +1,3 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
diff --git a/src/dnchost/precomp.h b/src/dnchost/precomp.h
new file mode 100644
index 00000000..6a12ef67
--- /dev/null
+++ b/src/dnchost/precomp.h
@@ -0,0 +1,29 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4#include <windows.h>
5#include <msiquery.h>
6#include <corerror.h>
7#include <Shlwapi.h>
8
9#include <dutil.h>
10#include <memutil.h>
11#include <pathutil.h>
12#include <strutil.h>
13#include <xmlutil.h>
14
15#include <BootstrapperEngine.h>
16#include <BootstrapperApplication.h>
17
18#include <IBootstrapperEngine.h>
19#include <IBootstrapperApplication.h>
20#include <IBootstrapperApplicationFactory.h>
21#include <balutil.h>
22
23#include <WixToolset.Dnc.Host.h>
24#include <nethost.h>
25
26#include "coreclrhost.h"
27#include "hostfxr.h"
28#include "dncutil.h"
29#include "dnchost.h"