diff options
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, |