aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/bundlepackageengine.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-03-30 17:08:40 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-04-01 22:06:11 -0500
commit386a3578413ba16b3c0615d47870ee44a0e461f6 (patch)
tree1dfcea9e5080f1f15cc880aba1541a962426c58b /src/burn/engine/bundlepackageengine.cpp
parentd97c0d1685ef4c3840776327e76ce25d4dbdbeb1 (diff)
downloadwix-386a3578413ba16b3c0615d47870ee44a0e461f6.tar.gz
wix-386a3578413ba16b3c0615d47870ee44a0e461f6.tar.bz2
wix-386a3578413ba16b3c0615d47870ee44a0e461f6.zip
Implement BundlePackage.
3693
Diffstat (limited to 'src/burn/engine/bundlepackageengine.cpp')
-rw-r--r--src/burn/engine/bundlepackageengine.cpp272
1 files changed, 261 insertions, 11 deletions
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp
index 89488b91..f3badfc1 100644
--- a/src/burn/engine/bundlepackageengine.cpp
+++ b/src/burn/engine/bundlepackageengine.cpp
@@ -2,16 +2,80 @@
2 2
3#include "precomp.h" 3#include "precomp.h"
4 4
5static HRESULT ExecuteBundle(
6 __in BURN_CACHE* pCache,
7 __in BURN_VARIABLES* pVariables,
8 __in BOOL fRollback,
9 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
10 __in LPVOID pvContext,
11 __in BOOTSTRAPPER_ACTION_STATE action,
12 __in BOOTSTRAPPER_RELATION_TYPE relationType,
13 __in BURN_PACKAGE* pPackage,
14 __in_z_opt LPCWSTR wzIgnoreDependencies,
15 __in_z_opt LPCWSTR wzAncestors,
16 __in_z_opt LPCWSTR wzEngineWorkingDirectory,
17 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
18 );
5static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType( 19static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType(
6 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relationType 20 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relationType
7 ); 21 );
8 22
9// function definitions 23// function definitions
10 24
25extern "C" HRESULT BundlePackageEngineParsePackageFromXml(
26 __in IXMLDOMNode* pixnBundlePackage,
27 __in BURN_PACKAGE* pPackage
28 )
29{
30 HRESULT hr = S_OK;
31 BOOL fFoundXml = FALSE;
32 LPWSTR scz = NULL;
33
34 // @DetectCondition
35 hr = XmlGetAttributeEx(pixnBundlePackage, L"BundleId", &pPackage->Bundle.sczBundleId);
36 ExitOnRequiredXmlQueryFailure(hr, "Failed to get @BundleId.");
37
38 // @InstallArguments
39 hr = XmlGetAttributeEx(pixnBundlePackage, L"InstallArguments", &pPackage->Bundle.sczInstallArguments);
40 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArguments.");
41
42 // @UninstallArguments
43 hr = XmlGetAttributeEx(pixnBundlePackage, L"UninstallArguments", &pPackage->Bundle.sczUninstallArguments);
44 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments.");
45
46 // @RepairArguments
47 hr = XmlGetAttributeEx(pixnBundlePackage, L"RepairArguments", &pPackage->Bundle.sczRepairArguments);
48 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArguments.");
49
50 // @SupportsBurnProtocol
51 hr = XmlGetYesNoAttribute(pixnBundlePackage, L"SupportsBurnProtocol", &pPackage->Bundle.fSupportsBurnProtocol);
52 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @SupportsBurnProtocol.");
53
54 // @Win64
55 hr = XmlGetYesNoAttribute(pixnBundlePackage, L"Win64", &pPackage->Bundle.fWin64);
56 ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Win64.");
57
58 hr = ExeEngineParseExitCodesFromXml(pixnBundlePackage, &pPackage->Bundle.rgExitCodes, &pPackage->Bundle.cExitCodes);
59 ExitOnFailure(hr, "Failed to parse exit codes.");
60
61 hr = ExeEngineParseCommandLineArgumentsFromXml(pixnBundlePackage, &pPackage->Bundle.rgCommandLineArguments, &pPackage->Bundle.cCommandLineArguments);
62 ExitOnFailure(hr, "Failed to parse command lines.");
63
64 hr = StrAllocFormatted(&pPackage->Bundle.sczRegistrationKey, L"%ls\\%ls", BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pPackage->Bundle.sczBundleId);
65 ExitOnFailure(hr, "Failed to build uninstall registry key path.");
66
67LExit:
68 ReleaseStr(scz);
69
70 return hr;
71}
72
11extern "C" void BundlePackageEnginePackageUninitialize( 73extern "C" void BundlePackageEnginePackageUninitialize(
12 __in BURN_PACKAGE* pPackage 74 __in BURN_PACKAGE* pPackage
13 ) 75 )
14{ 76{
77 ReleaseStr(pPackage->Bundle.sczBundleId);
78 ReleaseStr(pPackage->Bundle.sczRegistrationKey);
15 ReleaseStr(pPackage->Bundle.sczInstallArguments); 79 ReleaseStr(pPackage->Bundle.sczInstallArguments);
16 ReleaseStr(pPackage->Bundle.sczRepairArguments); 80 ReleaseStr(pPackage->Bundle.sczRepairArguments);
17 ReleaseStr(pPackage->Bundle.sczUninstallArguments); 81 ReleaseStr(pPackage->Bundle.sczUninstallArguments);
@@ -32,6 +96,44 @@ extern "C" void BundlePackageEnginePackageUninitialize(
32 memset(&pPackage->Bundle, 0, sizeof(pPackage->Bundle)); 96 memset(&pPackage->Bundle, 0, sizeof(pPackage->Bundle));
33} 97}
34 98
99extern "C" HRESULT BundlePackageEngineDetectPackage(
100 __in BURN_PACKAGE* pPackage
101 )
102{
103 HRESULT hr = S_OK;
104 HKEY hkRegistration = NULL;
105 DWORD dwInstalled = 0;
106 BOOL fDetected = FALSE;
107 HKEY hkRoot = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
108 REG_KEY_BITNESS bitness = pPackage->Bundle.fWin64 ? REG_KEY_64BIT : REG_KEY_32BIT;
109
110 // TODO: detect all related bundles, so that the Obsolete state can be detected.
111 hr = RegOpenEx(hkRoot, pPackage->Bundle.sczRegistrationKey, KEY_QUERY_VALUE, bitness, &hkRegistration);
112 if (SUCCEEDED(hr))
113 {
114 hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled);
115 }
116
117 // Not finding the key or value is okay.
118 if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
119 {
120 hr = S_OK;
121 }
122
123 fDetected = (1 == dwInstalled);
124
125 // update detect state
126 pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
127
128 if (pPackage->fCanAffectRegistration)
129 {
130 pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
131 }
132
133 ReleaseRegKey(hkRegistration);
134 return hr;
135}
136
35// 137//
36// PlanCalculate - calculates the execute and rollback state for the requested package state. 138// PlanCalculate - calculates the execute and rollback state for the requested package state.
37// 139//
@@ -151,6 +253,79 @@ LExit:
151// 253//
152// PlanAdd - adds the calculated execute and rollback actions for the package. 254// PlanAdd - adds the calculated execute and rollback actions for the package.
153// 255//
256extern "C" HRESULT BundlePackageEnginePlanAddPackage(
257 __in BURN_PACKAGE* pPackage,
258 __in BURN_PLAN* pPlan,
259 __in BURN_LOGGING* pLog,
260 __in BURN_VARIABLES* pVariables
261 )
262{
263 HRESULT hr = S_OK;
264 BURN_EXECUTE_ACTION* pAction = NULL;
265
266 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
267 ExitOnFailure(hr, "Failed to plan package dependency actions.");
268
269 // add rollback action
270 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback)
271 {
272 hr = PlanAppendRollbackAction(pPlan, &pAction);
273 ExitOnFailure(hr, "Failed to append rollback action.");
274
275 pAction->type = BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE;
276 pAction->bundlePackage.pPackage = pPackage;
277 pAction->bundlePackage.action = pPackage->rollback;
278
279 if (pPackage->Bundle.wzAncestors)
280 {
281 hr = StrAllocString(&pAction->bundlePackage.sczAncestors, pPackage->Bundle.wzAncestors, 0);
282 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
283 }
284
285 if (pPackage->Bundle.wzEngineWorkingDirectory)
286 {
287 hr = StrAllocString(&pAction->bundlePackage.sczEngineWorkingDirectory, pPackage->Bundle.wzEngineWorkingDirectory, 0);
288 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
289 }
290
291 LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors.
292
293 hr = PlanExecuteCheckpoint(pPlan);
294 ExitOnFailure(hr, "Failed to append execute checkpoint.");
295 }
296
297 // add execute action
298 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute)
299 {
300 hr = PlanAppendExecuteAction(pPlan, &pAction);
301 ExitOnFailure(hr, "Failed to append execute action.");
302
303 pAction->type = BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE;
304 pAction->bundlePackage.pPackage = pPackage;
305 pAction->bundlePackage.action = pPackage->execute;
306
307 if (pPackage->Bundle.wzAncestors)
308 {
309 hr = StrAllocString(&pAction->bundlePackage.sczAncestors, pPackage->Bundle.wzAncestors, 0);
310 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
311 }
312
313 if (pPackage->Bundle.wzEngineWorkingDirectory)
314 {
315 hr = StrAllocString(&pAction->bundlePackage.sczEngineWorkingDirectory, pPackage->Bundle.wzEngineWorkingDirectory, 0);
316 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
317 }
318
319 LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors.
320 }
321
322LExit:
323 return hr;
324}
325
326//
327// PlanAdd - adds the calculated execute and rollback actions for the related bundle.
328//
154extern "C" HRESULT BundlePackageEnginePlanAddRelatedBundle( 329extern "C" HRESULT BundlePackageEnginePlanAddRelatedBundle(
155 __in_opt DWORD *pdwInsertSequence, 330 __in_opt DWORD *pdwInsertSequence,
156 __in BURN_RELATED_BUNDLE* pRelatedBundle, 331 __in BURN_RELATED_BUNDLE* pRelatedBundle,
@@ -164,7 +339,7 @@ extern "C" HRESULT BundlePackageEnginePlanAddRelatedBundle(
164 BURN_PACKAGE* pPackage = &pRelatedBundle->package; 339 BURN_PACKAGE* pPackage = &pRelatedBundle->package;
165 340
166 hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan); 341 hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan);
167 ExitOnFailure(hr, "Failed to plan package dependency actions."); 342 ExitOnFailure(hr, "Failed to plan related bundle dependency actions.");
168 343
169 // add execute action 344 // add execute action
170 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) 345 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute)
@@ -240,6 +415,26 @@ LExit:
240 return hr; 415 return hr;
241} 416}
242 417
418extern "C" HRESULT BundlePackageEngineExecutePackage(
419 __in BURN_EXECUTE_ACTION* pExecuteAction,
420 __in BURN_CACHE* pCache,
421 __in BURN_VARIABLES* pVariables,
422 __in BOOL fRollback,
423 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
424 __in LPVOID pvContext,
425 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
426 )
427{
428 BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->bundlePackage.action;
429 LPCWSTR wzIgnoreDependencies = pExecuteAction->bundlePackage.sczIgnoreDependencies;
430 LPCWSTR wzAncestors = pExecuteAction->bundlePackage.sczAncestors;
431 LPCWSTR wzEngineWorkingDirectory = pExecuteAction->bundlePackage.sczEngineWorkingDirectory;
432 BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_CHAIN_PACKAGE;
433 BURN_PACKAGE* pPackage = pExecuteAction->bundlePackage.pPackage;
434
435 return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
436}
437
243extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle( 438extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
244 __in BURN_EXECUTE_ACTION* pExecuteAction, 439 __in BURN_EXECUTE_ACTION* pExecuteAction,
245 __in BURN_CACHE* pCache, 440 __in BURN_CACHE* pCache,
@@ -250,6 +445,57 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
250 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 445 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
251 ) 446 )
252{ 447{
448 BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action;
449 LPCWSTR wzIgnoreDependencies = pExecuteAction->relatedBundle.sczIgnoreDependencies;
450 LPCWSTR wzAncestors = pExecuteAction->relatedBundle.sczAncestors;
451 LPCWSTR wzEngineWorkingDirectory = pExecuteAction->relatedBundle.sczEngineWorkingDirectory;
452 BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle;
453 BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pRelatedBundle->planRelationType);
454 BURN_PACKAGE* pPackage = &pRelatedBundle->package;
455
456 return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
457}
458
459extern "C" void BundlePackageEngineUpdateInstallRegistrationState(
460 __in BURN_EXECUTE_ACTION* pAction,
461 __in HRESULT hrExecute
462 )
463{
464 BURN_PACKAGE* pPackage = pAction->bundlePackage.pPackage;
465
466 if (FAILED(hrExecute) || !pPackage->fCanAffectRegistration)
467 {
468 ExitFunction();
469 }
470
471 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->bundlePackage.action)
472 {
473 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
474 }
475 else
476 {
477 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
478 }
479
480LExit:
481 return;
482}
483
484static HRESULT ExecuteBundle(
485 __in BURN_CACHE* pCache,
486 __in BURN_VARIABLES* pVariables,
487 __in BOOL fRollback,
488 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
489 __in LPVOID pvContext,
490 __in BOOTSTRAPPER_ACTION_STATE action,
491 __in BOOTSTRAPPER_RELATION_TYPE relationType,
492 __in BURN_PACKAGE* pPackage,
493 __in_z_opt LPCWSTR wzIgnoreDependencies,
494 __in_z_opt LPCWSTR wzAncestors,
495 __in_z_opt LPCWSTR wzEngineWorkingDirectory,
496 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
497 )
498{
253 HRESULT hr = S_OK; 499 HRESULT hr = S_OK;
254 LPCWSTR wzArguments = NULL; 500 LPCWSTR wzArguments = NULL;
255 LPWSTR sczCachedDirectory = NULL; 501 LPWSTR sczCachedDirectory = NULL;
@@ -264,10 +510,6 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
264 PROCESS_INFORMATION pi = { }; 510 PROCESS_INFORMATION pi = { };
265 DWORD dwExitCode = 0; 511 DWORD dwExitCode = 0;
266 GENERIC_EXECUTE_MESSAGE message = { }; 512 GENERIC_EXECUTE_MESSAGE message = { };
267 BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action;
268 BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle;
269 BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pRelatedBundle->planRelationType);
270 BURN_PACKAGE* pPackage = &pRelatedBundle->package;
271 BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload; 513 BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
272 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); 514 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType);
273 LPCWSTR wzOperationCommandLine = NULL; 515 LPCWSTR wzOperationCommandLine = NULL;
@@ -376,21 +618,29 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
376 } 618 }
377 619
378 // Add the list of dependencies to ignore, if any, to the burn command line. 620 // Add the list of dependencies to ignore, if any, to the burn command line.
379 if (pExecuteAction->relatedBundle.sczIgnoreDependencies) 621 if (BOOTSTRAPPER_RELATION_CHAIN_PACKAGE == relationType)
380 { 622 {
381 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->relatedBundle.sczIgnoreDependencies); 623 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls=ALL", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES);
624 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line.");
625 }
626 else if (wzIgnoreDependencies)
627 {
628 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, wzIgnoreDependencies);
382 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line."); 629 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line.");
383 } 630 }
384 631
385 // Add the list of ancestors, if any, to the burn command line. 632 // Add the list of ancestors, if any, to the burn command line.
386 if (pExecuteAction->relatedBundle.sczAncestors) 633 if (wzAncestors)
387 { 634 {
388 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->relatedBundle.sczAncestors); 635 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, wzAncestors);
389 ExitOnFailure(hr, "Failed to append the list of ancestors to the command line."); 636 ExitOnFailure(hr, "Failed to append the list of ancestors to the command line.");
390 } 637 }
391 638
392 hr = CoreAppendEngineWorkingDirectoryToCommandLine(pExecuteAction->relatedBundle.sczEngineWorkingDirectory, &sczBaseCommand, NULL); 639 if (wzEngineWorkingDirectory)
393 ExitOnFailure(hr, "Failed to append the custom working directory to the bundlepackage command line."); 640 {
641 hr = CoreAppendEngineWorkingDirectoryToCommandLine(wzEngineWorkingDirectory, &sczBaseCommand, NULL);
642 ExitOnFailure(hr, "Failed to append the custom working directory to the bundlepackage command line.");
643 }
394 644
395 hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczBaseCommand, NULL); 645 hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczBaseCommand, NULL);
396 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); 646 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);