aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-02 18:09:58 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commitfd8c2b0899bfbce07386af245c04eb21dc01cbdf (patch)
tree33d928124b0028729916189ddb9f239a9574c75d
parent39725a1a6d1c72a6748bd3c306af32bcae6dbf8f (diff)
downloadwix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.tar.gz
wix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.tar.bz2
wix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.zip
Update the logic for determining when the bundle should be registered.
The basic rule is that if a non-permanent package is present at the end of the chain, then the bundle should be registered. If no non-permanent packages are present at the end of the chain, then the bundle should not be registered. This required tracking what actually happened with each package during Apply. Include cache status in registration calculation. Include dependency ref-counting when determining whether the bundle should be registered.
-rw-r--r--src/engine/apply.cpp247
-rw-r--r--src/engine/apply.h4
-rw-r--r--src/engine/core.cpp18
-rw-r--r--src/engine/dependency.cpp29
-rw-r--r--src/engine/detect.cpp2
-rw-r--r--src/engine/engine.mc19
-rw-r--r--src/engine/exeengine.cpp30
-rw-r--r--src/engine/exeengine.h4
-rw-r--r--src/engine/logging.cpp25
-rw-r--r--src/engine/logging.h5
-rw-r--r--src/engine/msiengine.cpp41
-rw-r--r--src/engine/msiengine.h5
-rw-r--r--src/engine/mspengine.cpp109
-rw-r--r--src/engine/mspengine.h8
-rw-r--r--src/engine/msuengine.cpp30
-rw-r--r--src/engine/msuengine.h4
-rw-r--r--src/engine/package.cpp1
-rw-r--r--src/engine/package.h18
-rw-r--r--src/engine/plan.cpp192
-rw-r--r--src/engine/plan.h18
-rw-r--r--src/test/BurnUnitTest/BurnTestFixture.h2
-rw-r--r--src/test/BurnUnitTest/PlanTest.cpp260
22 files changed, 804 insertions, 267 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp
index 76831461..8d2f5757 100644
--- a/src/engine/apply.cpp
+++ b/src/engine/apply.cpp
@@ -46,6 +46,10 @@ static HRESULT WINAPI AuthenticationRequired(
46 __out BOOL* pfRetry 46 __out BOOL* pfRetry
47 ); 47 );
48 48
49static void CalculateKeepRegistration(
50 __in BURN_ENGINE_STATE* pEngineState,
51 __inout BOOL* pfKeepRegistration
52 );
49static HRESULT ExecuteDependentRegistrationActions( 53static HRESULT ExecuteDependentRegistrationActions(
50 __in HANDLE hPipe, 54 __in HANDLE hPipe,
51 __in const BURN_REGISTRATION* pRegistration, 55 __in const BURN_REGISTRATION* pRegistration,
@@ -141,7 +145,6 @@ static HRESULT DoExecuteAction(
141 __in BURN_EXECUTE_CONTEXT* pContext, 145 __in BURN_EXECUTE_CONTEXT* pContext,
142 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 146 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
143 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, 147 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
144 __out BOOL* pfKeepRegistration,
145 __out BOOL* pfSuspend, 148 __out BOOL* pfSuspend,
146 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 149 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
147 ); 150 );
@@ -149,7 +152,6 @@ static HRESULT DoRollbackActions(
149 __in BURN_ENGINE_STATE* pEngineState, 152 __in BURN_ENGINE_STATE* pEngineState,
150 __in BURN_EXECUTE_CONTEXT* pContext, 153 __in BURN_EXECUTE_CONTEXT* pContext,
151 __in DWORD dwCheckpoint, 154 __in DWORD dwCheckpoint,
152 __out BOOL* pfKeepRegistration,
153 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 155 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
154 ); 156 );
155static HRESULT ExecuteExePackage( 157static HRESULT ExecuteExePackage(
@@ -165,6 +167,7 @@ static HRESULT ExecuteMsiPackage(
165 __in BURN_ENGINE_STATE* pEngineState, 167 __in BURN_ENGINE_STATE* pEngineState,
166 __in BURN_EXECUTE_ACTION* pExecuteAction, 168 __in BURN_EXECUTE_ACTION* pExecuteAction,
167 __in BURN_EXECUTE_CONTEXT* pContext, 169 __in BURN_EXECUTE_CONTEXT* pContext,
170 __in BOOL fInsideMsiTransaction,
168 __in BOOL fRollback, 171 __in BOOL fRollback,
169 __out BOOL* pfRetry, 172 __out BOOL* pfRetry,
170 __out BOOL* pfSuspend, 173 __out BOOL* pfSuspend,
@@ -174,6 +177,7 @@ static HRESULT ExecuteMspPackage(
174 __in BURN_ENGINE_STATE* pEngineState, 177 __in BURN_ENGINE_STATE* pEngineState,
175 __in BURN_EXECUTE_ACTION* pExecuteAction, 178 __in BURN_EXECUTE_ACTION* pExecuteAction,
176 __in BURN_EXECUTE_CONTEXT* pContext, 179 __in BURN_EXECUTE_CONTEXT* pContext,
180 __in BOOL fInsideMsiTransaction,
177 __in BOOL fRollback, 181 __in BOOL fRollback,
178 __out BOOL* pfRetry, 182 __out BOOL* pfRetry,
179 __out BOOL* pfSuspend, 183 __out BOOL* pfSuspend,
@@ -214,6 +218,10 @@ static HRESULT ExecuteMsiRollbackTransaction(
214 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, 218 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary,
215 __in BURN_EXECUTE_CONTEXT* pContext 219 __in BURN_EXECUTE_CONTEXT* pContext
216 ); 220 );
221static void ResetTransactionRegistrationState(
222 __in BURN_ENGINE_STATE* pEngineState,
223 __in BOOL fCommit
224 );
217static HRESULT CleanPackage( 225static HRESULT CleanPackage(
218 __in HANDLE hElevatedPipe, 226 __in HANDLE hElevatedPipe,
219 __in BURN_PACKAGE* pPackage 227 __in BURN_PACKAGE* pPackage
@@ -282,6 +290,7 @@ extern "C" void ApplyReset(
282 { 290 {
283 BURN_PACKAGE* pPackage = pPackages->rgPackages + i; 291 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
284 pPackage->hrCacheResult = S_OK; 292 pPackage->hrCacheResult = S_OK;
293 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
285 } 294 }
286} 295}
287 296
@@ -380,13 +389,15 @@ LExit:
380extern "C" HRESULT ApplyUnregister( 389extern "C" HRESULT ApplyUnregister(
381 __in BURN_ENGINE_STATE* pEngineState, 390 __in BURN_ENGINE_STATE* pEngineState,
382 __in BOOL fFailedOrRollback, 391 __in BOOL fFailedOrRollback,
383 __in BOOL fKeepRegistration,
384 __in BOOL fSuspend, 392 __in BOOL fSuspend,
385 __in BOOTSTRAPPER_APPLY_RESTART restart 393 __in BOOTSTRAPPER_APPLY_RESTART restart
386 ) 394 )
387{ 395{
388 HRESULT hr = S_OK; 396 HRESULT hr = S_OK;
389 BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE; 397 BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE;
398 BOOL fKeepRegistration = pEngineState->plan.fDisallowRemoval;
399
400 CalculateKeepRegistration(pEngineState, &fKeepRegistration);
390 401
391 hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience); 402 hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience);
392 ExitOnRootFailure(hr, "BA aborted unregister begin."); 403 ExitOnRootFailure(hr, "BA aborted unregister begin.");
@@ -443,7 +454,7 @@ extern "C" HRESULT ApplyCache(
443 __in BURN_PLAN* pPlan, 454 __in BURN_PLAN* pPlan,
444 __in HANDLE hPipe, 455 __in HANDLE hPipe,
445 __inout DWORD* pcOverallProgressTicks, 456 __inout DWORD* pcOverallProgressTicks,
446 __out BOOL* pfRollback 457 __inout BOOL* pfRollback
447 ) 458 )
448{ 459{
449 HRESULT hr = S_OK; 460 HRESULT hr = S_OK;
@@ -732,7 +743,6 @@ extern "C" HRESULT ApplyExecute(
732 __in BURN_ENGINE_STATE* pEngineState, 743 __in BURN_ENGINE_STATE* pEngineState,
733 __in_opt HANDLE hCacheThread, 744 __in_opt HANDLE hCacheThread,
734 __inout DWORD* pcOverallProgressTicks, 745 __inout DWORD* pcOverallProgressTicks,
735 __inout BOOL* pfKeepRegistration,
736 __out BOOL* pfRollback, 746 __out BOOL* pfRollback,
737 __out BOOL* pfSuspend, 747 __out BOOL* pfSuspend,
738 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 748 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
@@ -779,7 +789,7 @@ extern "C" HRESULT ApplyExecute(
779 } 789 }
780 790
781 // Execute the action. 791 // Execute the action.
782 hr = DoExecuteAction(pEngineState, pExecuteAction, hCacheThread, &context, &pRollbackBoundary, &pCheckpoint, pfKeepRegistration, pfSuspend, pRestart); 792 hr = DoExecuteAction(pEngineState, pExecuteAction, hCacheThread, &context, &pRollbackBoundary, &pCheckpoint, pfSuspend, pRestart);
783 793
784 if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) 794 if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart)
785 { 795 {
@@ -821,7 +831,7 @@ extern "C" HRESULT ApplyExecute(
821 // The action failed, roll back to previous rollback boundary. 831 // The action failed, roll back to previous rollback boundary.
822 if (pCheckpoint) 832 if (pCheckpoint)
823 { 833 {
824 hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pfKeepRegistration, pRestart); 834 hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pRestart);
825 IgnoreRollbackError(hrRollback, "Failed rollback actions"); 835 IgnoreRollbackError(hrRollback, "Failed rollback actions");
826 } 836 }
827 837
@@ -855,14 +865,46 @@ extern "C" void ApplyClean(
855 for (DWORD i = 0; i < pPlan->cCleanActions; ++i) 865 for (DWORD i = 0; i < pPlan->cCleanActions; ++i)
856 { 866 {
857 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i; 867 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i;
868 BURN_PACKAGE* pPackage = pCleanAction->pPackage;
858 869
859 hr = CleanPackage(hPipe, pCleanAction->pPackage); 870 hr = CleanPackage(hPipe, pPackage);
860 } 871 }
861} 872}
862 873
863 874
864// internal helper functions 875// internal helper functions
865 876
877static void CalculateKeepRegistration(
878 __in BURN_ENGINE_STATE* pEngineState,
879 __inout BOOL* pfKeepRegistration
880 )
881{
882 LogId(REPORT_STANDARD, MSG_POST_APPLY_CALCULATE_REGISTRATION);
883
884 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
885 {
886 BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
887
888 LogId(REPORT_STANDARD, MSG_POST_APPLY_PACKAGE, pPackage->sczId, LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
889
890 if (!pPackage->fCanAffectRegistration)
891 {
892 continue;
893 }
894
895 if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
896 {
897 MspEngineFinalizeInstallRegistrationState(pPackage);
898 }
899
900 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState ||
901 BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState)
902 {
903 *pfKeepRegistration = TRUE;
904 }
905 }
906}
907
866static HRESULT ExecuteDependentRegistrationActions( 908static HRESULT ExecuteDependentRegistrationActions(
867 __in HANDLE hPipe, 909 __in HANDLE hPipe,
868 __in const BURN_REGISTRATION* pRegistration, 910 __in const BURN_REGISTRATION* pRegistration,
@@ -1255,6 +1297,15 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1255 LARGE_INTEGER liContainerOrPayloadSize = { }; 1297 LARGE_INTEGER liContainerOrPayloadSize = { };
1256 LARGE_INTEGER liZero = { }; 1298 LARGE_INTEGER liZero = { };
1257 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; 1299 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { };
1300 BOOL fCanAffectRegistration = FALSE;
1301
1302 if (!wzLayoutDirectory)
1303 {
1304 Assert(!pContainer);
1305 Assert(pPackage);
1306
1307 fCanAffectRegistration = pPackage->fCanAffectRegistration;
1308 }
1258 1309
1259 liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize; 1310 liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize;
1260 1311
@@ -1297,9 +1348,6 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1297 } 1348 }
1298 else // complete the payload. 1349 else // complete the payload.
1299 { 1350 {
1300 Assert(!pContainer);
1301 Assert(pPackage);
1302
1303 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); 1351 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1304 } 1352 }
1305 1353
@@ -1307,6 +1355,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1307 // will get. 1355 // will get.
1308 if (SUCCEEDED(hr)) 1356 if (SUCCEEDED(hr))
1309 { 1357 {
1358 if (fCanAffectRegistration)
1359 {
1360 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1361 }
1362
1310 CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, &progress); 1363 CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, &progress);
1311 if (progress.fCancel) 1364 if (progress.fCancel)
1312 { 1365 {
@@ -1639,7 +1692,6 @@ static HRESULT DoExecuteAction(
1639 __in BURN_EXECUTE_CONTEXT* pContext, 1692 __in BURN_EXECUTE_CONTEXT* pContext,
1640 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 1693 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
1641 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, 1694 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
1642 __out BOOL* pfKeepRegistration,
1643 __out BOOL* pfSuspend, 1695 __out BOOL* pfSuspend,
1644 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 1696 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1645 ) 1697 )
@@ -1651,11 +1703,14 @@ static HRESULT DoExecuteAction(
1651 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; 1703 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
1652 BOOL fRetry = FALSE; 1704 BOOL fRetry = FALSE;
1653 BOOL fStopWusaService = FALSE; 1705 BOOL fStopWusaService = FALSE;
1706 BOOL fInsideMsiTransaction = FALSE;
1654 1707
1655 pContext->fRollback = FALSE; 1708 pContext->fRollback = FALSE;
1656 1709
1657 do 1710 do
1658 { 1711 {
1712 fInsideMsiTransaction = *ppRollbackBoundary && (*ppRollbackBoundary)->fActiveTransaction;
1713
1659 switch (pExecuteAction->type) 1714 switch (pExecuteAction->type)
1660 { 1715 {
1661 case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: 1716 case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT:
@@ -1695,12 +1750,12 @@ static HRESULT DoExecuteAction(
1695 break; 1750 break;
1696 1751
1697 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: 1752 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
1698 hr = ExecuteMsiPackage(pEngineState, pExecuteAction, pContext, FALSE, &fRetry, pfSuspend, &restart); 1753 hr = ExecuteMsiPackage(pEngineState, pExecuteAction, pContext, fInsideMsiTransaction, FALSE, &fRetry, pfSuspend, &restart);
1699 ExitOnFailure(hr, "Failed to execute MSI package."); 1754 ExitOnFailure(hr, "Failed to execute MSI package.");
1700 break; 1755 break;
1701 1756
1702 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: 1757 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
1703 hr = ExecuteMspPackage(pEngineState, pExecuteAction, pContext, FALSE, &fRetry, pfSuspend, &restart); 1758 hr = ExecuteMspPackage(pEngineState, pExecuteAction, pContext, fInsideMsiTransaction, FALSE, &fRetry, pfSuspend, &restart);
1704 ExitOnFailure(hr, "Failed to execute MSP package."); 1759 ExitOnFailure(hr, "Failed to execute MSP package.");
1705 break; 1760 break;
1706 1761
@@ -1720,8 +1775,6 @@ static HRESULT DoExecuteAction(
1720 ExitOnFailure(hr, "Failed to execute dependency action."); 1775 ExitOnFailure(hr, "Failed to execute dependency action.");
1721 break; 1776 break;
1722 1777
1723 case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
1724 *pfKeepRegistration = pExecuteAction->registration.fKeep;
1725 break; 1778 break;
1726 1779
1727 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: 1780 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
@@ -1757,7 +1810,6 @@ static HRESULT DoRollbackActions(
1757 __in BURN_ENGINE_STATE* pEngineState, 1810 __in BURN_ENGINE_STATE* pEngineState,
1758 __in BURN_EXECUTE_CONTEXT* pContext, 1811 __in BURN_EXECUTE_CONTEXT* pContext,
1759 __in DWORD dwCheckpoint, 1812 __in DWORD dwCheckpoint,
1760 __out BOOL* pfKeepRegistration,
1761 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 1813 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1762 ) 1814 )
1763{ 1815{
@@ -1811,12 +1863,12 @@ static HRESULT DoRollbackActions(
1811 break; 1863 break;
1812 1864
1813 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: 1865 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
1814 hr = ExecuteMsiPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); 1866 hr = ExecuteMsiPackage(pEngineState, pRollbackAction, pContext, FALSE, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart);
1815 IgnoreRollbackError(hr, "Failed to rollback MSI package."); 1867 IgnoreRollbackError(hr, "Failed to rollback MSI package.");
1816 break; 1868 break;
1817 1869
1818 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: 1870 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
1819 hr = ExecuteMspPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); 1871 hr = ExecuteMspPackage(pEngineState, pRollbackAction, pContext, FALSE, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart);
1820 IgnoreRollbackError(hr, "Failed to rollback MSP package."); 1872 IgnoreRollbackError(hr, "Failed to rollback MSP package.");
1821 break; 1873 break;
1822 1874
@@ -1835,10 +1887,6 @@ static HRESULT DoRollbackActions(
1835 IgnoreRollbackError(hr, "Failed to rollback dependency action."); 1887 IgnoreRollbackError(hr, "Failed to rollback dependency action.");
1836 break; 1888 break;
1837 1889
1838 case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
1839 *pfKeepRegistration = pRollbackAction->registration.fKeep;
1840 break;
1841
1842 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: 1890 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
1843 ExitFunction1(hr = S_OK); 1891 ExitFunction1(hr = S_OK);
1844 1892
@@ -1878,19 +1926,21 @@ static HRESULT ExecuteExePackage(
1878 GENERIC_EXECUTE_MESSAGE message = { }; 1926 GENERIC_EXECUTE_MESSAGE message = { };
1879 int nResult = 0; 1927 int nResult = 0;
1880 BOOL fBeginCalled = FALSE; 1928 BOOL fBeginCalled = FALSE;
1929 BOOL fExecuted = FALSE;
1930 BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage;
1881 1931
1882 if (FAILED(pExecuteAction->exePackage.pPackage->hrCacheResult)) 1932 if (FAILED(pPackage->hrCacheResult))
1883 { 1933 {
1884 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pExecuteAction->exePackage.pPackage->sczId, pExecuteAction->exePackage.pPackage->hrCacheResult); 1934 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult);
1885 ExitFunction1(hr = S_OK); 1935 ExitFunction1(hr = S_OK);
1886 } 1936 }
1887 1937
1888 Assert(pContext->fRollback == fRollback); 1938 Assert(pContext->fRollback == fRollback);
1889 pContext->pExecutingPackage = pExecuteAction->exePackage.pPackage; 1939 pContext->pExecutingPackage = pPackage;
1890 fBeginCalled = TRUE; 1940 fBeginCalled = TRUE;
1891 1941
1892 // Send package execute begin to BA. 1942 // Send package execute begin to BA.
1893 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pExecuteAction->exePackage.pPackage->sczId, !fRollback, pExecuteAction->exePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); 1943 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->exePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE);
1894 ExitOnRootFailure(hr, "BA aborted execute EXE package begin."); 1944 ExitOnRootFailure(hr, "BA aborted execute EXE package begin.");
1895 1945
1896 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 1946 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
@@ -1900,8 +1950,10 @@ static HRESULT ExecuteExePackage(
1900 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 1950 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult);
1901 ExitOnRootFailure(hr, "BA aborted EXE progress."); 1951 ExitOnRootFailure(hr, "BA aborted EXE progress.");
1902 1952
1953 fExecuted = TRUE;
1954
1903 // Execute package. 1955 // Execute package.
1904 if (pExecuteAction->exePackage.pPackage->fPerMachine) 1956 if (pPackage->fPerMachine)
1905 { 1957 {
1906 hrExecute = ElevationExecuteExePackage(pEngineState->companionConnection.hPipe, pExecuteAction, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart); 1958 hrExecute = ElevationExecuteExePackage(pEngineState->companionConnection.hPipe, pExecuteAction, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart);
1907 ExitOnFailure(hrExecute, "Failed to configure per-machine EXE package."); 1959 ExitOnFailure(hrExecute, "Failed to configure per-machine EXE package.");
@@ -1926,9 +1978,14 @@ static HRESULT ExecuteExePackage(
1926 ExitOnRootFailure(hr, "BA aborted EXE package execute progress."); 1978 ExitOnRootFailure(hr, "BA aborted EXE package execute progress.");
1927 1979
1928LExit: 1980LExit:
1981 if (fExecuted)
1982 {
1983 ExeEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute);
1984 }
1985
1929 if (fBeginCalled) 1986 if (fBeginCalled)
1930 { 1987 {
1931 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pExecuteAction->exePackage.pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); 1988 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend);
1932 } 1989 }
1933 1990
1934 return hr; 1991 return hr;
@@ -1938,6 +1995,7 @@ static HRESULT ExecuteMsiPackage(
1938 __in BURN_ENGINE_STATE* pEngineState, 1995 __in BURN_ENGINE_STATE* pEngineState,
1939 __in BURN_EXECUTE_ACTION* pExecuteAction, 1996 __in BURN_EXECUTE_ACTION* pExecuteAction,
1940 __in BURN_EXECUTE_CONTEXT* pContext, 1997 __in BURN_EXECUTE_CONTEXT* pContext,
1998 __in BOOL fInsideMsiTransaction,
1941 __in BOOL fRollback, 1999 __in BOOL fRollback,
1942 __out BOOL* pfRetry, 2000 __out BOOL* pfRetry,
1943 __out BOOL* pfSuspend, 2001 __out BOOL* pfSuspend,
@@ -1947,23 +2005,27 @@ static HRESULT ExecuteMsiPackage(
1947 HRESULT hr = S_OK; 2005 HRESULT hr = S_OK;
1948 HRESULT hrExecute = S_OK; 2006 HRESULT hrExecute = S_OK;
1949 BOOL fBeginCalled = FALSE; 2007 BOOL fBeginCalled = FALSE;
2008 BOOL fExecuted = FALSE;
2009 BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage;
1950 2010
1951 if (FAILED(pExecuteAction->msiPackage.pPackage->hrCacheResult)) 2011 if (FAILED(pPackage->hrCacheResult))
1952 { 2012 {
1953 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pExecuteAction->msiPackage.pPackage->sczId, pExecuteAction->msiPackage.pPackage->hrCacheResult); 2013 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult);
1954 ExitFunction1(hr = S_OK); 2014 ExitFunction1(hr = S_OK);
1955 } 2015 }
1956 2016
1957 Assert(pContext->fRollback == fRollback); 2017 Assert(pContext->fRollback == fRollback);
1958 pContext->pExecutingPackage = pExecuteAction->msiPackage.pPackage; 2018 pContext->pExecutingPackage = pPackage;
1959 fBeginCalled = TRUE; 2019 fBeginCalled = TRUE;
1960 2020
1961 // Send package execute begin to BA. 2021 // Send package execute begin to BA.
1962 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pExecuteAction->msiPackage.pPackage->sczId, !fRollback, pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.uiLevel, pExecuteAction->msiPackage.fDisableExternalUiHandler); 2022 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.uiLevel, pExecuteAction->msiPackage.fDisableExternalUiHandler);
1963 ExitOnRootFailure(hr, "BA aborted execute MSI package begin."); 2023 ExitOnRootFailure(hr, "BA aborted execute MSI package begin.");
1964 2024
2025 fExecuted = TRUE;
2026
1965 // execute package 2027 // execute package
1966 if (pExecuteAction->msiPackage.pPackage->fPerMachine) 2028 if (pPackage->fPerMachine)
1967 { 2029 {
1968 hrExecute = ElevationExecuteMsiPackage(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart); 2030 hrExecute = ElevationExecuteMsiPackage(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart);
1969 ExitOnFailure(hrExecute, "Failed to configure per-machine MSI package."); 2031 ExitOnFailure(hrExecute, "Failed to configure per-machine MSI package.");
@@ -1981,9 +2043,14 @@ static HRESULT ExecuteMsiPackage(
1981 ExitOnRootFailure(hr, "BA aborted MSI package execute progress."); 2043 ExitOnRootFailure(hr, "BA aborted MSI package execute progress.");
1982 2044
1983LExit: 2045LExit:
2046 if (fExecuted)
2047 {
2048 MsiEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute, fInsideMsiTransaction);
2049 }
2050
1984 if (fBeginCalled) 2051 if (fBeginCalled)
1985 { 2052 {
1986 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pExecuteAction->msiPackage.pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); 2053 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend);
1987 } 2054 }
1988 2055
1989 return hr; 2056 return hr;
@@ -1993,6 +2060,7 @@ static HRESULT ExecuteMspPackage(
1993 __in BURN_ENGINE_STATE* pEngineState, 2060 __in BURN_ENGINE_STATE* pEngineState,
1994 __in BURN_EXECUTE_ACTION* pExecuteAction, 2061 __in BURN_EXECUTE_ACTION* pExecuteAction,
1995 __in BURN_EXECUTE_CONTEXT* pContext, 2062 __in BURN_EXECUTE_CONTEXT* pContext,
2063 __in BOOL fInsideMsiTransaction,
1996 __in BOOL fRollback, 2064 __in BOOL fRollback,
1997 __out BOOL* pfRetry, 2065 __out BOOL* pfRetry,
1998 __out BOOL* pfSuspend, 2066 __out BOOL* pfSuspend,
@@ -2002,19 +2070,21 @@ static HRESULT ExecuteMspPackage(
2002 HRESULT hr = S_OK; 2070 HRESULT hr = S_OK;
2003 HRESULT hrExecute = S_OK; 2071 HRESULT hrExecute = S_OK;
2004 BOOL fBeginCalled = FALSE; 2072 BOOL fBeginCalled = FALSE;
2073 BOOL fExecuted = FALSE;
2074 BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage;
2005 2075
2006 if (FAILED(pExecuteAction->mspTarget.pPackage->hrCacheResult)) 2076 if (FAILED(pPackage->hrCacheResult))
2007 { 2077 {
2008 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pExecuteAction->mspTarget.pPackage->sczId, pExecuteAction->mspTarget.pPackage->hrCacheResult); 2078 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult);
2009 ExitFunction1(hr = S_OK); 2079 ExitFunction1(hr = S_OK);
2010 } 2080 }
2011 2081
2012 Assert(pContext->fRollback == fRollback); 2082 Assert(pContext->fRollback == fRollback);
2013 pContext->pExecutingPackage = pExecuteAction->mspTarget.pPackage; 2083 pContext->pExecutingPackage = pPackage;
2014 fBeginCalled = TRUE; 2084 fBeginCalled = TRUE;
2015 2085
2016 // Send package execute begin to BA. 2086 // Send package execute begin to BA.
2017 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pExecuteAction->mspTarget.pPackage->sczId, !fRollback, pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.uiLevel, pExecuteAction->mspTarget.fDisableExternalUiHandler); 2087 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.uiLevel, pExecuteAction->mspTarget.fDisableExternalUiHandler);
2018 ExitOnRootFailure(hr, "BA aborted execute MSP package begin."); 2088 ExitOnRootFailure(hr, "BA aborted execute MSP package begin.");
2019 2089
2020 // Now send all the patches that target this product code. 2090 // Now send all the patches that target this product code.
@@ -2026,6 +2096,8 @@ static HRESULT ExecuteMspPackage(
2026 ExitOnRootFailure(hr, "BA aborted execute MSP target."); 2096 ExitOnRootFailure(hr, "BA aborted execute MSP target.");
2027 } 2097 }
2028 2098
2099 fExecuted = TRUE;
2100
2029 // execute package 2101 // execute package
2030 if (pExecuteAction->mspTarget.fPerMachineTarget) 2102 if (pExecuteAction->mspTarget.fPerMachineTarget)
2031 { 2103 {
@@ -2045,9 +2117,14 @@ static HRESULT ExecuteMspPackage(
2045 ExitOnRootFailure(hr, "BA aborted MSP package execute progress."); 2117 ExitOnRootFailure(hr, "BA aborted MSP package execute progress.");
2046 2118
2047LExit: 2119LExit:
2120 if (fExecuted)
2121 {
2122 MspEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute, fInsideMsiTransaction);
2123 }
2124
2048 if (fBeginCalled) 2125 if (fBeginCalled)
2049 { 2126 {
2050 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pExecuteAction->mspTarget.pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); 2127 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend);
2051 } 2128 }
2052 2129
2053 return hr; 2130 return hr;
@@ -2069,19 +2146,21 @@ static HRESULT ExecuteMsuPackage(
2069 GENERIC_EXECUTE_MESSAGE message = { }; 2146 GENERIC_EXECUTE_MESSAGE message = { };
2070 int nResult = 0; 2147 int nResult = 0;
2071 BOOL fBeginCalled = FALSE; 2148 BOOL fBeginCalled = FALSE;
2149 BOOL fExecuted = FALSE;
2150 BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage;
2072 2151
2073 if (FAILED(pExecuteAction->msuPackage.pPackage->hrCacheResult)) 2152 if (FAILED(pPackage->hrCacheResult))
2074 { 2153 {
2075 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pExecuteAction->msuPackage.pPackage->sczId, pExecuteAction->msuPackage.pPackage->hrCacheResult); 2154 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult);
2076 ExitFunction1(hr = S_OK); 2155 ExitFunction1(hr = S_OK);
2077 } 2156 }
2078 2157
2079 Assert(pContext->fRollback == fRollback); 2158 Assert(pContext->fRollback == fRollback);
2080 pContext->pExecutingPackage = pExecuteAction->msuPackage.pPackage; 2159 pContext->pExecutingPackage = pPackage;
2081 fBeginCalled = TRUE; 2160 fBeginCalled = TRUE;
2082 2161
2083 // Send package execute begin to BA. 2162 // Send package execute begin to BA.
2084 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pExecuteAction->msuPackage.pPackage->sczId, !fRollback, pExecuteAction->msuPackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); 2163 hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msuPackage.action, INSTALLUILEVEL_NOCHANGE, FALSE);
2085 ExitOnRootFailure(hr, "BA aborted execute MSU package begin."); 2164 ExitOnRootFailure(hr, "BA aborted execute MSU package begin.");
2086 2165
2087 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 2166 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
@@ -2091,8 +2170,10 @@ static HRESULT ExecuteMsuPackage(
2091 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 2170 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult);
2092 ExitOnRootFailure(hr, "BA aborted MSU progress."); 2171 ExitOnRootFailure(hr, "BA aborted MSU progress.");
2093 2172
2173 fExecuted = TRUE;
2174
2094 // execute package 2175 // execute package
2095 if (pExecuteAction->msuPackage.pPackage->fPerMachine) 2176 if (pPackage->fPerMachine)
2096 { 2177 {
2097 hrExecute = ElevationExecuteMsuPackage(pEngineState->companionConnection.hPipe, pExecuteAction, fRollback, fStopWusaService, GenericExecuteMessageHandler, pContext, pRestart); 2178 hrExecute = ElevationExecuteMsuPackage(pEngineState->companionConnection.hPipe, pExecuteAction, fRollback, fStopWusaService, GenericExecuteMessageHandler, pContext, pRestart);
2098 ExitOnFailure(hrExecute, "Failed to configure per-machine MSU package."); 2179 ExitOnFailure(hrExecute, "Failed to configure per-machine MSU package.");
@@ -2117,9 +2198,14 @@ static HRESULT ExecuteMsuPackage(
2117 ExitOnRootFailure(hr, "BA aborted MSU package execute progress."); 2198 ExitOnRootFailure(hr, "BA aborted MSU package execute progress.");
2118 2199
2119LExit: 2200LExit:
2201 if (fExecuted)
2202 {
2203 MsuEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute);
2204 }
2205
2120 if (fBeginCalled) 2206 if (fBeginCalled)
2121 { 2207 {
2122 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pExecuteAction->msuPackage.pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); 2208 hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend);
2123 } 2209 }
2124 2210
2125 return hr; 2211 return hr;
@@ -2167,6 +2253,32 @@ static HRESULT ExecuteDependencyAction(
2167 ExitOnFailure(hr, "Failed to register the dependency on per-user package."); 2253 ExitOnFailure(hr, "Failed to register the dependency on per-user package.");
2168 } 2254 }
2169 2255
2256 if (pAction->packageDependency.pPackage->fCanAffectRegistration)
2257 {
2258 if (BURN_DEPENDENCY_ACTION_REGISTER == pAction->packageDependency.action)
2259 {
2260 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->cacheRegistrationState)
2261 {
2262 pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2263 }
2264 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->installRegistrationState)
2265 {
2266 pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2267 }
2268 }
2269 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pAction->packageDependency.action)
2270 {
2271 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->cacheRegistrationState)
2272 {
2273 pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2274 }
2275 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->installRegistrationState)
2276 {
2277 pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2278 }
2279 }
2280 }
2281
2170LExit: 2282LExit:
2171 return hr; 2283 return hr;
2172} 2284}
@@ -2202,6 +2314,8 @@ static HRESULT ExecuteMsiBeginTransaction(
2202 if (SUCCEEDED(hr)) 2314 if (SUCCEEDED(hr))
2203 { 2315 {
2204 pRollbackBoundary->fActiveTransaction = TRUE; 2316 pRollbackBoundary->fActiveTransaction = TRUE;
2317
2318 ResetTransactionRegistrationState(pEngineState, FALSE);
2205 } 2319 }
2206 2320
2207LExit: 2321LExit:
@@ -2244,6 +2358,8 @@ static HRESULT ExecuteMsiCommitTransaction(
2244 if (SUCCEEDED(hr)) 2358 if (SUCCEEDED(hr))
2245 { 2359 {
2246 pRollbackBoundary->fActiveTransaction = FALSE; 2360 pRollbackBoundary->fActiveTransaction = FALSE;
2361
2362 ResetTransactionRegistrationState(pEngineState, TRUE);
2247 } 2363 }
2248 2364
2249LExit: 2365LExit:
@@ -2285,6 +2401,8 @@ static HRESULT ExecuteMsiRollbackTransaction(
2285LExit: 2401LExit:
2286 pRollbackBoundary->fActiveTransaction = FALSE; 2402 pRollbackBoundary->fActiveTransaction = FALSE;
2287 2403
2404 ResetTransactionRegistrationState(pEngineState, FALSE);
2405
2288 if (fBeginCalled) 2406 if (fBeginCalled)
2289 { 2407 {
2290 UserExperienceOnRollbackMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr); 2408 UserExperienceOnRollbackMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr);
@@ -2293,6 +2411,38 @@ LExit:
2293 return hr; 2411 return hr;
2294} 2412}
2295 2413
2414static void ResetTransactionRegistrationState(
2415 __in BURN_ENGINE_STATE* pEngineState,
2416 __in BOOL fCommit
2417 )
2418{
2419 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
2420 {
2421 BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
2422
2423 if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
2424 {
2425 for (DWORD j = 0; j < pPackage->Msp.cTargetProductCodes; ++j)
2426 {
2427 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + j;
2428
2429 if (fCommit && BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN != pTargetProduct->transactionRegistrationState)
2430 {
2431 pTargetProduct->registrationState = pTargetProduct->transactionRegistrationState;
2432 }
2433
2434 pTargetProduct->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
2435 }
2436 }
2437 else if (fCommit && BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN != pPackage->transactionRegistrationState)
2438 {
2439 pPackage->installRegistrationState = pPackage->transactionRegistrationState;
2440 }
2441
2442 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
2443 }
2444}
2445
2296static HRESULT CleanPackage( 2446static HRESULT CleanPackage(
2297 __in HANDLE hElevatedPipe, 2447 __in HANDLE hElevatedPipe,
2298 __in BURN_PACKAGE* pPackage 2448 __in BURN_PACKAGE* pPackage
@@ -2309,6 +2459,11 @@ static HRESULT CleanPackage(
2309 hr = CacheRemovePackage(FALSE, pPackage->sczId, pPackage->sczCacheId); 2459 hr = CacheRemovePackage(FALSE, pPackage->sczId, pPackage->sczCacheId);
2310 } 2460 }
2311 2461
2462 if (pPackage->fCanAffectRegistration)
2463 {
2464 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
2465 }
2466
2312 return hr; 2467 return hr;
2313} 2468}
2314 2469
diff --git a/src/engine/apply.h b/src/engine/apply.h
index 00e1fceb..548e147d 100644
--- a/src/engine/apply.h
+++ b/src/engine/apply.h
@@ -72,7 +72,6 @@ HRESULT ApplyRegister(
72HRESULT ApplyUnregister( 72HRESULT ApplyUnregister(
73 __in BURN_ENGINE_STATE* pEngineState, 73 __in BURN_ENGINE_STATE* pEngineState,
74 __in BOOL fFailedOrRollback, 74 __in BOOL fFailedOrRollback,
75 __in BOOL fRollback,
76 __in BOOL fSuspend, 75 __in BOOL fSuspend,
77 __in BOOTSTRAPPER_APPLY_RESTART restart 76 __in BOOTSTRAPPER_APPLY_RESTART restart
78 ); 77 );
@@ -83,13 +82,12 @@ HRESULT ApplyCache(
83 __in BURN_PLAN* pPlan, 82 __in BURN_PLAN* pPlan,
84 __in HANDLE hPipe, 83 __in HANDLE hPipe,
85 __inout DWORD* pcOverallProgressTicks, 84 __inout DWORD* pcOverallProgressTicks,
86 __out BOOL* pfRollback 85 __inout BOOL* pfRollback
87 ); 86 );
88HRESULT ApplyExecute( 87HRESULT ApplyExecute(
89 __in BURN_ENGINE_STATE* pEngineState, 88 __in BURN_ENGINE_STATE* pEngineState,
90 __in_opt HANDLE hCacheThread, 89 __in_opt HANDLE hCacheThread,
91 __inout DWORD* pcOverallProgressTicks, 90 __inout DWORD* pcOverallProgressTicks,
92 __inout BOOL* pfKeepRegistration,
93 __out BOOL* pfRollback, 91 __out BOOL* pfRollback,
94 __out BOOL* pfSuspend, 92 __out BOOL* pfSuspend,
95 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 93 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
diff --git a/src/engine/core.cpp b/src/engine/core.cpp
index a4c118a3..36471e93 100644
--- a/src/engine/core.cpp
+++ b/src/engine/core.cpp
@@ -331,6 +331,8 @@ extern "C" HRESULT CoreDetect(
331 } 331 }
332 332
333 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; 333 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN;
334 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
335 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
334 } 336 }
335 } 337 }
336 338
@@ -342,7 +344,7 @@ extern "C" HRESULT CoreDetect(
342 { 344 {
343 pPackage = pEngineState->packages.rgPackages + iPackage; 345 pPackage = pEngineState->packages.rgPackages + iPackage;
344 346
345 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingCacheStateToString(pPackage->cache)); 347 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingCacheStateToString(pPackage->cache), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
346 348
347 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 349 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
348 { 350 {
@@ -565,7 +567,6 @@ extern "C" HRESULT CoreApply(
565 BOOL fApplyInitialize = FALSE; 567 BOOL fApplyInitialize = FALSE;
566 BOOL fElevated = FALSE; 568 BOOL fElevated = FALSE;
567 BOOL fRegistered = FALSE; 569 BOOL fRegistered = FALSE;
568 BOOL fKeepRegistration = pEngineState->plan.fKeepRegistrationDefault;
569 BOOL fRollback = FALSE; 570 BOOL fRollback = FALSE;
570 BOOL fSuspend = FALSE; 571 BOOL fSuspend = FALSE;
571 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; 572 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
@@ -652,9 +653,9 @@ extern "C" HRESULT CoreApply(
652 // Register. 653 // Register.
653 if (pEngineState->plan.fRegister) 654 if (pEngineState->plan.fRegister)
654 { 655 {
656 fRegistered = TRUE;
655 hr = ApplyRegister(pEngineState); 657 hr = ApplyRegister(pEngineState);
656 ExitOnFailure(hr, "Failed to register bundle."); 658 ExitOnFailure(hr, "Failed to register bundle.");
657 fRegistered = TRUE;
658 } 659 }
659 660
660 // Cache. 661 // Cache.
@@ -681,7 +682,7 @@ extern "C" HRESULT CoreApply(
681 // Execute. 682 // Execute.
682 if (pEngineState->plan.cExecuteActions) 683 if (pEngineState->plan.cExecuteActions)
683 { 684 {
684 hr = ApplyExecute(pEngineState, hCacheThread, &cOverallProgressTicks, &fKeepRegistration, &fRollback, &fSuspend, &restart); 685 hr = ApplyExecute(pEngineState, hCacheThread, &cOverallProgressTicks, &fRollback, &fSuspend, &restart);
685 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed. 686 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed.
686 } 687 }
687 688
@@ -711,7 +712,7 @@ LExit:
711 // Unregister. 712 // Unregister.
712 if (fRegistered) 713 if (fRegistered)
713 { 714 {
714 ApplyUnregister(pEngineState, FAILED(hr) || fRollback, fKeepRegistration || pEngineState->plan.fDisallowRemoval, fSuspend, restart); 715 ApplyUnregister(pEngineState, FAILED(hr) || fRollback, fSuspend, restart);
715 } 716 }
716 717
717 if (fElevated) 718 if (fElevated)
@@ -1611,6 +1612,11 @@ static HRESULT DetectPackagePayloadsCached(
1611 1612
1612 pPackage->cache = cache; 1613 pPackage->cache = cache;
1613 1614
1615 if (pPackage->fCanAffectRegistration)
1616 {
1617 pPackage->cacheRegistrationState = BURN_CACHE_STATE_NONE < pPackage->cache ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
1618 }
1619
1614LExit: 1620LExit:
1615 ReleaseStr(sczPayloadCachePath); 1621 ReleaseStr(sczPayloadCachePath);
1616 ReleaseStr(sczCachePath); 1622 ReleaseStr(sczCachePath);
@@ -1703,7 +1709,7 @@ static void LogPackages(
1703 const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i; 1709 const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i;
1704 const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage]; 1710 const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage];
1705 1711
1706 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute)); 1712 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState));
1707 } 1713 }
1708 1714
1709 // Display related bundles last if caching, installing, modifying, or repairing. 1715 // Display related bundles last if caching, installing, modifying, or repairing.
diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp
index 1c33aaf2..a6a8fe4d 100644
--- a/src/engine/dependency.cpp
+++ b/src/engine/dependency.cpp
@@ -708,6 +708,9 @@ static HRESULT DetectPackageDependents(
708{ 708{
709 HRESULT hr = S_OK; 709 HRESULT hr = S_OK;
710 HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 710 HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
711 BOOL fCanIgnorePresence = pPackage->fCanAffectRegistration && 0 < pPackage->cDependencyProviders &&
712 (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState || BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState);
713 BOOL fBundleRegisteredAsDependent = FALSE;
711 714
712 // There's currently no point in getting the dependents if the scope doesn't match, 715 // There's currently no point in getting the dependents if the scope doesn't match,
713 // because they will just get ignored. 716 // because they will just get ignored.
@@ -729,6 +732,20 @@ static HRESULT DetectPackageDependents(
729 { 732 {
730 pPackage->fPackageProviderExists = TRUE; 733 pPackage->fPackageProviderExists = TRUE;
731 } 734 }
735
736 if (fCanIgnorePresence && !fBundleRegisteredAsDependent)
737 {
738 for (DWORD iDependent = 0; iDependent < pProvider->cDependents; ++iDependent)
739 {
740 DEPENDENCY* pDependent = pProvider->rgDependents + iDependent;
741
742 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczId, -1, pDependent->sczKey, -1))
743 {
744 fBundleRegisteredAsDependent = TRUE;
745 break;
746 }
747 }
748 }
732 } 749 }
733 else 750 else
734 { 751 {
@@ -747,6 +764,18 @@ static HRESULT DetectPackageDependents(
747 pPackage->fPackageProviderExists = TRUE; 764 pPackage->fPackageProviderExists = TRUE;
748 } 765 }
749 766
767 if (fCanIgnorePresence && !fBundleRegisteredAsDependent)
768 {
769 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState)
770 {
771 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
772 }
773 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState)
774 {
775 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
776 }
777 }
778
750LExit: 779LExit:
751 return hr; 780 return hr;
752} 781}
diff --git a/src/engine/detect.cpp b/src/engine/detect.cpp
index ff6ba4d7..159df3d0 100644
--- a/src/engine/detect.cpp
+++ b/src/engine/detect.cpp
@@ -63,6 +63,8 @@ extern "C" void DetectReset(
63 63
64 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; 64 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN;
65 pPackage->fPackageProviderExists = FALSE; 65 pPackage->fPackageProviderExists = FALSE;
66 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
67 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
66 68
67 pPackage->cache = BURN_CACHE_STATE_NONE; 69 pPackage->cache = BURN_CACHE_STATE_NONE;
68 for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload) 70 for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload)
diff --git a/src/engine/engine.mc b/src/engine/engine.mc
index d2135839..59a05676 100644
--- a/src/engine/engine.mc
+++ b/src/engine/engine.mc
@@ -188,7 +188,7 @@ MessageId=101
188Severity=Success 188Severity=Success
189SymbolicName=MSG_DETECTED_PACKAGE 189SymbolicName=MSG_DETECTED_PACKAGE
190Language=English 190Language=English
191Detected package: %1!ls!, state: %2!hs!, cached: %3!hs! 191Detected package: %1!ls!, state: %2!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs!
192. 192.
193 193
194MessageId=102 194MessageId=102
@@ -300,7 +300,7 @@ MessageId=201
300Severity=Success 300Severity=Success
301SymbolicName=MSG_PLANNED_PACKAGE 301SymbolicName=MSG_PLANNED_PACKAGE
302Language=English 302Language=English
303Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, cache: %7!hs!, uncache: %8!hs!, dependency: %9!hs! 303Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, cache: %7!hs!, uncache: %8!hs!, dependency: %9!hs!, expected install registration state: %10!hs!, expected cache registration state: %11!hs!
304. 304.
305 305
306MessageId=202 306MessageId=202
@@ -829,6 +829,21 @@ Language=English
829Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs! 829Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs!
830. 830.
831 831
832MessageId=373
833Severity=Success
834SymbolicName=MSG_POST_APPLY_CALCULATE_REGISTRATION
835Language=English
836Calculating whether to keep registration
837.
838
839
840MessageId=374
841Severity=Success
842SymbolicName=MSG_POST_APPLY_PACKAGE
843Language=English
844 package: %1!ls!, install registration state: %2!hs!, cache registration state: %3!hs!
845.
846
832MessageId=380 847MessageId=380
833Severity=Warning 848Severity=Warning
834SymbolicName=MSG_APPLY_SKIPPED 849SymbolicName=MSG_APPLY_SKIPPED
diff --git a/src/engine/exeengine.cpp b/src/engine/exeengine.cpp
index fd33d926..1ca28473 100644
--- a/src/engine/exeengine.cpp
+++ b/src/engine/exeengine.cpp
@@ -145,6 +145,11 @@ extern "C" HRESULT ExeEngineDetectPackage(
145 // update detect state 145 // update detect state
146 pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT; 146 pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
147 147
148 if (pPackage->fCanAffectRegistration)
149 {
150 pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
151 }
152
148LExit: 153LExit:
149 return hr; 154 return hr;
150} 155}
@@ -585,6 +590,31 @@ LExit:
585 return hr; 590 return hr;
586} 591}
587 592
593extern "C" void ExeEngineUpdateInstallRegistrationState(
594 __in BURN_EXECUTE_ACTION* pAction,
595 __in HRESULT hrExecute
596 )
597{
598 BURN_PACKAGE* pPackage = pAction->exePackage.pPackage;
599
600 if (FAILED(hrExecute) || !pPackage->fCanAffectRegistration)
601 {
602 ExitFunction();
603 }
604
605 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->exePackage.action)
606 {
607 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
608 }
609 else
610 {
611 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
612 }
613
614LExit:
615 return;
616}
617
588 618
589// internal helper functions 619// internal helper functions
590 620
diff --git a/src/engine/exeengine.h b/src/engine/exeengine.h
index 402e51ed..1eac4232 100644
--- a/src/engine/exeengine.h
+++ b/src/engine/exeengine.h
@@ -41,6 +41,10 @@ HRESULT ExeEngineExecutePackage(
41 __in LPVOID pvContext, 41 __in LPVOID pvContext,
42 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 42 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
43 ); 43 );
44void ExeEngineUpdateInstallRegistrationState(
45 __in BURN_EXECUTE_ACTION* pAction,
46 __in HRESULT hrExecute
47 );
44 48
45 49
46#if defined(__cplusplus) 50#if defined(__cplusplus)
diff --git a/src/engine/logging.cpp b/src/engine/logging.cpp
index 9dca527a..a9646218 100644
--- a/src/engine/logging.cpp
+++ b/src/engine/logging.cpp
@@ -399,6 +399,31 @@ extern "C" LPCSTR LoggingPackageStateToString(
399 } 399 }
400} 400}
401 401
402extern "C" LPCSTR LoggingPackageRegistrationStateToString(
403 __in BOOL fCanAffectRegistration,
404 __in BURN_PACKAGE_REGISTRATION_STATE registrationState
405 )
406{
407 if (!fCanAffectRegistration)
408 {
409 return "(permanent)";
410 }
411
412 switch (registrationState)
413 {
414 case BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN:
415 return "Unknown";
416 case BURN_PACKAGE_REGISTRATION_STATE_IGNORED:
417 return "Ignored";
418 case BURN_PACKAGE_REGISTRATION_STATE_ABSENT:
419 return "Absent";
420 case BURN_PACKAGE_REGISTRATION_STATE_PRESENT:
421 return "Present";
422 default:
423 return "Invalid";
424 }
425}
426
402extern "C" LPCSTR LoggingCacheStateToString( 427extern "C" LPCSTR LoggingCacheStateToString(
403 __in BURN_CACHE_STATE cacheState 428 __in BURN_CACHE_STATE cacheState
404 ) 429 )
diff --git a/src/engine/logging.h b/src/engine/logging.h
index b5c6c052..49a8ef5d 100644
--- a/src/engine/logging.h
+++ b/src/engine/logging.h
@@ -89,6 +89,11 @@ LPCSTR LoggingPackageStateToString(
89 __in BOOTSTRAPPER_PACKAGE_STATE packageState 89 __in BOOTSTRAPPER_PACKAGE_STATE packageState
90 ); 90 );
91 91
92LPCSTR LoggingPackageRegistrationStateToString(
93 __in BOOL fCanAffectRegistration,
94 __in BURN_PACKAGE_REGISTRATION_STATE registrationState
95 );
96
92LPCSTR LoggingCacheStateToString( 97LPCSTR LoggingCacheStateToString(
93 __in BURN_CACHE_STATE cacheState 98 __in BURN_CACHE_STATE cacheState
94 ); 99 );
diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp
index 5bccb375..4fdf2b7a 100644
--- a/src/engine/msiengine.cpp
+++ b/src/engine/msiengine.cpp
@@ -661,6 +661,11 @@ extern "C" HRESULT MsiEngineDetectPackage(
661 } 661 }
662 } 662 }
663 663
664 if (pPackage->fCanAffectRegistration)
665 {
666 pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
667 }
668
664LExit: 669LExit:
665 ReleaseStr(sczInstalledLanguage); 670 ReleaseStr(sczInstalledLanguage);
666 ReleaseStr(sczInstalledVersion); 671 ReleaseStr(sczInstalledVersion);
@@ -1397,6 +1402,42 @@ extern "C" HRESULT MsiEngineCalculateInstallUiLevel(
1397 return UserExperienceOnPlanMsiPackage(pUserExperience, wzPackageId, fExecute, actionState, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler); 1402 return UserExperienceOnPlanMsiPackage(pUserExperience, wzPackageId, fExecute, actionState, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler);
1398} 1403}
1399 1404
1405extern "C" void MsiEngineUpdateInstallRegistrationState(
1406 __in BURN_EXECUTE_ACTION* pAction,
1407 __in HRESULT hrExecute,
1408 __in BOOL fInsideMsiTransaction
1409 )
1410{
1411 BURN_PACKAGE_REGISTRATION_STATE newState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1412 BURN_PACKAGE* pPackage = pAction->msiPackage.pPackage;
1413
1414 if (FAILED(hrExecute) || !pPackage->fCanAffectRegistration)
1415 {
1416 ExitFunction();
1417 }
1418
1419 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->msiPackage.action)
1420 {
1421 newState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
1422 }
1423 else
1424 {
1425 newState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1426 }
1427
1428 if (fInsideMsiTransaction)
1429 {
1430 pPackage->transactionRegistrationState = newState;
1431 }
1432 else
1433 {
1434 pPackage->installRegistrationState = newState;
1435 }
1436
1437LExit:
1438 return;
1439}
1440
1400 1441
1401// internal helper functions 1442// internal helper functions
1402 1443
diff --git a/src/engine/msiengine.h b/src/engine/msiengine.h
index 1f450147..d1e46da8 100644
--- a/src/engine/msiengine.h
+++ b/src/engine/msiengine.h
@@ -88,6 +88,11 @@ HRESULT MsiEngineCalculateInstallUiLevel(
88 __out INSTALLUILEVEL* pUiLevel, 88 __out INSTALLUILEVEL* pUiLevel,
89 __out BOOL* pfDisableExternalUiHandler 89 __out BOOL* pfDisableExternalUiHandler
90 ); 90 );
91void MsiEngineUpdateInstallRegistrationState(
92 __in BURN_EXECUTE_ACTION* pAction,
93 __in HRESULT hrExecute,
94 __in BOOL fInsideMsiTransaction
95 );
91 96
92#if defined(__cplusplus) 97#if defined(__cplusplus)
93} 98}
diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp
index c432b78b..c0329d79 100644
--- a/src/engine/mspengine.cpp
+++ b/src/engine/mspengine.cpp
@@ -200,20 +200,26 @@ extern "C" HRESULT MspEngineDetectPackage(
200 HRESULT hr = S_OK; 200 HRESULT hr = S_OK;
201 LPWSTR sczState = NULL; 201 LPWSTR sczState = NULL;
202 202
203 if (pPackage->fCanAffectRegistration)
204 {
205 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
206 }
207
203 if (0 == pPackage->Msp.cTargetProductCodes) 208 if (0 == pPackage->Msp.cTargetProductCodes)
204 { 209 {
205 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; 210 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
206 } 211 }
207 else 212 else
208 { 213 {
209 // Start the package state at the the highest state then loop through all the 214 // Start the package state at the highest state then loop through all the
210 // target product codes and end up setting the current state to the lowest 215 // target product codes and end up setting the current state to the lowest
211 // package state applied to the the target product codes. 216 // package state applied to the target product codes.
212 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 217 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
213 218
214 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) 219 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
215 { 220 {
216 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; 221 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
222 BOOL fInstalled = FALSE;
217 223
218 hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState); 224 hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState);
219 if (SUCCEEDED(hr)) 225 if (SUCCEEDED(hr))
@@ -221,14 +227,17 @@ extern "C" HRESULT MspEngineDetectPackage(
221 switch (*sczState) 227 switch (*sczState)
222 { 228 {
223 case '1': 229 case '1':
230 fInstalled = TRUE;
224 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; 231 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
225 break; 232 break;
226 233
227 case '2': 234 case '2':
235 fInstalled = TRUE;
228 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 236 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
229 break; 237 break;
230 238
231 case '4': 239 case '4':
240 fInstalled = TRUE;
232 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; 241 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE;
233 break; 242 break;
234 243
@@ -249,6 +258,16 @@ extern "C" HRESULT MspEngineDetectPackage(
249 pPackage->currentState = pTargetProduct->patchPackageState; 258 pPackage->currentState = pTargetProduct->patchPackageState;
250 } 259 }
251 260
261 if (pPackage->fCanAffectRegistration)
262 {
263 pTargetProduct->registrationState = fInstalled ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
264
265 if (fInstalled)
266 {
267 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
268 }
269 }
270
252 hr = UserExperienceOnDetectTargetMsiPackage(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState); 271 hr = UserExperienceOnDetectTargetMsiPackage(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState);
253 ExitOnRootFailure(hr, "BA aborted detect target MSI package."); 272 ExitOnRootFailure(hr, "BA aborted detect target MSI package.");
254 } 273 }
@@ -642,6 +661,92 @@ extern "C" void MspEngineSlipstreamUpdateState(
642 } 661 }
643} 662}
644 663
664extern "C" void MspEngineUpdateInstallRegistrationState(
665 __in BURN_EXECUTE_ACTION* pAction,
666 __in HRESULT hrExecute,
667 __in BOOL fInsideMsiTransaction
668 )
669{
670 BURN_PACKAGE_REGISTRATION_STATE newState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
671
672 if (FAILED(hrExecute))
673 {
674 ExitFunction();
675 }
676
677 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->mspTarget.action)
678 {
679 newState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
680 }
681 else
682 {
683 newState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
684 }
685
686 for (DWORD i = 0; i < pAction->mspTarget.cOrderedPatches; ++i)
687 {
688 BURN_ORDERED_PATCHES* pOrderedPatches = pAction->mspTarget.rgOrderedPatches + i;
689 BURN_PACKAGE* pPackage = pOrderedPatches->pPackage;
690 BURN_MSPTARGETPRODUCT* pTargetProduct = NULL;
691
692 Assert(BURN_PACKAGE_TYPE_MSP == pPackage->type);
693
694 if (!pPackage->fCanAffectRegistration)
695 {
696 continue;
697 }
698
699 for (DWORD j = 0; j < pPackage->Msp.cTargetProductCodes; ++j)
700 {
701 pTargetProduct = pPackage->Msp.rgTargetProducts + j;
702 if (pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) &&
703 CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1))
704 {
705 break;
706 }
707
708 pTargetProduct = NULL;
709 }
710
711 if (!pTargetProduct)
712 {
713 AssertSz(pTargetProduct, "Ordered patch didn't have corresponding target product");
714 continue;
715 }
716
717 if (fInsideMsiTransaction)
718 {
719 pTargetProduct->transactionRegistrationState = newState;
720 }
721 else
722 {
723 pTargetProduct->registrationState = newState;
724 }
725 }
726
727LExit:
728 return;
729}
730
731extern "C" void MspEngineFinalizeInstallRegistrationState(
732 __in BURN_PACKAGE* pPackage
733 )
734{
735 Assert(pPackage->fCanAffectRegistration);
736 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
737
738 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
739 {
740 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
741
742 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
743 {
744 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
745 break;
746 }
747 }
748}
749
645 750
646// internal helper functions 751// internal helper functions
647 752
diff --git a/src/engine/mspengine.h b/src/engine/mspengine.h
index e08fe992..7cc9a119 100644
--- a/src/engine/mspengine.h
+++ b/src/engine/mspengine.h
@@ -62,6 +62,14 @@ void MspEngineSlipstreamUpdateState(
62 __in BOOTSTRAPPER_ACTION_STATE execute, 62 __in BOOTSTRAPPER_ACTION_STATE execute,
63 __in BOOTSTRAPPER_ACTION_STATE rollback 63 __in BOOTSTRAPPER_ACTION_STATE rollback
64 ); 64 );
65void MspEngineUpdateInstallRegistrationState(
66 __in BURN_EXECUTE_ACTION* pAction,
67 __in HRESULT hrExecute,
68 __in BOOL fInsideMsiTransaction
69 );
70void MspEngineFinalizeInstallRegistrationState(
71 __in BURN_PACKAGE* pPackage
72 );
65 73
66 74
67#if defined(__cplusplus) 75#if defined(__cplusplus)
diff --git a/src/engine/msuengine.cpp b/src/engine/msuengine.cpp
index 641d55b1..b7a503ad 100644
--- a/src/engine/msuengine.cpp
+++ b/src/engine/msuengine.cpp
@@ -69,6 +69,11 @@ extern "C" HRESULT MsuEngineDetectPackage(
69 // update detect state 69 // update detect state
70 pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT; 70 pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
71 71
72 if (pPackage->fCanAffectRegistration)
73 {
74 pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
75 }
76
72LExit: 77LExit:
73 return hr; 78 return hr;
74} 79}
@@ -424,6 +429,31 @@ LExit:
424 return hr; 429 return hr;
425} 430}
426 431
432extern "C" void MsuEngineUpdateInstallRegistrationState(
433 __in BURN_EXECUTE_ACTION* pAction,
434 __in HRESULT hrExecute
435 )
436{
437 BURN_PACKAGE* pPackage = pAction->msuPackage.pPackage;
438
439 if (FAILED(hrExecute) || !pPackage->fCanAffectRegistration)
440 {
441 ExitFunction();
442 }
443
444 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->msuPackage.action)
445 {
446 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
447 }
448 else
449 {
450 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
451 }
452
453LExit:
454 return;
455}
456
427static HRESULT EnsureWUServiceEnabled( 457static HRESULT EnsureWUServiceEnabled(
428 __in BOOL fStopWusaService, 458 __in BOOL fStopWusaService,
429 __out SC_HANDLE* pschWu, 459 __out SC_HANDLE* pschWu,
diff --git a/src/engine/msuengine.h b/src/engine/msuengine.h
index d0323b06..7f57a084 100644
--- a/src/engine/msuengine.h
+++ b/src/engine/msuengine.h
@@ -41,6 +41,10 @@ HRESULT MsuEngineExecutePackage(
41 __in LPVOID pvContext, 41 __in LPVOID pvContext,
42 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 42 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
43 ); 43 );
44void MsuEngineUpdateInstallRegistrationState(
45 __in BURN_EXECUTE_ACTION* pAction,
46 __in HRESULT hrExecute
47 );
44 48
45 49
46#if defined(__cplusplus) 50#if defined(__cplusplus)
diff --git a/src/engine/package.cpp b/src/engine/package.cpp
index 701dda08..b27b1e07 100644
--- a/src/engine/package.cpp
+++ b/src/engine/package.cpp
@@ -156,6 +156,7 @@ extern "C" HRESULT PackagesParseFromXml(
156 hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fUninstallable); 156 hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fUninstallable);
157 ExitOnFailure(hr, "Failed to get @Permanent."); 157 ExitOnFailure(hr, "Failed to get @Permanent.");
158 pPackage->fUninstallable = !pPackage->fUninstallable; // TODO: change "Uninstallable" variable name to permanent, until then Uninstallable is the opposite of Permanent so fix the variable. 158 pPackage->fUninstallable = !pPackage->fUninstallable; // TODO: change "Uninstallable" variable name to permanent, until then Uninstallable is the opposite of Permanent so fix the variable.
159 pPackage->fCanAffectRegistration = pPackage->fUninstallable;
159 160
160 // @Vital 161 // @Vital
161 hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital); 162 hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital);
diff --git a/src/engine/package.h b/src/engine/package.h
index 8f801e85..d3225fbc 100644
--- a/src/engine/package.h
+++ b/src/engine/package.h
@@ -78,6 +78,14 @@ enum BOOTSTRAPPER_FEATURE_ACTION
78 BOOTSTRAPPER_FEATURE_ACTION_REMOVE, 78 BOOTSTRAPPER_FEATURE_ACTION_REMOVE,
79}; 79};
80 80
81enum BURN_PACKAGE_REGISTRATION_STATE
82{
83 BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN,
84 BURN_PACKAGE_REGISTRATION_STATE_IGNORED,
85 BURN_PACKAGE_REGISTRATION_STATE_ABSENT,
86 BURN_PACKAGE_REGISTRATION_STATE_PRESENT,
87};
88
81// structs 89// structs
82 90
83typedef struct _BURN_EXE_EXIT_CODE 91typedef struct _BURN_EXE_EXIT_CODE
@@ -106,6 +114,9 @@ typedef struct _BURN_MSPTARGETPRODUCT
106 BOOTSTRAPPER_PACKAGE_STATE patchPackageState; // only valid after Detect. 114 BOOTSTRAPPER_PACKAGE_STATE patchPackageState; // only valid after Detect.
107 BOOTSTRAPPER_ACTION_STATE execute; // only valid during Plan. 115 BOOTSTRAPPER_ACTION_STATE execute; // only valid during Plan.
108 BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan. 116 BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan.
117
118 BURN_PACKAGE_REGISTRATION_STATE registrationState; // initialized during Detect, updated during Apply.
119 BURN_PACKAGE_REGISTRATION_STATE transactionRegistrationState;// only valid during Apply inside an MSI transaction.
109} BURN_MSPTARGETPRODUCT; 120} BURN_MSPTARGETPRODUCT;
110 121
111typedef struct _BURN_MSIPROPERTY 122typedef struct _BURN_MSIPROPERTY
@@ -190,6 +201,7 @@ typedef struct _BURN_PACKAGE
190 BOOL fPerMachine; 201 BOOL fPerMachine;
191 BOOL fUninstallable; 202 BOOL fUninstallable;
192 BOOL fVital; 203 BOOL fVital;
204 BOOL fCanAffectRegistration;
193 205
194 BURN_CACHE_TYPE cacheType; 206 BURN_CACHE_TYPE cacheType;
195 LPWSTR sczCacheId; 207 LPWSTR sczCacheId;
@@ -216,6 +228,12 @@ typedef struct _BURN_PACKAGE
216 BOOL fDependencyManagerWasHere; // only valid during Plan. 228 BOOL fDependencyManagerWasHere; // only valid during Plan.
217 HRESULT hrCacheResult; // only valid during Apply. 229 HRESULT hrCacheResult; // only valid during Apply.
218 230
231 BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply.
232 BURN_PACKAGE_REGISTRATION_STATE installRegistrationState; // initialized during Detect, updated during Apply.
233 BURN_PACKAGE_REGISTRATION_STATE expectedCacheRegistrationState; // only valid after Plan.
234 BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState;// only valid after Plan.
235 BURN_PACKAGE_REGISTRATION_STATE transactionRegistrationState; // only valid during Apply inside an MSI transaction.
236
219 BURN_PACKAGE_PAYLOAD* rgPayloads; 237 BURN_PACKAGE_PAYLOAD* rgPayloads;
220 DWORD cPayloads; 238 DWORD cPayloads;
221 239
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index 6f5407b9..1aaec252 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -6,13 +6,6 @@
6 6
7// internal struct definitions 7// internal struct definitions
8 8
9struct PLAN_NONPERMANENT_PACKAGE_INDICES
10{
11 DWORD iAfterExecuteFirstNonPermanentPackage;
12 DWORD iBeforeRollbackFirstNonPermanentPackage;
13 DWORD iAfterExecuteLastNonPermanentPackage;
14 DWORD iAfterRollbackLastNonPermanentPackage;
15};
16 9
17// internal function definitions 10// internal function definitions
18 11
@@ -39,8 +32,7 @@ static HRESULT ProcessPackage(
39 __in BOOTSTRAPPER_RELATION_TYPE relationType, 32 __in BOOTSTRAPPER_RELATION_TYPE relationType,
40 __in_z_opt LPCWSTR wzLayoutDirectory, 33 __in_z_opt LPCWSTR wzLayoutDirectory,
41 __inout HANDLE* phSyncpointEvent, 34 __inout HANDLE* phSyncpointEvent,
42 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 35 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
43 __in_opt PLAN_NONPERMANENT_PACKAGE_INDICES* pNonpermanentPackageIndices
44 ); 36 );
45static HRESULT ProcessPackageRollbackBoundary( 37static HRESULT ProcessPackageRollbackBoundary(
46 __in BURN_PLAN* pPlan, 38 __in BURN_PLAN* pPlan,
@@ -479,7 +471,7 @@ extern "C" HRESULT PlanPackages(
479 __in BURN_PLAN* pPlan, 471 __in BURN_PLAN* pPlan,
480 __in BURN_LOGGING* pLog, 472 __in BURN_LOGGING* pLog,
481 __in BURN_VARIABLES* pVariables, 473 __in BURN_VARIABLES* pVariables,
482 __in BOOL fBundleInstalled, 474 __in BOOL /*fBundleInstalled*/,
483 __in BOOTSTRAPPER_DISPLAY display, 475 __in BOOTSTRAPPER_DISPLAY display,
484 __in BOOTSTRAPPER_RELATION_TYPE relationType, 476 __in BOOTSTRAPPER_RELATION_TYPE relationType,
485 __in_z_opt LPCWSTR wzLayoutDirectory, 477 __in_z_opt LPCWSTR wzLayoutDirectory,
@@ -490,12 +482,6 @@ extern "C" HRESULT PlanPackages(
490 BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine. 482 BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine.
491 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; 483 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
492 484
493 PLAN_NONPERMANENT_PACKAGE_INDICES nonpermanentPackageIndices;
494 nonpermanentPackageIndices.iAfterExecuteFirstNonPermanentPackage = BURN_PLAN_INVALID_ACTION_INDEX;
495 nonpermanentPackageIndices.iBeforeRollbackFirstNonPermanentPackage = BURN_PLAN_INVALID_ACTION_INDEX;
496 nonpermanentPackageIndices.iAfterExecuteLastNonPermanentPackage = BURN_PLAN_INVALID_ACTION_INDEX;
497 nonpermanentPackageIndices.iAfterRollbackLastNonPermanentPackage = BURN_PLAN_INVALID_ACTION_INDEX;
498
499 // Plan the packages. 485 // Plan the packages.
500 for (DWORD i = 0; i < pPackages->cPackages; ++i) 486 for (DWORD i = 0; i < pPackages->cPackages; ++i)
501 { 487 {
@@ -518,34 +504,10 @@ extern "C" HRESULT PlanPackages(
518 } 504 }
519 } 505 }
520 506
521 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, wzLayoutDirectory, phSyncpointEvent, &pRollbackBoundary, &nonpermanentPackageIndices); 507 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, wzLayoutDirectory, phSyncpointEvent, &pRollbackBoundary);
522 ExitOnFailure(hr, "Failed to process package."); 508 ExitOnFailure(hr, "Failed to process package.");
523 } 509 }
524 510
525 // Insert the "keep registration" and "remove registration" actions in the plan when installing the first time and anytime we are uninstalling respectively.
526 if (!fBundleInstalled && (BOOTSTRAPPER_ACTION_INSTALL == pPlan->action || BOOTSTRAPPER_ACTION_MODIFY == pPlan->action || BOOTSTRAPPER_ACTION_REPAIR == pPlan->action))
527 {
528 if (BURN_PLAN_INVALID_ACTION_INDEX == nonpermanentPackageIndices.iAfterExecuteFirstNonPermanentPackage)
529 {
530 nonpermanentPackageIndices.iAfterExecuteFirstNonPermanentPackage = pPlan->cExecuteActions;
531 nonpermanentPackageIndices.iBeforeRollbackFirstNonPermanentPackage = pPlan->cRollbackActions;
532 }
533
534 hr = PlanKeepRegistration(pPlan, nonpermanentPackageIndices.iAfterExecuteFirstNonPermanentPackage, nonpermanentPackageIndices.iBeforeRollbackFirstNonPermanentPackage);
535 ExitOnFailure(hr, "Failed to plan install keep registration.");
536 }
537 else if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action)
538 {
539 if (BURN_PLAN_INVALID_ACTION_INDEX == nonpermanentPackageIndices.iAfterExecuteLastNonPermanentPackage)
540 {
541 nonpermanentPackageIndices.iAfterExecuteLastNonPermanentPackage = pPlan->cExecuteActions;
542 nonpermanentPackageIndices.iAfterRollbackLastNonPermanentPackage = pPlan->cRollbackActions;
543 }
544
545 hr = PlanRemoveRegistration(pPlan, nonpermanentPackageIndices.iAfterExecuteLastNonPermanentPackage, nonpermanentPackageIndices.iAfterRollbackLastNonPermanentPackage);
546 ExitOnFailure(hr, "Failed to plan uninstall remove registration.");
547 }
548
549 // If we still have an open rollback boundary, complete it. 511 // If we still have an open rollback boundary, complete it.
550 if (pRollbackBoundary) 512 if (pRollbackBoundary)
551 { 513 {
@@ -572,9 +534,9 @@ LExit:
572extern "C" HRESULT PlanRegistration( 534extern "C" HRESULT PlanRegistration(
573 __in BURN_PLAN* pPlan, 535 __in BURN_PLAN* pPlan,
574 __in BURN_REGISTRATION* pRegistration, 536 __in BURN_REGISTRATION* pRegistration,
575 __in BOOTSTRAPPER_RESUME_TYPE resumeType, 537 __in BOOTSTRAPPER_RESUME_TYPE /*resumeType*/,
576 __in BOOTSTRAPPER_RELATION_TYPE relationType, 538 __in BOOTSTRAPPER_RELATION_TYPE relationType,
577 __out BOOL* pfContinuePlanning 539 __inout BOOL* pfContinuePlanning
578 ) 540 )
579{ 541{
580 HRESULT hr = S_OK; 542 HRESULT hr = S_OK;
@@ -583,9 +545,6 @@ extern "C" HRESULT PlanRegistration(
583 545
584 pPlan->fRegister = TRUE; // register the bundle since we're modifying machine state. 546 pPlan->fRegister = TRUE; // register the bundle since we're modifying machine state.
585 547
586 // Keep the registration if the bundle was already installed or we are planning after a restart.
587 pPlan->fKeepRegistrationDefault = (pRegistration->fInstalled || BOOTSTRAPPER_RESUME_TYPE_REBOOT == resumeType);
588
589 pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed 548 pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed
590 549
591 if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) 550 if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action)
@@ -692,7 +651,7 @@ extern "C" HRESULT PlanRegistration(
692 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; 651 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
693 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION; 652 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION;
694 } 653 }
695 else if (BOOTSTRAPPER_ACTION_REPAIR == pPlan->action && !CacheBundleRunningFromCache()) // repairing but not not running from the cache. 654 else if (BOOTSTRAPPER_ACTION_REPAIR == pPlan->action && !CacheBundleRunningFromCache()) // repairing but not running from the cache.
696 { 655 {
697 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; 656 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
698 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION; 657 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION;
@@ -786,7 +745,7 @@ extern "C" HRESULT PlanPassThroughBundle(
786 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; 745 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
787 746
788 // Plan passthrough package. 747 // Plan passthrough package.
789 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, NULL, phSyncpointEvent, &pRollbackBoundary, NULL); 748 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, NULL, phSyncpointEvent, &pRollbackBoundary);
790 ExitOnFailure(hr, "Failed to process passthrough package."); 749 ExitOnFailure(hr, "Failed to process passthrough package.");
791 750
792 // If we still have an open rollback boundary, complete it. 751 // If we still have an open rollback boundary, complete it.
@@ -820,7 +779,7 @@ extern "C" HRESULT PlanUpdateBundle(
820 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; 779 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
821 780
822 // Plan update package. 781 // Plan update package.
823 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, NULL, phSyncpointEvent, &pRollbackBoundary, NULL); 782 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, relationType, NULL, phSyncpointEvent, &pRollbackBoundary);
824 ExitOnFailure(hr, "Failed to process update package."); 783 ExitOnFailure(hr, "Failed to process update package.");
825 784
826 // If we still have an open rollback boundary, complete it. 785 // If we still have an open rollback boundary, complete it.
@@ -849,8 +808,7 @@ static HRESULT ProcessPackage(
849 __in BOOTSTRAPPER_RELATION_TYPE relationType, 808 __in BOOTSTRAPPER_RELATION_TYPE relationType,
850 __in_z_opt LPCWSTR wzLayoutDirectory, 809 __in_z_opt LPCWSTR wzLayoutDirectory,
851 __inout HANDLE* phSyncpointEvent, 810 __inout HANDLE* phSyncpointEvent,
852 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 811 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
853 __in_opt PLAN_NONPERMANENT_PACKAGE_INDICES* pNonpermanentPackageIndices
854 ) 812 )
855{ 813{
856 HRESULT hr = S_OK; 814 HRESULT hr = S_OK;
@@ -871,6 +829,12 @@ static HRESULT ProcessPackage(
871 hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary); 829 hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary);
872 ExitOnFailure(hr, "Failed to process package rollback boundary."); 830 ExitOnFailure(hr, "Failed to process package rollback boundary.");
873 831
832 if (pPackage->fCanAffectRegistration)
833 {
834 pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState;
835 pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState;
836 }
837
874 // If the package is in a requested state, plan it. 838 // If the package is in a requested state, plan it.
875 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) 839 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
876 { 840 {
@@ -881,26 +845,19 @@ static HRESULT ProcessPackage(
881 } 845 }
882 else 846 else
883 { 847 {
884 if (pPackage->fUninstallable && pNonpermanentPackageIndices)
885 {
886 if (BURN_PLAN_INVALID_ACTION_INDEX == pNonpermanentPackageIndices->iBeforeRollbackFirstNonPermanentPackage)
887 {
888 pNonpermanentPackageIndices->iBeforeRollbackFirstNonPermanentPackage = pPlan->cRollbackActions;
889 }
890 }
891
892 hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent); 848 hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
893 ExitOnFailure(hr, "Failed to plan execute package."); 849 ExitOnFailure(hr, "Failed to plan execute package.");
894 850
895 if (pPackage->fUninstallable && pNonpermanentPackageIndices) 851 if (pPackage->fCanAffectRegistration)
896 { 852 {
897 if (BURN_PLAN_INVALID_ACTION_INDEX == pNonpermanentPackageIndices->iAfterExecuteFirstNonPermanentPackage) 853 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
898 { 854 {
899 pNonpermanentPackageIndices->iAfterExecuteFirstNonPermanentPackage = pPlan->cExecuteActions - 1; 855 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
856 }
857 else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
858 {
859 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
900 } 860 }
901
902 pNonpermanentPackageIndices->iAfterExecuteLastNonPermanentPackage = pPlan->cExecuteActions;
903 pNonpermanentPackageIndices->iAfterRollbackLastNonPermanentPackage = pPlan->cRollbackActions;
904 } 861 }
905 } 862 }
906 } 863 }
@@ -920,6 +877,32 @@ static HRESULT ProcessPackage(
920 } 877 }
921 } 878 }
922 879
880 if (pPackage->fCanAffectRegistration)
881 {
882 if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute)
883 {
884 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedCacheRegistrationState)
885 {
886 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
887 }
888 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedInstallRegistrationState)
889 {
890 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
891 }
892 }
893 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pPackage->dependencyExecute)
894 {
895 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedCacheRegistrationState)
896 {
897 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
898 }
899 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedInstallRegistrationState)
900 {
901 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
902 }
903 }
904 }
905
923 // Add the checkpoint after each package and dependency registration action. 906 // Add the checkpoint after each package and dependency registration action.
924 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || BURN_DEPENDENCY_ACTION_NONE != pPackage->dependencyExecute) 907 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || BURN_DEPENDENCY_ACTION_NONE != pPackage->dependencyExecute)
925 { 908 {
@@ -1572,6 +1555,11 @@ extern "C" HRESULT PlanCleanPackage(
1572 pCleanAction->pPackage = pPackage; 1555 pCleanAction->pPackage = pPackage;
1573 1556
1574 pPackage->fUncache = TRUE; 1557 pPackage->fUncache = TRUE;
1558
1559 if (pPackage->fCanAffectRegistration)
1560 {
1561 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
1562 }
1575 } 1563 }
1576 1564
1577LExit: 1565LExit:
@@ -1708,68 +1696,6 @@ LExit:
1708 return hr; 1696 return hr;
1709} 1697}
1710 1698
1711extern "C" HRESULT PlanKeepRegistration(
1712 __in BURN_PLAN* pPlan,
1713 __in DWORD iAfterExecutePackageAction,
1714 __in DWORD iBeforeRollbackPackageAction
1715 )
1716{
1717 HRESULT hr = S_OK;
1718 BURN_EXECUTE_ACTION* pAction = NULL;
1719
1720 if (BURN_PLAN_INVALID_ACTION_INDEX != iAfterExecutePackageAction)
1721 {
1722 hr = PlanInsertExecuteAction(iAfterExecutePackageAction, pPlan, &pAction);
1723 ExitOnFailure(hr, "Failed to insert keep registration execute action.");
1724
1725 pAction->type = BURN_EXECUTE_ACTION_TYPE_REGISTRATION;
1726 pAction->registration.fKeep = TRUE;
1727 }
1728
1729 if (BURN_PLAN_INVALID_ACTION_INDEX != iBeforeRollbackPackageAction)
1730 {
1731 hr = PlanInsertRollbackAction(iBeforeRollbackPackageAction, pPlan, &pAction);
1732 ExitOnFailure(hr, "Failed to insert keep registration rollback action.");
1733
1734 pAction->type = BURN_EXECUTE_ACTION_TYPE_REGISTRATION;
1735 pAction->registration.fKeep = FALSE;
1736 }
1737
1738LExit:
1739 return hr;
1740}
1741
1742extern "C" HRESULT PlanRemoveRegistration(
1743 __in BURN_PLAN* pPlan,
1744 __in DWORD iAfterExecutePackageAction,
1745 __in DWORD iAfterRollbackPackageAction
1746 )
1747{
1748 HRESULT hr = S_OK;
1749 BURN_EXECUTE_ACTION* pAction = NULL;
1750
1751 if (BURN_PLAN_INVALID_ACTION_INDEX != iAfterExecutePackageAction)
1752 {
1753 hr = PlanInsertExecuteAction(iAfterExecutePackageAction, pPlan, &pAction);
1754 ExitOnFailure(hr, "Failed to insert remove registration execute action.");
1755
1756 pAction->type = BURN_EXECUTE_ACTION_TYPE_REGISTRATION;
1757 pAction->registration.fKeep = FALSE;
1758 }
1759
1760 if (BURN_PLAN_INVALID_ACTION_INDEX != iAfterRollbackPackageAction)
1761 {
1762 hr = PlanInsertRollbackAction(iAfterRollbackPackageAction, pPlan, &pAction);
1763 ExitOnFailure(hr, "Failed to insert remove registration rollback action.");
1764
1765 pAction->type = BURN_EXECUTE_ACTION_TYPE_REGISTRATION;
1766 pAction->registration.fKeep = TRUE;
1767 }
1768
1769LExit:
1770 return hr;
1771}
1772
1773extern "C" HRESULT PlanRollbackBoundaryBegin( 1699extern "C" HRESULT PlanRollbackBoundaryBegin(
1774 __in BURN_PLAN* pPlan, 1700 __in BURN_PLAN* pPlan,
1775 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary 1701 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
@@ -1925,6 +1851,8 @@ static void ResetPlannedPackageState(
1925 pPackage->dependencyExecute = BURN_DEPENDENCY_ACTION_NONE; 1851 pPackage->dependencyExecute = BURN_DEPENDENCY_ACTION_NONE;
1926 pPackage->dependencyRollback = BURN_DEPENDENCY_ACTION_NONE; 1852 pPackage->dependencyRollback = BURN_DEPENDENCY_ACTION_NONE;
1927 pPackage->fDependencyManagerWasHere = FALSE; 1853 pPackage->fDependencyManagerWasHere = FALSE;
1854 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1855 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1928 1856
1929 if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.rgFeatures) 1857 if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.rgFeatures)
1930 { 1858 {
@@ -2198,6 +2126,11 @@ static HRESULT AddCachePackageHelper(
2198 // did cache operations to verify the cache is valid so we did not plan the acquisition of the package. 2126 // did cache operations to verify the cache is valid so we did not plan the acquisition of the package.
2199 pPackage->fAcquire = (BURN_CACHE_STATE_COMPLETE != pPackage->cache); 2127 pPackage->fAcquire = (BURN_CACHE_STATE_COMPLETE != pPackage->cache);
2200 2128
2129 if (pPackage->fCanAffectRegistration)
2130 {
2131 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2132 }
2133
2201LExit: 2134LExit:
2202 return hr; 2135 return hr;
2203} 2136}
@@ -3118,10 +3051,6 @@ static void ExecuteActionLog(
3118 LogStringLine(PlanDumpLevel, "%ls action[%u]: MSU_PACKAGE package id: %ls, action: %hs, log path: %ls", wzBase, iAction, pAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pAction->msuPackage.action), pAction->msuPackage.sczLogPath); 3051 LogStringLine(PlanDumpLevel, "%ls action[%u]: MSU_PACKAGE package id: %ls, action: %hs, log path: %ls", wzBase, iAction, pAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pAction->msuPackage.action), pAction->msuPackage.sczLogPath);
3119 break; 3052 break;
3120 3053
3121 case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
3122 LogStringLine(PlanDumpLevel, "%ls action[%u]: REGISTRATION keep: %ls", wzBase, iAction, pAction->registration.fKeep ? L"yes" : L"no");
3123 break;
3124
3125 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: 3054 case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
3126 LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY id: %ls, vital: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no"); 3055 LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY id: %ls, vital: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no");
3127 break; 3056 break;
@@ -3157,7 +3086,6 @@ extern "C" void PlanDump(
3157 LogStringLine(PlanDumpLevel, "Plan action: %hs", LoggingBurnActionToString(pPlan->action)); 3086 LogStringLine(PlanDumpLevel, "Plan action: %hs", LoggingBurnActionToString(pPlan->action));
3158 LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); 3087 LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine));
3159 LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); 3088 LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback));
3160 LogStringLine(PlanDumpLevel, " keep registration by default: %hs", LoggingTrueFalseToString(pPlan->fKeepRegistrationDefault));
3161 LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize); 3089 LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize);
3162 3090
3163 LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal); 3091 LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal);
diff --git a/src/engine/plan.h b/src/engine/plan.h
index 54189973..6c12b5fa 100644
--- a/src/engine/plan.h
+++ b/src/engine/plan.h
@@ -64,7 +64,6 @@ enum BURN_EXECUTE_ACTION_TYPE
64 BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER, 64 BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER,
65 BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY, 65 BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY,
66 BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY, 66 BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY,
67 BURN_EXECUTE_ACTION_TYPE_REGISTRATION,
68 BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, 67 BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION,
69 BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, 68 BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION,
70}; 69};
@@ -282,10 +281,6 @@ typedef struct _BURN_EXECUTE_ACTION
282 } msuPackage; 281 } msuPackage;
283 struct 282 struct
284 { 283 {
285 BOOL fKeep;
286 } registration;
287 struct
288 {
289 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary; 284 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary;
290 } rollbackBoundary; 285 } rollbackBoundary;
291 struct 286 struct
@@ -319,7 +314,6 @@ typedef struct _BURN_PLAN
319 BOOL fPerMachine; 314 BOOL fPerMachine;
320 BOOL fRegister; 315 BOOL fRegister;
321 DWORD dwRegistrationOperations; 316 DWORD dwRegistrationOperations;
322 BOOL fKeepRegistrationDefault;
323 BOOL fDisallowRemoval; 317 BOOL fDisallowRemoval;
324 BOOL fDisableRollback; 318 BOOL fDisableRollback;
325 319
@@ -418,7 +412,7 @@ HRESULT PlanRegistration(
418 __in BURN_REGISTRATION* pRegistration, 412 __in BURN_REGISTRATION* pRegistration,
419 __in BOOTSTRAPPER_RESUME_TYPE resumeType, 413 __in BOOTSTRAPPER_RESUME_TYPE resumeType,
420 __in BOOTSTRAPPER_RELATION_TYPE relationType, 414 __in BOOTSTRAPPER_RELATION_TYPE relationType,
421 __out BOOL* pfContinuePlanning 415 __inout BOOL* pfContinuePlanning
422 ); 416 );
423HRESULT PlanPassThroughBundle( 417HRESULT PlanPassThroughBundle(
424 __in BURN_USER_EXPERIENCE* pUX, 418 __in BURN_USER_EXPERIENCE* pUX,
@@ -519,16 +513,6 @@ HRESULT PlanAppendRollbackAction(
519 __in BURN_PLAN* pPlan, 513 __in BURN_PLAN* pPlan,
520 __out BURN_EXECUTE_ACTION** ppExecuteAction 514 __out BURN_EXECUTE_ACTION** ppExecuteAction
521 ); 515 );
522HRESULT PlanKeepRegistration(
523 __in BURN_PLAN* pPlan,
524 __in DWORD iAfterExecutePackageAction,
525 __in DWORD iBeforeRollbackPackageAction
526 );
527HRESULT PlanRemoveRegistration(
528 __in BURN_PLAN* pPlan,
529 __in DWORD iAfterExecutePackageAction,
530 __in DWORD iAfterRollbackPackageAction
531 );
532HRESULT PlanRollbackBoundaryBegin( 516HRESULT PlanRollbackBoundaryBegin(
533 __in BURN_PLAN* pPlan, 517 __in BURN_PLAN* pPlan,
534 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary 518 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
diff --git a/src/test/BurnUnitTest/BurnTestFixture.h b/src/test/BurnUnitTest/BurnTestFixture.h
index 6b041641..103972ef 100644
--- a/src/test/BurnUnitTest/BurnTestFixture.h
+++ b/src/test/BurnUnitTest/BurnTestFixture.h
@@ -35,6 +35,8 @@ namespace Bootstrapper
35 35
36 LogInitialize(::GetModuleHandleW(NULL)); 36 LogInitialize(::GetModuleHandleW(NULL));
37 37
38 LogSetLevel(REPORT_DEBUG, FALSE);
39
38 hr = LogOpen(NULL, L"BurnUnitTest", NULL, L"txt", FALSE, FALSE, NULL); 40 hr = LogOpen(NULL, L"BurnUnitTest", NULL, L"txt", FALSE, FALSE, NULL);
39 TestThrowOnFailure(hr, L"Failed to open log."); 41 TestThrowOnFailure(hr, L"Failed to open log.");
40 } 42 }
diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp
index a65bef4d..a50c64e1 100644
--- a/src/test/BurnUnitTest/PlanTest.cpp
+++ b/src/test/BurnUnitTest/PlanTest.cpp
@@ -50,13 +50,12 @@ namespace Bootstrapper
50 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action); 50 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
51 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); 51 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
52 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); 52 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
53 Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
54 53
55 BOOL fRollback = FALSE; 54 BOOL fRollback = FALSE;
56 DWORD dwIndex = 0; 55 DWORD dwIndex = 0;
57 DWORD dwPackageStart = 0; 56 DWORD dwPackageStart = 0;
58 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 57 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
59 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 6, 2, 33743, FALSE); 58 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, 6, 2, 33743, FALSE);
60 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE); 59 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE);
61 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6); 60 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6);
62 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); 61 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
@@ -64,7 +63,7 @@ namespace Bootstrapper
64 ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); 63 ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
65 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); 64 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
66 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9); 65 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9);
67 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33743, FALSE); 66 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, 14, 2, 33743, FALSE);
68 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); 67 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
69 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); 68 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
70 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart); 69 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart);
@@ -72,7 +71,7 @@ namespace Bootstrapper
72 ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE); 71 ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE);
73 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); 72 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
74 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14); 73 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
75 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageC", 22, 2, 33743, FALSE); 74 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageC", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, 22, 2, 33743, FALSE);
76 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); 75 ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
77 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); 76 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
78 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart); 77 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart);
@@ -99,9 +98,8 @@ namespace Bootstrapper
99 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 98 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
100 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); 99 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
101 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 100 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
102 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 101 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
103 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 102 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
104 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
105 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER); 103 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
106 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 104 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
107 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 105 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -113,7 +111,7 @@ namespace Bootstrapper
113 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 111 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
114 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 112 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
115 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); 113 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER);
116 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 114 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
117 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 115 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
118 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER); 116 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
119 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 117 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -122,26 +120,25 @@ namespace Bootstrapper
122 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 120 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
123 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 121 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
124 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); 122 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER);
125 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 123 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
126 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 124 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
127 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER); 125 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
128 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 126 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
129 ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); 127 ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
130 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 128 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
131 ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); 129 ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent);
132 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); 130 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
133 Assert::Equal(dwIndex, pPlan->cExecuteActions); 131 Assert::Equal(dwIndex, pPlan->cExecuteActions);
134 132
135 fRollback = TRUE; 133 fRollback = TRUE;
136 dwIndex = 0; 134 dwIndex = 0;
137 dwExecuteCheckpointId = 2; 135 dwExecuteCheckpointId = 2;
138 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 136 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
139 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
140 ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 137 ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
141 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 138 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
142 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); 139 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
143 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 140 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
144 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 141 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
145 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 142 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
146 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER); 143 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
147 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 144 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -166,7 +163,7 @@ namespace Bootstrapper
166 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 163 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
167 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 164 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
168 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 165 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
169 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); 166 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN, BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
170 Assert::Equal(dwIndex, pPlan->cRollbackActions); 167 Assert::Equal(dwIndex, pPlan->cRollbackActions);
171 168
172 Assert::Equal(4ul, pPlan->cExecutePackagesTotal); 169 Assert::Equal(4ul, pPlan->cExecutePackagesTotal);
@@ -197,7 +194,6 @@ namespace Bootstrapper
197 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action); 194 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
198 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); 195 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
199 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); 196 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
200 Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
201 197
202 BOOL fRollback = FALSE; 198 BOOL fRollback = FALSE;
203 DWORD dwIndex = 0; 199 DWORD dwIndex = 0;
@@ -220,13 +216,13 @@ namespace Bootstrapper
220 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER); 216 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
221 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 217 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
222 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER); 218 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER);
223 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 219 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
224 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 220 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
225 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 221 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
226 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER); 222 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
227 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 223 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
228 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER); 224 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER);
229 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 225 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
230 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 226 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
231 ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); 227 ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
232 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 228 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -236,8 +232,7 @@ namespace Bootstrapper
236 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 232 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
237 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); 233 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
238 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 234 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
239 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 235 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
240 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
241 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 236 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
242 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 237 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
243 Assert::Equal(dwIndex, pPlan->cExecuteActions); 238 Assert::Equal(dwIndex, pPlan->cExecuteActions);
@@ -263,9 +258,8 @@ namespace Bootstrapper
263 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 258 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
264 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); 259 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
265 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 260 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
266 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 261 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
267 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 262 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
268 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
269 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 263 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
270 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 264 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
271 Assert::Equal(dwIndex, pPlan->cRollbackActions); 265 Assert::Equal(dwIndex, pPlan->cRollbackActions);
@@ -274,9 +268,9 @@ namespace Bootstrapper
274 Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); 268 Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal);
275 269
276 dwIndex = 0; 270 dwIndex = 0;
277 ValidateCleanAction(pPlan, dwIndex++, L"PackageC"); 271 ValidateCleanAction(pPlan, dwIndex++, L"PackageC", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
278 ValidateCleanAction(pPlan, dwIndex++, L"PackageB"); 272 ValidateCleanAction(pPlan, dwIndex++, L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
279 ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); 273 ValidateCleanAction(pPlan, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
280 Assert::Equal(dwIndex, pPlan->cCleanActions); 274 Assert::Equal(dwIndex, pPlan->cCleanActions);
281 275
282 UINT uIndex = 0; 276 UINT uIndex = 0;
@@ -306,13 +300,12 @@ namespace Bootstrapper
306 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_CACHE, pPlan->action); 300 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_CACHE, pPlan->action);
307 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); 301 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
308 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); 302 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
309 Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
310 303
311 BOOL fRollback = FALSE; 304 BOOL fRollback = FALSE;
312 DWORD dwIndex = 0; 305 DWORD dwIndex = 0;
313 DWORD dwPackageStart = 0; 306 DWORD dwPackageStart = 0;
314 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 307 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
315 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE); 308 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, 5, 2, 33743, FALSE);
316 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2); 309 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
317 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); 310 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
318 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); 311 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
@@ -378,13 +371,12 @@ namespace Bootstrapper
378 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action); 371 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
379 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); 372 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
380 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); 373 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
381 Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
382 374
383 BOOL fRollback = FALSE; 375 BOOL fRollback = FALSE;
384 DWORD dwIndex = 0; 376 DWORD dwIndex = 0;
385 DWORD dwPackageStart = 0; 377 DWORD dwPackageStart = 0;
386 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 378 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
387 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE); 379 dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, 5, 2, 33743, FALSE);
388 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2); 380 ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
389 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); 381 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
390 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); 382 ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
@@ -410,32 +402,30 @@ namespace Bootstrapper
410 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 402 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
411 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); 403 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
412 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 404 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
413 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 405 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
414 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 406 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
415 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
416 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER); 407 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER);
417 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 408 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
418 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 409 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
419 ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent); 410 ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
420 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); 411 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
421 Assert::Equal(dwIndex, pPlan->cExecuteActions); 412 Assert::Equal(dwIndex, pPlan->cExecuteActions);
422 413
423 fRollback = TRUE; 414 fRollback = TRUE;
424 dwIndex = 0; 415 dwIndex = 0;
425 dwExecuteCheckpointId = 2; 416 dwExecuteCheckpointId = 2;
426 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 417 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
427 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
428 ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 418 ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
429 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 419 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
430 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); 420 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
431 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 421 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
432 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 422 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
433 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 423 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
434 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER); 424 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER);
435 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 425 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
436 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 426 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
437 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 427 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
438 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); 428 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN, BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
439 Assert::Equal(dwIndex, pPlan->cRollbackActions); 429 Assert::Equal(dwIndex, pPlan->cRollbackActions);
440 430
441 Assert::Equal(2ul, pPlan->cExecutePackagesTotal); 431 Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
@@ -450,6 +440,62 @@ namespace Bootstrapper
450 } 440 }
451 441
452 [Fact] 442 [Fact]
443 void SingleMsiInstalledWithNoInstalledPackagesModifyTest()
444 {
445 HRESULT hr = S_OK;
446 BURN_ENGINE_STATE engineState = { };
447 BURN_ENGINE_STATE* pEngineState = &engineState;
448 BURN_PLAN* pPlan = &engineState.plan;
449
450 InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
451 PlanTestDetect(pEngineState);
452
453 pEngineState->registration.fInstalled = TRUE;
454
455 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY);
456 NativeAssert::Succeeded(hr, "CorePlan failed");
457
458 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_MODIFY, pPlan->action);
459 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
460 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
461
462 BOOL fRollback = FALSE;
463 DWORD dwIndex = 0;
464 Assert::Equal(dwIndex, pPlan->cCacheActions);
465
466 fRollback = TRUE;
467 dwIndex = 0;
468 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
469
470 Assert::Equal(0ull, pPlan->qwEstimatedSize);
471 Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
472
473 fRollback = FALSE;
474 dwIndex = 0;
475 DWORD dwExecuteCheckpointId = 1;
476 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
477 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
478 Assert::Equal(dwIndex, pPlan->cExecuteActions);
479
480 fRollback = TRUE;
481 dwIndex = 0;
482 dwExecuteCheckpointId = 1;
483 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
484 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
485 Assert::Equal(dwIndex, pPlan->cRollbackActions);
486
487 Assert::Equal(0ul, pPlan->cExecutePackagesTotal);
488 Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal);
489
490 dwIndex = 0;
491 Assert::Equal(dwIndex, pPlan->cCleanActions);
492
493 UINT uIndex = 0;
494 ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL);
495 Assert::Equal(uIndex, pPlan->cPlannedProviders);
496 }
497
498 [Fact]
453 void SingleMsiUninstallTest() 499 void SingleMsiUninstallTest()
454 { 500 {
455 HRESULT hr = S_OK; 501 HRESULT hr = S_OK;
@@ -466,7 +512,6 @@ namespace Bootstrapper
466 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action); 512 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
467 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); 513 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
468 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); 514 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
469 Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
470 515
471 BOOL fRollback = FALSE; 516 BOOL fRollback = FALSE;
472 DWORD dwIndex = 0; 517 DWORD dwIndex = 0;
@@ -488,8 +533,7 @@ namespace Bootstrapper
488 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 533 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
489 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); 534 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
490 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 535 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
491 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 536 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
492 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
493 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 537 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
494 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 538 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
495 Assert::Equal(dwIndex, pPlan->cExecuteActions); 539 Assert::Equal(dwIndex, pPlan->cExecuteActions);
@@ -502,9 +546,8 @@ namespace Bootstrapper
502 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 546 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
503 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); 547 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
504 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 548 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
505 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); 549 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
506 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 550 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
507 ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
508 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 551 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
509 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 552 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
510 Assert::Equal(dwIndex, pPlan->cRollbackActions); 553 Assert::Equal(dwIndex, pPlan->cRollbackActions);
@@ -513,7 +556,7 @@ namespace Bootstrapper
513 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); 556 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal);
514 557
515 dwIndex = 0; 558 dwIndex = 0;
516 ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); 559 ValidateCleanAction(pPlan, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
517 Assert::Equal(dwIndex, pPlan->cCleanActions); 560 Assert::Equal(dwIndex, pPlan->cCleanActions);
518 561
519 UINT uIndex = 0; 562 UINT uIndex = 0;
@@ -522,6 +565,66 @@ namespace Bootstrapper
522 Assert::Equal(uIndex, pPlan->cPlannedProviders); 565 Assert::Equal(uIndex, pPlan->cPlannedProviders);
523 } 566 }
524 567
568 [Fact]
569 void SingleMsiUninstallTestFromUpgradeBundleWithSameExactPackage()
570 {
571 HRESULT hr = S_OK;
572 BURN_ENGINE_STATE engineState = { };
573 BURN_ENGINE_STATE* pEngineState = &engineState;
574 BURN_PLAN* pPlan = &engineState.plan;
575
576 InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
577 DetectAsRelatedUpgradeBundle(&engineState, L"{02940F3E-C83E-452D-BFCF-C943777ACEAE}", L"2.0.0.0");
578
579 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
580 NativeAssert::Succeeded(hr, "CorePlan failed");
581
582 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
583 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
584 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
585
586 BOOL fRollback = FALSE;
587 DWORD dwIndex = 0;
588 Assert::Equal(dwIndex, pPlan->cCacheActions);
589
590 fRollback = TRUE;
591 dwIndex = 0;
592 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
593
594 Assert::Equal(0ull, pPlan->qwEstimatedSize);
595 Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
596
597 fRollback = FALSE;
598 dwIndex = 0;
599 DWORD dwExecuteCheckpointId = 1;
600 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
601 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
602 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER);
603 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
604 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
605 Assert::Equal(dwIndex, pPlan->cExecuteActions);
606
607 fRollback = TRUE;
608 dwIndex = 0;
609 dwExecuteCheckpointId = 1;
610 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
611 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER);
612 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
613 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
614 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
615 Assert::Equal(dwIndex, pPlan->cRollbackActions);
616
617 Assert::Equal(0ul, pPlan->cExecutePackagesTotal);
618 Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal);
619
620 dwIndex = 0;
621 Assert::Equal(dwIndex, pPlan->cCleanActions);
622
623 UINT uIndex = 0;
624 ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL);
625 Assert::Equal(uIndex, pPlan->cPlannedProviders);
626 }
627
525 private: 628 private:
526 // This doesn't initialize everything, just enough for CorePlan to work. 629 // This doesn't initialize everything, just enough for CorePlan to work.
527 void InitializeEngineStateForCorePlan(LPCWSTR wzManifestFileName, BURN_ENGINE_STATE* pEngineState) 630 void InitializeEngineStateForCorePlan(LPCWSTR wzManifestFileName, BURN_ENGINE_STATE* pEngineState)
@@ -586,12 +689,22 @@ namespace Bootstrapper
586 void DetectPackageAsAbsent(BURN_PACKAGE* pPackage) 689 void DetectPackageAsAbsent(BURN_PACKAGE* pPackage)
587 { 690 {
588 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; 691 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
692 if (pPackage->fCanAffectRegistration)
693 {
694 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
695 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
696 }
589 } 697 }
590 698
591 void DetectPackageAsPresentAndCached(BURN_PACKAGE* pPackage) 699 void DetectPackageAsPresentAndCached(BURN_PACKAGE* pPackage)
592 { 700 {
593 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; 701 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
594 pPackage->cache = BURN_CACHE_STATE_COMPLETE; 702 pPackage->cache = BURN_CACHE_STATE_COMPLETE;
703 if (pPackage->fCanAffectRegistration)
704 {
705 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
706 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
707 }
595 708
596 for (DWORD i = 0; i < pPackage->cPayloads; ++i) 709 for (DWORD i = 0; i < pPackage->cPayloads; ++i)
597 { 710 {
@@ -599,6 +712,19 @@ namespace Bootstrapper
599 } 712 }
600 } 713 }
601 714
715 void DetectPackageDependent(BURN_PACKAGE* pPackage, LPCWSTR wzId)
716 {
717 HRESULT hr = S_OK;
718
719 for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i)
720 {
721 BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders + i;
722
723 hr = DepDependencyArrayAlloc(&pProvider->rgDependents, &pProvider->cDependents, wzId, NULL);
724 NativeAssert::Succeeded(hr, "Failed to add package dependent");
725 }
726 }
727
602 void DetectPackagesAsAbsent(BURN_ENGINE_STATE* pEngineState) 728 void DetectPackagesAsAbsent(BURN_ENGINE_STATE* pEngineState)
603 { 729 {
604 PlanTestDetect(pEngineState); 730 PlanTestDetect(pEngineState);
@@ -620,6 +746,7 @@ namespace Bootstrapper
620 { 746 {
621 BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i; 747 BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
622 DetectPackageAsPresentAndCached(pPackage); 748 DetectPackageAsPresentAndCached(pPackage);
749 DetectPackageDependent(pPackage, pEngineState->registration.sczId);
623 } 750 }
624 } 751 }
625 752
@@ -639,11 +766,12 @@ namespace Bootstrapper
639 else 766 else
640 { 767 {
641 DetectPackageAsPresentAndCached(pPackage); 768 DetectPackageAsPresentAndCached(pPackage);
769 DetectPackageDependent(pPackage, pEngineState->registration.sczId);
642 } 770 }
643 } 771 }
644 } 772 }
645 773
646 HRESULT DetectUpgradeBundle( 774 void DetectUpgradeBundle(
647 __in BURN_ENGINE_STATE* pEngineState, 775 __in BURN_ENGINE_STATE* pEngineState,
648 __in LPCWSTR wzId, 776 __in LPCWSTR wzId,
649 __in LPCWSTR wzVersion 777 __in LPCWSTR wzVersion
@@ -654,30 +782,48 @@ namespace Bootstrapper
654 BURN_DEPENDENCY_PROVIDER dependencyProvider = { }; 782 BURN_DEPENDENCY_PROVIDER dependencyProvider = { };
655 783
656 hr = StrAllocString(&dependencyProvider.sczKey, wzId, 0); 784 hr = StrAllocString(&dependencyProvider.sczKey, wzId, 0);
657 ExitOnFailure(hr, "Failed to copy provider key"); 785 NativeAssert::Succeeded(hr, "Failed to copy provider key");
658 786
659 dependencyProvider.fImported = TRUE; 787 dependencyProvider.fImported = TRUE;
660 788
661 hr = StrAllocString(&dependencyProvider.sczVersion, wzVersion, 0); 789 hr = StrAllocString(&dependencyProvider.sczVersion, wzVersion, 0);
662 ExitOnFailure(hr, "Failed to copy version"); 790 NativeAssert::Succeeded(hr, "Failed to copy version");
663 791
664 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pRelatedBundles->rgRelatedBundles), pRelatedBundles->cRelatedBundles + 1, sizeof(BURN_RELATED_BUNDLE), 5); 792 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pRelatedBundles->rgRelatedBundles), pRelatedBundles->cRelatedBundles + 1, sizeof(BURN_RELATED_BUNDLE), 5);
665 ExitOnFailure(hr, "Failed to ensure there is space for related bundles."); 793 NativeAssert::Succeeded(hr, "Failed to ensure there is space for related bundles.");
666 794
667 BURN_RELATED_BUNDLE* pRelatedBundle = pRelatedBundles->rgRelatedBundles + pRelatedBundles->cRelatedBundles; 795 BURN_RELATED_BUNDLE* pRelatedBundle = pRelatedBundles->rgRelatedBundles + pRelatedBundles->cRelatedBundles;
668 796
669 hr = VerParseVersion(wzVersion, 0, FALSE, &pRelatedBundle->pVersion); 797 hr = VerParseVersion(wzVersion, 0, FALSE, &pRelatedBundle->pVersion);
670 ExitOnFailure(hr, "Failed to parse pseudo bundle version: %ls", wzVersion); 798 NativeAssert::Succeeded(hr, "Failed to parse pseudo bundle version: %ls", wzVersion);
671 799
672 pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE; 800 pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE;
673 801
674 hr = PseudoBundleInitialize(0, &pRelatedBundle->package, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, NULL, NULL, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0); 802 hr = PseudoBundleInitialize(0, &pRelatedBundle->package, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, NULL, NULL, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0);
675 ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId); 803 NativeAssert::Succeeded(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId);
676 804
677 ++pRelatedBundles->cRelatedBundles; 805 ++pRelatedBundles->cRelatedBundles;
806 }
807
808 void DetectAsRelatedUpgradeBundle(
809 __in BURN_ENGINE_STATE* pEngineState,
810 __in LPCWSTR wzId,
811 __in LPCWSTR wzVersion
812 )
813 {
814 HRESULT hr = StrAllocString(&pEngineState->registration.sczAncestors, wzId, 0);
815 NativeAssert::Succeeded(hr, "Failed to set registration's ancestors");
816
817 pEngineState->command.relationType = BOOTSTRAPPER_RELATION_UPGRADE;
678 818
679 LExit: 819 DetectPackagesAsPresentAndCached(pEngineState);
680 return hr; 820 DetectUpgradeBundle(pEngineState, wzId, wzVersion);
821
822 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
823 {
824 BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
825 DetectPackageDependent(pPackage, wzId);
826 }
681 } 827 }
682 828
683 void ValidateCacheAcquireContainer( 829 void ValidateCacheAcquireContainer(
@@ -755,6 +901,7 @@ namespace Bootstrapper
755 __in BOOL fRollback, 901 __in BOOL fRollback,
756 __in DWORD dwIndex, 902 __in DWORD dwIndex,
757 __in LPCWSTR wzPackageId, 903 __in LPCWSTR wzPackageId,
904 __in BURN_PACKAGE_REGISTRATION_STATE expectedCacheRegistrationState,
758 __in DWORD iPackageCompleteAction, 905 __in DWORD iPackageCompleteAction,
759 __in DWORD cCachePayloads, 906 __in DWORD cCachePayloads,
760 __in DWORD64 qwCachePayloadSizeTotal, 907 __in DWORD64 qwCachePayloadSizeTotal,
@@ -764,6 +911,7 @@ namespace Bootstrapper
764 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); 911 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
765 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type); 912 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type);
766 NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId); 913 NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId);
914 Assert::Equal<DWORD>(expectedCacheRegistrationState, pAction->packageStart.pPackage->expectedCacheRegistrationState);
767 Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction); 915 Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction);
768 Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads); 916 Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads);
769 Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal); 917 Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal);
@@ -815,7 +963,8 @@ namespace Bootstrapper
815 void ValidateCleanAction( 963 void ValidateCleanAction(
816 __in BURN_PLAN* pPlan, 964 __in BURN_PLAN* pPlan,
817 __in DWORD dwIndex, 965 __in DWORD dwIndex,
818 __in LPCWSTR wzPackageId 966 __in LPCWSTR wzPackageId,
967 __in BURN_PACKAGE_REGISTRATION_STATE expectedCacheRegistrationState
819 ) 968 )
820 { 969 {
821 Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions); 970 Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions);
@@ -823,6 +972,7 @@ namespace Bootstrapper
823 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + dwIndex; 972 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + dwIndex;
824 Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage); 973 Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage);
825 NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId); 974 NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId);
975 Assert::Equal<DWORD>(expectedCacheRegistrationState, pCleanAction->pPackage->expectedCacheRegistrationState);
826 } 976 }
827 977
828 BURN_EXECUTE_ACTION* ValidateExecuteActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex) 978 BURN_EXECUTE_ACTION* ValidateExecuteActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex)
@@ -872,6 +1022,7 @@ namespace Bootstrapper
872 __in BOOL fRollback, 1022 __in BOOL fRollback,
873 __in DWORD dwIndex, 1023 __in DWORD dwIndex,
874 __in LPCWSTR wzPackageId, 1024 __in LPCWSTR wzPackageId,
1025 __in BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState,
875 __in BOOTSTRAPPER_ACTION_STATE action, 1026 __in BOOTSTRAPPER_ACTION_STATE action,
876 __in LPCWSTR wzIgnoreDependencies 1027 __in LPCWSTR wzIgnoreDependencies
877 ) 1028 )
@@ -879,6 +1030,7 @@ namespace Bootstrapper
879 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); 1030 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
880 Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type); 1031 Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type);
881 NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId); 1032 NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId);
1033 Assert::Equal<DWORD>(expectedInstallRegistrationState, pAction->exePackage.pPackage->expectedInstallRegistrationState);
882 Assert::Equal<DWORD>(action, pAction->exePackage.action); 1034 Assert::Equal<DWORD>(action, pAction->exePackage.action);
883 NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies); 1035 NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies);
884 } 1036 }
@@ -888,6 +1040,7 @@ namespace Bootstrapper
888 __in BOOL fRollback, 1040 __in BOOL fRollback,
889 __in DWORD dwIndex, 1041 __in DWORD dwIndex,
890 __in LPCWSTR wzPackageId, 1042 __in LPCWSTR wzPackageId,
1043 __in BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState,
891 __in BOOTSTRAPPER_ACTION_STATE action, 1044 __in BOOTSTRAPPER_ACTION_STATE action,
892 __in BURN_MSI_PROPERTY actionMsiProperty, 1045 __in BURN_MSI_PROPERTY actionMsiProperty,
893 __in DWORD uiLevel, 1046 __in DWORD uiLevel,
@@ -898,6 +1051,7 @@ namespace Bootstrapper
898 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); 1051 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
899 Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, pAction->type); 1052 Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, pAction->type);
900 NativeAssert::StringEqual(wzPackageId, pAction->msiPackage.pPackage->sczId); 1053 NativeAssert::StringEqual(wzPackageId, pAction->msiPackage.pPackage->sczId);
1054 Assert::Equal<DWORD>(expectedInstallRegistrationState, pAction->msiPackage.pPackage->expectedInstallRegistrationState);
901 Assert::Equal<DWORD>(action, pAction->msiPackage.action); 1055 Assert::Equal<DWORD>(action, pAction->msiPackage.action);
902 Assert::Equal<DWORD>(actionMsiProperty, pAction->msiPackage.actionMsiProperty); 1056 Assert::Equal<DWORD>(actionMsiProperty, pAction->msiPackage.actionMsiProperty);
903 Assert::Equal<DWORD>(uiLevel, pAction->msiPackage.uiLevel); 1057 Assert::Equal<DWORD>(uiLevel, pAction->msiPackage.uiLevel);
@@ -936,18 +1090,6 @@ namespace Bootstrapper
936 Assert::Equal<DWORD>(action, pAction->packageProvider.action); 1090 Assert::Equal<DWORD>(action, pAction->packageProvider.action);
937 } 1091 }
938 1092
939 void ValidateExecuteRegistration(
940 __in BURN_PLAN* pPlan,
941 __in BOOL fRollback,
942 __in DWORD dwIndex,
943 __in BOOL fKeep
944 )
945 {
946 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
947 Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_REGISTRATION, pAction->type);
948 Assert::Equal<BOOL>(fKeep, pAction->registration.fKeep);
949 }
950
951 void ValidateExecuteRollbackBoundary( 1093 void ValidateExecuteRollbackBoundary(
952 __in BURN_PLAN* pPlan, 1094 __in BURN_PLAN* pPlan,
953 __in BOOL fRollback, 1095 __in BOOL fRollback,