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.
Sean Hall committed
May 13, 2022 at 13:50 UTC
6a6974a15deb6edf593736cdb8043bfb93064782
55 files changed
+500
-493
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+16
-2
@@ -1494,7 +1494,22 @@ extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_APPLICATION_PROC)(
1494
__in_opt LPVOID pvContext
1495
);
1496
1497
-extern "C" typedef void (WINAPI *PFN_BOOTSTRAPPER_APPLICATION_DESTROY)();
1497
+struct BOOTSTRAPPER_DESTROY_ARGS
1498
+{
1499
+ DWORD cbSize;
1500
+ BOOL fReload;
1501
+};
1502
+
1503
+struct BOOTSTRAPPER_DESTROY_RESULTS
1504
+{
1505
+ DWORD cbSize;
1506
+ BOOL fDisableUnloading; // indicates the BA dll must not be unloaded after BootstrapperApplicationDestroy.
1507
+};
1508
+
1509
+extern "C" typedef void (WINAPI *PFN_BOOTSTRAPPER_APPLICATION_DESTROY)(
1510
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
1511
+ __inout BOOTSTRAPPER_DESTROY_RESULTS* pResults
1512
+ );
1513
1514
1515
@@ -1512,7 +1527,6 @@ struct BOOTSTRAPPER_CREATE_RESULTS
1527
DWORD cbSize;
1528
PFN_BOOTSTRAPPER_APPLICATION_PROC pfnBootstrapperApplicationProc;
1529
LPVOID pvBootstrapperApplicationProcContext;
1515
- BOOL fDisableUnloading; // indicates the BA dll must not be unloaded after BootstrapperApplicationDestroy.
1530
};
1531
1532
extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_APPLICATION_CREATE)(
src/api/burn/balutil/inc/BAFunctions.h
+16
-1
@@ -126,6 +126,18 @@ struct BA_FUNCTIONS_CREATE_RESULTS
126
LPVOID pvBAFunctionsProcContext;
127
};
128
129
+struct BA_FUNCTIONS_DESTROY_ARGS
130
+{
131
+ DWORD cbSize;
132
+ BOOL fReload;
133
+};
134
+
135
+struct BA_FUNCTIONS_DESTROY_RESULTS
136
+{
137
+ DWORD cbSize;
138
+ BOOL fDisableUnloading; // indicates the BAFunctions dll must not be unloaded after BAFunctionsDestroy.
139
+};
140
+
141
struct BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS
142
{
143
DWORD cbSize;
@@ -218,7 +230,10 @@ typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_CREATE)(
230
__inout BA_FUNCTIONS_CREATE_RESULTS* pResults
231
);
232
221
-typedef void (WINAPI *PFN_BA_FUNCTIONS_DESTROY)();
233
+typedef void (WINAPI *PFN_BA_FUNCTIONS_DESTROY)(
234
+ __in const BA_FUNCTIONS_DESTROY_ARGS* pArgs,
235
+ __inout BA_FUNCTIONS_DESTROY_RESULTS* pResults
236
+ );
237
238
#ifdef __cplusplus
239
}
src/api/burn/balutil/inc/balutil.h
+1
@@ -39,6 +39,7 @@ static const HRESULT E_WIXSTDBA_CONDITION_FAILED = MAKE_HRESULT(SEVERITY_ERROR,
39
40
static const HRESULT E_MBAHOST_NET452_ON_WIN7RTM = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIX, 1000);
41
static const HRESULT E_DNCHOST_SCD_RUNTIME_FAILURE = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIX, 1001);
42
+static const HRESULT E_PREREQBA_INFINITE_LOOP = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIX, 1002);
43
44
45
/*******************************************************************
src/burn/engine/engine.cpp
+2
-2
@@ -796,7 +796,7 @@ LExit:
796
else if (BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER == shutdownAction)
797
{
798
LogId(REPORT_STANDARD, MSG_BA_REQUESTED_RELOAD);
799
- *pfReloadApp = TRUE;
799
+ *pfReloadApp = SUCCEEDED(hr);
800
}
801
else if (BOOTSTRAPPER_SHUTDOWN_ACTION_SKIP_CLEANUP == shutdownAction)
802
{
@@ -806,7 +806,7 @@ LExit:
806
}
807
808
// Unload BA.
809
- UserExperienceUnload(&pEngineState->userExperience);
809
+ UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp);
810
811
return hr;
812
}
src/burn/engine/userexperience.cpp
+11
-4
@@ -122,7 +122,6 @@ extern "C" HRESULT UserExperienceLoad(
122
123
pUserExperience->pfnBAProc = results.pfnBootstrapperApplicationProc;
124
pUserExperience->pvBAProcContext = results.pvBootstrapperApplicationProcContext;
125
- pUserExperience->fDisableUnloading = results.fDisableUnloading;
125
126
LExit:
127
return hr;
@@ -133,10 +132,18 @@ LExit:
132
133
*******************************************************************/
134
extern "C" HRESULT UserExperienceUnload(
136
- __in BURN_USER_EXPERIENCE* pUserExperience
135
+ __in BURN_USER_EXPERIENCE* pUserExperience,
136
+ __in BOOL fReload
137
)
138
{
139
HRESULT hr = S_OK;
140
+ BOOTSTRAPPER_DESTROY_ARGS args = { };
141
+ BOOTSTRAPPER_DESTROY_RESULTS results = { };
142
+
143
+ args.cbSize = sizeof(BOOTSTRAPPER_DESTROY_ARGS);
144
+ args.fReload = fReload;
145
+
146
+ results.cbSize = sizeof(BOOTSTRAPPER_DESTROY_RESULTS);
147
148
if (pUserExperience->hUXModule)
149
{
@@ -144,11 +151,11 @@ extern "C" HRESULT UserExperienceUnload(
151
PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = (PFN_BOOTSTRAPPER_APPLICATION_DESTROY)::GetProcAddress(pUserExperience->hUXModule, "BootstrapperApplicationDestroy");
152
if (pfnDestroy)
153
{
147
- pfnDestroy();
154
+ pfnDestroy(&args, &results);
155
}
156
157
// Free BA DLL if it supports it.
151
- if (!pUserExperience->fDisableUnloading && !::FreeLibrary(pUserExperience->hUXModule))
158
+ if (!results.fDisableUnloading && !::FreeLibrary(pUserExperience->hUXModule))
159
{
160
hr = HRESULT_FROM_WIN32(::GetLastError());
161
TraceError(hr, "Failed to unload BA DLL.");
src/burn/engine/userexperience.h
+2
-2
@@ -22,7 +22,6 @@ typedef struct _BURN_USER_EXPERIENCE
22
HMODULE hUXModule;
23
PFN_BOOTSTRAPPER_APPLICATION_PROC pfnBAProc;
24
LPVOID pvBAProcContext;
25
- BOOL fDisableUnloading;
25
LPWSTR sczTempDirectory;
26
27
CRITICAL_SECTION csEngineActive; // Changing the engine active state in the user experience must be
@@ -61,7 +60,8 @@ HRESULT UserExperienceLoad(
60
__in BOOTSTRAPPER_COMMAND* pCommand
61
);
62
HRESULT UserExperienceUnload(
64
- __in BURN_USER_EXPERIENCE* pUserExperience
63
+ __in BURN_USER_EXPERIENCE* pUserExperience,
64
+ __in BOOL fReload
65
);
66
HRESULT UserExperienceEnsureWorkingFolder(
67
__in BURN_CACHE* pCache,
src/ext/Bal/Samples/bafunctions/bafunctions.cpp
+2
@@ -40,6 +40,8 @@ LExit:
40
}
41
42
extern "C" void WINAPI BAFunctionsDestroy(
43
+ __in const BA_FUNCTIONS_DESTROY_ARGS* /*pArgs*/,
44
+ __inout BA_FUNCTIONS_DESTROY_RESULTS* /*pResults*/
45
)
46
{
47
BalUninitialize();
src/ext/Bal/dnchost/dnchost.cpp
+30
-21
@@ -21,9 +21,8 @@ static HRESULT LoadManagedBootstrapperApplicationFactory(
21
__in DNCSTATE* pState
22
);
23
static HRESULT CreatePrerequisiteBA(
24
- __in HRESULT hrHostInitialization,
24
+ __in DNCSTATE* pState,
25
__in IBootstrapperEngine* pEngine,
26
- __in LPCWSTR wzAppBase,
26
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
27
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults
28
);
@@ -58,13 +57,8 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
57
)
58
{
59
HRESULT hr = S_OK;
61
- HRESULT hrHostInitialization = S_OK;
60
IBootstrapperEngine* pEngine = NULL;
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
-
62
hr = BalInitializeFromCreateArgs(pArgs, &pEngine);
63
ExitOnFailure(hr, "Failed to initialize Bal.");
64
@@ -106,16 +100,22 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
100
{
101
if (DNCHOSTTYPE_SCD == vstate.type)
102
{
109
- hrHostInitialization = E_DNCHOST_SCD_RUNTIME_FAILURE;
103
+ vstate.prereqData.hrHostInitialization = E_DNCHOST_SCD_RUNTIME_FAILURE;
104
BalLogError(hr, "The self-contained .NET Core runtime failed to load. This is an unrecoverable error.");
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
113
{
114
- hrHostInitialization = S_OK;
114
+ vstate.prereqData.hrHostInitialization = S_OK;
115
}
116
BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because .NET Core host could not be loaded, error: 0x%08x.", hr);
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.");
120
}
121
@@ -125,14 +125,21 @@ LExit:
125
return hr;
126
}
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
+ )
132
{
133
+ BOOTSTRAPPER_DESTROY_RESULTS childResults = { };
134
+
135
+ childResults.cbSize = sizeof(BOOTSTRAPPER_DESTROY_RESULTS);
136
+
137
if (vstate.hMbapreqModule)
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"));
140
if (pfnDestroy)
141
{
135
- (*pfnDestroy)();
142
+ (*pfnDestroy)(pArgs, &childResults);
143
}
144
145
::FreeLibrary(vstate.hMbapreqModule);
@@ -140,6 +147,9 @@ extern "C" void WINAPI BootstrapperApplicationDestroy()
147
}
148
149
BalUninitialize();
150
+
151
+ // Need to keep track of state between reloads.
152
+ pResults->fDisableUnloading = TRUE;
153
}
154
155
static HRESULT LoadModulePaths(
@@ -262,9 +272,8 @@ static HRESULT LoadManagedBootstrapperApplicationFactory(
272
}
273
274
static HRESULT CreatePrerequisiteBA(
265
- __in HRESULT hrHostInitialization,
275
+ __in DNCSTATE* pState,
276
__in IBootstrapperEngine* pEngine,
267
- __in LPCWSTR wzAppBase,
277
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
278
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults
279
)
@@ -273,19 +282,19 @@ static HRESULT CreatePrerequisiteBA(
282
LPWSTR sczDncpreqPath = NULL;
283
HMODULE hModule = NULL;
284
276
- hr = PathConcat(wzAppBase, L"dncpreq.dll", &sczDncpreqPath);
285
+ hr = PathConcat(pState->sczAppBase, L"dncpreq.dll", &sczDncpreqPath);
286
BalExitOnFailure(hr, "Failed to get path to pre-requisite BA.");
287
279
- hModule = ::LoadLibraryW(sczDncpreqPath);
288
+ hModule = ::LoadLibraryExW(sczDncpreqPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
289
BalExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL.");
290
282
- PFN_DNCPREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_DNCPREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "DncPrereqBootstrapperApplicationCreate"));
283
- BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get DncPrereqBootstrapperApplicationCreate entry-point from: %ls", sczDncpreqPath);
291
+ PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "PrereqBootstrapperApplicationCreate"));
292
+ BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get PrereqBootstrapperApplicationCreate entry-point from: %ls", sczDncpreqPath);
293
285
- hr = pfnCreate(hrHostInitialization, pEngine, pArgs, pResults);
294
+ hr = pfnCreate(&pState->prereqData, pEngine, pArgs, pResults);
295
BalExitOnFailure(hr, "Failed to create prequisite bootstrapper app.");
296
288
- vstate.hMbapreqModule = hModule;
297
+ pState->hMbapreqModule = hModule;
298
hModule = NULL;
299
300
LExit:
src/ext/Bal/dnchost/dnchost.h
+1
-7
@@ -9,13 +9,6 @@ enum DNCHOSTTYPE
9
DNCHOSTTYPE_SCD,
10
};
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
-
12
struct DNCSTATE
13
{
14
BOOL fInitialized;
@@ -31,4 +24,5 @@ struct DNCSTATE
24
HOSTFXR_STATE hostfxrState;
25
IBootstrapperApplicationFactory* pAppFactory;
26
HMODULE hMbapreqModule;
27
+ PREQBA_DATA prereqData;
28
};
src/ext/Bal/dnchost/dnchost.vcxproj
+1
-1
@@ -50,7 +50,7 @@
50
<NetHostPlatform>$(Platform)</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>
53
- <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj;$(NetHostPath)</ProjectAdditionalIncludeDirectories>
53
+ <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj;$(NetHostPath);..\wixstdba\inc</ProjectAdditionalIncludeDirectories>
54
<ProjectAdditionalLinkLibraries>shlwapi.lib;$(NetHostPath)libnethost.lib</ProjectAdditionalLinkLibraries>
55
</PropertyGroup>
56
src/ext/Bal/dnchost/precomp.h
+2
@@ -25,6 +25,8 @@
25
#include <hostfxr.h>
26
#include <coreclr_delegates.h>
27
28
+#include <preqba.h>
29
+
30
#include "coreclrhost.h"
31
#include "dncutil.h"
32
#include "dnchost.h"
src/ext/Bal/mbahost/mbahost.cpp
+146
-143
@@ -1,7 +1,6 @@
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
-#include <WixToolset.Mba.Host.h> // includes the generated assembly name macros.
4
5
static const DWORD NET452_RELEASE = 379893;
6
@@ -14,26 +13,16 @@ extern "C" typedef HRESULT (WINAPI *PFN_CORBINDTOCURRENTRUNTIME)(
13
__out LPVOID *ppv
14
);
15
17
-extern "C" typedef HRESULT(WINAPI *PFN_MBAPREQ_BOOTSTRAPPER_APPLICATION_CREATE)(
18
- __in HRESULT hrHostInitialization,
19
- __in IBootstrapperEngine* pEngine,
20
- __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
21
- __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
22
- );
23
-
24
-static HINSTANCE vhInstance = NULL;
25
-static ICorRuntimeHost *vpCLRHost = NULL;
26
-static _AppDomain *vpAppDomain = NULL;
27
-static HMODULE vhMbapreqModule = NULL;
16
+static MBASTATE vstate = { };
17
18
19
// internal function declarations
20
21
static HRESULT GetAppDomain(
33
- __out _AppDomain** ppAppDomain
22
+ __in MBASTATE* pState
23
);
35
-static HRESULT GetAppBase(
36
- __out LPWSTR* psczAppBase
24
+static HRESULT LoadModulePaths(
25
+ __in MBASTATE* pState
26
);
27
static HRESULT CheckSupportedFrameworks(
28
__in LPCWSTR wzConfigPath
@@ -43,9 +32,8 @@ static HRESULT UpdateSupportedRuntime(
32
__in IXMLDOMNode* pixnSupportedFramework,
33
__out BOOL* pfUpdatedManifest
34
);
46
-static HRESULT GetCLRHost(
47
- __in LPCWSTR wzConfigPath,
48
- __out ICorRuntimeHost** ppCLRHost
35
+static HRESULT LoadRuntime(
36
+ __in MBASTATE* pState
37
);
38
static HRESULT CreateManagedBootstrapperApplication(
39
__in _AppDomain* pAppDomain,
@@ -57,7 +45,7 @@ static HRESULT CreateManagedBootstrapperApplicationFactory(
45
__out IBootstrapperApplicationFactory** ppAppFactory
46
);
47
static HRESULT CreatePrerequisiteBA(
60
- __in HRESULT hrHostInitialization,
48
+ __in MBASTATE* pState,
49
__in IBootstrapperEngine* pEngine,
50
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
51
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults
@@ -78,11 +66,11 @@ extern "C" BOOL WINAPI DllMain(
66
{
67
case DLL_PROCESS_ATTACH:
68
::DisableThreadLibraryCalls(hInstance);
81
- vhInstance = hInstance;
69
+ vstate.hInstance = hInstance;
70
break;
71
72
case DLL_PROCESS_DETACH:
85
- vhInstance = NULL;
73
+ vstate.hInstance = NULL;
74
break;
75
}
76
@@ -96,18 +84,39 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
84
)
85
{
86
HRESULT hr = S_OK;
99
- HRESULT hrHostInitialization = S_OK;
87
IBootstrapperEngine* pEngine = NULL;
88
89
+ if (vstate.fStoppedRuntime)
90
+ {
91
+ BalExitWithRootFailure(hr, E_INVALIDSTATE, "Reloaded mbahost after stopping .NET runtime.");
92
+ }
93
+
94
hr = BalInitializeFromCreateArgs(pArgs, &pEngine);
95
ExitOnFailure(hr, "Failed to initialize Bal.");
96
105
- hr = GetAppDomain(&vpAppDomain);
106
- if (SUCCEEDED(hr))
97
+ if (!vstate.fInitialized)
98
+ {
99
+ hr = LoadModulePaths(&vstate);
100
+ BalExitOnFailure(hr, "Failed to load the module paths.");
101
+
102
+ vstate.fInitialized = TRUE;
103
+ }
104
+
105
+ if (!vstate.fInitializedRuntime)
106
+ {
107
+ hr = LoadRuntime(&vstate);
108
+
109
+ vstate.fInitializedRuntime = SUCCEEDED(hr);
110
+ }
111
+
112
+ if (vstate.fInitializedRuntime)
113
{
114
+ hr = GetAppDomain(&vstate);
115
+ BalExitOnFailure(hr, "Failed to create the AppDomain for the managed bootstrapper application.");
116
+
117
BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading managed bootstrapper application.");
118
110
- hr = CreateManagedBootstrapperApplication(vpAppDomain, pArgs, pResults);
119
+ hr = CreateManagedBootstrapperApplication(vstate.pAppDomain, pArgs, pResults);
120
BalExitOnFailure(hr, "Failed to create the managed bootstrapper application.");
121
}
122
else // fallback to the prerequisite BA.
@@ -115,16 +124,22 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
124
if (E_MBAHOST_NET452_ON_WIN7RTM == hr)
125
{
126
BalLogError(hr, "The Burn engine cannot run with an MBA under the .NET 4 CLR on Windows 7 RTM with .NET 4.5.2 (or greater) installed.");
118
- hrHostInitialization = hr;
127
+ vstate.prereqData.hrHostInitialization = hr;
128
+ }
129
+ else if (vstate.prereqData.fCompleted)
130
+ {
131
+ hr = E_PREREQBA_INFINITE_LOOP;
132
+ BalLogError(hr, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop.");
133
+ vstate.prereqData.hrHostInitialization = hr;
134
}
135
else
136
{
122
- hrHostInitialization = S_OK;
137
+ vstate.prereqData.hrHostInitialization = S_OK;
138
}
139
140
BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because managed host could not be loaded, error: 0x%08x.", hr);
141
127
- hr = CreatePrerequisiteBA(hrHostInitialization, pEngine, pArgs, pResults);
142
+ hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults);
143
BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application.");
144
}
145
@@ -134,73 +149,65 @@ LExit:
149
return hr;
150
}
151
137
-extern "C" void WINAPI BootstrapperApplicationDestroy()
152
+extern "C" void WINAPI BootstrapperApplicationDestroy(
153
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
154
+ __in BOOTSTRAPPER_DESTROY_RESULTS* pResults
155
+ )
156
{
139
- if (vpAppDomain)
157
+ BOOTSTRAPPER_DESTROY_RESULTS childResults = { };
158
+
159
+ if (vstate.pAppDomain)
160
{
141
- HRESULT hr = vpCLRHost->UnloadDomain(vpAppDomain);
161
+ HRESULT hr = vstate.pCLRHost->UnloadDomain(vstate.pAppDomain);
162
if (FAILED(hr))
163
{
164
BalLogError(hr, "Failed to unload app domain.");
165
}
166
147
- vpAppDomain->Release();
167
+ vstate.pAppDomain->Release();
168
+ vstate.pAppDomain = NULL;
169
}
170
150
- if (vpCLRHost)
171
+ // pCLRHost can only be stopped once per process.
172
+ if (vstate.pCLRHost && !pArgs->fReload)
173
{
152
- vpCLRHost->Stop();
153
- vpCLRHost->Release();
174
+ vstate.pCLRHost->Stop();
175
+ vstate.pCLRHost->Release();
176
+ vstate.pCLRHost = NULL;
177
+ vstate.fStoppedRuntime = TRUE;
178
}
179
156
- if (vhMbapreqModule)
180
+ if (vstate.hMbapreqModule)
181
{
158
- PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast<PFN_BOOTSTRAPPER_APPLICATION_DESTROY>(::GetProcAddress(vhMbapreqModule, "MbaPrereqBootstrapperApplicationDestroy"));
182
+ PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast<PFN_BOOTSTRAPPER_APPLICATION_DESTROY>(::GetProcAddress(vstate.hMbapreqModule, "PrereqBootstrapperApplicationDestroy"));
183
if (pfnDestroy)
184
{
161
- (*pfnDestroy)();
185
+ (*pfnDestroy)(pArgs, &childResults);
186
}
187
164
- ::FreeLibrary(vhMbapreqModule);
165
- vhMbapreqModule = NULL;
188
+ ::FreeLibrary(vstate.hMbapreqModule);
189
+ vstate.hMbapreqModule = NULL;
190
}
191
192
BalUninitialize();
193
+
194
+ // Need to keep track of state between reloads.
195
+ pResults->fDisableUnloading = TRUE;
196
}
197
198
// Gets the custom AppDomain for loading managed BA.
199
static HRESULT GetAppDomain(
173
- __out _AppDomain **ppAppDomain
200
+ __in MBASTATE* pState
201
)
202
{
203
HRESULT hr = S_OK;
177
- ICorRuntimeHost *pCLRHost = NULL;
204
IUnknown *pUnk = NULL;
179
- LPWSTR sczAppBase = NULL;
180
- LPWSTR sczConfigPath = NULL;
181
- IAppDomainSetup *pAppDomainSetup;
205
+ IAppDomainSetup* pAppDomainSetup = NULL;
206
BSTR bstrAppBase = NULL;
207
BSTR bstrConfigPath = NULL;
208
185
- hr = GetAppBase(&sczAppBase);
186
- ExitOnFailure(hr, "Failed to get the host base path.");
187
-
188
- hr = PathConcat(sczAppBase, MBA_CONFIG_FILE_NAME, &sczConfigPath);
189
- ExitOnFailure(hr, "Failed to get the full path to the application configuration file.");
190
-
191
- // Check that the supported framework is installed.
192
- hr = CheckSupportedFrameworks(sczConfigPath);
193
- ExitOnFailure(hr, "Failed to find supported framework.");
194
-
195
- // Load the CLR.
196
- hr = GetCLRHost(sczConfigPath, &pCLRHost);
197
- ExitOnFailure(hr, "Failed to create the CLR host.");
198
-
199
- hr = pCLRHost->Start();
200
- ExitOnRootFailure(hr, "Failed to start the CLR host.");
201
-
209
// Create the setup information for a new AppDomain to set the app base and config.
203
- hr = pCLRHost->CreateDomainSetup(&pUnk);
210
+ hr = pState->pCLRHost->CreateDomainSetup(&pUnk);
211
ExitOnRootFailure(hr, "Failed to create the AppDomainSetup object.");
212
213
hr = pUnk->QueryInterface(__uuidof(IAppDomainSetup), reinterpret_cast<LPVOID*>(&pAppDomainSetup));
@@ -208,49 +215,49 @@ static HRESULT GetAppDomain(
215
ReleaseNullObject(pUnk);
216
217
// Set properties on the AppDomainSetup object.
211
- bstrAppBase = ::SysAllocString(sczAppBase);
218
+ bstrAppBase = ::SysAllocString(pState->sczAppBase);
219
ExitOnNull(bstrAppBase, hr, E_OUTOFMEMORY, "Failed to allocate the application base path for the AppDomainSetup.");
220
221
hr = pAppDomainSetup->put_ApplicationBase(bstrAppBase);
222
ExitOnRootFailure(hr, "Failed to set the application base path for the AppDomainSetup.");
223
217
- bstrConfigPath = ::SysAllocString(sczConfigPath);
224
+ bstrConfigPath = ::SysAllocString(pState->sczConfigPath);
225
ExitOnNull(bstrConfigPath, hr, E_OUTOFMEMORY, "Failed to allocate the application configuration file for the AppDomainSetup.");
226
227
hr = pAppDomainSetup->put_ConfigurationFile(bstrConfigPath);
228
ExitOnRootFailure(hr, "Failed to set the configuration file path for the AppDomainSetup.");
229
230
// Create the AppDomain to load the factory type.
224
- hr = pCLRHost->CreateDomainEx(L"MBA", pAppDomainSetup, NULL, &pUnk);
231
+ hr = pState->pCLRHost->CreateDomainEx(L"MBA", pAppDomainSetup, NULL, &pUnk);
232
ExitOnRootFailure(hr, "Failed to create the MBA AppDomain.");
233
227
- hr = pUnk->QueryInterface(__uuidof(_AppDomain), reinterpret_cast<LPVOID*>(ppAppDomain));
234
+ hr = pUnk->QueryInterface(__uuidof(_AppDomain), reinterpret_cast<LPVOID*>(&pState->pAppDomain));
235
ExitOnRootFailure(hr, "Failed to query for the _AppDomain interface.");
236
237
LExit:
238
ReleaseBSTR(bstrConfigPath);
239
ReleaseBSTR(bstrAppBase);
233
- ReleaseStr(sczConfigPath);
234
- ReleaseStr(sczAppBase);
240
ReleaseNullObject(pUnk);
236
- ReleaseNullObject(pCLRHost);
241
242
return hr;
243
}
244
241
-static HRESULT GetAppBase(
242
- __out LPWSTR *psczAppBase
245
+static HRESULT LoadModulePaths(
246
+ __in MBASTATE* pState
247
)
248
{
249
HRESULT hr = S_OK;
250
LPWSTR sczFullPath = NULL;
251
248
- hr = PathForCurrentProcess(&sczFullPath, vhInstance);
252
+ hr = PathForCurrentProcess(&sczFullPath, pState->hInstance);
253
ExitOnFailure(hr, "Failed to get the full host path.");
254
251
- hr = PathGetDirectory(sczFullPath, psczAppBase);
255
+ hr = PathGetDirectory(sczFullPath, &pState->sczAppBase);
256
ExitOnFailure(hr, "Failed to get the directory of the full process path.");
257
258
+ hr = PathConcat(pState->sczAppBase, MBA_CONFIG_FILE_NAME, &pState->sczConfigPath);
259
+ ExitOnFailure(hr, "Failed to get the full path to the application configuration file.");
260
+
261
LExit:
262
ReleaseStr(sczFullPath);
263
@@ -390,9 +397,8 @@ LExit:
397
}
398
399
// Gets the CLR host and caches it.
393
-static HRESULT GetCLRHost(
394
- __in LPCWSTR wzConfigPath,
395
- __out ICorRuntimeHost **ppCLRHost
400
+static HRESULT LoadRuntime(
401
+ __in MBASTATE* pState
402
)
403
{
404
HRESULT hr = S_OK;
@@ -411,84 +417,81 @@ static HRESULT GetCLRHost(
417
// Always set the error mode because we will always restore it below.
418
uiMode = ::SetErrorMode(0);
419
414
- // Cache the CLR host to be shutdown later. This can occur on a different thread.
415
- if (!vpCLRHost)
416
- {
417
- // Disable message boxes from being displayed on error and blocking execution.
418
- ::SetErrorMode(uiMode | SEM_FAILCRITICALERRORS);
420
+ // Check that the supported framework is installed.
421
+ hr = CheckSupportedFrameworks(pState->sczConfigPath);
422
+ ExitOnFailure(hr, "Failed to find supported framework.");
423
420
- hr = LoadSystemLibrary(L"mscoree.dll", &hModule);
421
- ExitOnFailure(hr, "Failed to load mscoree.dll");
424
+ // Cache the CLR host to be shutdown later. This can occur on a different thread.
425
+ // Disable message boxes from being displayed on error and blocking execution.
426
+ ::SetErrorMode(uiMode | SEM_FAILCRITICALERRORS);
427
423
- pfnCLRCreateInstance = reinterpret_cast<CLRCreateInstanceFnPtr>(::GetProcAddress(hModule, "CLRCreateInstance"));
424
-
425
- if (pfnCLRCreateInstance)
426
- {
427
- hr = pfnCLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, reinterpret_cast<LPVOID*>(&pCLRMetaHostPolicy));
428
- if (E_NOTIMPL != hr)
429
- {
430
- ExitOnRootFailure(hr, "Failed to create instance of ICLRMetaHostPolicy.");
428
+ hr = LoadSystemLibrary(L"mscoree.dll", &hModule);
429
+ ExitOnFailure(hr, "Failed to load mscoree.dll");
430
432
- fFallbackToCorBindToCurrentRuntime = FALSE;
433
- }
434
- }
431
+ pfnCLRCreateInstance = reinterpret_cast<CLRCreateInstanceFnPtr>(::GetProcAddress(hModule, "CLRCreateInstance"));
432
436
- if (fFallbackToCorBindToCurrentRuntime)
433
+ if (pfnCLRCreateInstance)
434
+ {
435
+ hr = pfnCLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, reinterpret_cast<LPVOID*>(&pCLRMetaHostPolicy));
436
+ if (E_NOTIMPL != hr)
437
{
438
- pfnCorBindToCurrentRuntime = reinterpret_cast<PFN_CORBINDTOCURRENTRUNTIME>(::GetProcAddress(hModule, "CorBindToCurrentRuntime"));
439
- ExitOnNullWithLastError(pfnCorBindToCurrentRuntime, hr, "Failed to get procedure address for CorBindToCurrentRuntime.");
438
+ ExitOnRootFailure(hr, "Failed to create instance of ICLRMetaHostPolicy.");
439
441
- hr = pfnCorBindToCurrentRuntime(wzConfigPath, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast<LPVOID*>(&vpCLRHost));
442
- ExitOnRootFailure(hr, "Failed to create the CLR host using the application configuration file path.");
440
+ fFallbackToCorBindToCurrentRuntime = FALSE;
441
}
444
- else
445
- {
446
-
447
- hr = SHCreateStreamOnFileEx(wzConfigPath, STGM_READ | STGM_SHARE_DENY_WRITE, 0, FALSE, NULL, &pCfgStream);
448
- ExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", wzConfigPath);
442
+ }
443
450
- hr = pCLRMetaHostPolicy->GetRequestedRuntime(METAHOST_POLICY_HIGHCOMPAT, NULL, pCfgStream, NULL, &cchVersion, NULL, NULL, &dwConfigFlags, IID_ICLRRuntimeInfo, reinterpret_cast<LPVOID*>(&pCLRRuntimeInfo));
451
- ExitOnRootFailure(hr, "Failed to get the CLR runtime info using the application configuration file path.");
444
+ if (fFallbackToCorBindToCurrentRuntime)
445
+ {
446
+ pfnCorBindToCurrentRuntime = reinterpret_cast<PFN_CORBINDTOCURRENTRUNTIME>(::GetProcAddress(hModule, "CorBindToCurrentRuntime"));
447
+ ExitOnNullWithLastError(pfnCorBindToCurrentRuntime, hr, "Failed to get procedure address for CorBindToCurrentRuntime.");
448
453
- // .NET 4 RTM had a bug where it wouldn't set pcchVersion if pwzVersion was NULL.
454
- if (!cchVersion)
455
- {
456
- hr = pCLRRuntimeInfo->GetVersionString(NULL, &cchVersion);
457
- if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr)
458
- {
459
- ExitOnFailure(hr, "Failed to get the length of the CLR version string.");
460
- }
461
- }
449
+ hr = pfnCorBindToCurrentRuntime(pState->sczConfigPath, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast<LPVOID*>(&pState->pCLRHost));
450
+ ExitOnRootFailure(hr, "Failed to create the CLR host using the application configuration file path.");
451
+ }
452
+ else
453
+ {
454
463
- hr = StrAlloc(&pwzVersion, cchVersion);
464
- ExitOnFailure(hr, "Failed to allocate the CLR version string.");
455
+ hr = SHCreateStreamOnFileEx(pState->sczConfigPath, STGM_READ | STGM_SHARE_DENY_WRITE, 0, FALSE, NULL, &pCfgStream);
456
+ ExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", pState->sczConfigPath);
457
466
- hr = pCLRRuntimeInfo->GetVersionString(pwzVersion, &cchVersion);
467
- ExitOnFailure(hr, "Failed to get the CLR version string.");
458
+ hr = pCLRMetaHostPolicy->GetRequestedRuntime(METAHOST_POLICY_HIGHCOMPAT, NULL, pCfgStream, NULL, &cchVersion, NULL, NULL, &dwConfigFlags, IID_ICLRRuntimeInfo, reinterpret_cast<LPVOID*>(&pCLRRuntimeInfo));
459
+ ExitOnRootFailure(hr, "Failed to get the CLR runtime info using the application configuration file path.");
460
469
- if (CSTR_EQUAL == CompareString(LOCALE_NEUTRAL, 0, L"v4.0.30319", -1, pwzVersion, cchVersion))
461
+ // .NET 4 RTM had a bug where it wouldn't set pcchVersion if pwzVersion was NULL.
462
+ if (!cchVersion)
463
+ {
464
+ hr = pCLRRuntimeInfo->GetVersionString(NULL, &cchVersion);
465
+ if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr)
466
{
471
- hr = VerifyNET4RuntimeIsSupported();
472
- ExitOnFailure(hr, "Found unsupported .NET 4 Runtime.");
467
+ ExitOnFailure(hr, "Failed to get the length of the CLR version string.");
468
}
469
+ }
470
475
- if (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_TRUE == (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_MASK & dwConfigFlags))
476
- {
477
- hr = pCLRRuntimeInfo->BindAsLegacyV2Runtime();
478
- ExitOnRootFailure(hr, "Failed to bind as legacy V2 runtime.");
479
- }
471
+ hr = StrAlloc(&pwzVersion, cchVersion);
472
+ ExitOnFailure(hr, "Failed to allocate the CLR version string.");
473
481
- hr = pCLRRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast<LPVOID*>(&vpCLRHost));
482
- ExitOnRootFailure(hr, "Failed to get instance of ICorRuntimeHost.");
474
+ hr = pCLRRuntimeInfo->GetVersionString(pwzVersion, &cchVersion);
475
+ ExitOnFailure(hr, "Failed to get the CLR version string.");
476
+
477
+ if (CSTR_EQUAL == CompareString(LOCALE_NEUTRAL, 0, L"v4.0.30319", -1, pwzVersion, cchVersion))
478
+ {
479
+ hr = VerifyNET4RuntimeIsSupported();
480
+ ExitOnFailure(hr, "Found unsupported .NET 4 Runtime.");
481
+ }
482
484
- // TODO: use ICLRRuntimeHost instead of ICorRuntimeHost on .NET 4 since the former is faster and the latter is deprecated
485
- //hr = pCLRRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, reinterpret_cast<LPVOID*>(&pCLRRuntimeHost));
486
- //ExitOnRootFailure(hr, "Failed to get instance of ICLRRuntimeHost.");
483
+ if (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_TRUE == (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_MASK & dwConfigFlags))
484
+ {
485
+ hr = pCLRRuntimeInfo->BindAsLegacyV2Runtime();
486
+ ExitOnRootFailure(hr, "Failed to bind as legacy V2 runtime.");
487
}
488
+
489
+ hr = pCLRRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast<LPVOID*>(&pState->pCLRHost));
490
+ ExitOnRootFailure(hr, "Failed to get instance of ICorRuntimeHost.");
491
}
492
490
- vpCLRHost->AddRef();
491
- *ppCLRHost = vpCLRHost;
493
+ hr = pState->pCLRHost->Start();
494
+ ExitOnRootFailure(hr, "Failed to start the CLR host.");
495
496
LExit:
497
ReleaseStr(pwzVersion);
@@ -569,7 +572,7 @@ LExit:
572
}
573
574
static HRESULT CreatePrerequisiteBA(
572
- __in HRESULT hrHostInitialization,
575
+ __in MBASTATE* pState,
576
__in IBootstrapperEngine* pEngine,
577
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
578
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults
@@ -579,19 +582,19 @@ static HRESULT CreatePrerequisiteBA(
582
LPWSTR sczMbapreqPath = NULL;
583
HMODULE hModule = NULL;
584
582
- hr = PathRelativeToModule(&sczMbapreqPath, L"mbapreq.dll", vhInstance);
583
- ExitOnFailure(hr, "Failed to get path to pre-requisite BA.");
585
+ hr = PathConcat(pState->sczAppBase, L"mbapreq.dll", &sczMbapreqPath);
586
+ BalExitOnFailure(hr, "Failed to get path to pre-requisite BA.");
587
585
- hModule = ::LoadLibraryW(sczMbapreqPath);
588
+ hModule = ::LoadLibraryExW(sczMbapreqPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
589
ExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL.");
590
588
- PFN_MBAPREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_MBAPREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "MbaPrereqBootstrapperApplicationCreate"));
589
- ExitOnNullWithLastError(pfnCreate, hr, "Failed to get MbaPrereqBootstrapperApplicationCreate entry-point from: %ls", sczMbapreqPath);
591
+ PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast<PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE>(::GetProcAddress(hModule, "PrereqBootstrapperApplicationCreate"));
592
+ ExitOnNullWithLastError(pfnCreate, hr, "Failed to get PrereqBootstrapperApplicationCreate entry-point from: %ls", sczMbapreqPath);
593
591
- hr = pfnCreate(hrHostInitialization, pEngine, pArgs, pResults);
594
+ hr = pfnCreate(&pState->prereqData, pEngine, pArgs, pResults);
595
ExitOnFailure(hr, "Failed to create prequisite bootstrapper app.");
596
594
- vhMbapreqModule = hModule;
597
+ pState->hMbapreqModule = hModule;
598
hModule = NULL;
599
600
LExit:
src/ext/Bal/mbahost/mbahost.h
new
+17
@@ -0,0 +1,17 @@
1
+#pragma once
2
+// 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.
3
+
4
+
5
+struct MBASTATE
6
+{
7
+ BOOL fInitialized;
8
+ BOOL fInitializedRuntime;
9
+ BOOL fStoppedRuntime;
10
+ HINSTANCE hInstance;
11
+ LPWSTR sczAppBase;
12
+ LPWSTR sczConfigPath;
13
+ mscorlib::_AppDomain* pAppDomain;
14
+ ICorRuntimeHost* pCLRHost;
15
+ HMODULE hMbapreqModule;
16
+ PREQBA_DATA prereqData;
17
+};
src/ext/Bal/mbahost/mbahost.vcxproj
+2
-1
@@ -41,7 +41,7 @@
41
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
42
43
<PropertyGroup>
44
- <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj</ProjectAdditionalIncludeDirectories>
44
+ <ProjectAdditionalIncludeDirectories>$(BaseOutputPath)obj;..\wixstdba\inc</ProjectAdditionalIncludeDirectories>
45
<ProjectAdditionalLinkLibraries>shlwapi.lib</ProjectAdditionalLinkLibraries>
46
</PropertyGroup>
47
@@ -52,6 +52,7 @@
52
</ClCompile>
53
</ItemGroup>
54
<ItemGroup>
55
+ <ClInclude Include="mbahost.h" />
56
<ClInclude Include="precomp.h" />
57
</ItemGroup>
58
<ItemGroup>
src/ext/Bal/mbahost/precomp.h
+11
-6
@@ -16,10 +16,15 @@
16
#include <strutil.h>
17
#include <xmlutil.h>
18
19
-#include "BootstrapperEngine.h"
20
-#include "BootstrapperApplication.h"
21
-#include "IBootstrapperEngine.h"
22
-#include "IBootstrapperApplication.h"
23
-#include "IBootstrapperApplicationFactory.h"
19
+#include <BootstrapperEngine.h>
20
+#include <BootstrapperApplication.h>
21
+#include <IBootstrapperEngine.h>
22
+#include <IBootstrapperApplication.h>
23
+#include <IBootstrapperApplicationFactory.h>
24
25
-#include "balutil.h"
25
+#include <balutil.h>
26
+
27
+#include <preqba.h>
28
+#include <WixToolset.Mba.Host.h> // includes the generated assembly name macros.
29
+
30
+#include "mbahost.h"
src/ext/Bal/test/examples/TestEngine/ReloadEngine.cpp
+2
-2
@@ -31,7 +31,7 @@ HRESULT RunReloadEngine(
31
hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER);
32
ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown.");
33
34
- pTestEngine->UnloadBA();
34
+ pTestEngine->UnloadBA(TRUE);
35
36
hr = pTestEngine->LoadBA(wzBAFilePath);
37
ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to load BA.");
@@ -48,7 +48,7 @@ HRESULT RunReloadEngine(
48
hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART);
49
ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown.");
50
51
- pTestEngine->UnloadBA();
51
+ pTestEngine->UnloadBA(FALSE);
52
53
LExit:
54
return hr;
src/ext/Bal/test/examples/TestEngine/ShutdownEngine.cpp
+1
-1
@@ -31,7 +31,7 @@ HRESULT RunShutdownEngine(
31
hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER);
32
ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown.");
33
34
- pTestEngine->UnloadBA();
34
+ pTestEngine->UnloadBA(FALSE);
35
36
LExit:
37
return hr;
src/ext/Bal/test/examples/TestEngine/TestEngine.cpp
+12
-4
@@ -147,10 +147,18 @@ HRESULT TestEngine::SimulateQuit(
147
return BAEngineQuit(&args, &results);
148
}
149
150
-void TestEngine::UnloadBA()
150
+void TestEngine::UnloadBA(
151
+ __in BOOL fReload
152
+ )
153
{
154
PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = NULL;
153
- BOOL fDisableUnloading = m_pCreateResults && m_pCreateResults->fDisableUnloading;
155
+ BOOTSTRAPPER_DESTROY_ARGS args = { };
156
+ BOOTSTRAPPER_DESTROY_RESULTS results = { };
157
+
158
+ args.cbSize = sizeof(args);
159
+ args.fReload = fReload;
160
+
161
+ results.cbSize = sizeof(results);
162
163
ReleaseNullMem(m_pCreateResults);
164
@@ -158,12 +166,12 @@ void TestEngine::UnloadBA()
166
167
if (pfnDestroy)
168
{
161
- pfnDestroy();
169
+ pfnDestroy(&args, &results);
170
}
171
172
if (m_hBAModule)
173
{
166
- if (!fDisableUnloading)
174
+ if (!results.fDisableUnloading)
175
{
176
::FreeLibrary(m_hBAModule);
177
}
src/ext/Bal/test/examples/TestEngine/TestEngine.h
+4
-2
@@ -44,7 +44,9 @@ public:
44
__in DWORD dwExitCode
45
);
46
47
- void UnloadBA();
47
+ void UnloadBA(
48
+ __in BOOL fReload
49
+ );
50
51
private:
52
HRESULT BAEngineLog(
@@ -77,4 +79,4 @@ private:
79
HMODULE m_hBAModule;
80
BOOTSTRAPPER_CREATE_RESULTS* m_pCreateResults;
81
DWORD m_dwThreadId;
80
-};
\ No newline at end of file
82
+};
src/ext/Bal/test/examples/TestEngine/WaitForQuitEngine.cpp
+1
-1
@@ -28,7 +28,7 @@ HRESULT RunWaitForQuitEngine(
28
hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER);
29
ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown.");
30
31
- pTestEngine->UnloadBA();
31
+ pTestEngine->UnloadBA(FALSE);
32
33
LExit:
34
return hr;
src/ext/Bal/wixstdba/Resources/1028/mbapreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">重新啟動(&R)</String>
30
<String Id="FailureCloseButton">關閉(&C)</String>
31
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1029/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Restartovat</String>
33
<String Id="FailureCloseButton">&Zavřít</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1030/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Genstart</String>
33
<String Id="FailureCloseButton">&Luk</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1031/mbapreq.wxl
+1
@@ -35,5 +35,6 @@
35
<String Id="FailureRestartButton">&Neu starten</String>
36
<String Id="FailureCloseButton">&Schließen</String>
37
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
38
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
39
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
40
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1032/mbapreq.wxl
+1
@@ -34,5 +34,6 @@
34
<String Id="FailureRestartButton">&Επανεκκίνηση</String>
35
<String Id="FailureCloseButton">&Κλείσιμο</String>
36
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
37
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
38
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
39
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1035/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Käynnistä uudelleen</String>
33
<String Id="FailureCloseButton">&Sulje</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1036/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Redémarrer</String>
33
<String Id="FailureCloseButton">&Fermer</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1038/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Újraindítás</String>
33
<String Id="FailureCloseButton">&Bezárás</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1040/mbapreq.wxl
+1
@@ -33,5 +33,6 @@
33
<String Id="FailureRestartButton">&Riavvia</String>
34
<String Id="FailureCloseButton">&Chiudi</String>
35
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
36
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
37
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
38
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1041/mbapreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">再起動(&R)</String>
30
<String Id="FailureCloseButton">閉じる(&C)</String>
31
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1042/mbapreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">다시 시작(&R)</String>
30
<String Id="FailureCloseButton">닫기(&C)</String>
31
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1043/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Opnieuw opstarten</String>
33
<String Id="FailureCloseButton">&Sluiten</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1044/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Start på nytt</String>
33
<String Id="FailureCloseButton">&Lukk</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1045/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Uruchom ponownie</String>
33
<String Id="FailureCloseButton">&Zamknij</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1046/mbapreq.wxl
+1
@@ -31,5 +31,6 @@
31
<String Id="FailureRestartButton">&Reiniciar</String>
32
<String Id="FailureCloseButton">&Fechar</String>
33
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
34
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
35
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
36
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1049/mbapreq.wxl
+1
@@ -31,5 +31,6 @@
31
<String Id="FailureRestartButton">&Перезагрузить</String>
32
<String Id="FailureCloseButton">&Закрыть</String>
33
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
34
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
35
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
36
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1051/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Reštartovať</String>
33
<String Id="FailureCloseButton">&Zavrieť</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1053/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Starta om</String>
33
<String Id="FailureCloseButton">&Stäng</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1055/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Yeniden Başlat</String>
33
<String Id="FailureCloseButton">&Kapat</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/1060/mbapreq.wxl
+1
@@ -32,5 +32,6 @@
32
<String Id="FailureRestartButton">&Ponovni zagon</String>
33
<String Id="FailureCloseButton">&Zapri</String>
34
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
35
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
36
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
37
</WixLocalization>
src/ext/Bal/wixstdba/Resources/2052/mbapreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">重启(&R)</String>
30
<String Id="FailureCloseButton">关闭(&C)</String>
31
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/Resources/2070/mbapreq.wxl
+1
@@ -31,5 +31,6 @@
31
<String Id="FailureRestartButton">&Reiniciar</String>
32
<String Id="FailureCloseButton">&Fechar</String>
33
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
34
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
35
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
36
</WixLocalization>
src/ext/Bal/wixstdba/Resources/3082/mbapreq.wxl
+1
@@ -33,5 +33,6 @@
33
<String Id="FailureRestartButton">&Reiniciar</String>
34
<String Id="FailureCloseButton">&Cerrar</String>
35
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
36
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
37
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
38
</WixLocalization>
src/ext/Bal/wixstdba/Resources/dncpreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">&Restart</String>
30
<String Id="FailureCloseButton">&Close</String>
31
<String Id="SCDRUNTIMEFAILUREErrorMessage">[WixBundleName] cannot run on this machine. Install the latest updates and/or the latest OS to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Core runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/Resources/mbapreq.wxl
+1
@@ -29,5 +29,6 @@
29
<String Id="FailureRestartButton">&Restart</String>
30
<String Id="FailureCloseButton">&Close</String>
31
<String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String>
32
+ <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String>
33
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
34
</WixLocalization>
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+102
-218
@@ -123,14 +123,6 @@ enum WIXSTDBA_CONTROL
123
LAST_WIXSTDBA_CONTROL,
124
};
125
126
-typedef struct _WIXSTDBA_PACKAGE_INFO
127
-{
128
- LPWSTR sczPackageId;
129
- BOOL fWasAlreadyInstalled;
130
- BOOL fPlannedToBeInstalled;
131
- BOOL fSuccessfullyInstalled;
132
-} WIXSTDBA_PACKAGE_INFO;
133
-
126
127
static HRESULT DAPI EvaluateVariableConditionCallback(
128
__in_z LPCWSTR wzCondition,
@@ -229,10 +221,7 @@ public: // IBootstrapperApplication
221
{
222
BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were successfully installed. The bootstrapper application will be reloaded.");
223
*pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER;
232
- }
233
- else if (m_fPrereqAlreadyInstalled)
234
- {
235
- BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop.");
224
+ m_pPrereqData->fCompleted = TRUE;
225
}
226
else if (m_fPrereq)
227
{
@@ -311,38 +300,14 @@ public: // IBootstrapperApplication
300
301
if (!fMissingFromCache)
302
{
314
- if (SUCCEEDED(BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage)))
315
- {
316
- InitializePackageInfoForPackage(pPackage);
317
- }
303
+ BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage);
304
+ // Best effort
305
}
306
307
return CBalBaseBootstrapperApplication::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, fMissingFromCache, pfCancel);
308
}
309
310
324
- virtual STDMETHODIMP OnDetectPackageComplete(
325
- __in LPCWSTR wzPackageId,
326
- __in HRESULT /*hrStatus*/,
327
- __in BOOTSTRAPPER_PACKAGE_STATE state,
328
- __in BOOL /*fCached*/
329
- )
330
- {
331
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
332
- BAL_INFO_PACKAGE* pPackage = NULL;
333
-
334
- if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state &&
335
- SUCCEEDED(GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage)) &&
336
- pPackageInfo)
337
- {
338
- // If the package is already installed, remember that.
339
- pPackageInfo->fWasAlreadyInstalled = TRUE;
340
- }
341
-
342
- return S_OK;
343
- }
344
-
345
-
311
virtual STDMETHODIMP OnDetectComplete(
312
__in HRESULT hrStatus,
313
__in BOOL /*fEligibleForCleanup*/
@@ -366,29 +331,10 @@ public: // IBootstrapperApplication
331
if (fEvaluateConditions)
332
{
333
hrStatus = EvaluateConditions();
369
- }
334
371
- if (FAILED(hrStatus))
372
- {
373
- fSkipToPlan = FALSE;
374
- }
375
- else
376
- {
377
- if (m_fPrereq)
335
+ if (FAILED(hrStatus))
336
{
379
- m_fPrereqAlreadyInstalled = TRUE;
380
-
381
- // At this point we have to assume that all prerequisite packages need to be installed, so set to false if any of them aren't installed.
382
- for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
383
- {
384
- BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
385
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
386
- if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled)
387
- {
388
- m_fPrereqAlreadyInstalled = FALSE;
389
- break;
390
- }
391
- }
337
+ fSkipToPlan = FALSE;
338
}
339
}
340
@@ -403,20 +349,20 @@ public: // IBootstrapperApplication
349
}
350
351
406
- virtual STDMETHODIMP OnPlanRelatedBundle(
352
+ virtual STDMETHODIMP OnPlanRelatedBundleType(
353
__in_z LPCWSTR wzBundleId,
408
- __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
409
- __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
354
+ __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE recommendedType,
355
+ __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType,
356
__inout BOOL* pfCancel
357
)
358
{
359
// If we're only installing prerequisites, do not touch related bundles.
360
if (m_fPrereq)
361
{
416
- *pRequestedState = BOOTSTRAPPER_REQUEST_STATE_NONE;
362
+ *pRequestedType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE;
363
}
364
419
- return CBalBaseBootstrapperApplication::OnPlanRelatedBundle(wzBundleId, recommendedState, pRequestedState, pfCancel);
365
+ return CBalBaseBootstrapperApplication::OnPlanRelatedBundleType(wzBundleId, recommendedType, pRequestedType, pfCancel);
366
}
367
368
@@ -434,7 +380,6 @@ public: // IBootstrapperApplication
380
)
381
{
382
HRESULT hr = S_OK;
437
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
383
BAL_INFO_PACKAGE* pPackage = NULL;
384
385
// If we're planning to install prerequisites, install them. The prerequisites need to be installed
@@ -443,10 +388,11 @@ public: // IBootstrapperApplication
388
{
389
// Only install prerequisite packages, and check the InstallCondition on them.
390
BOOL fInstall = FALSE;
446
- hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
447
- if (SUCCEEDED(hr) && pPackage->fPrereqPackage && pPackageInfo)
391
+
392
+ hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
393
+ if (SUCCEEDED(hr) && pPackage->fPrereqPackage)
394
{
449
- pPackageInfo->fPlannedToBeInstalled = fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition;
395
+ fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition;
396
}
397
398
if (fInstall)
@@ -503,7 +449,6 @@ public: // IBootstrapperApplication
449
)
450
{
451
HRESULT hr = S_OK;
506
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
452
BAL_INFO_PACKAGE* pPackage = NULL;
453
BOOL fShowInternalUI = FALSE;
454
INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NOCHANGE;
@@ -521,7 +466,7 @@ public: // IBootstrapperApplication
466
467
if (INSTALLUILEVEL_NOCHANGE != uiLevel)
468
{
524
- hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
469
+ hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
470
if (SUCCEEDED(hr) && pPackage->sczDisplayInternalUICondition)
471
{
472
hr = BalEvaluateCondition(pPackage->sczDisplayInternalUICondition, &fShowInternalUI);
@@ -545,23 +490,6 @@ public: // IBootstrapperApplication
490
{
491
HRESULT hr = S_OK;
492
548
- if (m_fPrereq)
549
- {
550
- m_fPrereqAlreadyInstalled = TRUE;
551
-
552
- // Now that we've planned the packages, we can focus on the prerequisite packages that are supposed to be installed.
553
- for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
554
- {
555
- BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
556
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
557
- if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled && pPackageInfo->fPlannedToBeInstalled)
558
- {
559
- m_fPrereqAlreadyInstalled = FALSE;
560
- break;
561
- }
562
- }
563
- }
564
-
493
SetState(WIXSTDBA_STATE_PLANNED, hrStatus);
494
495
if (SUCCEEDED(hrStatus))
@@ -1033,13 +961,10 @@ public: // IBootstrapperApplication
961
962
hr = __super::OnExecutePackageComplete(wzPackageId, hrStatus, restart, recommendation, pAction);
963
1036
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
1037
- BAL_INFO_PACKAGE* pPackage;
1038
- HRESULT hrPrereq = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
1039
- if (SUCCEEDED(hrPrereq) && pPackageInfo)
964
+ BAL_INFO_PACKAGE* pPackage = NULL;
965
+ HRESULT hrPrereq = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
966
+ if (SUCCEEDED(hrPrereq))
967
{
1041
- pPackageInfo->fSuccessfullyInstalled = SUCCEEDED(hrStatus);
1042
-
968
// If the prerequisite required a restart (any restart) then do an immediate
969
// restart to ensure that the bundle will get launched again post reboot.
970
if (m_fPrereq && pPackage->fPrereqPackage && BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
@@ -1157,28 +1082,7 @@ public: // IBootstrapperApplication
1082
1083
if (m_fPrereq)
1084
{
1160
- m_fPrereqInstalled = TRUE;
1161
- BOOL fInstalledAPackage = FALSE;
1162
-
1163
- for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
1164
- {
1165
- BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
1166
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
1167
- if (pPackage->fPrereqPackage && pPackageInfo && pPackageInfo->fPlannedToBeInstalled && !pPackageInfo->fWasAlreadyInstalled)
1168
- {
1169
- if (pPackageInfo->fSuccessfullyInstalled)
1170
- {
1171
- fInstalledAPackage = TRUE;
1172
- }
1173
- else
1174
- {
1175
- m_fPrereqInstalled = FALSE;
1176
- break;
1177
- }
1178
- }
1179
- }
1180
-
1181
- m_fPrereqInstalled = m_fPrereqInstalled && fInstalledAPackage;
1085
+ m_fPrereqInstalled = SUCCEEDED(hrStatus);
1086
}
1087
1088
// If we are showing UI, wait a beat before moving to the final screen.
@@ -1223,10 +1127,10 @@ public: // IBootstrapperApplication
1127
{
1128
BAL_INFO_PACKAGE* pPackage = NULL;
1129
1226
- if (SUCCEEDED(hrStatus) && wzNewPackageId &&
1227
- SUCCEEDED(BalInfoAddUpdateBundleAsPackage(&m_Bundle.packages, wzNewPackageId, wzPreviousPackageId, &pPackage)))
1130
+ if (SUCCEEDED(hrStatus) && wzNewPackageId)
1131
{
1229
- InitializePackageInfoForPackage(pPackage);
1132
+ BalInfoAddUpdateBundleAsPackage(&m_Bundle.packages, wzNewPackageId, wzPreviousPackageId, &pPackage);
1133
+ // Best effort
1134
}
1135
1136
return S_OK;
@@ -2201,6 +2105,36 @@ public: //CBalBaseBootstrapperApplication
2105
return hr;
2106
}
2107
2108
+ void Uninitialize(
2109
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
2110
+ __in BOOTSTRAPPER_DESTROY_RESULTS* /*pResults*/
2111
+ )
2112
+ {
2113
+ if (m_hBAFModule)
2114
+ {
2115
+ BA_FUNCTIONS_DESTROY_ARGS args = { };
2116
+ BA_FUNCTIONS_DESTROY_RESULTS results = { };
2117
+
2118
+ args.cbSize = sizeof(BA_FUNCTIONS_DESTROY_ARGS);
2119
+ args.fReload = pArgs->fReload;
2120
+
2121
+ results.cbSize = sizeof(BA_FUNCTIONS_DESTROY_RESULTS);
2122
+
2123
+ PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
2124
+ if (pfnBAFunctionsDestroy)
2125
+ {
2126
+ pfnBAFunctionsDestroy(&args, &results);
2127
+ }
2128
+
2129
+ if (!results.fDisableUnloading)
2130
+ {
2131
+ ::FreeLibrary(m_hBAFModule);
2132
+ m_hBAFModule = NULL;
2133
+ }
2134
+ }
2135
+ }
2136
+
2137
+
2138
private:
2139
//
2140
// UiThreadProc - entrypoint for UI thread.
@@ -2214,6 +2148,7 @@ private:
2148
BOOL fComInitialized = FALSE;
2149
BOOL fRet = FALSE;
2150
MSG msg = { };
2151
+ DWORD dwQuit = 0;
2152
2153
// Initialize COM and theme.
2154
hr = ::CoInitialize(NULL);
@@ -2274,8 +2209,6 @@ private:
2209
pThis->DestroyMainWindow();
2210
pThis->UninitializeTaskbarButton();
2211
2277
- // initiate engine shutdown
2278
- DWORD dwQuit = HRESULT_CODE(hr);
2212
if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->m_restartResult)
2213
{
2214
dwQuit = ERROR_SUCCESS_REBOOT_INITIATED;
@@ -2284,6 +2217,17 @@ private:
2217
{
2218
dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED;
2219
}
2220
+ else if (SEVERITY_ERROR == HRESULT_SEVERITY(hr) && FACILITY_WIN32 == HRESULT_FACILITY(hr))
2221
+ {
2222
+ // Convert Win32 HRESULTs back to the error code.
2223
+ dwQuit = HRESULT_CODE(hr);
2224
+ }
2225
+ else
2226
+ {
2227
+ dwQuit = hr;
2228
+ }
2229
+
2230
+ // initiate engine shutdown
2231
pThis->m_pEngine->Quit(dwQuit);
2232
2233
ReleaseTheme(pThis->m_pTheme);
@@ -2335,9 +2279,6 @@ private:
2279
GetBundleFileVersion();
2280
// don't fail if we couldn't get the version info; best-effort only
2281
2338
- hr = InitializePackageInfo();
2339
- BalExitOnFailure(hr, "Failed to initialize wixstdba package information.");
2340
-
2282
if (m_fPrereq)
2283
{
2284
hr = InitializePrerequisiteInformation();
@@ -2521,38 +2462,6 @@ private:
2462
}
2463
2464
2524
- HRESULT InitializePackageInfo()
2525
- {
2526
- HRESULT hr = S_OK;
2527
- BAL_INFO_PACKAGE* pPackage = NULL;
2528
-
2529
- for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
2530
- {
2531
- pPackage = &m_Bundle.packages.rgPackages[i];
2532
-
2533
- hr = InitializePackageInfoForPackage(pPackage);
2534
- BalExitOnFailure(hr, "Failed to initialize wixstdba package info for package: %ls.", pPackage->sczId);
2535
- }
2536
-
2537
- LExit:
2538
- return hr;
2539
- }
2540
-
2541
-
2542
- HRESULT InitializePackageInfoForPackage(
2543
- __in BAL_INFO_PACKAGE* pPackage
2544
- )
2545
- {
2546
- HRESULT hr = S_OK;
2547
-
2548
- pPackage->pvCustomData = MemAlloc(sizeof(WIXSTDBA_PACKAGE_INFO), TRUE);
2549
- BalExitOnNull(pPackage->pvCustomData, hr, E_OUTOFMEMORY, "Failed to allocate memory for wixstdba package info.");
2550
-
2551
- LExit:
2552
- return hr;
2553
- }
2554
-
2555
-
2465
HRESULT InitializePrerequisiteInformation()
2466
{
2467
HRESULT hr = S_OK;
@@ -2673,35 +2582,6 @@ private:
2582
return hr;
2583
}
2584
2676
- HRESULT GetPackageInfo(
2677
- __in_z LPCWSTR wzPackageId,
2678
- __out WIXSTDBA_PACKAGE_INFO** ppPackageInfo,
2679
- __out BAL_INFO_PACKAGE** ppPackage
2680
- )
2681
- {
2682
- HRESULT hr = E_NOTFOUND;
2683
- WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
2684
- BAL_INFO_PACKAGE* pPackage = NULL;
2685
-
2686
- Assert(wzPackageId && *wzPackageId);
2687
- Assert(ppPackage);
2688
- Assert(ppPackageInfo);
2689
-
2690
- hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
2691
- if (E_NOTFOUND != hr)
2692
- {
2693
- ExitOnFailure(hr, "Failed trying to find the requested package.");
2694
-
2695
- pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
2696
- }
2697
-
2698
- *ppPackageInfo = pPackageInfo;
2699
- *ppPackage = pPackage;
2700
-
2701
- LExit:
2702
- return hr;
2703
- }
2704
-
2585
2586
//
2587
// Get the file version of the bootstrapper and record in bootstrapper log file
@@ -3408,6 +3288,23 @@ private:
3288
}
3289
}
3290
}
3291
+ else if (E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3292
+ {
3293
+ HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.PREREQBAINFINITELOOPErrorMessage)", 0);
3294
+ if (FAILED(hr))
3295
+ {
3296
+ BalLogError(hr, "Failed to initialize PREREQBAINFINITELOOPErrorMessage loc identifier.");
3297
+ }
3298
+ else
3299
+ {
3300
+ hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3301
+ if (FAILED(hr))
3302
+ {
3303
+ BalLogError(hr, "Failed to localize PREREQBAINFINITELOOPErrorMessage: %ls", sczUnformattedText);
3304
+ ReleaseNullStr(sczUnformattedText);
3305
+ }
3306
+ }
3307
+ }
3308
else // try to get the error message from the error code.
3309
{
3310
StrAllocFromError(&sczUnformattedText, m_hrFinal, NULL);
@@ -3424,14 +3321,9 @@ private:
3321
StrAllocString(&sczText, sczUnformattedText, 0);
3322
}
3323
}
3427
- else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal)
3428
- {
3429
- if (sczUnformattedText)
3430
- {
3431
- BalFormatString(sczUnformattedText, &sczText);
3432
- }
3433
- }
3434
- else if (E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal)
3324
+ else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal ||
3325
+ E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal ||
3326
+ E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3327
{
3328
if (sczUnformattedText)
3329
{
@@ -4180,8 +4072,7 @@ public:
4072
//
4073
CWixStandardBootstrapperApplication(
4074
__in HMODULE hModule,
4183
- __in BOOL fPrereq,
4184
- __in HRESULT hrHostInitialization,
4075
+ __in_opt PREQBA_DATA* pPrereqData,
4076
__in IBootstrapperEngine* pEngine
4077
) : CBalBaseBootstrapperApplication(pEngine, 3, 3000)
4078
{
@@ -4210,7 +4101,7 @@ public:
4101
m_hWnd = NULL;
4102
4103
m_state = WIXSTDBA_STATE_INITIALIZING;
4213
- m_hrFinal = hrHostInitialization;
4104
+ m_hrFinal = pPrereqData ? pPrereqData->hrHostInitialization : S_OK;
4105
4106
m_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
4107
m_fRestartRequired = FALSE;
@@ -4231,9 +4122,9 @@ public:
4122
m_fShowingInternalUiThisPackage = FALSE;
4123
m_fTriedToLaunchElevated = FALSE;
4124
4234
- m_fPrereq = fPrereq;
4125
+ m_pPrereqData = pPrereqData;
4126
+ m_fPrereq = NULL != pPrereqData;
4127
m_fPrereqInstalled = FALSE;
4236
- m_fPrereqAlreadyInstalled = FALSE;
4128
4129
pEngine->AddRef();
4130
m_pEngine = pEngine;
@@ -4418,11 +4309,6 @@ public:
4309
AssertSz(!m_pTaskbarList, "Taskbar should have been released before destructor.");
4310
AssertSz(!m_pTheme, "Theme should have been released before destructor.");
4311
4421
- for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
4422
- {
4423
- ReleaseMem(m_Bundle.packages.rgPackages[i].pvCustomData);
4424
- }
4425
-
4312
::DeleteCriticalSection(&m_csShowingInternalUiThisPackage);
4313
ReleaseStr(m_sczFailedMessage);
4314
ReleaseStr(m_sczConfirmCloseMessage);
@@ -4436,18 +4322,6 @@ public:
4322
ReleaseStr(m_sczBundleVersion);
4323
ReleaseStr(m_sczAfterForcedRestartPackage);
4324
ReleaseNullObject(m_pEngine);
4439
-
4440
- if (m_hBAFModule)
4441
- {
4442
- PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
4443
- if (pfnBAFunctionsDestroy)
4444
- {
4445
- pfnBAFunctionsDestroy();
4446
- }
4447
-
4448
- ::FreeLibrary(m_hBAFModule);
4449
- m_hBAFModule = NULL;
4450
- }
4325
}
4326
4327
private:
@@ -4529,9 +4403,9 @@ private:
4403
BOOL m_fSupportCacheOnly;
4404
BOOL m_fRequestedCacheOnly;
4405
4406
+ PREQBA_DATA* m_pPrereqData;
4407
BOOL m_fPrereq;
4408
BOOL m_fPrereqInstalled;
4534
- BOOL m_fPrereqAlreadyInstalled;
4409
4410
ITaskbarList3* m_pTaskbarList;
4411
UINT m_uTaskbarButtonCreatedMessage;
@@ -4551,8 +4425,7 @@ private:
4425
//
4426
HRESULT CreateBootstrapperApplication(
4427
__in HMODULE hModule,
4554
- __in BOOL fPrereq,
4555
- __in HRESULT hrHostInitialization,
4428
+ __in_opt PREQBA_DATA* pPrereqData,
4429
__in IBootstrapperEngine* pEngine,
4430
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
4431
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults,
@@ -4567,7 +4440,7 @@ HRESULT CreateBootstrapperApplication(
4440
BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type.");
4441
}
4442
4570
- pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine);
4443
+ pApplication = new CWixStandardBootstrapperApplication(hModule, pPrereqData, pEngine);
4444
BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");
4445
4446
hr = pApplication->Initialize(pArgs);
@@ -4584,6 +4457,17 @@ LExit:
4457
}
4458
4459
4460
+void DestroyBootstrapperApplication(
4461
+ __in IBootstrapperApplication* pApplication,
4462
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
4463
+ __inout BOOTSTRAPPER_DESTROY_RESULTS* pResults
4464
+ )
4465
+{
4466
+ CWixStandardBootstrapperApplication* pBA = (CWixStandardBootstrapperApplication*)pApplication;
4467
+ pBA->Uninitialize(pArgs, pResults);
4468
+}
4469
+
4470
+
4471
static HRESULT DAPI EvaluateVariableConditionCallback(
4472
__in_z LPCWSTR wzCondition,
4473
__out BOOL* pf,
src/ext/Bal/wixstdba/inc/preqba.h
new
+16
@@ -0,0 +1,16 @@
1
+#pragma once
2
+// 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.
3
+
4
+
5
+struct PREQBA_DATA
6
+{
7
+ HRESULT hrHostInitialization;
8
+ BOOL fCompleted;
9
+};
10
+
11
+extern "C" typedef HRESULT(WINAPI* PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE)(
12
+ __in PREQBA_DATA* pPreqData,
13
+ __in IBootstrapperEngine* pEngine,
14
+ __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
15
+ __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
16
+ );
src/ext/Bal/wixstdba/precomp.h
+36
-30
@@ -17,43 +17,49 @@
17
#include <strsafe.h>
18
#include <stddef.h>
19
20
-#include "dutil.h"
21
-#include "apputil.h"
22
-#include "memutil.h"
23
-#include "dictutil.h"
24
-#include "dirutil.h"
25
-#include "fileutil.h"
26
-#include "locutil.h"
27
-#include "logutil.h"
28
-#include "pathutil.h"
29
-#include "resrutil.h"
30
-#include "shelutil.h"
31
-#include "strutil.h"
32
-#include "wndutil.h"
33
-#include "thmutil.h"
34
-#include "verutil.h"
35
-#include "uriutil.h"
36
-#include "xmlutil.h"
37
-
38
-#include "BootstrapperEngine.h"
39
-#include "BootstrapperApplication.h"
40
-#include "IBootstrapperEngine.h"
41
-#include "IBootstrapperApplication.h"
42
-
43
-#include "balutil.h"
44
-#include "balinfo.h"
45
-#include "balcondition.h"
46
-
47
-#include "BAFunctions.h"
20
+#include <dutil.h>
21
+#include <apputil.h>
22
+#include <memutil.h>
23
+#include <dictutil.h>
24
+#include <dirutil.h>
25
+#include <fileutil.h>
26
+#include <locutil.h>
27
+#include <logutil.h>
28
+#include <pathutil.h>
29
+#include <resrutil.h>
30
+#include <shelutil.h>
31
+#include <strutil.h>
32
+#include <wndutil.h>
33
+#include <thmutil.h>
34
+#include <verutil.h>
35
+#include <uriutil.h>
36
+#include <xmlutil.h>
37
38
+#include <BootstrapperEngine.h>
39
+#include <BootstrapperApplication.h>
40
+#include <IBootstrapperEngine.h>
41
+#include <IBootstrapperApplication.h>
42
+
43
+#include <balutil.h>
44
+#include <balinfo.h>
45
+#include <balcondition.h>
46
+
47
+#include <BAFunctions.h>
48
+
49
+#include "inc\preqba.h"
50
#include "wixstdba.messages.h"
51
52
HRESULT CreateBootstrapperApplication(
53
__in HMODULE hModule,
53
- __in BOOL fPrereq,
54
- __in HRESULT hrHostInitialization,
54
+ __in_opt PREQBA_DATA* pPrereqData,
55
__in IBootstrapperEngine* pEngine,
56
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
57
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults,
58
__out IBootstrapperApplication** ppApplication
59
);
60
+
61
+void DestroyBootstrapperApplication(
62
+ __in IBootstrapperApplication* pApplication,
63
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
64
+ __inout BOOTSTRAPPER_DESTROY_RESULTS* pResults
65
+ );
src/ext/Bal/wixstdba/wixstdba.cpp
+17
-37
@@ -50,7 +50,7 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
50
hr = BalInitializeFromCreateArgs(pArgs, &pEngine);
51
ExitOnFailure(hr, "Failed to initialize Bal.");
52
53
- hr = CreateBootstrapperApplication(vhInstance, FALSE, S_OK, pEngine, pArgs, pResults, &vpApplication);
53
+ hr = CreateBootstrapperApplication(vhInstance, NULL, pEngine, pArgs, pResults, &vpApplication);
54
BalExitOnFailure(hr, "Failed to create bootstrapper application interface.");
55
56
LExit:
@@ -60,45 +60,24 @@ LExit:
60
}
61
62
63
-extern "C" void WINAPI BootstrapperApplicationDestroy()
64
-{
65
- ReleaseNullObject(vpApplication);
66
- BalUninitialize();
67
- DutilUninitialize();
68
-}
69
-
70
-
71
-extern "C" HRESULT WINAPI DncPrereqBootstrapperApplicationCreate(
72
- __in HRESULT hrHostInitialization,
73
- __in IBootstrapperEngine* pEngine,
74
- __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
75
- __inout BOOTSTRAPPER_CREATE_RESULTS* pResults
63
+extern "C" void WINAPI BootstrapperApplicationDestroy(
64
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
65
+ __in BOOTSTRAPPER_DESTROY_RESULTS* pResults
66
)
67
{
78
- HRESULT hr = S_OK;
79
-
80
- DutilInitialize(&WixstdbaTraceError);
81
-
82
- BalInitialize(pEngine);
83
-
84
- hr = CreateBootstrapperApplication(vhInstance, TRUE, hrHostInitialization, pEngine, pArgs, pResults, &vpApplication);
85
- BalExitOnFailure(hr, "Failed to create .NET Core prerequisite bootstrapper application interface.");
86
-
87
-LExit:
88
- return hr;
89
-}
90
-
68
+ if (vpApplication)
69
+ {
70
+ DestroyBootstrapperApplication(vpApplication, pArgs, pResults);
71
+ }
72
92
-extern "C" void WINAPI DncPrereqBootstrapperApplicationDestroy()
93
-{
73
ReleaseNullObject(vpApplication);
74
BalUninitialize();
75
DutilUninitialize();
76
}
77
78
100
-extern "C" HRESULT WINAPI MbaPrereqBootstrapperApplicationCreate(
101
- __in HRESULT hrHostInitialization,
79
+extern "C" HRESULT WINAPI PrereqBootstrapperApplicationCreate(
80
+ __in_opt PREQBA_DATA* pPrereqData,
81
__in IBootstrapperEngine* pEngine,
82
__in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
83
__inout BOOTSTRAPPER_CREATE_RESULTS* pResults
@@ -110,19 +89,20 @@ extern "C" HRESULT WINAPI MbaPrereqBootstrapperApplicationCreate(
89
90
BalInitialize(pEngine);
91
113
- hr = CreateBootstrapperApplication(vhInstance, TRUE, hrHostInitialization, pEngine, pArgs, pResults, &vpApplication);
114
- BalExitOnFailure(hr, "Failed to create managed prerequisite bootstrapper application interface.");
92
+ hr = CreateBootstrapperApplication(vhInstance, pPrereqData, pEngine, pArgs, pResults, &vpApplication);
93
+ BalExitOnFailure(hr, "Failed to create prerequisite bootstrapper application interface.");
94
95
LExit:
96
return hr;
97
}
98
99
121
-extern "C" void WINAPI MbaPrereqBootstrapperApplicationDestroy()
100
+extern "C" void WINAPI PrereqBootstrapperApplicationDestroy(
101
+ __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
102
+ __in BOOTSTRAPPER_DESTROY_RESULTS* pResults
103
+ )
104
{
123
- ReleaseNullObject(vpApplication);
124
- BalUninitialize();
125
- DutilUninitialize();
105
+ BootstrapperApplicationDestroy(pArgs, pResults);
106
}
107
108
static void CALLBACK WixstdbaTraceError(
src/ext/Bal/wixstdba/wixstdba.def
+2
-4
@@ -4,7 +4,5 @@
4
EXPORTS
5
BootstrapperApplicationCreate
6
BootstrapperApplicationDestroy
7
- DncPrereqBootstrapperApplicationCreate
8
- DncPrereqBootstrapperApplicationDestroy
9
- MbaPrereqBootstrapperApplicationCreate
10
- MbaPrereqBootstrapperApplicationDestroy
7
+ PrereqBootstrapperApplicationCreate
8
+ PrereqBootstrapperApplicationDestroy
src/ext/Bal/wixstdba/wixstdba.vcxproj
+1
@@ -52,6 +52,7 @@
52
<ClCompile Include="wixstdba.cpp" />
53
</ItemGroup>
54
<ItemGroup>
55
+ <ClInclude Include="inc\preqba.h" />
56
<ClInclude Include="precomp.h" />
57
<ClInclude Include="resource.h" />
58
</ItemGroup>
src/test/burn/TestBA/TestBA.cs
+7
-1
@@ -171,7 +171,13 @@ namespace WixToolset.Test.BA
171
this.dummyWindow.Dispose();
172
}
173
174
- this.Engine.Quit(this.result & 0xFFFF); // return plain old Win32 error, not HRESULT.
174
+ var exitCode = this.result;
175
+ if ((exitCode & 0xFFFF0000) == unchecked(0x80070000))
176
+ {
177
+ exitCode &= 0xFFFF; // return plain old Win32 error, not HRESULT.
178
+ }
179
+
180
+ this.Engine.Quit(exitCode);
181
}
182
183
protected override void OnDetectUpdateBegin(DetectUpdateBeginEventArgs args)
src/test/burn/TestData/Manual/BafThmutilTesting/precomp.cpp
+2
@@ -40,6 +40,8 @@ LExit:
40
}
41
42
extern "C" void WINAPI BAFunctionsDestroy(
43
+ __in const BA_FUNCTIONS_DESTROY_ARGS* /*pArgs*/,
44
+ __inout BA_FUNCTIONS_DESTROY_RESULTS* /*pResults*/
45
)
46
{
47
BalUninitialize();
src/test/burn/WixToolset.WixBA/WixBA.cs
+8
-1
@@ -179,7 +179,14 @@ namespace WixToolset.WixBA
179
Threading.Dispatcher.Run();
180
181
this.PostTelemetry();
182
- this.Engine.Quit(WixBA.Model.Result);
182
+
183
+ var exitCode = WixBA.Model.Result;
184
+ if ((exitCode & 0xFFFF0000) == unchecked(0x80070000))
185
+ {
186
+ exitCode &= 0xFFFF; // return plain old Win32 error, not HRESULT.
187
+ }
188
+
189
+ this.Engine.Quit(exitCode);
190
}
191
192
private void PostTelemetry()
src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs
+4
-2
@@ -12,6 +12,8 @@ namespace WixToolsetTest.BurnE2E
12
{
13
public PrereqBaTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15
+ const int E_PREREQBA_INFINITE_LOOP = -2_114_714_646;
16
+
17
/// <summary>
18
/// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist,
19
/// with an MSI package to represent the prerequisite package.
@@ -32,7 +34,7 @@ namespace WixToolsetTest.BurnE2E
34
// Source file should *not* be installed
35
Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
36
35
- bundleA.Install();
37
+ bundleA.Install(E_PREREQBA_INFINITE_LOOP);
38
39
// Part of the test is Install actually completing.
40
@@ -63,7 +65,7 @@ namespace WixToolsetTest.BurnE2E
65
// Source file should *not* be installed
66
Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}");
67
66
- bundleB.Install();
68
+ bundleB.Install(E_PREREQBA_INFINITE_LOOP);
69
70
// Part of the test is Install actually completing.
71