aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Bal/dnchost/dnchost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Bal/dnchost/dnchost.cpp')
-rw-r--r--src/ext/Bal/dnchost/dnchost.cpp328
1 files changed, 0 insertions, 328 deletions
diff --git a/src/ext/Bal/dnchost/dnchost.cpp b/src/ext/Bal/dnchost/dnchost.cpp
deleted file mode 100644
index 1868e3f8..00000000
--- a/src/ext/Bal/dnchost/dnchost.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
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 );
23static HRESULT CreatePrerequisiteBA(
24 __in DNCSTATE* pState,
25 __in IBootstrapperEngine* pEngine,
26 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
27 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
28 );
29
30
31// function definitions
32
33extern "C" BOOL WINAPI DllMain(
34 IN HINSTANCE hInstance,
35 IN DWORD dwReason,
36 IN LPVOID /* pvReserved */
37 )
38{
39 switch (dwReason)
40 {
41 case DLL_PROCESS_ATTACH:
42 ::DisableThreadLibraryCalls(hInstance);
43 vstate.hInstance = hInstance;
44 break;
45
46 case DLL_PROCESS_DETACH:
47 vstate.hInstance = NULL;
48 break;
49 }
50
51 return TRUE;
52}
53
54extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
55 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
56 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
57 )
58{
59 HRESULT hr = S_OK;
60 IBootstrapperEngine* pEngine = NULL;
61
62 hr = BalInitializeFromCreateArgs(pArgs, &pEngine);
63 ExitOnFailure(hr, "Failed to initialize Bal.");
64
65 if (!vstate.fInitialized)
66 {
67 hr = XmlInitialize();
68 BalExitOnFailure(hr, "Failed to initialize XML.");
69
70 hr = LoadModulePaths(&vstate);
71 BalExitOnFailure(hr, "Failed to get the host base path.");
72
73 hr = LoadDncConfiguration(&vstate, pArgs);
74 BalExitOnFailure(hr, "Failed to get the dnc configuration.");
75
76 vstate.fInitialized = TRUE;
77 }
78
79 if (vstate.prereqData.fAlwaysInstallPrereqs && !vstate.prereqData.fCompleted)
80 {
81 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application since it's configured to always run before loading the runtime.");
82
83 hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults);
84 BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application.");
85
86 ExitFunction();
87 }
88
89 if (!vstate.fInitializedRuntime)
90 {
91 hr = LoadRuntime(&vstate);
92
93 vstate.fInitializedRuntime = SUCCEEDED(hr);
94 }
95
96 if (vstate.fInitializedRuntime)
97 {
98 if (!vstate.pAppFactory)
99 {
100 hr = LoadManagedBootstrapperApplicationFactory(&vstate);
101 BalExitOnFailure(hr, "Failed to create the .NET Core bootstrapper application factory.");
102 }
103
104 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading .NET Core %ls bootstrapper application.", DNCHOSTTYPE_FDD == vstate.type ? L"FDD" : L"SCD");
105
106 hr = vstate.pAppFactory->Create(pArgs, pResults);
107 BalExitOnFailure(hr, "Failed to create the .NET Core bootstrapper application.");
108 }
109 else // fallback to the prerequisite BA.
110 {
111 if (DNCHOSTTYPE_SCD == vstate.type)
112 {
113 vstate.prereqData.hrFatalError = E_DNCHOST_SCD_RUNTIME_FAILURE;
114 BalLogError(hr, "The self-contained .NET Core runtime failed to load. This is an unrecoverable error.");
115 }
116 else if (vstate.prereqData.fCompleted)
117 {
118 hr = E_PREREQBA_INFINITE_LOOP;
119 BalLogError(hr, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop.");
120 vstate.prereqData.hrFatalError = hr;
121 }
122 else
123 {
124 vstate.prereqData.hrFatalError = S_OK;
125 }
126 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because .NET Core host could not be loaded, error: 0x%08x.", hr);
127
128 hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults);
129 BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application.");
130 }
131
132LExit:
133 ReleaseNullObject(pEngine);
134
135 return hr;
136}
137
138extern "C" void WINAPI BootstrapperApplicationDestroy(
139 __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
140 __in BOOTSTRAPPER_DESTROY_RESULTS* pResults
141 )
142{
143 BOOTSTRAPPER_DESTROY_RESULTS childResults = { };
144
145 childResults.cbSize = sizeof(BOOTSTRAPPER_DESTROY_RESULTS);
146
147 if (vstate.hMbapreqModule)
148 {
149 PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast<PFN_BOOTSTRAPPER_APPLICATION_DESTROY>(::GetProcAddress(vstate.hMbapreqModule, "PrereqBootstrapperApplicationDestroy"));
150 if (pfnDestroy)
151 {
152 (*pfnDestroy)(pArgs, &childResults);
153 }
154
155 ::FreeLibrary(vstate.hMbapreqModule);
156 vstate.hMbapreqModule = NULL;
157 }
158
159 BalUninitialize();
160
161 // Need to keep track of state between reloads.
162 pResults->fDisableUnloading = TRUE;
163}
164
165static HRESULT LoadModulePaths(
166 __in DNCSTATE* pState
167 )
168{
169 HRESULT hr = S_OK;
170
171 hr = PathForCurrentProcess(&pState->sczModuleFullPath, pState->hInstance);
172 BalExitOnFailure(hr, "Failed to get the full host path.");
173
174 hr = PathGetDirectory(pState->sczModuleFullPath, &pState->sczAppBase);
175 BalExitOnFailure(hr, "Failed to get the directory of the full process path.");
176
177LExit:
178 return hr;
179}
180
181static HRESULT LoadDncConfiguration(
182 __in DNCSTATE* pState,
183 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs
184 )
185{
186 HRESULT hr = S_OK;
187 IXMLDOMDocument* pixdManifest = NULL;
188 IXMLDOMNode* pixnHost = NULL;
189 LPWSTR sczPayloadName = NULL;
190 DWORD dwBool = 0;
191 BOOL fXmlFound = FALSE;
192
193 hr = XmlLoadDocumentFromFile(pArgs->pCommand->wzBootstrapperApplicationDataPath, &pixdManifest);
194 BalExitOnFailure(hr, "Failed to load BalManifest '%ls'", pArgs->pCommand->wzBootstrapperApplicationDataPath);
195
196 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBalBAFactoryAssembly", &pixnHost);
197 BalExitOnRequiredXmlQueryFailure(hr, "Failed to get WixBalBAFactoryAssembly element.");
198
199 hr = XmlGetAttributeEx(pixnHost, L"FilePath", &sczPayloadName);
200 BalExitOnRequiredXmlQueryFailure(hr, "Failed to get WixBalBAFactoryAssembly/@FilePath.");
201
202 hr = PathConcatRelativeToBase(pArgs->pCommand->wzBootstrapperWorkingFolder, sczPayloadName, &pState->sczBaFactoryAssemblyPath);
203 BalExitOnFailure(hr, "Failed to create BaFactoryAssemblyPath.");
204
205 LPCWSTR wzFileName = PathFile(pState->sczBaFactoryAssemblyPath);
206 LPCWSTR wzExtension = PathExtension(pState->sczBaFactoryAssemblyPath);
207 if (!wzExtension)
208 {
209 BalExitOnFailure(hr = E_FAIL, "BaFactoryAssemblyPath has no extension.");
210 }
211
212 hr = StrAllocString(&pState->sczBaFactoryAssemblyName, wzFileName, wzExtension - wzFileName);
213 BalExitOnFailure(hr, "Failed to copy BAFactoryAssembly payload Name.");
214
215 hr = StrAllocString(&pState->sczBaFactoryDepsJsonPath, pState->sczBaFactoryAssemblyPath, wzExtension - pState->sczBaFactoryAssemblyPath);
216 BalExitOnFailure(hr, "Failed to initialize deps json path.");
217
218 hr = StrAllocString(&pState->sczBaFactoryRuntimeConfigPath, pState->sczBaFactoryDepsJsonPath, 0);
219 BalExitOnFailure(hr, "Failed to initialize runtime config path.");
220
221 hr = StrAllocConcat(&pState->sczBaFactoryDepsJsonPath, L".deps.json", 0);
222 BalExitOnFailure(hr, "Failed to concat extension to deps json path.");
223
224 hr = StrAllocConcat(&pState->sczBaFactoryRuntimeConfigPath, L".runtimeconfig.json", 0);
225 BalExitOnFailure(hr, "Failed to concat extension to runtime config path.");
226
227 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixMbaPrereqOptions", &pixnHost);
228 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find WixMbaPrereqOptions element in bootstrapper application config.");
229
230 if (fXmlFound)
231 {
232 hr = XmlGetAttributeNumber(pixnHost, L"AlwaysInstallPrereqs", reinterpret_cast<DWORD*>(&pState->prereqData.fAlwaysInstallPrereqs));
233 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get AlwaysInstallPrereqs value.");
234 }
235
236 pState->prereqData.fPerformHelp = !pState->prereqData.fAlwaysInstallPrereqs;
237
238 pState->type = DNCHOSTTYPE_FDD;
239
240 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixDncOptions", &pixnHost);
241 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find WixDncOptions element in bootstrapper application config.");
242
243 if (!fXmlFound)
244 {
245 ExitFunction();
246 }
247
248 hr = XmlGetAttributeNumber(pixnHost, L"SelfContainedDeployment", &dwBool);
249 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get SelfContainedDeployment value.");
250
251 if (fXmlFound && dwBool)
252 {
253 pState->type = DNCHOSTTYPE_SCD;
254 }
255
256LExit:
257 ReleaseStr(sczPayloadName);
258 ReleaseObject(pixnHost);
259 ReleaseObject(pixdManifest);
260
261 return hr;
262}
263
264static HRESULT LoadRuntime(
265 __in DNCSTATE* pState
266 )
267{
268 HRESULT hr = S_OK;
269
270 hr = DnchostLoadRuntime(
271 &pState->hostfxrState,
272 pState->sczModuleFullPath,
273 pState->sczBaFactoryAssemblyPath,
274 pState->sczBaFactoryDepsJsonPath,
275 pState->sczBaFactoryRuntimeConfigPath);
276
277 return hr;
278}
279
280static HRESULT LoadManagedBootstrapperApplicationFactory(
281 __in DNCSTATE* pState
282 )
283{
284 HRESULT hr = S_OK;
285
286 hr = DnchostCreateFactory(
287 &pState->hostfxrState,
288 pState->sczBaFactoryAssemblyName,
289 &pState->pAppFactory);
290
291 return hr;
292}
293
294static HRESULT CreatePrerequisiteBA(
295 __in DNCSTATE* pState,
296 __in IBootstrapperEngine* pEngine,
297 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
298 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
299 )
300{
301 HRESULT hr = S_OK;
302 LPWSTR sczDncpreqPath = NULL;
303 HMODULE hModule = NULL;
304
305 hr = PathConcat(pState->sczAppBase, L"dncpreq.dll", &sczDncpreqPath);
306 BalExitOnFailure(hr, "Failed to get path to pre-requisite BA.");
307
308 hModule = ::LoadLibraryExW(sczDncpreqPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
309 BalExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL.");
310
311 PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "PrereqBootstrapperApplicationCreate"));
312 BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get PrereqBootstrapperApplicationCreate entry-point from: %ls", sczDncpreqPath);
313
314 hr = pfnCreate(&pState->prereqData, pEngine, pArgs, pResults);
315 BalExitOnFailure(hr, "Failed to create prequisite bootstrapper app.");
316
317 pState->hMbapreqModule = hModule;
318 hModule = NULL;
319
320LExit:
321 if (hModule)
322 {
323 ::FreeLibrary(hModule);
324 }
325 ReleaseStr(sczDncpreqPath);
326
327 return hr;
328}