aboutsummaryrefslogtreecommitdiff
path: root/src/burn
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn')
-rw-r--r--src/burn/engine/apply.cpp87
-rw-r--r--src/burn/engine/core.h3
-rw-r--r--src/burn/engine/elevation.cpp36
-rw-r--r--src/burn/engine/elevation.h9
-rw-r--r--src/burn/engine/engine.mc2
-rw-r--r--src/burn/engine/logging.cpp17
-rw-r--r--src/burn/engine/logging.h4
-rw-r--r--src/burn/engine/registration.cpp140
-rw-r--r--src/burn/engine/registration.h10
-rw-r--r--src/burn/engine/userexperience.cpp18
-rw-r--r--src/burn/engine/userexperience.h5
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp38
12 files changed, 269 insertions, 100 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index aad9e6eb..c32f4c84 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -75,7 +75,8 @@ static HRESULT WINAPI AuthenticationRequired(
75 75
76static void CalculateKeepRegistration( 76static void CalculateKeepRegistration(
77 __in BURN_ENGINE_STATE* pEngineState, 77 __in BURN_ENGINE_STATE* pEngineState,
78 __inout BOOL* pfKeepRegistration 78 __in BOOL fLog,
79 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
79 ); 80 );
80static HRESULT ExecuteDependentRegistrationActions( 81static HRESULT ExecuteDependentRegistrationActions(
81 __in HANDLE hPipe, 82 __in HANDLE hPipe,
@@ -376,8 +377,11 @@ extern "C" HRESULT ApplyRegister(
376{ 377{
377 HRESULT hr = S_OK; 378 HRESULT hr = S_OK;
378 LPWSTR sczEngineWorkingPath = NULL; 379 LPWSTR sczEngineWorkingPath = NULL;
380 BOOTSTRAPPER_REGISTRATION_TYPE registrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
379 381
380 hr = UserExperienceOnRegisterBegin(&pEngineState->userExperience); 382 CalculateKeepRegistration(pEngineState, FALSE, &registrationType);
383
384 hr = UserExperienceOnRegisterBegin(&pEngineState->userExperience, &registrationType);
381 ExitOnRootFailure(hr, "BA aborted register begin."); 385 ExitOnRootFailure(hr, "BA aborted register begin.");
382 386
383 // If we have a resume mode that suggests the bundle is on the machine. 387 // If we have a resume mode that suggests the bundle is on the machine.
@@ -386,12 +390,12 @@ extern "C" HRESULT ApplyRegister(
386 // resume previous session 390 // resume previous session
387 if (pEngineState->registration.fPerMachine) 391 if (pEngineState->registration.fPerMachine)
388 { 392 {
389 hr = ElevationSessionResume(pEngineState->companionConnection.hPipe, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables); 393 hr = ElevationSessionResume(pEngineState->companionConnection.hPipe, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, registrationType);
390 ExitOnFailure(hr, "Failed to resume registration session in per-machine process."); 394 ExitOnFailure(hr, "Failed to resume registration session in per-machine process.");
391 } 395 }
392 else 396 else
393 { 397 {
394 hr = RegistrationSessionResume(&pEngineState->registration, &pEngineState->variables); 398 hr = RegistrationSessionResume(&pEngineState->registration, &pEngineState->variables, registrationType);
395 ExitOnFailure(hr, "Failed to resume registration session."); 399 ExitOnFailure(hr, "Failed to resume registration session.");
396 } 400 }
397 } 401 }
@@ -403,12 +407,12 @@ extern "C" HRESULT ApplyRegister(
403 // begin new session 407 // begin new session
404 if (pEngineState->registration.fPerMachine) 408 if (pEngineState->registration.fPerMachine)
405 { 409 {
406 hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize); 410 hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType);
407 ExitOnFailure(hr, "Failed to begin registration session in per-machine process."); 411 ExitOnFailure(hr, "Failed to begin registration session in per-machine process.");
408 } 412 }
409 else 413 else
410 { 414 {
411 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize); 415 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType);
412 ExitOnFailure(hr, "Failed to begin registration session."); 416 ExitOnFailure(hr, "Failed to begin registration session.");
413 } 417 }
414 } 418 }
@@ -441,17 +445,11 @@ extern "C" HRESULT ApplyUnregister(
441{ 445{
442 HRESULT hr = S_OK; 446 HRESULT hr = S_OK;
443 BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE; 447 BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE;
444 BOOL fKeepRegistration = pEngineState->plan.fDisallowRemoval; 448 BOOTSTRAPPER_REGISTRATION_TYPE defaultRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
445 449 BOOTSTRAPPER_REGISTRATION_TYPE registrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
446 CalculateKeepRegistration(pEngineState, &fKeepRegistration);
447
448 hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience, &fKeepRegistration);
449 ExitOnRootFailure(hr, "BA aborted unregister begin.");
450 450
451 // Calculate the correct resume mode. If a restart has been initiated, that trumps all other 451 // Calculate special cases for the resume mode. If a restart has been initiated, that trumps all other
452 // modes. If the user chose to suspend the install then we'll use that as the resume mode. 452 // modes. If the user chose to suspend the install then we'll use that as the resume mode.
453 // Barring those special cases, if it was determined that we should keep the registration then
454 // do that, otherwise the resume mode was initialized to none and registration will be removed.
455 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) 453 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
456 { 454 {
457 resumeMode = BURN_RESUME_MODE_REBOOT_PENDING; 455 resumeMode = BURN_RESUME_MODE_REBOOT_PENDING;
@@ -460,28 +458,50 @@ extern "C" HRESULT ApplyUnregister(
460 { 458 {
461 resumeMode = BURN_RESUME_MODE_SUSPEND; 459 resumeMode = BURN_RESUME_MODE_SUSPEND;
462 } 460 }
463 else if (fKeepRegistration) 461 else if (pEngineState->plan.fDisallowRemoval)
462 {
463 resumeMode = BURN_RESUME_MODE_ARP;
464 }
465
466 // If there was a special case, make sure the registration is kept.
467 if (BURN_RESUME_MODE_NONE < resumeMode)
468 {
469 defaultRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
470 }
471
472 CalculateKeepRegistration(pEngineState, TRUE, &defaultRegistrationType);
473
474 registrationType = defaultRegistrationType;
475
476 hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience, &registrationType);
477 ExitOnRootFailure(hr, "BA aborted unregister begin.");
478
479 // Barring the special cases, if it was determined that we should keep the registration then
480 // do that, otherwise the resume mode is NONE and registration will be removed.
481 if (BURN_RESUME_MODE_NONE == resumeMode && BOOTSTRAPPER_REGISTRATION_TYPE_NONE < registrationType)
464 { 482 {
465 resumeMode = BURN_RESUME_MODE_ARP; 483 resumeMode = BURN_RESUME_MODE_ARP;
466 } 484 }
467 485
468 // If apply failed in any way and we're going to be keeping the bundle registered then 486 // If apply failed in any way and we're going to be keeping the bundle registered then
469 // execute any rollback dependency registration actions. 487 // execute any rollback dependency registration actions.
470 if (fFailed && fKeepRegistration) 488 if (fFailed && BURN_RESUME_MODE_NONE < resumeMode)
471 { 489 {
472 // Execute any rollback registration actions. 490 // Execute any rollback registration actions.
473 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions); 491 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions);
474 UNREFERENCED_PARAMETER(hrRegistrationRollback); 492 IgnoreRollbackError(hrRegistrationRollback, "Dependent registration actions failed");
475 } 493 }
476 494
495 LogId(REPORT_STANDARD, MSG_SESSION_END, pEngineState->registration.sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingRestartToString(restart), LoggingBoolToString(pEngineState->registration.fDisableResume), LoggingRegistrationTypeToString(defaultRegistrationType), LoggingRegistrationTypeToString(registrationType));
496
477 if (pEngineState->registration.fPerMachine) 497 if (pEngineState->registration.fPerMachine)
478 { 498 {
479 hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction); 499 hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType);
480 ExitOnFailure(hr, "Failed to end session in per-machine process."); 500 ExitOnFailure(hr, "Failed to end session in per-machine process.");
481 } 501 }
482 else 502 else
483 { 503 {
484 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction); 504 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType);
485 ExitOnFailure(hr, "Failed to end session in per-user process."); 505 ExitOnFailure(hr, "Failed to end session in per-user process.");
486 } 506 }
487 507
@@ -751,10 +771,14 @@ extern "C" void ApplyClean(
751 771
752static void CalculateKeepRegistration( 772static void CalculateKeepRegistration(
753 __in BURN_ENGINE_STATE* pEngineState, 773 __in BURN_ENGINE_STATE* pEngineState,
754 __inout BOOL* pfKeepRegistration 774 __in BOOL fLog,
775 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
755 ) 776 )
756{ 777{
757 LogId(REPORT_STANDARD, MSG_POST_APPLY_CALCULATE_REGISTRATION); 778 if (fLog)
779 {
780 LogId(REPORT_STANDARD, MSG_POST_APPLY_CALCULATE_REGISTRATION);
781 }
758 782
759 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i) 783 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
760 { 784 {
@@ -765,17 +789,28 @@ static void CalculateKeepRegistration(
765 MspEngineFinalizeInstallRegistrationState(pPackage); 789 MspEngineFinalizeInstallRegistrationState(pPackage);
766 } 790 }
767 791
768 LogId(REPORT_STANDARD, MSG_POST_APPLY_PACKAGE, pPackage->sczId, LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState)); 792 if (fLog)
793 {
794 LogId(REPORT_STANDARD, MSG_POST_APPLY_PACKAGE, pPackage->sczId, LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
795 }
769 796
770 if (!pPackage->fCanAffectRegistration) 797 if (!pPackage->fCanAffectRegistration)
771 { 798 {
772 continue; 799 continue;
773 } 800 }
774 801
775 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState || 802 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState)
776 BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState) 803 {
804 *pRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
805
806 if (!fLog)
807 {
808 break;
809 }
810 }
811 else if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState && BOOTSTRAPPER_REGISTRATION_TYPE_NONE == *pRegistrationType)
777 { 812 {
778 *pfKeepRegistration = TRUE; 813 *pRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
779 } 814 }
780 } 815 }
781} 816}
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index 27cb2e25..3a28188b 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -48,8 +48,9 @@ const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel";
48const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; 48const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion";
49const LPCWSTR BURN_REBOOT_PENDING = L"RebootPending"; 49const LPCWSTR BURN_REBOOT_PENDING = L"RebootPending";
50 50
51// The following constants must stay in sync with src\wix\Binder.cs 51// The following constants must stay in sync with src\api\wix\WixToolset.Data\Burn\BurnConstants.cs
52const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName"; 52const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName";
53const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName";
53const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource"; 54const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource";
54const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder"; 55const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder";
55const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource"; 56const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource";
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 85e4b692..db2a82a6 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -477,7 +477,8 @@ extern "C" HRESULT ElevationSessionBegin(
477 __in BURN_VARIABLES* pVariables, 477 __in BURN_VARIABLES* pVariables,
478 __in DWORD dwRegistrationOperations, 478 __in DWORD dwRegistrationOperations,
479 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 479 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
480 __in DWORD64 qwEstimatedSize 480 __in DWORD64 qwEstimatedSize,
481 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
481 ) 482 )
482{ 483{
483 HRESULT hr = S_OK; 484 HRESULT hr = S_OK;
@@ -504,6 +505,9 @@ extern "C" HRESULT ElevationSessionBegin(
504 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize); 505 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize);
505 ExitOnFailure(hr, "Failed to write estimated size to message buffer."); 506 ExitOnFailure(hr, "Failed to write estimated size to message buffer.");
506 507
508 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
509 ExitOnFailure(hr, "Failed to write registration type to message buffer.");
510
507 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); 511 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
508 ExitOnFailure(hr, "Failed to write variables."); 512 ExitOnFailure(hr, "Failed to write variables.");
509 513
@@ -527,7 +531,8 @@ extern "C" HRESULT ElevationSessionResume(
527 __in HANDLE hPipe, 531 __in HANDLE hPipe,
528 __in_z LPCWSTR wzResumeCommandLine, 532 __in_z LPCWSTR wzResumeCommandLine,
529 __in BOOL fDisableResume, 533 __in BOOL fDisableResume,
530 __in BURN_VARIABLES* pVariables 534 __in BURN_VARIABLES* pVariables,
535 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
531 ) 536 )
532{ 537{
533 HRESULT hr = S_OK; 538 HRESULT hr = S_OK;
@@ -542,6 +547,9 @@ extern "C" HRESULT ElevationSessionResume(
542 hr = BuffWriteNumber(&pbData, &cbData, fDisableResume); 547 hr = BuffWriteNumber(&pbData, &cbData, fDisableResume);
543 ExitOnFailure(hr, "Failed to write resume flag."); 548 ExitOnFailure(hr, "Failed to write resume flag.");
544 549
550 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
551 ExitOnFailure(hr, "Failed to write registration type to message buffer.");
552
545 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); 553 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
546 ExitOnFailure(hr, "Failed to write variables."); 554 ExitOnFailure(hr, "Failed to write variables.");
547 555
@@ -565,7 +573,8 @@ extern "C" HRESULT ElevationSessionEnd(
565 __in HANDLE hPipe, 573 __in HANDLE hPipe,
566 __in BURN_RESUME_MODE resumeMode, 574 __in BURN_RESUME_MODE resumeMode,
567 __in BOOTSTRAPPER_APPLY_RESTART restart, 575 __in BOOTSTRAPPER_APPLY_RESTART restart,
568 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction 576 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
577 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
569 ) 578 )
570{ 579{
571 HRESULT hr = S_OK; 580 HRESULT hr = S_OK;
@@ -583,6 +592,9 @@ extern "C" HRESULT ElevationSessionEnd(
583 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction); 592 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction);
584 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer."); 593 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
585 594
595 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
596 ExitOnFailure(hr, "Failed to write registration type to message buffer.");
597
586 // send message 598 // send message
587 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, pbData, cbData, NULL, NULL, &dwResult); 599 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, pbData, cbData, NULL, NULL, &dwResult);
588 ExitOnFailure(hr, "Failed to send message to per-machine process."); 600 ExitOnFailure(hr, "Failed to send message to per-machine process.");
@@ -2080,6 +2092,7 @@ static HRESULT OnSessionBegin(
2080 DWORD dwRegistrationOperations = 0; 2092 DWORD dwRegistrationOperations = 0;
2081 DWORD dwDependencyRegistrationAction = 0; 2093 DWORD dwDependencyRegistrationAction = 0;
2082 DWORD64 qwEstimatedSize = 0; 2094 DWORD64 qwEstimatedSize = 0;
2095 DWORD dwRegistrationType = 0;
2083 2096
2084 // Deserialize message data. 2097 // Deserialize message data.
2085 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingPath); 2098 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingPath);
@@ -2100,11 +2113,14 @@ static HRESULT OnSessionBegin(
2100 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize); 2113 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize);
2101 ExitOnFailure(hr, "Failed to read estimated size."); 2114 ExitOnFailure(hr, "Failed to read estimated size.");
2102 2115
2116 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2117 ExitOnFailure(hr, "Failed to read dependency registration action.");
2118
2103 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); 2119 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2104 ExitOnFailure(hr, "Failed to read variables."); 2120 ExitOnFailure(hr, "Failed to read variables.");
2105 2121
2106 // Begin session in per-machine process. 2122 // Begin session in per-machine process.
2107 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize); 2123 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2108 ExitOnFailure(hr, "Failed to begin registration session."); 2124 ExitOnFailure(hr, "Failed to begin registration session.");
2109 2125
2110LExit: 2126LExit:
@@ -2122,6 +2138,7 @@ static HRESULT OnSessionResume(
2122{ 2138{
2123 HRESULT hr = S_OK; 2139 HRESULT hr = S_OK;
2124 SIZE_T iData = 0; 2140 SIZE_T iData = 0;
2141 DWORD dwRegistrationType = 0;
2125 2142
2126 // Deserialize message data. 2143 // Deserialize message data.
2127 hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine); 2144 hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine);
@@ -2130,11 +2147,14 @@ static HRESULT OnSessionResume(
2130 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume); 2147 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume);
2131 ExitOnFailure(hr, "Failed to read resume flag."); 2148 ExitOnFailure(hr, "Failed to read resume flag.");
2132 2149
2150 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2151 ExitOnFailure(hr, "Failed to read dependency registration action.");
2152
2133 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); 2153 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2134 ExitOnFailure(hr, "Failed to read variables."); 2154 ExitOnFailure(hr, "Failed to read variables.");
2135 2155
2136 // resume session in per-machine process 2156 // resume session in per-machine process
2137 hr = RegistrationSessionResume(pRegistration, pVariables); 2157 hr = RegistrationSessionResume(pRegistration, pVariables, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2138 ExitOnFailure(hr, "Failed to resume registration session."); 2158 ExitOnFailure(hr, "Failed to resume registration session.");
2139 2159
2140LExit: 2160LExit:
@@ -2154,6 +2174,7 @@ static HRESULT OnSessionEnd(
2154 DWORD dwResumeMode = 0; 2174 DWORD dwResumeMode = 0;
2155 DWORD dwRestart = 0; 2175 DWORD dwRestart = 0;
2156 DWORD dwDependencyRegistrationAction = 0; 2176 DWORD dwDependencyRegistrationAction = 0;
2177 DWORD dwRegistrationType = 0;
2157 2178
2158 // Deserialize message data. 2179 // Deserialize message data.
2159 hr = BuffReadNumber(pbData, cbData, &iData, &dwResumeMode); 2180 hr = BuffReadNumber(pbData, cbData, &iData, &dwResumeMode);
@@ -2165,8 +2186,11 @@ static HRESULT OnSessionEnd(
2165 hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction); 2186 hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction);
2166 ExitOnFailure(hr, "Failed to read dependency registration action."); 2187 ExitOnFailure(hr, "Failed to read dependency registration action.");
2167 2188
2189 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2190 ExitOnFailure(hr, "Failed to read dependency registration action.");
2191
2168 // suspend session in per-machine process 2192 // suspend session in per-machine process
2169 hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction); 2193 hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2170 ExitOnFailure(hr, "Failed to suspend registration session."); 2194 ExitOnFailure(hr, "Failed to suspend registration session.");
2171 2195
2172LExit: 2196LExit:
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h
index af2dec8b..00dca8dc 100644
--- a/src/burn/engine/elevation.h
+++ b/src/burn/engine/elevation.h
@@ -31,19 +31,22 @@ HRESULT ElevationSessionBegin(
31 __in BURN_VARIABLES* pVariables, 31 __in BURN_VARIABLES* pVariables,
32 __in DWORD dwRegistrationOperations, 32 __in DWORD dwRegistrationOperations,
33 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 33 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
34 __in DWORD64 qwEstimatedSize 34 __in DWORD64 qwEstimatedSize,
35 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
35 ); 36 );
36HRESULT ElevationSessionResume( 37HRESULT ElevationSessionResume(
37 __in HANDLE hPipe, 38 __in HANDLE hPipe,
38 __in_z LPCWSTR wzResumeCommandLine, 39 __in_z LPCWSTR wzResumeCommandLine,
39 __in BOOL fDisableResume, 40 __in BOOL fDisableResume,
40 __in BURN_VARIABLES* pVariables 41 __in BURN_VARIABLES* pVariables,
42 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
41 ); 43 );
42HRESULT ElevationSessionEnd( 44HRESULT ElevationSessionEnd(
43 __in HANDLE hPipe, 45 __in HANDLE hPipe,
44 __in BURN_RESUME_MODE resumeMode, 46 __in BURN_RESUME_MODE resumeMode,
45 __in BOOTSTRAPPER_APPLY_RESTART restart, 47 __in BOOTSTRAPPER_APPLY_RESTART restart,
46 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction 48 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
49 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
47 ); 50 );
48HRESULT ElevationSaveState( 51HRESULT ElevationSaveState(
49 __in HANDLE hPipe, 52 __in HANDLE hPipe,
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 929bf67a..ad9d676f 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -889,7 +889,7 @@ MessageId=372
889Severity=Success 889Severity=Success
890SymbolicName=MSG_SESSION_END 890SymbolicName=MSG_SESSION_END
891Language=English 891Language=English
892Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs! 892Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs!, default registration: %5!hs!, ba requested registration: %6!hs!
893. 893.
894 894
895MessageId=373 895MessageId=373
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp
index 7ee1ec85..2db7defd 100644
--- a/src/burn/engine/logging.cpp
+++ b/src/burn/engine/logging.cpp
@@ -561,6 +561,23 @@ extern "C" LPCSTR LoggingPerMachineToString(
561 return "PerUser"; 561 return "PerUser";
562} 562}
563 563
564extern "C" LPCSTR LoggingRegistrationTypeToString(
565 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
566 )
567{
568 switch (registrationType)
569 {
570 case BOOTSTRAPPER_REGISTRATION_TYPE_NONE:
571 return "None";
572 case BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS:
573 return "InProgress";
574 case BOOTSTRAPPER_REGISTRATION_TYPE_FULL:
575 return "Full";
576 default:
577 return "Invalid";
578 }
579}
580
564extern "C" LPCSTR LoggingRestartToString( 581extern "C" LPCSTR LoggingRestartToString(
565 __in BOOTSTRAPPER_APPLY_RESTART restart 582 __in BOOTSTRAPPER_APPLY_RESTART restart
566 ) 583 )
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h
index 909ce591..21ea6297 100644
--- a/src/burn/engine/logging.h
+++ b/src/burn/engine/logging.h
@@ -123,6 +123,10 @@ LPCSTR LoggingPerMachineToString(
123 __in BOOL fPerMachine 123 __in BOOL fPerMachine
124 ); 124 );
125 125
126LPCSTR LoggingRegistrationTypeToString(
127 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
128 );
129
126LPCSTR LoggingRestartToString( 130LPCSTR LoggingRestartToString(
127 __in BOOTSTRAPPER_APPLY_RESTART restart 131 __in BOOTSTRAPPER_APPLY_RESTART restart
128 ); 132 );
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index 5b246112..eed1fee2 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -46,12 +46,23 @@ static HRESULT SetPaths(
46static HRESULT GetBundleManufacturer( 46static HRESULT GetBundleManufacturer(
47 __in BURN_REGISTRATION* pRegistration, 47 __in BURN_REGISTRATION* pRegistration,
48 __in BURN_VARIABLES* pVariables, 48 __in BURN_VARIABLES* pVariables,
49 __out LPWSTR* psczBundleManufacturer 49 __out_z LPWSTR* psczBundleManufacturer
50 );
51static HRESULT GetBundleInProgressName(
52 __in BURN_REGISTRATION* pRegistration,
53 __in BURN_VARIABLES* pVariables,
54 __out_z LPWSTR* psczBundleName
50 ); 55 );
51static HRESULT GetBundleName( 56static HRESULT GetBundleName(
52 __in BURN_REGISTRATION* pRegistration, 57 __in BURN_REGISTRATION* pRegistration,
53 __in BURN_VARIABLES* pVariables, 58 __in BURN_VARIABLES* pVariables,
54 __out LPWSTR* psczBundleName 59 __out_z LPWSTR* psczBundleName
60 );
61static HRESULT EnsureRegistrationVariable(
62 __in BURN_VARIABLES* pVariables,
63 __in_z LPCWSTR wzVariable,
64 __in_z LPCWSTR wzDefaultValue,
65 __out_z LPWSTR* psczValue
55 ); 66 );
56static HRESULT UpdateResumeMode( 67static HRESULT UpdateResumeMode(
57 __in BURN_REGISTRATION* pRegistration, 68 __in BURN_REGISTRATION* pRegistration,
@@ -91,7 +102,8 @@ static HRESULT RegWriteStringVariable(
91static HRESULT UpdateBundleNameRegistration( 102static HRESULT UpdateBundleNameRegistration(
92 __in BURN_REGISTRATION* pRegistration, 103 __in BURN_REGISTRATION* pRegistration,
93 __in BURN_VARIABLES* pVariables, 104 __in BURN_VARIABLES* pVariables,
94 __in HKEY hkRegistration 105 __in HKEY hkRegistration,
106 __in BOOL fInProgressRegistration
95 ); 107 );
96static BOOL IsWuRebootPending(); 108static BOOL IsWuRebootPending();
97static BOOL IsBundleRebootPending( 109static BOOL IsBundleRebootPending(
@@ -176,6 +188,13 @@ extern "C" HRESULT RegistrationParseFromXml(
176 ExitOnFailure(hr, "Failed to get @DisplayName."); 188 ExitOnFailure(hr, "Failed to get @DisplayName.");
177 } 189 }
178 190
191 // @InProgressDisplayName
192 hr = XmlGetAttributeEx(pixnArpNode, L"InProgressDisplayName", &pRegistration->sczInProgressDisplayName);
193 if (E_NOTFOUND != hr)
194 {
195 ExitOnFailure(hr, "Failed to get @InProgressDisplayName.");
196 }
197
179 // @DisplayVersion 198 // @DisplayVersion
180 hr = XmlGetAttributeEx(pixnArpNode, L"DisplayVersion", &pRegistration->sczDisplayVersion); 199 hr = XmlGetAttributeEx(pixnArpNode, L"DisplayVersion", &pRegistration->sczDisplayVersion);
181 if (E_NOTFOUND != hr) 200 if (E_NOTFOUND != hr)
@@ -372,6 +391,7 @@ extern "C" void RegistrationUninitialize(
372 ReleaseStr(pRegistration->sczStateFile); 391 ReleaseStr(pRegistration->sczStateFile);
373 392
374 ReleaseStr(pRegistration->sczDisplayName); 393 ReleaseStr(pRegistration->sczDisplayName);
394 ReleaseStr(pRegistration->sczInProgressDisplayName);
375 ReleaseStr(pRegistration->sczDisplayVersion); 395 ReleaseStr(pRegistration->sczDisplayVersion);
376 ReleaseStr(pRegistration->sczPublisher); 396 ReleaseStr(pRegistration->sczPublisher);
377 ReleaseStr(pRegistration->sczHelpLink); 397 ReleaseStr(pRegistration->sczHelpLink);
@@ -421,8 +441,7 @@ extern "C" HRESULT RegistrationSetVariables(
421 ) 441 )
422{ 442{
423 HRESULT hr = S_OK; 443 HRESULT hr = S_OK;
424 LPWSTR sczBundleManufacturer = NULL; 444 LPWSTR scz = NULL;
425 LPWSTR sczBundleName = NULL;
426 445
427 if (pRegistration->fInstalled) 446 if (pRegistration->fInstalled)
428 { 447 {
@@ -431,10 +450,13 @@ extern "C" HRESULT RegistrationSetVariables(
431 } 450 }
432 451
433 // Ensure the registration bundle name is updated. 452 // Ensure the registration bundle name is updated.
434 hr = GetBundleName(pRegistration, pVariables, &sczBundleName); 453 hr = GetBundleInProgressName(pRegistration, pVariables, &scz);
435 ExitOnFailure(hr, "Failed to initialize bundle name."); 454 ExitOnFailure(hr, "Failed to initialize bundle name.");
436 455
437 hr = GetBundleManufacturer(pRegistration, pVariables, &sczBundleName); 456 hr = GetBundleName(pRegistration, pVariables, &scz);
457 ExitOnFailure(hr, "Failed to initialize bundle name.");
458
459 hr = GetBundleManufacturer(pRegistration, pVariables, &scz);
438 ExitOnFailure(hr, "Failed to initialize bundle manufacturer."); 460 ExitOnFailure(hr, "Failed to initialize bundle manufacturer.");
439 461
440 if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent) 462 if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent)
@@ -456,8 +478,7 @@ extern "C" HRESULT RegistrationSetVariables(
456 ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable."); 478 ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable.");
457 479
458LExit: 480LExit:
459 ReleaseStr(sczBundleManufacturer); 481 ReleaseStr(scz);
460 ReleaseStr(sczBundleName);
461 482
462 return hr; 483 return hr;
463} 484}
@@ -595,7 +616,8 @@ extern "C" HRESULT RegistrationSessionBegin(
595 __in BURN_VARIABLES* pVariables, 616 __in BURN_VARIABLES* pVariables,
596 __in DWORD dwRegistrationOptions, 617 __in DWORD dwRegistrationOptions,
597 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 618 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
598 __in DWORD64 qwEstimatedSize 619 __in DWORD64 qwEstimatedSize,
620 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
599 ) 621 )
600{ 622{
601 HRESULT hr = S_OK; 623 HRESULT hr = S_OK;
@@ -603,6 +625,8 @@ extern "C" HRESULT RegistrationSessionBegin(
603 HKEY hkRegistration = NULL; 625 HKEY hkRegistration = NULL;
604 LPWSTR sczPublisher = NULL; 626 LPWSTR sczPublisher = NULL;
605 627
628 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type can't be NONE");
629
606 LogId(REPORT_VERBOSE, MSG_SESSION_BEGIN, pRegistration->sczRegistrationKey, dwRegistrationOptions, LoggingBoolToString(pRegistration->fDisableResume)); 630 LogId(REPORT_VERBOSE, MSG_SESSION_BEGIN, pRegistration->sczRegistrationKey, dwRegistrationOptions, LoggingBoolToString(pRegistration->fDisableResume));
607 631
608 // Cache bundle executable. 632 // Cache bundle executable.
@@ -668,7 +692,7 @@ extern "C" HRESULT RegistrationSessionBegin(
668 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON); 692 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON);
669 693
670 // update display name 694 // update display name
671 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration); 695 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
672 ExitOnFailure(hr, "Failed to update name and publisher."); 696 ExitOnFailure(hr, "Failed to update name and publisher.");
673 697
674 // DisplayVersion: provided by UI 698 // DisplayVersion: provided by UI
@@ -841,12 +865,15 @@ LExit:
841*******************************************************************/ 865*******************************************************************/
842extern "C" HRESULT RegistrationSessionResume( 866extern "C" HRESULT RegistrationSessionResume(
843 __in BURN_REGISTRATION* pRegistration, 867 __in BURN_REGISTRATION* pRegistration,
844 __in BURN_VARIABLES* pVariables 868 __in BURN_VARIABLES* pVariables,
869 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
845 ) 870 )
846{ 871{
847 HRESULT hr = S_OK; 872 HRESULT hr = S_OK;
848 HKEY hkRegistration = NULL; 873 HKEY hkRegistration = NULL;
849 874
875 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type can't be NONE");
876
850 // open registration key 877 // open registration key
851 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration); 878 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration);
852 ExitOnFailure(hr, "Failed to open registration key."); 879 ExitOnFailure(hr, "Failed to open registration key.");
@@ -856,7 +883,7 @@ extern "C" HRESULT RegistrationSessionResume(
856 ExitOnFailure(hr, "Failed to update resume mode."); 883 ExitOnFailure(hr, "Failed to update resume mode.");
857 884
858 // update display name 885 // update display name
859 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration); 886 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
860 ExitOnFailure(hr, "Failed to update name and publisher."); 887 ExitOnFailure(hr, "Failed to update name and publisher.");
861 888
862LExit: 889LExit:
@@ -876,7 +903,8 @@ extern "C" HRESULT RegistrationSessionEnd(
876 __in BURN_PACKAGES* pPackages, 903 __in BURN_PACKAGES* pPackages,
877 __in BURN_RESUME_MODE resumeMode, 904 __in BURN_RESUME_MODE resumeMode,
878 __in BOOTSTRAPPER_APPLY_RESTART restart, 905 __in BOOTSTRAPPER_APPLY_RESTART restart,
879 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction 906 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
907 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
880 ) 908 )
881{ 909{
882 HRESULT hr = S_OK; 910 HRESULT hr = S_OK;
@@ -884,8 +912,6 @@ extern "C" HRESULT RegistrationSessionEnd(
884 HKEY hkRebootRequired = NULL; 912 HKEY hkRebootRequired = NULL;
885 HKEY hkRegistration = NULL; 913 HKEY hkRegistration = NULL;
886 914
887 LogId(REPORT_STANDARD, MSG_SESSION_END, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingRestartToString(restart), LoggingBoolToString(pRegistration->fDisableResume));
888
889 // If a restart is required for any reason, write a volatile registry key to track of 915 // If a restart is required for any reason, write a volatile registry key to track of
890 // of that fact until the reboot has taken place. 916 // of that fact until the reboot has taken place.
891 if (BOOTSTRAPPER_APPLY_RESTART_NONE != restart) 917 if (BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
@@ -910,6 +936,8 @@ extern "C" HRESULT RegistrationSessionEnd(
910 // If no resume mode, then remove the bundle registration. 936 // If no resume mode, then remove the bundle registration.
911 if (BURN_RESUME_MODE_NONE == resumeMode) 937 if (BURN_RESUME_MODE_NONE == resumeMode)
912 { 938 {
939 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE");
940
913 // If we just registered the bundle dependency but something went wrong and caused us to not 941 // If we just registered the bundle dependency but something went wrong and caused us to not
914 // keep the bundle registration (like rollback) or we are supposed to unregister the bundle 942 // keep the bundle registration (like rollback) or we are supposed to unregister the bundle
915 // dependency when unregistering the bundle, do so. 943 // dependency when unregistering the bundle, do so.
@@ -939,9 +967,15 @@ extern "C" HRESULT RegistrationSessionEnd(
939 } 967 }
940 else // the mode needs to be updated so open the registration key. 968 else // the mode needs to be updated so open the registration key.
941 { 969 {
970 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type must not be NONE if resume mode is not NONE");
971
942 // Open registration key. 972 // Open registration key.
943 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration); 973 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration);
944 ExitOnFailure(hr, "Failed to open registration key."); 974 ExitOnFailure(hr, "Failed to open registration key.");
975
976 // update display name
977 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
978 ExitOnFailure(hr, "Failed to update name and publisher.");
945 } 979 }
946 980
947 // Update resume mode. 981 // Update resume mode.
@@ -1133,44 +1167,69 @@ LExit:
1133static HRESULT GetBundleManufacturer( 1167static HRESULT GetBundleManufacturer(
1134 __in BURN_REGISTRATION* pRegistration, 1168 __in BURN_REGISTRATION* pRegistration,
1135 __in BURN_VARIABLES* pVariables, 1169 __in BURN_VARIABLES* pVariables,
1136 __out LPWSTR* psczBundleManufacturer 1170 __out_z LPWSTR* psczBundleManufacturer
1137 ) 1171 )
1138{ 1172{
1139 HRESULT hr = S_OK; 1173 HRESULT hr = S_OK;
1140 LPCWSTR wzPublisher = pRegistration->sczPublisher ? pRegistration->sczPublisher : L""; 1174 LPCWSTR wzPublisher = pRegistration->sczPublisher ? pRegistration->sczPublisher : L"";
1141 1175
1142 hr = VariableGetString(pVariables, BURN_BUNDLE_MANUFACTURER, psczBundleManufacturer); 1176 hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_MANUFACTURER, wzPublisher, psczBundleManufacturer);
1143 if (E_NOTFOUND == hr)
1144 {
1145 hr = VariableSetString(pVariables, BURN_BUNDLE_MANUFACTURER, wzPublisher, FALSE, FALSE);
1146 ExitOnFailure(hr, "Failed to set bundle manufacturer.");
1147
1148 hr = StrAllocString(psczBundleManufacturer, wzPublisher, 0);
1149 }
1150 ExitOnFailure(hr, "Failed to get bundle manufacturer."); 1177 ExitOnFailure(hr, "Failed to get bundle manufacturer.");
1151 1178
1152LExit: 1179LExit:
1153 return hr; 1180 return hr;
1154} 1181}
1155 1182
1183static HRESULT GetBundleInProgressName(
1184 __in BURN_REGISTRATION* pRegistration,
1185 __in BURN_VARIABLES* pVariables,
1186 __out_z LPWSTR* psczInProgressBundleName
1187 )
1188{
1189 HRESULT hr = S_OK;
1190 LPCWSTR wzInProgressDisplayName = pRegistration->sczInProgressDisplayName ? pRegistration->sczInProgressDisplayName : L"";
1191
1192 hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_INPROGRESS_NAME, wzInProgressDisplayName, psczInProgressBundleName);
1193 ExitOnFailure(hr, "Failed to ensure in-progress bundle name.");
1194
1195LExit:
1196 return hr;
1197}
1198
1156static HRESULT GetBundleName( 1199static HRESULT GetBundleName(
1157 __in BURN_REGISTRATION* pRegistration, 1200 __in BURN_REGISTRATION* pRegistration,
1158 __in BURN_VARIABLES* pVariables, 1201 __in BURN_VARIABLES* pVariables,
1159 __out LPWSTR* psczBundleName 1202 __out_z LPWSTR* psczBundleName
1160 ) 1203 )
1161{ 1204{
1162 HRESULT hr = S_OK; 1205 HRESULT hr = S_OK;
1163 LPCWSTR wzDisplayName = pRegistration->sczDisplayName ? pRegistration->sczDisplayName : L""; 1206 LPCWSTR wzDisplayName = pRegistration->sczDisplayName ? pRegistration->sczDisplayName : L"";
1164 1207
1165 hr = VariableGetString(pVariables, BURN_BUNDLE_NAME, psczBundleName); 1208 hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_NAME, wzDisplayName, psczBundleName);
1209 ExitOnFailure(hr, "Failed to ensure bundle name.");
1210
1211LExit:
1212 return hr;
1213}
1214
1215static HRESULT EnsureRegistrationVariable(
1216 __in BURN_VARIABLES* pVariables,
1217 __in_z LPCWSTR wzVariable,
1218 __in_z LPCWSTR wzDefaultValue,
1219 __out_z LPWSTR* psczValue
1220 )
1221{
1222 HRESULT hr = S_OK;
1223
1224 hr = VariableGetString(pVariables, wzVariable, psczValue);
1166 if (E_NOTFOUND == hr) 1225 if (E_NOTFOUND == hr)
1167 { 1226 {
1168 hr = VariableSetString(pVariables, BURN_BUNDLE_NAME, wzDisplayName, FALSE, FALSE); 1227 hr = VariableSetString(pVariables, wzVariable, wzDefaultValue, FALSE, FALSE);
1169 ExitOnFailure(hr, "Failed to set bundle name."); 1228 ExitOnFailure(hr, "Failed to set registration variable.");
1170 1229
1171 hr = StrAllocString(psczBundleName, wzDisplayName, 0); 1230 hr = StrAllocString(psczValue, wzDefaultValue, 0);
1172 } 1231 }
1173 ExitOnFailure(hr, "Failed to get bundle name."); 1232 ExitOnFailure(hr, "Failed to get registration variable.");
1174 1233
1175LExit: 1234LExit:
1176 return hr; 1235 return hr;
@@ -1584,15 +1643,26 @@ LExit:
1584static HRESULT UpdateBundleNameRegistration( 1643static HRESULT UpdateBundleNameRegistration(
1585 __in BURN_REGISTRATION* pRegistration, 1644 __in BURN_REGISTRATION* pRegistration,
1586 __in BURN_VARIABLES* pVariables, 1645 __in BURN_VARIABLES* pVariables,
1587 __in HKEY hkRegistration 1646 __in HKEY hkRegistration,
1647 __in BOOL fInProgressRegistration
1588 ) 1648 )
1589{ 1649{
1590 HRESULT hr = S_OK; 1650 HRESULT hr = S_OK;
1591 LPWSTR sczDisplayName = NULL; 1651 LPWSTR sczDisplayName = NULL;
1592 1652
1593 // DisplayName: provided by UI 1653 if (fInProgressRegistration)
1594 hr = GetBundleName(pRegistration, pVariables, &sczDisplayName); 1654 {
1595 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME, SUCCEEDED(hr) ? sczDisplayName : pRegistration->sczDisplayName); 1655 hr = GetBundleInProgressName(pRegistration, pVariables, &sczDisplayName);
1656 ExitOnFailure(hr, "Failed to get bundle in-progress name.");
1657 }
1658
1659 if (!sczDisplayName || !*sczDisplayName)
1660 {
1661 hr = GetBundleName(pRegistration, pVariables, &sczDisplayName);
1662 ExitOnFailure(hr, "Failed to get bundle name.");
1663 }
1664
1665 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME, sczDisplayName);
1596 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME); 1666 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME);
1597 1667
1598LExit: 1668LExit:
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h
index 6d8a6d2a..936e5966 100644
--- a/src/burn/engine/registration.h
+++ b/src/burn/engine/registration.h
@@ -123,6 +123,7 @@ typedef struct _BURN_REGISTRATION
123 123
124 // ARP registration 124 // ARP registration
125 LPWSTR sczDisplayName; 125 LPWSTR sczDisplayName;
126 LPWSTR sczInProgressDisplayName;
126 LPWSTR sczDisplayVersion; 127 LPWSTR sczDisplayVersion;
127 LPWSTR sczPublisher; 128 LPWSTR sczPublisher;
128 LPWSTR sczHelpLink; 129 LPWSTR sczHelpLink;
@@ -190,11 +191,13 @@ HRESULT RegistrationSessionBegin(
190 __in BURN_VARIABLES* pVariables, 191 __in BURN_VARIABLES* pVariables,
191 __in DWORD dwRegistrationOptions, 192 __in DWORD dwRegistrationOptions,
192 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 193 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
193 __in DWORD64 qwEstimatedSize 194 __in DWORD64 qwEstimatedSize,
195 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
194 ); 196 );
195HRESULT RegistrationSessionResume( 197HRESULT RegistrationSessionResume(
196 __in BURN_REGISTRATION* pRegistration, 198 __in BURN_REGISTRATION* pRegistration,
197 __in BURN_VARIABLES* pVariables 199 __in BURN_VARIABLES* pVariables,
200 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
198 ); 201 );
199HRESULT RegistrationSessionEnd( 202HRESULT RegistrationSessionEnd(
200 __in BURN_REGISTRATION* pRegistration, 203 __in BURN_REGISTRATION* pRegistration,
@@ -202,7 +205,8 @@ HRESULT RegistrationSessionEnd(
202 __in BURN_PACKAGES* pPackages, 205 __in BURN_PACKAGES* pPackages,
203 __in BURN_RESUME_MODE resumeMode, 206 __in BURN_RESUME_MODE resumeMode,
204 __in BOOTSTRAPPER_APPLY_RESTART restart, 207 __in BOOTSTRAPPER_APPLY_RESTART restart,
205 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction 208 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
209 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
206 ); 210 );
207HRESULT RegistrationSaveState( 211HRESULT RegistrationSaveState(
208 __in BURN_REGISTRATION* pRegistration, 212 __in BURN_REGISTRATION* pRegistration,
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index 5a54f26e..07f4b831 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -2119,7 +2119,8 @@ EXTERN_C BAAPI UserExperienceOnProgress(
2119} 2119}
2120 2120
2121EXTERN_C BAAPI UserExperienceOnRegisterBegin( 2121EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2122 __in BURN_USER_EXPERIENCE* pUserExperience 2122 __in BURN_USER_EXPERIENCE* pUserExperience,
2123 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
2123 ) 2124 )
2124{ 2125{
2125 HRESULT hr = S_OK; 2126 HRESULT hr = S_OK;
@@ -2127,8 +2128,10 @@ EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2127 BA_ONREGISTERBEGIN_RESULTS results = { }; 2128 BA_ONREGISTERBEGIN_RESULTS results = { };
2128 2129
2129 args.cbSize = sizeof(args); 2130 args.cbSize = sizeof(args);
2131 args.recommendedRegistrationType = *pRegistrationType;
2130 2132
2131 results.cbSize = sizeof(results); 2133 results.cbSize = sizeof(results);
2134 results.registrationType = *pRegistrationType;
2132 2135
2133 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, &results); 2136 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, &results);
2134 ExitOnFailure(hr, "BA OnRegisterBegin failed."); 2137 ExitOnFailure(hr, "BA OnRegisterBegin failed.");
@@ -2137,6 +2140,10 @@ EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2137 { 2140 {
2138 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); 2141 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
2139 } 2142 }
2143 else if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType)
2144 {
2145 *pRegistrationType = results.registrationType;
2146 }
2140 2147
2141LExit: 2148LExit:
2142 return hr; 2149 return hr;
@@ -2316,7 +2323,7 @@ LExit:
2316 2323
2317EXTERN_C BAAPI UserExperienceOnUnregisterBegin( 2324EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
2318 __in BURN_USER_EXPERIENCE* pUserExperience, 2325 __in BURN_USER_EXPERIENCE* pUserExperience,
2319 __inout BOOL* pfKeepRegistration 2326 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
2320 ) 2327 )
2321{ 2328{
2322 HRESULT hr = S_OK; 2329 HRESULT hr = S_OK;
@@ -2324,16 +2331,17 @@ EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
2324 BA_ONUNREGISTERBEGIN_RESULTS results = { }; 2331 BA_ONUNREGISTERBEGIN_RESULTS results = { };
2325 2332
2326 args.cbSize = sizeof(args); 2333 args.cbSize = sizeof(args);
2327 args.fKeepRegistration = *pfKeepRegistration; 2334 args.recommendedRegistrationType = *pRegistrationType;
2328 2335
2329 results.cbSize = sizeof(results); 2336 results.cbSize = sizeof(results);
2337 results.registrationType = *pRegistrationType;
2330 2338
2331 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, &results); 2339 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, &results);
2332 ExitOnFailure(hr, "BA OnUnregisterBegin failed."); 2340 ExitOnFailure(hr, "BA OnUnregisterBegin failed.");
2333 2341
2334 if (!args.fKeepRegistration && results.fForceKeepRegistration) 2342 if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType)
2335 { 2343 {
2336 *pfKeepRegistration = TRUE; 2344 *pRegistrationType = results.registrationType;
2337 } 2345 }
2338 2346
2339LExit: 2347LExit:
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index f2453dca..56bc3239 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -486,7 +486,8 @@ BAAPI UserExperienceOnProgress(
486 __in DWORD dwOverallPercentage 486 __in DWORD dwOverallPercentage
487 ); 487 );
488BAAPI UserExperienceOnRegisterBegin( 488BAAPI UserExperienceOnRegisterBegin(
489 __in BURN_USER_EXPERIENCE* pUserExperience 489 __in BURN_USER_EXPERIENCE* pUserExperience,
490 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
490 ); 491 );
491BAAPI UserExperienceOnRegisterComplete( 492BAAPI UserExperienceOnRegisterComplete(
492 __in BURN_USER_EXPERIENCE* pUserExperience, 493 __in BURN_USER_EXPERIENCE* pUserExperience,
@@ -522,7 +523,7 @@ BAAPI UserExperienceOnSystemShutdown(
522 ); 523 );
523BAAPI UserExperienceOnUnregisterBegin( 524BAAPI UserExperienceOnUnregisterBegin(
524 __in BURN_USER_EXPERIENCE* pUserExperience, 525 __in BURN_USER_EXPERIENCE* pUserExperience,
525 __inout BOOL* pfKeepRegistration 526 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
526 ); 527 );
527BAAPI UserExperienceOnUnregisterComplete( 528BAAPI UserExperienceOnUnregisterComplete(
528 __in BURN_USER_EXPERIENCE* pUserExperience, 529 __in BURN_USER_EXPERIENCE* pUserExperience,
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 7b126f61..96bdb2bf 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -112,7 +112,7 @@ namespace Bootstrapper
112 TestThrowOnFailure(hr, L"Failed to get current process path."); 112 TestThrowOnFailure(hr, L"Failed to get current process path.");
113 113
114 // write registration 114 // write registration
115 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); 115 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
116 TestThrowOnFailure(hr, L"Failed to register bundle."); 116 TestThrowOnFailure(hr, L"Failed to register bundle.");
117 117
118 // verify that registration was created 118 // verify that registration was created
@@ -123,7 +123,7 @@ namespace Bootstrapper
123 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr))); 123 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)));
124 124
125 // end session 125 // end session
126 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); 126 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
127 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 127 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
128 128
129 // verify that registration was removed 129 // verify that registration was removed
@@ -178,7 +178,7 @@ namespace Bootstrapper
178 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 178 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
179 L" </UX>" 179 L" </UX>"
180 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 180 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
181 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />" 181 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' InProgressDisplayName='Product1 Installation' DisplayVersion='1.0.0.0' />"
182 L" </Registration>" 182 L" </Registration>"
183 L"</Bundle>"; 183 L"</Bundle>";
184 184
@@ -205,15 +205,16 @@ namespace Bootstrapper
205 // 205 //
206 206
207 // write registration 207 // write registration
208 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); 208 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
209 TestThrowOnFailure(hr, L"Failed to register bundle."); 209 TestThrowOnFailure(hr, L"Failed to register bundle.");
210 210
211 // verify that registration was created 211 // verify that registration was created
212 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
212 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 213 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
213 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 214 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
214 215
215 // complete registration 216 // complete registration
216 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); 217 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
217 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 218 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
218 219
219 // verify that registration was updated 220 // verify that registration was updated
@@ -226,7 +227,7 @@ namespace Bootstrapper
226 // 227 //
227 228
228 // write registration 229 // write registration
229 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0); 230 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
230 TestThrowOnFailure(hr, L"Failed to register bundle."); 231 TestThrowOnFailure(hr, L"Failed to register bundle.");
231 232
232 // verify that registration was updated 233 // verify that registration was updated
@@ -235,7 +236,7 @@ namespace Bootstrapper
235 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 236 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
236 237
237 // delete registration 238 // delete registration
238 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); 239 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
239 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 240 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
240 241
241 // verify that registration was removed 242 // verify that registration was removed
@@ -316,7 +317,7 @@ namespace Bootstrapper
316 // 317 //
317 318
318 // write registration 319 // write registration
319 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); 320 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
320 TestThrowOnFailure(hr, L"Failed to register bundle."); 321 TestThrowOnFailure(hr, L"Failed to register bundle.");
321 322
322 // verify that registration was created 323 // verify that registration was created
@@ -324,10 +325,11 @@ namespace Bootstrapper
324 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 325 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
325 326
326 // complete registration 327 // complete registration
327 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); 328 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
328 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 329 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
329 330
330 // verify that registration variables were updated 331 // verify that registration variables were updated
332 Assert::Equal<String^>(gcnew String(L"Product1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
331 registration.fInstalled = TRUE; 333 registration.fInstalled = TRUE;
332 334
333 hr = RegistrationSetVariables(&registration, &variables); 335 hr = RegistrationSetVariables(&registration, &variables);
@@ -344,7 +346,7 @@ namespace Bootstrapper
344 // 346 //
345 347
346 // delete registration 348 // delete registration
347 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); 349 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
348 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 350 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
349 351
350 // verify that registration was removed 352 // verify that registration was removed
@@ -427,7 +429,7 @@ namespace Bootstrapper
427 // 429 //
428 430
429 // write registration 431 // write registration
430 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); 432 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
431 TestThrowOnFailure(hr, L"Failed to register bundle."); 433 TestThrowOnFailure(hr, L"Failed to register bundle.");
432 434
433 // verify that registration was created 435 // verify that registration was created
@@ -435,7 +437,7 @@ namespace Bootstrapper
435 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 437 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
436 438
437 // finish registration 439 // finish registration
438 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); 440 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
439 TestThrowOnFailure(hr, L"Failed to register bundle."); 441 TestThrowOnFailure(hr, L"Failed to register bundle.");
440 442
441 // verify that registration was updated 443 // verify that registration was updated
@@ -460,7 +462,7 @@ namespace Bootstrapper
460 // 462 //
461 463
462 // write registration 464 // write registration
463 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0); 465 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
464 TestThrowOnFailure(hr, L"Failed to register bundle."); 466 TestThrowOnFailure(hr, L"Failed to register bundle.");
465 467
466 // verify that registration was updated 468 // verify that registration was updated
@@ -468,7 +470,7 @@ namespace Bootstrapper
468 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 470 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
469 471
470 // delete registration 472 // delete registration
471 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); 473 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
472 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 474 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
473 475
474 // verify that registration was removed 476 // verify that registration was removed
@@ -560,7 +562,7 @@ namespace Bootstrapper
560 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType); 562 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType);
561 563
562 // begin session 564 // begin session
563 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); 565 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
564 TestThrowOnFailure(hr, L"Failed to register bundle."); 566 TestThrowOnFailure(hr, L"Failed to register bundle.");
565 567
566 hr = RegistrationSaveState(&registration, rgbData, sizeof(rgbData)); 568 hr = RegistrationSaveState(&registration, rgbData, sizeof(rgbData));
@@ -573,7 +575,7 @@ namespace Bootstrapper
573 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType); 575 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType);
574 576
575 // suspend session 577 // suspend session
576 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); 578 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
577 TestThrowOnFailure(hr, L"Failed to suspend session."); 579 TestThrowOnFailure(hr, L"Failed to suspend session.");
578 580
579 // verify that run key was removed 581 // verify that run key was removed
@@ -593,14 +595,14 @@ namespace Bootstrapper
593 Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData))); 595 Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData)));
594 596
595 // write active resume mode 597 // write active resume mode
596 hr = RegistrationSessionResume(&registration, &variables); 598 hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
597 TestThrowOnFailure(hr, L"Failed to write active resume mode."); 599 TestThrowOnFailure(hr, L"Failed to write active resume mode.");
598 600
599 // verify that run key was put back 601 // verify that run key was put back
600 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 602 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
601 603
602 // end session 604 // end session
603 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); 605 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
604 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 606 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
605 607
606 // read resume type after session 608 // read resume type after session