From 337124bed6a57b40fca11c5c2f5b554f570522a6 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 4 May 2021 11:41:55 -0700 Subject: Move ComPlus.wixext into ext --- src/ext/ComPlus/ca/cpappexec.cpp | 344 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 src/ext/ComPlus/ca/cpappexec.cpp (limited to 'src/ext/ComPlus/ca/cpappexec.cpp') diff --git a/src/ext/ComPlus/ca/cpappexec.cpp b/src/ext/ComPlus/ca/cpappexec.cpp new file mode 100644 index 00000000..48948210 --- /dev/null +++ b/src/ext/ComPlus/ca/cpappexec.cpp @@ -0,0 +1,344 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + + +// private structs + +struct CPI_APPLICATION_ATTRIBUTES +{ + int iActionType; + int iActionCost; + LPWSTR pwzKey; + LPWSTR pwzID; + LPWSTR pwzName; + LPWSTR pwzPartID; + CPI_PROPERTY* pPropList; +}; + + +// prototypes for private helper functions + +static HRESULT ReadApplicationAttributes( + LPWSTR* ppwzData, + CPI_APPLICATION_ATTRIBUTES* pAttrs + ); +static void FreeApplicationAttributes( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ); +static HRESULT CreateApplication( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ); +static HRESULT RemoveApplication( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ); + + +// function definitions + +HRESULT CpiConfigureApplications( + LPWSTR* ppwzData, + HANDLE hRollbackFile + ) +{ + HRESULT hr = S_OK; + + CPI_APPLICATION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // read action text + hr = CpiActionStartMessage(ppwzData, FALSE); + ExitOnFailure(hr, "Failed to send action start message"); + + // get count + int iCnt = 0; + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + // write count to rollback file + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt); + ExitOnFailure(hr, "Failed to write count to rollback file"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadApplicationAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // progress message + hr = CpiActionDataMessage(1, attrs.pwzName); + ExitOnFailure(hr, "Failed to send progress messages"); + + if (S_FALSE == hr) + ExitFunction(); + + // write key to rollback file + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey); + ExitOnFailure(hr, "Failed to write key to rollback file"); + + // action + switch (attrs.iActionType) + { + case atCreate: + hr = CreateApplication(&attrs); + ExitOnFailure(hr, "Failed to create application, key: %S", attrs.pwzKey); + break; + case atRemove: + hr = RemoveApplication(&attrs); + ExitOnFailure(hr, "Failed to remove application, key: %S", attrs.pwzKey); + break; + } + + // write completion status to rollback file + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1); + ExitOnFailure(hr, "Failed to write completion status to rollback file"); + + // progress + hr = WcaProgressMessage(attrs.iActionCost, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeApplicationAttributes(&attrs); + + return hr; +} + +HRESULT CpiRollbackConfigureApplications( + LPWSTR* ppwzData, + CPI_ROLLBACK_DATA* pRollbackDataList + ) +{ + HRESULT hr = S_OK; + + int iRollbackStatus; + + CPI_APPLICATION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // read action text + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList); + ExitOnFailure(hr, "Failed to send action start message"); + + // get count + int iCnt = 0; + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadApplicationAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // rollback status + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus); + + if (S_FALSE == hr) + continue; // not found, nothing to rollback + + // progress message + hr = CpiActionDataMessage(1, attrs.pwzName); + ExitOnFailure(hr, "Failed to send progress messages"); + + if (S_FALSE == hr) + ExitFunction(); + + // action + switch (attrs.iActionType) + { + case atCreate: + hr = CreateApplication(&attrs); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to create application, hr: 0x%x, key: %S", hr, attrs.pwzKey); + break; + case atRemove: + hr = RemoveApplication(&attrs); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to remove application, hr: 0x%x, key: %S", hr, attrs.pwzKey); + break; + } + + // check rollback status + if (0 == iRollbackStatus) + continue; // operation did not complete, skip progress + + // progress + hr = WcaProgressMessage(attrs.iActionCost, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeApplicationAttributes(&attrs); + + return hr; +} + + +// helper function definitions + +static HRESULT ReadApplicationAttributes( + LPWSTR* ppwzData, + CPI_APPLICATION_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType); + ExitOnFailure(hr, "Failed to read action type"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost); + ExitOnFailure(hr, "Failed to read action cost"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey); + ExitOnFailure(hr, "Failed to read key"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID); + ExitOnFailure(hr, "Failed to read id"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName); + ExitOnFailure(hr, "Failed to read name"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID); + ExitOnFailure(hr, "Failed to read partition id"); + hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList); + ExitOnFailure(hr, "Failed to read properties"); + + hr = S_OK; + +LExit: + return hr; +} + +static void FreeApplicationAttributes( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ) +{ + ReleaseStr(pAttrs->pwzKey); + ReleaseStr(pAttrs->pwzID); + ReleaseStr(pAttrs->pwzName); + ReleaseStr(pAttrs->pwzPartID); + + if (pAttrs->pPropList) + CpiFreePropertyList(pAttrs->pPropList); +} + +static HRESULT CreateApplication( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + ICatalogCollection* piAppColl = NULL; + ICatalogObject* piAppObj = NULL; + + long lChanges = 0; + + // log + WcaLog(LOGMSG_VERBOSE, "Creating application, key: %S", pAttrs->pwzKey); + + // get applications collection + hr = CpiExecGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl); + if (S_FALSE == hr) + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + ExitOnFailure(hr, "Failed to get applications collection"); + + // check if application exists + hr = CpiFindCollectionObjectByStringKey(piAppColl, pAttrs->pwzID, &piAppObj); + ExitOnFailure(hr, "Failed to find application"); + + if (S_FALSE == hr) + { + // create application + hr = CpiAddCollectionObject(piAppColl, &piAppObj); + ExitOnFailure(hr, "Failed to add application to collection"); + + hr = CpiPutCollectionObjectValue(piAppObj, L"ID", pAttrs->pwzID); + ExitOnFailure(hr, "Failed to set application id property"); + + hr = CpiPutCollectionObjectValue(piAppObj, L"Name", pAttrs->pwzName); + ExitOnFailure(hr, "Failed to set application name property"); + + // save changes + hr = piAppColl->SaveChanges(&lChanges); + if (COMADMIN_E_OBJECTERRORS == hr) + CpiLogCatalogErrorInfo(); + ExitOnFailure(hr, "Failed to add application"); + } + + // properties + hr = CpiPutCollectionObjectValues(piAppObj, pAttrs->pPropList); + ExitOnFailure(hr, "Failed to write properties"); + + // save changes + hr = piAppColl->SaveChanges(&lChanges); + if (COMADMIN_E_OBJECTERRORS == hr) + CpiLogCatalogErrorInfo(); + ExitOnFailure(hr, "Failed to save changes"); + + // log + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey); + + hr = S_OK; + +LExit: + // clean up + ReleaseObject(piAppColl); + ReleaseObject(piAppObj); + + return hr; +} + +static HRESULT RemoveApplication( + CPI_APPLICATION_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + ICatalogCollection* piAppColl = NULL; + + long lChanges = 0; + + // log + WcaLog(LOGMSG_VERBOSE, "Removing application, key: %S", pAttrs->pwzKey); + + // get applications collection + hr = CpiExecGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl); + ExitOnFailure(hr, "Failed to get applications collection"); + + if (S_FALSE == hr) + { + // applications collection not found + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve applications collection, nothing to delete, key: %S", pAttrs->pwzKey); + ExitFunction1(hr = S_OK); + } + + // remove + hr = CpiRemoveCollectionObject(piAppColl, pAttrs->pwzID, NULL, TRUE); + ExitOnFailure(hr, "Failed to remove application"); + + if (S_FALSE == hr) + { + // application not found + WcaLog(LOGMSG_VERBOSE, "Application not found, nothing to delete, key: %S", pAttrs->pwzKey); + ExitFunction1(hr = S_OK); + } + + // save changes + hr = piAppColl->SaveChanges(&lChanges); + if (COMADMIN_E_OBJECTERRORS == hr) + CpiLogCatalogErrorInfo(); + ExitOnFailure(hr, "Failed to save changes"); + + // log + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey); + + hr = S_OK; + +LExit: + // clean up + ReleaseObject(piAppColl); + + return hr; +} -- cgit v1.2.3-55-g6feb