diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-14 21:37:24 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-01-16 10:30:28 -0600 |
| commit | da1d1376953ef1c9afb32d5eee02b785e52e372e (patch) | |
| tree | 0df8550960259d7b13f5cd90f04d21b5576f16b7 /src/burn/engine/elevation.cpp | |
| parent | abe316b80fae80eba54b0b79e76b6362105fa098 (diff) | |
| download | wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.tar.gz wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.tar.bz2 wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.zip | |
Remove orphan compatible MSI packages.
Reimplements #3190
Diffstat (limited to 'src/burn/engine/elevation.cpp')
| -rw-r--r-- | src/burn/engine/elevation.cpp | 303 |
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 | ); |
| 179 | static HRESULT ElevatedProcessDetect( | ||
| 180 | __in BURN_REGISTRATION* pRegistration, | ||
| 181 | __in BURN_PACKAGES* pPackages | ||
| 182 | ); | ||
| 176 | static HRESULT OnApplyUninitialize( | 183 | static 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 | ); |
| 281 | static 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 | ); | ||
| 274 | static HRESULT OnExecutePackageProviderAction( | 289 | static 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 | ); |
| 324 | static HRESULT OnCleanCompatiblePackage( | ||
| 325 | __in BURN_CACHE* pCache, | ||
| 326 | __in BURN_PACKAGES* pPackages, | ||
| 327 | __in BYTE* pbData, | ||
| 328 | __in SIZE_T cbData | ||
| 329 | ); | ||
| 309 | static HRESULT OnCleanPackage( | 330 | static 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 | ||
| 1254 | extern "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 | |||
| 1300 | LExit: | ||
| 1301 | ReleaseBuffer(pbData); | ||
| 1302 | |||
| 1303 | return hr; | ||
| 1304 | } | ||
| 1305 | |||
| 1233 | extern "C" HRESULT ElevationExecutePackageProviderAction( | 1306 | extern "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 | ||
| 1371 | extern "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 | |||
| 1394 | LExit: | ||
| 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 | ||
| 2299 | static 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 | |||
| 2328 | LExit: | ||
| 2329 | return hr; | ||
| 2330 | } | ||
| 2331 | |||
| 2190 | static HRESULT OnApplyUninitialize( | 2332 | static 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 | ||
| 3108 | static 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 | |||
| 3170 | LExit: | ||
| 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 | |||
| 2946 | static HRESULT OnExecutePackageProviderAction( | 3190 | static 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 | ||
| 3505 | static 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 | |||
| 3546 | LExit: | ||
| 3547 | ReleaseStr(sczPackageId); | ||
| 3548 | ReleaseStr(sczCompatiblePackageId); | ||
| 3549 | return hr; | ||
| 3550 | } | ||
| 3551 | |||
| 3261 | static HRESULT OnCleanPackage( | 3552 | static HRESULT OnCleanPackage( |
| 3262 | __in BURN_CACHE* pCache, | 3553 | __in BURN_CACHE* pCache, |
| 3263 | __in BURN_PACKAGES* pPackages, | 3554 | __in BURN_PACKAGES* pPackages, |
