diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-03 15:35:14 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-01-04 19:19:43 -0600 |
commit | 1f5314302b3c8bc1977aed79df1d05c52608f382 (patch) | |
tree | f0fef3a4462352c914a4cc9413515d07f2244703 | |
parent | db44f6cf3b1eb476e47384f2eccba5712808def5 (diff) | |
download | wix-1f5314302b3c8bc1977aed79df1d05c52608f382.tar.gz wix-1f5314302b3c8bc1977aed79df1d05c52608f382.tar.bz2 wix-1f5314302b3c8bc1977aed79df1d05c52608f382.zip |
Don't assume Exe packages with Burn protocol are bundles.
Related to #3693
-rw-r--r-- | src/burn/engine/apply.cpp | 94 | ||||
-rw-r--r-- | src/burn/engine/bundlepackageengine.cpp | 460 | ||||
-rw-r--r-- | src/burn/engine/bundlepackageengine.h | 38 | ||||
-rw-r--r-- | src/burn/engine/core.cpp | 14 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 166 | ||||
-rw-r--r-- | src/burn/engine/elevation.h | 9 | ||||
-rw-r--r-- | src/burn/engine/engine.vcxproj | 2 | ||||
-rw-r--r-- | src/burn/engine/exeengine.cpp | 177 | ||||
-rw-r--r-- | src/burn/engine/exeengine.h | 20 | ||||
-rw-r--r-- | src/burn/engine/package.cpp | 22 | ||||
-rw-r--r-- | src/burn/engine/package.h | 22 | ||||
-rw-r--r-- | src/burn/engine/plan.cpp | 128 | ||||
-rw-r--r-- | src/burn/engine/plan.h | 22 | ||||
-rw-r--r-- | src/burn/engine/precomp.h | 1 | ||||
-rw-r--r-- | src/burn/engine/pseudobundle.cpp | 153 | ||||
-rw-r--r-- | src/burn/engine/pseudobundle.h | 15 | ||||
-rw-r--r-- | src/burn/engine/relatedbundle.cpp | 47 | ||||
-rw-r--r-- | src/burn/engine/relatedbundle.h | 5 | ||||
-rw-r--r-- | src/burn/test/BurnUnitTest/PlanTest.cpp | 33 |
19 files changed, 1018 insertions, 410 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index e2939f40..99884234 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
@@ -201,6 +201,15 @@ static HRESULT DoRollbackActions( | |||
201 | __in DWORD dwCheckpoint, | 201 | __in DWORD dwCheckpoint, |
202 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 202 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
203 | ); | 203 | ); |
204 | static HRESULT ExecuteRelatedBundle( | ||
205 | __in BURN_ENGINE_STATE* pEngineState, | ||
206 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
207 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
208 | __in BOOL fRollback, | ||
209 | __out BOOL* pfRetry, | ||
210 | __out BOOL* pfSuspend, | ||
211 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
212 | ); | ||
204 | static HRESULT ExecuteExePackage( | 213 | static HRESULT ExecuteExePackage( |
205 | __in BURN_ENGINE_STATE* pEngineState, | 214 | __in BURN_ENGINE_STATE* pEngineState, |
206 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 215 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
@@ -686,6 +695,9 @@ extern "C" HRESULT ApplyExecute( | |||
686 | LPCWSTR wzId = NULL; | 695 | LPCWSTR wzId = NULL; |
687 | switch (pExecuteAction->type) | 696 | switch (pExecuteAction->type) |
688 | { | 697 | { |
698 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
699 | wzId = pExecuteAction->relatedBundle.pRelatedBundle->package.sczId; | ||
700 | break; | ||
689 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 701 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
690 | wzId = pExecuteAction->exePackage.pPackage->sczId; | 702 | wzId = pExecuteAction->exePackage.pPackage->sczId; |
691 | break; | 703 | break; |
@@ -2285,6 +2297,11 @@ static HRESULT DoExecuteAction( | |||
2285 | } | 2297 | } |
2286 | break; | 2298 | break; |
2287 | 2299 | ||
2300 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
2301 | hr = ExecuteRelatedBundle(pEngineState, pExecuteAction, pContext, FALSE, &fRetry, pfSuspend, &restart); | ||
2302 | ExitOnFailure(hr, "Failed to execute related bundle."); | ||
2303 | break; | ||
2304 | |||
2288 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 2305 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
2289 | hr = ExecuteExePackage(pEngineState, pExecuteAction, pContext, FALSE, &fRetry, pfSuspend, &restart); | 2306 | hr = ExecuteExePackage(pEngineState, pExecuteAction, pContext, FALSE, &fRetry, pfSuspend, &restart); |
2290 | ExitOnFailure(hr, "Failed to execute EXE package."); | 2307 | ExitOnFailure(hr, "Failed to execute EXE package."); |
@@ -2399,6 +2416,11 @@ static HRESULT DoRollbackActions( | |||
2399 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: | 2416 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: |
2400 | break; | 2417 | break; |
2401 | 2418 | ||
2419 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
2420 | hr = ExecuteRelatedBundle(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | ||
2421 | ExitOnFailure(hr, "Failed to execute related bundle."); | ||
2422 | break; | ||
2423 | |||
2402 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 2424 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
2403 | hr = ExecuteExePackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | 2425 | hr = ExecuteExePackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); |
2404 | IgnoreRollbackError(hr, "Failed to rollback EXE package."); | 2426 | IgnoreRollbackError(hr, "Failed to rollback EXE package."); |
@@ -2462,6 +2484,78 @@ LExit: | |||
2462 | return hr; | 2484 | return hr; |
2463 | } | 2485 | } |
2464 | 2486 | ||
2487 | static HRESULT ExecuteRelatedBundle( | ||
2488 | __in BURN_ENGINE_STATE* pEngineState, | ||
2489 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
2490 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
2491 | __in BOOL fRollback, | ||
2492 | __out BOOL* pfRetry, | ||
2493 | __out BOOL* pfSuspend, | ||
2494 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
2495 | ) | ||
2496 | { | ||
2497 | HRESULT hr = S_OK; | ||
2498 | HRESULT hrExecute = S_OK; | ||
2499 | GENERIC_EXECUTE_MESSAGE message = { }; | ||
2500 | int nResult = 0; | ||
2501 | BOOL fBeginCalled = FALSE; | ||
2502 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; | ||
2503 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | ||
2504 | |||
2505 | if (FAILED(pPackage->hrCacheResult)) | ||
2506 | { | ||
2507 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2508 | ExitFunction1(hr = S_OK); | ||
2509 | } | ||
2510 | |||
2511 | Assert(pContext->fRollback == fRollback); | ||
2512 | pContext->pExecutingPackage = pPackage; | ||
2513 | fBeginCalled = TRUE; | ||
2514 | |||
2515 | // Send package execute begin to BA. | ||
2516 | hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->relatedBundle.action, INSTALLUILEVEL_NOCHANGE, FALSE); | ||
2517 | ExitOnRootFailure(hr, "BA aborted execute related bundle begin."); | ||
2518 | |||
2519 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; | ||
2520 | message.dwUIHint = MB_OKCANCEL; | ||
2521 | message.progress.dwPercentage = fRollback ? 100 : 0; | ||
2522 | nResult = GenericExecuteMessageHandler(&message, pContext); | ||
2523 | hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); | ||
2524 | ExitOnRootFailure(hr, "BA aborted related bundle progress."); | ||
2525 | |||
2526 | // Execute package. | ||
2527 | if (pPackage->fPerMachine) | ||
2528 | { | ||
2529 | hrExecute = ElevationExecuteRelatedBundle(pEngineState->companionConnection.hPipe, pExecuteAction, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart); | ||
2530 | ExitOnFailure(hrExecute, "Failed to configure per-machine related bundle."); | ||
2531 | } | ||
2532 | else | ||
2533 | { | ||
2534 | hrExecute = BundlePackageEngineExecuteRelatedBundle(pExecuteAction, pContext->pCache, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart); | ||
2535 | ExitOnFailure(hrExecute, "Failed to configure per-user related bundle."); | ||
2536 | } | ||
2537 | |||
2538 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; | ||
2539 | message.dwUIHint = MB_OKCANCEL; | ||
2540 | message.progress.dwPercentage = fRollback ? 0 : 100; | ||
2541 | nResult = GenericExecuteMessageHandler(&message, pContext); | ||
2542 | hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); | ||
2543 | ExitOnRootFailure(hr, "BA aborted related bundle progress."); | ||
2544 | |||
2545 | pContext->cExecutedPackages += fRollback ? -1 : 1; | ||
2546 | |||
2547 | hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext); | ||
2548 | ExitOnRootFailure(hr, "BA aborted related bundle execute progress."); | ||
2549 | |||
2550 | LExit: | ||
2551 | if (fBeginCalled) | ||
2552 | { | ||
2553 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2554 | } | ||
2555 | |||
2556 | return hr; | ||
2557 | } | ||
2558 | |||
2465 | static HRESULT ExecuteExePackage( | 2559 | static HRESULT ExecuteExePackage( |
2466 | __in BURN_ENGINE_STATE* pEngineState, | 2560 | __in BURN_ENGINE_STATE* pEngineState, |
2467 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 2561 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp new file mode 100644 index 00000000..10022b6a --- /dev/null +++ b/src/burn/engine/bundlepackageengine.cpp | |||
@@ -0,0 +1,460 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | |||
7 | // function definitions | ||
8 | |||
9 | extern "C" void BundlePackageEnginePackageUninitialize( | ||
10 | __in BURN_PACKAGE* pPackage | ||
11 | ) | ||
12 | { | ||
13 | ReleaseStr(pPackage->Bundle.sczInstallArguments); | ||
14 | ReleaseStr(pPackage->Bundle.sczRepairArguments); | ||
15 | ReleaseStr(pPackage->Bundle.sczUninstallArguments); | ||
16 | ReleaseStr(pPackage->Bundle.sczIgnoreDependencies); | ||
17 | ReleaseMem(pPackage->Bundle.rgExitCodes); | ||
18 | |||
19 | // free command-line arguments | ||
20 | if (pPackage->Bundle.rgCommandLineArguments) | ||
21 | { | ||
22 | for (DWORD i = 0; i < pPackage->Bundle.cCommandLineArguments; ++i) | ||
23 | { | ||
24 | ExeEngineCommandLineArgumentUninitialize(pPackage->Bundle.rgCommandLineArguments + i); | ||
25 | } | ||
26 | MemFree(pPackage->Bundle.rgCommandLineArguments); | ||
27 | } | ||
28 | |||
29 | // clear struct | ||
30 | memset(&pPackage->Bundle, 0, sizeof(pPackage->Bundle)); | ||
31 | } | ||
32 | |||
33 | // | ||
34 | // PlanCalculate - calculates the execute and rollback state for the requested package state. | ||
35 | // | ||
36 | extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( | ||
37 | __in BURN_PACKAGE* pPackage | ||
38 | ) | ||
39 | { | ||
40 | HRESULT hr = S_OK; | ||
41 | BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
42 | BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
43 | |||
44 | // execute action | ||
45 | switch (pPackage->currentState) | ||
46 | { | ||
47 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: | ||
48 | switch (pPackage->requested) | ||
49 | { | ||
50 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: | ||
51 | execute = pPackage->Bundle.fPseudoBundle ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; | ||
52 | break; | ||
53 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
54 | execute = pPackage->Bundle.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE; | ||
55 | break; | ||
56 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | ||
57 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: | ||
58 | execute = pPackage->fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; | ||
59 | break; | ||
60 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | ||
61 | execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
62 | break; | ||
63 | default: | ||
64 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
65 | break; | ||
66 | } | ||
67 | break; | ||
68 | |||
69 | case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: | ||
70 | switch (pPackage->requested) | ||
71 | { | ||
72 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; | ||
73 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
74 | execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; | ||
75 | break; | ||
76 | default: | ||
77 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
78 | break; | ||
79 | } | ||
80 | break; | ||
81 | |||
82 | default: | ||
83 | hr = E_INVALIDARG; | ||
84 | ExitOnRootFailure(hr, "Invalid package current state: %d.", pPackage->currentState); | ||
85 | } | ||
86 | |||
87 | // Calculate the rollback action if there is an execute action. | ||
88 | if (BOOTSTRAPPER_ACTION_STATE_NONE != execute) | ||
89 | { | ||
90 | switch (pPackage->currentState) | ||
91 | { | ||
92 | case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: | ||
93 | switch (pPackage->requested) | ||
94 | { | ||
95 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; | ||
96 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
97 | rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
98 | break; | ||
99 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: __fallthrough; | ||
100 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: | ||
101 | rollback = BOOTSTRAPPER_ACTION_STATE_INSTALL; | ||
102 | break; | ||
103 | default: | ||
104 | rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
105 | break; | ||
106 | } | ||
107 | break; | ||
108 | |||
109 | case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: | ||
110 | switch (pPackage->requested) | ||
111 | { | ||
112 | case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; | ||
113 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
114 | rollback = pPackage->fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; | ||
115 | break; | ||
116 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: __fallthrough; | ||
117 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: | ||
118 | rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
119 | break; | ||
120 | default: | ||
121 | rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
122 | break; | ||
123 | } | ||
124 | break; | ||
125 | |||
126 | default: | ||
127 | hr = E_INVALIDARG; | ||
128 | ExitOnRootFailure(hr, "Invalid package expected state."); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | // return values | ||
133 | pPackage->execute = execute; | ||
134 | pPackage->rollback = rollback; | ||
135 | |||
136 | LExit: | ||
137 | return hr; | ||
138 | } | ||
139 | |||
140 | // | ||
141 | // PlanAdd - adds the calculated execute and rollback actions for the package. | ||
142 | // | ||
143 | extern "C" HRESULT BundlePackageEnginePlanAddRelatedBundle( | ||
144 | __in_opt DWORD *pdwInsertSequence, | ||
145 | __in BURN_RELATED_BUNDLE* pRelatedBundle, | ||
146 | __in BURN_PLAN* pPlan, | ||
147 | __in BURN_LOGGING* pLog, | ||
148 | __in BURN_VARIABLES* pVariables | ||
149 | ) | ||
150 | { | ||
151 | HRESULT hr = S_OK; | ||
152 | BURN_EXECUTE_ACTION* pAction = NULL; | ||
153 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | ||
154 | |||
155 | hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan); | ||
156 | ExitOnFailure(hr, "Failed to plan package dependency actions."); | ||
157 | |||
158 | // add execute action | ||
159 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) | ||
160 | { | ||
161 | if (pdwInsertSequence) | ||
162 | { | ||
163 | hr = PlanInsertExecuteAction(*pdwInsertSequence, pPlan, &pAction); | ||
164 | ExitOnFailure(hr, "Failed to insert execute action."); | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | hr = PlanAppendExecuteAction(pPlan, &pAction); | ||
169 | ExitOnFailure(hr, "Failed to append execute action."); | ||
170 | } | ||
171 | |||
172 | pAction->type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; | ||
173 | pAction->relatedBundle.pRelatedBundle = pRelatedBundle; | ||
174 | pAction->relatedBundle.action = pPackage->execute; | ||
175 | |||
176 | if (pPackage->Bundle.sczIgnoreDependencies) | ||
177 | { | ||
178 | hr = StrAllocString(&pAction->relatedBundle.sczIgnoreDependencies, pPackage->Bundle.sczIgnoreDependencies, 0); | ||
179 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
180 | } | ||
181 | |||
182 | if (pPackage->Bundle.wzAncestors) | ||
183 | { | ||
184 | hr = StrAllocString(&pAction->relatedBundle.sczAncestors, pPackage->Bundle.wzAncestors, 0); | ||
185 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
186 | } | ||
187 | |||
188 | if (pPackage->Bundle.wzEngineWorkingDirectory) | ||
189 | { | ||
190 | hr = StrAllocString(&pAction->relatedBundle.sczEngineWorkingDirectory, pPackage->Bundle.wzEngineWorkingDirectory, 0); | ||
191 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
192 | } | ||
193 | |||
194 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. | ||
195 | } | ||
196 | |||
197 | // add rollback action | ||
198 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) | ||
199 | { | ||
200 | hr = PlanAppendRollbackAction(pPlan, &pAction); | ||
201 | ExitOnFailure(hr, "Failed to append rollback action."); | ||
202 | |||
203 | pAction->type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; | ||
204 | pAction->relatedBundle.pRelatedBundle = pRelatedBundle; | ||
205 | pAction->relatedBundle.action = pPackage->rollback; | ||
206 | |||
207 | if (pPackage->Bundle.sczIgnoreDependencies) | ||
208 | { | ||
209 | hr = StrAllocString(&pAction->relatedBundle.sczIgnoreDependencies, pPackage->Bundle.sczIgnoreDependencies, 0); | ||
210 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
211 | } | ||
212 | |||
213 | if (pPackage->Bundle.wzAncestors) | ||
214 | { | ||
215 | hr = StrAllocString(&pAction->relatedBundle.sczAncestors, pPackage->Bundle.wzAncestors, 0); | ||
216 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
217 | } | ||
218 | |||
219 | if (pPackage->Bundle.wzEngineWorkingDirectory) | ||
220 | { | ||
221 | hr = StrAllocString(&pAction->relatedBundle.sczEngineWorkingDirectory, pPackage->Bundle.wzEngineWorkingDirectory, 0); | ||
222 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
223 | } | ||
224 | |||
225 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. | ||
226 | } | ||
227 | |||
228 | LExit: | ||
229 | return hr; | ||
230 | } | ||
231 | |||
232 | extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle( | ||
233 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
234 | __in BURN_CACHE* pCache, | ||
235 | __in BURN_VARIABLES* pVariables, | ||
236 | __in BOOL fRollback, | ||
237 | __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, | ||
238 | __in LPVOID pvContext, | ||
239 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
240 | ) | ||
241 | { | ||
242 | HRESULT hr = S_OK; | ||
243 | int nResult = IDNOACTION; | ||
244 | LPCWSTR wzArguments = NULL; | ||
245 | LPWSTR sczArguments = NULL; | ||
246 | LPWSTR sczArgumentsFormatted = NULL; | ||
247 | LPWSTR sczArgumentsObfuscated = NULL; | ||
248 | LPWSTR sczCachedDirectory = NULL; | ||
249 | LPWSTR sczExecutablePath = NULL; | ||
250 | LPWSTR sczCommand = NULL; | ||
251 | LPWSTR sczCommandObfuscated = NULL; | ||
252 | HANDLE hExecutableFile = INVALID_HANDLE_VALUE; | ||
253 | STARTUPINFOW si = { }; | ||
254 | PROCESS_INFORMATION pi = { }; | ||
255 | DWORD dwExitCode = 0; | ||
256 | GENERIC_EXECUTE_MESSAGE message = { }; | ||
257 | BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action; | ||
258 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; | ||
259 | BOOTSTRAPPER_RELATION_TYPE relationType = pRelatedBundle->relationType; | ||
260 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | ||
261 | BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload; | ||
262 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); | ||
263 | LPCWSTR wzOperationCommandLine = NULL; | ||
264 | BOOL fRunEmbedded = pPackage->Bundle.fSupportsBurnProtocol; | ||
265 | |||
266 | // get cached executable path | ||
267 | hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory); | ||
268 | ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); | ||
269 | |||
270 | // Best effort to set the execute package cache folder and action variables. | ||
271 | VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE); | ||
272 | VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, action, TRUE); | ||
273 | |||
274 | hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath); | ||
275 | ExitOnFailure(hr, "Failed to build executable path."); | ||
276 | |||
277 | // pick arguments | ||
278 | switch (action) | ||
279 | { | ||
280 | case BOOTSTRAPPER_ACTION_STATE_INSTALL: | ||
281 | wzArguments = pPackage->Bundle.sczInstallArguments; | ||
282 | break; | ||
283 | |||
284 | case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: | ||
285 | wzOperationCommandLine = L"-uninstall"; | ||
286 | wzArguments = pPackage->Bundle.sczUninstallArguments; | ||
287 | break; | ||
288 | |||
289 | case BOOTSTRAPPER_ACTION_STATE_REPAIR: | ||
290 | wzOperationCommandLine = L"-repair"; | ||
291 | wzArguments = pPackage->Bundle.sczRepairArguments; | ||
292 | break; | ||
293 | |||
294 | default: | ||
295 | hr = E_INVALIDARG; | ||
296 | ExitOnFailure(hr, "Invalid Bundle package action: %d.", action); | ||
297 | } | ||
298 | |||
299 | // now add optional arguments | ||
300 | if (wzArguments && *wzArguments) | ||
301 | { | ||
302 | hr = StrAllocString(&sczArguments, wzArguments, 0); | ||
303 | ExitOnFailure(hr, "Failed to copy package arguments."); | ||
304 | } | ||
305 | |||
306 | for (DWORD i = 0; i < pPackage->Bundle.cCommandLineArguments; ++i) | ||
307 | { | ||
308 | BURN_EXE_COMMAND_LINE_ARGUMENT* commandLineArgument = &pPackage->Bundle.rgCommandLineArguments[i]; | ||
309 | BOOL fCondition = FALSE; | ||
310 | |||
311 | hr = ConditionEvaluate(pVariables, commandLineArgument->sczCondition, &fCondition); | ||
312 | ExitOnFailure(hr, "Failed to evaluate bundle package command-line condition."); | ||
313 | |||
314 | if (fCondition) | ||
315 | { | ||
316 | if (sczArguments) | ||
317 | { | ||
318 | hr = StrAllocConcat(&sczArguments, L" ", 0); | ||
319 | ExitOnFailure(hr, "Failed to separate command-line arguments."); | ||
320 | } | ||
321 | |||
322 | switch (action) | ||
323 | { | ||
324 | case BOOTSTRAPPER_ACTION_STATE_INSTALL: | ||
325 | hr = StrAllocConcat(&sczArguments, commandLineArgument->sczInstallArgument, 0); | ||
326 | ExitOnFailure(hr, "Failed to get command-line argument for install."); | ||
327 | break; | ||
328 | |||
329 | case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: | ||
330 | hr = StrAllocConcat(&sczArguments, commandLineArgument->sczUninstallArgument, 0); | ||
331 | ExitOnFailure(hr, "Failed to get command-line argument for uninstall."); | ||
332 | break; | ||
333 | |||
334 | case BOOTSTRAPPER_ACTION_STATE_REPAIR: | ||
335 | hr = StrAllocConcat(&sczArguments, commandLineArgument->sczRepairArgument, 0); | ||
336 | ExitOnFailure(hr, "Failed to get command-line argument for repair."); | ||
337 | break; | ||
338 | |||
339 | default: | ||
340 | hr = E_INVALIDARG; | ||
341 | ExitOnFailure(hr, "Invalid Bundle package action: %d.", action); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | |||
346 | // build command | ||
347 | AppAppendCommandLineArgument(&sczCommand, sczExecutablePath); | ||
348 | ExitOnFailure(hr, "Failed to create executable command."); | ||
349 | |||
350 | if (!fRunEmbedded) | ||
351 | { | ||
352 | hr = StrAllocConcat(&sczCommand, L" -quiet", 0); | ||
353 | ExitOnFailure(hr, "Failed to append quiet argument."); | ||
354 | } | ||
355 | |||
356 | if (wzOperationCommandLine) | ||
357 | { | ||
358 | hr = StrAllocConcatFormatted(&sczCommand, L" %ls", wzOperationCommandLine); | ||
359 | ExitOnFailure(hr, "Failed to append operation argument."); | ||
360 | } | ||
361 | |||
362 | if (wzRelationTypeCommandLine) | ||
363 | { | ||
364 | hr = StrAllocConcatFormatted(&sczCommand, L" -%ls", wzRelationTypeCommandLine); | ||
365 | ExitOnFailure(hr, "Failed to append relation type argument."); | ||
366 | } | ||
367 | |||
368 | // Add the list of dependencies to ignore, if any, to the burn command line. | ||
369 | if (pExecuteAction->relatedBundle.sczIgnoreDependencies) | ||
370 | { | ||
371 | hr = StrAllocConcatFormatted(&sczCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->relatedBundle.sczIgnoreDependencies); | ||
372 | ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line."); | ||
373 | } | ||
374 | |||
375 | // Add the list of ancestors, if any, to the burn command line. | ||
376 | if (pExecuteAction->relatedBundle.sczAncestors) | ||
377 | { | ||
378 | hr = StrAllocConcatFormatted(&sczCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->relatedBundle.sczAncestors); | ||
379 | ExitOnFailure(hr, "Failed to append the list of ancestors to the command line."); | ||
380 | } | ||
381 | |||
382 | hr = CoreAppendEngineWorkingDirectoryToCommandLine(pExecuteAction->relatedBundle.sczEngineWorkingDirectory, &sczCommand, NULL); | ||
383 | ExitOnFailure(hr, "Failed to append the custom working directory to the bundlepackage command line."); | ||
384 | |||
385 | hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, NULL); | ||
386 | ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); | ||
387 | |||
388 | // Always add user supplied arguments last. | ||
389 | if (sczArguments && *sczArguments) | ||
390 | { | ||
391 | hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL); | ||
392 | ExitOnFailure(hr, "Failed to format argument string."); | ||
393 | |||
394 | hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL); | ||
395 | ExitOnFailure(hr, "Failed to format obfuscated argument string."); | ||
396 | |||
397 | hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls %ls", sczCommand, sczArgumentsObfuscated); | ||
398 | ExitOnFailure(hr, "Failed to copy obfuscated formatted arguments."); | ||
399 | |||
400 | hr = StrAllocConcatFormattedSecure(&sczCommand, L" %ls", sczArgumentsFormatted); | ||
401 | ExitOnFailure(hr, "Failed to copy formatted arguments."); | ||
402 | } | ||
403 | |||
404 | // Log before we add the secret pipe name and client token for embedded processes. | ||
405 | LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(action), sczExecutablePath, sczCommandObfuscated); | ||
406 | |||
407 | if (fRunEmbedded) | ||
408 | { | ||
409 | hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); | ||
410 | ExitOnFailure(hr, "Failed to run bundle as embedded from path: %ls", sczExecutablePath); | ||
411 | } | ||
412 | else // create and wait for the executable process while sending fake progress to allow cancel. | ||
413 | { | ||
414 | // Make the cache location of the executable the current directory to help those executables | ||
415 | // that expect stuff to be relative to them. | ||
416 | si.cb = sizeof(si); | ||
417 | if (!::CreateProcessW(sczExecutablePath, sczCommand, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, sczCachedDirectory, &si, &pi)) | ||
418 | { | ||
419 | ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", sczExecutablePath); | ||
420 | } | ||
421 | |||
422 | do | ||
423 | { | ||
424 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; | ||
425 | message.dwUIHint = MB_OKCANCEL; | ||
426 | message.progress.dwPercentage = 50; | ||
427 | nResult = pfnGenericMessageHandler(&message, pvContext); | ||
428 | hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); | ||
429 | ExitOnRootFailure(hr, "Bootstrapper application aborted during BUNDLE progress."); | ||
430 | |||
431 | hr = ProcWaitForCompletion(pi.hProcess, 500, &dwExitCode); | ||
432 | if (HRESULT_FROM_WIN32(WAIT_TIMEOUT) != hr) | ||
433 | { | ||
434 | ExitOnFailure(hr, "Failed to wait for executable to complete: %ls", sczExecutablePath); | ||
435 | } | ||
436 | } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); | ||
437 | } | ||
438 | |||
439 | hr = ExeEngineHandleExitCode(pPackage->Bundle.rgExitCodes, pPackage->Bundle.cExitCodes, dwExitCode, pRestart); | ||
440 | ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode); | ||
441 | |||
442 | LExit: | ||
443 | StrSecureZeroFreeString(sczArguments); | ||
444 | StrSecureZeroFreeString(sczArgumentsFormatted); | ||
445 | ReleaseStr(sczArgumentsObfuscated); | ||
446 | ReleaseStr(sczCachedDirectory); | ||
447 | ReleaseStr(sczExecutablePath); | ||
448 | StrSecureZeroFreeString(sczCommand); | ||
449 | ReleaseStr(sczCommandObfuscated); | ||
450 | |||
451 | ReleaseHandle(pi.hThread); | ||
452 | ReleaseHandle(pi.hProcess); | ||
453 | ReleaseFileHandle(hExecutableFile); | ||
454 | |||
455 | // Best effort to clear the execute package cache folder and action variables. | ||
456 | VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE); | ||
457 | VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE, FALSE); | ||
458 | |||
459 | return hr; | ||
460 | } | ||
diff --git a/src/burn/engine/bundlepackageengine.h b/src/burn/engine/bundlepackageengine.h new file mode 100644 index 00000000..0d59907d --- /dev/null +++ b/src/burn/engine/bundlepackageengine.h | |||
@@ -0,0 +1,38 @@ | |||
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 | #if defined(__cplusplus) | ||
6 | extern "C" { | ||
7 | #endif | ||
8 | |||
9 | |||
10 | // function declarations | ||
11 | |||
12 | void BundlePackageEnginePackageUninitialize( | ||
13 | __in BURN_PACKAGE* pPackage | ||
14 | ); | ||
15 | HRESULT BundlePackageEnginePlanCalculatePackage( | ||
16 | __in BURN_PACKAGE* pPackage | ||
17 | ); | ||
18 | HRESULT BundlePackageEnginePlanAddRelatedBundle( | ||
19 | __in_opt DWORD *pdwInsertSequence, | ||
20 | __in BURN_RELATED_BUNDLE* pRelatedBundle, | ||
21 | __in BURN_PLAN* pPlan, | ||
22 | __in BURN_LOGGING* pLog, | ||
23 | __in BURN_VARIABLES* pVariables | ||
24 | ); | ||
25 | HRESULT BundlePackageEngineExecuteRelatedBundle( | ||
26 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
27 | __in BURN_CACHE* pCache, | ||
28 | __in BURN_VARIABLES* pVariables, | ||
29 | __in BOOL fRollback, | ||
30 | __in PFN_GENERICMESSAGEHANDLER pfnGenericExecuteProgress, | ||
31 | __in LPVOID pvContext, | ||
32 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
33 | ); | ||
34 | |||
35 | |||
36 | #if defined(__cplusplus) | ||
37 | } | ||
38 | #endif | ||
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 30c64b01..8a181e7c 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -228,11 +228,11 @@ extern "C" HRESULT CoreInitializeConstants( | |||
228 | { | 228 | { |
229 | BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i; | 229 | BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i; |
230 | 230 | ||
231 | if (BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) // TODO: Don't assume exePackages with burn protocol are bundles. | 231 | if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type) |
232 | { | 232 | { |
233 | // Pass along any ancestors and ourself to prevent infinite loops. | 233 | // Pass along any ancestors and ourself to prevent infinite loops. |
234 | pPackage->Exe.wzAncestors = pRegistration->sczBundlePackageAncestors; | 234 | pPackage->Bundle.wzAncestors = pRegistration->sczBundlePackageAncestors; |
235 | pPackage->Exe.wzEngineWorkingDirectory = pInternalCommand->sczEngineWorkingDirectory; | 235 | pPackage->Bundle.wzEngineWorkingDirectory = pInternalCommand->sczEngineWorkingDirectory; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
@@ -518,7 +518,7 @@ extern "C" HRESULT CorePlan( | |||
518 | ExitOnFailure(hr, "Failed to plan the layout of the bundle."); | 518 | ExitOnFailure(hr, "Failed to plan the layout of the bundle."); |
519 | 519 | ||
520 | // Plan the packages' layout. | 520 | // Plan the packages' layout. |
521 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); | 521 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables); |
522 | ExitOnFailure(hr, "Failed to plan packages."); | 522 | ExitOnFailure(hr, "Failed to plan packages."); |
523 | } | 523 | } |
524 | else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action) | 524 | else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action) |
@@ -527,7 +527,7 @@ extern "C" HRESULT CorePlan( | |||
527 | 527 | ||
528 | pUpgradeBundlePackage = &pEngineState->update.package; | 528 | pUpgradeBundlePackage = &pEngineState->update.package; |
529 | 529 | ||
530 | hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); | 530 | hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables); |
531 | ExitOnFailure(hr, "Failed to plan update."); | 531 | ExitOnFailure(hr, "Failed to plan update."); |
532 | } | 532 | } |
533 | else | 533 | else |
@@ -541,7 +541,7 @@ extern "C" HRESULT CorePlan( | |||
541 | 541 | ||
542 | pForwardCompatibleBundlePackage = &pEngineState->plan.forwardCompatibleBundle; | 542 | pForwardCompatibleBundlePackage = &pEngineState->plan.forwardCompatibleBundle; |
543 | 543 | ||
544 | hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); | 544 | hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables); |
545 | ExitOnFailure(hr, "Failed to plan passthrough."); | 545 | ExitOnFailure(hr, "Failed to plan passthrough."); |
546 | } | 546 | } |
547 | else // doing an action that modifies the machine state. | 547 | else // doing an action that modifies the machine state. |
@@ -562,7 +562,7 @@ extern "C" HRESULT CorePlan( | |||
562 | hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); | 562 | hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); |
563 | ExitOnFailure(hr, "Failed to plan related bundles."); | 563 | ExitOnFailure(hr, "Failed to plan related bundles."); |
564 | 564 | ||
565 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); | 565 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables); |
566 | ExitOnFailure(hr, "Failed to plan packages."); | 566 | ExitOnFailure(hr, "Failed to plan packages."); |
567 | 567 | ||
568 | // Schedule the update of related bundles last. | 568 | // Schedule the update of related bundles last. |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 6c4a775f..355b4a34 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -19,6 +19,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE | |||
19 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, | 19 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, |
20 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, | 20 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, |
21 | BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION, | 21 | BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION, |
22 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE, | ||
22 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, | 23 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, |
23 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, | 24 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, |
24 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, | 25 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, |
@@ -230,11 +231,18 @@ static HRESULT OnProcessDependentRegistration( | |||
230 | __in BYTE* pbData, | 231 | __in BYTE* pbData, |
231 | __in SIZE_T cbData | 232 | __in SIZE_T cbData |
232 | ); | 233 | ); |
234 | static HRESULT OnExecuteRelatedBundle( | ||
235 | __in HANDLE hPipe, | ||
236 | __in BURN_CACHE* pCache, | ||
237 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
238 | __in BURN_VARIABLES* pVariables, | ||
239 | __in BYTE* pbData, | ||
240 | __in SIZE_T cbData | ||
241 | ); | ||
233 | static HRESULT OnExecuteExePackage( | 242 | static HRESULT OnExecuteExePackage( |
234 | __in HANDLE hPipe, | 243 | __in HANDLE hPipe, |
235 | __in BURN_CACHE* pCache, | 244 | __in BURN_CACHE* pCache, |
236 | __in BURN_PACKAGES* pPackages, | 245 | __in BURN_PACKAGES* pPackages, |
237 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
238 | __in BURN_VARIABLES* pVariables, | 246 | __in BURN_VARIABLES* pVariables, |
239 | __in BYTE* pbData, | 247 | __in BYTE* pbData, |
240 | __in SIZE_T cbData | 248 | __in SIZE_T cbData |
@@ -818,10 +826,10 @@ LExit: | |||
818 | } | 826 | } |
819 | 827 | ||
820 | /******************************************************************* | 828 | /******************************************************************* |
821 | ElevationExecuteExePackage - | 829 | ElevationExecuteRelatedBundle - |
822 | 830 | ||
823 | *******************************************************************/ | 831 | *******************************************************************/ |
824 | extern "C" HRESULT ElevationExecuteExePackage( | 832 | extern "C" HRESULT ElevationExecuteRelatedBundle( |
825 | __in HANDLE hPipe, | 833 | __in HANDLE hPipe, |
826 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 834 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
827 | __in BURN_VARIABLES* pVariables, | 835 | __in BURN_VARIABLES* pVariables, |
@@ -838,22 +846,22 @@ extern "C" HRESULT ElevationExecuteExePackage( | |||
838 | DWORD dwResult = 0; | 846 | DWORD dwResult = 0; |
839 | 847 | ||
840 | // serialize message data | 848 | // serialize message data |
841 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.pPackage->sczId); | 849 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.pRelatedBundle->package.sczId); |
842 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | 850 | ExitOnFailure(hr, "Failed to write package id to message buffer."); |
843 | 851 | ||
844 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->exePackage.action); | 852 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.action); |
845 | ExitOnFailure(hr, "Failed to write action to message buffer."); | 853 | ExitOnFailure(hr, "Failed to write action to message buffer."); |
846 | 854 | ||
847 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); | 855 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); |
848 | ExitOnFailure(hr, "Failed to write rollback."); | 856 | ExitOnFailure(hr, "Failed to write rollback."); |
849 | 857 | ||
850 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczIgnoreDependencies); | 858 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczIgnoreDependencies); |
851 | ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer."); | 859 | ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer."); |
852 | 860 | ||
853 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczAncestors); | 861 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczAncestors); |
854 | ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer."); | 862 | ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer."); |
855 | 863 | ||
856 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczEngineWorkingDirectory); | 864 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczEngineWorkingDirectory); |
857 | ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer."); | 865 | ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer."); |
858 | 866 | ||
859 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | 867 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); |
@@ -863,6 +871,54 @@ extern "C" HRESULT ElevationExecuteExePackage( | |||
863 | context.pfnGenericMessageHandler = pfnGenericMessageHandler; | 871 | context.pfnGenericMessageHandler = pfnGenericMessageHandler; |
864 | context.pvContext = pvContext; | 872 | context.pvContext = pvContext; |
865 | 873 | ||
874 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult); | ||
875 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE message to per-machine process."); | ||
876 | |||
877 | hr = ProcessResult(dwResult, pRestart); | ||
878 | |||
879 | LExit: | ||
880 | ReleaseBuffer(pbData); | ||
881 | |||
882 | return hr; | ||
883 | } | ||
884 | |||
885 | /******************************************************************* | ||
886 | ElevationExecuteExePackage - | ||
887 | |||
888 | *******************************************************************/ | ||
889 | extern "C" HRESULT ElevationExecuteExePackage( | ||
890 | __in HANDLE hPipe, | ||
891 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
892 | __in BURN_VARIABLES* pVariables, | ||
893 | __in BOOL fRollback, | ||
894 | __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, | ||
895 | __in LPVOID pvContext, | ||
896 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
897 | ) | ||
898 | { | ||
899 | HRESULT hr = S_OK; | ||
900 | BYTE* pbData = NULL; | ||
901 | SIZE_T cbData = 0; | ||
902 | BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { }; | ||
903 | DWORD dwResult = 0; | ||
904 | |||
905 | // serialize message data | ||
906 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.pPackage->sczId); | ||
907 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
908 | |||
909 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->exePackage.action); | ||
910 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
911 | |||
912 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); | ||
913 | ExitOnFailure(hr, "Failed to write rollback."); | ||
914 | |||
915 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
916 | ExitOnFailure(hr, "Failed to write variables."); | ||
917 | |||
918 | // send message | ||
919 | context.pfnGenericMessageHandler = pfnGenericMessageHandler; | ||
920 | context.pvContext = pvContext; | ||
921 | |||
866 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult); | 922 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult); |
867 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE message to per-machine process."); | 923 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE message to per-machine process."); |
868 | 924 | ||
@@ -1911,8 +1967,12 @@ static HRESULT ProcessElevatedChildMessage( | |||
1911 | hrResult = OnProcessDependentRegistration(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData); | 1967 | hrResult = OnProcessDependentRegistration(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData); |
1912 | break; | 1968 | break; |
1913 | 1969 | ||
1970 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE: | ||
1971 | hrResult = OnExecuteRelatedBundle(pContext->hPipe, pContext->pCache, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1972 | break; | ||
1973 | |||
1914 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE: | 1974 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE: |
1915 | hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | 1975 | hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); |
1916 | break; | 1976 | break; |
1917 | 1977 | ||
1918 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE: | 1978 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE: |
@@ -2473,10 +2533,9 @@ LExit: | |||
2473 | return hr; | 2533 | return hr; |
2474 | } | 2534 | } |
2475 | 2535 | ||
2476 | static HRESULT OnExecuteExePackage( | 2536 | static HRESULT OnExecuteRelatedBundle( |
2477 | __in HANDLE hPipe, | 2537 | __in HANDLE hPipe, |
2478 | __in BURN_CACHE* pCache, | 2538 | __in BURN_CACHE* pCache, |
2479 | __in BURN_PACKAGES* pPackages, | ||
2480 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | 2539 | __in BURN_RELATED_BUNDLES* pRelatedBundles, |
2481 | __in BURN_VARIABLES* pVariables, | 2540 | __in BURN_VARIABLES* pVariables, |
2482 | __in BYTE* pbData, | 2541 | __in BYTE* pbData, |
@@ -2491,15 +2550,15 @@ static HRESULT OnExecuteExePackage( | |||
2491 | LPWSTR sczIgnoreDependencies = NULL; | 2550 | LPWSTR sczIgnoreDependencies = NULL; |
2492 | LPWSTR sczAncestors = NULL; | 2551 | LPWSTR sczAncestors = NULL; |
2493 | LPWSTR sczEngineWorkingDirectory = NULL; | 2552 | LPWSTR sczEngineWorkingDirectory = NULL; |
2494 | BOOTSTRAPPER_APPLY_RESTART exeRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | 2553 | BOOTSTRAPPER_APPLY_RESTART bundleRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; |
2495 | 2554 | ||
2496 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | 2555 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; |
2497 | 2556 | ||
2498 | // Deserialize message data. | 2557 | // Deserialize message data. |
2499 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | 2558 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); |
2500 | ExitOnFailure(hr, "Failed to read EXE package id."); | 2559 | ExitOnFailure(hr, "Failed to read related bundle id."); |
2501 | 2560 | ||
2502 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.exePackage.action); | 2561 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.relatedBundle.action); |
2503 | ExitOnFailure(hr, "Failed to read action."); | 2562 | ExitOnFailure(hr, "Failed to read action."); |
2504 | 2563 | ||
2505 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); | 2564 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); |
@@ -2517,36 +2576,32 @@ static HRESULT OnExecuteExePackage( | |||
2517 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | 2576 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); |
2518 | ExitOnFailure(hr, "Failed to read variables."); | 2577 | ExitOnFailure(hr, "Failed to read variables."); |
2519 | 2578 | ||
2520 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); | 2579 | hr = RelatedBundleFindById(pRelatedBundles, sczPackage, &executeAction.relatedBundle.pRelatedBundle); |
2521 | if (E_NOTFOUND == hr) | 2580 | ExitOnFailure(hr, "Failed to find related bundle: %ls", sczPackage); |
2522 | { | ||
2523 | hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.exePackage.pPackage); | ||
2524 | } | ||
2525 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2526 | 2581 | ||
2527 | // Pass the list of dependencies to ignore, if any, to the related bundle. | 2582 | // Pass the list of dependencies to ignore, if any, to the related bundle. |
2528 | if (sczIgnoreDependencies && *sczIgnoreDependencies) | 2583 | if (sczIgnoreDependencies && *sczIgnoreDependencies) |
2529 | { | 2584 | { |
2530 | hr = StrAllocString(&executeAction.exePackage.sczIgnoreDependencies, sczIgnoreDependencies, 0); | 2585 | hr = StrAllocString(&executeAction.relatedBundle.sczIgnoreDependencies, sczIgnoreDependencies, 0); |
2531 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | 2586 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); |
2532 | } | 2587 | } |
2533 | 2588 | ||
2534 | // Pass the list of ancestors, if any, to the related bundle. | 2589 | // Pass the list of ancestors, if any, to the related bundle. |
2535 | if (sczAncestors && *sczAncestors) | 2590 | if (sczAncestors && *sczAncestors) |
2536 | { | 2591 | { |
2537 | hr = StrAllocString(&executeAction.exePackage.sczAncestors, sczAncestors, 0); | 2592 | hr = StrAllocString(&executeAction.relatedBundle.sczAncestors, sczAncestors, 0); |
2538 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | 2593 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); |
2539 | } | 2594 | } |
2540 | 2595 | ||
2541 | if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory) | 2596 | if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory) |
2542 | { | 2597 | { |
2543 | hr = StrAllocString(&executeAction.exePackage.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0); | 2598 | hr = StrAllocString(&executeAction.relatedBundle.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0); |
2544 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | 2599 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); |
2545 | } | 2600 | } |
2546 | 2601 | ||
2547 | // Execute EXE package. | 2602 | // Execute related bundle. |
2548 | hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); | 2603 | hr = BundlePackageEngineExecuteRelatedBundle(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &bundleRestart); |
2549 | ExitOnFailure(hr, "Failed to execute EXE package."); | 2604 | ExitOnFailure(hr, "Failed to execute related bundle."); |
2550 | 2605 | ||
2551 | LExit: | 2606 | LExit: |
2552 | ReleaseStr(sczEngineWorkingDirectory); | 2607 | ReleaseStr(sczEngineWorkingDirectory); |
@@ -2557,6 +2612,63 @@ LExit: | |||
2557 | 2612 | ||
2558 | if (SUCCEEDED(hr)) | 2613 | if (SUCCEEDED(hr)) |
2559 | { | 2614 | { |
2615 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == bundleRestart) | ||
2616 | { | ||
2617 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
2618 | } | ||
2619 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == bundleRestart) | ||
2620 | { | ||
2621 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
2622 | } | ||
2623 | } | ||
2624 | |||
2625 | return hr; | ||
2626 | } | ||
2627 | |||
2628 | static HRESULT OnExecuteExePackage( | ||
2629 | __in HANDLE hPipe, | ||
2630 | __in BURN_CACHE* pCache, | ||
2631 | __in BURN_PACKAGES* pPackages, | ||
2632 | __in BURN_VARIABLES* pVariables, | ||
2633 | __in BYTE* pbData, | ||
2634 | __in SIZE_T cbData | ||
2635 | ) | ||
2636 | { | ||
2637 | HRESULT hr = S_OK; | ||
2638 | SIZE_T iData = 0; | ||
2639 | LPWSTR sczPackage = NULL; | ||
2640 | DWORD dwRollback = 0; | ||
2641 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2642 | BOOTSTRAPPER_APPLY_RESTART exeRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
2643 | |||
2644 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | ||
2645 | |||
2646 | // Deserialize message data. | ||
2647 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2648 | ExitOnFailure(hr, "Failed to read EXE package id."); | ||
2649 | |||
2650 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.exePackage.action); | ||
2651 | ExitOnFailure(hr, "Failed to read action."); | ||
2652 | |||
2653 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); | ||
2654 | ExitOnFailure(hr, "Failed to read rollback."); | ||
2655 | |||
2656 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2657 | ExitOnFailure(hr, "Failed to read variables."); | ||
2658 | |||
2659 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); | ||
2660 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2661 | |||
2662 | // Execute EXE package. | ||
2663 | hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); | ||
2664 | ExitOnFailure(hr, "Failed to execute EXE package."); | ||
2665 | |||
2666 | LExit: | ||
2667 | ReleaseStr(sczPackage); | ||
2668 | PlanUninitializeExecuteAction(&executeAction); | ||
2669 | |||
2670 | if (SUCCEEDED(hr)) | ||
2671 | { | ||
2560 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == exeRestart) | 2672 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == exeRestart) |
2561 | { | 2673 | { |
2562 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | 2674 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); |
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h index ad1141bb..0e63c687 100644 --- a/src/burn/engine/elevation.h +++ b/src/burn/engine/elevation.h | |||
@@ -80,6 +80,15 @@ HRESULT ElevationProcessDependentRegistration( | |||
80 | __in HANDLE hPipe, | 80 | __in HANDLE hPipe, |
81 | __in const BURN_DEPENDENT_REGISTRATION_ACTION* pAction | 81 | __in const BURN_DEPENDENT_REGISTRATION_ACTION* pAction |
82 | ); | 82 | ); |
83 | HRESULT ElevationExecuteRelatedBundle( | ||
84 | __in HANDLE hPipe, | ||
85 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
86 | __in BURN_VARIABLES* pVariables, | ||
87 | __in BOOL fRollback, | ||
88 | __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, | ||
89 | __in LPVOID pvContext, | ||
90 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
91 | ); | ||
83 | HRESULT ElevationExecuteExePackage( | 92 | HRESULT ElevationExecuteExePackage( |
84 | __in HANDLE hPipe, | 93 | __in HANDLE hPipe, |
85 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 94 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
diff --git a/src/burn/engine/engine.vcxproj b/src/burn/engine/engine.vcxproj index 3d6ed181..5c4860f1 100644 --- a/src/burn/engine/engine.vcxproj +++ b/src/burn/engine/engine.vcxproj | |||
@@ -52,6 +52,7 @@ | |||
52 | <ItemGroup> | 52 | <ItemGroup> |
53 | <ClCompile Include="apply.cpp" /> | 53 | <ClCompile Include="apply.cpp" /> |
54 | <ClCompile Include="approvedexe.cpp" /> | 54 | <ClCompile Include="approvedexe.cpp" /> |
55 | <ClCompile Include="bundlepackageengine.cpp" /> | ||
55 | <ClCompile Include="burnextension.cpp" /> | 56 | <ClCompile Include="burnextension.cpp" /> |
56 | <ClCompile Include="detect.cpp" /> | 57 | <ClCompile Include="detect.cpp" /> |
57 | <ClCompile Include="embedded.cpp" /> | 58 | <ClCompile Include="embedded.cpp" /> |
@@ -101,6 +102,7 @@ | |||
101 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BootstrapperEngine.h" /> | 102 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BootstrapperEngine.h" /> |
102 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BundleExtension.h" /> | 103 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BundleExtension.h" /> |
103 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BundleExtensionEngine.h" /> | 104 | <ClInclude Include="..\..\api\burn\WixToolset.BootstrapperCore.Native\inc\BundleExtensionEngine.h" /> |
105 | <ClInclude Include="bundlepackageengine.h" /> | ||
104 | <ClInclude Include="burnextension.h" /> | 106 | <ClInclude Include="burnextension.h" /> |
105 | <ClInclude Include="cabextract.h" /> | 107 | <ClInclude Include="cabextract.h" /> |
106 | <ClInclude Include="cache.h" /> | 108 | <ClInclude Include="cache.h" /> |
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index b728f599..45349ed0 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp | |||
@@ -3,23 +3,6 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | 5 | ||
6 | // internal function declarations | ||
7 | |||
8 | static HRESULT HandleExitCode( | ||
9 | __in BURN_PACKAGE* pPackage, | ||
10 | __in DWORD dwExitCode, | ||
11 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
12 | ); | ||
13 | static HRESULT ParseCommandLineArgumentsFromXml( | ||
14 | __in IXMLDOMNode* pixnExePackage, | ||
15 | __in BURN_PACKAGE* pPackage | ||
16 | ); | ||
17 | static HRESULT ParseExitCodesFromXml( | ||
18 | __in IXMLDOMNode* pixnExePackage, | ||
19 | __in BURN_PACKAGE* pPackage | ||
20 | ); | ||
21 | |||
22 | |||
23 | // function definitions | 6 | // function definitions |
24 | 7 | ||
25 | extern "C" HRESULT ExeEngineParsePackageFromXml( | 8 | extern "C" HRESULT ExeEngineParsePackageFromXml( |
@@ -82,10 +65,10 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( | |||
82 | ExitOnFailure(hr, "Failed to get @Protocol."); | 65 | ExitOnFailure(hr, "Failed to get @Protocol."); |
83 | } | 66 | } |
84 | 67 | ||
85 | hr = ParseExitCodesFromXml(pixnExePackage, pPackage); | 68 | hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes); |
86 | ExitOnFailure(hr, "Failed to parse exit codes."); | 69 | ExitOnFailure(hr, "Failed to parse exit codes."); |
87 | 70 | ||
88 | hr = ParseCommandLineArgumentsFromXml(pixnExePackage, pPackage); | 71 | hr = ExeEngineParseCommandLineArgumentsFromXml(pixnExePackage, &pPackage->Exe.rgCommandLineArguments, &pPackage->Exe.cCommandLineArguments); |
89 | ExitOnFailure(hr, "Failed to parse command lines."); | 72 | ExitOnFailure(hr, "Failed to parse command lines."); |
90 | 73 | ||
91 | LExit: | 74 | LExit: |
@@ -104,8 +87,6 @@ extern "C" void ExeEnginePackageUninitialize( | |||
104 | ReleaseStr(pPackage->Exe.sczInstallArguments); | 87 | ReleaseStr(pPackage->Exe.sczInstallArguments); |
105 | ReleaseStr(pPackage->Exe.sczRepairArguments); | 88 | ReleaseStr(pPackage->Exe.sczRepairArguments); |
106 | ReleaseStr(pPackage->Exe.sczUninstallArguments); | 89 | ReleaseStr(pPackage->Exe.sczUninstallArguments); |
107 | ReleaseStr(pPackage->Exe.sczIgnoreDependencies); | ||
108 | //ReleaseStr(pPackage->Exe.sczProgressSwitch); | ||
109 | ReleaseMem(pPackage->Exe.rgExitCodes); | 90 | ReleaseMem(pPackage->Exe.rgExitCodes); |
110 | 91 | ||
111 | // free command-line arguments | 92 | // free command-line arguments |
@@ -113,11 +94,7 @@ extern "C" void ExeEnginePackageUninitialize( | |||
113 | { | 94 | { |
114 | for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i) | 95 | for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i) |
115 | { | 96 | { |
116 | BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = &pPackage->Exe.rgCommandLineArguments[i]; | 97 | ExeEngineCommandLineArgumentUninitialize(pPackage->Exe.rgCommandLineArguments + i); |
117 | ReleaseStr(pCommandLineArgument->sczInstallArgument); | ||
118 | ReleaseStr(pCommandLineArgument->sczUninstallArgument); | ||
119 | ReleaseStr(pCommandLineArgument->sczRepairArgument); | ||
120 | ReleaseStr(pCommandLineArgument->sczCondition); | ||
121 | } | 98 | } |
122 | MemFree(pPackage->Exe.rgCommandLineArguments); | 99 | MemFree(pPackage->Exe.rgCommandLineArguments); |
123 | } | 100 | } |
@@ -126,6 +103,16 @@ extern "C" void ExeEnginePackageUninitialize( | |||
126 | memset(&pPackage->Exe, 0, sizeof(pPackage->Exe)); | 103 | memset(&pPackage->Exe, 0, sizeof(pPackage->Exe)); |
127 | } | 104 | } |
128 | 105 | ||
106 | extern "C" void ExeEngineCommandLineArgumentUninitialize( | ||
107 | __in BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument | ||
108 | ) | ||
109 | { | ||
110 | ReleaseStr(pCommandLineArgument->sczInstallArgument); | ||
111 | ReleaseStr(pCommandLineArgument->sczUninstallArgument); | ||
112 | ReleaseStr(pCommandLineArgument->sczRepairArgument); | ||
113 | ReleaseStr(pCommandLineArgument->sczCondition); | ||
114 | } | ||
115 | |||
129 | extern "C" HRESULT ExeEngineDetectPackage( | 116 | extern "C" HRESULT ExeEngineDetectPackage( |
130 | __in BURN_PACKAGE* pPackage, | 117 | __in BURN_PACKAGE* pPackage, |
131 | __in BURN_VARIABLES* pVariables | 118 | __in BURN_VARIABLES* pVariables |
@@ -264,7 +251,6 @@ LExit: | |||
264 | // PlanAdd - adds the calculated execute and rollback actions for the package. | 251 | // PlanAdd - adds the calculated execute and rollback actions for the package. |
265 | // | 252 | // |
266 | extern "C" HRESULT ExeEnginePlanAddPackage( | 253 | extern "C" HRESULT ExeEnginePlanAddPackage( |
267 | __in_opt DWORD *pdwInsertSequence, | ||
268 | __in BURN_PACKAGE* pPackage, | 254 | __in BURN_PACKAGE* pPackage, |
269 | __in BURN_PLAN* pPlan, | 255 | __in BURN_PLAN* pPlan, |
270 | __in BURN_LOGGING* pLog, | 256 | __in BURN_LOGGING* pLog, |
@@ -274,46 +260,19 @@ extern "C" HRESULT ExeEnginePlanAddPackage( | |||
274 | HRESULT hr = S_OK; | 260 | HRESULT hr = S_OK; |
275 | BURN_EXECUTE_ACTION* pAction = NULL; | 261 | BURN_EXECUTE_ACTION* pAction = NULL; |
276 | 262 | ||
277 | hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan); | 263 | hr = DependencyPlanPackage(NULL, pPackage, pPlan); |
278 | ExitOnFailure(hr, "Failed to plan package dependency actions."); | 264 | ExitOnFailure(hr, "Failed to plan package dependency actions."); |
279 | 265 | ||
280 | // add execute action | 266 | // add execute action |
281 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) | 267 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) |
282 | { | 268 | { |
283 | if (NULL != pdwInsertSequence) | 269 | hr = PlanAppendExecuteAction(pPlan, &pAction); |
284 | { | 270 | ExitOnFailure(hr, "Failed to append execute action."); |
285 | hr = PlanInsertExecuteAction(*pdwInsertSequence, pPlan, &pAction); | ||
286 | ExitOnFailure(hr, "Failed to insert execute action."); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | hr = PlanAppendExecuteAction(pPlan, &pAction); | ||
291 | ExitOnFailure(hr, "Failed to append execute action."); | ||
292 | } | ||
293 | 271 | ||
294 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | 272 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; |
295 | pAction->exePackage.pPackage = pPackage; | 273 | pAction->exePackage.pPackage = pPackage; |
296 | pAction->exePackage.fFireAndForget = (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == pPlan->action); | ||
297 | pAction->exePackage.action = pPackage->execute; | 274 | pAction->exePackage.action = pPackage->execute; |
298 | 275 | ||
299 | if (pPackage->Exe.sczIgnoreDependencies) | ||
300 | { | ||
301 | hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0); | ||
302 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
303 | } | ||
304 | |||
305 | if (pPackage->Exe.wzAncestors) | ||
306 | { | ||
307 | hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0); | ||
308 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
309 | } | ||
310 | |||
311 | if (pPackage->Exe.wzEngineWorkingDirectory) | ||
312 | { | ||
313 | hr = StrAllocString(&pAction->exePackage.sczEngineWorkingDirectory, pPackage->Exe.wzEngineWorkingDirectory, 0); | ||
314 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
315 | } | ||
316 | |||
317 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. | 276 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. |
318 | } | 277 | } |
319 | 278 | ||
@@ -327,18 +286,6 @@ extern "C" HRESULT ExeEnginePlanAddPackage( | |||
327 | pAction->exePackage.pPackage = pPackage; | 286 | pAction->exePackage.pPackage = pPackage; |
328 | pAction->exePackage.action = pPackage->rollback; | 287 | pAction->exePackage.action = pPackage->rollback; |
329 | 288 | ||
330 | if (pPackage->Exe.sczIgnoreDependencies) | ||
331 | { | ||
332 | hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0); | ||
333 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
334 | } | ||
335 | |||
336 | if (pPackage->Exe.wzAncestors) | ||
337 | { | ||
338 | hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0); | ||
339 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
340 | } | ||
341 | |||
342 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. | 289 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. |
343 | } | 290 | } |
344 | 291 | ||
@@ -452,13 +399,13 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
452 | hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL); | 399 | hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL); |
453 | ExitOnFailure(hr, "Failed to format argument string."); | 400 | ExitOnFailure(hr, "Failed to format argument string."); |
454 | 401 | ||
455 | hr = StrAllocFormattedSecure(&sczCommand, L"\"%ls\" %s", sczExecutablePath, sczArgumentsFormatted); | 402 | hr = StrAllocFormattedSecure(&sczCommand, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsFormatted); |
456 | ExitOnFailure(hr, "Failed to create executable command."); | 403 | ExitOnFailure(hr, "Failed to create executable command."); |
457 | 404 | ||
458 | hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL); | 405 | hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL); |
459 | ExitOnFailure(hr, "Failed to format obfuscated argument string."); | 406 | ExitOnFailure(hr, "Failed to format obfuscated argument string."); |
460 | 407 | ||
461 | hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\" %s", sczExecutablePath, sczArgumentsObfuscated); | 408 | hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsObfuscated); |
462 | } | 409 | } |
463 | else | 410 | else |
464 | { | 411 | { |
@@ -469,47 +416,15 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
469 | } | 416 | } |
470 | ExitOnFailure(hr, "Failed to create obfuscated executable command."); | 417 | ExitOnFailure(hr, "Failed to create obfuscated executable command."); |
471 | 418 | ||
472 | if (pPackage->Exe.fSupportsAncestors) | ||
473 | { | ||
474 | // Add the list of dependencies to ignore, if any, to the burn command line. | ||
475 | if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) | ||
476 | { | ||
477 | hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies); | ||
478 | ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line."); | ||
479 | |||
480 | hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls -%ls=%ls", sczCommandObfuscated, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies); | ||
481 | ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the obfuscated command line."); | ||
482 | } | ||
483 | |||
484 | // Add the list of ancestors, if any, to the burn command line. | ||
485 | if (pExecuteAction->exePackage.sczAncestors) | ||
486 | { | ||
487 | hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->exePackage.sczAncestors); | ||
488 | ExitOnFailure(hr, "Failed to append the list of ancestors to the command line."); | ||
489 | |||
490 | hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls -%ls=%ls", sczCommandObfuscated, BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->exePackage.sczAncestors); | ||
491 | ExitOnFailure(hr, "Failed to append the list of ancestors to the obfuscated command line."); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | if (BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) | ||
496 | { | ||
497 | hr = CoreAppendEngineWorkingDirectoryToCommandLine(pExecuteAction->exePackage.sczEngineWorkingDirectory, &sczCommand, &sczCommandObfuscated); | ||
498 | ExitOnFailure(hr, "Failed to append the custom working directory to the exepackage command line."); | ||
499 | |||
500 | hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, &sczCommandObfuscated); | ||
501 | ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); | ||
502 | } | ||
503 | |||
504 | // Log before we add the secret pipe name and client token for embedded processes. | 419 | // Log before we add the secret pipe name and client token for embedded processes. |
505 | LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated); | 420 | LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated); |
506 | 421 | ||
507 | if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) | 422 | if (!pPackage->Exe.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) |
508 | { | 423 | { |
509 | hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); | 424 | hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); |
510 | ExitOnFailure(hr, "Failed to run bundle as embedded from path: %ls", sczExecutablePath); | 425 | ExitOnFailure(hr, "Failed to run exe with Burn protocol from path: %ls", sczExecutablePath); |
511 | } | 426 | } |
512 | else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol) | 427 | else if (!pPackage->Exe.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol) |
513 | { | 428 | { |
514 | hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); | 429 | hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); |
515 | ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath); | 430 | ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath); |
@@ -524,7 +439,7 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
524 | ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", sczExecutablePath); | 439 | ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", sczExecutablePath); |
525 | } | 440 | } |
526 | 441 | ||
527 | if (pExecuteAction->exePackage.fFireAndForget) | 442 | if (pPackage->Exe.fFireAndForget) |
528 | { | 443 | { |
529 | ::WaitForInputIdle(pi.hProcess, 5000); | 444 | ::WaitForInputIdle(pi.hProcess, 5000); |
530 | ExitFunction(); | 445 | ExitFunction(); |
@@ -547,7 +462,7 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
547 | } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); | 462 | } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); |
548 | } | 463 | } |
549 | 464 | ||
550 | hr = HandleExitCode(pPackage, dwExitCode, pRestart); | 465 | hr = ExeEngineHandleExitCode(pPackage->Exe.rgExitCodes, pPackage->Exe.cExitCodes, dwExitCode, pRestart); |
551 | ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode); | 466 | ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode); |
552 | 467 | ||
553 | LExit: | 468 | LExit: |
@@ -595,12 +510,10 @@ LExit: | |||
595 | return; | 510 | return; |
596 | } | 511 | } |
597 | 512 | ||
598 | 513 | extern "C" HRESULT ExeEngineParseExitCodesFromXml( | |
599 | // internal helper functions | 514 | __in IXMLDOMNode* pixnPackage, |
600 | 515 | __inout BURN_EXE_EXIT_CODE** prgExitCodes, | |
601 | static HRESULT ParseExitCodesFromXml( | 516 | __inout DWORD* pcExitCodes |
602 | __in IXMLDOMNode* pixnExePackage, | ||
603 | __in BURN_PACKAGE* pPackage | ||
604 | ) | 517 | ) |
605 | { | 518 | { |
606 | HRESULT hr = S_OK; | 519 | HRESULT hr = S_OK; |
@@ -610,7 +523,7 @@ static HRESULT ParseExitCodesFromXml( | |||
610 | LPWSTR scz = NULL; | 523 | LPWSTR scz = NULL; |
611 | 524 | ||
612 | // select exit code nodes | 525 | // select exit code nodes |
613 | hr = XmlSelectNodes(pixnExePackage, L"ExitCode", &pixnNodes); | 526 | hr = XmlSelectNodes(pixnPackage, L"ExitCode", &pixnNodes); |
614 | ExitOnFailure(hr, "Failed to select exit code nodes."); | 527 | ExitOnFailure(hr, "Failed to select exit code nodes."); |
615 | 528 | ||
616 | // get exit code node count | 529 | // get exit code node count |
@@ -620,15 +533,15 @@ static HRESULT ParseExitCodesFromXml( | |||
620 | if (cNodes) | 533 | if (cNodes) |
621 | { | 534 | { |
622 | // allocate memory for exit codes | 535 | // allocate memory for exit codes |
623 | pPackage->Exe.rgExitCodes = (BURN_EXE_EXIT_CODE*) MemAlloc(sizeof(BURN_EXE_EXIT_CODE) * cNodes, TRUE); | 536 | *prgExitCodes = (BURN_EXE_EXIT_CODE*) MemAlloc(sizeof(BURN_EXE_EXIT_CODE) * cNodes, TRUE); |
624 | ExitOnNull(pPackage->Exe.rgExitCodes, hr, E_OUTOFMEMORY, "Failed to allocate memory for exit code structs."); | 537 | ExitOnNull(*prgExitCodes, hr, E_OUTOFMEMORY, "Failed to allocate memory for exit code structs."); |
625 | 538 | ||
626 | pPackage->Exe.cExitCodes = cNodes; | 539 | *pcExitCodes = cNodes; |
627 | 540 | ||
628 | // parse package elements | 541 | // parse package elements |
629 | for (DWORD i = 0; i < cNodes; ++i) | 542 | for (DWORD i = 0; i < cNodes; ++i) |
630 | { | 543 | { |
631 | BURN_EXE_EXIT_CODE* pExitCode = &pPackage->Exe.rgExitCodes[i]; | 544 | BURN_EXE_EXIT_CODE* pExitCode = *prgExitCodes + i; |
632 | 545 | ||
633 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); | 546 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); |
634 | ExitOnFailure(hr, "Failed to get next node."); | 547 | ExitOnFailure(hr, "Failed to get next node."); |
@@ -666,9 +579,10 @@ LExit: | |||
666 | return hr; | 579 | return hr; |
667 | } | 580 | } |
668 | 581 | ||
669 | static HRESULT ParseCommandLineArgumentsFromXml( | 582 | extern "C" HRESULT ExeEngineParseCommandLineArgumentsFromXml( |
670 | __in IXMLDOMNode* pixnExePackage, | 583 | __in IXMLDOMNode* pixnPackage, |
671 | __in BURN_PACKAGE* pPackage | 584 | __inout BURN_EXE_COMMAND_LINE_ARGUMENT** prgCommandLineArguments, |
585 | __inout DWORD* pcCommandLineArguments | ||
672 | ) | 586 | ) |
673 | { | 587 | { |
674 | HRESULT hr = S_OK; | 588 | HRESULT hr = S_OK; |
@@ -678,7 +592,7 @@ static HRESULT ParseCommandLineArgumentsFromXml( | |||
678 | LPWSTR scz = NULL; | 592 | LPWSTR scz = NULL; |
679 | 593 | ||
680 | // Select command-line argument nodes. | 594 | // Select command-line argument nodes. |
681 | hr = XmlSelectNodes(pixnExePackage, L"CommandLine", &pixnNodes); | 595 | hr = XmlSelectNodes(pixnPackage, L"CommandLine", &pixnNodes); |
682 | ExitOnFailure(hr, "Failed to select command-line argument nodes."); | 596 | ExitOnFailure(hr, "Failed to select command-line argument nodes."); |
683 | 597 | ||
684 | // Get command-line argument node count. | 598 | // Get command-line argument node count. |
@@ -687,15 +601,15 @@ static HRESULT ParseCommandLineArgumentsFromXml( | |||
687 | 601 | ||
688 | if (cNodes) | 602 | if (cNodes) |
689 | { | 603 | { |
690 | pPackage->Exe.rgCommandLineArguments = (BURN_EXE_COMMAND_LINE_ARGUMENT*) MemAlloc(sizeof(BURN_EXE_COMMAND_LINE_ARGUMENT) * cNodes, TRUE); | 604 | *prgCommandLineArguments = (BURN_EXE_COMMAND_LINE_ARGUMENT*) MemAlloc(sizeof(BURN_EXE_COMMAND_LINE_ARGUMENT) * cNodes, TRUE); |
691 | ExitOnNull(pPackage->Exe.rgCommandLineArguments, hr, E_OUTOFMEMORY, "Failed to allocate memory for command-line argument structs."); | 605 | ExitOnNull(*prgCommandLineArguments, hr, E_OUTOFMEMORY, "Failed to allocate memory for command-line argument structs."); |
692 | 606 | ||
693 | pPackage->Exe.cCommandLineArguments = cNodes; | 607 | *pcCommandLineArguments = cNodes; |
694 | 608 | ||
695 | // Parse command-line argument elements. | 609 | // Parse command-line argument elements. |
696 | for (DWORD i = 0; i < cNodes; ++i) | 610 | for (DWORD i = 0; i < cNodes; ++i) |
697 | { | 611 | { |
698 | BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = &pPackage->Exe.rgCommandLineArguments[i]; | 612 | BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i; |
699 | 613 | ||
700 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); | 614 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); |
701 | ExitOnFailure(hr, "Failed to get next command-line argument node."); | 615 | ExitOnFailure(hr, "Failed to get next command-line argument node."); |
@@ -731,8 +645,9 @@ LExit: | |||
731 | return hr; | 645 | return hr; |
732 | } | 646 | } |
733 | 647 | ||
734 | static HRESULT HandleExitCode( | 648 | extern "C" HRESULT ExeEngineHandleExitCode( |
735 | __in BURN_PACKAGE* pPackage, | 649 | __in BURN_EXE_EXIT_CODE* rgCustomExitCodes, |
650 | __in DWORD cCustomExitCodes, | ||
736 | __in DWORD dwExitCode, | 651 | __in DWORD dwExitCode, |
737 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 652 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
738 | ) | 653 | ) |
@@ -740,9 +655,9 @@ static HRESULT HandleExitCode( | |||
740 | HRESULT hr = S_OK; | 655 | HRESULT hr = S_OK; |
741 | BURN_EXE_EXIT_CODE_TYPE typeCode = BURN_EXE_EXIT_CODE_TYPE_NONE; | 656 | BURN_EXE_EXIT_CODE_TYPE typeCode = BURN_EXE_EXIT_CODE_TYPE_NONE; |
742 | 657 | ||
743 | for (DWORD i = 0; i < pPackage->Exe.cExitCodes; ++i) | 658 | for (DWORD i = 0; i < cCustomExitCodes; ++i) |
744 | { | 659 | { |
745 | BURN_EXE_EXIT_CODE* pExitCode = &pPackage->Exe.rgExitCodes[i]; | 660 | BURN_EXE_EXIT_CODE* pExitCode = rgCustomExitCodes + i; |
746 | 661 | ||
747 | // If this is a wildcard, use the last one we come across. | 662 | // If this is a wildcard, use the last one we come across. |
748 | if (pExitCode->fWildcard) | 663 | if (pExitCode->fWildcard) |
diff --git a/src/burn/engine/exeengine.h b/src/burn/engine/exeengine.h index 877968cd..bd5d7ea9 100644 --- a/src/burn/engine/exeengine.h +++ b/src/burn/engine/exeengine.h | |||
@@ -16,6 +16,9 @@ HRESULT ExeEngineParsePackageFromXml( | |||
16 | void ExeEnginePackageUninitialize( | 16 | void ExeEnginePackageUninitialize( |
17 | __in BURN_PACKAGE* pPackage | 17 | __in BURN_PACKAGE* pPackage |
18 | ); | 18 | ); |
19 | void ExeEngineCommandLineArgumentUninitialize( | ||
20 | __in BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument | ||
21 | ); | ||
19 | HRESULT ExeEngineDetectPackage( | 22 | HRESULT ExeEngineDetectPackage( |
20 | __in BURN_PACKAGE* pPackage, | 23 | __in BURN_PACKAGE* pPackage, |
21 | __in BURN_VARIABLES* pVariables | 24 | __in BURN_VARIABLES* pVariables |
@@ -24,7 +27,6 @@ HRESULT ExeEnginePlanCalculatePackage( | |||
24 | __in BURN_PACKAGE* pPackage | 27 | __in BURN_PACKAGE* pPackage |
25 | ); | 28 | ); |
26 | HRESULT ExeEnginePlanAddPackage( | 29 | HRESULT ExeEnginePlanAddPackage( |
27 | __in_opt DWORD *pdwInsertSequence, | ||
28 | __in BURN_PACKAGE* pPackage, | 30 | __in BURN_PACKAGE* pPackage, |
29 | __in BURN_PLAN* pPlan, | 31 | __in BURN_PLAN* pPlan, |
30 | __in BURN_LOGGING* pLog, | 32 | __in BURN_LOGGING* pLog, |
@@ -43,6 +45,22 @@ void ExeEngineUpdateInstallRegistrationState( | |||
43 | __in BURN_EXECUTE_ACTION* pAction, | 45 | __in BURN_EXECUTE_ACTION* pAction, |
44 | __in HRESULT hrExecute | 46 | __in HRESULT hrExecute |
45 | ); | 47 | ); |
48 | HRESULT ExeEngineParseExitCodesFromXml( | ||
49 | __in IXMLDOMNode* pixnPackage, | ||
50 | __inout BURN_EXE_EXIT_CODE** prgExitCodes, | ||
51 | __inout DWORD* pcExitCodes | ||
52 | ); | ||
53 | HRESULT ExeEngineParseCommandLineArgumentsFromXml( | ||
54 | __in IXMLDOMNode* pixnPackage, | ||
55 | __inout BURN_EXE_COMMAND_LINE_ARGUMENT** prgCommandLineArguments, | ||
56 | __inout DWORD* pcCommandLineArguments | ||
57 | ); | ||
58 | HRESULT ExeEngineHandleExitCode( | ||
59 | __in BURN_EXE_EXIT_CODE* rgCustomExitCodes, | ||
60 | __in DWORD cCustomExitCodes, | ||
61 | __in DWORD dwExitCode, | ||
62 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
63 | ); | ||
46 | 64 | ||
47 | 65 | ||
48 | #if defined(__cplusplus) | 66 | #if defined(__cplusplus) |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index bea48cb5..d9087f79 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
@@ -350,6 +350,9 @@ extern "C" void PackageUninitialize( | |||
350 | 350 | ||
351 | switch (pPackage->type) | 351 | switch (pPackage->type) |
352 | { | 352 | { |
353 | case BURN_PACKAGE_TYPE_BUNDLE: | ||
354 | BundlePackageEnginePackageUninitialize(pPackage); | ||
355 | break; | ||
353 | case BURN_PACKAGE_TYPE_EXE: | 356 | case BURN_PACKAGE_TYPE_EXE: |
354 | ExeEnginePackageUninitialize(pPackage); // TODO: Modularization | 357 | ExeEnginePackageUninitialize(pPackage); // TODO: Modularization |
355 | break; | 358 | break; |
@@ -439,22 +442,11 @@ extern "C" HRESULT PackageFindRelatedById( | |||
439 | ) | 442 | ) |
440 | { | 443 | { |
441 | HRESULT hr = S_OK; | 444 | HRESULT hr = S_OK; |
442 | BURN_PACKAGE* pPackage = NULL; | 445 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; |
443 | 446 | ||
444 | for (DWORD i = 0; i < pRelatedBundles->cRelatedBundles; ++i) | 447 | hr = RelatedBundleFindById(pRelatedBundles, wzId, &pRelatedBundle); |
445 | { | 448 | *ppPackage = FAILED(hr) ? NULL : &pRelatedBundle->package; |
446 | pPackage = &pRelatedBundles->rgRelatedBundles[i].package; | ||
447 | |||
448 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPackage->sczId, -1, wzId, -1)) | ||
449 | { | ||
450 | *ppPackage = pPackage; | ||
451 | ExitFunction1(hr = S_OK); | ||
452 | } | ||
453 | } | ||
454 | 449 | ||
455 | hr = E_NOTFOUND; | ||
456 | |||
457 | LExit: | ||
458 | return hr; | 450 | return hr; |
459 | } | 451 | } |
460 | 452 | ||
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index f2a1c304..10b5f33c 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
@@ -35,6 +35,7 @@ enum BURN_EXE_PROTOCOL_TYPE | |||
35 | enum BURN_PACKAGE_TYPE | 35 | enum BURN_PACKAGE_TYPE |
36 | { | 36 | { |
37 | BURN_PACKAGE_TYPE_NONE, | 37 | BURN_PACKAGE_TYPE_NONE, |
38 | BURN_PACKAGE_TYPE_BUNDLE, | ||
38 | BURN_PACKAGE_TYPE_EXE, | 39 | BURN_PACKAGE_TYPE_EXE, |
39 | BURN_PACKAGE_TYPE_MSI, | 40 | BURN_PACKAGE_TYPE_MSI, |
40 | BURN_PACKAGE_TYPE_MSP, | 41 | BURN_PACKAGE_TYPE_MSP, |
@@ -263,21 +264,36 @@ typedef struct _BURN_PACKAGE | |||
263 | { | 264 | { |
264 | struct | 265 | struct |
265 | { | 266 | { |
266 | LPWSTR sczDetectCondition; | ||
267 | LPWSTR sczInstallArguments; | 267 | LPWSTR sczInstallArguments; |
268 | LPWSTR sczRepairArguments; | 268 | LPWSTR sczRepairArguments; |
269 | LPWSTR sczUninstallArguments; | 269 | LPWSTR sczUninstallArguments; |
270 | |||
270 | LPWSTR sczIgnoreDependencies; | 271 | LPWSTR sczIgnoreDependencies; |
271 | LPCWSTR wzAncestors; // points directly into engine state. | 272 | LPCWSTR wzAncestors; // points directly into engine state. |
272 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. | 273 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. |
273 | 274 | ||
274 | BOOL fPseudoBundle; | 275 | BOOL fPseudoBundle; |
276 | BOOL fRepairable; | ||
277 | BOOL fSupportsBurnProtocol; | ||
275 | 278 | ||
279 | BURN_EXE_EXIT_CODE* rgExitCodes; | ||
280 | DWORD cExitCodes; | ||
281 | |||
282 | BURN_EXE_COMMAND_LINE_ARGUMENT* rgCommandLineArguments; | ||
283 | DWORD cCommandLineArguments; | ||
284 | } Bundle; | ||
285 | struct | ||
286 | { | ||
287 | LPWSTR sczDetectCondition; | ||
288 | LPWSTR sczInstallArguments; | ||
289 | LPWSTR sczRepairArguments; | ||
290 | LPWSTR sczUninstallArguments; | ||
291 | |||
292 | BOOL fPseudoBundle; | ||
293 | BOOL fFireAndForget; | ||
276 | BOOL fRepairable; | 294 | BOOL fRepairable; |
277 | BURN_EXE_PROTOCOL_TYPE protocol; | 295 | BURN_EXE_PROTOCOL_TYPE protocol; |
278 | 296 | ||
279 | BOOL fSupportsAncestors; | ||
280 | |||
281 | BURN_EXE_EXIT_CODE* rgExitCodes; | 297 | BURN_EXE_EXIT_CODE* rgExitCodes; |
282 | DWORD cExitCodes; | 298 | DWORD cExitCodes; |
283 | 299 | ||
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 0f63a945..e0e9a82b 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -36,16 +36,13 @@ static HRESULT PlanPackagesHelper( | |||
36 | __in BURN_USER_EXPERIENCE* pUX, | 36 | __in BURN_USER_EXPERIENCE* pUX, |
37 | __in BURN_PLAN* pPlan, | 37 | __in BURN_PLAN* pPlan, |
38 | __in BURN_LOGGING* pLog, | 38 | __in BURN_LOGGING* pLog, |
39 | __in BURN_VARIABLES* pVariables, | 39 | __in BURN_VARIABLES* pVariables |
40 | __in BOOTSTRAPPER_DISPLAY display, | ||
41 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
42 | ); | 40 | ); |
43 | static HRESULT InitializePackage( | 41 | static HRESULT InitializePackage( |
44 | __in BURN_PLAN* pPlan, | 42 | __in BURN_PLAN* pPlan, |
45 | __in BURN_USER_EXPERIENCE* pUX, | 43 | __in BURN_USER_EXPERIENCE* pUX, |
46 | __in BURN_VARIABLES* pVariables, | 44 | __in BURN_VARIABLES* pVariables, |
47 | __in BURN_PACKAGE* pPackage, | 45 | __in BURN_PACKAGE* pPackage |
48 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
49 | ); | 46 | ); |
50 | static HRESULT ProcessPackage( | 47 | static HRESULT ProcessPackage( |
51 | __in BOOL fBundlePerMachine, | 48 | __in BOOL fBundlePerMachine, |
@@ -54,7 +51,6 @@ static HRESULT ProcessPackage( | |||
54 | __in BURN_PACKAGE* pPackage, | 51 | __in BURN_PACKAGE* pPackage, |
55 | __in BURN_LOGGING* pLog, | 52 | __in BURN_LOGGING* pLog, |
56 | __in BURN_VARIABLES* pVariables, | 53 | __in BURN_VARIABLES* pVariables, |
57 | __in BOOTSTRAPPER_DISPLAY display, | ||
58 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary | 54 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary |
59 | ); | 55 | ); |
60 | static HRESULT ProcessPackageRollbackBoundary( | 56 | static HRESULT ProcessPackageRollbackBoundary( |
@@ -266,10 +262,10 @@ extern "C" void PlanUninitializeExecuteAction( | |||
266 | { | 262 | { |
267 | switch (pExecuteAction->type) | 263 | switch (pExecuteAction->type) |
268 | { | 264 | { |
269 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 265 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: |
270 | ReleaseStr(pExecuteAction->exePackage.sczIgnoreDependencies); | 266 | ReleaseStr(pExecuteAction->relatedBundle.sczIgnoreDependencies); |
271 | ReleaseStr(pExecuteAction->exePackage.sczAncestors); | 267 | ReleaseStr(pExecuteAction->relatedBundle.sczAncestors); |
272 | ReleaseStr(pExecuteAction->exePackage.sczEngineWorkingDirectory); | 268 | ReleaseStr(pExecuteAction->relatedBundle.sczEngineWorkingDirectory); |
273 | break; | 269 | break; |
274 | 270 | ||
275 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 271 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
@@ -500,14 +496,12 @@ extern "C" HRESULT PlanPackages( | |||
500 | __in BURN_PACKAGES* pPackages, | 496 | __in BURN_PACKAGES* pPackages, |
501 | __in BURN_PLAN* pPlan, | 497 | __in BURN_PLAN* pPlan, |
502 | __in BURN_LOGGING* pLog, | 498 | __in BURN_LOGGING* pLog, |
503 | __in BURN_VARIABLES* pVariables, | 499 | __in BURN_VARIABLES* pVariables |
504 | __in BOOTSTRAPPER_DISPLAY display, | ||
505 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
506 | ) | 500 | ) |
507 | { | 501 | { |
508 | HRESULT hr = S_OK; | 502 | HRESULT hr = S_OK; |
509 | 503 | ||
510 | hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, pUX, pPlan, pLog, pVariables, display, relationType); | 504 | hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, pUX, pPlan, pLog, pVariables); |
511 | 505 | ||
512 | return hr; | 506 | return hr; |
513 | } | 507 | } |
@@ -712,15 +706,13 @@ extern "C" HRESULT PlanPassThroughBundle( | |||
712 | __in BURN_PACKAGE* pPackage, | 706 | __in BURN_PACKAGE* pPackage, |
713 | __in BURN_PLAN* pPlan, | 707 | __in BURN_PLAN* pPlan, |
714 | __in BURN_LOGGING* pLog, | 708 | __in BURN_LOGGING* pLog, |
715 | __in BURN_VARIABLES* pVariables, | 709 | __in BURN_VARIABLES* pVariables |
716 | __in BOOTSTRAPPER_DISPLAY display, | ||
717 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
718 | ) | 710 | ) |
719 | { | 711 | { |
720 | HRESULT hr = S_OK; | 712 | HRESULT hr = S_OK; |
721 | 713 | ||
722 | // Plan passthrough package. | 714 | // Plan passthrough package. |
723 | hr = PlanPackagesHelper(pPackage, 1, pUX, pPlan, pLog, pVariables, display, relationType); | 715 | hr = PlanPackagesHelper(pPackage, 1, pUX, pPlan, pLog, pVariables); |
724 | ExitOnFailure(hr, "Failed to process passthrough package."); | 716 | ExitOnFailure(hr, "Failed to process passthrough package."); |
725 | 717 | ||
726 | LExit: | 718 | LExit: |
@@ -732,15 +724,17 @@ extern "C" HRESULT PlanUpdateBundle( | |||
732 | __in BURN_PACKAGE* pPackage, | 724 | __in BURN_PACKAGE* pPackage, |
733 | __in BURN_PLAN* pPlan, | 725 | __in BURN_PLAN* pPlan, |
734 | __in BURN_LOGGING* pLog, | 726 | __in BURN_LOGGING* pLog, |
735 | __in BURN_VARIABLES* pVariables, | 727 | __in BURN_VARIABLES* pVariables |
736 | __in BOOTSTRAPPER_DISPLAY display, | ||
737 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
738 | ) | 728 | ) |
739 | { | 729 | { |
740 | HRESULT hr = S_OK; | 730 | HRESULT hr = S_OK; |
741 | 731 | ||
732 | Assert(!pPackage->fPerMachine); | ||
733 | Assert(BURN_PACKAGE_TYPE_EXE == pPackage->type); | ||
734 | pPackage->Exe.fFireAndForget = BOOTSTRAPPER_ACTION_UPDATE_REPLACE == pPlan->action; | ||
735 | |||
742 | // Plan update package. | 736 | // Plan update package. |
743 | hr = PlanPackagesHelper(pPackage, 1, pUX, pPlan, pLog, pVariables, display, relationType); | 737 | hr = PlanPackagesHelper(pPackage, 1, pUX, pPlan, pLog, pVariables); |
744 | ExitOnFailure(hr, "Failed to process update package."); | 738 | ExitOnFailure(hr, "Failed to process update package."); |
745 | 739 | ||
746 | LExit: | 740 | LExit: |
@@ -753,9 +747,7 @@ static HRESULT PlanPackagesHelper( | |||
753 | __in BURN_USER_EXPERIENCE* pUX, | 747 | __in BURN_USER_EXPERIENCE* pUX, |
754 | __in BURN_PLAN* pPlan, | 748 | __in BURN_PLAN* pPlan, |
755 | __in BURN_LOGGING* pLog, | 749 | __in BURN_LOGGING* pLog, |
756 | __in BURN_VARIABLES* pVariables, | 750 | __in BURN_VARIABLES* pVariables |
757 | __in BOOTSTRAPPER_DISPLAY display, | ||
758 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
759 | ) | 751 | ) |
760 | { | 752 | { |
761 | HRESULT hr = S_OK; | 753 | HRESULT hr = S_OK; |
@@ -768,7 +760,7 @@ static HRESULT PlanPackagesHelper( | |||
768 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 760 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; |
769 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 761 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
770 | 762 | ||
771 | hr = InitializePackage(pPlan, pUX, pVariables, pPackage, relationType); | 763 | hr = InitializePackage(pPlan, pUX, pVariables, pPackage); |
772 | ExitOnFailure(hr, "Failed to initialize package."); | 764 | ExitOnFailure(hr, "Failed to initialize package."); |
773 | } | 765 | } |
774 | 766 | ||
@@ -791,7 +783,7 @@ static HRESULT PlanPackagesHelper( | |||
791 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 783 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; |
792 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 784 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
793 | 785 | ||
794 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &pRollbackBoundary); | 786 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, &pRollbackBoundary); |
795 | ExitOnFailure(hr, "Failed to process package."); | 787 | ExitOnFailure(hr, "Failed to process package."); |
796 | } | 788 | } |
797 | 789 | ||
@@ -841,14 +833,24 @@ static HRESULT InitializePackage( | |||
841 | __in BURN_PLAN* pPlan, | 833 | __in BURN_PLAN* pPlan, |
842 | __in BURN_USER_EXPERIENCE* pUX, | 834 | __in BURN_USER_EXPERIENCE* pUX, |
843 | __in BURN_VARIABLES* pVariables, | 835 | __in BURN_VARIABLES* pVariables, |
844 | __in BURN_PACKAGE* pPackage, | 836 | __in BURN_PACKAGE* pPackage |
845 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
846 | ) | 837 | ) |
847 | { | 838 | { |
848 | HRESULT hr = S_OK; | 839 | HRESULT hr = S_OK; |
849 | BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT; | 840 | BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT; |
850 | BOOL fInstallCondition = FALSE; | 841 | BOOL fInstallCondition = FALSE; |
851 | BOOL fBeginCalled = FALSE; | 842 | BOOL fBeginCalled = FALSE; |
843 | BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType; | ||
844 | |||
845 | if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fPseudoBundle) | ||
846 | { | ||
847 | // Exe pseudo bundles are not configurable. | ||
848 | // The BA already requested this package to be executed | ||
849 | // * by the overall plan action for UpdateReplace | ||
850 | // * by enabling the forward compatible bundle for Passthrough | ||
851 | pPackage->defaultRequested = pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
852 | ExitFunction(); | ||
853 | } | ||
852 | 854 | ||
853 | if (pPackage->fCanAffectRegistration) | 855 | if (pPackage->fCanAffectRegistration) |
854 | { | 856 | { |
@@ -896,7 +898,6 @@ static HRESULT ProcessPackage( | |||
896 | __in BURN_PACKAGE* pPackage, | 898 | __in BURN_PACKAGE* pPackage, |
897 | __in BURN_LOGGING* pLog, | 899 | __in BURN_LOGGING* pLog, |
898 | __in BURN_VARIABLES* pVariables, | 900 | __in BURN_VARIABLES* pVariables, |
899 | __in BOOTSTRAPPER_DISPLAY display, | ||
900 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary | 901 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary |
901 | ) | 902 | ) |
902 | { | 903 | { |
@@ -920,7 +921,7 @@ static HRESULT ProcessPackage( | |||
920 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) | 921 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) |
921 | { | 922 | { |
922 | // If the package is in a requested state, plan it. | 923 | // If the package is in a requested state, plan it. |
923 | hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables); | 924 | hr = PlanExecutePackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables); |
924 | ExitOnFailure(hr, "Failed to plan execute package."); | 925 | ExitOnFailure(hr, "Failed to plan execute package."); |
925 | } | 926 | } |
926 | else | 927 | else |
@@ -1064,7 +1065,6 @@ LExit: | |||
1064 | 1065 | ||
1065 | extern "C" HRESULT PlanExecutePackage( | 1066 | extern "C" HRESULT PlanExecutePackage( |
1066 | __in BOOL fPerMachine, | 1067 | __in BOOL fPerMachine, |
1067 | __in BOOTSTRAPPER_DISPLAY display, | ||
1068 | __in BURN_USER_EXPERIENCE* pUserExperience, | 1068 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1069 | __in BURN_PLAN* pPlan, | 1069 | __in BURN_PLAN* pPlan, |
1070 | __in BURN_PACKAGE* pPackage, | 1070 | __in BURN_PACKAGE* pPackage, |
@@ -1073,6 +1073,7 @@ extern "C" HRESULT PlanExecutePackage( | |||
1073 | ) | 1073 | ) |
1074 | { | 1074 | { |
1075 | HRESULT hr = S_OK; | 1075 | HRESULT hr = S_OK; |
1076 | BOOTSTRAPPER_DISPLAY display = pPlan->pCommand->display; | ||
1076 | BOOL fRequestedCache = BOOTSTRAPPER_CACHE_TYPE_REMOVE < pPackage->cacheType && (BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage)); | 1077 | BOOL fRequestedCache = BOOTSTRAPPER_CACHE_TYPE_REMOVE < pPackage->cacheType && (BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage)); |
1077 | 1078 | ||
1078 | hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary); | 1079 | hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary); |
@@ -1124,7 +1125,7 @@ extern "C" HRESULT PlanExecutePackage( | |||
1124 | switch (pPackage->type) | 1125 | switch (pPackage->type) |
1125 | { | 1126 | { |
1126 | case BURN_PACKAGE_TYPE_EXE: | 1127 | case BURN_PACKAGE_TYPE_EXE: |
1127 | hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables); | 1128 | hr = ExeEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables); |
1128 | break; | 1129 | break; |
1129 | 1130 | ||
1130 | case BURN_PACKAGE_TYPE_MSI: | 1131 | case BURN_PACKAGE_TYPE_MSI: |
@@ -1288,8 +1289,8 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1288 | } | 1289 | } |
1289 | 1290 | ||
1290 | // Pass along any ancestors and ourself to prevent infinite loops. | 1291 | // Pass along any ancestors and ourself to prevent infinite loops. |
1291 | pRelatedBundle->package.Exe.wzAncestors = pRegistration->sczBundlePackageAncestors; | 1292 | pRelatedBundle->package.Bundle.wzAncestors = pRegistration->sczBundlePackageAncestors; |
1292 | pRelatedBundle->package.Exe.wzEngineWorkingDirectory = pPlan->pInternalCommand->sczEngineWorkingDirectory; | 1293 | pRelatedBundle->package.Bundle.wzEngineWorkingDirectory = pPlan->pInternalCommand->sczEngineWorkingDirectory; |
1293 | 1294 | ||
1294 | hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->relationType, pPlan->action, pRegistration->pVersion, pRelatedBundle->pVersion, &pRelatedBundle->package.requested); | 1295 | hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->relationType, pPlan->action, pRegistration->pVersion, pRelatedBundle->pVersion, &pRelatedBundle->package.requested); |
1295 | ExitOnFailure(hr, "Failed to get default request state for related bundle."); | 1296 | ExitOnFailure(hr, "Failed to get default request state for related bundle."); |
@@ -1349,37 +1350,38 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1349 | 1350 | ||
1350 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) | 1351 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) |
1351 | { | 1352 | { |
1352 | if (BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE == pPlan->rgExecuteActions[i].type && BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].exePackage.action) | 1353 | switch (pPlan->rgExecuteActions[i].type) |
1353 | { | 1354 | { |
1354 | fExecutingAnyPackage = TRUE; | 1355 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: |
1355 | 1356 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].relatedBundle.action) | |
1356 | BURN_PACKAGE* pPackage = pPlan->rgExecuteActions[i].packageProvider.pPackage; | ||
1357 | if (BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) | ||
1358 | { | 1357 | { |
1359 | if (0 < pPackage->cDependencyProviders) | 1358 | fExecutingAnyPackage = TRUE; |
1359 | |||
1360 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; | ||
1361 | if (pPackage->cDependencyProviders) | ||
1360 | { | 1362 | { |
1361 | // Bundles only support a single provider key. | 1363 | // Bundles only support a single provider key. |
1362 | const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders; | 1364 | const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders; |
1363 | DictAddKey(sdProviderKeys, pProvider->sczKey); | 1365 | DictAddKey(sdProviderKeys, pProvider->sczKey); |
1364 | } | 1366 | } |
1365 | } | 1367 | } |
1366 | } | 1368 | break; |
1367 | else | ||
1368 | { | ||
1369 | switch (pPlan->rgExecuteActions[i].type) | ||
1370 | { | ||
1371 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | ||
1372 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msiPackage.action); | ||
1373 | break; | ||
1374 | 1369 | ||
1375 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 1370 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
1376 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].mspTarget.action); | 1371 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].exePackage.action); |
1377 | break; | 1372 | break; |
1378 | 1373 | ||
1379 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | 1374 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
1380 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msuPackage.action); | 1375 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msiPackage.action); |
1381 | break; | 1376 | break; |
1382 | } | 1377 | |
1378 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | ||
1379 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].mspTarget.action); | ||
1380 | break; | ||
1381 | |||
1382 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | ||
1383 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msuPackage.action); | ||
1384 | break; | ||
1383 | } | 1385 | } |
1384 | } | 1386 | } |
1385 | 1387 | ||
@@ -1422,7 +1424,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1422 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1424 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) |
1423 | { | 1425 | { |
1424 | // Addon and patch bundles will be passed a list of dependencies to ignore for planning. | 1426 | // Addon and patch bundles will be passed a list of dependencies to ignore for planning. |
1425 | hr = StrAllocString(&pRelatedBundle->package.Exe.sczIgnoreDependencies, sczIgnoreDependencies, 0); | 1427 | hr = StrAllocString(&pRelatedBundle->package.Bundle.sczIgnoreDependencies, sczIgnoreDependencies, 0); |
1426 | ExitOnFailure(hr, "Failed to copy the list of dependencies to ignore."); | 1428 | ExitOnFailure(hr, "Failed to copy the list of dependencies to ignore."); |
1427 | 1429 | ||
1428 | // Uninstall addons and patches early in the chain, before other packages are uninstalled. | 1430 | // Uninstall addons and patches early in the chain, before other packages are uninstalled. |
@@ -1434,8 +1436,8 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1434 | 1436 | ||
1435 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1437 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
1436 | { | 1438 | { |
1437 | hr = ExeEnginePlanCalculatePackage(&pRelatedBundle->package); | 1439 | hr = BundlePackageEnginePlanCalculatePackage(&pRelatedBundle->package); |
1438 | ExitOnFailure(hr, "Failed to calcuate plan for related bundle: %ls", pRelatedBundle->package.sczId); | 1440 | ExitOnFailure(hr, "Failed to calculate plan for related bundle: %ls", pRelatedBundle->package.sczId); |
1439 | 1441 | ||
1440 | // Calculate package states based on reference count for addon and patch related bundles. | 1442 | // Calculate package states based on reference count for addon and patch related bundles. |
1441 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1443 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) |
@@ -1450,7 +1452,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1450 | } | 1452 | } |
1451 | } | 1453 | } |
1452 | 1454 | ||
1453 | hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables); | 1455 | hr = BundlePackageEnginePlanAddRelatedBundle(pdwInsertIndex, pRelatedBundle, pPlan, pLog, pVariables); |
1454 | ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); | 1456 | ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); |
1455 | 1457 | ||
1456 | // Calculate package states based on reference count for addon and patch related bundles. | 1458 | // Calculate package states based on reference count for addon and patch related bundles. |
@@ -2603,8 +2605,12 @@ static void ExecuteActionLog( | |||
2603 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls, action: %hs", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey, LoggingDependencyActionToString(pAction->packageDependency.action)); | 2605 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls, action: %hs", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey, LoggingDependencyActionToString(pAction->packageDependency.action)); |
2604 | break; | 2606 | break; |
2605 | 2607 | ||
2608 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
2609 | LogStringLine(PlanDumpLevel, "%ls action[%u]: RELATED_BUNDLE package id: %ls, action: %hs, ignore dependencies: %ls", wzBase, iAction, pAction->relatedBundle.pRelatedBundle->package.sczId, LoggingActionStateToString(pAction->relatedBundle.action), pAction->relatedBundle.sczIgnoreDependencies); | ||
2610 | break; | ||
2611 | |||
2606 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 2612 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
2607 | LogStringLine(PlanDumpLevel, "%ls action[%u]: EXE_PACKAGE package id: %ls, action: %hs, ignore dependencies: %ls", wzBase, iAction, pAction->exePackage.pPackage->sczId, LoggingActionStateToString(pAction->exePackage.action), pAction->exePackage.sczIgnoreDependencies); | 2613 | LogStringLine(PlanDumpLevel, "%ls action[%u]: EXE_PACKAGE package id: %ls, action: %hs", wzBase, iAction, pAction->exePackage.pPackage->sczId, LoggingActionStateToString(pAction->exePackage.action)); |
2608 | break; | 2614 | break; |
2609 | 2615 | ||
2610 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 2616 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index f0560e6e..6be19a10 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
@@ -50,6 +50,7 @@ enum BURN_EXECUTE_ACTION_TYPE | |||
50 | BURN_EXECUTE_ACTION_TYPE_CHECKPOINT, | 50 | BURN_EXECUTE_ACTION_TYPE_CHECKPOINT, |
51 | BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE, | 51 | BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE, |
52 | BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE, | 52 | BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE, |
53 | BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE, | ||
53 | BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, | 54 | BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, |
54 | BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, | 55 | BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, |
55 | BURN_EXECUTE_ACTION_TYPE_MSP_TARGET, | 56 | BURN_EXECUTE_ACTION_TYPE_MSP_TARGET, |
@@ -160,12 +161,16 @@ typedef struct _BURN_EXECUTE_ACTION | |||
160 | } uncachePackage; | 161 | } uncachePackage; |
161 | struct | 162 | struct |
162 | { | 163 | { |
163 | BURN_PACKAGE* pPackage; | 164 | BURN_RELATED_BUNDLE* pRelatedBundle; |
164 | BOOL fFireAndForget; | ||
165 | BOOTSTRAPPER_ACTION_STATE action; | 165 | BOOTSTRAPPER_ACTION_STATE action; |
166 | LPWSTR sczIgnoreDependencies; | 166 | LPWSTR sczIgnoreDependencies; |
167 | LPWSTR sczAncestors; | 167 | LPWSTR sczAncestors; |
168 | LPWSTR sczEngineWorkingDirectory; | 168 | LPWSTR sczEngineWorkingDirectory; |
169 | } relatedBundle; | ||
170 | struct | ||
171 | { | ||
172 | BURN_PACKAGE* pPackage; | ||
173 | BOOTSTRAPPER_ACTION_STATE action; | ||
169 | } exePackage; | 174 | } exePackage; |
170 | struct | 175 | struct |
171 | { | 176 | { |
@@ -339,9 +344,7 @@ HRESULT PlanPackages( | |||
339 | __in BURN_PACKAGES* pPackages, | 344 | __in BURN_PACKAGES* pPackages, |
340 | __in BURN_PLAN* pPlan, | 345 | __in BURN_PLAN* pPlan, |
341 | __in BURN_LOGGING* pLog, | 346 | __in BURN_LOGGING* pLog, |
342 | __in BURN_VARIABLES* pVariables, | 347 | __in BURN_VARIABLES* pVariables |
343 | __in BOOTSTRAPPER_DISPLAY display, | ||
344 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
345 | ); | 348 | ); |
346 | HRESULT PlanRegistration( | 349 | HRESULT PlanRegistration( |
347 | __in BURN_PLAN* pPlan, | 350 | __in BURN_PLAN* pPlan, |
@@ -356,18 +359,14 @@ HRESULT PlanPassThroughBundle( | |||
356 | __in BURN_PACKAGE* pPackage, | 359 | __in BURN_PACKAGE* pPackage, |
357 | __in BURN_PLAN* pPlan, | 360 | __in BURN_PLAN* pPlan, |
358 | __in BURN_LOGGING* pLog, | 361 | __in BURN_LOGGING* pLog, |
359 | __in BURN_VARIABLES* pVariables, | 362 | __in BURN_VARIABLES* pVariables |
360 | __in BOOTSTRAPPER_DISPLAY display, | ||
361 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
362 | ); | 363 | ); |
363 | HRESULT PlanUpdateBundle( | 364 | HRESULT PlanUpdateBundle( |
364 | __in BURN_USER_EXPERIENCE* pUX, | 365 | __in BURN_USER_EXPERIENCE* pUX, |
365 | __in BURN_PACKAGE* pPackage, | 366 | __in BURN_PACKAGE* pPackage, |
366 | __in BURN_PLAN* pPlan, | 367 | __in BURN_PLAN* pPlan, |
367 | __in BURN_LOGGING* pLog, | 368 | __in BURN_LOGGING* pLog, |
368 | __in BURN_VARIABLES* pVariables, | 369 | __in BURN_VARIABLES* pVariables |
369 | __in BOOTSTRAPPER_DISPLAY display, | ||
370 | __in BOOTSTRAPPER_RELATION_TYPE relationType | ||
371 | ); | 370 | ); |
372 | HRESULT PlanLayoutContainer( | 371 | HRESULT PlanLayoutContainer( |
373 | __in BURN_PLAN* pPlan, | 372 | __in BURN_PLAN* pPlan, |
@@ -379,7 +378,6 @@ HRESULT PlanLayoutPackage( | |||
379 | ); | 378 | ); |
380 | HRESULT PlanExecutePackage( | 379 | HRESULT PlanExecutePackage( |
381 | __in BOOL fPerMachine, | 380 | __in BOOL fPerMachine, |
382 | __in BOOTSTRAPPER_DISPLAY display, | ||
383 | __in BURN_USER_EXPERIENCE* pUserExperience, | 381 | __in BURN_USER_EXPERIENCE* pUserExperience, |
384 | __in BURN_PLAN* pPlan, | 382 | __in BURN_PLAN* pPlan, |
385 | __in BURN_PACKAGE* pPackage, | 383 | __in BURN_PACKAGE* pPackage, |
diff --git a/src/burn/engine/precomp.h b/src/burn/engine/precomp.h index 3b4d989b..26adf44c 100644 --- a/src/burn/engine/precomp.h +++ b/src/burn/engine/precomp.h | |||
@@ -86,6 +86,7 @@ | |||
86 | #include "dependency.h" | 86 | #include "dependency.h" |
87 | #include "core.h" | 87 | #include "core.h" |
88 | #include "apply.h" | 88 | #include "apply.h" |
89 | #include "bundlepackageengine.h" | ||
89 | #include "exeengine.h" | 90 | #include "exeengine.h" |
90 | #include "msiengine.h" | 91 | #include "msiengine.h" |
91 | #include "mspengine.h" | 92 | #include "mspengine.h" |
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 14dd2b77..7b670035 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
@@ -3,36 +3,24 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | 5 | ||
6 | extern "C" HRESULT PseudoBundleInitialize( | 6 | extern "C" HRESULT PseudoBundleInitializeRelated( |
7 | __in BURN_PACKAGE* pPackage, | 7 | __in BURN_PACKAGE* pPackage, |
8 | __in BOOL fSupportsBurnProtocol, | 8 | __in BOOL fSupportsBurnProtocol, |
9 | __in BOOL fPerMachine, | 9 | __in BOOL fPerMachine, |
10 | __in_z LPCWSTR wzId, | 10 | __in_z LPCWSTR wzId, |
11 | #ifdef DEBUG | ||
11 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 12 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
12 | __in BOOTSTRAPPER_PACKAGE_STATE state, | 13 | #endif |
13 | __in BOOL fCached, | 14 | __in BOOL fCached, |
14 | __in_z LPCWSTR wzFilePath, | 15 | __in_z LPCWSTR wzFilePath, |
15 | __in_z LPCWSTR wzLocalSource, | ||
16 | __in_z_opt LPCWSTR wzDownloadSource, | ||
17 | __in DWORD64 qwSize, | 16 | __in DWORD64 qwSize, |
18 | __in BOOL fVital, | 17 | __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider |
19 | __in_z_opt LPCWSTR wzInstallArguments, | ||
20 | __in_z_opt LPCWSTR wzRepairArguments, | ||
21 | __in_z_opt LPCWSTR wzUninstallArguments, | ||
22 | __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider, | ||
23 | __in_opt const BYTE* pbHash, | ||
24 | __in const DWORD cbHash | ||
25 | ) | 18 | ) |
26 | { | 19 | { |
27 | HRESULT hr = S_OK; | 20 | HRESULT hr = S_OK; |
28 | LPWSTR sczRelationTypeCommandLineSwitch = NULL; | ||
29 | BURN_PAYLOAD* pPayload = NULL; | 21 | BURN_PAYLOAD* pPayload = NULL; |
30 | 22 | ||
31 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); | 23 | AssertSz(BOOTSTRAPPER_RELATION_UPDATE != relationType, "Update pseudo bundles must use PseudoBundleInitializeUpdateBundle instead."); |
32 | if (wzRelationTypeCommandLine) | ||
33 | { | ||
34 | hr = StrAllocFormatted(&sczRelationTypeCommandLineSwitch, L" -%ls", wzRelationTypeCommandLine); | ||
35 | } | ||
36 | 24 | ||
37 | // Initialize the single payload, and fill out all the necessary fields | 25 | // Initialize the single payload, and fill out all the necessary fields |
38 | pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE); | 26 | pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE); |
@@ -51,41 +39,21 @@ extern "C" HRESULT PseudoBundleInitialize( | |||
51 | hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0); | 39 | hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0); |
52 | ExitOnFailure(hr, "Failed to copy filename for pseudo bundle."); | 40 | ExitOnFailure(hr, "Failed to copy filename for pseudo bundle."); |
53 | 41 | ||
54 | hr = StrAllocString(&pPayload->sczSourcePath, wzLocalSource, 0); | 42 | hr = StrAllocString(&pPayload->sczSourcePath, wzFilePath, 0); |
55 | ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle."); | 43 | ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle."); |
56 | 44 | ||
57 | if (wzDownloadSource && *wzDownloadSource) | 45 | pPackage->type = BURN_PACKAGE_TYPE_BUNDLE; |
58 | { | ||
59 | hr = StrAllocString(&pPayload->downloadSource.sczUrl, wzDownloadSource, 0); | ||
60 | ExitOnFailure(hr, "Failed to copy download source for pseudo bundle."); | ||
61 | } | ||
62 | |||
63 | if (pbHash) | ||
64 | { | ||
65 | pPayload->pbHash = static_cast<BYTE*>(MemAlloc(cbHash, FALSE)); | ||
66 | ExitOnNull(pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash."); | ||
67 | |||
68 | pPayload->cbHash = cbHash; | ||
69 | memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash); | ||
70 | } | ||
71 | |||
72 | if (BOOTSTRAPPER_RELATION_UPDATE == relationType) | ||
73 | { | ||
74 | pPayload->verification = BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE; | ||
75 | } | ||
76 | |||
77 | pPackage->Exe.fPseudoBundle = TRUE; | ||
78 | |||
79 | pPackage->type = BURN_PACKAGE_TYPE_EXE; | ||
80 | pPackage->fPerMachine = fPerMachine; | 46 | pPackage->fPerMachine = fPerMachine; |
81 | pPackage->currentState = state; | 47 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; |
82 | pPackage->fCached = fCached; | 48 | pPackage->fCached = fCached; |
83 | pPackage->qwInstallSize = qwSize; | 49 | pPackage->qwInstallSize = qwSize; |
84 | pPackage->qwSize = qwSize; | 50 | pPackage->qwSize = qwSize; |
85 | pPackage->fVital = fVital; | 51 | pPackage->fVital = FALSE; |
86 | 52 | ||
87 | pPackage->Exe.protocol = fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; | 53 | pPackage->fUninstallable = TRUE; |
88 | pPackage->Exe.fSupportsAncestors = TRUE; | 54 | pPackage->Bundle.fPseudoBundle = TRUE; |
55 | pPackage->Bundle.fRepairable = TRUE; | ||
56 | pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; | ||
89 | 57 | ||
90 | hr = StrAllocString(&pPackage->sczId, wzId, 0); | 58 | hr = StrAllocString(&pPackage->sczId, wzId, 0); |
91 | ExitOnFailure(hr, "Failed to copy key for pseudo bundle."); | 59 | ExitOnFailure(hr, "Failed to copy key for pseudo bundle."); |
@@ -93,47 +61,6 @@ extern "C" HRESULT PseudoBundleInitialize( | |||
93 | hr = StrAllocString(&pPackage->sczCacheId, wzId, 0); | 61 | hr = StrAllocString(&pPackage->sczCacheId, wzId, 0); |
94 | ExitOnFailure(hr, "Failed to copy cache id for pseudo bundle."); | 62 | ExitOnFailure(hr, "Failed to copy cache id for pseudo bundle."); |
95 | 63 | ||
96 | // If we are a self updating bundle, we don't have to have Install arguments. | ||
97 | if (wzInstallArguments) | ||
98 | { | ||
99 | hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); | ||
100 | ExitOnFailure(hr, "Failed to copy install arguments for related bundle package"); | ||
101 | } | ||
102 | |||
103 | if (sczRelationTypeCommandLineSwitch) | ||
104 | { | ||
105 | hr = StrAllocConcat(&pPackage->Exe.sczInstallArguments, sczRelationTypeCommandLineSwitch, 0); | ||
106 | ExitOnFailure(hr, "Failed to append relation type to install arguments for related bundle package"); | ||
107 | } | ||
108 | |||
109 | if (wzRepairArguments) | ||
110 | { | ||
111 | hr = StrAllocString(&pPackage->Exe.sczRepairArguments, wzRepairArguments, 0); | ||
112 | ExitOnFailure(hr, "Failed to copy repair arguments for related bundle package"); | ||
113 | |||
114 | if (sczRelationTypeCommandLineSwitch) | ||
115 | { | ||
116 | hr = StrAllocConcat(&pPackage->Exe.sczRepairArguments, sczRelationTypeCommandLineSwitch, 0); | ||
117 | ExitOnFailure(hr, "Failed to append relation type to repair arguments for related bundle package"); | ||
118 | } | ||
119 | |||
120 | pPackage->Exe.fRepairable = TRUE; | ||
121 | } | ||
122 | |||
123 | if (wzUninstallArguments) | ||
124 | { | ||
125 | hr = StrAllocString(&pPackage->Exe.sczUninstallArguments, wzUninstallArguments, 0); | ||
126 | ExitOnFailure(hr, "Failed to copy uninstall arguments for related bundle package"); | ||
127 | |||
128 | if (sczRelationTypeCommandLineSwitch) | ||
129 | { | ||
130 | hr = StrAllocConcat(&pPackage->Exe.sczUninstallArguments, sczRelationTypeCommandLineSwitch, 0); | ||
131 | ExitOnFailure(hr, "Failed to append relation type to uninstall arguments for related bundle package"); | ||
132 | } | ||
133 | |||
134 | pPackage->fUninstallable = TRUE; | ||
135 | } | ||
136 | |||
137 | if (pDependencyProvider) | 64 | if (pDependencyProvider) |
138 | { | 65 | { |
139 | pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE); | 66 | pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE); |
@@ -153,8 +80,6 @@ extern "C" HRESULT PseudoBundleInitialize( | |||
153 | } | 80 | } |
154 | 81 | ||
155 | LExit: | 82 | LExit: |
156 | ReleaseStr(sczRelationTypeCommandLineSwitch); | ||
157 | |||
158 | return hr; | 83 | return hr; |
159 | } | 84 | } |
160 | 85 | ||
@@ -165,7 +90,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( | |||
165 | __in BURN_PACKAGE* pPackage | 90 | __in BURN_PACKAGE* pPackage |
166 | ) | 91 | ) |
167 | { | 92 | { |
168 | Assert(BURN_PACKAGE_TYPE_EXE == pPackage->type); | 93 | Assert(BURN_PACKAGE_TYPE_BUNDLE == pPackage->type); |
169 | 94 | ||
170 | HRESULT hr = S_OK; | 95 | HRESULT hr = S_OK; |
171 | LPWSTR sczArguments = NULL; | 96 | LPWSTR sczArguments = NULL; |
@@ -180,59 +105,29 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( | |||
180 | pPassthroughPackage->payloads.rgItems[iPayload].pPayload = pPackage->payloads.rgItems[iPayload].pPayload; | 105 | pPassthroughPackage->payloads.rgItems[iPayload].pPayload = pPackage->payloads.rgItems[iPayload].pPayload; |
181 | } | 106 | } |
182 | 107 | ||
183 | pPassthroughPackage->Exe.fPseudoBundle = TRUE; | ||
184 | |||
185 | pPassthroughPackage->fPerMachine = FALSE; // passthrough bundles are always launched per-user. | 108 | pPassthroughPackage->fPerMachine = FALSE; // passthrough bundles are always launched per-user. |
186 | pPassthroughPackage->type = pPackage->type; | 109 | pPassthroughPackage->type = BURN_PACKAGE_TYPE_EXE; |
187 | pPassthroughPackage->currentState = pPackage->currentState; | 110 | pPassthroughPackage->currentState = pPackage->currentState; |
188 | pPassthroughPackage->fCached = pPackage->fCached; | 111 | pPassthroughPackage->fCached = pPackage->fCached; |
189 | pPassthroughPackage->qwInstallSize = pPackage->qwInstallSize; | 112 | pPassthroughPackage->qwInstallSize = pPackage->qwInstallSize; |
190 | pPassthroughPackage->qwSize = pPackage->qwSize; | 113 | pPassthroughPackage->qwSize = pPackage->qwSize; |
191 | pPassthroughPackage->fVital = pPackage->fVital; | 114 | pPassthroughPackage->fVital = pPackage->fVital; |
192 | 115 | ||
116 | pPassthroughPackage->Exe.fPseudoBundle = TRUE; | ||
117 | pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; | ||
118 | |||
193 | hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0); | 119 | hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0); |
194 | ExitOnFailure(hr, "Failed to copy key for passthrough pseudo bundle."); | 120 | ExitOnFailure(hr, "Failed to copy key for passthrough pseudo bundle."); |
195 | 121 | ||
196 | hr = StrAllocString(&pPassthroughPackage->sczCacheId, pPackage->sczCacheId, 0); | 122 | hr = StrAllocString(&pPassthroughPackage->sczCacheId, pPackage->sczCacheId, 0); |
197 | ExitOnFailure(hr, "Failed to copy cache id for passthrough pseudo bundle."); | 123 | ExitOnFailure(hr, "Failed to copy cache id for passthrough pseudo bundle."); |
198 | 124 | ||
199 | pPassthroughPackage->Exe.protocol = pPackage->Exe.protocol; | ||
200 | |||
201 | hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); | 125 | hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); |
202 | ExitOnFailure(hr, "Failed to create command-line arguments."); | 126 | ExitOnFailure(hr, "Failed to create command-line arguments."); |
203 | 127 | ||
204 | hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0); | 128 | hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0); |
205 | ExitOnFailure(hr, "Failed to copy install arguments for passthrough bundle package"); | 129 | ExitOnFailure(hr, "Failed to copy install arguments for passthrough bundle package"); |
206 | 130 | ||
207 | hr = StrAllocString(&pPassthroughPackage->Exe.sczRepairArguments, sczArguments, 0); | ||
208 | ExitOnFailure(hr, "Failed to copy related arguments for passthrough bundle package"); | ||
209 | |||
210 | pPassthroughPackage->Exe.fRepairable = TRUE; | ||
211 | |||
212 | hr = StrAllocString(&pPassthroughPackage->Exe.sczUninstallArguments, sczArguments, 0); | ||
213 | ExitOnFailure(hr, "Failed to copy uninstall arguments for passthrough bundle package"); | ||
214 | |||
215 | pPassthroughPackage->fUninstallable = TRUE; | ||
216 | |||
217 | // TODO: consider bringing this back in the near future. | ||
218 | //if (pDependencyProvider) | ||
219 | //{ | ||
220 | // pPassthroughPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE); | ||
221 | // ExitOnNull(pPassthroughPackage->rgDependencyProviders, hr, E_OUTOFMEMORY, "Failed to allocate memory for dependency providers."); | ||
222 | // pPassthroughPackage->cDependencyProviders = 1; | ||
223 | |||
224 | // pPassthroughPackage->rgDependencyProviders[0].fImported = pDependencyProvider->fImported; | ||
225 | |||
226 | // hr = StrAllocString(&pPassthroughPackage->rgDependencyProviders[0].sczKey, pDependencyProvider->sczKey, 0); | ||
227 | // ExitOnFailure(hr, "Failed to copy key for pseudo bundle."); | ||
228 | |||
229 | // hr = StrAllocString(&pPassthroughPackage->rgDependencyProviders[0].sczVersion, pDependencyProvider->sczVersion, 0); | ||
230 | // ExitOnFailure(hr, "Failed to copy version for pseudo bundle."); | ||
231 | |||
232 | // hr = StrAllocString(&pPassthroughPackage->rgDependencyProviders[0].sczDisplayName, pDependencyProvider->sczDisplayName, 0); | ||
233 | // ExitOnFailure(hr, "Failed to copy display name for pseudo bundle."); | ||
234 | //} | ||
235 | |||
236 | LExit: | 131 | LExit: |
237 | ReleaseStr(sczArguments); | 132 | ReleaseStr(sczArguments); |
238 | return hr; | 133 | return hr; |
@@ -290,14 +185,16 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | |||
290 | memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash); | 185 | memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash); |
291 | } | 186 | } |
292 | 187 | ||
293 | pPackage->Exe.fPseudoBundle = TRUE; | ||
294 | |||
295 | pPackage->type = BURN_PACKAGE_TYPE_EXE; | 188 | pPackage->type = BURN_PACKAGE_TYPE_EXE; |
296 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; | 189 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; |
297 | pPackage->qwInstallSize = qwSize; | 190 | pPackage->qwInstallSize = qwSize; |
298 | pPackage->qwSize = qwSize; | 191 | pPackage->qwSize = qwSize; |
299 | pPackage->fVital = TRUE; | 192 | pPackage->fVital = TRUE; |
300 | 193 | ||
194 | // Trust the BA to only use UPDATE_REPLACE_EMBEDDED when appropriate. | ||
195 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; | ||
196 | pPackage->Exe.fPseudoBundle = TRUE; | ||
197 | |||
301 | hr = StrAllocString(&pPackage->sczId, wzId, 0); | 198 | hr = StrAllocString(&pPackage->sczId, wzId, 0); |
302 | ExitOnFailure(hr, "Failed to copy id for update bundle."); | 199 | ExitOnFailure(hr, "Failed to copy id for update bundle."); |
303 | 200 | ||
@@ -307,10 +204,6 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | |||
307 | hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); | 204 | hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0); |
308 | ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); | 205 | ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); |
309 | 206 | ||
310 | // Trust the BA to only use UPDATE_REPLACE_EMBEDDED when appropriate. | ||
311 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; | ||
312 | pPackage->Exe.fSupportsAncestors = TRUE; | ||
313 | |||
314 | LExit: | 207 | LExit: |
315 | return hr; | 208 | return hr; |
316 | } \ No newline at end of file | 209 | } |
diff --git a/src/burn/engine/pseudobundle.h b/src/burn/engine/pseudobundle.h index 22132c5e..78a681df 100644 --- a/src/burn/engine/pseudobundle.h +++ b/src/burn/engine/pseudobundle.h | |||
@@ -6,25 +6,18 @@ | |||
6 | extern "C" { | 6 | extern "C" { |
7 | #endif | 7 | #endif |
8 | 8 | ||
9 | HRESULT PseudoBundleInitialize( | 9 | HRESULT PseudoBundleInitializeRelated( |
10 | __in BURN_PACKAGE* pPackage, | 10 | __in BURN_PACKAGE* pPackage, |
11 | __in BOOL fSupportsBurnProtocol, | 11 | __in BOOL fSupportsBurnProtocol, |
12 | __in BOOL fPerMachine, | 12 | __in BOOL fPerMachine, |
13 | __in_z LPCWSTR wzId, | 13 | __in_z LPCWSTR wzId, |
14 | #ifdef DEBUG | ||
14 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 15 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
15 | __in BOOTSTRAPPER_PACKAGE_STATE state, | 16 | #endif |
16 | __in BOOL fCached, | 17 | __in BOOL fCached, |
17 | __in_z LPCWSTR wzFilePath, | 18 | __in_z LPCWSTR wzFilePath, |
18 | __in_z LPCWSTR wzLocalSource, | ||
19 | __in_z_opt LPCWSTR wzDownloadSource, | ||
20 | __in DWORD64 qwSize, | 19 | __in DWORD64 qwSize, |
21 | __in BOOL fVital, | 20 | __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider |
22 | __in_z_opt LPCWSTR wzInstallArguments, | ||
23 | __in_z_opt LPCWSTR wzRepairArguments, | ||
24 | __in_z_opt LPCWSTR wzUninstallArguments, | ||
25 | __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider, | ||
26 | __in_opt const BYTE* pbHash, | ||
27 | __in const DWORD cbHash | ||
28 | ); | 21 | ); |
29 | HRESULT PseudoBundleInitializePassthrough( | 22 | HRESULT PseudoBundleInitializePassthrough( |
30 | __in BURN_PACKAGE* pPassthroughPackage, | 23 | __in BURN_PACKAGE* pPassthroughPackage, |
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index 4a694ef6..e2380aab 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
@@ -98,6 +98,37 @@ extern "C" void RelatedBundlesUninitialize( | |||
98 | } | 98 | } |
99 | 99 | ||
100 | 100 | ||
101 | extern "C" HRESULT RelatedBundleFindById( | ||
102 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
103 | __in_z LPCWSTR wzId, | ||
104 | __out BURN_RELATED_BUNDLE** ppRelatedBundle | ||
105 | ) | ||
106 | { | ||
107 | HRESULT hr = S_OK; | ||
108 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; | ||
109 | BURN_PACKAGE* pPackage = NULL; | ||
110 | |||
111 | *ppRelatedBundle = NULL; | ||
112 | |||
113 | for (DWORD i = 0; i < pRelatedBundles->cRelatedBundles; ++i) | ||
114 | { | ||
115 | pRelatedBundle = pRelatedBundles->rgRelatedBundles + i; | ||
116 | pPackage = &pRelatedBundle->package; | ||
117 | |||
118 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPackage->sczId, -1, wzId, -1)) | ||
119 | { | ||
120 | *ppRelatedBundle = pRelatedBundle; | ||
121 | ExitFunction1(hr = S_OK); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | hr = E_NOTFOUND; | ||
126 | |||
127 | LExit: | ||
128 | return hr; | ||
129 | } | ||
130 | |||
131 | |||
101 | // internal helper functions | 132 | // internal helper functions |
102 | 133 | ||
103 | static HRESULT LoadIfRelatedBundle( | 134 | static HRESULT LoadIfRelatedBundle( |
@@ -410,6 +441,7 @@ static HRESULT LoadRelatedBundleFromKey( | |||
410 | BOOL fCached = FALSE; | 441 | BOOL fCached = FALSE; |
411 | DWORD64 qwFileSize = 0; | 442 | DWORD64 qwFileSize = 0; |
412 | BURN_DEPENDENCY_PROVIDER dependencyProvider = { }; | 443 | BURN_DEPENDENCY_PROVIDER dependencyProvider = { }; |
444 | BURN_DEPENDENCY_PROVIDER* pBundleDependencyProvider = NULL; | ||
413 | 445 | ||
414 | // Only support progress from engines that are compatible. | 446 | // Only support progress from engines that are compatible. |
415 | hr = RegReadNumber(hkBundleId, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, &dwEngineProtocolVersion); | 447 | hr = RegReadNumber(hkBundleId, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, &dwEngineProtocolVersion); |
@@ -458,6 +490,11 @@ static HRESULT LoadRelatedBundleFromKey( | |||
458 | if (E_FILENOTFOUND != hr) | 490 | if (E_FILENOTFOUND != hr) |
459 | { | 491 | { |
460 | ExitOnFailure(hr, "Failed to read provider key from registry for bundle: %ls", wzRelatedBundleId); | 492 | ExitOnFailure(hr, "Failed to read provider key from registry for bundle: %ls", wzRelatedBundleId); |
493 | } | ||
494 | |||
495 | if (dependencyProvider.sczKey && *dependencyProvider.sczKey) | ||
496 | { | ||
497 | pBundleDependencyProvider = &dependencyProvider; | ||
461 | 498 | ||
462 | dependencyProvider.fImported = TRUE; | 499 | dependencyProvider.fImported = TRUE; |
463 | 500 | ||
@@ -480,11 +517,11 @@ static HRESULT LoadRelatedBundleFromKey( | |||
480 | 517 | ||
481 | pRelatedBundle->relationType = relationType; | 518 | pRelatedBundle->relationType = relationType; |
482 | 519 | ||
483 | hr = PseudoBundleInitialize(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, pRelatedBundle->relationType, | 520 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, |
484 | BOOTSTRAPPER_PACKAGE_STATE_PRESENT, fCached, sczCachePath, sczCachePath, NULL, qwFileSize, FALSE, | 521 | #ifdef DEBUG |
485 | L"-quiet", L"-repair -quiet", L"-uninstall -quiet", | 522 | pRelatedBundle->relationType, |
486 | (dependencyProvider.sczKey && *dependencyProvider.sczKey) ? &dependencyProvider : NULL, | 523 | #endif |
487 | NULL, 0); | 524 | fCached, sczCachePath, qwFileSize, pBundleDependencyProvider); |
488 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); | 525 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); |
489 | 526 | ||
490 | LExit: | 527 | LExit: |
diff --git a/src/burn/engine/relatedbundle.h b/src/burn/engine/relatedbundle.h index 01691c25..0113c8ee 100644 --- a/src/burn/engine/relatedbundle.h +++ b/src/burn/engine/relatedbundle.h | |||
@@ -14,6 +14,11 @@ HRESULT RelatedBundlesInitializeForScope( | |||
14 | void RelatedBundlesUninitialize( | 14 | void RelatedBundlesUninitialize( |
15 | __in BURN_RELATED_BUNDLES* pRelatedBundles | 15 | __in BURN_RELATED_BUNDLES* pRelatedBundles |
16 | ); | 16 | ); |
17 | HRESULT RelatedBundleFindById( | ||
18 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
19 | __in_z LPCWSTR wzId, | ||
20 | __out BURN_RELATED_BUNDLE** ppRelatedBundle | ||
21 | ); | ||
17 | 22 | ||
18 | #if defined(__cplusplus) | 23 | #if defined(__cplusplus) |
19 | } | 24 | } |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 35ddb22f..7e704c23 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
@@ -117,7 +117,7 @@ namespace Bootstrapper | |||
117 | ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); | 117 | ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); |
118 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 118 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
119 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 119 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
120 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); | 120 | ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); |
121 | Assert::Equal(dwIndex, pPlan->cExecuteActions); | 121 | Assert::Equal(dwIndex, pPlan->cExecuteActions); |
122 | 122 | ||
123 | fRollback = TRUE; | 123 | fRollback = TRUE; |
@@ -155,7 +155,7 @@ namespace Bootstrapper | |||
155 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 155 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
156 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 156 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
157 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 157 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
158 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | 158 | ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); |
159 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | 159 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
160 | 160 | ||
161 | Assert::Equal(4ul, pPlan->cExecutePackagesTotal); | 161 | Assert::Equal(4ul, pPlan->cExecutePackagesTotal); |
@@ -496,7 +496,7 @@ namespace Bootstrapper | |||
496 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 496 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
497 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 497 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
498 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 498 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
499 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); | 499 | ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); |
500 | Assert::Equal(dwIndex, pPlan->cExecuteActions); | 500 | Assert::Equal(dwIndex, pPlan->cExecuteActions); |
501 | 501 | ||
502 | fRollback = TRUE; | 502 | fRollback = TRUE; |
@@ -514,7 +514,7 @@ namespace Bootstrapper | |||
514 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 514 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
515 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 515 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
516 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 516 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
517 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | 517 | ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); |
518 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | 518 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
519 | 519 | ||
520 | Assert::Equal(2ul, pPlan->cExecutePackagesTotal); | 520 | Assert::Equal(2ul, pPlan->cExecutePackagesTotal); |
@@ -1154,7 +1154,11 @@ namespace Bootstrapper | |||
1154 | pRelatedBundle->fPlannable = TRUE; | 1154 | pRelatedBundle->fPlannable = TRUE; |
1155 | pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE; | 1155 | pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE; |
1156 | 1156 | ||
1157 | hr = PseudoBundleInitialize(&pRelatedBundle->package, TRUE, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, TRUE, wzFilePath, wzFilePath, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0); | 1157 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, TRUE, TRUE, wzId, |
1158 | #ifdef DEBUG | ||
1159 | pRelatedBundle->relationType, | ||
1160 | #endif | ||
1161 | TRUE, wzFilePath, 0, &dependencyProvider); | ||
1158 | NativeAssert::Succeeded(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId); | 1162 | NativeAssert::Succeeded(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId); |
1159 | 1163 | ||
1160 | ++pRelatedBundles->cRelatedBundles; | 1164 | ++pRelatedBundles->cRelatedBundles; |
@@ -1310,7 +1314,7 @@ namespace Bootstrapper | |||
1310 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); | 1314 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); |
1311 | } | 1315 | } |
1312 | 1316 | ||
1313 | void ValidateExecuteExePackage( | 1317 | void ValidateExecuteRelatedBundle( |
1314 | __in BURN_PLAN* pPlan, | 1318 | __in BURN_PLAN* pPlan, |
1315 | __in BOOL fRollback, | 1319 | __in BOOL fRollback, |
1316 | __in DWORD dwIndex, | 1320 | __in DWORD dwIndex, |
@@ -1320,10 +1324,25 @@ namespace Bootstrapper | |||
1320 | ) | 1324 | ) |
1321 | { | 1325 | { |
1322 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); | 1326 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); |
1327 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE, pAction->type); | ||
1328 | NativeAssert::StringEqual(wzPackageId, pAction->relatedBundle.pRelatedBundle->package.sczId); | ||
1329 | Assert::Equal<DWORD>(action, pAction->relatedBundle.action); | ||
1330 | NativeAssert::StringEqual(wzIgnoreDependencies, pAction->relatedBundle.sczIgnoreDependencies); | ||
1331 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); | ||
1332 | } | ||
1333 | |||
1334 | void ValidateExecuteExePackage( | ||
1335 | __in BURN_PLAN* pPlan, | ||
1336 | __in BOOL fRollback, | ||
1337 | __in DWORD dwIndex, | ||
1338 | __in LPCWSTR wzPackageId, | ||
1339 | __in BOOTSTRAPPER_ACTION_STATE action | ||
1340 | ) | ||
1341 | { | ||
1342 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); | ||
1323 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type); | 1343 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type); |
1324 | NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId); | 1344 | NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId); |
1325 | Assert::Equal<DWORD>(action, pAction->exePackage.action); | 1345 | Assert::Equal<DWORD>(action, pAction->exePackage.action); |
1326 | NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies); | ||
1327 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); | 1346 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); |
1328 | } | 1347 | } |
1329 | 1348 | ||