diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-05-13 13:50:50 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-05-14 11:12:31 -0500 |
commit | 6a6974a15deb6edf593736cdb8043bfb93064782 (patch) | |
tree | 0ae2afffcd02967ba3fe0f0a5d3e9273811f1e6f /src/ext/Bal/dnchost | |
parent | 7d56566b7c51c49ded526466dfae6af9e1709040 (diff) | |
download | wix-6a6974a15deb6edf593736cdb8043bfb93064782.tar.gz wix-6a6974a15deb6edf593736cdb8043bfb93064782.tar.bz2 wix-6a6974a15deb6edf593736cdb8043bfb93064782.zip |
Move infinite loop detection into the hosts.
Tell the BA during Destroy whether it will be reloaded, and let the BA decide then whether it's module should be unloaded.
Show error when infinite prereq loop detected.
Only clip the exit code if they're Win32 errors.
Set related bundle type to none to avoid downgrades during preqba.
Diffstat (limited to 'src/ext/Bal/dnchost')
-rw-r--r-- | src/ext/Bal/dnchost/dnchost.cpp | 51 | ||||
-rw-r--r-- | src/ext/Bal/dnchost/dnchost.h | 8 | ||||
-rw-r--r-- | src/ext/Bal/dnchost/dnchost.vcxproj | 2 | ||||
-rw-r--r-- | src/ext/Bal/dnchost/precomp.h | 2 |
4 files changed, 34 insertions, 29 deletions
diff --git a/src/ext/Bal/dnchost/dnchost.cpp b/src/ext/Bal/dnchost/dnchost.cpp index 644ba30e..6c066f43 100644 --- a/src/ext/Bal/dnchost/dnchost.cpp +++ b/src/ext/Bal/dnchost/dnchost.cpp | |||
@@ -21,9 +21,8 @@ static HRESULT LoadManagedBootstrapperApplicationFactory( | |||
21 | __in DNCSTATE* pState | 21 | __in DNCSTATE* pState |
22 | ); | 22 | ); |
23 | static HRESULT CreatePrerequisiteBA( | 23 | static HRESULT CreatePrerequisiteBA( |
24 | __in HRESULT hrHostInitialization, | 24 | __in DNCSTATE* pState, |
25 | __in IBootstrapperEngine* pEngine, | 25 | __in IBootstrapperEngine* pEngine, |
26 | __in LPCWSTR wzAppBase, | ||
27 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, | 26 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, |
28 | __inout BOOTSTRAPPER_CREATE_RESULTS* pResults | 27 | __inout BOOTSTRAPPER_CREATE_RESULTS* pResults |
29 | ); | 28 | ); |
@@ -58,13 +57,8 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate( | |||
58 | ) | 57 | ) |
59 | { | 58 | { |
60 | HRESULT hr = S_OK; | 59 | HRESULT hr = S_OK; |
61 | HRESULT hrHostInitialization = S_OK; | ||
62 | IBootstrapperEngine* pEngine = NULL; | 60 | IBootstrapperEngine* pEngine = NULL; |
63 | 61 | ||
64 | // coreclr.dll doesn't support unloading, so the rest of the .NET Core hosting stack doesn't support it either. | ||
65 | // This means we also can't unload. | ||
66 | pResults->fDisableUnloading = TRUE; | ||
67 | |||
68 | hr = BalInitializeFromCreateArgs(pArgs, &pEngine); | 62 | hr = BalInitializeFromCreateArgs(pArgs, &pEngine); |
69 | ExitOnFailure(hr, "Failed to initialize Bal."); | 63 | ExitOnFailure(hr, "Failed to initialize Bal."); |
70 | 64 | ||
@@ -106,16 +100,22 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate( | |||
106 | { | 100 | { |
107 | if (DNCHOSTTYPE_SCD == vstate.type) | 101 | if (DNCHOSTTYPE_SCD == vstate.type) |
108 | { | 102 | { |
109 | hrHostInitialization = E_DNCHOST_SCD_RUNTIME_FAILURE; | 103 | vstate.prereqData.hrHostInitialization = E_DNCHOST_SCD_RUNTIME_FAILURE; |
110 | BalLogError(hr, "The self-contained .NET Core runtime failed to load. This is an unrecoverable error."); | 104 | BalLogError(hr, "The self-contained .NET Core runtime failed to load. This is an unrecoverable error."); |
111 | } | 105 | } |
106 | else if (vstate.prereqData.fCompleted) | ||
107 | { | ||
108 | hr = E_PREREQBA_INFINITE_LOOP; | ||
109 | BalLogError(hr, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop."); | ||
110 | vstate.prereqData.hrHostInitialization = hr; | ||
111 | } | ||
112 | else | 112 | else |
113 | { | 113 | { |
114 | hrHostInitialization = S_OK; | 114 | vstate.prereqData.hrHostInitialization = S_OK; |
115 | } | 115 | } |
116 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because .NET Core host could not be loaded, error: 0x%08x.", hr); | 116 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because .NET Core host could not be loaded, error: 0x%08x.", hr); |
117 | 117 | ||
118 | hr = CreatePrerequisiteBA(hrHostInitialization, pEngine, vstate.sczAppBase, pArgs, pResults); | 118 | hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults); |
119 | BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); | 119 | BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); |
120 | } | 120 | } |
121 | 121 | ||
@@ -125,14 +125,21 @@ LExit: | |||
125 | return hr; | 125 | return hr; |
126 | } | 126 | } |
127 | 127 | ||
128 | extern "C" void WINAPI BootstrapperApplicationDestroy() | 128 | extern "C" void WINAPI BootstrapperApplicationDestroy( |
129 | __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs, | ||
130 | __in BOOTSTRAPPER_DESTROY_RESULTS* pResults | ||
131 | ) | ||
129 | { | 132 | { |
133 | BOOTSTRAPPER_DESTROY_RESULTS childResults = { }; | ||
134 | |||
135 | childResults.cbSize = sizeof(BOOTSTRAPPER_DESTROY_RESULTS); | ||
136 | |||
130 | if (vstate.hMbapreqModule) | 137 | if (vstate.hMbapreqModule) |
131 | { | 138 | { |
132 | PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast<PFN_BOOTSTRAPPER_APPLICATION_DESTROY>(::GetProcAddress(vstate.hMbapreqModule, "DncPrereqBootstrapperApplicationDestroy")); | 139 | PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast<PFN_BOOTSTRAPPER_APPLICATION_DESTROY>(::GetProcAddress(vstate.hMbapreqModule, "PrereqBootstrapperApplicationDestroy")); |
133 | if (pfnDestroy) | 140 | if (pfnDestroy) |
134 | { | 141 | { |
135 | (*pfnDestroy)(); | 142 | (*pfnDestroy)(pArgs, &childResults); |
136 | } | 143 | } |
137 | 144 | ||
138 | ::FreeLibrary(vstate.hMbapreqModule); | 145 | ::FreeLibrary(vstate.hMbapreqModule); |
@@ -140,6 +147,9 @@ extern "C" void WINAPI BootstrapperApplicationDestroy() | |||
140 | } | 147 | } |
141 | 148 | ||
142 | BalUninitialize(); | 149 | BalUninitialize(); |
150 | |||
151 | // Need to keep track of state between reloads. | ||
152 | pResults->fDisableUnloading = TRUE; | ||
143 | } | 153 | } |
144 | 154 | ||
145 | static HRESULT LoadModulePaths( | 155 | static HRESULT LoadModulePaths( |
@@ -262,9 +272,8 @@ static HRESULT LoadManagedBootstrapperApplicationFactory( | |||
262 | } | 272 | } |
263 | 273 | ||
264 | static HRESULT CreatePrerequisiteBA( | 274 | static HRESULT CreatePrerequisiteBA( |
265 | __in HRESULT hrHostInitialization, | 275 | __in DNCSTATE* pState, |
266 | __in IBootstrapperEngine* pEngine, | 276 | __in IBootstrapperEngine* pEngine, |
267 | __in LPCWSTR wzAppBase, | ||
268 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, | 277 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, |
269 | __inout BOOTSTRAPPER_CREATE_RESULTS* pResults | 278 | __inout BOOTSTRAPPER_CREATE_RESULTS* pResults |
270 | ) | 279 | ) |
@@ -273,19 +282,19 @@ static HRESULT CreatePrerequisiteBA( | |||
273 | LPWSTR sczDncpreqPath = NULL; | 282 | LPWSTR sczDncpreqPath = NULL; |
274 | HMODULE hModule = NULL; | 283 | HMODULE hModule = NULL; |
275 | 284 | ||
276 | hr = PathConcat(wzAppBase, L"dncpreq.dll", &sczDncpreqPath); | 285 | hr = PathConcat(pState->sczAppBase, L"dncpreq.dll", &sczDncpreqPath); |
277 | BalExitOnFailure(hr, "Failed to get path to pre-requisite BA."); | 286 | BalExitOnFailure(hr, "Failed to get path to pre-requisite BA."); |
278 | 287 | ||
279 | hModule = ::LoadLibraryW(sczDncpreqPath); | 288 | hModule = ::LoadLibraryExW(sczDncpreqPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
280 | BalExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL."); | 289 | BalExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL."); |
281 | 290 | ||
282 | PFN_DNCPREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_DNCPREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "DncPrereqBootstrapperApplicationCreate")); | 291 | PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "PrereqBootstrapperApplicationCreate")); |
283 | BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get DncPrereqBootstrapperApplicationCreate entry-point from: %ls", sczDncpreqPath); | 292 | BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get PrereqBootstrapperApplicationCreate entry-point from: %ls", sczDncpreqPath); |
284 | 293 | ||
285 | hr = pfnCreate(hrHostInitialization, pEngine, pArgs, pResults); | 294 | hr = pfnCreate(&pState->prereqData, pEngine, pArgs, pResults); |
286 | BalExitOnFailure(hr, "Failed to create prequisite bootstrapper app."); | 295 | BalExitOnFailure(hr, "Failed to create prequisite bootstrapper app."); |
287 | 296 | ||
288 | vstate.hMbapreqModule = hModule; | 297 | pState->hMbapreqModule = hModule; |
289 | hModule = NULL; | 298 | hModule = NULL; |
290 | 299 | ||
291 | LExit: | 300 | LExit: |
diff --git a/src/ext/Bal/dnchost/dnchost.h b/src/ext/Bal/dnchost/dnchost.h index b0ba9638..000cf43d 100644 --- a/src/ext/Bal/dnchost/dnchost.h +++ b/src/ext/Bal/dnchost/dnchost.h | |||
@@ -9,13 +9,6 @@ enum DNCHOSTTYPE | |||
9 | DNCHOSTTYPE_SCD, | 9 | DNCHOSTTYPE_SCD, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | extern "C" typedef HRESULT(WINAPI* PFN_DNCPREQ_BOOTSTRAPPER_APPLICATION_CREATE)( | ||
13 | __in HRESULT hrHostInitialization, | ||
14 | __in IBootstrapperEngine* pEngine, | ||
15 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, | ||
16 | __inout BOOTSTRAPPER_CREATE_RESULTS* pResults | ||
17 | ); | ||
18 | |||
19 | struct DNCSTATE | 12 | struct DNCSTATE |
20 | { | 13 | { |
21 | BOOL fInitialized; | 14 | BOOL fInitialized; |
@@ -31,4 +24,5 @@ struct DNCSTATE | |||
31 | HOSTFXR_STATE hostfxrState; | 24 | HOSTFXR_STATE hostfxrState; |
32 | IBootstrapperApplicationFactory* pAppFactory; | 25 | IBootstrapperApplicationFactory* pAppFactory; |
33 | HMODULE hMbapreqModule; | 26 | HMODULE hMbapreqModule; |
27 | PREQBA_DATA prereqData; | ||
34 | }; | 28 | }; |
diff --git a/src/ext/Bal/dnchost/dnchost.vcxproj b/src/ext/Bal/dnchost/dnchost.vcxproj index ca0c09d6..b258ccae 100644 --- a/src/ext/Bal/dnchost/dnchost.vcxproj +++ b/src/ext/Bal/dnchost/dnchost.vcxproj | |||
@@ -50,7 +50,7 @@ | |||
50 | <NetHostPlatform>$(Platform)</NetHostPlatform> | 50 | <NetHostPlatform>$(Platform)</NetHostPlatform> |
51 | <NetHostPlatform Condition=" '$(NetHostPlatform)'=='Win32' ">x86</NetHostPlatform> | 51 | <NetHostPlatform Condition=" '$(NetHostPlatform)'=='Win32' ">x86</NetHostPlatform> |
52 | <NetHostPath>..\..\..\..\packages\runtime.win-$(NetHostPlatform).Microsoft.NETCore.DotNetAppHost.6.0.4\runtimes\win-$(NetHostPlatform)\native\</NetHostPath> | 52 | <NetHostPath>..\..\..\..\packages\runtime.win-$(NetHostPlatform).Microsoft.NETCore.DotNetAppHost.6.0.4\runtimes\win-$(NetHostPlatform)\native\</NetHostPath> |
53 | <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj;$(NetHostPath)</ProjectAdditionalIncludeDirectories> | 53 | <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj;$(NetHostPath);..\wixstdba\inc</ProjectAdditionalIncludeDirectories> |
54 | <ProjectAdditionalLinkLibraries>shlwapi.lib;$(NetHostPath)libnethost.lib</ProjectAdditionalLinkLibraries> | 54 | <ProjectAdditionalLinkLibraries>shlwapi.lib;$(NetHostPath)libnethost.lib</ProjectAdditionalLinkLibraries> |
55 | </PropertyGroup> | 55 | </PropertyGroup> |
56 | 56 | ||
diff --git a/src/ext/Bal/dnchost/precomp.h b/src/ext/Bal/dnchost/precomp.h index 7aefc4e3..5f365fba 100644 --- a/src/ext/Bal/dnchost/precomp.h +++ b/src/ext/Bal/dnchost/precomp.h | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <hostfxr.h> | 25 | #include <hostfxr.h> |
26 | #include <coreclr_delegates.h> | 26 | #include <coreclr_delegates.h> |
27 | 27 | ||
28 | #include <preqba.h> | ||
29 | |||
28 | #include "coreclrhost.h" | 30 | #include "coreclrhost.h" |
29 | #include "dncutil.h" | 31 | #include "dncutil.h" |
30 | #include "dnchost.h" | 32 | #include "dnchost.h" |