aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/elevation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/elevation.cpp')
-rw-r--r--src/burn/engine/elevation.cpp303
1 files changed, 297 insertions, 6 deletions
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 221d8b6d..9ebba7c5 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -32,6 +32,8 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
32 BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, 32 BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION,
33 BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, 33 BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION,
34 BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, 34 BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION,
35 BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE,
36 BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE,
35 37
36 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, 38 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN,
37 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, 39 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE,
@@ -168,11 +170,16 @@ static HRESULT OnApplyInitialize(
168 __in HANDLE hPipe, 170 __in HANDLE hPipe,
169 __in BURN_VARIABLES* pVariables, 171 __in BURN_VARIABLES* pVariables,
170 __in BURN_REGISTRATION* pRegistration, 172 __in BURN_REGISTRATION* pRegistration,
173 __in BURN_PACKAGES* pPackages,
171 __in HANDLE* phLock, 174 __in HANDLE* phLock,
172 __in BOOL* pfDisabledWindowsUpdate, 175 __in BOOL* pfDisabledWindowsUpdate,
173 __in BYTE* pbData, 176 __in BYTE* pbData,
174 __in SIZE_T cbData 177 __in SIZE_T cbData
175 ); 178 );
179static HRESULT ElevatedProcessDetect(
180 __in BURN_REGISTRATION* pRegistration,
181 __in BURN_PACKAGES* pPackages
182 );
176static HRESULT OnApplyUninitialize( 183static HRESULT OnApplyUninitialize(
177 __in HANDLE* phLock 184 __in HANDLE* phLock
178 ); 185 );
@@ -271,6 +278,14 @@ static HRESULT OnExecuteMsuPackage(
271 __in BYTE* pbData, 278 __in BYTE* pbData,
272 __in SIZE_T cbData 279 __in SIZE_T cbData
273 ); 280 );
281static HRESULT OnUninstallMsiCompatiblePackage(
282 __in HANDLE hPipe,
283 __in BURN_CACHE* pCache,
284 __in BURN_PACKAGES* pPackages,
285 __in BURN_VARIABLES* pVariables,
286 __in BYTE* pbData,
287 __in SIZE_T cbData
288 );
274static HRESULT OnExecutePackageProviderAction( 289static HRESULT OnExecutePackageProviderAction(
275 __in BURN_PACKAGES* pPackages, 290 __in BURN_PACKAGES* pPackages,
276 __in BURN_RELATED_BUNDLES* pRelatedBundles, 291 __in BURN_RELATED_BUNDLES* pRelatedBundles,
@@ -306,6 +321,12 @@ static int MsiExecuteMessageHandler(
306 __in WIU_MSI_EXECUTE_MESSAGE* pMessage, 321 __in WIU_MSI_EXECUTE_MESSAGE* pMessage,
307 __in_opt LPVOID pvContext 322 __in_opt LPVOID pvContext
308 ); 323 );
324static HRESULT OnCleanCompatiblePackage(
325 __in BURN_CACHE* pCache,
326 __in BURN_PACKAGES* pPackages,
327 __in BYTE* pbData,
328 __in SIZE_T cbData
329 );
309static HRESULT OnCleanPackage( 330static HRESULT OnCleanPackage(
310 __in BURN_CACHE* pCache, 331 __in BURN_CACHE* pCache,
311 __in BURN_PACKAGES* pPackages, 332 __in BURN_PACKAGES* pPackages,
@@ -1230,6 +1251,58 @@ LExit:
1230 return hr; 1251 return hr;
1231} 1252}
1232 1253
1254extern "C" HRESULT ElevationUninstallMsiCompatiblePackage(
1255 __in HANDLE hPipe,
1256 __in_opt HWND hwndParent,
1257 __in BURN_EXECUTE_ACTION* pExecuteAction,
1258 __in BURN_VARIABLES* pVariables,
1259 __in BOOL fRollback,
1260 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1261 __in LPVOID pvContext,
1262 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1263 )
1264{
1265 HRESULT hr = S_OK;
1266 BYTE* pbData = NULL;
1267 SIZE_T cbData = 0;
1268 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1269 DWORD dwResult = 0;
1270
1271 // serialize message data
1272 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1273 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1274
1275 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->sczId);
1276 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1277
1278 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.compatibleEntry.sczId);
1279 ExitOnFailure(hr, "Failed to write compatible package id to message buffer.");
1280
1281 hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent);
1282 ExitOnFailure(hr, "Failed to write parent hwnd to message buffer.");
1283
1284 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath);
1285 ExitOnFailure(hr, "Failed to write package log to message buffer.");
1286
1287 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
1288 ExitOnFailure(hr, "Failed to write variables.");
1289
1290
1291 // send message
1292 context.pfnMessageHandler = pfnMessageHandler;
1293 context.pvContext = pvContext;
1294
1295 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1296 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE message to per-machine process.");
1297
1298 hr = ProcessResult(dwResult, pRestart);
1299
1300LExit:
1301 ReleaseBuffer(pbData);
1302
1303 return hr;
1304}
1305
1233extern "C" HRESULT ElevationExecutePackageProviderAction( 1306extern "C" HRESULT ElevationExecutePackageProviderAction(
1234 __in HANDLE hPipe, 1307 __in HANDLE hPipe,
1235 __in BURN_EXECUTE_ACTION* pExecuteAction 1308 __in BURN_EXECUTE_ACTION* pExecuteAction
@@ -1295,6 +1368,35 @@ LExit:
1295 return hr; 1368 return hr;
1296} 1369}
1297 1370
1371extern "C" HRESULT ElevationCleanCompatiblePackage(
1372 __in HANDLE hPipe,
1373 __in BURN_PACKAGE* pPackage
1374 )
1375{
1376 HRESULT hr = S_OK;
1377 BYTE* pbData = NULL;
1378 SIZE_T cbData = 0;
1379 DWORD dwResult = 0;
1380
1381 // serialize message data
1382 hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
1383 ExitOnFailure(hr, "Failed to write clean package id to message buffer.");
1384
1385 hr = BuffWriteString(&pbData, &cbData, pPackage->compatiblePackage.compatibleEntry.sczId);
1386 ExitOnFailure(hr, "Failed to write compatible package id to message buffer.");
1387
1388 // send message
1389 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE, pbData, cbData, NULL, NULL, &dwResult);
1390 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE message to per-machine process.");
1391
1392 hr = (HRESULT)dwResult;
1393
1394LExit:
1395 ReleaseBuffer(pbData);
1396
1397 return hr;
1398}
1399
1298/******************************************************************* 1400/*******************************************************************
1299 ElevationCleanPackage - 1401 ElevationCleanPackage -
1300 1402
@@ -1940,7 +2042,7 @@ static HRESULT ProcessElevatedChildMessage(
1940 break; 2042 break;
1941 2043
1942 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: 2044 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE:
1943 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); 2045 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->pPackages, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData);
1944 break; 2046 break;
1945 2047
1946 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: 2048 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE:
@@ -2003,6 +2105,14 @@ static HRESULT ProcessElevatedChildMessage(
2003 hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 2105 hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2004 break; 2106 break;
2005 2107
2108 case BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE:
2109 hrResult = OnUninstallMsiCompatiblePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2110 break;
2111
2112 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE:
2113 hrResult = OnCleanCompatiblePackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2114 break;
2115
2006 default: 2116 default:
2007 hr = E_INVALIDARG; 2117 hr = E_INVALIDARG;
2008 ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage); 2118 ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage);
@@ -2082,6 +2192,7 @@ static HRESULT OnApplyInitialize(
2082 __in HANDLE hPipe, 2192 __in HANDLE hPipe,
2083 __in BURN_VARIABLES* pVariables, 2193 __in BURN_VARIABLES* pVariables,
2084 __in BURN_REGISTRATION* pRegistration, 2194 __in BURN_REGISTRATION* pRegistration,
2195 __in BURN_PACKAGES* pPackages,
2085 __in HANDLE* phLock, 2196 __in HANDLE* phLock,
2086 __in BOOL* pfDisabledWindowsUpdate, 2197 __in BOOL* pfDisabledWindowsUpdate,
2087 __in BYTE* pbData, 2198 __in BYTE* pbData,
@@ -2113,11 +2224,9 @@ static HRESULT OnApplyInitialize(
2113 hr = ApplyLock(TRUE, phLock); 2224 hr = ApplyLock(TRUE, phLock);
2114 ExitOnFailure(hr, "Failed to acquire lock due to setup in other session."); 2225 ExitOnFailure(hr, "Failed to acquire lock due to setup in other session.");
2115 2226
2116 // Reset and reload the related bundles. 2227 // Detect.
2117 RelatedBundlesUninitialize(&pRegistration->relatedBundles); 2228 hr = ElevatedProcessDetect(pRegistration, pPackages);
2118 2229 ExitOnFailure(hr, "Failed to run detection in elevated process.");
2119 hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles);
2120 ExitOnFailure(hr, "Failed to initialize per-machine related bundles.");
2121 2230
2122 // Attempt to pause AU with best effort. 2231 // Attempt to pause AU with best effort.
2123 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction) 2232 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction)
@@ -2187,6 +2296,39 @@ LExit:
2187 return hr; 2296 return hr;
2188} 2297}
2189 2298
2299static HRESULT ElevatedProcessDetect(
2300 __in BURN_REGISTRATION* pRegistration,
2301 __in BURN_PACKAGES* pPackages
2302 )
2303{
2304 HRESULT hr = S_OK;
2305
2306 DetectReset(pRegistration, pPackages);
2307
2308 hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles);
2309 ExitOnFailure(hr, "Failed to initialize per-machine related bundles.");
2310
2311 for (DWORD i = 0; i < pPackages->cPackages; ++i)
2312 {
2313 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
2314
2315 hr = DependencyDetectCompatibleEntry(pPackage, pRegistration);
2316 ExitOnFailure(hr, "Failed to detect per-machine compatible entry for package: %ls", pPackage->sczId);
2317
2318 switch (pPackage->type)
2319 {
2320 case BURN_PACKAGE_TYPE_MSI:
2321 hr = MsiEngineDetectCompatiblePackage(pPackage);
2322 ExitOnFailure(hr, "Failed to detect per-machine compatible package for package: %ls", pPackage->sczId);
2323
2324 break;
2325 }
2326 }
2327
2328LExit:
2329 return hr;
2330}
2331
2190static HRESULT OnApplyUninitialize( 2332static HRESULT OnApplyUninitialize(
2191 __in HANDLE* phLock 2333 __in HANDLE* phLock
2192 ) 2334 )
@@ -2659,6 +2801,11 @@ static HRESULT OnExecuteExePackage(
2659 hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); 2801 hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage);
2660 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); 2802 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
2661 2803
2804 if (BURN_PACKAGE_TYPE_EXE != executeAction.exePackage.pPackage->type)
2805 {
2806 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage);
2807 }
2808
2662 // Execute EXE package. 2809 // Execute EXE package.
2663 hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); 2810 hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart);
2664 ExitOnFailure(hr, "Failed to execute EXE package."); 2811 ExitOnFailure(hr, "Failed to execute EXE package.");
@@ -2760,6 +2907,11 @@ static HRESULT OnExecuteMsiPackage(
2760 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); 2907 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2761 ExitOnFailure(hr, "Failed to read variables."); 2908 ExitOnFailure(hr, "Failed to read variables.");
2762 2909
2910 if (BURN_PACKAGE_TYPE_MSI != executeAction.msiPackage.pPackage->type)
2911 {
2912 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSI package: %ls", sczPackage);
2913 }
2914
2763 // Execute MSI package. 2915 // Execute MSI package.
2764 hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); 2916 hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
2765 ExitOnFailure(hr, "Failed to execute MSI package."); 2917 ExitOnFailure(hr, "Failed to execute MSI package.");
@@ -2859,6 +3011,11 @@ static HRESULT OnExecuteMspPackage(
2859 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); 3011 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
2860 ExitOnFailure(hr, "Failed to read rollback flag."); 3012 ExitOnFailure(hr, "Failed to read rollback flag.");
2861 3013
3014 if (BURN_PACKAGE_TYPE_MSP != executeAction.mspTarget.pPackage->type)
3015 {
3016 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSP package: %ls", sczPackage);
3017 }
3018
2862 // Execute MSP package. 3019 // Execute MSP package.
2863 hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart); 3020 hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart);
2864 ExitOnFailure(hr, "Failed to execute MSP package."); 3021 ExitOnFailure(hr, "Failed to execute MSP package.");
@@ -2920,6 +3077,11 @@ static HRESULT OnExecuteMsuPackage(
2920 hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); 3077 hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage);
2921 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); 3078 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
2922 3079
3080 if (BURN_PACKAGE_TYPE_MSU != executeAction.msuPackage.pPackage->type)
3081 {
3082 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSU package: %ls", sczPackage);
3083 }
3084
2923 // execute MSU package 3085 // execute MSU package
2924 hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart); 3086 hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart);
2925 ExitOnFailure(hr, "Failed to execute MSU package."); 3087 ExitOnFailure(hr, "Failed to execute MSU package.");
@@ -2943,6 +3105,88 @@ LExit:
2943 return hr; 3105 return hr;
2944} 3106}
2945 3107
3108static HRESULT OnUninstallMsiCompatiblePackage(
3109 __in HANDLE hPipe,
3110 __in BURN_CACHE* pCache,
3111 __in BURN_PACKAGES* pPackages,
3112 __in BURN_VARIABLES* pVariables,
3113 __in BYTE* pbData,
3114 __in SIZE_T cbData
3115 )
3116{
3117 HRESULT hr = S_OK;
3118 SIZE_T iData = 0;
3119 LPWSTR sczPackageId = NULL;
3120 LPWSTR sczCompatiblePackageId = NULL;
3121 HWND hwndParent = NULL;
3122 BOOL fRollback = 0;
3123 BURN_EXECUTE_ACTION executeAction = { };
3124 BURN_PACKAGE* pPackage = NULL;
3125 BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL;
3126 BOOTSTRAPPER_APPLY_RESTART msiRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3127
3128 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
3129
3130 // Deserialize message data.
3131 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3132 ExitOnFailure(hr, "Failed to read rollback flag.");
3133
3134 hr = BuffReadString(pbData, cbData, &iData, &sczPackageId);
3135 ExitOnFailure(hr, "Failed to read MSI package id.");
3136
3137 hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId);
3138 ExitOnFailure(hr, "Failed to read MSI compatible package id.");
3139
3140 hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent);
3141 ExitOnFailure(hr, "Failed to read parent hwnd.");
3142
3143 hr = BuffReadString(pbData, cbData, &iData, &executeAction.uninstallMsiCompatiblePackage.sczLogPath);
3144 ExitOnFailure(hr, "Failed to read package log.");
3145
3146 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
3147 ExitOnFailure(hr, "Failed to read variables.");
3148
3149 hr = PackageFindById(pPackages, sczPackageId, &pPackage);
3150 ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId);
3151
3152 executeAction.uninstallMsiCompatiblePackage.pParentPackage = pPackage;
3153 pCompatiblePackage = &pPackage->compatiblePackage;
3154
3155 if (!pCompatiblePackage->fDetected || BURN_PACKAGE_TYPE_MSI != pCompatiblePackage->type || !pCompatiblePackage->compatibleEntry.sczId)
3156 {
3157 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible MSI package", sczPackageId);
3158 }
3159
3160 if (!sczCompatiblePackageId || !*sczCompatiblePackageId ||
3161 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1))
3162 {
3163 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId);
3164 }
3165
3166 // Uninstall MSI compatible package.
3167 hr = MsiEngineUninstallCompatiblePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
3168 ExitOnFailure(hr, "Failed to execute MSI package.");
3169
3170LExit:
3171 ReleaseStr(sczPackageId);
3172 ReleaseStr(sczCompatiblePackageId);
3173 PlanUninitializeExecuteAction(&executeAction);
3174
3175 if (SUCCEEDED(hr))
3176 {
3177 if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == msiRestart)
3178 {
3179 hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3180 }
3181 else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == msiRestart)
3182 {
3183 hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3184 }
3185 }
3186
3187 return hr;
3188}
3189
2946static HRESULT OnExecutePackageProviderAction( 3190static HRESULT OnExecutePackageProviderAction(
2947 __in BURN_PACKAGES* pPackages, 3191 __in BURN_PACKAGES* pPackages,
2948 __in BURN_RELATED_BUNDLES* pRelatedBundles, 3192 __in BURN_RELATED_BUNDLES* pRelatedBundles,
@@ -3258,6 +3502,53 @@ LExit:
3258 return nResult; 3502 return nResult;
3259} 3503}
3260 3504
3505static HRESULT OnCleanCompatiblePackage(
3506 __in BURN_CACHE* pCache,
3507 __in BURN_PACKAGES* pPackages,
3508 __in BYTE* pbData,
3509 __in SIZE_T cbData
3510 )
3511{
3512 HRESULT hr = S_OK;
3513 SIZE_T iData = 0;
3514 LPWSTR sczPackageId = NULL;
3515 LPWSTR sczCompatiblePackageId = NULL;
3516 BURN_PACKAGE* pPackage = NULL;
3517 BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL;
3518
3519 // Deserialize message data.
3520 hr = BuffReadString(pbData, cbData, &iData, &sczPackageId);
3521 ExitOnFailure(hr, "Failed to read package id.");
3522
3523 hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId);
3524 ExitOnFailure(hr, "Failed to read compatible package id.");
3525
3526 hr = PackageFindById(pPackages, sczPackageId, &pPackage);
3527 ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId);
3528
3529 pCompatiblePackage = &pPackage->compatiblePackage;
3530
3531 if (!pCompatiblePackage->fDetected || !pCompatiblePackage->compatibleEntry.sczId || !pCompatiblePackage->sczCacheId || !*pCompatiblePackage->sczCacheId)
3532 {
3533 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package to clean.", sczPackageId);
3534 }
3535
3536 if (!sczCompatiblePackageId || !*sczCompatiblePackageId ||
3537 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1))
3538 {
3539 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId);
3540 }
3541
3542 // Remove the package from the cache.
3543 hr = CacheRemovePackage(pCache, TRUE, pCompatiblePackage->compatibleEntry.sczId, pCompatiblePackage->sczCacheId);
3544 ExitOnFailure(hr, "Failed to remove from cache compatible package: %ls", pCompatiblePackage->compatibleEntry.sczId);
3545
3546LExit:
3547 ReleaseStr(sczPackageId);
3548 ReleaseStr(sczCompatiblePackageId);
3549 return hr;
3550}
3551
3261static HRESULT OnCleanPackage( 3552static HRESULT OnCleanPackage(
3262 __in BURN_CACHE* pCache, 3553 __in BURN_CACHE* pCache,
3263 __in BURN_PACKAGES* pPackages, 3554 __in BURN_PACKAGES* pPackages,