diff options
Diffstat (limited to 'src/engine/apply.cpp')
| -rw-r--r-- | src/engine/apply.cpp | 758 |
1 files changed, 350 insertions, 408 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index b79bf934..7e03ebf9 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
| @@ -13,18 +13,28 @@ const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; | |||
| 13 | 13 | ||
| 14 | // structs | 14 | // structs |
| 15 | 15 | ||
| 16 | struct BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT | 16 | typedef struct _BURN_CACHE_CONTEXT |
| 17 | { | 17 | { |
| 18 | BURN_USER_EXPERIENCE* pUX; | 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; | ||
| 19 | BURN_CONTAINER* pContainer; | 31 | BURN_CONTAINER* pContainer; |
| 20 | BURN_PACKAGE* pPackage; | 32 | BURN_PACKAGE* pPackage; |
| 21 | BURN_PAYLOAD* pPayload; | 33 | BURN_PAYLOAD* pPayload; |
| 22 | DWORD64 qwCacheProgress; | ||
| 23 | DWORD64 qwTotalCacheSize; | ||
| 24 | 34 | ||
| 25 | BOOL fCancel; | 35 | BOOL fCancel; |
| 26 | BOOL fError; | 36 | BOOL fError; |
| 27 | }; | 37 | } BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; |
| 28 | 38 | ||
| 29 | typedef struct _BURN_EXECUTE_CONTEXT | 39 | typedef struct _BURN_EXECUTE_CONTEXT |
| 30 | { | 40 | { |
| @@ -56,50 +66,49 @@ static HRESULT ExecuteDependentRegistrationActions( | |||
| 56 | __in_ecount(cActions) const BURN_DEPENDENT_REGISTRATION_ACTION* rgActions, | 66 | __in_ecount(cActions) const BURN_DEPENDENT_REGISTRATION_ACTION* rgActions, |
| 57 | __in DWORD cActions | 67 | __in DWORD cActions |
| 58 | ); | 68 | ); |
| 59 | static HRESULT ExtractContainer( | 69 | static HRESULT ApplyCachePackage( |
| 60 | __in HANDLE hSourceEngineFile, | 70 | __in BURN_CACHE_CONTEXT* pContext, |
| 61 | __in BURN_CONTAINER* pContainer, | 71 | __in BURN_PACKAGE* pPackage |
| 62 | __in_z LPCWSTR wzContainerPath, | ||
| 63 | __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads, | ||
| 64 | __in DWORD cExtractPayloads | ||
| 65 | ); | 72 | ); |
| 66 | static void UpdateCacheSuccessProgress( | 73 | static HRESULT ApplyExtractContainer( |
| 67 | __in BURN_PLAN* pPlan, | 74 | __in BURN_CACHE_CONTEXT* pContext, |
| 68 | __in BURN_CACHE_ACTION* pCacheAction, | 75 | __in BURN_CONTAINER* pContainer |
| 69 | __inout DWORD64* pqwSuccessfulCachedProgress | 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 | ||
| 70 | ); | 95 | ); |
| 71 | static HRESULT LayoutBundle( | 96 | static HRESULT LayoutBundle( |
| 72 | __in HANDLE hSourceEngineFile, | 97 | __in BURN_CACHE_CONTEXT* pContext, |
| 73 | __in BURN_USER_EXPERIENCE* pUX, | ||
| 74 | __in BURN_VARIABLES* pVariables, | ||
| 75 | __in HANDLE hPipe, | ||
| 76 | __in_z LPCWSTR wzExecutableName, | 98 | __in_z LPCWSTR wzExecutableName, |
| 77 | __in_z LPCWSTR wzLayoutDirectory, | 99 | __in_z LPCWSTR wzUnverifiedPath |
| 78 | __in_z LPCWSTR wzUnverifiedPath, | ||
| 79 | __in DWORD64 qwSuccessfulCacheProgress, | ||
| 80 | __in DWORD64 qwTotalCacheSize | ||
| 81 | ); | 100 | ); |
| 82 | static HRESULT AcquireContainerOrPayload( | 101 | static HRESULT AcquireContainerOrPayload( |
| 83 | __in BURN_USER_EXPERIENCE* pUX, | 102 | __in BURN_CACHE_CONTEXT* pContext, |
| 84 | __in BURN_VARIABLES* pVariables, | ||
| 85 | __in_opt BURN_CONTAINER* pContainer, | 103 | __in_opt BURN_CONTAINER* pContainer, |
| 86 | __in_opt BURN_PACKAGE* pPackage, | 104 | __in_opt BURN_PACKAGE* pPackage, |
| 87 | __in_opt BURN_PAYLOAD* pPayload, | 105 | __in_opt BURN_PAYLOAD* pPayload |
| 88 | __in LPCWSTR wzDestinationPath, | ||
| 89 | __in DWORD64 qwSuccessfulCacheProgress, | ||
| 90 | __in DWORD64 qwTotalCacheSize | ||
| 91 | ); | 106 | ); |
| 92 | static HRESULT LayoutOrCacheContainerOrPayload( | 107 | static HRESULT LayoutOrCacheContainerOrPayload( |
| 93 | __in BURN_USER_EXPERIENCE* pUX, | 108 | __in BURN_CACHE_CONTEXT* pContext, |
| 94 | __in HANDLE hPipe, | ||
| 95 | __in_opt BURN_CONTAINER* pContainer, | 109 | __in_opt BURN_CONTAINER* pContainer, |
| 96 | __in_opt BURN_PACKAGE* pPackage, | 110 | __in_opt BURN_PACKAGE* pPackage, |
| 97 | __in_opt BURN_PAYLOAD* pPayload, | 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, | ||
| 103 | __in BOOL fMove, | 112 | __in BOOL fMove, |
| 104 | __in DWORD cTryAgainAttempts, | 113 | __in DWORD cTryAgainAttempts, |
| 105 | __out BOOL* pfRetry | 114 | __out BOOL* pfRetry |
| @@ -461,268 +470,83 @@ extern "C" HRESULT ApplyCache( | |||
| 461 | { | 470 | { |
| 462 | HRESULT hr = S_OK; | 471 | HRESULT hr = S_OK; |
| 463 | DWORD dwCheckpoint = 0; | 472 | DWORD dwCheckpoint = 0; |
| 464 | BOOL fRetry = FALSE; | 473 | BURN_CACHE_CONTEXT cacheContext = { }; |
| 465 | DWORD iRetryAction = BURN_PLAN_INVALID_ACTION_INDEX; | 474 | BURN_PACKAGE* pPackage = NULL; |
| 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; | ||
| 472 | 475 | ||
| 473 | *pfRollback = FALSE; | 476 | *pfRollback = FALSE; |
| 474 | 477 | ||
| 475 | hr = UserExperienceOnCacheBegin(pUX); | 478 | hr = UserExperienceOnCacheBegin(pUX); |
| 476 | ExitOnRootFailure(hr, "BA aborted cache."); | 479 | ExitOnRootFailure(hr, "BA aborted cache."); |
| 477 | 480 | ||
| 478 | do | 481 | cacheContext.hSourceEngineFile = hSourceEngineFile; |
| 479 | { | 482 | cacheContext.pPayloads = pPlan->pPayloads; |
| 480 | hr = S_OK; | 483 | cacheContext.pUX = pUX; |
| 481 | fRetry = FALSE; | 484 | cacheContext.pVariables = pVariables; |
| 485 | cacheContext.qwTotalCacheSize = pPlan->qwCacheSizeTotal; | ||
| 486 | cacheContext.wzLayoutDirectory = pPlan->sczLayoutDirectory; | ||
| 482 | 487 | ||
| 483 | // Allow us to retry just a container or payload. | 488 | for (DWORD i = 0; i < pPlan->cCacheActions; ++i) |
| 484 | LPCWSTR wzRetryId = NULL; | 489 | { |
| 485 | DWORD iRetryContainerOrPayloadAction = BURN_PLAN_INVALID_ACTION_INDEX; | 490 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; |
| 486 | BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; | 491 | cacheContext.hPipe = hPipe; |
| 492 | pPackage = NULL; | ||
| 487 | 493 | ||
| 488 | // cache actions | 494 | switch (pCacheAction->type) |
| 489 | for (DWORD i = (BURN_PLAN_INVALID_ACTION_INDEX == iRetryAction) ? 0 : iRetryAction; SUCCEEDED(hr) && i < pPlan->cCacheActions; ++i) | ||
| 490 | { | 495 | { |
| 491 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; | 496 | case BURN_CACHE_ACTION_TYPE_CHECKPOINT: |
| 492 | BOOL fRetryContainerOrPayload = FALSE; | 497 | dwCheckpoint = pCacheAction->checkpoint.dwId; |
| 493 | cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; | 498 | break; |
| 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."); | ||
| 642 | 499 | ||
| 643 | hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks + 1); | 500 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: |
| 644 | if (FAILED(hr)) | 501 | hr = ApplyLayoutBundle(&cacheContext, pCacheAction->bundleLayout.pPayloadGroup, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczUnverifiedPath); |
| 645 | { | 502 | ExitOnFailure(hr, "Failed cache action: %ls", L"layout bundle"); |
| 646 | LogErrorId(hr, MSG_USER_CANCELED, L"end cache package", NULL, NULL); | ||
| 647 | } | ||
| 648 | else | ||
| 649 | { | ||
| 650 | ++(*pcOverallProgressTicks); | ||
| 651 | 503 | ||
| 652 | UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction); | 504 | ++(*pcOverallProgressTicks); |
| 653 | 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"); | ||
| 655 | 508 | ||
| 656 | iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX; | 509 | break; |
| 657 | iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 658 | pStartedPackage = NULL; | ||
| 659 | } | ||
| 660 | break; | ||
| 661 | 510 | ||
| 662 | case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: | 511 | case BURN_CACHE_ACTION_TYPE_PACKAGE: |
| 663 | if (!::SetEvent(pCacheAction->syncpoint.hEvent)) | 512 | pPackage = pCacheAction->package.pPackage; |
| 664 | { | ||
| 665 | ExitWithLastError(hr, "Failed to set syncpoint event."); | ||
| 666 | } | ||
| 667 | break; | ||
| 668 | 513 | ||
| 669 | default: | 514 | if (!pPackage->fPerMachine && !cacheContext.wzLayoutDirectory) |
| 670 | AssertSz(FALSE, "Unknown cache action."); | 515 | { |
| 671 | break; | 516 | cacheContext.hPipe = INVALID_HANDLE_VALUE; |
| 672 | } | 517 | } |
| 673 | } | ||
| 674 | |||
| 675 | if (BURN_PLAN_INVALID_ACTION_INDEX != iRetryContainerOrPayloadAction) | ||
| 676 | { | ||
| 677 | Assert(wzRetryId); | ||
| 678 | 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"); | ||
| 680 | 521 | ||
| 681 | iRetryAction = iRetryContainerOrPayloadAction; | 522 | ++(*pcOverallProgressTicks); |
| 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); | ||
| 688 | 523 | ||
| 689 | cachePackageCompleteAction = SUCCEEDED(hr) || pStartedPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE; | 524 | hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks); |
| 690 | UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction); | 525 | LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"cache package"); |
| 691 | if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction) | ||
| 692 | { | ||
| 693 | LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pStartedPackage->sczId, NULL, NULL); | ||
| 694 | 526 | ||
| 695 | iRetryAction = iPackageStartAction; | 527 | break; |
| 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); | ||
| 701 | 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; | ||
| 703 | 535 | ||
| 704 | iRetryAction = iPackageCompleteAction + 1; | 536 | case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: |
| 705 | fRetry = TRUE; | 537 | if (!::SetEvent(pCacheAction->syncpoint.hEvent)) |
| 538 | { | ||
| 539 | ExitWithLastError(hr, "Failed to set syncpoint event."); | ||
| 706 | } | 540 | } |
| 541 | break; | ||
| 707 | 542 | ||
| 708 | pStartedPackage->hrCacheResult = hr; | 543 | default: |
| 709 | 544 | AssertSz(FALSE, "Unknown cache action."); | |
| 710 | iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX; | 545 | break; |
| 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); | ||
| 718 | } | 546 | } |
| 719 | } while (fRetry); | 547 | } |
| 720 | 548 | ||
| 721 | LExit: | 549 | LExit: |
| 722 | Assert(NULL == pStartedPackage); | ||
| 723 | Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageStartAction); | ||
| 724 | Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageCompleteAction); | ||
| 725 | |||
| 726 | if (FAILED(hr)) | 550 | if (FAILED(hr)) |
| 727 | { | 551 | { |
| 728 | DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint); | 552 | DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint); |
| @@ -936,12 +760,216 @@ LExit: | |||
| 936 | return hr; | 760 | return hr; |
| 937 | } | 761 | } |
| 938 | 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 | |||
| 939 | static HRESULT ExtractContainer( | 970 | static HRESULT ExtractContainer( |
| 940 | __in HANDLE hSourceEngineFile, | 971 | __in BURN_CACHE_CONTEXT* pContext, |
| 941 | __in BURN_CONTAINER* pContainer, | 972 | __in BURN_CONTAINER* pContainer |
| 942 | __in_z LPCWSTR wzContainerPath, | ||
| 943 | __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads, | ||
| 944 | __in DWORD cExtractPayloads | ||
| 945 | ) | 973 | ) |
| 946 | { | 974 | { |
| 947 | HRESULT hr = S_OK; | 975 | HRESULT hr = S_OK; |
| @@ -952,20 +980,20 @@ static HRESULT ExtractContainer( | |||
| 952 | // If the container is actually attached, then it was planned to be acquired through hSourceEngineFile. | 980 | // If the container is actually attached, then it was planned to be acquired through hSourceEngineFile. |
| 953 | if (pContainer->fActuallyAttached) | 981 | if (pContainer->fActuallyAttached) |
| 954 | { | 982 | { |
| 955 | hContainerHandle = hSourceEngineFile; | 983 | hContainerHandle = pContext->hSourceEngineFile; |
| 956 | } | 984 | } |
| 957 | 985 | ||
| 958 | hr = ContainerOpen(&context, pContainer, hContainerHandle, wzContainerPath); | 986 | hr = ContainerOpen(&context, pContainer, hContainerHandle, pContainer->sczUnverifiedPath); |
| 959 | ExitOnFailure(hr, "Failed to open container: %ls.", pContainer->sczId); | 987 | ExitOnFailure(hr, "Failed to open container: %ls.", pContainer->sczId); |
| 960 | 988 | ||
| 961 | while (S_OK == (hr = ContainerNextStream(&context, &sczExtractPayloadId))) | 989 | while (S_OK == (hr = ContainerNextStream(&context, &sczExtractPayloadId))) |
| 962 | { | 990 | { |
| 963 | BOOL fExtracted = FALSE; | 991 | BOOL fExtracted = FALSE; |
| 964 | 992 | ||
| 965 | for (DWORD iExtract = 0; iExtract < cExtractPayloads; ++iExtract) | 993 | for (DWORD iExtract = 0; iExtract < pContext->pPayloads->cPayloads; ++iExtract) |
| 966 | { | 994 | { |
| 967 | BURN_EXTRACT_PAYLOAD* pExtract = rgExtractPayloads + iExtract; | 995 | BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract; |
| 968 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->pPayload->sczSourcePath, -1)) | 996 | if (pExtract->sczUnverifiedPath && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1)) |
| 969 | { | 997 | { |
| 970 | // TODO: Send progress when extracting stream to file. | 998 | // TODO: Send progress when extracting stream to file. |
| 971 | hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath); | 999 | hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath); |
| @@ -996,74 +1024,10 @@ LExit: | |||
| 996 | return hr; | 1024 | return hr; |
| 997 | } | 1025 | } |
| 998 | 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 | |||
| 1057 | static HRESULT LayoutBundle( | 1027 | static HRESULT LayoutBundle( |
| 1058 | __in HANDLE hSourceEngineFile, | 1028 | __in BURN_CACHE_CONTEXT* pContext, |
| 1059 | __in BURN_USER_EXPERIENCE* pUX, | ||
| 1060 | __in BURN_VARIABLES* pVariables, | ||
| 1061 | __in HANDLE hPipe, | ||
| 1062 | __in_z LPCWSTR wzExecutableName, | 1029 | __in_z LPCWSTR wzExecutableName, |
| 1063 | __in_z LPCWSTR wzLayoutDirectory, | 1030 | __in_z LPCWSTR wzUnverifiedPath |
| 1064 | __in_z LPCWSTR wzUnverifiedPath, | ||
| 1065 | __in DWORD64 qwSuccessfulCacheProgress, | ||
| 1066 | __in DWORD64 qwTotalCacheSize | ||
| 1067 | ) | 1031 | ) |
| 1068 | { | 1032 | { |
| 1069 | HRESULT hr = S_OK; | 1033 | HRESULT hr = S_OK; |
| @@ -1074,7 +1038,7 @@ static HRESULT LayoutBundle( | |||
| 1074 | BOOL fRetry = FALSE; | 1038 | BOOL fRetry = FALSE; |
| 1075 | BOOL fRetryAcquire = FALSE; | 1039 | BOOL fRetryAcquire = FALSE; |
| 1076 | 1040 | ||
| 1077 | hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); | 1041 | hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); |
| 1078 | if (FAILED(hr)) | 1042 | if (FAILED(hr)) |
| 1079 | { | 1043 | { |
| 1080 | if (E_NOTFOUND != hr) | 1044 | if (E_NOTFOUND != hr) |
| @@ -1086,7 +1050,7 @@ static HRESULT LayoutBundle( | |||
| 1086 | ExitOnFailure(hr, "Failed to get path to bundle to layout."); | 1050 | ExitOnFailure(hr, "Failed to get path to bundle to layout."); |
| 1087 | } | 1051 | } |
| 1088 | 1052 | ||
| 1089 | hr = PathConcat(wzLayoutDirectory, wzExecutableName, &sczDestinationPath); | 1053 | hr = PathConcat(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath); |
| 1090 | ExitOnFailure(hr, "Failed to concat layout path for bundle."); | 1054 | ExitOnFailure(hr, "Failed to concat layout path for bundle."); |
| 1091 | 1055 | ||
| 1092 | // If the destination path is the currently running bundle, bail. | 1056 | // If the destination path is the currently running bundle, bail. |
| @@ -1098,9 +1062,7 @@ static HRESULT LayoutBundle( | |||
| 1098 | ExitFunction1(hr = S_OK); | 1062 | ExitFunction1(hr = S_OK); |
| 1099 | } | 1063 | } |
| 1100 | 1064 | ||
| 1101 | progress.pUX = pUX; | 1065 | progress.pCacheContext = pContext; |
| 1102 | progress.qwCacheProgress = qwSuccessfulCacheProgress; | ||
| 1103 | progress.qwTotalCacheSize = qwTotalCacheSize; | ||
| 1104 | 1066 | ||
| 1105 | do | 1067 | do |
| 1106 | { | 1068 | { |
| @@ -1112,13 +1074,13 @@ static HRESULT LayoutBundle( | |||
| 1112 | fRetryAcquire = FALSE; | 1074 | fRetryAcquire = FALSE; |
| 1113 | progress.fCancel = FALSE; | 1075 | progress.fCancel = FALSE; |
| 1114 | 1076 | ||
| 1115 | hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); | 1077 | hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); |
| 1116 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); | 1078 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); |
| 1117 | 1079 | ||
| 1118 | hr = CopyPayload(&progress, hSourceEngineFile, sczBundlePath, wzUnverifiedPath); | 1080 | hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath); |
| 1119 | // Error handling happens after sending complete message to BA. | 1081 | // Error handling happens after sending complete message to BA. |
| 1120 | 1082 | ||
| 1121 | UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire); | 1083 | UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire); |
| 1122 | if (fRetryAcquire) | 1084 | if (fRetryAcquire) |
| 1123 | { | 1085 | { |
| 1124 | continue; | 1086 | continue; |
| @@ -1130,20 +1092,20 @@ static HRESULT LayoutBundle( | |||
| 1130 | 1092 | ||
| 1131 | do | 1093 | do |
| 1132 | { | 1094 | { |
| 1133 | hr = UserExperienceOnCacheVerifyBegin(pUX, NULL, NULL); | 1095 | hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL); |
| 1134 | ExitOnRootFailure(hr, "BA aborted cache verify begin."); | 1096 | ExitOnRootFailure(hr, "BA aborted cache verify begin."); |
| 1135 | 1097 | ||
| 1136 | if (INVALID_HANDLE_VALUE != hPipe) | 1098 | if (INVALID_HANDLE_VALUE != pContext->hPipe) |
| 1137 | { | 1099 | { |
| 1138 | hr = ElevationLayoutBundle(hPipe, wzLayoutDirectory, wzUnverifiedPath); | 1100 | hr = ElevationLayoutBundle(pContext->hPipe, pContext->wzLayoutDirectory, wzUnverifiedPath); |
| 1139 | } | 1101 | } |
| 1140 | else | 1102 | else |
| 1141 | { | 1103 | { |
| 1142 | hr = CacheLayoutBundle(wzExecutableName, wzLayoutDirectory, wzUnverifiedPath); | 1104 | hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath); |
| 1143 | } | 1105 | } |
| 1144 | 1106 | ||
| 1145 | BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; | 1107 | BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; |
| 1146 | UserExperienceOnCacheVerifyComplete(pUX, NULL, NULL, hr, &action); | 1108 | UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); |
| 1147 | if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) | 1109 | if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) |
| 1148 | { | 1110 | { |
| 1149 | hr = S_FALSE; // retry verify. | 1111 | hr = S_FALSE; // retry verify. |
| @@ -1154,7 +1116,7 @@ static HRESULT LayoutBundle( | |||
| 1154 | } | 1116 | } |
| 1155 | } while (S_FALSE == hr); | 1117 | } while (S_FALSE == hr); |
| 1156 | } while (fRetry); | 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); |
| 1158 | 1120 | ||
| 1159 | LExit: | 1121 | LExit: |
| 1160 | ReleaseStr(sczDestinationPath); | 1122 | ReleaseStr(sczDestinationPath); |
| @@ -1164,14 +1126,10 @@ LExit: | |||
| 1164 | } | 1126 | } |
| 1165 | 1127 | ||
| 1166 | static HRESULT AcquireContainerOrPayload( | 1128 | static HRESULT AcquireContainerOrPayload( |
| 1167 | __in BURN_USER_EXPERIENCE* pUX, | 1129 | __in BURN_CACHE_CONTEXT* pContext, |
| 1168 | __in BURN_VARIABLES* pVariables, | ||
| 1169 | __in_opt BURN_CONTAINER* pContainer, | 1130 | __in_opt BURN_CONTAINER* pContainer, |
| 1170 | __in_opt BURN_PACKAGE* pPackage, | 1131 | __in_opt BURN_PACKAGE* pPackage, |
| 1171 | __in_opt BURN_PAYLOAD* pPayload, | 1132 | __in_opt BURN_PAYLOAD* pPayload |
| 1172 | __in LPCWSTR wzDestinationPath, | ||
| 1173 | __in DWORD64 qwSuccessfulCacheProgress, | ||
| 1174 | __in DWORD64 qwTotalCacheSize | ||
| 1175 | ) | 1133 | ) |
| 1176 | { | 1134 | { |
| 1177 | AssertSz(pContainer || pPayload, "Must provide a container or a payload."); | 1135 | AssertSz(pContainer || pPayload, "Must provide a container or a payload."); |
| @@ -1180,17 +1138,16 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1180 | int nEquivalentPaths = 0; | 1138 | int nEquivalentPaths = 0; |
| 1181 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; | 1139 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; |
| 1182 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL; | 1140 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL; |
| 1141 | LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath; | ||
| 1183 | LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; | 1142 | LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; |
| 1184 | LPWSTR sczSourceFullPath = NULL; | 1143 | LPWSTR sczSourceFullPath = NULL; |
| 1185 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; | 1144 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; |
| 1186 | BOOL fRetry = FALSE; | 1145 | BOOL fRetry = FALSE; |
| 1187 | 1146 | ||
| 1147 | progress.pCacheContext = pContext; | ||
| 1188 | progress.pContainer = pContainer; | 1148 | progress.pContainer = pContainer; |
| 1189 | progress.pPackage = pPackage; | 1149 | progress.pPackage = pPackage; |
| 1190 | progress.pPayload = pPayload; | 1150 | progress.pPayload = pPayload; |
| 1191 | progress.pUX = pUX; | ||
| 1192 | progress.qwCacheProgress = qwSuccessfulCacheProgress; | ||
| 1193 | progress.qwTotalCacheSize = qwTotalCacheSize; | ||
| 1194 | 1151 | ||
| 1195 | do | 1152 | do |
| 1196 | { | 1153 | { |
| @@ -1204,7 +1161,7 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1204 | fRetry = FALSE; | 1161 | fRetry = FALSE; |
| 1205 | progress.fCancel = FALSE; | 1162 | progress.fCancel = FALSE; |
| 1206 | 1163 | ||
| 1207 | hr = CacheFindLocalSource(wzSourcePath, pVariables, &fFoundLocal, &sczSourceFullPath); | 1164 | hr = CacheFindLocalSource(wzSourcePath, wzDestinationPath, pContext->pVariables, &fFoundLocal, &sczSourceFullPath); |
| 1208 | ExitOnFailure(hr, "Failed to search local source."); | 1165 | ExitOnFailure(hr, "Failed to search local source."); |
| 1209 | 1166 | ||
| 1210 | if (fFoundLocal) // the file exists locally, so copy it. | 1167 | if (fFoundLocal) // the file exists locally, so copy it. |
| @@ -1220,7 +1177,7 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1220 | DWORD dwLogId = pContainer ? (wzPayloadId ? MSG_PROMPT_CONTAINER_PAYLOAD_SOURCE : MSG_PROMPT_CONTAINER_SOURCE) : pPackage ? MSG_PROMPT_PACKAGE_PAYLOAD_SOURCE : MSG_PROMPT_BUNDLE_PAYLOAD_SOURCE; | 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; |
| 1221 | LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId ? wzPackageOrContainerId : L"", wzPayloadId ? wzPayloadId : L"", sczSourceFullPath); | 1178 | LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId ? wzPackageOrContainerId : L"", wzPayloadId ? wzPayloadId : L"", sczSourceFullPath); |
| 1222 | 1179 | ||
| 1223 | hr = PromptForSource(pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload); | 1180 | hr = PromptForSource(pContext->pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload); |
| 1224 | 1181 | ||
| 1225 | // If the BA requested download then ensure a download url is available (it may have been set | 1182 | // If the BA requested download then ensure a download url is available (it may have been set |
| 1226 | // during PromptForSource so we need to check again). | 1183 | // during PromptForSource so we need to check again). |
| @@ -1239,7 +1196,7 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1239 | 1196 | ||
| 1240 | if (fCopy) | 1197 | if (fCopy) |
| 1241 | { | 1198 | { |
| 1242 | hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); | 1199 | hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); |
| 1243 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); | 1200 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); |
| 1244 | 1201 | ||
| 1245 | hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath); | 1202 | hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath); |
| @@ -1248,12 +1205,12 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1248 | // We successfully copied from a source location, set that as the last used source. | 1205 | // We successfully copied from a source location, set that as the last used source. |
| 1249 | if (SUCCEEDED(hr)) | 1206 | if (SUCCEEDED(hr)) |
| 1250 | { | 1207 | { |
| 1251 | CacheSetLastUsedSource(pVariables, sczSourceFullPath, wzRelativePath); | 1208 | CacheSetLastUsedSource(pContext->pVariables, sczSourceFullPath, wzRelativePath); |
| 1252 | } | 1209 | } |
| 1253 | } | 1210 | } |
| 1254 | else if (fDownload) | 1211 | else if (fDownload) |
| 1255 | { | 1212 | { |
| 1256 | hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl); | 1213 | hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl); |
| 1257 | ExitOnRootFailure(hr, "BA aborted cache download payload begin."); | 1214 | ExitOnRootFailure(hr, "BA aborted cache download payload begin."); |
| 1258 | 1215 | ||
| 1259 | hr = DownloadPayload(&progress, wzDestinationPath); | 1216 | hr = DownloadPayload(&progress, wzDestinationPath); |
| @@ -1262,7 +1219,7 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1262 | 1219 | ||
| 1263 | if (fCopy || fDownload) | 1220 | if (fCopy || fDownload) |
| 1264 | { | 1221 | { |
| 1265 | UserExperienceOnCacheAcquireComplete(pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | 1222 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); |
| 1266 | if (fRetry) | 1223 | if (fRetry) |
| 1267 | { | 1224 | { |
| 1268 | hr = S_OK; | 1225 | hr = S_OK; |
| @@ -1279,16 +1236,10 @@ LExit: | |||
| 1279 | } | 1236 | } |
| 1280 | 1237 | ||
| 1281 | static HRESULT LayoutOrCacheContainerOrPayload( | 1238 | static HRESULT LayoutOrCacheContainerOrPayload( |
| 1282 | __in BURN_USER_EXPERIENCE* pUX, | 1239 | __in BURN_CACHE_CONTEXT* pContext, |
| 1283 | __in HANDLE hPipe, | ||
| 1284 | __in_opt BURN_CONTAINER* pContainer, | 1240 | __in_opt BURN_CONTAINER* pContainer, |
| 1285 | __in_opt BURN_PACKAGE* pPackage, | 1241 | __in_opt BURN_PACKAGE* pPackage, |
| 1286 | __in_opt BURN_PAYLOAD* pPayload, | 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, | ||
| 1292 | __in BOOL fMove, | 1243 | __in BOOL fMove, |
| 1293 | __in DWORD cTryAgainAttempts, | 1244 | __in DWORD cTryAgainAttempts, |
| 1294 | __out BOOL* pfRetry | 1245 | __out BOOL* pfRetry |
| @@ -1296,13 +1247,14 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1296 | { | 1247 | { |
| 1297 | HRESULT hr = S_OK; | 1248 | HRESULT hr = S_OK; |
| 1298 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L""; | 1249 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L""; |
| 1250 | LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; | ||
| 1299 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; | 1251 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; |
| 1300 | LARGE_INTEGER liContainerOrPayloadSize = { }; | 1252 | LARGE_INTEGER liContainerOrPayloadSize = { }; |
| 1301 | LARGE_INTEGER liZero = { }; | 1253 | LARGE_INTEGER liZero = { }; |
| 1302 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; | 1254 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; |
| 1303 | BOOL fCanAffectRegistration = FALSE; | 1255 | BOOL fCanAffectRegistration = FALSE; |
| 1304 | 1256 | ||
| 1305 | if (!wzLayoutDirectory) | 1257 | if (!pContext->wzLayoutDirectory) |
| 1306 | { | 1258 | { |
| 1307 | Assert(!pContainer); | 1259 | Assert(!pContainer); |
| 1308 | Assert(pPackage); | 1260 | Assert(pPackage); |
| @@ -1312,41 +1264,31 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1312 | 1264 | ||
| 1313 | liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize; | 1265 | liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize; |
| 1314 | 1266 | ||
| 1267 | progress.pCacheContext = pContext; | ||
| 1315 | progress.pContainer = pContainer; | 1268 | progress.pContainer = pContainer; |
| 1316 | progress.pPackage = pPackage; | 1269 | progress.pPackage = pPackage; |
| 1317 | progress.pPayload = pPayload; | 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 | } | ||
| 1329 | 1271 | ||
| 1330 | *pfRetry = FALSE; | 1272 | *pfRetry = FALSE; |
| 1331 | 1273 | ||
| 1332 | do | 1274 | do |
| 1333 | { | 1275 | { |
| 1334 | hr = UserExperienceOnCacheVerifyBegin(pUX, wzPackageOrContainerId, wzPayloadId); | 1276 | hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId); |
| 1335 | ExitOnRootFailure(hr, "BA aborted cache verify begin."); | 1277 | ExitOnRootFailure(hr, "BA aborted cache verify begin."); |
| 1336 | 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. |
| 1338 | { | 1280 | { |
| 1339 | hr = ElevationCacheOrLayoutContainerOrPayload(hPipe, pContainer, pPackage, pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove); | 1281 | hr = ElevationCacheOrLayoutContainerOrPayload(pContext->hPipe, pContainer, pPackage, pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); |
| 1340 | } | 1282 | } |
| 1341 | else if (wzLayoutDirectory) // layout the container or payload. | 1283 | else if (pContext->wzLayoutDirectory) // layout the container or payload. |
| 1342 | { | 1284 | { |
| 1343 | if (pContainer) | 1285 | if (pContainer) |
| 1344 | { | 1286 | { |
| 1345 | hr = CacheLayoutContainer(pContainer, wzLayoutDirectory, wzUnverifiedPath, fMove); | 1287 | hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); |
| 1346 | } | 1288 | } |
| 1347 | else | 1289 | else |
| 1348 | { | 1290 | { |
| 1349 | hr = CacheLayoutPayload(pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove); | 1291 | hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); |
| 1350 | } | 1292 | } |
| 1351 | } | 1293 | } |
| 1352 | else // complete the payload. | 1294 | else // complete the payload. |
| @@ -1376,7 +1318,7 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1376 | } | 1318 | } |
| 1377 | 1319 | ||
| 1378 | BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; | 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); |
| 1380 | if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) | 1322 | if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) |
| 1381 | { | 1323 | { |
| 1382 | hr = S_FALSE; // retry verify. | 1324 | hr = S_FALSE; // retry verify. |
| @@ -1541,7 +1483,7 @@ static HRESULT DownloadPayload( | |||
| 1541 | cacheCallback.pfnCancel = NULL; // TODO: set this | 1483 | cacheCallback.pfnCancel = NULL; // TODO: set this |
| 1542 | cacheCallback.pv = pProgress; | 1484 | cacheCallback.pv = pProgress; |
| 1543 | 1485 | ||
| 1544 | authenticationData.pUX = pProgress->pUX; | 1486 | authenticationData.pUX = pProgress->pCacheContext->pUX; |
| 1545 | authenticationData.wzPackageOrContainerId = wzPackageOrContainerId; | 1487 | authenticationData.wzPackageOrContainerId = wzPackageOrContainerId; |
| 1546 | authenticationData.wzPayloadId = wzPayloadId; | 1488 | authenticationData.wzPayloadId = wzPayloadId; |
| 1547 | authenticationCallback.pv = static_cast<LPVOID>(&authenticationData); | 1489 | authenticationCallback.pv = static_cast<LPVOID>(&authenticationData); |
| @@ -1630,15 +1572,15 @@ static DWORD CALLBACK CacheProgressRoutine( | |||
| 1630 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT*>(lpData); | 1572 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT*>(lpData); |
| 1631 | LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; | 1573 | LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; |
| 1632 | LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; | 1574 | LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; |
| 1633 | DWORD64 qwCacheProgress = pProgress->qwCacheProgress + TotalBytesTransferred.QuadPart; | 1575 | DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart; |
| 1634 | if (qwCacheProgress > pProgress->qwTotalCacheSize) | 1576 | if (qwCacheProgress > pProgress->pCacheContext->qwTotalCacheSize) |
| 1635 | { | 1577 | { |
| 1636 | AssertSz(FALSE, "Apply has cached more than Plan envisioned."); | 1578 | //AssertSz(FALSE, "Apply has cached more than Plan envisioned."); |
| 1637 | qwCacheProgress = pProgress->qwTotalCacheSize; | 1579 | qwCacheProgress = pProgress->pCacheContext->qwTotalCacheSize; |
| 1638 | } | 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; |
| 1640 | 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); |
| 1642 | if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) | 1584 | if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) |
| 1643 | { | 1585 | { |
| 1644 | dwResult = PROGRESS_CANCEL; | 1586 | dwResult = PROGRESS_CANCEL; |
