diff options
Diffstat (limited to 'src/dnchost/dnchost.cpp')
-rw-r--r-- | src/dnchost/dnchost.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
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 | |||
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 | |||
24 | |||
25 | // function definitions | ||
26 | |||
27 | extern "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 | |||
48 | extern "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 | |||
93 | LExit: | ||
94 | ReleaseNullObject(pEngine); | ||
95 | |||
96 | return hr; | ||
97 | } | ||
98 | |||
99 | extern "C" void WINAPI BootstrapperApplicationDestroy() | ||
100 | { | ||
101 | BalUninitialize(); | ||
102 | } | ||
103 | |||
104 | static 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 | |||
119 | LExit: | ||
120 | return hr; | ||
121 | } | ||
122 | |||
123 | static 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 | |||
189 | LExit: | ||
190 | ReleaseStr(sczPayloadName); | ||
191 | ReleaseObject(pixnPayload); | ||
192 | ReleaseStr(sczPayloadXPath); | ||
193 | ReleaseStr(sczPayloadId); | ||
194 | ReleaseObject(pixnHost); | ||
195 | ReleaseObject(pixdManifest); | ||
196 | |||
197 | return hr; | ||
198 | } | ||
199 | |||
200 | static 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 | |||
216 | static 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 | } | ||