aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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,