diff options
Diffstat (limited to 'src/ext/Bal/dnchost/dnchost.cpp')
-rw-r--r-- | src/ext/Bal/dnchost/dnchost.cpp | 328 |
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 | |||
5 | static DNCSTATE vstate = { }; | ||
6 | |||
7 | |||
8 | // internal function declarations | ||
9 | |||
10 | static HRESULT LoadModulePaths( | ||
11 | __in DNCSTATE* pState | ||
12 | ); | ||
13 | static HRESULT LoadDncConfiguration( | ||
14 | __in DNCSTATE* pState, | ||
15 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs | ||
16 | ); | ||
17 | static HRESULT LoadRuntime( | ||
18 | __in DNCSTATE* pState | ||
19 | ); | ||
20 | static HRESULT LoadManagedBootstrapperApplicationFactory( | ||
21 | __in DNCSTATE* pState | ||
22 | ); | ||
23 | static 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 | |||
33 | extern "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 | |||
54 | extern "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 | |||
132 | LExit: | ||
133 | ReleaseNullObject(pEngine); | ||
134 | |||
135 | return hr; | ||
136 | } | ||
137 | |||
138 | extern "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 | |||
165 | static 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 | |||
177 | LExit: | ||
178 | return hr; | ||
179 | } | ||
180 | |||
181 | static 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 | |||
256 | LExit: | ||
257 | ReleaseStr(sczPayloadName); | ||
258 | ReleaseObject(pixnHost); | ||
259 | ReleaseObject(pixdManifest); | ||
260 | |||
261 | return hr; | ||
262 | } | ||
263 | |||
264 | static 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 | |||
280 | static 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 | |||
294 | static 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 | |||
320 | LExit: | ||
321 | if (hModule) | ||
322 | { | ||
323 | ::FreeLibrary(hModule); | ||
324 | } | ||
325 | ReleaseStr(sczDncpreqPath); | ||
326 | |||
327 | return hr; | ||
328 | } | ||