Update the logic for determining when the bundle should be registered.
The basic rule is that if a non-permanent package is present at the end of the chain, then the bundle should be registered. If no non-permanent packages are present at the end of the chain, then the bundle should not be registered. This required tracking what actually happened with each package during Apply. Include cache status in registration calculation. Include dependency ref-counting when determining whether the bundle should be registered.
Sean Hall committed
Feb 2, 2021 at 18:09 UTC
fd8c2b0899bfbce07386af245c04eb21dc01cbdf
22 files changed
+804
-267
src/engine/apply.cpp
+201
-46
@@ -46,6 +46,10 @@ static HRESULT WINAPI AuthenticationRequired(
46
__out BOOL* pfRetry
47
);
48
49
+static void CalculateKeepRegistration(
50
+ __in BURN_ENGINE_STATE* pEngineState,
51
+ __inout BOOL* pfKeepRegistration
52
+ );
53
static HRESULT ExecuteDependentRegistrationActions(
54
__in HANDLE hPipe,
55
__in const BURN_REGISTRATION* pRegistration,
@@ -141,7 +145,6 @@ static HRESULT DoExecuteAction(
145
__in BURN_EXECUTE_CONTEXT* pContext,
146
__inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
147
__inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
144
- __out BOOL* pfKeepRegistration,
148
__out BOOL* pfSuspend,
149
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
150
);
@@ -149,7 +152,6 @@ static HRESULT DoRollbackActions(
152
__in BURN_ENGINE_STATE* pEngineState,
153
__in BURN_EXECUTE_CONTEXT* pContext,
154
__in DWORD dwCheckpoint,
152
- __out BOOL* pfKeepRegistration,
155
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
156
);
157
static HRESULT ExecuteExePackage(
@@ -165,6 +167,7 @@ static HRESULT ExecuteMsiPackage(
167
__in BURN_ENGINE_STATE* pEngineState,
168
__in BURN_EXECUTE_ACTION* pExecuteAction,
169
__in BURN_EXECUTE_CONTEXT* pContext,
170
+ __in BOOL fInsideMsiTransaction,
171
__in BOOL fRollback,
172
__out BOOL* pfRetry,
173
__out BOOL* pfSuspend,
@@ -174,6 +177,7 @@ static HRESULT ExecuteMspPackage(
177
__in BURN_ENGINE_STATE* pEngineState,
178
__in BURN_EXECUTE_ACTION* pExecuteAction,
179
__in BURN_EXECUTE_CONTEXT* pContext,
180
+ __in BOOL fInsideMsiTransaction,
181
__in BOOL fRollback,
182
__out BOOL* pfRetry,
183
__out BOOL* pfSuspend,
@@ -214,6 +218,10 @@ static HRESULT ExecuteMsiRollbackTransaction(
218
__in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary,
219
__in BURN_EXECUTE_CONTEXT* pContext
220
);
221
+static void ResetTransactionRegistrationState(
222
+ __in BURN_ENGINE_STATE* pEngineState,
223
+ __in BOOL fCommit
224
+ );
225
static HRESULT CleanPackage(
226
__in HANDLE hElevatedPipe,
227
__in BURN_PACKAGE* pPackage
@@ -282,6 +290,7 @@ extern "C" void ApplyReset(
290
{
291
BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
292
pPackage->hrCacheResult = S_OK;
293
+ pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
294
}
295
}
296
@@ -380,13 +389,15 @@ LExit:
389
extern "C" HRESULT ApplyUnregister(
390
__in BURN_ENGINE_STATE* pEngineState,
391
__in BOOL fFailedOrRollback,
383
- __in BOOL fKeepRegistration,
392
__in BOOL fSuspend,
393
__in BOOTSTRAPPER_APPLY_RESTART restart
394
)
395
{
396
HRESULT hr = S_OK;
397
BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE;
398
+ BOOL fKeepRegistration = pEngineState->plan.fDisallowRemoval;
399
+
400
+ CalculateKeepRegistration(pEngineState, &fKeepRegistration);
401
402
hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience);
403
ExitOnRootFailure(hr, "BA aborted unregister begin.");
@@ -443,7 +454,7 @@ extern "C" HRESULT ApplyCache(
454
__in BURN_PLAN* pPlan,
455
__in HANDLE hPipe,
456
__inout DWORD* pcOverallProgressTicks,
446
- __out BOOL* pfRollback
457
+ __inout BOOL* pfRollback
458
)
459
{
460
HRESULT hr = S_OK;
@@ -732,7 +743,6 @@ extern "C" HRESULT ApplyExecute(
743
__in BURN_ENGINE_STATE* pEngineState,
744
__in_opt HANDLE hCacheThread,
745
__inout DWORD* pcOverallProgressTicks,
735
- __inout BOOL* pfKeepRegistration,
746
__out BOOL* pfRollback,
747
__out BOOL* pfSuspend,
748
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
@@ -779,7 +789,7 @@ extern "C" HRESULT ApplyExecute(
789
}
790
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);
793
794
if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart)
795
{
@@ -821,7 +831,7 @@ extern "C" HRESULT ApplyExecute(
831
// The action failed, roll back to previous rollback boundary.
832
if (pCheckpoint)
833
{
824
- hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pfKeepRegistration, pRestart);
834
+ hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pRestart);
835
IgnoreRollbackError(hrRollback, "Failed rollback actions");
836
}
837
@@ -855,14 +865,46 @@ extern "C" void ApplyClean(
865
for (DWORD i = 0; i < pPlan->cCleanActions; ++i)
866
{
867
BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i;
868
+ BURN_PACKAGE* pPackage = pCleanAction->pPackage;
869
859
- hr = CleanPackage(hPipe, pCleanAction->pPackage);
870
+ hr = CleanPackage(hPipe, pPackage);
871
}
872
}
873
874
875
// internal helper functions
876
877
+static 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
+
908
static HRESULT ExecuteDependentRegistrationActions(
909
__in HANDLE hPipe,
910
__in const BURN_REGISTRATION* pRegistration,
@@ -1255,6 +1297,15 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1297
LARGE_INTEGER liContainerOrPayloadSize = { };
1298
LARGE_INTEGER liZero = { };
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
+ }
1309
1310
liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize;
1311
@@ -1297,9 +1348,6 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1348
}
1349
else // complete the payload.
1350
{
1300
- Assert(!pContainer);
1301
- Assert(pPackage);
1302
-
1351
hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1352
}
1353
@@ -1307,6 +1355,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1355
// will get.
1356
if (SUCCEEDED(hr))
1357
{
1358
+ if (fCanAffectRegistration)
1359
+ {
1360
+ pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1361
+ }
1362
+
1363
CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, &progress);
1364
if (progress.fCancel)
1365
{
@@ -1639,7 +1692,6 @@ static HRESULT DoExecuteAction(
1692
__in BURN_EXECUTE_CONTEXT* pContext,
1693
__inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
1694
__inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
1642
- __out BOOL* pfKeepRegistration,
1695
__out BOOL* pfSuspend,
1696
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
1697
)
@@ -1651,11 +1703,14 @@ static HRESULT DoExecuteAction(
1703
BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
1704
BOOL fRetry = FALSE;
1705
BOOL fStopWusaService = FALSE;
1706
+ BOOL fInsideMsiTransaction = FALSE;
1707
1708
pContext->fRollback = FALSE;
1709
1710
do
1711
{
1712
+ fInsideMsiTransaction = *ppRollbackBoundary && (*ppRollbackBoundary)->fActiveTransaction;
1713
+
1714
switch (pExecuteAction->type)
1715
{
1716
case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT:
@@ -1695,12 +1750,12 @@ static HRESULT DoExecuteAction(
1750
break;
1751
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);
1754
ExitOnFailure(hr, "Failed to execute MSI package.");
1755
break;
1756
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);
1759
ExitOnFailure(hr, "Failed to execute MSP package.");
1760
break;
1761
@@ -1720,8 +1775,6 @@ static HRESULT DoExecuteAction(
1775
ExitOnFailure(hr, "Failed to execute dependency action.");
1776
break;
1777
1723
- case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
1724
- *pfKeepRegistration = pExecuteAction->registration.fKeep;
1778
break;
1779
1780
case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
@@ -1757,7 +1810,6 @@ static HRESULT DoRollbackActions(
1810
__in BURN_ENGINE_STATE* pEngineState,
1811
__in BURN_EXECUTE_CONTEXT* pContext,
1812
__in DWORD dwCheckpoint,
1760
- __out BOOL* pfKeepRegistration,
1813
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
1814
)
1815
{
@@ -1811,12 +1863,12 @@ static HRESULT DoRollbackActions(
1863
break;
1864
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);
1867
IgnoreRollbackError(hr, "Failed to rollback MSI package.");
1868
break;
1869
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);
1872
IgnoreRollbackError(hr, "Failed to rollback MSP package.");
1873
break;
1874
@@ -1835,10 +1887,6 @@ static HRESULT DoRollbackActions(
1887
IgnoreRollbackError(hr, "Failed to rollback dependency action.");
1888
break;
1889
1838
- case BURN_EXECUTE_ACTION_TYPE_REGISTRATION:
1839
- *pfKeepRegistration = pRollbackAction->registration.fKeep;
1840
- break;
1841
-
1890
case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
1891
ExitFunction1(hr = S_OK);
1892
@@ -1878,19 +1926,21 @@ static HRESULT ExecuteExePackage(
1926
GENERIC_EXECUTE_MESSAGE message = { };
1927
int nResult = 0;
1928
BOOL fBeginCalled = FALSE;
1929
+ BOOL fExecuted = FALSE;
1930
+ BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage;
1931
1882
- if (FAILED(pExecuteAction->exePackage.pPackage->hrCacheResult))
1932
+ if (FAILED(pPackage->hrCacheResult))
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);
1935
ExitFunction1(hr = S_OK);
1936
}
1937
1938
Assert(pContext->fRollback == fRollback);
1889
- pContext->pExecutingPackage = pExecuteAction->exePackage.pPackage;
1939
+ pContext->pExecutingPackage = pPackage;
1940
fBeginCalled = TRUE;
1941
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);
1944
ExitOnRootFailure(hr, "BA aborted execute EXE package begin.");
1945
1946
message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
@@ -1900,8 +1950,10 @@ static HRESULT ExecuteExePackage(
1950
hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult);
1951
ExitOnRootFailure(hr, "BA aborted EXE progress.");
1952
1953
+ fExecuted = TRUE;
1954
+
1955
// Execute package.
1904
- if (pExecuteAction->exePackage.pPackage->fPerMachine)
1956
+ if (pPackage->fPerMachine)
1957
{
1958
hrExecute = ElevationExecuteExePackage(pEngineState->companionConnection.hPipe, pExecuteAction, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart);
1959
ExitOnFailure(hrExecute, "Failed to configure per-machine EXE package.");
@@ -1926,9 +1978,14 @@ static HRESULT ExecuteExePackage(
1978
ExitOnRootFailure(hr, "BA aborted EXE package execute progress.");
1979
1980
LExit:
1981
+ if (fExecuted)
1982
+ {
1983
+ ExeEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute);
1984
+ }
1985
+
1986
if (fBeginCalled)
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);
1989
}
1990
1991
return hr;
@@ -1938,6 +1995,7 @@ static HRESULT ExecuteMsiPackage(
1995
__in BURN_ENGINE_STATE* pEngineState,
1996
__in BURN_EXECUTE_ACTION* pExecuteAction,
1997
__in BURN_EXECUTE_CONTEXT* pContext,
1998
+ __in BOOL fInsideMsiTransaction,
1999
__in BOOL fRollback,
2000
__out BOOL* pfRetry,
2001
__out BOOL* pfSuspend,
@@ -1947,23 +2005,27 @@ static HRESULT ExecuteMsiPackage(
2005
HRESULT hr = S_OK;
2006
HRESULT hrExecute = S_OK;
2007
BOOL fBeginCalled = FALSE;
2008
+ BOOL fExecuted = FALSE;
2009
+ BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage;
2010
1951
- if (FAILED(pExecuteAction->msiPackage.pPackage->hrCacheResult))
2011
+ if (FAILED(pPackage->hrCacheResult))
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);
2014
ExitFunction1(hr = S_OK);
2015
}
2016
2017
Assert(pContext->fRollback == fRollback);
1958
- pContext->pExecutingPackage = pExecuteAction->msiPackage.pPackage;
2018
+ pContext->pExecutingPackage = pPackage;
2019
fBeginCalled = TRUE;
2020
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);
2023
ExitOnRootFailure(hr, "BA aborted execute MSI package begin.");
2024
2025
+ fExecuted = TRUE;
2026
+
2027
// execute package
1966
- if (pExecuteAction->msiPackage.pPackage->fPerMachine)
2028
+ if (pPackage->fPerMachine)
2029
{
2030
hrExecute = ElevationExecuteMsiPackage(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart);
2031
ExitOnFailure(hrExecute, "Failed to configure per-machine MSI package.");
@@ -1981,9 +2043,14 @@ static HRESULT ExecuteMsiPackage(
2043
ExitOnRootFailure(hr, "BA aborted MSI package execute progress.");
2044
2045
LExit:
2046
+ if (fExecuted)
2047
+ {
2048
+ MsiEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute, fInsideMsiTransaction);
2049
+ }
2050
+
2051
if (fBeginCalled)
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);
2054
}
2055
2056
return hr;
@@ -1993,6 +2060,7 @@ static HRESULT ExecuteMspPackage(
2060
__in BURN_ENGINE_STATE* pEngineState,
2061
__in BURN_EXECUTE_ACTION* pExecuteAction,
2062
__in BURN_EXECUTE_CONTEXT* pContext,
2063
+ __in BOOL fInsideMsiTransaction,
2064
__in BOOL fRollback,
2065
__out BOOL* pfRetry,
2066
__out BOOL* pfSuspend,
@@ -2002,19 +2070,21 @@ static HRESULT ExecuteMspPackage(
2070
HRESULT hr = S_OK;
2071
HRESULT hrExecute = S_OK;
2072
BOOL fBeginCalled = FALSE;
2073
+ BOOL fExecuted = FALSE;
2074
+ BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage;
2075
2006
- if (FAILED(pExecuteAction->mspTarget.pPackage->hrCacheResult))
2076
+ if (FAILED(pPackage->hrCacheResult))
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);
2079
ExitFunction1(hr = S_OK);
2080
}
2081
2082
Assert(pContext->fRollback == fRollback);
2013
- pContext->pExecutingPackage = pExecuteAction->mspTarget.pPackage;
2083
+ pContext->pExecutingPackage = pPackage;
2084
fBeginCalled = TRUE;
2085
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);
2088
ExitOnRootFailure(hr, "BA aborted execute MSP package begin.");
2089
2090
// Now send all the patches that target this product code.
@@ -2026,6 +2096,8 @@ static HRESULT ExecuteMspPackage(
2096
ExitOnRootFailure(hr, "BA aborted execute MSP target.");
2097
}
2098
2099
+ fExecuted = TRUE;
2100
+
2101
// execute package
2102
if (pExecuteAction->mspTarget.fPerMachineTarget)
2103
{
@@ -2045,9 +2117,14 @@ static HRESULT ExecuteMspPackage(
2117
ExitOnRootFailure(hr, "BA aborted MSP package execute progress.");
2118
2119
LExit:
2120
+ if (fExecuted)
2121
+ {
2122
+ MspEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute, fInsideMsiTransaction);
2123
+ }
2124
+
2125
if (fBeginCalled)
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);
2128
}
2129
2130
return hr;
@@ -2069,19 +2146,21 @@ static HRESULT ExecuteMsuPackage(
2146
GENERIC_EXECUTE_MESSAGE message = { };
2147
int nResult = 0;
2148
BOOL fBeginCalled = FALSE;
2149
+ BOOL fExecuted = FALSE;
2150
+ BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage;
2151
2073
- if (FAILED(pExecuteAction->msuPackage.pPackage->hrCacheResult))
2152
+ if (FAILED(pPackage->hrCacheResult))
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);
2155
ExitFunction1(hr = S_OK);
2156
}
2157
2158
Assert(pContext->fRollback == fRollback);
2080
- pContext->pExecutingPackage = pExecuteAction->msuPackage.pPackage;
2159
+ pContext->pExecutingPackage = pPackage;
2160
fBeginCalled = TRUE;
2161
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);
2164
ExitOnRootFailure(hr, "BA aborted execute MSU package begin.");
2165
2166
message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
@@ -2091,8 +2170,10 @@ static HRESULT ExecuteMsuPackage(
2170
hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult);
2171
ExitOnRootFailure(hr, "BA aborted MSU progress.");
2172
2173
+ fExecuted = TRUE;
2174
+
2175
// execute package
2095
- if (pExecuteAction->msuPackage.pPackage->fPerMachine)
2176
+ if (pPackage->fPerMachine)
2177
{
2178
hrExecute = ElevationExecuteMsuPackage(pEngineState->companionConnection.hPipe, pExecuteAction, fRollback, fStopWusaService, GenericExecuteMessageHandler, pContext, pRestart);
2179
ExitOnFailure(hrExecute, "Failed to configure per-machine MSU package.");
@@ -2117,9 +2198,14 @@ static HRESULT ExecuteMsuPackage(
2198
ExitOnRootFailure(hr, "BA aborted MSU package execute progress.");
2199
2200
LExit:
2201
+ if (fExecuted)
2202
+ {
2203
+ MsuEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute);
2204
+ }
2205
+
2206
if (fBeginCalled)
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);
2209
}
2210
2211
return hr;
@@ -2167,6 +2253,32 @@ static HRESULT ExecuteDependencyAction(
2253
ExitOnFailure(hr, "Failed to register the dependency on per-user package.");
2254
}
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
+
2282
LExit:
2283
return hr;
2284
}
@@ -2202,6 +2314,8 @@ static HRESULT ExecuteMsiBeginTransaction(
2314
if (SUCCEEDED(hr))
2315
{
2316
pRollbackBoundary->fActiveTransaction = TRUE;
2317
+
2318
+ ResetTransactionRegistrationState(pEngineState, FALSE);
2319
}
2320
2321
LExit:
@@ -2244,6 +2358,8 @@ static HRESULT ExecuteMsiCommitTransaction(
2358
if (SUCCEEDED(hr))
2359
{
2360
pRollbackBoundary->fActiveTransaction = FALSE;
2361
+
2362
+ ResetTransactionRegistrationState(pEngineState, TRUE);
2363
}
2364
2365
LExit:
@@ -2285,6 +2401,8 @@ static HRESULT ExecuteMsiRollbackTransaction(
2401
LExit:
2402
pRollbackBoundary->fActiveTransaction = FALSE;
2403
2404
+ ResetTransactionRegistrationState(pEngineState, FALSE);
2405
+
2406
if (fBeginCalled)
2407
{
2408
UserExperienceOnRollbackMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr);
@@ -2293,6 +2411,38 @@ LExit:
2411
return hr;
2412
}
2413
2414
+static 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
+
2446
static HRESULT CleanPackage(
2447
__in HANDLE hElevatedPipe,
2448
__in BURN_PACKAGE* pPackage
@@ -2309,6 +2459,11 @@ static HRESULT CleanPackage(
2459
hr = CacheRemovePackage(FALSE, pPackage->sczId, pPackage->sczCacheId);
2460
}
2461
2462
+ if (pPackage->fCanAffectRegistration)
2463
+ {
2464
+ pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
2465
+ }
2466
+
2467
return hr;
2468
}
2469
src/engine/apply.h
+1
-3
@@ -72,7 +72,6 @@ HRESULT ApplyRegister(
72
HRESULT ApplyUnregister(
73
__in BURN_ENGINE_STATE* pEngineState,
74
__in BOOL fFailedOrRollback,
75
- __in BOOL fRollback,
75
__in BOOL fSuspend,
76
__in BOOTSTRAPPER_APPLY_RESTART restart
77
);
@@ -83,13 +82,12 @@ HRESULT ApplyCache(
82
__in BURN_PLAN* pPlan,
83
__in HANDLE hPipe,
84
__inout DWORD* pcOverallProgressTicks,
86
- __out BOOL* pfRollback
85
+ __inout BOOL* pfRollback
86
);
87
HRESULT ApplyExecute(
88
__in BURN_ENGINE_STATE* pEngineState,
89
__in_opt HANDLE hCacheThread,
90
__inout DWORD* pcOverallProgressTicks,
92
- __inout BOOL* pfKeepRegistration,
91
__out BOOL* pfRollback,
92
__out BOOL* pfSuspend,
93
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
src/engine/core.cpp
+12
-6
@@ -331,6 +331,8 @@ extern "C" HRESULT CoreDetect(
331
}
332
333
pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN;
334
+ pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
335
+ pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
336
}
337
}
338
@@ -342,7 +344,7 @@ extern "C" HRESULT CoreDetect(
344
{
345
pPackage = pEngineState->packages.rgPackages + iPackage;
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));
348
349
if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
350
{
@@ -565,7 +567,6 @@ extern "C" HRESULT CoreApply(
567
BOOL fApplyInitialize = FALSE;
568
BOOL fElevated = FALSE;
569
BOOL fRegistered = FALSE;
568
- BOOL fKeepRegistration = pEngineState->plan.fKeepRegistrationDefault;
570
BOOL fRollback = FALSE;
571
BOOL fSuspend = FALSE;
572
BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
@@ -652,9 +653,9 @@ extern "C" HRESULT CoreApply(
653
// Register.
654
if (pEngineState->plan.fRegister)
655
{
656
+ fRegistered = TRUE;
657
hr = ApplyRegister(pEngineState);
658
ExitOnFailure(hr, "Failed to register bundle.");
657
- fRegistered = TRUE;
659
}
660
661
// Cache.
@@ -681,7 +682,7 @@ extern "C" HRESULT CoreApply(
682
// Execute.
683
if (pEngineState->plan.cExecuteActions)
684
{
684
- hr = ApplyExecute(pEngineState, hCacheThread, &cOverallProgressTicks, &fKeepRegistration, &fRollback, &fSuspend, &restart);
685
+ hr = ApplyExecute(pEngineState, hCacheThread, &cOverallProgressTicks, &fRollback, &fSuspend, &restart);
686
UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed.
687
}
688
@@ -711,7 +712,7 @@ LExit:
712
// Unregister.
713
if (fRegistered)
714
{
714
- ApplyUnregister(pEngineState, FAILED(hr) || fRollback, fKeepRegistration || pEngineState->plan.fDisallowRemoval, fSuspend, restart);
715
+ ApplyUnregister(pEngineState, FAILED(hr) || fRollback, fSuspend, restart);
716
}
717
718
if (fElevated)
@@ -1611,6 +1612,11 @@ static HRESULT DetectPackagePayloadsCached(
1612
1613
pPackage->cache = cache;
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
+
1620
LExit:
1621
ReleaseStr(sczPayloadCachePath);
1622
ReleaseStr(sczCachePath);
@@ -1703,7 +1709,7 @@ static void LogPackages(
1709
const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i;
1710
const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage];
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));
1713
}
1714
1715
// Display related bundles last if caching, installing, modifying, or repairing.
src/engine/dependency.cpp
+29
@@ -708,6 +708,9 @@ static HRESULT DetectPackageDependents(
708
{
709
HRESULT hr = S_OK;
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;
714
715
// There's currently no point in getting the dependents if the scope doesn't match,
716
// because they will just get ignored.
@@ -729,6 +732,20 @@ static HRESULT DetectPackageDependents(
732
{
733
pPackage->fPackageProviderExists = TRUE;
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
+ }
749
}
750
else
751
{
@@ -747,6 +764,18 @@ static HRESULT DetectPackageDependents(
764
pPackage->fPackageProviderExists = TRUE;
765
}
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
+
779
LExit:
780
return hr;
781
}
src/engine/detect.cpp
+2
@@ -63,6 +63,8 @@ extern "C" void DetectReset(
63
64
pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN;
65
pPackage->fPackageProviderExists = FALSE;
66
+ pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
67
+ pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
68
69
pPackage->cache = BURN_CACHE_STATE_NONE;
70
for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload)
src/engine/engine.mc
+17
-2
@@ -188,7 +188,7 @@ MessageId=101
188
Severity=Success
189
SymbolicName=MSG_DETECTED_PACKAGE
190
Language=English
191
-Detected package: %1!ls!, state: %2!hs!, cached: %3!hs!
191
+Detected package: %1!ls!, state: %2!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs!
192
.
193
194
MessageId=102
@@ -300,7 +300,7 @@ MessageId=201
300
Severity=Success
301
SymbolicName=MSG_PLANNED_PACKAGE
302
Language=English
303
-Planned 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!
303
+Planned 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
.
305
306
MessageId=202
@@ -829,6 +829,21 @@ Language=English
829
Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs!
830
.
831
832
+MessageId=373
833
+Severity=Success
834
+SymbolicName=MSG_POST_APPLY_CALCULATE_REGISTRATION
835
+Language=English
836
+Calculating whether to keep registration
837
+.
838
+
839
+
840
+MessageId=374
841
+Severity=Success
842
+SymbolicName=MSG_POST_APPLY_PACKAGE
843
+Language=English
844
+ package: %1!ls!, install registration state: %2!hs!, cache registration state: %3!hs!
845
+.
846
+
847
MessageId=380
848
Severity=Warning
849
SymbolicName=MSG_APPLY_SKIPPED
src/engine/exeengine.cpp
+30
@@ -145,6 +145,11 @@ extern "C" HRESULT ExeEngineDetectPackage(
145
// update detect state
146
pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
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
+
153
LExit:
154
return hr;
155
}
@@ -585,6 +590,31 @@ LExit:
590
return hr;
591
}
592
593
+extern "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
+
614
+LExit:
615
+ return;
616
+}
617
+
618
619
// internal helper functions
620
src/engine/exeengine.h
+4
@@ -41,6 +41,10 @@ HRESULT ExeEngineExecutePackage(
41
__in LPVOID pvContext,
42
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
43
);
44
+void ExeEngineUpdateInstallRegistrationState(
45
+ __in BURN_EXECUTE_ACTION* pAction,
46
+ __in HRESULT hrExecute
47
+ );
48
49
50
#if defined(__cplusplus)
src/engine/logging.cpp
+25
@@ -399,6 +399,31 @@ extern "C" LPCSTR LoggingPackageStateToString(
399
}
400
}
401
402
+extern "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
+
427
extern "C" LPCSTR LoggingCacheStateToString(
428
__in BURN_CACHE_STATE cacheState
429
)
src/engine/logging.h
+5
@@ -89,6 +89,11 @@ LPCSTR LoggingPackageStateToString(
89
__in BOOTSTRAPPER_PACKAGE_STATE packageState
90
);
91
92
+LPCSTR LoggingPackageRegistrationStateToString(
93
+ __in BOOL fCanAffectRegistration,
94
+ __in BURN_PACKAGE_REGISTRATION_STATE registrationState
95
+ );
96
+
97
LPCSTR LoggingCacheStateToString(
98
__in BURN_CACHE_STATE cacheState
99
);
src/engine/msiengine.cpp
+41
@@ -661,6 +661,11 @@ extern "C" HRESULT MsiEngineDetectPackage(
661
}
662
}
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
+
669
LExit:
670
ReleaseStr(sczInstalledLanguage);
671
ReleaseStr(sczInstalledVersion);
@@ -1397,6 +1402,42 @@ extern "C" HRESULT MsiEngineCalculateInstallUiLevel(
1402
return UserExperienceOnPlanMsiPackage(pUserExperience, wzPackageId, fExecute, actionState, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler);
1403
}
1404
1405
+extern "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
+
1437
+LExit:
1438
+ return;
1439
+}
1440
+
1441
1442
// internal helper functions
1443
src/engine/msiengine.h
+5
@@ -88,6 +88,11 @@ HRESULT MsiEngineCalculateInstallUiLevel(
88
__out INSTALLUILEVEL* pUiLevel,
89
__out BOOL* pfDisableExternalUiHandler
90
);
91
+void MsiEngineUpdateInstallRegistrationState(
92
+ __in BURN_EXECUTE_ACTION* pAction,
93
+ __in HRESULT hrExecute,
94
+ __in BOOL fInsideMsiTransaction
95
+ );
96
97
#if defined(__cplusplus)
98
}
src/engine/mspengine.cpp
+107
-2
@@ -200,20 +200,26 @@ extern "C" HRESULT MspEngineDetectPackage(
200
HRESULT hr = S_OK;
201
LPWSTR sczState = NULL;
202
203
+ if (pPackage->fCanAffectRegistration)
204
+ {
205
+ pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
206
+ }
207
+
208
if (0 == pPackage->Msp.cTargetProductCodes)
209
{
210
pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
211
}
212
else
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
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.
217
pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
218
219
for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
220
{
221
BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
222
+ BOOL fInstalled = FALSE;
223
224
hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState);
225
if (SUCCEEDED(hr))
@@ -221,14 +227,17 @@ extern "C" HRESULT MspEngineDetectPackage(
227
switch (*sczState)
228
{
229
case '1':
230
+ fInstalled = TRUE;
231
pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
232
break;
233
234
case '2':
235
+ fInstalled = TRUE;
236
pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
237
break;
238
239
case '4':
240
+ fInstalled = TRUE;
241
pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE;
242
break;
243
@@ -249,6 +258,16 @@ extern "C" HRESULT MspEngineDetectPackage(
258
pPackage->currentState = pTargetProduct->patchPackageState;
259
}
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
+
271
hr = UserExperienceOnDetectTargetMsiPackage(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState);
272
ExitOnRootFailure(hr, "BA aborted detect target MSI package.");
273
}
@@ -642,6 +661,92 @@ extern "C" void MspEngineSlipstreamUpdateState(
661
}
662
}
663
664
+extern "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
+
727
+LExit:
728
+ return;
729
+}
730
+
731
+extern "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
+
750
751
// internal helper functions
752
src/engine/mspengine.h
+8
@@ -62,6 +62,14 @@ void MspEngineSlipstreamUpdateState(
62
__in BOOTSTRAPPER_ACTION_STATE execute,
63
__in BOOTSTRAPPER_ACTION_STATE rollback
64
);
65
+void MspEngineUpdateInstallRegistrationState(
66
+ __in BURN_EXECUTE_ACTION* pAction,
67
+ __in HRESULT hrExecute,
68
+ __in BOOL fInsideMsiTransaction
69
+ );
70
+void MspEngineFinalizeInstallRegistrationState(
71
+ __in BURN_PACKAGE* pPackage
72
+ );
73
74
75
#if defined(__cplusplus)
src/engine/msuengine.cpp
+30
@@ -69,6 +69,11 @@ extern "C" HRESULT MsuEngineDetectPackage(
69
// update detect state
70
pPackage->currentState = fDetected ? BOOTSTRAPPER_PACKAGE_STATE_PRESENT : BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
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
+
77
LExit:
78
return hr;
79
}
@@ -424,6 +429,31 @@ LExit:
429
return hr;
430
}
431
432
+extern "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
+
453
+LExit:
454
+ return;
455
+}
456
+
457
static HRESULT EnsureWUServiceEnabled(
458
__in BOOL fStopWusaService,
459
__out SC_HANDLE* pschWu,
src/engine/msuengine.h
+4
@@ -41,6 +41,10 @@ HRESULT MsuEngineExecutePackage(
41
__in LPVOID pvContext,
42
__out BOOTSTRAPPER_APPLY_RESTART* pRestart
43
);
44
+void MsuEngineUpdateInstallRegistrationState(
45
+ __in BURN_EXECUTE_ACTION* pAction,
46
+ __in HRESULT hrExecute
47
+ );
48
49
50
#if defined(__cplusplus)
src/engine/package.cpp
+1
@@ -156,6 +156,7 @@ extern "C" HRESULT PackagesParseFromXml(
156
hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fUninstallable);
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.
159
+ pPackage->fCanAffectRegistration = pPackage->fUninstallable;
160
161
// @Vital
162
hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital);
src/engine/package.h
+18
@@ -78,6 +78,14 @@ enum BOOTSTRAPPER_FEATURE_ACTION
78
BOOTSTRAPPER_FEATURE_ACTION_REMOVE,
79
};
80
81
+enum 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
+
89
// structs
90
91
typedef struct _BURN_EXE_EXIT_CODE
@@ -106,6 +114,9 @@ typedef struct _BURN_MSPTARGETPRODUCT
114
BOOTSTRAPPER_PACKAGE_STATE patchPackageState; // only valid after Detect.
115
BOOTSTRAPPER_ACTION_STATE execute; // 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.
120
} BURN_MSPTARGETPRODUCT;
121
122
typedef struct _BURN_MSIPROPERTY
@@ -190,6 +201,7 @@ typedef struct _BURN_PACKAGE
201
BOOL fPerMachine;
202
BOOL fUninstallable;
203
BOOL fVital;
204
+ BOOL fCanAffectRegistration;
205
206
BURN_CACHE_TYPE cacheType;
207
LPWSTR sczCacheId;
@@ -216,6 +228,12 @@ typedef struct _BURN_PACKAGE
228
BOOL fDependencyManagerWasHere; // only valid during Plan.
229
HRESULT hrCacheResult; // only valid during Apply.
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
+
237
BURN_PACKAGE_PAYLOAD* rgPayloads;
238
DWORD cPayloads;
239
src/engine/plan.cpp
+60
-132
@@ -6,13 +6,6 @@
6
7
// internal struct definitions
8
9
-struct PLAN_NONPERMANENT_PACKAGE_INDICES
10
-{
11
- DWORD iAfterExecuteFirstNonPermanentPackage;
12
- DWORD iBeforeRollbackFirstNonPermanentPackage;
13
- DWORD iAfterExecuteLastNonPermanentPackage;
14
- DWORD iAfterRollbackLastNonPermanentPackage;
15
-};
9
10
// internal function definitions
11
@@ -39,8 +32,7 @@ static HRESULT ProcessPackage(
32
__in BOOTSTRAPPER_RELATION_TYPE relationType,
33
__in_z_opt LPCWSTR wzLayoutDirectory,
34
__inout HANDLE* phSyncpointEvent,
42
- __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
43
- __in_opt PLAN_NONPERMANENT_PACKAGE_INDICES* pNonpermanentPackageIndices
35
+ __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
36
);
37
static HRESULT ProcessPackageRollbackBoundary(
38
__in BURN_PLAN* pPlan,
@@ -479,7 +471,7 @@ extern "C" HRESULT PlanPackages(
471
__in BURN_PLAN* pPlan,
472
__in BURN_LOGGING* pLog,
473
__in BURN_VARIABLES* pVariables,
482
- __in BOOL fBundleInstalled,
474
+ __in BOOL /*fBundleInstalled*/,
475
__in BOOTSTRAPPER_DISPLAY display,
476
__in BOOTSTRAPPER_RELATION_TYPE relationType,
477
__in_z_opt LPCWSTR wzLayoutDirectory,
@@ -490,12 +482,6 @@ extern "C" HRESULT PlanPackages(
482
BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine.
483
BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
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
-
485
// Plan the packages.
486
for (DWORD i = 0; i < pPackages->cPackages; ++i)
487
{
@@ -518,34 +504,10 @@ extern "C" HRESULT PlanPackages(
504
}
505
}
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);
508
ExitOnFailure(hr, "Failed to process package.");
509
}
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
-
511
// If we still have an open rollback boundary, complete it.
512
if (pRollbackBoundary)
513
{
@@ -572,9 +534,9 @@ LExit:
534
extern "C" HRESULT PlanRegistration(
535
__in BURN_PLAN* pPlan,
536
__in BURN_REGISTRATION* pRegistration,
575
- __in BOOTSTRAPPER_RESUME_TYPE resumeType,
537
+ __in BOOTSTRAPPER_RESUME_TYPE /*resumeType*/,
538
__in BOOTSTRAPPER_RELATION_TYPE relationType,
577
- __out BOOL* pfContinuePlanning
539
+ __inout BOOL* pfContinuePlanning
540
)
541
{
542
HRESULT hr = S_OK;
@@ -583,9 +545,6 @@ extern "C" HRESULT PlanRegistration(
545
546
pPlan->fRegister = TRUE; // register the bundle since we're modifying machine state.
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
-
548
pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed
549
550
if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action)
@@ -692,7 +651,7 @@ extern "C" HRESULT PlanRegistration(
651
pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
652
pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION;
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.
655
{
656
pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
657
pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION;
@@ -786,7 +745,7 @@ extern "C" HRESULT PlanPassThroughBundle(
745
BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
746
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);
749
ExitOnFailure(hr, "Failed to process passthrough package.");
750
751
// If we still have an open rollback boundary, complete it.
@@ -820,7 +779,7 @@ extern "C" HRESULT PlanUpdateBundle(
779
BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
780
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);
783
ExitOnFailure(hr, "Failed to process update package.");
784
785
// If we still have an open rollback boundary, complete it.
@@ -849,8 +808,7 @@ static HRESULT ProcessPackage(
808
__in BOOTSTRAPPER_RELATION_TYPE relationType,
809
__in_z_opt LPCWSTR wzLayoutDirectory,
810
__inout HANDLE* phSyncpointEvent,
852
- __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
853
- __in_opt PLAN_NONPERMANENT_PACKAGE_INDICES* pNonpermanentPackageIndices
811
+ __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
812
)
813
{
814
HRESULT hr = S_OK;
@@ -871,6 +829,12 @@ static HRESULT ProcessPackage(
829
hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary);
830
ExitOnFailure(hr, "Failed to process package rollback boundary.");
831
832
+ if (pPackage->fCanAffectRegistration)
833
+ {
834
+ pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState;
835
+ pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState;
836
+ }
837
+
838
// If the package is in a requested state, plan it.
839
if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
840
{
@@ -881,26 +845,19 @@ static HRESULT ProcessPackage(
845
}
846
else
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
-
848
hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
849
ExitOnFailure(hr, "Failed to plan execute package.");
850
895
- if (pPackage->fUninstallable && pNonpermanentPackageIndices)
851
+ if (pPackage->fCanAffectRegistration)
852
{
897
- if (BURN_PLAN_INVALID_ACTION_INDEX == pNonpermanentPackageIndices->iAfterExecuteFirstNonPermanentPackage)
853
+ if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
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;
860
}
901
-
902
- pNonpermanentPackageIndices->iAfterExecuteLastNonPermanentPackage = pPlan->cExecuteActions;
903
- pNonpermanentPackageIndices->iAfterRollbackLastNonPermanentPackage = pPlan->cRollbackActions;
861
}
862
}
863
}
@@ -920,6 +877,32 @@ static HRESULT ProcessPackage(
877
}
878
}
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
+
906
// Add the checkpoint after each package and dependency registration action.
907
if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || BURN_DEPENDENCY_ACTION_NONE != pPackage->dependencyExecute)
908
{
@@ -1572,6 +1555,11 @@ extern "C" HRESULT PlanCleanPackage(
1555
pCleanAction->pPackage = pPackage;
1556
1557
pPackage->fUncache = TRUE;
1558
+
1559
+ if (pPackage->fCanAffectRegistration)
1560
+ {
1561
+ pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
1562
+ }
1563
}
1564
1565
LExit:
@@ -1708,68 +1696,6 @@ LExit:
1696
return hr;
1697
}
1698
1711
-extern "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
-
1738
-LExit:
1739
- return hr;
1740
-}
1741
-
1742
-extern "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
-
1769
-LExit:
1770
- return hr;
1771
-}
1772
-
1699
extern "C" HRESULT PlanRollbackBoundaryBegin(
1700
__in BURN_PLAN* pPlan,
1701
__in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
@@ -1925,6 +1851,8 @@ static void ResetPlannedPackageState(
1851
pPackage->dependencyExecute = BURN_DEPENDENCY_ACTION_NONE;
1852
pPackage->dependencyRollback = BURN_DEPENDENCY_ACTION_NONE;
1853
pPackage->fDependencyManagerWasHere = FALSE;
1854
+ pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1855
+ pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1856
1857
if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.rgFeatures)
1858
{
@@ -2198,6 +2126,11 @@ static HRESULT AddCachePackageHelper(
2126
// did cache operations to verify the cache is valid so we did not plan the acquisition of the package.
2127
pPackage->fAcquire = (BURN_CACHE_STATE_COMPLETE != pPackage->cache);
2128
2129
+ if (pPackage->fCanAffectRegistration)
2130
+ {
2131
+ pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2132
+ }
2133
+
2134
LExit:
2135
return hr;
2136
}
@@ -3118,10 +3051,6 @@ static void ExecuteActionLog(
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);
3052
break;
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
-
3054
case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY:
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");
3056
break;
@@ -3157,7 +3086,6 @@ extern "C" void PlanDump(
3086
LogStringLine(PlanDumpLevel, "Plan action: %hs", LoggingBurnActionToString(pPlan->action));
3087
LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine));
3088
LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback));
3160
- LogStringLine(PlanDumpLevel, " keep registration by default: %hs", LoggingTrueFalseToString(pPlan->fKeepRegistrationDefault));
3089
LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize);
3090
3091
LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal);
src/engine/plan.h
+1
-17
@@ -64,7 +64,6 @@ enum BURN_EXECUTE_ACTION_TYPE
64
BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER,
65
BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY,
66
BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY,
67
- BURN_EXECUTE_ACTION_TYPE_REGISTRATION,
67
BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION,
68
BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION,
69
};
@@ -281,10 +280,6 @@ typedef struct _BURN_EXECUTE_ACTION
280
BOOTSTRAPPER_ACTION_STATE action;
281
} msuPackage;
282
struct
284
- {
285
- BOOL fKeep;
286
- } registration;
287
- struct
283
{
284
BURN_ROLLBACK_BOUNDARY* pRollbackBoundary;
285
} rollbackBoundary;
@@ -319,7 +314,6 @@ typedef struct _BURN_PLAN
314
BOOL fPerMachine;
315
BOOL fRegister;
316
DWORD dwRegistrationOperations;
322
- BOOL fKeepRegistrationDefault;
317
BOOL fDisallowRemoval;
318
BOOL fDisableRollback;
319
@@ -418,7 +412,7 @@ HRESULT PlanRegistration(
412
__in BURN_REGISTRATION* pRegistration,
413
__in BOOTSTRAPPER_RESUME_TYPE resumeType,
414
__in BOOTSTRAPPER_RELATION_TYPE relationType,
421
- __out BOOL* pfContinuePlanning
415
+ __inout BOOL* pfContinuePlanning
416
);
417
HRESULT PlanPassThroughBundle(
418
__in BURN_USER_EXPERIENCE* pUX,
@@ -519,16 +513,6 @@ HRESULT PlanAppendRollbackAction(
513
__in BURN_PLAN* pPlan,
514
__out BURN_EXECUTE_ACTION** ppExecuteAction
515
);
522
-HRESULT PlanKeepRegistration(
523
- __in BURN_PLAN* pPlan,
524
- __in DWORD iAfterExecutePackageAction,
525
- __in DWORD iBeforeRollbackPackageAction
526
- );
527
-HRESULT PlanRemoveRegistration(
528
- __in BURN_PLAN* pPlan,
529
- __in DWORD iAfterExecutePackageAction,
530
- __in DWORD iAfterRollbackPackageAction
531
- );
516
HRESULT PlanRollbackBoundaryBegin(
517
__in BURN_PLAN* pPlan,
518
__in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
src/test/BurnUnitTest/BurnTestFixture.h
+2
@@ -35,6 +35,8 @@ namespace Bootstrapper
35
36
LogInitialize(::GetModuleHandleW(NULL));
37
38
+ LogSetLevel(REPORT_DEBUG, FALSE);
39
+
40
hr = LogOpen(NULL, L"BurnUnitTest", NULL, L"txt", FALSE, FALSE, NULL);
41
TestThrowOnFailure(hr, L"Failed to open log.");
42
}
src/test/BurnUnitTest/PlanTest.cpp
+201
-59
@@ -50,13 +50,12 @@ namespace Bootstrapper
50
Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
51
Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
52
Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
53
- Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
53
54
BOOL fRollback = FALSE;
55
DWORD dwIndex = 0;
56
DWORD dwPackageStart = 0;
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);
59
ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE);
60
ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6);
61
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
@@ -64,7 +63,7 @@ namespace Bootstrapper
63
ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
64
ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
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);
67
ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
68
ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
69
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart);
@@ -72,7 +71,7 @@ namespace Bootstrapper
71
ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE);
72
ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
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);
75
ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
76
ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
77
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart);
@@ -99,9 +98,8 @@ namespace Bootstrapper
98
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
99
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
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);
102
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
104
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
103
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
104
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
105
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -113,7 +111,7 @@ namespace Bootstrapper
111
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
112
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
115
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
116
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
117
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -122,26 +120,25 @@ namespace Bootstrapper
120
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
121
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
124
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
125
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
126
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
127
ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
128
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
131
Assert::Equal(dwIndex, pPlan->cExecuteActions);
132
133
fRollback = TRUE;
134
dwIndex = 0;
135
dwExecuteCheckpointId = 2;
136
ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
139
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
137
ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
138
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
139
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
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);
142
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
143
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
144
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -166,7 +163,7 @@ namespace Bootstrapper
163
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
164
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);
167
Assert::Equal(dwIndex, pPlan->cRollbackActions);
168
169
Assert::Equal(4ul, pPlan->cExecutePackagesTotal);
@@ -197,7 +194,6 @@ namespace Bootstrapper
194
Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
195
Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
196
Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
200
- Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
197
198
BOOL fRollback = FALSE;
199
DWORD dwIndex = 0;
@@ -220,13 +216,13 @@ namespace Bootstrapper
216
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
217
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
220
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
221
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
222
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_UNREGISTER);
223
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
226
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
227
ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
228
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -236,8 +232,7 @@ namespace Bootstrapper
232
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
233
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
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);
240
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
235
+ ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
236
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
237
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
238
Assert::Equal(dwIndex, pPlan->cExecuteActions);
@@ -263,9 +258,8 @@ namespace Bootstrapper
258
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
259
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
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);
262
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
268
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
263
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
264
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
265
Assert::Equal(dwIndex, pPlan->cRollbackActions);
@@ -274,9 +268,9 @@ namespace Bootstrapper
268
Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal);
269
270
dwIndex = 0;
277
- ValidateCleanAction(pPlan, dwIndex++, L"PackageC");
278
- ValidateCleanAction(pPlan, dwIndex++, L"PackageB");
279
- ValidateCleanAction(pPlan, dwIndex++, L"PackageA");
271
+ ValidateCleanAction(pPlan, dwIndex++, L"PackageC", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
272
+ ValidateCleanAction(pPlan, dwIndex++, L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
273
+ ValidateCleanAction(pPlan, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
274
Assert::Equal(dwIndex, pPlan->cCleanActions);
275
276
UINT uIndex = 0;
@@ -306,13 +300,12 @@ namespace Bootstrapper
300
Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_CACHE, pPlan->action);
301
Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
302
Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
309
- Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
303
304
BOOL fRollback = FALSE;
305
DWORD dwIndex = 0;
306
DWORD dwPackageStart = 0;
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);
309
ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
310
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
311
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
@@ -378,13 +371,12 @@ namespace Bootstrapper
371
Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
372
Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
373
Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
381
- Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
374
375
BOOL fRollback = FALSE;
376
DWORD dwIndex = 0;
377
DWORD dwPackageStart = 0;
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);
380
ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
381
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
382
ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart);
@@ -410,32 +402,30 @@ namespace Bootstrapper
402
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
403
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
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);
406
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
415
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
407
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER);
408
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
409
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
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);
412
Assert::Equal(dwIndex, pPlan->cExecuteActions);
413
414
fRollback = TRUE;
415
dwIndex = 0;
416
dwExecuteCheckpointId = 2;
417
ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
427
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
418
ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
419
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
420
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
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);
423
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
424
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER);
425
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
426
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);
429
Assert::Equal(dwIndex, pPlan->cRollbackActions);
430
431
Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
@@ -449,6 +439,62 @@ namespace Bootstrapper
439
Assert::Equal(uIndex, pPlan->cPlannedProviders);
440
}
441
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]
499
void SingleMsiUninstallTest()
500
{
@@ -466,7 +512,6 @@ namespace Bootstrapper
512
Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
513
Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
514
Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
469
- Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
515
516
BOOL fRollback = FALSE;
517
DWORD dwIndex = 0;
@@ -488,8 +533,7 @@ namespace Bootstrapper
533
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
534
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
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);
492
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
536
+ ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
537
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
538
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
539
Assert::Equal(dwIndex, pPlan->cExecuteActions);
@@ -502,9 +546,8 @@ namespace Bootstrapper
546
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
547
ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
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);
550
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
507
- ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
551
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
552
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
553
Assert::Equal(dwIndex, pPlan->cRollbackActions);
@@ -513,7 +556,7 @@ namespace Bootstrapper
556
Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal);
557
558
dwIndex = 0;
516
- ValidateCleanAction(pPlan, dwIndex++, L"PackageA");
559
+ ValidateCleanAction(pPlan, dwIndex++, L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
560
Assert::Equal(dwIndex, pPlan->cCleanActions);
561
562
UINT uIndex = 0;
@@ -522,6 +565,66 @@ namespace Bootstrapper
565
Assert::Equal(uIndex, pPlan->cPlannedProviders);
566
}
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
+
628
private:
629
// This doesn't initialize everything, just enough for CorePlan to work.
630
void InitializeEngineStateForCorePlan(LPCWSTR wzManifestFileName, BURN_ENGINE_STATE* pEngineState)
@@ -586,12 +689,22 @@ namespace Bootstrapper
689
void DetectPackageAsAbsent(BURN_PACKAGE* pPackage)
690
{
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
+ }
697
}
698
699
void DetectPackageAsPresentAndCached(BURN_PACKAGE* pPackage)
700
{
701
pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
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
+ }
708
709
for (DWORD i = 0; i < pPackage->cPayloads; ++i)
710
{
@@ -599,6 +712,19 @@ namespace Bootstrapper
712
}
713
}
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
+
728
void DetectPackagesAsAbsent(BURN_ENGINE_STATE* pEngineState)
729
{
730
PlanTestDetect(pEngineState);
@@ -620,6 +746,7 @@ namespace Bootstrapper
746
{
747
BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
748
DetectPackageAsPresentAndCached(pPackage);
749
+ DetectPackageDependent(pPackage, pEngineState->registration.sczId);
750
}
751
}
752
@@ -639,11 +766,12 @@ namespace Bootstrapper
766
else
767
{
768
DetectPackageAsPresentAndCached(pPackage);
769
+ DetectPackageDependent(pPackage, pEngineState->registration.sczId);
770
}
771
}
772
}
773
646
- HRESULT DetectUpgradeBundle(
774
+ void DetectUpgradeBundle(
775
__in BURN_ENGINE_STATE* pEngineState,
776
__in LPCWSTR wzId,
777
__in LPCWSTR wzVersion
@@ -654,30 +782,48 @@ namespace Bootstrapper
782
BURN_DEPENDENCY_PROVIDER dependencyProvider = { };
783
784
hr = StrAllocString(&dependencyProvider.sczKey, wzId, 0);
657
- ExitOnFailure(hr, "Failed to copy provider key");
785
+ NativeAssert::Succeeded(hr, "Failed to copy provider key");
786
787
dependencyProvider.fImported = TRUE;
788
789
hr = StrAllocString(&dependencyProvider.sczVersion, wzVersion, 0);
662
- ExitOnFailure(hr, "Failed to copy version");
790
+ NativeAssert::Succeeded(hr, "Failed to copy version");
791
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.");
794
795
BURN_RELATED_BUNDLE* pRelatedBundle = pRelatedBundles->rgRelatedBundles + pRelatedBundles->cRelatedBundles;
796
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);
799
800
pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE;
801
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);
804
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;
818
679
- LExit:
680
- return hr;
819
+ DetectPackagesAsPresentAndCached(pEngineState);
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
+ }
827
}
828
829
void ValidateCacheAcquireContainer(
@@ -755,6 +901,7 @@ namespace Bootstrapper
901
__in BOOL fRollback,
902
__in DWORD dwIndex,
903
__in LPCWSTR wzPackageId,
904
+ __in BURN_PACKAGE_REGISTRATION_STATE expectedCacheRegistrationState,
905
__in DWORD iPackageCompleteAction,
906
__in DWORD cCachePayloads,
907
__in DWORD64 qwCachePayloadSizeTotal,
@@ -764,6 +911,7 @@ namespace Bootstrapper
911
BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
912
Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type);
913
NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId);
914
+ Assert::Equal<DWORD>(expectedCacheRegistrationState, pAction->packageStart.pPackage->expectedCacheRegistrationState);
915
Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction);
916
Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads);
917
Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal);
@@ -815,7 +963,8 @@ namespace Bootstrapper
963
void ValidateCleanAction(
964
__in BURN_PLAN* pPlan,
965
__in DWORD dwIndex,
818
- __in LPCWSTR wzPackageId
966
+ __in LPCWSTR wzPackageId,
967
+ __in BURN_PACKAGE_REGISTRATION_STATE expectedCacheRegistrationState
968
)
969
{
970
Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions);
@@ -823,6 +972,7 @@ namespace Bootstrapper
972
BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + dwIndex;
973
Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage);
974
NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId);
975
+ Assert::Equal<DWORD>(expectedCacheRegistrationState, pCleanAction->pPackage->expectedCacheRegistrationState);
976
}
977
978
BURN_EXECUTE_ACTION* ValidateExecuteActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex)
@@ -872,6 +1022,7 @@ namespace Bootstrapper
1022
__in BOOL fRollback,
1023
__in DWORD dwIndex,
1024
__in LPCWSTR wzPackageId,
1025
+ __in BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState,
1026
__in BOOTSTRAPPER_ACTION_STATE action,
1027
__in LPCWSTR wzIgnoreDependencies
1028
)
@@ -879,6 +1030,7 @@ namespace Bootstrapper
1030
BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
1031
Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type);
1032
NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId);
1033
+ Assert::Equal<DWORD>(expectedInstallRegistrationState, pAction->exePackage.pPackage->expectedInstallRegistrationState);
1034
Assert::Equal<DWORD>(action, pAction->exePackage.action);
1035
NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies);
1036
}
@@ -888,6 +1040,7 @@ namespace Bootstrapper
1040
__in BOOL fRollback,
1041
__in DWORD dwIndex,
1042
__in LPCWSTR wzPackageId,
1043
+ __in BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState,
1044
__in BOOTSTRAPPER_ACTION_STATE action,
1045
__in BURN_MSI_PROPERTY actionMsiProperty,
1046
__in DWORD uiLevel,
@@ -898,6 +1051,7 @@ namespace Bootstrapper
1051
BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
1052
Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, pAction->type);
1053
NativeAssert::StringEqual(wzPackageId, pAction->msiPackage.pPackage->sczId);
1054
+ Assert::Equal<DWORD>(expectedInstallRegistrationState, pAction->msiPackage.pPackage->expectedInstallRegistrationState);
1055
Assert::Equal<DWORD>(action, pAction->msiPackage.action);
1056
Assert::Equal<DWORD>(actionMsiProperty, pAction->msiPackage.actionMsiProperty);
1057
Assert::Equal<DWORD>(uiLevel, pAction->msiPackage.uiLevel);
@@ -936,18 +1090,6 @@ namespace Bootstrapper
1090
Assert::Equal<DWORD>(action, pAction->packageProvider.action);
1091
}
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
-
1093
void ValidateExecuteRollbackBoundary(
1094
__in BURN_PLAN* pPlan,
1095
__in BOOL fRollback,