@joebigelow / wix / commits / 90cdf39e

Don't plan payloads.

Contributes to #3640 and #5253

Sean Hall committed Apr 16, 2021 at 10:09 UTC 90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd
24 files changed +718 -1580
src/engine/apply.cpp
+350 -408
@@ -13,18 +13,28 @@ const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2;
13
14 // structs
15
16 -struct BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT
16 +typedef struct _BURN_CACHE_CONTEXT
17 {
18 BURN_USER_EXPERIENCE* pUX;
19 + BURN_VARIABLES* pVariables;
20 + BURN_PAYLOADS* pPayloads;
21 + HANDLE hPipe;
22 + HANDLE hSourceEngineFile;
23 + DWORD64 qwTotalCacheSize;
24 + DWORD64 qwSuccessfulCacheProgress;
25 + LPCWSTR wzLayoutDirectory;
26 +} BURN_CACHE_CONTEXT;
27 +
28 +typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT
29 +{
30 + BURN_CACHE_CONTEXT* pCacheContext;
31 BURN_CONTAINER* pContainer;
32 BURN_PACKAGE* pPackage;
33 BURN_PAYLOAD* pPayload;
22 - DWORD64 qwCacheProgress;
23 - DWORD64 qwTotalCacheSize;
34
35 BOOL fCancel;
36 BOOL fError;
27 -};
37 +} BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT;
38
39 typedef struct _BURN_EXECUTE_CONTEXT
40 {
@@ -56,50 +66,49 @@ static HRESULT ExecuteDependentRegistrationActions(
66 __in_ecount(cActions) const BURN_DEPENDENT_REGISTRATION_ACTION* rgActions,
67 __in DWORD cActions
68 );
59 -static HRESULT ExtractContainer(
60 - __in HANDLE hSourceEngineFile,
61 - __in BURN_CONTAINER* pContainer,
62 - __in_z LPCWSTR wzContainerPath,
63 - __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads,
64 - __in DWORD cExtractPayloads
69 +static HRESULT ApplyCachePackage(
70 + __in BURN_CACHE_CONTEXT* pContext,
71 + __in BURN_PACKAGE* pPackage
72 );
66 -static void UpdateCacheSuccessProgress(
67 - __in BURN_PLAN* pPlan,
68 - __in BURN_CACHE_ACTION* pCacheAction,
69 - __inout DWORD64* pqwSuccessfulCachedProgress
73 +static HRESULT ApplyExtractContainer(
74 + __in BURN_CACHE_CONTEXT* pContext,
75 + __in BURN_CONTAINER* pContainer
76 + );
77 +static HRESULT ApplyLayoutBundle(
78 + __in BURN_CACHE_CONTEXT* pContext,
79 + __in BURN_PAYLOAD_GROUP* pPayloads,
80 + __in_z LPCWSTR wzExecutableName,
81 + __in_z LPCWSTR wzUnverifiedPath
82 + );
83 +static HRESULT ApplyLayoutContainer(
84 + __in BURN_CACHE_CONTEXT* pContext,
85 + __in BURN_CONTAINER* pContainer
86 + );
87 +static HRESULT ApplyProcessPayload(
88 + __in BURN_CACHE_CONTEXT* pContext,
89 + __in_opt BURN_PACKAGE* pPackage,
90 + __in BURN_PAYLOAD* pPayload
91 + );
92 +static HRESULT ExtractContainer(
93 + __in BURN_CACHE_CONTEXT* pContext,
94 + __in BURN_CONTAINER* pContainer
95 );
96 static HRESULT LayoutBundle(
72 - __in HANDLE hSourceEngineFile,
73 - __in BURN_USER_EXPERIENCE* pUX,
74 - __in BURN_VARIABLES* pVariables,
75 - __in HANDLE hPipe,
97 + __in BURN_CACHE_CONTEXT* pContext,
98 __in_z LPCWSTR wzExecutableName,
77 - __in_z LPCWSTR wzLayoutDirectory,
78 - __in_z LPCWSTR wzUnverifiedPath,
79 - __in DWORD64 qwSuccessfulCacheProgress,
80 - __in DWORD64 qwTotalCacheSize
99 + __in_z LPCWSTR wzUnverifiedPath
100 );
101 static HRESULT AcquireContainerOrPayload(
83 - __in BURN_USER_EXPERIENCE* pUX,
84 - __in BURN_VARIABLES* pVariables,
102 + __in BURN_CACHE_CONTEXT* pContext,
103 __in_opt BURN_CONTAINER* pContainer,
104 __in_opt BURN_PACKAGE* pPackage,
87 - __in_opt BURN_PAYLOAD* pPayload,
88 - __in LPCWSTR wzDestinationPath,
89 - __in DWORD64 qwSuccessfulCacheProgress,
90 - __in DWORD64 qwTotalCacheSize
105 + __in_opt BURN_PAYLOAD* pPayload
106 );
107 static HRESULT LayoutOrCacheContainerOrPayload(
93 - __in BURN_USER_EXPERIENCE* pUX,
94 - __in HANDLE hPipe,
108 + __in BURN_CACHE_CONTEXT* pContext,
109 __in_opt BURN_CONTAINER* pContainer,
110 __in_opt BURN_PACKAGE* pPackage,
111 __in_opt BURN_PAYLOAD* pPayload,
98 - __in BOOL fAlreadyProvidedProgress,
99 - __in DWORD64 qwSuccessfullyCacheProgress,
100 - __in DWORD64 qwTotalCacheSize,
101 - __in_z_opt LPCWSTR wzLayoutDirectory,
102 - __in_z LPCWSTR wzUnverifiedPath,
112 __in BOOL fMove,
113 __in DWORD cTryAgainAttempts,
114 __out BOOL* pfRetry
@@ -461,268 +470,83 @@ extern "C" HRESULT ApplyCache(
470 {
471 HRESULT hr = S_OK;
472 DWORD dwCheckpoint = 0;
464 - BOOL fRetry = FALSE;
465 - DWORD iRetryAction = BURN_PLAN_INVALID_ACTION_INDEX;
466 - BURN_PACKAGE* pStartedPackage = NULL;
467 - DWORD64 qwSuccessfulCachedProgress = 0;
468 -
469 - // Allow us to retry and skip packages.
470 - DWORD iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX;
471 - DWORD iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX;
473 + BURN_CACHE_CONTEXT cacheContext = { };
474 + BURN_PACKAGE* pPackage = NULL;
475
476 *pfRollback = FALSE;
477
478 hr = UserExperienceOnCacheBegin(pUX);
479 ExitOnRootFailure(hr, "BA aborted cache.");
480
478 - do
479 - {
480 - hr = S_OK;
481 - fRetry = FALSE;
481 + cacheContext.hSourceEngineFile = hSourceEngineFile;
482 + cacheContext.pPayloads = pPlan->pPayloads;
483 + cacheContext.pUX = pUX;
484 + cacheContext.pVariables = pVariables;
485 + cacheContext.qwTotalCacheSize = pPlan->qwCacheSizeTotal;
486 + cacheContext.wzLayoutDirectory = pPlan->sczLayoutDirectory;
487
483 - // Allow us to retry just a container or payload.
484 - LPCWSTR wzRetryId = NULL;
485 - DWORD iRetryContainerOrPayloadAction = BURN_PLAN_INVALID_ACTION_INDEX;
486 - BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
488 + for (DWORD i = 0; i < pPlan->cCacheActions; ++i)
489 + {
490 + BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i;
491 + cacheContext.hPipe = hPipe;
492 + pPackage = NULL;
493
488 - // cache actions
489 - for (DWORD i = (BURN_PLAN_INVALID_ACTION_INDEX == iRetryAction) ? 0 : iRetryAction; SUCCEEDED(hr) && i < pPlan->cCacheActions; ++i)
494 + switch (pCacheAction->type)
495 {
491 - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i;
492 - BOOL fRetryContainerOrPayload = FALSE;
493 - cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
494 -
495 - if (pCacheAction->fSkipUntilRetried)
496 - {
497 - // If this action was retried, let's make sure it will not be skipped any longer.
498 - if (iRetryAction == i)
499 - {
500 - pCacheAction->fSkipUntilRetried = FALSE;
501 - }
502 - else // skip the action.
503 - {
504 - continue;
505 - }
506 - }
507 -
508 - switch (pCacheAction->type)
509 - {
510 - case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
511 - dwCheckpoint = pCacheAction->checkpoint.dwId;
512 - break;
513 -
514 - case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
515 - hr = LayoutBundle(hSourceEngineFile, pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal);
516 - if (SUCCEEDED(hr))
517 - {
518 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
519 - ++(*pcOverallProgressTicks);
520 -
521 - hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks);
522 - if (FAILED(hr))
523 - {
524 - LogErrorId(hr, MSG_USER_CANCELED, L"layout bundle", NULL, NULL);
525 - }
526 - }
527 - break;
528 -
529 - case BURN_CACHE_ACTION_TYPE_PACKAGE_START:
530 - iPackageStartAction = i; // if we retry this package, we'll start here in the plan.
531 - iPackageCompleteAction = pCacheAction->packageStart.iPackageCompleteAction; // if we ignore this package, we'll start after the complete action in the plan.
532 - pStartedPackage = pCacheAction->packageStart.pPackage;
533 -
534 - hr = UserExperienceOnCachePackageBegin(pUX, pStartedPackage->sczId, pCacheAction->packageStart.cCachePayloads, pCacheAction->packageStart.qwCachePayloadSizeTotal);
535 - if (FAILED(hr))
536 - {
537 - LogErrorId(hr, MSG_USER_CANCELED, L"begin cache package", pStartedPackage->sczId, NULL);
538 - }
539 - break;
540 -
541 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER:
542 - hr = AcquireContainerOrPayload(pUX, pVariables, pCacheAction->resolveContainer.pContainer, NULL, NULL, pCacheAction->resolveContainer.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal);
543 - if (SUCCEEDED(hr))
544 - {
545 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
546 - }
547 - else
548 - {
549 - LogErrorId(hr, MSG_FAILED_ACQUIRE_CONTAINER, pCacheAction->resolveContainer.pContainer->sczId, pCacheAction->resolveContainer.sczUnverifiedPath, NULL);
550 - }
551 - break;
552 -
553 - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER:
554 - // If this action is to be skipped until the acquire action is not skipped and the other
555 - // action is still being skipped then skip this action.
556 - if (BURN_PLAN_INVALID_ACTION_INDEX != pCacheAction->extractContainer.iSkipUntilAcquiredByAction && pPlan->rgCacheActions[pCacheAction->extractContainer.iSkipUntilAcquiredByAction].fSkipUntilRetried)
557 - {
558 - break;
559 - }
560 -
561 - hr = ExtractContainer(hSourceEngineFile, pCacheAction->extractContainer.pContainer, pCacheAction->extractContainer.sczContainerUnverifiedPath, pCacheAction->extractContainer.rgPayloads, pCacheAction->extractContainer.cPayloads);
562 - if (FAILED(hr))
563 - {
564 - LogErrorId(hr, MSG_FAILED_EXTRACT_CONTAINER, pCacheAction->extractContainer.pContainer->sczId, pCacheAction->extractContainer.sczContainerUnverifiedPath, NULL);
565 - }
566 - break;
567 -
568 - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER:
569 - hr = LayoutOrCacheContainerOrPayload(pUX, hPipe, pCacheAction->layoutContainer.pContainer, pCacheAction->layoutContainer.pPackage, NULL, pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, pCacheAction->layoutContainer.sczLayoutDirectory, pCacheAction->layoutContainer.sczUnverifiedPath, pCacheAction->layoutContainer.fMove, pCacheAction->layoutContainer.cTryAgainAttempts, &fRetryContainerOrPayload);
570 - if (SUCCEEDED(hr))
571 - {
572 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
573 - }
574 - else
575 - {
576 - LogErrorId(hr, MSG_FAILED_LAYOUT_CONTAINER, pCacheAction->layoutContainer.pContainer->sczId, pCacheAction->layoutContainer.sczLayoutDirectory, pCacheAction->layoutContainer.sczUnverifiedPath);
577 -
578 - if (fRetryContainerOrPayload)
579 - {
580 - wzRetryId = pCacheAction->layoutContainer.pContainer->sczId;
581 - iRetryContainerOrPayloadAction = pCacheAction->layoutContainer.iTryAgainAction;
582 -
583 - ++pCacheAction->layoutContainer.cTryAgainAttempts;
584 - }
585 - }
586 - break;
587 -
588 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD:
589 - hr = AcquireContainerOrPayload(pUX, pVariables, NULL, pCacheAction->resolvePayload.pPackage, pCacheAction->resolvePayload.pPayload, pCacheAction->resolvePayload.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal);
590 - if (SUCCEEDED(hr))
591 - {
592 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
593 - }
594 - else
595 - {
596 - LogErrorId(hr, MSG_FAILED_ACQUIRE_PAYLOAD, pCacheAction->resolvePayload.pPayload->sczKey, pCacheAction->resolvePayload.sczUnverifiedPath, NULL);
597 - }
598 - break;
599 -
600 - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD:
601 - hr = LayoutOrCacheContainerOrPayload(pUX, pCacheAction->cachePayload.pPackage->fPerMachine ? hPipe : INVALID_HANDLE_VALUE, NULL, pCacheAction->cachePayload.pPackage, pCacheAction->cachePayload.pPayload, pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, NULL, pCacheAction->cachePayload.sczUnverifiedPath, pCacheAction->cachePayload.fMove, pCacheAction->cachePayload.cTryAgainAttempts, &fRetryContainerOrPayload);
602 - if (SUCCEEDED(hr))
603 - {
604 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
605 - }
606 - else
607 - {
608 - LogErrorId(hr, MSG_FAILED_CACHE_PAYLOAD, pCacheAction->cachePayload.pPayload->sczKey, pCacheAction->cachePayload.sczUnverifiedPath, NULL);
609 -
610 - if (fRetryContainerOrPayload)
611 - {
612 - wzRetryId = pCacheAction->cachePayload.pPayload->sczKey;
613 - iRetryContainerOrPayloadAction = pCacheAction->cachePayload.iTryAgainAction;
614 -
615 - ++pCacheAction->cachePayload.cTryAgainAttempts;
616 - }
617 - }
618 - break;
619 -
620 - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD:
621 - hr = LayoutOrCacheContainerOrPayload(pUX, hPipe, NULL, pCacheAction->layoutPayload.pPackage, pCacheAction->layoutPayload.pPayload, pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, pCacheAction->layoutPayload.sczLayoutDirectory, pCacheAction->layoutPayload.sczUnverifiedPath, pCacheAction->layoutPayload.fMove, pCacheAction->layoutPayload.cTryAgainAttempts, &fRetryContainerOrPayload);
622 - if (SUCCEEDED(hr))
623 - {
624 - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress);
625 - }
626 - else
627 - {
628 - LogErrorId(hr, MSG_FAILED_LAYOUT_PAYLOAD, pCacheAction->layoutPayload.pPayload->sczKey, pCacheAction->layoutPayload.sczLayoutDirectory, pCacheAction->layoutPayload.sczUnverifiedPath);
629 -
630 - if (fRetryContainerOrPayload)
631 - {
632 - wzRetryId = pCacheAction->layoutPayload.pPayload->sczKey;
633 - iRetryContainerOrPayloadAction = pCacheAction->layoutPayload.iTryAgainAction;
634 -
635 - ++pCacheAction->layoutPayload.cTryAgainAttempts;
636 - }
637 - }
638 - break;
639 -
640 - case BURN_CACHE_ACTION_TYPE_PACKAGE_STOP:
641 - AssertSz(pStartedPackage == pCacheAction->packageStop.pPackage, "Expected package started cached to be the same as the package checkpointed.");
496 + case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
497 + dwCheckpoint = pCacheAction->checkpoint.dwId;
498 + break;
499
643 - hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks + 1);
644 - if (FAILED(hr))
645 - {
646 - LogErrorId(hr, MSG_USER_CANCELED, L"end cache package", NULL, NULL);
647 - }
648 - else
649 - {
650 - ++(*pcOverallProgressTicks);
500 + case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
501 + hr = ApplyLayoutBundle(&cacheContext, pCacheAction->bundleLayout.pPayloadGroup, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczUnverifiedPath);
502 + ExitOnFailure(hr, "Failed cache action: %ls", L"layout bundle");
503
652 - UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction);
504 + ++(*pcOverallProgressTicks);
505
654 - pStartedPackage->hrCacheResult = hr;
506 + hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks);
507 + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"layout bundle");
508
656 - iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX;
657 - iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX;
658 - pStartedPackage = NULL;
659 - }
660 - break;
509 + break;
510
662 - case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
663 - if (!::SetEvent(pCacheAction->syncpoint.hEvent))
664 - {
665 - ExitWithLastError(hr, "Failed to set syncpoint event.");
666 - }
667 - break;
511 + case BURN_CACHE_ACTION_TYPE_PACKAGE:
512 + pPackage = pCacheAction->package.pPackage;
513
669 - default:
670 - AssertSz(FALSE, "Unknown cache action.");
671 - break;
514 + if (!pPackage->fPerMachine && !cacheContext.wzLayoutDirectory)
515 + {
516 + cacheContext.hPipe = INVALID_HANDLE_VALUE;
517 }
673 - }
674 -
675 - if (BURN_PLAN_INVALID_ACTION_INDEX != iRetryContainerOrPayloadAction)
676 - {
677 - Assert(wzRetryId);
518
679 - LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, wzRetryId, NULL, NULL);
519 + hr = ApplyCachePackage(&cacheContext, pPackage);
520 + ExitOnFailure(hr, "Failed cache action: %ls", L"cache package");
521
681 - iRetryAction = iRetryContainerOrPayloadAction;
682 - fRetry = TRUE;
683 - }
684 - else if (pStartedPackage)
685 - {
686 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iPackageStartAction);
687 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iPackageCompleteAction);
522 + ++(*pcOverallProgressTicks);
523
689 - cachePackageCompleteAction = SUCCEEDED(hr) || pStartedPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE;
690 - UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction);
691 - if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction)
692 - {
693 - LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pStartedPackage->sczId, NULL, NULL);
524 + hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks);
525 + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"cache package");
526
695 - iRetryAction = iPackageStartAction;
696 - fRetry = TRUE;
697 - }
698 - else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && !pStartedPackage->fVital) // ignore non-vital download failures.
699 - {
700 - LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pStartedPackage->sczId, hr);
527 + break;
528
702 - ++(*pcOverallProgressTicks); // add progress even though we didn't fully cache the package.
529 + case BURN_CACHE_ACTION_TYPE_CONTAINER:
530 + Assert(pPlan->sczLayoutDirectory);
531 + hr = ApplyLayoutContainer(&cacheContext, pCacheAction->container.pContainer);
532 + ExitOnFailure(hr, "Failed cache action: %ls", L"layout container");
533 +
534 + break;
535
704 - iRetryAction = iPackageCompleteAction + 1;
705 - fRetry = TRUE;
536 + case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
537 + if (!::SetEvent(pCacheAction->syncpoint.hEvent))
538 + {
539 + ExitWithLastError(hr, "Failed to set syncpoint event.");
540 }
541 + break;
542
708 - pStartedPackage->hrCacheResult = hr;
709 -
710 - iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX;
711 - iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX;
712 - pStartedPackage = NULL;
713 - }
714 - else
715 - {
716 - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageStartAction);
717 - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageCompleteAction);
543 + default:
544 + AssertSz(FALSE, "Unknown cache action.");
545 + break;
546 }
719 - } while (fRetry);
547 + }
548
549 LExit:
722 - Assert(NULL == pStartedPackage);
723 - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageStartAction);
724 - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageCompleteAction);
725 -
550 if (FAILED(hr))
551 {
552 DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint);
@@ -936,12 +760,216 @@ LExit:
760 return hr;
761 }
762
763 +static HRESULT ApplyCachePackage(
764 + __in BURN_CACHE_CONTEXT* pContext,
765 + __in BURN_PACKAGE* pPackage
766 + )
767 +{
768 + HRESULT hr = S_OK;
769 + BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
770 +
771 + for (;;)
772 + {
773 + hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize);
774 + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls: %ls", L"begin cache package", pPackage->sczId);
775 +
776 + for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i)
777 + {
778 + BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i];
779 +
780 + hr = ApplyProcessPayload(pContext, pPackage, pPayload);
781 + if (FAILED(hr))
782 + {
783 + break;
784 + }
785 + }
786 +
787 + pPackage->hrCacheResult = hr;
788 + cachePackageCompleteAction = SUCCEEDED(hr) || pPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE;
789 + UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction);
790 +
791 + if (SUCCEEDED(hr))
792 + {
793 + break;
794 + }
795 +
796 + if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction)
797 + {
798 + // TODO: the progress needs to account for the payloads (potentially) being recached.
799 + LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pPackage->sczId, NULL, NULL);
800 +
801 + continue;
802 + }
803 + else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && !pPackage->fVital) // ignore non-vital download failures.
804 + {
805 + LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hr);
806 + hr = S_OK;
807 + }
808 +
809 + break;
810 + }
811 +
812 +LExit:
813 + return hr;
814 +}
815 +
816 +static HRESULT ApplyExtractContainer(
817 + __in BURN_CACHE_CONTEXT* pContext,
818 + __in BURN_CONTAINER* pContainer
819 + )
820 +{
821 + HRESULT hr = S_OK;
822 +
823 + if (!pContainer->fActuallyAttached)
824 + {
825 + hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL);
826 + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath);
827 + }
828 +
829 + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize;
830 +
831 + hr = ExtractContainer(pContext, pContainer);
832 + LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath);
833 +
834 + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize;
835 +
836 +LExit:
837 + return hr;
838 +}
839 +
840 +static HRESULT ApplyLayoutBundle(
841 + __in BURN_CACHE_CONTEXT* pContext,
842 + __in BURN_PAYLOAD_GROUP* pPayloads,
843 + __in_z LPCWSTR wzExecutableName,
844 + __in_z LPCWSTR wzUnverifiedPath
845 + )
846 +{
847 + HRESULT hr = S_OK;
848 +
849 + hr = LayoutBundle(pContext, wzExecutableName, wzUnverifiedPath);
850 + ExitOnFailure(hr, "Failed to layout bundle.");
851 +
852 + for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
853 + {
854 + BURN_PAYLOAD* pPayload = pPayloads->rgpPayloads[i];
855 +
856 + hr = ApplyProcessPayload(pContext, NULL, pPayload);
857 + ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayload->sczKey);
858 + }
859 +
860 +LExit:
861 + return hr;
862 +}
863 +
864 +static HRESULT ApplyLayoutContainer(
865 + __in BURN_CACHE_CONTEXT* pContext,
866 + __in BURN_CONTAINER* pContainer
867 + )
868 +{
869 + HRESULT hr = S_OK;
870 + DWORD cTryAgainAttempts = 0;
871 + BOOL fRetry = FALSE;
872 +
873 + Assert(!pContainer->fAttached);
874 +
875 + for (;;)
876 + {
877 + fRetry = FALSE;
878 +
879 + hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL);
880 + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath);
881 +
882 + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize;
883 +
884 + hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry);
885 + if (SUCCEEDED(hr))
886 + {
887 + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize;
888 + break;
889 + }
890 + else
891 + {
892 + LogErrorId(hr, MSG_FAILED_LAYOUT_CONTAINER, pContainer->sczId, pContext->wzLayoutDirectory, pContainer->sczUnverifiedPath);
893 +
894 + if (!fRetry)
895 + {
896 + ExitFunction();
897 + }
898 +
899 + ++cTryAgainAttempts;
900 + pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize;
901 + LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, pContainer->sczId, NULL, NULL);
902 + }
903 + }
904 +
905 +LExit:
906 + return hr;
907 +}
908 +
909 +static HRESULT ApplyProcessPayload(
910 + __in BURN_CACHE_CONTEXT* pContext,
911 + __in_opt BURN_PACKAGE* pPackage,
912 + __in BURN_PAYLOAD* pPayload
913 + )
914 +{
915 + HRESULT hr = S_OK;
916 + DWORD cTryAgainAttempts = 0;
917 + BOOL fRetry = FALSE;
918 +
919 + Assert(pContext->pPayloads || pContext->wzLayoutDirectory);
920 +
921 + for (;;)
922 + {
923 + fRetry = FALSE;
924 +
925 + if (pPayload->pContainer)
926 + {
927 + if (pContext->wzLayoutDirectory)
928 + {
929 + ExitFunction();
930 + }
931 +
932 + // TODO: only extract container if payload isn't already cached and isn't already extracted
933 + hr = ApplyExtractContainer(pContext, pPayload->pContainer);
934 + ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey);
935 + }
936 + else
937 + {
938 + hr = AcquireContainerOrPayload(pContext, NULL, pPackage, pPayload);
939 + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_PAYLOAD, "Failed to acquire payload: %ls to working path: %ls", pPayload->sczKey, pPayload->sczUnverifiedPath);
940 + }
941 +
942 + pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize;
943 +
944 + // TODO: set fMove to TRUE appropriately
945 + hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry);
946 + if (SUCCEEDED(hr))
947 + {
948 + pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize;
949 + break;
950 + }
951 + else
952 + {
953 + LogErrorId(hr, pContext->wzLayoutDirectory ? MSG_FAILED_LAYOUT_PAYLOAD : MSG_FAILED_CACHE_PAYLOAD, pPayload->sczKey, pContext->wzLayoutDirectory, pPayload->sczUnverifiedPath);
954 +
955 + if (!fRetry)
956 + {
957 + ExitFunction();
958 + }
959 +
960 + ++cTryAgainAttempts;
961 + pContext->qwSuccessfulCacheProgress -= pPayload->qwFileSize;
962 + LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, pPayload->sczKey, NULL, NULL);
963 + }
964 + }
965 +
966 +LExit:
967 + return hr;
968 +}
969 +
970 static HRESULT ExtractContainer(
940 - __in HANDLE hSourceEngineFile,
941 - __in BURN_CONTAINER* pContainer,
942 - __in_z LPCWSTR wzContainerPath,
943 - __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads,
944 - __in DWORD cExtractPayloads
971 + __in BURN_CACHE_CONTEXT* pContext,
972 + __in BURN_CONTAINER* pContainer
973 )
974 {
975 HRESULT hr = S_OK;
@@ -952,20 +980,20 @@ static HRESULT ExtractContainer(
980 // If the container is actually attached, then it was planned to be acquired through hSourceEngineFile.
981 if (pContainer->fActuallyAttached)
982 {
955 - hContainerHandle = hSourceEngineFile;
983 + hContainerHandle = pContext->hSourceEngineFile;
984 }
985
958 - hr = ContainerOpen(&context, pContainer, hContainerHandle, wzContainerPath);
986 + hr = ContainerOpen(&context, pContainer, hContainerHandle, pContainer->sczUnverifiedPath);
987 ExitOnFailure(hr, "Failed to open container: %ls.", pContainer->sczId);
988
989 while (S_OK == (hr = ContainerNextStream(&context, &sczExtractPayloadId)))
990 {
991 BOOL fExtracted = FALSE;
992
965 - for (DWORD iExtract = 0; iExtract < cExtractPayloads; ++iExtract)
993 + for (DWORD iExtract = 0; iExtract < pContext->pPayloads->cPayloads; ++iExtract)
994 {
967 - BURN_EXTRACT_PAYLOAD* pExtract = rgExtractPayloads + iExtract;
968 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->pPayload->sczSourcePath, -1))
995 + BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract;
996 + if (pExtract->sczUnverifiedPath && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1))
997 {
998 // TODO: Send progress when extracting stream to file.
999 hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath);
@@ -996,74 +1024,10 @@ LExit:
1024 return hr;
1025 }
1026
999 -static void UpdateCacheSuccessProgress(
1000 - __in BURN_PLAN* pPlan,
1001 - __in BURN_CACHE_ACTION* pCacheAction,
1002 - __inout DWORD64* pqwSuccessfulCachedProgress
1003 - )
1004 -{
1005 - switch (pCacheAction->type)
1006 - {
1007 - case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
1008 - *pqwSuccessfulCachedProgress += pCacheAction->bundleLayout.qwBundleSize;
1009 - break;
1010 -
1011 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER:
1012 - if (!pPlan->rgContainerProgress[pCacheAction->resolveContainer.iProgress].fCachedDuringApply)
1013 - {
1014 - pPlan->rgContainerProgress[pCacheAction->resolveContainer.iProgress].fCachedDuringApply = TRUE;
1015 - *pqwSuccessfulCachedProgress += pCacheAction->resolveContainer.pContainer->qwFileSize;
1016 - }
1017 - break;
1018 -
1019 - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER:
1020 - if (!pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply)
1021 - {
1022 - pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply = TRUE;
1023 - *pqwSuccessfulCachedProgress += pCacheAction->layoutContainer.pContainer->qwFileSize;
1024 - }
1025 - break;
1026 -
1027 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD:
1028 - if (!pPlan->rgPayloadProgress[pCacheAction->resolvePayload.iProgress].fCachedDuringApply)
1029 - {
1030 - pPlan->rgPayloadProgress[pCacheAction->resolvePayload.iProgress].fCachedDuringApply = TRUE;
1031 - *pqwSuccessfulCachedProgress += pCacheAction->resolvePayload.pPayload->qwFileSize;
1032 - }
1033 - break;
1034 -
1035 - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD:
1036 - if (!pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply)
1037 - {
1038 - pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply = TRUE;
1039 - *pqwSuccessfulCachedProgress += pCacheAction->cachePayload.pPayload->qwFileSize;
1040 - }
1041 - break;
1042 -
1043 - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD:
1044 - if (!pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply)
1045 - {
1046 - pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply = TRUE;
1047 - *pqwSuccessfulCachedProgress += pCacheAction->layoutPayload.pPayload->qwFileSize;
1048 - }
1049 - break;
1050 -
1051 - default:
1052 - AssertSz(FALSE, "Unexpected cache action type.");
1053 - break;
1054 - }
1055 -}
1056 -
1027 static HRESULT LayoutBundle(
1058 - __in HANDLE hSourceEngineFile,
1059 - __in BURN_USER_EXPERIENCE* pUX,
1060 - __in BURN_VARIABLES* pVariables,
1061 - __in HANDLE hPipe,
1028 + __in BURN_CACHE_CONTEXT* pContext,
1029 __in_z LPCWSTR wzExecutableName,
1063 - __in_z LPCWSTR wzLayoutDirectory,
1064 - __in_z LPCWSTR wzUnverifiedPath,
1065 - __in DWORD64 qwSuccessfulCacheProgress,
1066 - __in DWORD64 qwTotalCacheSize
1030 + __in_z LPCWSTR wzUnverifiedPath
1031 )
1032 {
1033 HRESULT hr = S_OK;
@@ -1074,7 +1038,7 @@ static HRESULT LayoutBundle(
1038 BOOL fRetry = FALSE;
1039 BOOL fRetryAcquire = FALSE;
1040
1077 - hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath);
1041 + hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath);
1042 if (FAILED(hr))
1043 {
1044 if (E_NOTFOUND != hr)
@@ -1086,7 +1050,7 @@ static HRESULT LayoutBundle(
1050 ExitOnFailure(hr, "Failed to get path to bundle to layout.");
1051 }
1052
1089 - hr = PathConcat(wzLayoutDirectory, wzExecutableName, &sczDestinationPath);
1053 + hr = PathConcat(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath);
1054 ExitOnFailure(hr, "Failed to concat layout path for bundle.");
1055
1056 // If the destination path is the currently running bundle, bail.
@@ -1098,9 +1062,7 @@ static HRESULT LayoutBundle(
1062 ExitFunction1(hr = S_OK);
1063 }
1064
1101 - progress.pUX = pUX;
1102 - progress.qwCacheProgress = qwSuccessfulCacheProgress;
1103 - progress.qwTotalCacheSize = qwTotalCacheSize;
1065 + progress.pCacheContext = pContext;
1066
1067 do
1068 {
@@ -1112,13 +1074,13 @@ static HRESULT LayoutBundle(
1074 fRetryAcquire = FALSE;
1075 progress.fCancel = FALSE;
1076
1115 - hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath);
1077 + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath);
1078 ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
1079
1118 - hr = CopyPayload(&progress, hSourceEngineFile, sczBundlePath, wzUnverifiedPath);
1080 + hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath);
1081 // Error handling happens after sending complete message to BA.
1082
1121 - UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire);
1083 + UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire);
1084 if (fRetryAcquire)
1085 {
1086 continue;
@@ -1130,20 +1092,20 @@ static HRESULT LayoutBundle(
1092
1093 do
1094 {
1133 - hr = UserExperienceOnCacheVerifyBegin(pUX, NULL, NULL);
1095 + hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
1096 ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1097
1136 - if (INVALID_HANDLE_VALUE != hPipe)
1098 + if (INVALID_HANDLE_VALUE != pContext->hPipe)
1099 {
1138 - hr = ElevationLayoutBundle(hPipe, wzLayoutDirectory, wzUnverifiedPath);
1100 + hr = ElevationLayoutBundle(pContext->hPipe, pContext->wzLayoutDirectory, wzUnverifiedPath);
1101 }
1102 else
1103 {
1142 - hr = CacheLayoutBundle(wzExecutableName, wzLayoutDirectory, wzUnverifiedPath);
1104 + hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1105 }
1106
1107 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1146 - UserExperienceOnCacheVerifyComplete(pUX, NULL, NULL, hr, &action);
1108 + UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action);
1109 if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
1110 {
1111 hr = S_FALSE; // retry verify.
@@ -1154,7 +1116,7 @@ static HRESULT LayoutBundle(
1116 }
1117 } while (S_FALSE == hr);
1118 } while (fRetry);
1157 - LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, wzLayoutDirectory);
1119 + LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory);
1120
1121 LExit:
1122 ReleaseStr(sczDestinationPath);
@@ -1164,14 +1126,10 @@ LExit:
1126 }
1127
1128 static HRESULT AcquireContainerOrPayload(
1167 - __in BURN_USER_EXPERIENCE* pUX,
1168 - __in BURN_VARIABLES* pVariables,
1129 + __in BURN_CACHE_CONTEXT* pContext,
1130 __in_opt BURN_CONTAINER* pContainer,
1131 __in_opt BURN_PACKAGE* pPackage,
1171 - __in_opt BURN_PAYLOAD* pPayload,
1172 - __in LPCWSTR wzDestinationPath,
1173 - __in DWORD64 qwSuccessfulCacheProgress,
1174 - __in DWORD64 qwTotalCacheSize
1132 + __in_opt BURN_PAYLOAD* pPayload
1133 )
1134 {
1135 AssertSz(pContainer || pPayload, "Must provide a container or a payload.");
@@ -1180,17 +1138,16 @@ static HRESULT AcquireContainerOrPayload(
1138 int nEquivalentPaths = 0;
1139 LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL;
1140 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL;
1141 + LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath;
1142 LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath;
1143 LPWSTR sczSourceFullPath = NULL;
1144 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { };
1145 BOOL fRetry = FALSE;
1146
1147 + progress.pCacheContext = pContext;
1148 progress.pContainer = pContainer;
1149 progress.pPackage = pPackage;
1150 progress.pPayload = pPayload;
1191 - progress.pUX = pUX;
1192 - progress.qwCacheProgress = qwSuccessfulCacheProgress;
1193 - progress.qwTotalCacheSize = qwTotalCacheSize;
1151
1152 do
1153 {
@@ -1204,7 +1161,7 @@ static HRESULT AcquireContainerOrPayload(
1161 fRetry = FALSE;
1162 progress.fCancel = FALSE;
1163
1207 - hr = CacheFindLocalSource(wzSourcePath, pVariables, &fFoundLocal, &sczSourceFullPath);
1164 + hr = CacheFindLocalSource(wzSourcePath, wzDestinationPath, pContext->pVariables, &fFoundLocal, &sczSourceFullPath);
1165 ExitOnFailure(hr, "Failed to search local source.");
1166
1167 if (fFoundLocal) // the file exists locally, so copy it.
@@ -1220,7 +1177,7 @@ static HRESULT AcquireContainerOrPayload(
1177 DWORD dwLogId = pContainer ? (wzPayloadId ? MSG_PROMPT_CONTAINER_PAYLOAD_SOURCE : MSG_PROMPT_CONTAINER_SOURCE) : pPackage ? MSG_PROMPT_PACKAGE_PAYLOAD_SOURCE : MSG_PROMPT_BUNDLE_PAYLOAD_SOURCE;
1178 LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId ? wzPackageOrContainerId : L"", wzPayloadId ? wzPayloadId : L"", sczSourceFullPath);
1179
1223 - hr = PromptForSource(pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload);
1180 + hr = PromptForSource(pContext->pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload);
1181
1182 // If the BA requested download then ensure a download url is available (it may have been set
1183 // during PromptForSource so we need to check again).
@@ -1239,7 +1196,7 @@ static HRESULT AcquireContainerOrPayload(
1196
1197 if (fCopy)
1198 {
1242 - hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath);
1199 + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath);
1200 ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
1201
1202 hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath);
@@ -1248,12 +1205,12 @@ static HRESULT AcquireContainerOrPayload(
1205 // We successfully copied from a source location, set that as the last used source.
1206 if (SUCCEEDED(hr))
1207 {
1251 - CacheSetLastUsedSource(pVariables, sczSourceFullPath, wzRelativePath);
1208 + CacheSetLastUsedSource(pContext->pVariables, sczSourceFullPath, wzRelativePath);
1209 }
1210 }
1211 else if (fDownload)
1212 {
1256 - hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl);
1213 + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl);
1214 ExitOnRootFailure(hr, "BA aborted cache download payload begin.");
1215
1216 hr = DownloadPayload(&progress, wzDestinationPath);
@@ -1262,7 +1219,7 @@ static HRESULT AcquireContainerOrPayload(
1219
1220 if (fCopy || fDownload)
1221 {
1265 - UserExperienceOnCacheAcquireComplete(pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry);
1222 + UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry);
1223 if (fRetry)
1224 {
1225 hr = S_OK;
@@ -1279,16 +1236,10 @@ LExit:
1236 }
1237
1238 static HRESULT LayoutOrCacheContainerOrPayload(
1282 - __in BURN_USER_EXPERIENCE* pUX,
1283 - __in HANDLE hPipe,
1239 + __in BURN_CACHE_CONTEXT* pContext,
1240 __in_opt BURN_CONTAINER* pContainer,
1241 __in_opt BURN_PACKAGE* pPackage,
1242 __in_opt BURN_PAYLOAD* pPayload,
1287 - __in BOOL fAlreadyProvidedProgress,
1288 - __in DWORD64 qwSuccessfulCachedProgress,
1289 - __in DWORD64 qwTotalCacheSize,
1290 - __in_z_opt LPCWSTR wzLayoutDirectory,
1291 - __in_z LPCWSTR wzUnverifiedPath,
1243 __in BOOL fMove,
1244 __in DWORD cTryAgainAttempts,
1245 __out BOOL* pfRetry
@@ -1296,13 +1247,14 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1247 {
1248 HRESULT hr = S_OK;
1249 LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L"";
1250 + LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath;
1251 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L"";
1252 LARGE_INTEGER liContainerOrPayloadSize = { };
1253 LARGE_INTEGER liZero = { };
1254 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { };
1255 BOOL fCanAffectRegistration = FALSE;
1256
1305 - if (!wzLayoutDirectory)
1257 + if (!pContext->wzLayoutDirectory)
1258 {
1259 Assert(!pContainer);
1260 Assert(pPackage);
@@ -1312,41 +1264,31 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1264
1265 liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize;
1266
1267 + progress.pCacheContext = pContext;
1268 progress.pContainer = pContainer;
1269 progress.pPackage = pPackage;
1270 progress.pPayload = pPayload;
1318 - progress.pUX = pUX;
1319 - progress.qwTotalCacheSize = qwTotalCacheSize;
1320 - if (fAlreadyProvidedProgress)
1321 - {
1322 - Assert(qwSuccessfulCachedProgress >= static_cast<DWORD64>(liContainerOrPayloadSize.QuadPart));
1323 - progress.qwCacheProgress = qwSuccessfulCachedProgress - liContainerOrPayloadSize.QuadPart; // remove the payload size, since it was marked successful thus included in the successful size already.
1324 - }
1325 - else
1326 - {
1327 - progress.qwCacheProgress = qwSuccessfulCachedProgress;
1328 - }
1271
1272 *pfRetry = FALSE;
1273
1274 do
1275 {
1334 - hr = UserExperienceOnCacheVerifyBegin(pUX, wzPackageOrContainerId, wzPayloadId);
1276 + hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId);
1277 ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1278
1337 - if (INVALID_HANDLE_VALUE != hPipe) // pass the decision off to the elevated process.
1279 + if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process.
1280 {
1339 - hr = ElevationCacheOrLayoutContainerOrPayload(hPipe, pContainer, pPackage, pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove);
1281 + hr = ElevationCacheOrLayoutContainerOrPayload(pContext->hPipe, pContainer, pPackage, pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1282 }
1341 - else if (wzLayoutDirectory) // layout the container or payload.
1283 + else if (pContext->wzLayoutDirectory) // layout the container or payload.
1284 {
1285 if (pContainer)
1286 {
1345 - hr = CacheLayoutContainer(pContainer, wzLayoutDirectory, wzUnverifiedPath, fMove);
1287 + hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1288 }
1289 else
1290 {
1349 - hr = CacheLayoutPayload(pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove);
1291 + hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1292 }
1293 }
1294 else // complete the payload.
@@ -1376,7 +1318,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1318 }
1319
1320 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1379 - UserExperienceOnCacheVerifyComplete(pUX, wzPackageOrContainerId, wzPayloadId, hr, &action);
1321 + UserExperienceOnCacheVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &action);
1322 if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
1323 {
1324 hr = S_FALSE; // retry verify.
@@ -1541,7 +1483,7 @@ static HRESULT DownloadPayload(
1483 cacheCallback.pfnCancel = NULL; // TODO: set this
1484 cacheCallback.pv = pProgress;
1485
1544 - authenticationData.pUX = pProgress->pUX;
1486 + authenticationData.pUX = pProgress->pCacheContext->pUX;
1487 authenticationData.wzPackageOrContainerId = wzPackageOrContainerId;
1488 authenticationData.wzPayloadId = wzPayloadId;
1489 authenticationCallback.pv = static_cast<LPVOID>(&authenticationData);
@@ -1630,15 +1572,15 @@ static DWORD CALLBACK CacheProgressRoutine(
1572 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT*>(lpData);
1573 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
1574 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
1633 - DWORD64 qwCacheProgress = pProgress->qwCacheProgress + TotalBytesTransferred.QuadPart;
1634 - if (qwCacheProgress > pProgress->qwTotalCacheSize)
1575 + DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart;
1576 + if (qwCacheProgress > pProgress->pCacheContext->qwTotalCacheSize)
1577 {
1636 - AssertSz(FALSE, "Apply has cached more than Plan envisioned.");
1637 - qwCacheProgress = pProgress->qwTotalCacheSize;
1578 + //AssertSz(FALSE, "Apply has cached more than Plan envisioned.");
1579 + qwCacheProgress = pProgress->pCacheContext->qwTotalCacheSize;
1580 }
1639 - DWORD dwOverallPercentage = pProgress->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->qwTotalCacheSize) : 0;
1581 + DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0;
1582
1641 - hr = UserExperienceOnCacheAcquireProgress(pProgress->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1583 + hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1584 if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr)
1585 {
1586 dwResult = PROGRESS_CANCEL;
src/engine/cache.cpp
+10 -5
@@ -391,6 +391,7 @@ LExit:
391
392 extern "C" HRESULT CacheFindLocalSource(
393 __in_z LPCWSTR wzSourcePath,
394 + __in_z LPCWSTR wzDestinationPath,
395 __in BURN_VARIABLES* pVariables,
396 __out BOOL* pfFound,
397 __out_z LPWSTR* psczSourceFullPath
@@ -403,7 +404,7 @@ extern "C" HRESULT CacheFindLocalSource(
404 LPWSTR sczLastSourceFolder = NULL;
405 LPWSTR sczLayoutPath = NULL;
406 LPWSTR sczLayoutFolder = NULL;
406 - LPCWSTR rgwzSearchPaths[3] = { };
407 + LPCWSTR rgwzSearchPaths[4] = { };
408 DWORD cSearchPaths = 0;
409
410 // If the source path provided is a full path, obviously that is where we should be looking.
@@ -414,8 +415,12 @@ extern "C" HRESULT CacheFindLocalSource(
415 }
416 else
417 {
418 + // Use the destination path first.
419 + rgwzSearchPaths[0] = wzDestinationPath;
420 + cSearchPaths = 1;
421 +
422 // If we're not running from cache or we couldn't get the last source, use
418 - // the source path location first. In the case where we are in the bundle's
423 + // the source path location. In the case where we are in the bundle's
424 // package cache and couldn't find a last used source we unfortunately will
425 // be picking the package cache path which isn't likely to have what we are
426 // looking for.
@@ -428,8 +433,8 @@ extern "C" HRESULT CacheFindLocalSource(
433 hr = PathConcat(sczSourceProcessFolder, wzSourcePath, &sczCurrentPath);
434 ExitOnFailure(hr, "Failed to combine last source with source.");
435
431 - rgwzSearchPaths[0] = sczCurrentPath;
432 - cSearchPaths = 1;
436 + rgwzSearchPaths[cSearchPaths] = sczCurrentPath;
437 + ++cSearchPaths;
438 }
439
440 // If we have a last used source and it does not duplicate the existing search path,
@@ -439,7 +444,7 @@ extern "C" HRESULT CacheFindLocalSource(
444 hr = PathConcat(sczLastSourceFolder, wzSourcePath, &sczLastSourcePath);
445 ExitOnFailure(hr, "Failed to combine last source with source.");
446
442 - if (0 == cSearchPaths || CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, rgwzSearchPaths[0], -1, sczLastSourcePath, -1))
447 + if (1 == cSearchPaths || CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, rgwzSearchPaths[1], -1, sczLastSourcePath, -1))
448 {
449 rgwzSearchPaths[cSearchPaths] = sczLastSourcePath;
450 ++cSearchPaths;
src/engine/cache.h
+1
@@ -54,6 +54,7 @@ HRESULT CacheGetResumePath(
54 );
55 HRESULT CacheFindLocalSource(
56 __in_z LPCWSTR wzSourcePath,
57 + __in_z LPCWSTR wzDestinationPath,
58 __in BURN_VARIABLES* pVariables,
59 __out BOOL* pfFound,
60 __out_z LPWSTR* psczSourceFullPath
src/engine/container.cpp
+1 -11
@@ -3,17 +3,6 @@
3 #include "precomp.h"
4
5
6 -// internal function declarations
7 -
8 -static HRESULT GetAttachedContainerInfo(
9 - __in HANDLE hFile,
10 - __in DWORD iContainerIndex,
11 - __out DWORD* pdwFormat,
12 - __out DWORD64* pqwOffset,
13 - __out DWORD64* pqwSize
14 - );
15 -
16 -
6 // function definitions
7
8 extern "C" HRESULT ContainersParseFromXml(
@@ -186,6 +175,7 @@ extern "C" void ContainersUninitialize(
175 ReleaseStr(pContainer->downloadSource.sczUrl);
176 ReleaseStr(pContainer->downloadSource.sczUser);
177 ReleaseStr(pContainer->downloadSource.sczPassword);
178 + ReleaseStr(pContainer->sczUnverifiedPath);
179 }
180 MemFree(pContainers->rgContainers);
181 }
src/engine/container.h
+4 -3
@@ -65,7 +65,6 @@ typedef struct _BURN_CONTAINER
65 DWORD64 qwFileSize;
66 LPWSTR sczHash;
67 LPWSTR sczFilePath; // relative path to container.
68 - LPWSTR sczSourcePath;
68 DOWNLOAD_SOURCE downloadSource;
69
70 BYTE* pbHash;
@@ -73,8 +72,10 @@ typedef struct _BURN_CONTAINER
72 DWORD64 qwAttachedOffset;
73 BOOL fActuallyAttached; // indicates whether an attached container is attached or missing.
74
76 - //LPWSTR* rgsczPayloads;
77 - //DWORD cPayloads;
75 + // mutable members
76 + BOOL fPlanned;
77 + LPWSTR sczSourcePath;
78 + LPWSTR sczUnverifiedPath;
79 } BURN_CONTAINER;
80
81 typedef struct _BURN_CONTAINERS
src/engine/core.cpp
+12 -14
@@ -287,7 +287,7 @@ extern "C" HRESULT CoreDetect(
287 pEngineState->fDetected = FALSE;
288 pEngineState->fPlanned = FALSE;
289 DetectReset(&pEngineState->registration, &pEngineState->packages);
290 - PlanReset(&pEngineState->plan, &pEngineState->packages);
290 + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
291
292 // Detect if bundle installed state has changed since start up. This
293 // only happens if Apply() changed the state of bundle (installed or
@@ -438,7 +438,6 @@ extern "C" HRESULT CorePlan(
438 {
439 HRESULT hr = S_OK;
440 BOOL fPlanBegan = FALSE;
441 - LPWSTR sczLayoutDirectory = NULL;
441 BURN_PACKAGE* pUpgradeBundlePackage = NULL;
442 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL;
443 BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies.
@@ -460,11 +459,12 @@ extern "C" HRESULT CorePlan(
459
460 // Always reset the plan.
461 pEngineState->fPlanned = FALSE;
463 - PlanReset(&pEngineState->plan, &pEngineState->packages);
462 + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
463
464 // Remember the overall action state in the plan since it shapes the changes
465 // we make everywhere.
466 pEngineState->plan.action = action;
467 + pEngineState->plan.pPayloads = &pEngineState->payloads;
468 pEngineState->plan.wzBundleId = pEngineState->registration.sczId;
469 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId;
470 pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback;
@@ -484,11 +484,11 @@ extern "C" HRESULT CorePlan(
484 Assert(!pEngineState->plan.fPerMachine);
485
486 // Plan the bundle's layout.
487 - hr = PlanLayoutBundle(&pEngineState->plan, pEngineState->registration.sczExecutableName, pEngineState->section.qwBundleSize, &pEngineState->variables, &pEngineState->payloads, &sczLayoutDirectory);
487 + hr = PlanLayoutBundle(&pEngineState->plan, pEngineState->registration.sczExecutableName, pEngineState->section.qwBundleSize, &pEngineState->variables, &pEngineState->layoutPayloads);
488 ExitOnFailure(hr, "Failed to plan the layout of the bundle.");
489
490 // Plan the packages' layout.
491 - hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory);
491 + hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType);
492 ExitOnFailure(hr, "Failed to plan packages.");
493 }
494 else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action)
@@ -532,7 +532,7 @@ extern "C" HRESULT CorePlan(
532 hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan);
533 ExitOnFailure(hr, "Failed to plan related bundles.");
534
535 - hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL);
535 + hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType);
536 ExitOnFailure(hr, "Failed to plan packages.");
537
538 // Schedule the update of related bundles last.
@@ -562,7 +562,6 @@ LExit:
562 }
563
564 LogId(REPORT_STANDARD, MSG_PLAN_COMPLETE, hr);
565 - ReleaseStr(sczLayoutDirectory);
565
566 return hr;
567 }
@@ -1679,23 +1678,22 @@ static HRESULT DetectPackagePayloadsCached(
1678 // If the cached directory exists, we have something.
1679 if (DirExists(sczCachePath, NULL))
1680 {
1682 - // Check all payloads to see if they exist.
1683 - for (DWORD i = 0; i < pPackage->cPayloads; ++i)
1681 + // Check all payloads to see if any exist.
1682 + for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i)
1683 {
1685 - BURN_PACKAGE_PAYLOAD* pPackagePayload = pPackage->rgPayloads + i;
1684 + BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i];
1685
1687 - hr = PathConcat(sczCachePath, pPackagePayload->pPayload->sczFilePath, &sczPayloadCachePath);
1686 + hr = PathConcat(sczCachePath, pPayload->sczFilePath, &sczPayloadCachePath);
1687 ExitOnFailure(hr, "Failed to concat payload cache path.");
1688
1689 if (FileExistsEx(sczPayloadCachePath, NULL))
1690 {
1692 - // TODO: We shouldn't track whether the payload was cached since all we did was check whether the file exists.
1693 - pPackagePayload->fCached = TRUE;
1691 fCached = TRUE;
1692 + break;
1693 }
1694 else
1695 {
1698 - LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPackagePayload->pPayload->sczKey);
1696 + LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPayload->sczKey);
1697 }
1698 }
1699 }
src/engine/core.h
+2
@@ -112,6 +112,8 @@ typedef struct _BURN_ENGINE_STATE
112
113 BURN_LOGGING log;
114
115 + BURN_PAYLOAD_GROUP layoutPayloads;
116 +
117 BURN_PLAN plan;
118
119 BURN_MODE mode;
src/engine/detect.cpp
-5
@@ -68,11 +68,6 @@ extern "C" void DetectReset(
68 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
69
70 pPackage->fCached = FALSE;
71 - for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload)
72 - {
73 - BURN_PACKAGE_PAYLOAD* pPayload = pPackage->rgPayloads + iPayload;
74 - pPayload->fCached = FALSE;
75 - }
71
72 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
73 {
src/engine/engine.mc
+2 -2
@@ -552,7 +552,7 @@ MessageId=314
552 Severity=Error
553 SymbolicName=MSG_FAILED_CACHE_PAYLOAD
554 Language=English
555 -Failed to cache payload: %2!ls! from working path: %3!ls!, error: %1!ls!.
555 +Failed to cache payload: %2!ls! from working path: %4!ls!, error: %1!ls!.
556 .
557
558 MessageId=315
@@ -574,7 +574,7 @@ MessageId=317
574 Severity=Error
575 SymbolicName=MSG_FAILED_LAYOUT_PAYLOAD
576 Language=English
577 -Failed to layout payload: %2!ls! to layout directory: %3!ls!, error: %1!ls!.
577 +Failed to layout payload: %2!ls! from working path: %4!ls! to layout directory: %3!ls!, error: %1!ls!.
578 .
579
580 MessageId=318
src/engine/exeengine.cpp
+17 -15
@@ -372,31 +372,33 @@ extern "C" HRESULT ExeEngineExecutePackage(
372 PROCESS_INFORMATION pi = { };
373 DWORD dwExitCode = 0;
374 GENERIC_EXECUTE_MESSAGE message = { };
375 + BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage;
376 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
377
378 // get cached executable path
377 - hr = CacheGetCompletedPath(pExecuteAction->exePackage.pPackage->fPerMachine, pExecuteAction->exePackage.pPackage->sczCacheId, &sczCachedDirectory);
378 - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->exePackage.pPackage->sczId);
379 + hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
380 + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
381
382 // Best effort to set the execute package cache folder and action variables.
383 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
384 VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, pExecuteAction->exePackage.action, TRUE);
385
384 - hr = PathConcat(sczCachedDirectory, pExecuteAction->exePackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczExecutablePath);
386 + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath);
387 ExitOnFailure(hr, "Failed to build executable path.");
388
389 // pick arguments
390 switch (pExecuteAction->exePackage.action)
391 {
392 case BOOTSTRAPPER_ACTION_STATE_INSTALL:
391 - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczInstallArguments;
393 + wzArguments = pPackage->Exe.sczInstallArguments;
394 break;
395
396 case BOOTSTRAPPER_ACTION_STATE_UNINSTALL:
395 - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczUninstallArguments;
397 + wzArguments = pPackage->Exe.sczUninstallArguments;
398 break;
399
400 case BOOTSTRAPPER_ACTION_STATE_REPAIR:
399 - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczRepairArguments;
401 + wzArguments = pPackage->Exe.sczRepairArguments;
402 break;
403
404 default:
@@ -408,9 +410,9 @@ extern "C" HRESULT ExeEngineExecutePackage(
410 hr = StrAllocString(&sczArguments, wzArguments && *wzArguments ? wzArguments : L"", 0);
411 ExitOnFailure(hr, "Failed to copy package arguments.");
412
411 - for (DWORD i = 0; i < pExecuteAction->exePackage.pPackage->Exe.cCommandLineArguments; ++i)
413 + for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i)
414 {
413 - BURN_EXE_COMMAND_LINE_ARGUMENT* commandLineArgument = &pExecuteAction->exePackage.pPackage->Exe.rgCommandLineArguments[i];
415 + BURN_EXE_COMMAND_LINE_ARGUMENT* commandLineArgument = &pPackage->Exe.rgCommandLineArguments[i];
416 BOOL fCondition = FALSE;
417
418 hr = ConditionEvaluate(pVariables, commandLineArgument->sczCondition, &fCondition);
@@ -468,10 +470,10 @@ extern "C" HRESULT ExeEngineExecutePackage(
470 }
471 ExitOnFailure(hr, "Failed to create obfuscated executable command.");
472
471 - if (pExecuteAction->exePackage.pPackage->Exe.fSupportsAncestors)
473 + if (pPackage->Exe.fSupportsAncestors)
474 {
475 // Add the list of dependencies to ignore, if any, to the burn command line.
474 - if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol)
476 + if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
477 {
478 hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies);
479 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line.");
@@ -491,21 +493,21 @@ extern "C" HRESULT ExeEngineExecutePackage(
493 }
494 }
495
494 - if (BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol)
496 + if (BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
497 {
498 hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, &sczCommandObfuscated);
499 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
500 }
501
502 // Log before we add the secret pipe name and client token for embedded processes.
501 - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->exePackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated);
503 + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated);
504
503 - if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol)
505 + if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
506 {
507 hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode);
508 ExitOnFailure(hr, "Failed to run bundle as embedded from path: %ls", sczExecutablePath);
509 }
508 - else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pExecuteAction->exePackage.pPackage->Exe.protocol)
510 + else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol)
511 {
512 hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode);
513 ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath);
@@ -543,7 +545,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
545 } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr);
546 }
547
546 - hr = HandleExitCode(pExecuteAction->exePackage.pPackage, dwExitCode, pRestart);
548 + hr = HandleExitCode(pPackage, dwExitCode, pRestart);
549 ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode);
550
551 LExit:
src/engine/manifest.cpp
+1 -1
@@ -145,7 +145,7 @@ static HRESULT ParseFromXml(
145 ExitOnFailure(hr, "Failed to parse containers.");
146
147 // parse payloads
148 - hr = PayloadsParseFromXml(&pEngineState->payloads, &pEngineState->containers, pixeBundle);
148 + hr = PayloadsParseFromXml(&pEngineState->payloads, &pEngineState->containers, &pEngineState->layoutPayloads, pixeBundle);
149 ExitOnFailure(hr, "Failed to parse payloads.");
150
151 // parse packages
src/engine/msiengine.cpp
+25 -22
@@ -1099,6 +1099,8 @@ extern "C" HRESULT MsiEngineExecutePackage(
1099 LPWSTR sczMsiPath = NULL;
1100 LPWSTR sczProperties = NULL;
1101 LPWSTR sczObfuscatedProperties = NULL;
1102 + BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage;
1103 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
1104
1105 // During rollback, if the package is already in the rollback state we expect don't
1106 // touch it again.
@@ -1106,10 +1108,10 @@ extern "C" HRESULT MsiEngineExecutePackage(
1108 {
1109 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->msiPackage.action)
1110 {
1109 - hr = WiuGetProductInfoEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, NULL, pExecuteAction->msiPackage.pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1111 + hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1112 if (FAILED(hr)) // package not present.
1113 {
1112 - LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_ABSENT));
1114 + LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_ABSENT));
1115
1116 hr = S_OK;
1117 ExitFunction();
@@ -1117,10 +1119,10 @@ extern "C" HRESULT MsiEngineExecutePackage(
1119 }
1120 else if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->msiPackage.action)
1121 {
1120 - hr = WiuGetProductInfoEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, NULL, pExecuteAction->msiPackage.pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1122 + hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1123 if (SUCCEEDED(hr)) // package present.
1124 {
1123 - LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_PRESENT));
1125 + LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_PRESENT));
1126
1127 hr = S_OK;
1128 ExitFunction();
@@ -1141,13 +1143,13 @@ extern "C" HRESULT MsiEngineExecutePackage(
1143 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pExecuteAction->msiPackage.action)
1144 {
1145 // get cached MSI path
1144 - hr = CacheGetCompletedPath(pExecuteAction->msiPackage.pPackage->fPerMachine, pExecuteAction->msiPackage.pPackage->sczCacheId, &sczCachedDirectory);
1145 - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msiPackage.pPackage->sczId);
1146 + hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
1147 + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
1148
1149 // Best effort to set the execute package cache folder variable.
1150 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
1151
1150 - hr = PathConcat(sczCachedDirectory, pExecuteAction->msiPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsiPath);
1152 + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsiPath);
1153 ExitOnFailure(hr, "Failed to build MSI path.");
1154 }
1155
@@ -1169,28 +1171,28 @@ extern "C" HRESULT MsiEngineExecutePackage(
1171 if (pExecuteAction->msiPackage.sczLogPath && *pExecuteAction->msiPackage.sczLogPath)
1172 {
1173 hr = WiuEnableLog(dwLogMode, pExecuteAction->msiPackage.sczLogPath, 0);
1172 - ExitOnFailure(hr, "Failed to enable logging for package: %ls to: %ls", pExecuteAction->msiPackage.pPackage->sczId, pExecuteAction->msiPackage.sczLogPath);
1174 + ExitOnFailure(hr, "Failed to enable logging for package: %ls to: %ls", pPackage->sczId, pExecuteAction->msiPackage.sczLogPath);
1175 }
1176
1177 // set up properties
1176 - hr = MsiEngineConcatProperties(pExecuteAction->msiPackage.pPackage->Msi.rgProperties, pExecuteAction->msiPackage.pPackage->Msi.cProperties, pVariables, fRollback, &sczProperties, FALSE);
1178 + hr = MsiEngineConcatProperties(pPackage->Msi.rgProperties, pPackage->Msi.cProperties, pVariables, fRollback, &sczProperties, FALSE);
1179 ExitOnFailure(hr, "Failed to add properties to argument string.");
1180
1179 - hr = MsiEngineConcatProperties(pExecuteAction->msiPackage.pPackage->Msi.rgProperties, pExecuteAction->msiPackage.pPackage->Msi.cProperties, pVariables, fRollback, &sczObfuscatedProperties, TRUE);
1181 + hr = MsiEngineConcatProperties(pPackage->Msi.rgProperties, pPackage->Msi.cProperties, pVariables, fRollback, &sczObfuscatedProperties, TRUE);
1182 ExitOnFailure(hr, "Failed to add obfuscated properties to argument string.");
1183
1184 // add feature action properties
1183 - hr = ConcatFeatureActionProperties(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgFeatures, &sczProperties);
1185 + hr = ConcatFeatureActionProperties(pPackage, pExecuteAction->msiPackage.rgFeatures, &sczProperties);
1186 ExitOnFailure(hr, "Failed to add feature action properties to argument string.");
1187
1186 - hr = ConcatFeatureActionProperties(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgFeatures, &sczObfuscatedProperties);
1188 + hr = ConcatFeatureActionProperties(pPackage, pExecuteAction->msiPackage.rgFeatures, &sczObfuscatedProperties);
1189 ExitOnFailure(hr, "Failed to add feature action properties to obfuscated argument string.");
1190
1191 // add slipstream patch properties
1190 - hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczProperties);
1192 + hr = ConcatPatchProperty(pPackage, fRollback, &sczProperties);
1193 ExitOnFailure(hr, "Failed to add patch properties to argument string.");
1194
1193 - hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczObfuscatedProperties);
1195 + hr = ConcatPatchProperty(pPackage, fRollback, &sczObfuscatedProperties);
1196 ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string.");
1197
1198 hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczProperties);
@@ -1199,7 +1201,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1201 hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczObfuscatedProperties);
1202 ExitOnFailure(hr, "Failed to add action property to obfuscated argument string.");
1203
1202 - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L"");
1204 + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L"");
1205
1206 //
1207 // Do the actual action.
@@ -1213,13 +1215,13 @@ extern "C" HRESULT MsiEngineExecutePackage(
1215 hr = WiuInstallProduct(sczMsiPath, sczProperties, &restart);
1216 ExitOnFailure(hr, "Failed to install MSI package.");
1217
1216 - RegisterSourceDirectory(pExecuteAction->msiPackage.pPackage, sczMsiPath);
1218 + RegisterSourceDirectory(pPackage, sczMsiPath);
1219 break;
1220
1221 case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE:
1222 // If feature selection is not enabled, then reinstall the existing features to ensure they get
1223 // updated.
1222 - if (0 == pExecuteAction->msiPackage.pPackage->Msi.cFeatures)
1224 + if (0 == pPackage->Msi.cFeatures)
1225 {
1226 hr = StrAllocConcatSecure(&sczProperties, L" REINSTALL=ALL", 0);
1227 ExitOnFailure(hr, "Failed to add reinstall all property on minor upgrade.");
@@ -1231,7 +1233,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1233 hr = WiuInstallProduct(sczMsiPath, sczProperties, &restart);
1234 ExitOnFailure(hr, "Failed to perform minor upgrade of MSI package.");
1235
1234 - RegisterSourceDirectory(pExecuteAction->msiPackage.pPackage, sczMsiPath);
1236 + RegisterSourceDirectory(pPackage, sczMsiPath);
1237 break;
1238
1239 case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough;
@@ -1239,7 +1241,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1241 case BOOTSTRAPPER_ACTION_STATE_REPAIR:
1242 {
1243 LPCWSTR wzReinstallAll = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action ||
1242 - pExecuteAction->msiPackage.pPackage->Msi.cFeatures) ? L"" : L" REINSTALL=ALL";
1244 + pPackage->Msi.cFeatures) ? L"" : L" REINSTALL=ALL";
1245 LPCWSTR wzReinstallMode = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action || BOOTSTRAPPER_ACTION_STATE_MEND == pExecuteAction->msiPackage.action) ? L"o" : L"e";
1246
1247 hr = StrAllocFormattedSecure(&sczProperties, L"%ls%ls REINSTALLMODE=\"cmus%ls\" REBOOT=ReallySuppress", sczProperties ? sczProperties : L"", wzReinstallAll, wzReinstallMode);
@@ -1262,10 +1264,10 @@ extern "C" HRESULT MsiEngineExecutePackage(
1264 hr = StrAllocFormattedSecure(&sczProperties, L"%ls %ls=ALL", sczProperties, DEPENDENCY_IGNOREDEPENDENCIES);
1265 ExitOnFailure(hr, "Failed to add the list of dependencies to ignore to the properties.");
1266
1265 - hr = WiuConfigureProductEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, sczProperties, &restart);
1267 + hr = WiuConfigureProductEx(pPackage->Msi.sczProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, sczProperties, &restart);
1268 if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr)
1269 {
1268 - LogId(REPORT_STANDARD, MSG_ATTEMPTED_UNINSTALL_ABSENT_PACKAGE, pExecuteAction->msiPackage.pPackage->sczId);
1270 + LogId(REPORT_STANDARD, MSG_ATTEMPTED_UNINSTALL_ABSENT_PACKAGE, pPackage->sczId);
1271 hr = S_OK;
1272 }
1273 ExitOnFailure(hr, "Failed to uninstall MSI package.");
@@ -1979,6 +1981,7 @@ static HRESULT ConcatPatchProperty(
1981 {
1982 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + i;
1983 BURN_PACKAGE* pMspPackage = pSlipstreamMsp->pMspPackage;
1984 + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0];
1985 BOOTSTRAPPER_ACTION_STATE patchExecuteAction = fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute;
1986
1987 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction)
@@ -1986,7 +1989,7 @@ static HRESULT ConcatPatchProperty(
1989 hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
1990 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId);
1991
1989 - hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath);
1992 + hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
1993 ExitOnFailure(hr, "Failed to build MSP path.");
1994
1995 if (!sczPatches)
src/engine/mspengine.cpp
+2 -1
@@ -581,6 +581,7 @@ extern "C" HRESULT MspEngineExecutePackage(
581 {
582 LPCWSTR wzAppend = NULL;
583 BURN_PACKAGE* pMspPackage = pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage;
584 + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0];
585 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Invalid package type added to ordered patches.");
586
587 if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action)
@@ -592,7 +593,7 @@ extern "C" HRESULT MspEngineExecutePackage(
593 // Best effort to set the execute package cache folder variable.
594 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
595
595 - hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath);
596 + hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
597 ExitOnFailure(hr, "Failed to build MSP path.");
598
599 wzAppend = sczMspPath;
src/engine/msuengine.cpp
+7 -5
@@ -264,6 +264,8 @@ extern "C" HRESULT MsuEngineExecutePackage(
264 GENERIC_EXECUTE_MESSAGE message = { };
265 DWORD dwExitCode = 0;
266 BOOL fUseSysNativePath = FALSE;
267 + BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage;
268 + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0];
269
270 #if !defined(_WIN64)
271 hr = ProcWow64(::GetCurrentProcess(), &fUseSysNativePath);
@@ -295,13 +297,13 @@ extern "C" HRESULT MsuEngineExecutePackage(
297 {
298 case BOOTSTRAPPER_ACTION_STATE_INSTALL:
299 // get cached MSU path
298 - hr = CacheGetCompletedPath(TRUE, pExecuteAction->msuPackage.pPackage->sczCacheId, &sczCachedDirectory);
299 - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msuPackage.pPackage->sczId);
300 + hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCachedDirectory);
301 + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
302
303 // Best effort to set the execute package cache folder variable.
304 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
305
304 - hr = PathConcat(sczCachedDirectory, pExecuteAction->msuPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsuPath);
306 + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsuPath);
307 ExitOnFailure(hr, "Failed to build MSU path.");
308
309 // format command
@@ -311,7 +313,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
313
314 case BOOTSTRAPPER_ACTION_STATE_UNINSTALL:
315 // format command
314 - hr = StrAllocFormatted(&sczCommand, L"\"%ls\" /uninstall /kb:%ls /quiet /norestart", sczWusaPath, pExecuteAction->msuPackage.pPackage->Msu.sczKB);
316 + hr = StrAllocFormatted(&sczCommand, L"\"%ls\" /uninstall /kb:%ls /quiet /norestart", sczWusaPath, pPackage->Msu.sczKB);
317 ExitOnFailure(hr, "Failed to format MSU uninstall command.");
318 break;
319
@@ -329,7 +331,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
331 ExitOnFailure(hr, "Failed to append log path to MSU command-line.");
332 }
333
332 - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msuPackage.action), sczMsuPath ? sczMsuPath : pExecuteAction->msuPackage.pPackage->Msu.sczKB, sczCommand);
334 + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msuPackage.action), sczMsuPath ? sczMsuPath : pPackage->Msu.sczKB, sczCommand);
335
336 hr = EnsureWUServiceEnabled(fStopWusaService, &schWu, &fWuWasDisabled);
337 ExitOnFailure(hr, "Failed to ensure WU service was enabled to install MSU package.");
src/engine/package.cpp
+7 -7
@@ -349,7 +349,7 @@ extern "C" void PackageUninitialize(
349 MemFree(pPackage->rgDependencyProviders);
350 }
351
352 - ReleaseMem(pPackage->rgPayloads);
352 + ReleaseMem(pPackage->payloads.rgpPayloads);
353
354 switch (pPackage->type)
355 {
@@ -567,16 +567,14 @@ static HRESULT ParsePayloadRefsFromXml(
567 }
568
569 // allocate memory for payload pointers
570 - pPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD*)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD) * cNodes, TRUE);
571 - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads.");
570 + pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * cNodes, TRUE);
571 + ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads.");
572
573 - pPackage->cPayloads = cNodes;
573 + pPackage->payloads.cPayloads = cNodes;
574
575 // parse package elements
576 for (DWORD i = 0; i < cNodes; ++i)
577 {
578 - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i];
579 -
578 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
579 ExitOnFailure(hr, "Failed to get next node.");
580
@@ -585,9 +583,11 @@ static HRESULT ParsePayloadRefsFromXml(
583 ExitOnFailure(hr, "Failed to get Id attribute.");
584
585 // find payload
588 - hr = PayloadFindById(pPayloads, sczId, &pPackagePayload->pPayload);
586 + hr = PayloadFindById(pPayloads, sczId, &pPackage->payloads.rgpPayloads[i]);
587 ExitOnFailure(hr, "Failed to find payload.");
588
589 + pPackage->payloads.qwTotalSize += pPackage->payloads.rgpPayloads[i]->qwFileSize;
590 +
591 // prepare next iteration
592 ReleaseNullObject(pixnNode);
593 }
src/engine/package.h
+1 -8
@@ -184,12 +184,6 @@ typedef struct _BURN_SLIPSTREAM_MSP
184 BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan.
185 } BURN_SLIPSTREAM_MSP;
186
187 -typedef struct _BURN_PACKAGE_PAYLOAD
188 -{
189 - BURN_PAYLOAD* pPayload;
190 - BOOL fCached;
191 -} BURN_PACKAGE_PAYLOAD;
192 -
187 typedef struct _BURN_DEPENDENCY_PROVIDER
188 {
189 LPWSTR sczKey;
@@ -260,8 +254,7 @@ typedef struct _BURN_PACKAGE
254 BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState;// only valid after Plan.
255 BURN_PACKAGE_REGISTRATION_STATE transactionRegistrationState; // only valid during Apply inside an MSI transaction.
256
263 - BURN_PACKAGE_PAYLOAD* rgPayloads;
264 - DWORD cPayloads;
257 + BURN_PAYLOAD_GROUP payloads;
258
259 BURN_DEPENDENCY_PROVIDER* rgDependencyProviders;
260 DWORD cDependencyProviders;
src/engine/payload.cpp
+31 -10
@@ -18,6 +18,7 @@ static HRESULT FindEmbeddedBySourcePath(
18 extern "C" HRESULT PayloadsParseFromXml(
19 __in BURN_PAYLOADS* pPayloads,
20 __in_opt BURN_CONTAINERS* pContainers,
21 + __in_opt BURN_PAYLOAD_GROUP* pLayoutPayloads,
22 __in IXMLDOMNode* pixnBundle
23 )
24 {
@@ -136,6 +137,17 @@ extern "C" HRESULT PayloadsParseFromXml(
137 hr = StrAllocHexDecode(scz, &pPayload->pbHash, &pPayload->cbHash);
138 ExitOnFailure(hr, "Failed to hex decode the Payload/@Hash.");
139
140 + if (pPayload->fLayoutOnly && pLayoutPayloads)
141 + {
142 + hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pLayoutPayloads->rgpPayloads), pLayoutPayloads->cPayloads + 1, sizeof(BURN_PAYLOAD*), 5);
143 + ExitOnNull(pPayloads->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for layout payloads.");
144 +
145 + pLayoutPayloads->rgpPayloads[pLayoutPayloads->cPayloads] = pPayload;
146 + ++pLayoutPayloads->cPayloads;
147 +
148 + pLayoutPayloads->qwTotalSize += pPayload->qwFileSize;
149 + }
150 +
151 // prepare next iteration
152 ReleaseNullObject(pixnNode);
153 }
@@ -150,6 +162,24 @@ LExit:
162 return hr;
163 }
164
165 +extern "C" void PayloadUninitialize(
166 + __in BURN_PAYLOAD* pPayload
167 + )
168 +{
169 + if (pPayload)
170 + {
171 + ReleaseStr(pPayload->sczKey);
172 + ReleaseStr(pPayload->sczFilePath);
173 + ReleaseMem(pPayload->pbHash);
174 + ReleaseStr(pPayload->sczSourcePath);
175 + ReleaseStr(pPayload->sczLocalFilePath);
176 + ReleaseStr(pPayload->downloadSource.sczUrl);
177 + ReleaseStr(pPayload->downloadSource.sczUser);
178 + ReleaseStr(pPayload->downloadSource.sczPassword);
179 + ReleaseStr(pPayload->sczUnverifiedPath);
180 + }
181 +}
182 +
183 extern "C" void PayloadsUninitialize(
184 __in BURN_PAYLOADS* pPayloads
185 )
@@ -158,16 +188,7 @@ extern "C" void PayloadsUninitialize(
188 {
189 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
190 {
161 - BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i];
162 -
163 - ReleaseStr(pPayload->sczKey);
164 - ReleaseStr(pPayload->sczFilePath);
165 - ReleaseMem(pPayload->pbHash);
166 - ReleaseStr(pPayload->sczSourcePath);
167 - ReleaseStr(pPayload->sczLocalFilePath);
168 - ReleaseStr(pPayload->downloadSource.sczUrl);
169 - ReleaseStr(pPayload->downloadSource.sczUser);
170 - ReleaseStr(pPayload->downloadSource.sczPassword);
191 + PayloadUninitialize(pPayloads->rgPayloads + i);
192 }
193 MemFree(pPayloads->rgPayloads);
194 }
src/engine/payload.h
+12
@@ -45,6 +45,8 @@ typedef struct _BURN_PAYLOAD
45 // mutable members
46 BURN_PAYLOAD_STATE state;
47 LPWSTR sczLocalFilePath; // location of extracted or downloaded copy
48 +
49 + LPWSTR sczUnverifiedPath;
50 } BURN_PAYLOAD;
51
52 typedef struct _BURN_PAYLOADS
@@ -53,14 +55,24 @@ typedef struct _BURN_PAYLOADS
55 DWORD cPayloads;
56 } BURN_PAYLOADS;
57
58 +typedef struct _BURN_PAYLOAD_GROUP
59 +{
60 + BURN_PAYLOAD** rgpPayloads;
61 + DWORD cPayloads;
62 + DWORD64 qwTotalSize;
63 +} BURN_PAYLOAD_GROUP;
64
65 // functions
66
67 HRESULT PayloadsParseFromXml(
68 __in BURN_PAYLOADS* pPayloads,
69 __in_opt BURN_CONTAINERS* pContainers,
70 + __in_opt BURN_PAYLOAD_GROUP* pLayoutPayloads,
71 __in IXMLDOMNode* pixnBundle
72 );
73 +void PayloadUninitialize(
74 + __in BURN_PAYLOAD* pPayload
75 + );
76 void PayloadsUninitialize(
77 __in BURN_PAYLOADS* pPayloads
78 );
src/engine/plan.cpp
+144 -749
@@ -15,6 +15,15 @@ static void UninitializeRegistrationAction(
15 static void UninitializeCacheAction(
16 __in BURN_CACHE_ACTION* pCacheAction
17 );
18 +static void ResetPlannedContainerState(
19 + __in BURN_CONTAINER* pContainer
20 + );
21 +static void ResetPlannedPayloadsState(
22 + __in BURN_PAYLOADS* pPayloads
23 + );
24 +static void ResetPlannedPayloadGroupState(
25 + __in BURN_PAYLOAD_GROUP* pPayloadGroup
26 + );
27 static void ResetPlannedPackageState(
28 __in BURN_PACKAGE* pPackage
29 );
@@ -30,8 +39,7 @@ static HRESULT PlanPackagesHelper(
39 __in BURN_LOGGING* pLog,
40 __in BURN_VARIABLES* pVariables,
41 __in BOOTSTRAPPER_DISPLAY display,
33 - __in BOOTSTRAPPER_RELATION_TYPE relationType,
34 - __in_z_opt LPCWSTR wzLayoutDirectory
42 + __in BOOTSTRAPPER_RELATION_TYPE relationType
43 );
44 static HRESULT InitializePackage(
45 __in BURN_PLAN* pPlan,
@@ -48,7 +56,6 @@ static HRESULT ProcessPackage(
56 __in BURN_LOGGING* pLog,
57 __in BURN_VARIABLES* pVariables,
58 __in BOOTSTRAPPER_DISPLAY display,
51 - __in_z_opt LPCWSTR wzLayoutDirectory,
59 __inout HANDLE* phSyncpointEvent,
60 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
61 );
@@ -99,54 +106,9 @@ static HRESULT AppendRollbackCacheAction(
106 __in BURN_PLAN* pPlan,
107 __out BURN_CACHE_ACTION** ppCacheAction
108 );
102 -static HRESULT AppendLayoutContainerAction(
103 - __in BURN_PLAN* pPlan,
104 - __in_opt BURN_PACKAGE* pPackage,
105 - __in DWORD iPackageStartAction,
106 - __in BURN_CONTAINER* pContainer,
107 - __in BOOL fContainerCached,
108 - __in_z LPCWSTR wzLayoutDirectory
109 - );
110 -static HRESULT AppendCacheOrLayoutPayloadAction(
111 - __in BURN_PLAN* pPlan,
112 - __in_opt BURN_PACKAGE* pPackage,
113 - __in DWORD iPackageStartAction,
114 - __in BURN_PAYLOAD* pPayload,
115 - __in BOOL fPayloadCached,
116 - __in_z_opt LPCWSTR wzLayoutDirectory
117 - );
118 -static BOOL FindContainerCacheAction(
119 - __in BURN_CACHE_ACTION_TYPE type,
120 - __in BURN_PLAN* pPlan,
121 - __in BURN_CONTAINER* pContainer,
122 - __in DWORD iSearchStart,
123 - __in DWORD iSearchEnd,
124 - __out_opt BURN_CACHE_ACTION** ppCacheAction,
125 - __out_opt DWORD* piCacheAction
126 - );
127 -static HRESULT CreateContainerAcquireAndExtractAction(
109 +static HRESULT ProcessPayloadGroup(
110 __in BURN_PLAN* pPlan,
129 - __in BURN_CONTAINER* pContainer,
130 - __in DWORD iPackageStartAction,
131 - __in BOOL fPayloadCached,
132 - __out BURN_CACHE_ACTION** ppContainerExtractAction,
133 - __out DWORD* piContainerTryAgainAction
134 - );
135 -static HRESULT AddAcquireContainer(
136 - __in BURN_PLAN* pPlan,
137 - __in BURN_CONTAINER* pContainer,
138 - __out_opt BURN_CACHE_ACTION** ppCacheAction,
139 - __out_opt DWORD* piCacheAction
140 - );
141 -static HRESULT AddExtractPayload(
142 - __in BURN_CACHE_ACTION* pCacheAction,
143 - __in_opt BURN_PACKAGE* pPackage,
144 - __in BURN_PAYLOAD* pPayload,
145 - __in_z LPCWSTR wzPayloadWorkingPath
146 - );
147 -static BURN_CACHE_ACTION* ProcessSharedPayload(
148 - __in BURN_PLAN* pPlan,
149 - __in BURN_PAYLOAD* pPayload
111 + __in BURN_PAYLOAD_GROUP* pPayloadGroup
112 );
113 static void RemoveUnnecessaryActions(
114 __in BOOL fExecute,
@@ -175,24 +137,17 @@ static BOOL NeedsCache(
137 __in BURN_PACKAGE* pPackage,
138 __in BOOL fExecute
139 );
178 -static HRESULT CreateContainerProgress(
179 - __in BURN_PLAN* pPlan,
180 - __in BURN_CONTAINER* pContainer,
181 - __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress
182 - );
183 -static HRESULT CreatePayloadProgress(
184 - __in BURN_PLAN* pPlan,
185 - __in BURN_PAYLOAD* pPayload,
186 - __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress
187 - );
140
141 // function definitions
142
143 extern "C" void PlanReset(
144 __in BURN_PLAN* pPlan,
193 - __in BURN_PACKAGES* pPackages
145 + __in BURN_CONTAINERS* pContainers,
146 + __in BURN_PACKAGES* pPackages,
147 + __in BURN_PAYLOAD_GROUP* pLayoutPayloads
148 )
149 {
150 + ReleaseNullStr(pPlan->sczLayoutDirectory);
151 PackageUninitialize(&pPlan->forwardCompatibleBundle);
152
153 if (pPlan->rgRegistrationActions)
@@ -271,8 +226,21 @@ extern "C" void PlanReset(
226 ReleaseDict(pPlan->shPayloadProgress);
227 }
228
229 + if (pPlan->pPayloads)
230 + {
231 + ResetPlannedPayloadsState(pPlan->pPayloads);
232 + }
233 +
234 memset(pPlan, 0, sizeof(BURN_PLAN));
235
236 + if (pContainers->rgContainers)
237 + {
238 + for (DWORD i = 0; i < pContainers->cContainers; ++i)
239 + {
240 + ResetPlannedContainerState(&pContainers->rgContainers[i]);
241 + }
242 + }
243 +
244 // Reset the planned actions for each package.
245 if (pPackages->rgPackages)
246 {
@@ -282,6 +250,8 @@ extern "C" void PlanReset(
250 }
251 }
252
253 + ResetPlannedPayloadGroupState(pLayoutPayloads);
254 +
255 // Reset the planned state for each rollback boundary.
256 if (pPackages->rgRollbackBoundaries)
257 {
@@ -417,34 +387,35 @@ extern "C" HRESULT PlanLayoutBundle(
387 __in_z LPCWSTR wzExecutableName,
388 __in DWORD64 qwBundleSize,
389 __in BURN_VARIABLES* pVariables,
420 - __in BURN_PAYLOADS* pPayloads,
421 - __out_z LPWSTR* psczLayoutDirectory
390 + __in BURN_PAYLOAD_GROUP* pLayoutPayloads
391 )
392 {
393 HRESULT hr = S_OK;
394 BURN_CACHE_ACTION* pCacheAction = NULL;
395 LPWSTR sczExecutablePath = NULL;
427 - LPWSTR sczLayoutDirectory = NULL;
396
397 // Get the layout directory.
430 - hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &sczLayoutDirectory);
398 + hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &pPlan->sczLayoutDirectory);
399 if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory.
400 {
433 - hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &sczLayoutDirectory);
401 + hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &pPlan->sczLayoutDirectory);
402 if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory.
403 {
404 hr = PathForCurrentProcess(&sczExecutablePath, NULL);
405 ExitOnFailure(hr, "Failed to get path for current executing process as layout directory.");
406
439 - hr = PathGetDirectory(sczExecutablePath, &sczLayoutDirectory);
407 + hr = PathGetDirectory(sczExecutablePath, &pPlan->sczLayoutDirectory);
408 ExitOnFailure(hr, "Failed to get executing process as layout directory.");
409 }
410 }
411 ExitOnFailure(hr, "Failed to get bundle layout directory property.");
412
445 - hr = PathBackslashTerminate(&sczLayoutDirectory);
413 + hr = PathBackslashTerminate(&pPlan->sczLayoutDirectory);
414 ExitOnFailure(hr, "Failed to ensure layout directory is backslash terminated.");
415
416 + hr = ProcessPayloadGroup(pPlan, pLayoutPayloads);
417 + ExitOnFailure(hr, "Failed to process payload group for bundle.");
418 +
419 // Plan the layout of the bundle engine itself.
420 hr = AppendCacheAction(pPlan, &pCacheAction);
421 ExitOnFailure(hr, "Failed to append bundle start action.");
@@ -454,36 +425,17 @@ extern "C" HRESULT PlanLayoutBundle(
425 hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0);
426 ExitOnFailure(hr, "Failed to to copy executable name for bundle.");
427
457 - hr = StrAllocString(&pCacheAction->bundleLayout.sczLayoutDirectory, sczLayoutDirectory, 0);
458 - ExitOnFailure(hr, "Failed to to copy layout directory for bundle.");
459 -
428 hr = CacheCalculateBundleLayoutWorkingPath(pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath);
429 ExitOnFailure(hr, "Failed to calculate bundle layout working path.");
430
431 pCacheAction->bundleLayout.qwBundleSize = qwBundleSize;
432 + pCacheAction->bundleLayout.pPayloadGroup = pLayoutPayloads;
433
465 - pPlan->qwCacheSizeTotal += qwBundleSize;
434 + pPlan->qwCacheSizeTotal += 2 * qwBundleSize;
435
436 ++pPlan->cOverallProgressTicksTotal;
437
469 - // Plan the layout of layout-only payloads.
470 - for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
471 - {
472 - BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i;
473 - if (pPayload->fLayoutOnly)
474 - {
475 - // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached
476 - // (instead of always FALSE).
477 - hr = AppendCacheOrLayoutPayloadAction(pPlan, NULL, BURN_PLAN_INVALID_ACTION_INDEX, pPayload, FALSE, sczLayoutDirectory);
478 - ExitOnFailure(hr, "Failed to plan layout payload.");
479 - }
480 - }
481 -
482 - *psczLayoutDirectory = sczLayoutDirectory;
483 - sczLayoutDirectory = NULL;
484 -
438 LExit:
486 - ReleaseStr(sczLayoutDirectory);
439 ReleaseStr(sczExecutablePath);
440
441 return hr;
@@ -562,13 +514,12 @@ extern "C" HRESULT PlanPackages(
514 __in BURN_LOGGING* pLog,
515 __in BURN_VARIABLES* pVariables,
516 __in BOOTSTRAPPER_DISPLAY display,
565 - __in BOOTSTRAPPER_RELATION_TYPE relationType,
566 - __in_z_opt LPCWSTR wzLayoutDirectory
517 + __in BOOTSTRAPPER_RELATION_TYPE relationType
518 )
519 {
520 HRESULT hr = S_OK;
521
571 - hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, wzLayoutDirectory);
522 + hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType);
523
524 return hr;
525 }
@@ -782,7 +733,7 @@ extern "C" HRESULT PlanPassThroughBundle(
733 // Plan passthrough package.
734 // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate)
735 // so we don't need to plan clean up.
785 - hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType, NULL);
736 + hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType);
737 ExitOnFailure(hr, "Failed to process passthrough package.");
738
739 LExit:
@@ -802,7 +753,7 @@ extern "C" HRESULT PlanUpdateBundle(
753 HRESULT hr = S_OK;
754
755 // Plan update package.
805 - hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, NULL);
756 + hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType);
757 ExitOnFailure(hr, "Failed to process update package.");
758
759 LExit:
@@ -818,8 +769,7 @@ static HRESULT PlanPackagesHelper(
769 __in BURN_LOGGING* pLog,
770 __in BURN_VARIABLES* pVariables,
771 __in BOOTSTRAPPER_DISPLAY display,
821 - __in BOOTSTRAPPER_RELATION_TYPE relationType,
822 - __in_z_opt LPCWSTR wzLayoutDirectory
772 + __in BOOTSTRAPPER_RELATION_TYPE relationType
773 )
774 {
775 HRESULT hr = S_OK;
@@ -856,7 +806,7 @@ static HRESULT PlanPackagesHelper(
806 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
807 BURN_PACKAGE* pPackage = rgPackages + iPackage;
808
859 - hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, wzLayoutDirectory, &hSyncpointEvent, &pRollbackBoundary);
809 + hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &hSyncpointEvent, &pRollbackBoundary);
810 ExitOnFailure(hr, "Failed to process package.");
811 }
812
@@ -962,7 +912,6 @@ static HRESULT ProcessPackage(
912 __in BURN_LOGGING* pLog,
913 __in BURN_VARIABLES* pVariables,
914 __in BOOTSTRAPPER_DISPLAY display,
965 - __in_z_opt LPCWSTR wzLayoutDirectory,
915 __inout HANDLE* phSyncpointEvent,
916 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
917 )
@@ -976,7 +925,7 @@ static HRESULT ProcessPackage(
925
926 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
927 {
979 - hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory);
928 + hr = PlanLayoutPackage(pPlan, pPackage);
929 ExitOnFailure(hr, "Failed to plan layout package.");
930 }
931 else
@@ -1035,59 +984,69 @@ LExit:
984 return hr;
985 }
986
1038 -extern "C" HRESULT PlanLayoutPackage(
987 +extern "C" HRESULT PlanLayoutContainer(
988 __in BURN_PLAN* pPlan,
1040 - __in BURN_PACKAGE* pPackage,
1041 - __in_z_opt LPCWSTR wzLayoutDirectory
989 + __in BURN_CONTAINER* pContainer
990 )
991 {
992 HRESULT hr = S_OK;
993 BURN_CACHE_ACTION* pCacheAction = NULL;
1046 - DWORD iPackageStartAction = 0;
994
1048 - hr = AppendCacheAction(pPlan, &pCacheAction);
1049 - ExitOnFailure(hr, "Failed to append package start action.");
995 + Assert(!pContainer->fPlanned);
996 + pContainer->fPlanned = TRUE;
997
1051 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START;
1052 - pCacheAction->packageStart.pPackage = pPackage;
998 + if (pPlan->sczLayoutDirectory)
999 + {
1000 + if (!pContainer->fAttached)
1001 + {
1002 + hr = AppendCacheAction(pPlan, &pCacheAction);
1003 + ExitOnFailure(hr, "Failed to append package start action.");
1004
1054 - // Remember the index for the package start action (which is now the last in the cache
1055 - // actions array) because the array may be resized later and move around in memory.
1056 - iPackageStartAction = pPlan->cCacheActions - 1;
1005 + pCacheAction->type = BURN_CACHE_ACTION_TYPE_CONTAINER;
1006 + pCacheAction->container.pContainer = pContainer;
1007
1058 - // If any of the package payloads are not cached, add them to the plan.
1059 - for (DWORD i = 0; i < pPackage->cPayloads; ++i)
1008 + pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize;
1009 + }
1010 + }
1011 + else
1012 {
1061 - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i];
1013 + pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize;
1014 + }
1015
1063 - // If doing layout and the package is in a container.
1064 - if (wzLayoutDirectory && pPackagePayload->pPayload->pContainer)
1016 + if (!pContainer->sczUnverifiedPath)
1017 + {
1018 + if (pContainer->fActuallyAttached)
1019 {
1066 - // TODO: determine if a container already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE).
1067 - hr = AppendLayoutContainerAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload->pContainer, FALSE, wzLayoutDirectory);
1068 - ExitOnFailure(hr, "Failed to append layout container action.");
1020 + hr = PathForCurrentProcess(&pContainer->sczUnverifiedPath, NULL);
1021 + ExitOnFailure(hr, "Failed to get path for executing module as attached container working path.");
1022 }
1023 else
1024 {
1072 - // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE).
1073 - hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, FALSE, wzLayoutDirectory);
1074 - ExitOnFailure(hr, "Failed to append cache/layout payload action.");
1025 + hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &pContainer->sczUnverifiedPath);
1026 + ExitOnFailure(hr, "Failed to calculate unverified path for container.");
1027 }
1076 -
1077 - Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type);
1078 - ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads;
1079 - pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize;
1028 }
1029
1082 - // Create package stop action.
1083 - hr = AppendCacheAction(pPlan, &pCacheAction);
1084 - ExitOnFailure(hr, "Failed to append cache action.");
1030 +LExit:
1031 + return hr;
1032 +}
1033
1086 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP;
1087 - pCacheAction->packageStop.pPackage = pPackage;
1034 +extern "C" HRESULT PlanLayoutPackage(
1035 + __in BURN_PLAN* pPlan,
1036 + __in BURN_PACKAGE* pPackage
1037 + )
1038 +{
1039 + HRESULT hr = S_OK;
1040 + BURN_CACHE_ACTION* pCacheAction = NULL;
1041 +
1042 + hr = ProcessPayloadGroup(pPlan, &pPackage->payloads);
1043 + ExitOnFailure(hr, "Failed to process payload group for package: %ls.", pPackage->sczId);
1044
1089 - // Update the start action with the location of the complete action.
1090 - pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1;
1045 + hr = AppendCacheAction(pPlan, &pCacheAction);
1046 + ExitOnFailure(hr, "Failed to append package start action.");
1047 +
1048 + pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE;
1049 + pCacheAction->package.pPackage = pPackage;
1050
1051 ++pPlan->cOverallProgressTicksTotal;
1052
@@ -1854,29 +1813,37 @@ static void UninitializeCacheAction(
1813
1814 case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
1815 ReleaseStr(pCacheAction->bundleLayout.sczExecutableName);
1857 - ReleaseStr(pCacheAction->bundleLayout.sczLayoutDirectory);
1816 ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath);
1817 break;
1818 + }
1819 +}
1820
1861 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER:
1862 - ReleaseStr(pCacheAction->resolveContainer.sczUnverifiedPath);
1863 - break;
1864 -
1865 - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER:
1866 - ReleaseStr(pCacheAction->extractContainer.sczContainerUnverifiedPath);
1867 - ReleaseMem(pCacheAction->extractContainer.rgPayloads);
1868 - break;
1821 +static void ResetPlannedContainerState(
1822 + __in BURN_CONTAINER* pContainer
1823 + )
1824 +{
1825 + pContainer->fPlanned = FALSE;
1826 +}
1827
1870 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD:
1871 - ReleaseStr(pCacheAction->resolvePayload.sczUnverifiedPath);
1872 - break;
1828 +static void ResetPlannedPayloadsState(
1829 + __in BURN_PAYLOADS* pPayloads
1830 + )
1831 +{
1832 + for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
1833 + {
1834 + BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i;
1835
1874 - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD:
1875 - ReleaseStr(pCacheAction->cachePayload.sczUnverifiedPath);
1876 - break;
1836 + pPayload->state = BURN_PAYLOAD_STATE_NONE;
1837 + ReleaseNullStr(pPayload->sczLocalFilePath);
1838 }
1839 }
1840
1841 +static void ResetPlannedPayloadGroupState(
1842 + __in BURN_PAYLOAD_GROUP* /*pPayloadGroup*/
1843 + )
1844 +{
1845 +}
1846 +
1847 static void ResetPlannedPackageState(
1848 __in BURN_PACKAGE* pPackage
1849 )
@@ -1931,6 +1898,8 @@ static void ResetPlannedPackageState(
1898 pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_NONE;
1899 }
1900 }
1901 +
1902 + ResetPlannedPayloadGroupState(&pPackage->payloads);
1903 }
1904
1905 static void ResetPlannedRollbackBoundaryState(
@@ -2091,7 +2060,6 @@ static HRESULT AddCachePackageHelper(
2060 HRESULT hr = S_OK;
2061 BURN_CACHE_ACTION* pCacheAction = NULL;
2062 DWORD dwCheckpoint = 0;
2094 - DWORD iPackageStartAction = 0;
2063
2064 BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent);
2065 if (fPlanned)
@@ -2105,7 +2073,7 @@ static HRESULT AddCachePackageHelper(
2073 dwCheckpoint = GetNextCheckpointId(pPlan);
2074
2075 hr = AppendCacheAction(pPlan, &pCacheAction);
2108 - ExitOnFailure(hr, "Failed to append package start action.");
2076 + ExitOnFailure(hr, "Failed to append checkpoint before package start action.");
2077
2078 pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT;
2079 pCacheAction->checkpoint.dwId = dwCheckpoint;
@@ -2123,50 +2091,8 @@ static HRESULT AddCachePackageHelper(
2091 pCacheAction->checkpoint.dwId = dwCheckpoint;
2092 }
2093
2126 - // Plan the package start.
2127 - hr = AppendCacheAction(pPlan, &pCacheAction);
2128 - ExitOnFailure(hr, "Failed to append package start action.");
2129 -
2130 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START;
2131 - pCacheAction->packageStart.pPackage = pPackage;
2132 -
2133 - // Remember the index for the package start action (which is now the last in the cache
2134 - // actions array) because we have to update this action after processing all the payloads
2135 - // and the array may be resized later which would move a pointer around in memory.
2136 - iPackageStartAction = pPlan->cCacheActions - 1;
2137 -
2138 - if (fPlanCacheRollback)
2139 - {
2140 - // Create a package cache rollback action.
2141 - hr = AppendRollbackCacheAction(pPlan, &pCacheAction);
2142 - ExitOnFailure(hr, "Failed to append rollback cache action.");
2143 -
2144 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE;
2145 - pCacheAction->rollbackPackage.pPackage = pPackage;
2146 - }
2147 -
2148 - // Add all the payload cache operations to the plan for this package.
2149 - for (DWORD i = 0; i < pPackage->cPayloads; ++i)
2150 - {
2151 - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i];
2152 -
2153 - hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, pPackagePayload->fCached, NULL);
2154 - ExitOnFailure(hr, "Failed to append payload cache action.");
2155 -
2156 - Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type);
2157 - ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads;
2158 - pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize;
2159 - }
2160 -
2161 - // Create package stop action.
2162 - hr = AppendCacheAction(pPlan, &pCacheAction);
2163 - ExitOnFailure(hr, "Failed to append cache action.");
2164 -
2165 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP;
2166 - pCacheAction->packageStop.pPackage = pPackage;
2167 -
2168 - // Update the start action with the location of the complete action.
2169 - pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1;
2094 + hr = PlanLayoutPackage(pPlan, pPackage);
2095 + ExitOnFailure(hr, "Failed to plan cache for package.");
2096
2097 // Create syncpoint action.
2098 hr = AppendCacheAction(pPlan, &pCacheAction);
@@ -2178,8 +2104,6 @@ static HRESULT AddCachePackageHelper(
2104
2105 *phSyncpointEvent = pCacheAction->syncpoint.hEvent;
2106
2181 - ++pPlan->cOverallProgressTicksTotal;
2182 -
2107 pPackage->fPlannedCache = TRUE;
2108 if (pPackage->fCanAffectRegistration)
2109 {
@@ -2225,9 +2149,9 @@ static BOOL AlreadyPlannedCachePackage(
2149 {
2150 BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction;
2151
2228 - if (BURN_CACHE_ACTION_TYPE_PACKAGE_STOP == pCacheAction->type)
2152 + if (BURN_CACHE_ACTION_TYPE_PACKAGE == pCacheAction->type)
2153 {
2230 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->packageStop.pPackage->sczId, -1, wzPackageId, -1))
2154 + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->package.pPackage->sczId, -1, wzPackageId, -1))
2155 {
2156 if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type)
2157 {
@@ -2284,460 +2208,39 @@ LExit:
2208 return hr;
2209 }
2210
2287 -static HRESULT AppendLayoutContainerAction(
2288 - __in BURN_PLAN* pPlan,
2289 - __in_opt BURN_PACKAGE* pPackage,
2290 - __in DWORD iPackageStartAction,
2291 - __in BURN_CONTAINER* pContainer,
2292 - __in BOOL fContainerCached,
2293 - __in_z LPCWSTR wzLayoutDirectory
2294 - )
2295 -{
2296 - HRESULT hr = S_OK;
2297 - BURN_CACHE_ACTION* pAcquireAction = NULL;
2298 - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX;
2299 - LPWSTR sczContainerWorkingPath = NULL;
2300 - BURN_CACHE_ACTION* pCacheAction = NULL;
2301 - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL;
2302 -
2303 - // No need to do anything if the container is already cached or is attached to the bundle (since the
2304 - // bundle itself will already have a layout action).
2305 - if (fContainerCached || pContainer->fAttached)
2306 - {
2307 - ExitFunction();
2308 - }
2309 -
2310 - // Ensure the container is being acquired. If it is, then some earlier package already planned the layout of this container so
2311 - // don't do it again. Otherwise, plan away!
2312 - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, 0, iPackageStartAction, NULL, NULL))
2313 - {
2314 - hr = AddAcquireContainer(pPlan, pContainer, &pAcquireAction, &iAcquireAction);
2315 - ExitOnFailure(hr, "Failed to append acquire container action for layout to plan.");
2316 -
2317 - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireAction->type);
2318 -
2319 - // Create the layout container action.
2320 - hr = StrAllocString(&sczContainerWorkingPath, pAcquireAction->resolveContainer.sczUnverifiedPath, 0);
2321 - ExitOnFailure(hr, "Failed to copy container working path for layout.");
2322 -
2323 - hr = AppendCacheAction(pPlan, &pCacheAction);
2324 - ExitOnFailure(hr, "Failed to append cache action to cache payload.");
2325 -
2326 - hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress);
2327 - ExitOnFailure(hr, "Failed to create container progress.");
2328 -
2329 - hr = StrAllocString(&pCacheAction->layoutContainer.sczLayoutDirectory, wzLayoutDirectory, 0);
2330 - ExitOnFailure(hr, "Failed to copy layout directory into plan.");
2331 -
2332 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER;
2333 - pCacheAction->layoutContainer.pPackage = pPackage;
2334 - pCacheAction->layoutContainer.pContainer = pContainer;
2335 - pCacheAction->layoutContainer.iProgress = pContainerProgress->iIndex;
2336 - pCacheAction->layoutContainer.fMove = TRUE;
2337 - pCacheAction->layoutContainer.iTryAgainAction = iAcquireAction;
2338 - pCacheAction->layoutContainer.sczUnverifiedPath = sczContainerWorkingPath;
2339 - sczContainerWorkingPath = NULL;
2340 - }
2341 -
2342 -LExit:
2343 - ReleaseNullStr(sczContainerWorkingPath);
2344 -
2345 - return hr;
2346 -}
2347 -
2348 -static HRESULT AppendCacheOrLayoutPayloadAction(
2211 +static HRESULT ProcessPayloadGroup(
2212 __in BURN_PLAN* pPlan,
2350 - __in_opt BURN_PACKAGE* pPackage,
2351 - __in DWORD iPackageStartAction,
2352 - __in BURN_PAYLOAD* pPayload,
2353 - __in BOOL fPayloadCached,
2354 - __in_z_opt LPCWSTR wzLayoutDirectory
2213 + __in BURN_PAYLOAD_GROUP* pPayloadGroup
2214 )
2215 {
2216 HRESULT hr = S_OK;
2358 - LPWSTR sczPayloadWorkingPath = NULL;
2359 - BURN_CACHE_ACTION* pCacheAction = NULL;
2360 - DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX;
2361 - BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL;
2362 -
2363 - hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &sczPayloadWorkingPath);
2364 - ExitOnFailure(hr, "Failed to calculate unverified path for payload.");
2365 -
2366 - // If the payload is in a container, ensure the container is being acquired
2367 - // then add this payload to the list of payloads to extract already in the plan.
2368 - if (pPayload->pContainer)
2369 - {
2370 - BURN_CACHE_ACTION* pPreviousPackageExtractAction = NULL;
2371 - BURN_CACHE_ACTION* pThisPackageExtractAction = NULL;
2372 -
2373 - // If the payload is not already cached, then add it to the first extract container action in the plan. Extracting
2374 - // all the needed payloads from the container in a single pass is the most efficient way to extract files from
2375 - // containers. If there is not an extract container action before our package, that is okay because we'll create
2376 - // an extract container action for our package in a second anyway.
2377 - if (!fPayloadCached)
2378 - {
2379 - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, 0, iPackageStartAction, &pPreviousPackageExtractAction, NULL))
2380 - {
2381 - hr = AddExtractPayload(pPreviousPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath);
2382 - ExitOnFailure(hr, "Failed to add extract payload action to previous package.");
2383 - }
2384 - }
2385 -
2386 - // If there is already an extract container action after our package start action then try to find an acquire action
2387 - // that is matched with it. If there is an acquire action then that is our "try again" action, otherwise we'll use the existing
2388 - // extract action as the "try again" action.
2389 - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pThisPackageExtractAction, &iTryAgainAction))
2390 - {
2391 - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX;
2392 - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, iTryAgainAction, NULL, &iAcquireAction))
2393 - {
2394 - iTryAgainAction = iAcquireAction;
2395 - }
2396 - }
2397 - else // did not find an extract container action for our package.
2398 - {
2399 - // Ensure there is an extract action (and maybe an acquire action) for every package that has payloads. The
2400 - // acquire and extract action will be skipped if the payload is already cached or was added to a previous
2401 - // package's extract action above.
2402 - //
2403 - // These actions always exist (even when they are likely to be skipped) so that "try again" will not
2404 - // jump so far back in the plan that you end up extracting payloads for other packages. With these actions
2405 - // "try again" will only retry the extraction for payloads in this package.
2406 - hr = CreateContainerAcquireAndExtractAction(pPlan, pPayload->pContainer, iPackageStartAction, pPreviousPackageExtractAction ? TRUE : fPayloadCached, &pThisPackageExtractAction, &iTryAgainAction);
2407 - ExitOnFailure(hr, "Failed to create container extract action.");
2408 - }
2409 - ExitOnFailure(hr, "Failed while searching for package's container extract action.");
2410 -
2411 - // We *always* add the payload to this package's extract action even though the extract action
2412 - // is probably being skipped until retry if there was a previous package extract action.
2413 - hr = AddExtractPayload(pThisPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath);
2414 - ExitOnFailure(hr, "Failed to add extract payload to current package.");
2415 - }
2416 - else // add a payload acquire action to the plan.
2417 - {
2418 - // Try to find an existing acquire action for this payload. If one is not found,
2419 - // we'll create it. At the same time we will change any cache/layout payload actions
2420 - // that would "MOVE" the file to "COPY" so that our new cache/layout action below
2421 - // can do the move.
2422 - pCacheAction = ProcessSharedPayload(pPlan, pPayload);
2423 - if (!pCacheAction)
2424 - {
2425 - hr = AppendCacheAction(pPlan, &pCacheAction);
2426 - ExitOnFailure(hr, "Failed to append cache action to acquire payload.");
2427 -
2428 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD;
2429 - pCacheAction->fSkipUntilRetried = fPayloadCached;
2430 - pCacheAction->resolvePayload.pPackage = pPackage;
2431 - pCacheAction->resolvePayload.pPayload = pPayload;
2432 - hr = StrAllocString(&pCacheAction->resolvePayload.sczUnverifiedPath, sczPayloadWorkingPath, 0);
2433 - ExitOnFailure(hr, "Failed to copy unverified path for payload to acquire.");
2434 - }
2435 -
2436 - iTryAgainAction = static_cast<DWORD>(pCacheAction - pPlan->rgCacheActions);
2437 - pCacheAction = NULL;
2438 - }
2217
2440 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iTryAgainAction);
2441 - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type ||
2442 - BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type ||
2443 - BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pPlan->rgCacheActions[iTryAgainAction].type);
2444 -
2445 - hr = AppendCacheAction(pPlan, &pCacheAction);
2446 - ExitOnFailure(hr, "Failed to append cache action to cache payload.");
2447 -
2448 - hr = CreatePayloadProgress(pPlan, pPayload, &pPayloadProgress);
2449 - ExitOnFailure(hr, "Failed to create payload progress.");
2450 -
2451 - if (!wzLayoutDirectory)
2218 + for (DWORD i = 0; i < pPayloadGroup->cPayloads; ++i)
2219 {
2453 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD;
2454 - pCacheAction->cachePayload.pPackage = pPackage;
2455 - pCacheAction->cachePayload.pPayload = pPayload;
2456 - pCacheAction->cachePayload.iProgress = pPayloadProgress->iIndex;
2457 - pCacheAction->cachePayload.fMove = TRUE;
2458 - pCacheAction->cachePayload.iTryAgainAction = iTryAgainAction;
2459 - pCacheAction->cachePayload.sczUnverifiedPath = sczPayloadWorkingPath;
2460 - sczPayloadWorkingPath = NULL;
2461 - }
2462 - else
2463 - {
2464 - hr = StrAllocString(&pCacheAction->layoutPayload.sczLayoutDirectory, wzLayoutDirectory, 0);
2465 - ExitOnFailure(hr, "Failed to copy layout directory into plan.");
2466 -
2467 - pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD;
2468 - pCacheAction->layoutPayload.pPackage = pPackage;
2469 - pCacheAction->layoutPayload.pPayload = pPayload;
2470 - pCacheAction->layoutPayload.iProgress = pPayloadProgress->iIndex;
2471 - pCacheAction->layoutPayload.fMove = TRUE;
2472 - pCacheAction->layoutPayload.iTryAgainAction = iTryAgainAction;
2473 - pCacheAction->layoutPayload.sczUnverifiedPath = sczPayloadWorkingPath;
2474 - sczPayloadWorkingPath = NULL;
2475 - }
2476 -
2477 - pCacheAction = NULL;
2478 -
2479 -LExit:
2480 - ReleaseStr(sczPayloadWorkingPath);
2481 -
2482 - return hr;
2483 -}
2484 -
2485 -static BOOL FindContainerCacheAction(
2486 - __in BURN_CACHE_ACTION_TYPE type,
2487 - __in BURN_PLAN* pPlan,
2488 - __in BURN_CONTAINER* pContainer,
2489 - __in DWORD iSearchStart,
2490 - __in DWORD iSearchEnd,
2491 - __out_opt BURN_CACHE_ACTION** ppCacheAction,
2492 - __out_opt DWORD* piCacheAction
2493 - )
2494 -{
2495 - BOOL fFound = FALSE; // assume we won't find what we are looking for.
2496 -
2497 - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == type || BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == type);
2498 -
2499 - iSearchStart = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchStart) ? 0 : iSearchStart;
2500 - iSearchEnd = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchEnd) ? pPlan->cCacheActions : iSearchEnd;
2220 + BURN_PAYLOAD* pPayload = pPayloadGroup->rgpPayloads[i];
2221
2502 - for (DWORD iSearch = iSearchStart; iSearch < iSearchEnd; ++iSearch)
2503 - {
2504 - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iSearch;
2505 - if (pCacheAction->type == type &&
2506 - ((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pCacheAction->type && pCacheAction->resolveContainer.pContainer == pContainer) ||
2507 - (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type && pCacheAction->extractContainer.pContainer == pContainer)))
2222 + if (pPayload->pContainer && !pPayload->pContainer->fPlanned)
2223 {
2509 - if (ppCacheAction)
2510 - {
2511 - *ppCacheAction = pCacheAction;
2512 - }
2513 -
2514 - if (piCacheAction)
2515 - {
2516 - *piCacheAction = iSearch;
2517 - }
2518 -
2519 - fFound = TRUE;
2520 - break;
2224 + hr = PlanLayoutContainer(pPlan, pPayload->pContainer);
2225 + ExitOnFailure(hr, "Failed to plan container: %ls", pPayload->pContainer->sczId);
2226 }
2522 - }
2523 -
2524 - return fFound;
2525 -}
2227
2527 -static HRESULT CreateContainerAcquireAndExtractAction(
2528 - __in BURN_PLAN* pPlan,
2529 - __in BURN_CONTAINER* pContainer,
2530 - __in DWORD iPackageStartAction,
2531 - __in BOOL fPayloadCached,
2532 - __out BURN_CACHE_ACTION** ppContainerExtractAction,
2533 - __out DWORD* piContainerTryAgainAction
2534 - )
2535 -{
2536 - HRESULT hr = S_OK;
2537 - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX;
2538 - BURN_CACHE_ACTION* pContainerExtractAction = NULL;
2539 - DWORD iExtractAction = BURN_PLAN_INVALID_ACTION_INDEX;
2540 - DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX;
2541 - LPWSTR sczContainerWorkingPath = NULL;
2542 -
2543 - // If the container is actually attached to the executable then we will not need an acquire
2544 - // container action.
2545 - if (!pContainer->fActuallyAttached)
2546 - {
2547 - BURN_CACHE_ACTION* pAcquireContainerAction = NULL;
2548 -
2549 - // If there is no plan to acquire the container then add acquire action since we
2550 - // can't extract stuff out of a container until we acquire the container.
2551 - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pAcquireContainerAction, &iAcquireAction))
2228 + if (!pPlan->sczLayoutDirectory || !pPayload->pContainer)
2229 {
2553 - hr = AddAcquireContainer(pPlan, pContainer, &pAcquireContainerAction, &iAcquireAction);
2554 - ExitOnFailure(hr, "Failed to append acquire container action to plan.");
2555 -
2556 - pAcquireContainerAction->fSkipUntilRetried = TRUE; // we'll start by assuming the acquire is not necessary and the fPayloadCached below will set us straight if wrong.
2230 + pPlan->qwCacheSizeTotal += 2 * pPayload->qwFileSize;
2231 }
2232
2559 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction);
2560 - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireContainerAction->type);
2561 - Assert(pContainer == pAcquireContainerAction->resolveContainer.pContainer);
2562 - }
2563 -
2564 - Assert((pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction) ||
2565 - (!pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction));
2566 -
2567 - // If we do not find an action for extracting payloads from this container, create it now.
2568 - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pContainer, (BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction) ? iPackageStartAction : iAcquireAction, BURN_PLAN_INVALID_ACTION_INDEX, &pContainerExtractAction, &iExtractAction))
2569 - {
2570 - // Attached containers that are actually attached use the executable path for their working path.
2571 - if (pContainer->fActuallyAttached)
2233 + if (!pPayload->sczUnverifiedPath)
2234 {
2573 - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction);
2574 -
2575 - hr = PathForCurrentProcess(&sczContainerWorkingPath, NULL);
2576 - ExitOnFailure(hr, "Failed to get path for executing module as attached container working path.");
2235 + hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &pPayload->sczUnverifiedPath);
2236 + ExitOnFailure(hr, "Failed to calculate unverified path for payload.");
2237 }
2578 - else // use the acquired working path as the location of the container.
2579 - {
2580 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction);
2581 -
2582 - hr = StrAllocString(&sczContainerWorkingPath, pPlan->rgCacheActions[iAcquireAction].resolveContainer.sczUnverifiedPath, 0);
2583 - ExitOnFailure(hr, "Failed to copy container unverified path for cache action to extract container.");
2584 - }
2585 -
2586 - hr = AppendCacheAction(pPlan, &pContainerExtractAction);
2587 - ExitOnFailure(hr, "Failed to append cache action to extract payloads from container.");
2588 -
2589 - iExtractAction = pPlan->cCacheActions - 1;
2590 -
2591 - pContainerExtractAction->type = BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER;
2592 - pContainerExtractAction->fSkipUntilRetried = pContainer->fActuallyAttached; // assume we can skip the extract engine when the container is already attached and the fPayloadCached below will set us straight if wrong.
2593 - pContainerExtractAction->extractContainer.pContainer = pContainer;
2594 - pContainerExtractAction->extractContainer.iSkipUntilAcquiredByAction = iAcquireAction;
2595 - pContainerExtractAction->extractContainer.sczContainerUnverifiedPath = sczContainerWorkingPath;
2596 - sczContainerWorkingPath = NULL;
2597 - }
2598 -
2599 - Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pContainerExtractAction->type);
2600 - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iExtractAction);
2601 -
2602 - // If there is an acquire action, that is our try again action. Otherwise, we'll use the extract action.
2603 - iTryAgainAction = (BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction) ? iAcquireAction : iExtractAction;
2604 -
2605 - // If the try again action thinks it can be skipped but the payload is not cached,
2606 - // ensure the action will not be skipped.
2607 - BURN_CACHE_ACTION* pTryAgainAction = pPlan->rgCacheActions + iTryAgainAction;
2608 - Assert((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->resolveContainer.pContainer) ||
2609 - (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->extractContainer.pContainer));
2610 - if (pTryAgainAction->fSkipUntilRetried && !fPayloadCached)
2611 - {
2612 - pTryAgainAction->fSkipUntilRetried = FALSE;
2613 - }
2614 -
2615 - *ppContainerExtractAction = pContainerExtractAction;
2616 - *piContainerTryAgainAction = iTryAgainAction;
2617 -
2618 -LExit:
2619 - ReleaseStr(sczContainerWorkingPath);
2620 -
2621 - return hr;
2622 -}
2623 -
2624 -static HRESULT AddAcquireContainer(
2625 - __in BURN_PLAN* pPlan,
2626 - __in BURN_CONTAINER* pContainer,
2627 - __out_opt BURN_CACHE_ACTION** ppCacheAction,
2628 - __out_opt DWORD* piCacheAction
2629 - )
2630 -{
2631 - HRESULT hr = S_OK;
2632 - LPWSTR sczContainerWorkingPath = NULL;
2633 - BURN_CACHE_ACTION* pAcquireContainerAction = NULL;
2634 - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL;
2635 -
2636 - hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &sczContainerWorkingPath);
2637 - ExitOnFailure(hr, "Failed to calculate unverified path for container.");
2638 -
2639 - hr = AppendCacheAction(pPlan, &pAcquireContainerAction);
2640 - ExitOnFailure(hr, "Failed to append acquire container action to plan.");
2641 -
2642 - hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress);
2643 - ExitOnFailure(hr, "Failed to create container progress.");
2644 -
2645 - pAcquireContainerAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER;
2646 - pAcquireContainerAction->resolveContainer.pContainer = pContainer;
2647 - pAcquireContainerAction->resolveContainer.iProgress = pContainerProgress->iIndex;
2648 - pAcquireContainerAction->resolveContainer.sczUnverifiedPath = sczContainerWorkingPath;
2649 - sczContainerWorkingPath = NULL;
2650 -
2651 - if (ppCacheAction)
2652 - {
2653 - *ppCacheAction = pAcquireContainerAction;
2654 - }
2655 -
2656 - if (piCacheAction)
2657 - {
2658 - *piCacheAction = pPlan->cCacheActions - 1;
2238 }
2239
2661 -LExit:
2662 - ReleaseStr(sczContainerWorkingPath);
2663 -
2664 - return hr;
2665 -}
2666 -
2667 -static HRESULT AddExtractPayload(
2668 - __in BURN_CACHE_ACTION* pCacheAction,
2669 - __in_opt BURN_PACKAGE* pPackage,
2670 - __in BURN_PAYLOAD* pPayload,
2671 - __in_z LPCWSTR wzPayloadWorkingPath
2672 - )
2673 -{
2674 - HRESULT hr = S_OK;
2675 -
2676 - Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type);
2677 -
2678 - hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pCacheAction->extractContainer.rgPayloads), pCacheAction->extractContainer.cPayloads + 1, sizeof(BURN_EXTRACT_PAYLOAD), 5);
2679 - ExitOnFailure(hr, "Failed to grow list of payloads to extract from container.");
2680 -
2681 - BURN_EXTRACT_PAYLOAD* pExtractPayload = pCacheAction->extractContainer.rgPayloads + pCacheAction->extractContainer.cPayloads;
2682 - pExtractPayload->pPackage = pPackage;
2683 - pExtractPayload->pPayload = pPayload;
2684 - hr = StrAllocString(&pExtractPayload->sczUnverifiedPath, wzPayloadWorkingPath, 0);
2685 - ExitOnFailure(hr, "Failed to copy unverified path for payload to extract.");
2686 - ++pCacheAction->extractContainer.cPayloads;
2687 -
2240 LExit:
2241 return hr;
2242 }
2243
2692 -static BURN_CACHE_ACTION* ProcessSharedPayload(
2693 - __in BURN_PLAN* pPlan,
2694 - __in BURN_PAYLOAD* pPayload
2695 - )
2696 -{
2697 - BURN_CACHE_ACTION* pAcquireAction = NULL;
2698 -#ifdef DEBUG
2699 - DWORD cMove = 0;
2700 -#endif
2701 -
2702 - for (DWORD i = 0; i < pPlan->cCacheActions; ++i)
2703 - {
2704 - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i;
2705 -
2706 - if (BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pCacheAction->type &&
2707 - pCacheAction->resolvePayload.pPayload == pPayload)
2708 - {
2709 - AssertSz(!pAcquireAction, "There should be at most one acquire cache action per payload.");
2710 - pAcquireAction = pCacheAction;
2711 - }
2712 - else if (BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD == pCacheAction->type &&
2713 - pCacheAction->cachePayload.pPayload == pPayload &&
2714 - pCacheAction->cachePayload.fMove)
2715 - {
2716 - // Since we found a shared payload, change its operation from MOVE to COPY.
2717 - pCacheAction->cachePayload.fMove = FALSE;
2718 -
2719 - AssertSz(1 == ++cMove, "Shared payload should be moved once and only once.");
2720 -#ifndef DEBUG
2721 - break;
2722 -#endif
2723 - }
2724 - else if (BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD == pCacheAction->type &&
2725 - pCacheAction->layoutPayload.pPayload == pPayload &&
2726 - pCacheAction->layoutPayload.fMove)
2727 - {
2728 - // Since we found a shared payload, change its operation from MOVE to COPY if necessary
2729 - pCacheAction->layoutPayload.fMove = FALSE;
2730 -
2731 - AssertSz(1 == ++cMove, "Shared payload should be moved once and only once.");
2732 -#ifndef DEBUG
2733 - break;
2734 -#endif
2735 - }
2736 - }
2737 -
2738 - return pAcquireAction;
2739 -}
2740 -
2244 static void RemoveUnnecessaryActions(
2245 __in BOOL fExecute,
2246 __in BURN_EXECUTE_ACTION* rgActions,
@@ -2984,86 +2487,6 @@ static BOOL NeedsCache(
2487 }
2488 }
2489
2987 -static HRESULT CreateContainerProgress(
2988 - __in BURN_PLAN* pPlan,
2989 - __in BURN_CONTAINER* pContainer,
2990 - __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress
2991 - )
2992 -{
2993 - HRESULT hr = S_OK;
2994 - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL;
2995 -
2996 - hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPlan->rgContainerProgress), pPlan->cContainerProgress + 1, sizeof(BURN_CACHE_CONTAINER_PROGRESS), 5);
2997 - ExitOnFailure(hr, "Failed to grow container progress list.");
2998 -
2999 - if (!pPlan->shContainerProgress)
3000 - {
3001 - hr = DictCreateWithEmbeddedKey(&pPlan->shContainerProgress, 5, reinterpret_cast<void **>(&pPlan->rgContainerProgress), offsetof(BURN_CACHE_CONTAINER_PROGRESS, wzId), DICT_FLAG_NONE);
3002 - ExitOnFailure(hr, "Failed to create container progress dictionary.");
3003 - }
3004 -
3005 - hr = DictGetValue(pPlan->shContainerProgress, pContainer->sczId, reinterpret_cast<void **>(&pContainerProgress));
3006 - if (E_NOTFOUND == hr)
3007 - {
3008 - pContainerProgress = &pPlan->rgContainerProgress[pPlan->cContainerProgress];
3009 - pContainerProgress->iIndex = pPlan->cContainerProgress;
3010 - pContainerProgress->pContainer = pContainer;
3011 - pContainerProgress->wzId = pContainer->sczId;
3012 -
3013 - hr = DictAddValue(pPlan->shContainerProgress, pContainerProgress);
3014 - ExitOnFailure(hr, "Failed to add \"%ls\" to the container progress dictionary.", pContainerProgress->wzId);
3015 -
3016 - ++pPlan->cContainerProgress;
3017 - pPlan->qwCacheSizeTotal += pContainer->qwFileSize;
3018 - }
3019 - ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the container progress dictionary.", pContainer->sczId);
3020 -
3021 - *ppContainerProgress = pContainerProgress;
3022 -
3023 -LExit:
3024 - return hr;
3025 -}
3026 -
3027 -static HRESULT CreatePayloadProgress(
3028 - __in BURN_PLAN* pPlan,
3029 - __in BURN_PAYLOAD* pPayload,
3030 - __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress
3031 - )
3032 -{
3033 - HRESULT hr = S_OK;
3034 - BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL;
3035 -
3036 - hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPlan->rgPayloadProgress), pPlan->cPayloadProgress + 1, sizeof(BURN_CACHE_PAYLOAD_PROGRESS), 5);
3037 - ExitOnFailure(hr, "Failed to grow payload progress list.");
3038 -
3039 - if (!pPlan->shPayloadProgress)
3040 - {
3041 - hr = DictCreateWithEmbeddedKey(&pPlan->shPayloadProgress, 5, reinterpret_cast<void **>(&pPlan->rgPayloadProgress), offsetof(BURN_CACHE_PAYLOAD_PROGRESS, wzId), DICT_FLAG_NONE);
3042 - ExitOnFailure(hr, "Failed to create payload progress dictionary.");
3043 - }
3044 -
3045 - hr = DictGetValue(pPlan->shPayloadProgress, pPayload->sczKey, reinterpret_cast<void **>(&pPayloadProgress));
3046 - if (E_NOTFOUND == hr)
3047 - {
3048 - pPayloadProgress = &pPlan->rgPayloadProgress[pPlan->cPayloadProgress];
3049 - pPayloadProgress->iIndex = pPlan->cPayloadProgress;
3050 - pPayloadProgress->pPayload = pPayload;
3051 - pPayloadProgress->wzId = pPayload->sczKey;
3052 -
3053 - hr = DictAddValue(pPlan->shPayloadProgress, pPayloadProgress);
3054 - ExitOnFailure(hr, "Failed to add \"%ls\" to the payload progress dictionary.", pPayloadProgress->wzId);
3055 -
3056 - ++pPlan->cPayloadProgress;
3057 - pPlan->qwCacheSizeTotal += pPayload->qwFileSize;
3058 - }
3059 - ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the payload progress dictionary.", pPayload->sczKey);
3060 -
3061 - *ppPayloadProgress = pPayloadProgress;
3062 -
3063 -LExit:
3064 - return hr;
3065 -}
3066 -
2490 static void CacheActionLog(
2491 __in DWORD iAction,
2492 __in BURN_CACHE_ACTION* pAction,
@@ -3073,60 +2496,28 @@ static void CacheActionLog(
2496 LPCWSTR wzBase = fRollback ? L" Rollback cache" : L" Cache";
2497 switch (pAction->type)
2498 {
3076 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER:
3077 - LogStringLine(PlanDumpLevel, "%ls action[%u]: ACQUIRE_CONTAINER id: %ls, source path: %ls, working path: %ls, skip until retried: %hs", wzBase, iAction, pAction->resolveContainer.pContainer->sczId, pAction->resolveContainer.pContainer->sczSourcePath, pAction->resolveContainer.sczUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried));
3078 - break;
3079 -
3080 - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD:
3081 - LogStringLine(PlanDumpLevel, "%ls action[%u]: ACQUIRE_PAYLOAD package id: %ls, payload id: %ls, source path: %ls, working path: %ls, skip until retried: %hs", wzBase, iAction, pAction->resolvePayload.pPackage ? pAction->resolvePayload.pPackage->sczId : L"", pAction->resolvePayload.pPayload->sczKey, pAction->resolvePayload.pPayload->sczSourcePath, pAction->resolvePayload.sczUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried));
3082 - break;
3083 -
3084 - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD:
3085 - LogStringLine(PlanDumpLevel, "%ls action[%u]: CACHE_PAYLOAD package id: %ls, payload id: %ls, working path: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->cachePayload.pPackage->sczId, pAction->cachePayload.pPayload->sczKey, pAction->cachePayload.sczUnverifiedPath, pAction->cachePayload.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->cachePayload.iTryAgainAction);
3086 - break;
3087 -
2499 case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
2500 LogStringLine(PlanDumpLevel, "%ls action[%u]: CHECKPOINT id: %u", wzBase, iAction, pAction->checkpoint.dwId);
2501 break;
2502
3092 - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER:
3093 - LogStringLine(PlanDumpLevel, "%ls action[%u]: EXTRACT_CONTAINER id: %ls, working path: %ls, skip until retried: %hs, skip until acquired by action: %u", wzBase, iAction, pAction->extractContainer.pContainer->sczId, pAction->extractContainer.sczContainerUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried), pAction->extractContainer.iSkipUntilAcquiredByAction);
3094 - for (DWORD j = 0; j < pAction->extractContainer.cPayloads; j++)
3095 - {
3096 - LogStringLine(PlanDumpLevel, " extract package id: %ls, payload id: %ls, working path: %ls", pAction->extractContainer.rgPayloads[j].pPackage->sczId, pAction->extractContainer.rgPayloads[j].pPayload->sczKey, pAction->extractContainer.rgPayloads[j].sczUnverifiedPath);
3097 - }
3098 - break;
3099 -
2503 case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
3101 - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_BUNDLE working path: %ls, layout directory: %ls, exe name: %ls, skip until retried: %hs", wzBase, iAction, pAction->bundleLayout.sczUnverifiedPath, pAction->bundleLayout.sczLayoutDirectory, pAction->bundleLayout.sczExecutableName, LoggingBoolToString(pAction->fSkipUntilRetried));
3102 - break;
3103 -
3104 - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER:
3105 - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_CONTAINER package id: %ls, container id: %ls, working path: %ls, layout directory: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->layoutContainer.pPackage ? pAction->layoutContainer.pPackage->sczId : L"", pAction->layoutContainer.pContainer->sczId, pAction->layoutContainer.sczUnverifiedPath, pAction->layoutContainer.sczLayoutDirectory, pAction->layoutContainer.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->layoutContainer.iTryAgainAction);
3106 - break;
3107 -
3108 - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD:
3109 - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_PAYLOAD package id: %ls, payload id: %ls, working path: %ls, layout directory: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->layoutPayload.pPackage ? pAction->layoutPayload.pPackage->sczId : L"", pAction->layoutPayload.pPayload->sczKey, pAction->layoutPayload.sczUnverifiedPath, pAction->layoutPayload.sczLayoutDirectory, pAction->layoutPayload.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->layoutPayload.iTryAgainAction);
2504 + LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_BUNDLE working path: %ls, exe name: %ls", wzBase, iAction, pAction->bundleLayout.sczUnverifiedPath, pAction->bundleLayout.sczExecutableName);
2505 break;
2506
3112 - case BURN_CACHE_ACTION_TYPE_PACKAGE_START:
3113 - LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_START id: %ls, plan index for skip: %u, payloads to cache: %u, bytes to cache: %llu, skip until retried: %hs", wzBase, iAction, pAction->packageStart.pPackage->sczId, pAction->packageStart.iPackageCompleteAction, pAction->packageStart.cCachePayloads, pAction->packageStart.qwCachePayloadSizeTotal, LoggingBoolToString(pAction->fSkipUntilRetried));
2507 + case BURN_CACHE_ACTION_TYPE_CONTAINER:
2508 + LogStringLine(PlanDumpLevel, "%ls action[%u]: CONTAINER container id: %ls, working path: %ls", wzBase, iAction, pAction->container.pContainer->sczId, pAction->container.pContainer->sczUnverifiedPath);
2509 break;
2510
3116 - case BURN_CACHE_ACTION_TYPE_PACKAGE_STOP:
3117 - LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_STOP id: %ls, skip until retried: %hs", wzBase, iAction, pAction->packageStop.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried));
2511 + case BURN_CACHE_ACTION_TYPE_PACKAGE:
2512 + LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE id: %ls", wzBase, iAction, pAction->package.pPackage->sczId);
2513 break;
2514
2515 case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE:
3121 - LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls, skip until retried: %hs", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried));
2516 + LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId);
2517 break;
2518
2519 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
3125 - LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p, skip until retried: %hs", wzBase, iAction, pAction->syncpoint.hEvent, LoggingBoolToString(pAction->fSkipUntilRetried));
3126 - break;
3127 -
3128 - case BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY:
3129 - LogStringLine(PlanDumpLevel, "%ls action[%u]: TRANSACTION_BOUNDARY id: %ls, event handle: 0x%p, vital: %ls, transaction: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.hEvent, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no", pAction->rollbackBoundary.pRollbackBoundary->fTransaction ? L"yes" : L"no");
2520 + LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent);
2521 break;
2522
2523 default:
@@ -3222,6 +2613,10 @@ extern "C" void PlanDump(
2613 LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine));
2614 LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback));
2615 LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize);
2616 + if (pPlan->sczLayoutDirectory)
2617 + {
2618 + LogStringLine(PlanDumpLevel, " layout directory: %ls", pPlan->sczLayoutDirectory);
2619 + }
2620
2621 LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal);
2622 for (DWORD i = 0; i < pPlan->cCacheActions; ++i)
src/engine/plan.h
+17 -89
@@ -38,17 +38,10 @@ enum BURN_CACHE_ACTION_TYPE
38 BURN_CACHE_ACTION_TYPE_NONE,
39 BURN_CACHE_ACTION_TYPE_CHECKPOINT,
40 BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE,
41 - BURN_CACHE_ACTION_TYPE_PACKAGE_START,
42 - BURN_CACHE_ACTION_TYPE_PACKAGE_STOP,
41 + BURN_CACHE_ACTION_TYPE_PACKAGE,
42 BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE,
43 BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT,
45 - BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER,
46 - BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER,
47 - BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER,
48 - BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD,
49 - BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD,
50 - BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD,
51 - BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY,
44 + BURN_CACHE_ACTION_TYPE_CONTAINER,
45 };
46
47 enum BURN_EXECUTE_ACTION_TYPE
@@ -78,13 +71,6 @@ enum BURN_CLEAN_ACTION_TYPE
71
72 // structs
73
81 -typedef struct _BURN_EXTRACT_PAYLOAD
82 -{
83 - BURN_PACKAGE* pPackage;
84 - BURN_PAYLOAD* pPayload;
85 - LPWSTR sczUnverifiedPath;
86 -} BURN_EXTRACT_PAYLOAD;
87 -
74 typedef struct _BURN_DEPENDENT_REGISTRATION_ACTION
75 {
76 BURN_DEPENDENT_REGISTRATION_ACTION_TYPE type;
@@ -111,7 +97,6 @@ typedef struct _BURN_CACHE_PAYLOAD_PROGRESS
97 typedef struct _BURN_CACHE_ACTION
98 {
99 BURN_CACHE_ACTION_TYPE type;
114 - BOOL fSkipUntilRetried;
100 union
101 {
102 struct
@@ -121,21 +106,14 @@ typedef struct _BURN_CACHE_ACTION
106 struct
107 {
108 LPWSTR sczExecutableName;
124 - LPWSTR sczLayoutDirectory;
109 LPWSTR sczUnverifiedPath;
110 DWORD64 qwBundleSize;
111 + BURN_PAYLOAD_GROUP* pPayloadGroup;
112 } bundleLayout;
113 struct
114 {
115 BURN_PACKAGE* pPackage;
131 - DWORD cCachePayloads;
132 - DWORD64 qwCachePayloadSizeTotal;
133 - DWORD iPackageCompleteAction;
134 - } packageStart;
135 - struct
136 - {
137 - BURN_PACKAGE* pPackage;
138 - } packageStop;
116 + } package;
117 struct
118 {
119 BURN_PACKAGE* pPackage;
@@ -147,62 +125,7 @@ typedef struct _BURN_CACHE_ACTION
125 struct
126 {
127 BURN_CONTAINER* pContainer;
150 - DWORD iProgress;
151 - LPWSTR sczUnverifiedPath;
152 - } resolveContainer;
153 - struct
154 - {
155 - BURN_CONTAINER* pContainer;
156 - DWORD iSkipUntilAcquiredByAction;
157 - LPWSTR sczContainerUnverifiedPath;
158 -
159 - BURN_EXTRACT_PAYLOAD* rgPayloads;
160 - DWORD cPayloads;
161 - } extractContainer;
162 - struct
163 - {
164 - BURN_PACKAGE* pPackage;
165 - BURN_CONTAINER* pContainer;
166 - DWORD iProgress;
167 - DWORD iTryAgainAction;
168 - DWORD cTryAgainAttempts;
169 - LPWSTR sczLayoutDirectory;
170 - LPWSTR sczUnverifiedPath;
171 - BOOL fMove;
172 - } layoutContainer;
173 - struct
174 - {
175 - BURN_PACKAGE* pPackage;
176 - BURN_PAYLOAD* pPayload;
177 - DWORD iProgress;
178 - LPWSTR sczUnverifiedPath;
179 - } resolvePayload;
180 - struct
181 - {
182 - BURN_PACKAGE* pPackage;
183 - BURN_PAYLOAD* pPayload;
184 - DWORD iProgress;
185 - DWORD iTryAgainAction;
186 - DWORD cTryAgainAttempts;
187 - LPWSTR sczUnverifiedPath;
188 - BOOL fMove;
189 - } cachePayload;
190 - struct
191 - {
192 - BURN_PACKAGE* pPackage;
193 - BURN_PAYLOAD* pPayload;
194 - DWORD iProgress;
195 - DWORD iTryAgainAction;
196 - DWORD cTryAgainAttempts;
197 - LPWSTR sczLayoutDirectory;
198 - LPWSTR sczUnverifiedPath;
199 - BOOL fMove;
200 - } layoutPayload;
201 - struct
202 - {
203 - BURN_ROLLBACK_BOUNDARY* pRollbackBoundary;
204 - HANDLE hEvent;
205 - } rollbackBoundary;
128 + } container;
129 };
130 } BURN_CACHE_ACTION;
131
@@ -306,6 +229,7 @@ typedef struct _BURN_CLEAN_ACTION
229 typedef struct _BURN_PLAN
230 {
231 BOOTSTRAPPER_ACTION action;
232 + BURN_PAYLOADS* pPayloads; // points directly into parent the ENGINE_STATE.
233 LPWSTR wzBundleId; // points directly into parent the ENGINE_STATE.
234 LPWSTR wzBundleProviderKey; // points directly into parent the ENGINE_STATE.
235 BOOL fPerMachine;
@@ -315,6 +239,7 @@ typedef struct _BURN_PLAN
239 BOOL fDisableRollback;
240 BOOL fAffectedMachineState;
241 BOOL fIgnoreAllDependents;
242 + LPWSTR sczLayoutDirectory;
243
244 DWORD64 qwCacheSizeTotal;
245
@@ -369,7 +294,9 @@ typedef struct _BURN_PLAN
294
295 void PlanReset(
296 __in BURN_PLAN* pPlan,
372 - __in BURN_PACKAGES* pPackages
297 + __in BURN_CONTAINERS* pContainers,
298 + __in BURN_PACKAGES* pPackages,
299 + __in BURN_PAYLOAD_GROUP* pLayoutPayloads
300 );
301 void PlanUninitializeExecuteAction(
302 __in BURN_EXECUTE_ACTION* pExecuteAction
@@ -393,8 +320,7 @@ HRESULT PlanLayoutBundle(
320 __in_z LPCWSTR wzExecutableName,
321 __in DWORD64 qwBundleSize,
322 __in BURN_VARIABLES* pVariables,
396 - __in BURN_PAYLOADS* pPayloads,
397 - __out_z LPWSTR* psczLayoutDirectory
323 + __in BURN_PAYLOAD_GROUP* pLayoutPayloads
324 );
325 HRESULT PlanForwardCompatibleBundles(
326 __in BURN_USER_EXPERIENCE* pUX,
@@ -410,8 +336,7 @@ HRESULT PlanPackages(
336 __in BURN_LOGGING* pLog,
337 __in BURN_VARIABLES* pVariables,
338 __in BOOTSTRAPPER_DISPLAY display,
413 - __in BOOTSTRAPPER_RELATION_TYPE relationType,
414 - __in_z_opt LPCWSTR wzLayoutDirectory
339 + __in BOOTSTRAPPER_RELATION_TYPE relationType
340 );
341 HRESULT PlanRegistration(
342 __in BURN_PLAN* pPlan,
@@ -438,10 +363,13 @@ HRESULT PlanUpdateBundle(
363 __in BOOTSTRAPPER_DISPLAY display,
364 __in BOOTSTRAPPER_RELATION_TYPE relationType
365 );
366 +HRESULT PlanLayoutContainer(
367 + __in BURN_PLAN* pPlan,
368 + __in BURN_CONTAINER* pContainer
369 + );
370 HRESULT PlanLayoutPackage(
371 __in BURN_PLAN* pPlan,
443 - __in BURN_PACKAGE* pPackage,
444 - __in_z_opt LPCWSTR wzLayoutDirectory
372 + __in BURN_PACKAGE* pPackage
373 );
374 HRESULT PlanExecutePackage(
375 __in BOOL fPerMachine,
src/engine/pseudobundle.cpp
+22 -53
@@ -26,6 +26,7 @@ extern "C" HRESULT PseudoBundleInitialize(
26 {
27 HRESULT hr = S_OK;
28 LPWSTR sczRelationTypeCommandLineSwitch = NULL;
29 + BURN_PAYLOAD* pPayload = NULL;
30
31 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType);
32 if (wzRelationTypeCommandLine)
@@ -34,41 +35,40 @@ extern "C" HRESULT PseudoBundleInitialize(
35 }
36
37 // Initialize the single payload, and fill out all the necessary fields
37 - pPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD *)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD), TRUE);
38 - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of related bundle struct");
39 - pPackage->cPayloads = 1;
38 + pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*), TRUE);
39 + ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of related bundle struct");
40 + pPackage->payloads.cPayloads = 1;
41
41 - pPackage->rgPayloads->pPayload = (BURN_PAYLOAD *)MemAlloc(sizeof(BURN_PAYLOAD), TRUE);
42 - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct");
43 - pPackage->rgPayloads->pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
44 - pPackage->rgPayloads->pPayload->qwFileSize = qwSize;
42 + pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE);
43 + ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct");
44 + pPackage->payloads.rgpPayloads[0] = pPayload;
45 + pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
46 + pPayload->qwFileSize = qwSize;
47
46 - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczKey, wzId, 0);
48 + hr = StrAllocString(&pPayload->sczKey, wzId, 0);
49 ExitOnFailure(hr, "Failed to copy key for pseudo bundle payload.");
50
49 - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczFilePath, wzFilePath, 0);
51 + hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0);
52 ExitOnFailure(hr, "Failed to copy filename for pseudo bundle.");
53
52 - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczSourcePath, wzLocalSource, 0);
54 + hr = StrAllocString(&pPayload->sczSourcePath, wzLocalSource, 0);
55 ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle.");
56
57 if (wzDownloadSource && *wzDownloadSource)
58 {
57 - hr = StrAllocString(&pPackage->rgPayloads->pPayload->downloadSource.sczUrl, wzDownloadSource, 0);
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 {
63 - pPackage->rgPayloads->pPayload->pbHash = static_cast<BYTE*>(MemAlloc(cbHash, FALSE));
64 - ExitOnNull(pPackage->rgPayloads->pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash.");
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
66 - pPackage->rgPayloads->pPayload->cbHash = cbHash;
67 - memcpy_s(pPackage->rgPayloads->pPayload->pbHash, pPackage->rgPayloads->pPayload->cbHash, pbHash, cbHash);
68 + pPayload->cbHash = cbHash;
69 + memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash);
70 }
71
70 - pPackage->rgPayloads->fCached = fCached;
71 -
72 pPackage->Exe.fPseudoBundle = TRUE;
73
74 pPackage->type = BURN_PACKAGE_TYPE_EXE;
@@ -171,44 +171,13 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
171 LPWSTR sczArguments = NULL;
172
173 // Initialize the payloads, and copy the necessary fields.
174 - pPassthroughPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD *)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD) * pPackage->cPayloads, TRUE);
175 - ExitOnNull(pPassthroughPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle.");
176 - pPassthroughPackage->cPayloads = pPackage->cPayloads;
174 + pPassthroughPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * pPackage->payloads.cPayloads, TRUE);
175 + ExitOnNull(pPassthroughPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle.");
176 + pPassthroughPackage->payloads.cPayloads = pPackage->payloads.cPayloads;
177
178 - for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload)
178 + for (DWORD iPayload = 0; iPayload < pPackage->payloads.cPayloads; ++iPayload)
179 {
180 - BURN_PACKAGE_PAYLOAD* pPayload = pPackage->rgPayloads + iPayload;
181 -
182 - pPassthroughPackage->rgPayloads[iPayload].pPayload = (BURN_PAYLOAD *)MemAlloc(sizeof(BURN_PAYLOAD), TRUE);
183 - ExitOnNull(pPassthroughPackage->rgPayloads[iPayload].pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct");
184 - pPassthroughPackage->rgPayloads[iPayload].pPayload->packaging = pPayload->pPayload->packaging;
185 - pPassthroughPackage->rgPayloads[iPayload].pPayload->qwFileSize = pPayload->pPayload->qwFileSize;
186 -
187 - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczKey, pPayload->pPayload->sczKey, 0);
188 - ExitOnFailure(hr, "Failed to copy key for passthrough pseudo bundle payload.");
189 -
190 - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczFilePath, pPayload->pPayload->sczFilePath, 0);
191 - ExitOnFailure(hr, "Failed to copy filename for passthrough pseudo bundle.");
192 -
193 - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczSourcePath, pPayload->pPayload->sczSourcePath, 0);
194 - ExitOnFailure(hr, "Failed to copy local source path for passthrough pseudo bundle.");
195 -
196 - if (pPayload->pPayload->downloadSource.sczUrl)
197 - {
198 - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->downloadSource.sczUrl, pPayload->pPayload->downloadSource.sczUrl, 0);
199 - ExitOnFailure(hr, "Failed to copy download source for passthrough pseudo bundle.");
200 - }
201 -
202 - if (pPayload->pPayload->pbHash)
203 - {
204 - pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash = static_cast<BYTE*>(MemAlloc(pPayload->pPayload->cbHash, FALSE));
205 - ExitOnNull(pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash.");
206 -
207 - pPassthroughPackage->rgPayloads[iPayload].pPayload->cbHash = pPayload->pPayload->cbHash;
208 - memcpy_s(pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash, pPassthroughPackage->rgPayloads[iPayload].pPayload->cbHash, pPayload->pPayload->pbHash, pPayload->pPayload->cbHash);
209 - }
210 -
211 - pPassthroughPackage->rgPayloads[iPayload].fCached = pPayload->fCached;
180 + pPassthroughPackage->payloads.rgpPayloads[iPayload] = pPackage->payloads.rgpPayloads[iPayload];
181 }
182
183 pPassthroughPackage->Exe.fPseudoBundle = TRUE;
src/engine/relatedbundle.cpp
+8 -1
@@ -80,7 +80,14 @@ extern "C" void RelatedBundlesUninitialize(
80 {
81 for (DWORD i = 0; i < pRelatedBundles->cRelatedBundles; ++i)
82 {
83 - PackageUninitialize(&pRelatedBundles->rgRelatedBundles[i].package);
83 + BURN_PACKAGE* pPackage = &pRelatedBundles->rgRelatedBundles[i].package;
84 +
85 + for (DWORD j = 0; j < pPackage->payloads.cPayloads; ++j)
86 + {
87 + PayloadUninitialize(pPackage->payloads.rgpPayloads[j]);
88 + }
89 +
90 + PackageUninitialize(pPackage);
91 ReleaseStr(pRelatedBundles->rgRelatedBundles[i].sczTag);
92 }
93
src/engine/userexperience.cpp
+1 -1
@@ -62,7 +62,7 @@ extern "C" HRESULT UserExperienceParseFromXml(
62 }
63
64 // parse payloads
65 - hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, pixnUserExperienceNode);
65 + hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, NULL, pixnUserExperienceNode);
66 ExitOnFailure(hr, "Failed to parse user experience payloads.");
67
68 // make sure we have at least one payload
src/test/BurnUnitTest/PlanTest.cpp
+41 -170
@@ -54,47 +54,30 @@ namespace Bootstrapper
54
55 BOOL fRollback = FALSE;
56 DWORD dwIndex = 0;
57 - DWORD dwPackageStart = 0;
57 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
59 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 6, 2, 33743, FALSE);
60 - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE);
61 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6);
62 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
63 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
64 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
65 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
58 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
59 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
60 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9);
67 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33743, FALSE);
68 - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
69 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
70 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart);
71 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"cablKtJUKxAbhSMIBwQU6vJ_CDsIkE", TRUE, FALSE, dwPackageStart);
72 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE);
73 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
61 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
62 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
63 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
75 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageC", 22, 2, 33743, FALSE);
76 - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
77 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
78 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart);
79 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"cab3wekki1le1R8RPDV2B8_g8jcjZc", TRUE, FALSE, dwPackageStart);
80 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageC", FALSE);
81 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
82 - Assert::Equal(24ul, pPlan->cCacheActions);
64 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageC");
65 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
66 + Assert::Equal(dwIndex, pPlan->cCacheActions);
67
68 fRollback = TRUE;
69 dwIndex = 0;
70 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
87 - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
71 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
72
73 Assert::Equal(107082ull, pPlan->qwEstimatedSize);
91 - Assert::Equal(101229ull, pPlan->qwCacheSizeTotal);
74 + Assert::Equal(202458ull, pPlan->qwCacheSizeTotal);
75
76 fRollback = FALSE;
77 dwIndex = 0;
78 DWORD dwExecuteCheckpointId = 2;
79 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
97 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[7].syncpoint.hEvent);
80 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
81 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
82 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
83 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
@@ -107,7 +90,7 @@ namespace Bootstrapper
90 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
91 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
92 ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
110 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[15].syncpoint.hEvent);
93 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent);
94 dwExecuteCheckpointId += 1; // cache checkpoints
95 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
96 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -116,7 +99,7 @@ namespace Bootstrapper
99 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
100 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
101 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
119 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent);
102 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent);
103 dwExecuteCheckpointId += 1; // cache checkpoints
104 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
105 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -314,30 +297,24 @@ namespace Bootstrapper
297
298 BOOL fRollback = FALSE;
299 DWORD dwIndex = 0;
317 - DWORD dwPackageStart = 0;
300 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
319 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE);
320 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
321 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
322 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
323 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
324 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
301 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
302 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
303 Assert::Equal(dwIndex, pPlan->cCacheActions);
304
305 fRollback = TRUE;
306 dwIndex = 0;
307 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
330 - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
308 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
309
310 Assert::Equal(35694ull, pPlan->qwEstimatedSize);
334 - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal);
311 + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal);
312
313 fRollback = FALSE;
314 dwIndex = 0;
315 DWORD dwExecuteCheckpointId = 2;
316 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
340 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
317 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
318 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
319 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
320 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
@@ -401,14 +378,9 @@ namespace Bootstrapper
378
379 BOOL fRollback = FALSE;
380 DWORD dwIndex = 0;
404 - DWORD dwPackageStart = 0;
381 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
406 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE);
407 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
408 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
409 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
410 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
411 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
382 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
383 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
384 Assert::Equal(dwIndex, pPlan->cCacheActions);
385
386 fRollback = TRUE;
@@ -416,13 +388,13 @@ namespace Bootstrapper
388 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
389
390 Assert::Equal(33743ull, pPlan->qwEstimatedSize);
419 - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal);
391 + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal);
392
393 fRollback = FALSE;
394 dwIndex = 0;
395 DWORD dwExecuteCheckpointId = 2;
396 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
425 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
397 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
398 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
399 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
400 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -475,30 +447,24 @@ namespace Bootstrapper
447
448 BOOL fRollback = FALSE;
449 DWORD dwIndex = 0;
478 - DWORD dwPackageStart = 0;
450 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
480 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE);
481 - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
482 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
483 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
484 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
485 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
451 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
452 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
453 Assert::Equal(dwIndex, pPlan->cCacheActions);
454
455 fRollback = TRUE;
456 dwIndex = 0;
457 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
491 - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
458 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
459
460 Assert::Equal(35694ull, pPlan->qwEstimatedSize);
495 - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal);
461 + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal);
462
463 fRollback = FALSE;
464 dwIndex = 0;
465 DWORD dwExecuteCheckpointId = 2;
466 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
501 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
467 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
468 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
469 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
470 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
@@ -759,36 +725,28 @@ namespace Bootstrapper
725
726 BOOL fRollback = FALSE;
727 DWORD dwIndex = 0;
762 - DWORD dwPackageStart = 0;
728 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
764 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PatchA", 4, 1, 20480, FALSE);
765 - ValidateCacheAcquirePayload(pPlan, fRollback, dwIndex++, L"PatchA", L"PatchA", FALSE);
766 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PatchA", L"PatchA", TRUE, FALSE, dwPackageStart);
767 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PatchA", FALSE);
768 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
729 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA");
730 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
731 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2);
770 - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 10, 1, 32768, FALSE);
771 - ValidateCacheAcquirePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", FALSE);
772 - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
773 - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
774 - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
732 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
733 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
734 Assert::Equal(dwIndex, pPlan->cCacheActions);
735
736 fRollback = TRUE;
737 dwIndex = 0;
738 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2);
780 - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
739 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
740
741 Assert::Equal(3055111ull, pPlan->qwEstimatedSize);
784 - Assert::Equal(53248ull, pPlan->qwCacheSizeTotal);
742 + Assert::Equal(106496ull, pPlan->qwCacheSizeTotal);
743
744 fRollback = FALSE;
745 dwIndex = 0;
746 DWORD dwExecuteCheckpointId = 3;
747 BURN_EXECUTE_ACTION* pExecuteAction = NULL;
748 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
791 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[11].syncpoint.hEvent);
749 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent);
750 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
751 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
752 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
@@ -797,7 +755,7 @@ namespace Bootstrapper
755 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
756 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_REGISTER);
757 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
800 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent);
758 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
759 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
760 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
761 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_REGISTER);
@@ -983,7 +941,7 @@ namespace Bootstrapper
941 BURN_REGISTRATION* pRegistration = &pEngineState->registration;
942
943 DetectReset(pRegistration, &pEngineState->packages);
986 - PlanReset(&pEngineState->plan, &pEngineState->packages);
944 + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
945
946 hr = DepDependencyArrayAlloc(&pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, pRegistration->sczProviderKey, NULL);
947 NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore.");
@@ -1047,11 +1005,6 @@ namespace Bootstrapper
1005 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1006 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1007 }
1050 -
1051 - for (DWORD i = 0; i < pPackage->cPayloads; ++i)
1052 - {
1053 - pPackage->rgPayloads[i].fCached = TRUE;
1054 - }
1008 }
1009
1010 void DetectPackageDependent(BURN_PACKAGE* pPackage, LPCWSTR wzId)
@@ -1186,34 +1139,16 @@ namespace Bootstrapper
1139 }
1140 }
1141
1189 - void ValidateCacheAcquireContainer(
1190 - __in BURN_PLAN* pPlan,
1191 - __in BOOL fRollback,
1192 - __in DWORD dwIndex,
1193 - __in LPCWSTR wzContainerId,
1194 - __in BOOL fSkipUntilRetried
1195 - )
1196 - {
1197 - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1198 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pAction->type);
1199 - NativeAssert::StringEqual(wzContainerId, pAction->resolveContainer.pContainer->sczId);
1200 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1201 - }
1202 -
1203 - void ValidateCacheAcquirePayload(
1142 + void ValidateCacheContainer(
1143 __in BURN_PLAN* pPlan,
1144 __in BOOL fRollback,
1145 __in DWORD dwIndex,
1207 - __in LPCWSTR wzPackageId,
1208 - __in LPCWSTR wzPayloadId,
1209 - __in BOOL fSkipUntilRetried
1146 + __in LPCWSTR wzContainerId
1147 )
1148 {
1149 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1213 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD, pAction->type);
1214 - NativeAssert::StringEqual(wzPackageId, pAction->resolvePayload.pPackage->sczId);
1215 - NativeAssert::StringEqual(wzPayloadId, pAction->resolvePayload.pPayload->sczKey);
1216 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1150 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_CONTAINER, pAction->type);
1151 + NativeAssert::StringEqual(wzContainerId, pAction->container.pContainer->sczId);
1152 }
1153
1154 BURN_CACHE_ACTION* ValidateCacheActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex)
@@ -1222,26 +1157,6 @@ namespace Bootstrapper
1157 return (fRollback ? pPlan->rgRollbackCacheActions : pPlan->rgCacheActions) + dwIndex;
1158 }
1159
1225 - void ValidateCacheCachePayload(
1226 - __in BURN_PLAN* pPlan,
1227 - __in BOOL fRollback,
1228 - __in DWORD dwIndex,
1229 - __in LPCWSTR wzPackageId,
1230 - __in LPCWSTR wzPayloadId,
1231 - __in BOOL fMove,
1232 - __in BOOL fSkipUntilRetried,
1233 - __in DWORD iTryAgainAction
1234 - )
1235 - {
1236 - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1237 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD, pAction->type);
1238 - NativeAssert::StringEqual(wzPackageId, pAction->cachePayload.pPackage->sczId);
1239 - NativeAssert::StringEqual(wzPayloadId, pAction->cachePayload.pPayload->sczKey);
1240 - Assert::Equal<BOOL>(fMove, pAction->cachePayload.fMove);
1241 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1242 - Assert::Equal(iTryAgainAction, pAction->cachePayload.iTryAgainAction);
1243 - }
1244 -
1160 void ValidateCacheCheckpoint(
1161 __in BURN_PLAN* pPlan,
1162 __in BOOL fRollback,
@@ -1254,84 +1169,40 @@ namespace Bootstrapper
1169 Assert::Equal(dwId, pAction->checkpoint.dwId);
1170 }
1171
1257 - void ValidateCacheExtractContainer(
1258 - __in BURN_PLAN* pPlan,
1259 - __in BOOL fRollback,
1260 - __in DWORD dwIndex,
1261 - __in LPCWSTR wzContainerId,
1262 - __in BOOL fSkipUntilRetried,
1263 - __in DWORD iSkipUntilAcquiredByAction,
1264 - __in DWORD cPayloads
1265 - )
1266 - {
1267 - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1268 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pAction->type);
1269 - NativeAssert::StringEqual(wzContainerId, pAction->extractContainer.pContainer->sczId);
1270 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1271 - Assert::Equal(iSkipUntilAcquiredByAction, pAction->extractContainer.iSkipUntilAcquiredByAction);
1272 - Assert::Equal(cPayloads, pAction->extractContainer.cPayloads);
1273 - }
1274 -
1275 - DWORD ValidateCachePackageStart(
1172 + DWORD ValidateCachePackage(
1173 __in BURN_PLAN* pPlan,
1174 __in BOOL fRollback,
1175 __in DWORD dwIndex,
1279 - __in LPCWSTR wzPackageId,
1280 - __in DWORD iPackageCompleteAction,
1281 - __in DWORD cCachePayloads,
1282 - __in DWORD64 qwCachePayloadSizeTotal,
1283 - __in BOOL fSkipUntilRetried
1176 + __in LPCWSTR wzPackageId
1177 )
1178 {
1179 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1287 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type);
1288 - NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId);
1289 - Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction);
1290 - Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads);
1291 - Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal);
1292 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1180 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE, pAction->type);
1181 + NativeAssert::StringEqual(wzPackageId, pAction->package.pPackage->sczId);
1182 return dwIndex + 1;
1183 }
1184
1296 - void ValidateCachePackageStop(
1297 - __in BURN_PLAN* pPlan,
1298 - __in BOOL fRollback,
1299 - __in DWORD dwIndex,
1300 - __in LPCWSTR wzPackageId,
1301 - __in BOOL fSkipUntilRetried
1302 - )
1303 - {
1304 - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1305 - Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_STOP, pAction->type);
1306 - NativeAssert::StringEqual(wzPackageId, pAction->packageStop.pPackage->sczId);
1307 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1308 - }
1309 -
1185 void ValidateCacheRollbackPackage(
1186 __in BURN_PLAN* pPlan,
1187 __in BOOL fRollback,
1188 __in DWORD dwIndex,
1314 - __in LPCWSTR wzPackageId,
1315 - __in BOOL fSkipUntilRetried
1189 + __in LPCWSTR wzPackageId
1190 )
1191 {
1192 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1193 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE, pAction->type);
1194 NativeAssert::StringEqual(wzPackageId, pAction->rollbackPackage.pPackage->sczId);
1321 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1195 }
1196
1197 void ValidateCacheSignalSyncpoint(
1198 __in BURN_PLAN* pPlan,
1199 __in BOOL fRollback,
1327 - __in DWORD dwIndex,
1328 - __in BOOL fSkipUntilRetried
1200 + __in DWORD dwIndex
1201 )
1202 {
1203 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
1204 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, pAction->type);
1205 Assert::NotEqual((DWORD_PTR)NULL, (DWORD_PTR)pAction->syncpoint.hEvent);
1334 - Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
1206 }
1207
1208 void ValidateCleanAction(