aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Bal/dnchost
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-05-13 13:50:50 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-05-14 11:12:31 -0500
commit6a6974a15deb6edf593736cdb8043bfb93064782 (patch)
tree0ae2afffcd02967ba3fe0f0a5d3e9273811f1e6f /src/ext/Bal/dnchost
parent7d56566b7c51c49ded526466dfae6af9e1709040 (diff)
downloadwix-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.cpp51
-rw-r--r--src/ext/Bal/dnchost/dnchost.h8
-rw-r--r--src/ext/Bal/dnchost/dnchost.vcxproj2
-rw-r--r--src/ext/Bal/dnchost/precomp.h2
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 );
23static HRESULT CreatePrerequisiteBA( 23static 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
128extern "C" void WINAPI BootstrapperApplicationDestroy() 128extern "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
145static HRESULT LoadModulePaths( 155static HRESULT LoadModulePaths(
@@ -262,9 +272,8 @@ static HRESULT LoadManagedBootstrapperApplicationFactory(
262} 272}
263 273
264static HRESULT CreatePrerequisiteBA( 274static 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
291LExit: 300LExit:
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
12extern "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
19struct DNCSTATE 12struct 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"