Exemplo n.º 1
0
static HRESULT InstallCertificatePackage(
    __in HCERTSTORE hStore,
    __in BOOL fUserCertificateStore,
    __in LPCWSTR wzName,
    __in_opt BYTE* rgbData,
    __in DWORD cbData,
    __in_opt LPCWSTR wzPFXPassword
    )
{
    HRESULT hr = S_OK;

    HCERTSTORE hPfxCertStore = NULL;
    PCCERT_CONTEXT pCertContext = NULL;
    CERT_BLOB blob = { 0 };
    DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET;
    DWORD dwEncodingType;
    DWORD dwContentType;
    DWORD dwFormatType;
    LPWSTR pwzUniqueName = NULL;
    int iUniqueId = 0;

    // Figure out what type of blob (certificate or PFX) we're dealing with here.
    blob.pbData = rgbData;
    blob.cbData = cbData;

    if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext))
    {
        ExitWithLastError1(hr, "Failed to parse the certificate blob: %ls", wzName);
    }

    hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId);
    ExitOnFailure(hr, "Failed to format unique name");

    if (!pCertContext)
    {
        // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX.
        if (dwContentType & CERT_QUERY_CONTENT_PFX)
        {
            ExitOnNull(wzPFXPassword, hr, E_INVALIDARG, "Failed to import PFX blob because no password was provided");

            // If we fail and our password is blank, also try passing in NULL for the password (according to the docs)
            hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset);
            if (NULL == hPfxCertStore && !*wzPFXPassword)
            {
                hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset);
            }
            ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file.");

            // Install all certificates in the PFX
            for (pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext);
                 pCertContext;
                 pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext))
            {
                WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", pwzUniqueName);
                hr = CertInstallSingleCertificate(hStore, pCertContext, pwzUniqueName);
                MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store.");

                hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId);
                ExitOnFailure(hr, "Failed to format unique name");
            }
        }
        else
        {
            hr = E_UNEXPECTED;
            ExitOnFailure(hr, "Unexpected certificate type processed.");
        }
    }
    else
    {
        WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", pwzUniqueName);
        hr = CertInstallSingleCertificate(hStore, pCertContext, pwzUniqueName);
        MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store.");
    }

    hr = WcaProgressMessage(COST_CERT_ADD, FALSE);
    ExitOnFailure(hr, "Failed to send install progress message.");

LExit:
    ReleaseStr(pwzUniqueName);

    if (pCertContext)
    {
        ::CertFreeCertificateContext(pCertContext);
    }

    // Close the stores after the context's are released.
    if (hPfxCertStore)
    {
        if (!::CertCloseStore(hPfxCertStore, CERT_CLOSE_STORE_CHECK_FLAG))
        {
            WcaLog(LOGMSG_VERBOSE, "PFX cert store was closed but not all resources were freed.  Error 0x%x", GetLastError());
        }
    }

    return hr;
}
Exemplo n.º 2
0
HRESULT CpiPartitionsVerifyInstall(
    CPI_PARTITION_LIST* pList
    )
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    ICatalogCollection* piPartColl = NULL;
    ICatalogObject* piPartObj = NULL;

    for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
    {
        // referenced locaters or partitions that are being installed
        if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
            continue;

        // if the partition is referensed and is not a locater, it must be installed
        if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
            MessageExitOnFailure(hr = E_FAIL, msierrComPlusPartitionDependency, "A partition is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);

        // get partitions collection
        if (!piPartColl)
        {
            hr = CpiGetPartitionsCollection(&piPartColl);
            ExitOnFailure(hr, "Failed to get partitions collection");
        }

        // partition is supposed to exist
        if (!pItm->fHasComponent || CpiIsInstalled(pItm->isInstalled))
        {
            // get collection object for partition
            hr = CpiFindCollectionObject(piPartColl, pItm->wzID, *pItm->wzID ? NULL : pItm->wzName, &piPartObj);
            ExitOnFailure(hr, "Failed to find collection object for partition");

            // if the partition was found
            if (S_OK == hr)
            {
                // if we don't have an id, copy id from object
                if (!*pItm->wzID)
                {
                    hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
                    ExitOnFailure(hr, "Failed to get id");
                }
            }

            // if the partition was not found
            else
            {
                // if the application is a locater, this is an error
                if (!pItm->fHasComponent)
                    MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusPartitionNotFound, "A partition required by this installation was not found, key: %S", pItm->wzKey);

                // create a new id if one is missing
                if (!*pItm->wzID)
                {
                    hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
                    ExitOnFailure(hr, "Failed to create id");
                }
            }
        }

        // partition is supposed to be created
        else
        {
            // check for conflicts
            do {
                if (*pItm->wzID)
                {
                    // find partitions with conflicting id
                    hr = CpiFindCollectionObject(piPartColl, pItm->wzID, NULL, &piPartObj);
                    ExitOnFailure(hr, "Failed to find collection object for partition");

                    if (S_FALSE == hr)
                    {
                        // find partitions with conflicting name
                        hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
                        ExitOnFailure(hr, "Failed to find collection object for partition");

                        if (S_OK == hr)
                            // "A partition with a conflictiong name exists. retry cancel"
                            er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
                        else
                            break; // no conflicting entry found, break loop
                    }
                    else
                        // "A partition with a conflicting id exists. abort retry ignore"
                        er = WcaErrorMessage(msierrComPlusPartitionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
                }
                else
                {
                    // find partitions with conflicting name
                    hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
                    ExitOnFailure(hr, "Failed to find collection object for partition");

                    if (S_OK == hr)
                        // "A partition with a conflictiong name exists. abort retry ignore"
                        er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
                    else
                        break; // no conflicting entry found, break loop
                }

                switch (er)
                {
                case IDCANCEL:
                case IDABORT:
                    ExitOnFailure(hr = E_FAIL, "A partition with a conflictiong name or id exists, key: %S", pItm->wzKey);
                    break;
                case IDRETRY:
                    break;
                case IDIGNORE:
                default:
                    // if we don't have an id, copy id from object
                    if (!*pItm->wzID)
                    {
                        hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
                        ExitOnFailure(hr, "Failed to get id");
                    }
                    hr = S_FALSE; // indicate that this is not a conflict
                }
            } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts

            // create a new id if one is missing
            if (!*pItm->wzID)
            {
                hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
                ExitOnFailure(hr, "Failed to create id");
            }
        }

        // clean up
        ReleaseNullObject(piPartObj);
    }

    hr = S_OK;

LExit:
    // clean up
    ReleaseObject(piPartColl);
    ReleaseObject(piPartObj);

    return hr;
}
Exemplo n.º 3
0
/******************************************************************
 SchedXmlConfig - entry point for XmlConfig Custom Action

********************************************************************/
extern "C" UINT __stdcall SchedXmlConfig(
    __in MSIHANDLE hInstall
    )
{
//    AssertSz(FALSE, "debug SchedXmlConfig");

    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    LPWSTR pwzCurrentFile = NULL;
    BOOL fCurrentFileChanged = FALSE;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRec = NULL;

    XML_CONFIG_CHANGE* pxfcHead = NULL;
    XML_CONFIG_CHANGE* pxfcTail = NULL; // TODO: do we need this any more?
    XML_CONFIG_CHANGE* pxfc = NULL;

    eXmlAction xa = xaUnknown;
    eXmlPreserveDate xd;

    LPWSTR pwzCustomActionData = NULL;

    DWORD cFiles = 0;

    // initialize
    hr = WcaInitialize(hInstall, "SchedXmlConfig");
    ExitOnFailure(hr, "failed to initialize");

    hr = ReadXmlConfigTable(&pxfcHead, &pxfcTail);
    MessageExitOnFailure(hr, msierrXmlConfigFailedRead, "failed to read XmlConfig table");

    hr = ProcessChanges(&pxfcHead);
    ExitOnFailure(hr, "failed to process XmlConfig changes");

    // loop through all the xml configurations
    for (pxfc = pxfcHead; pxfc; pxfc = pxfc->pxfcNext)
    {
        // If this is a different file, or the first file...
        if (NULL == pwzCurrentFile || 0 != lstrcmpW(pwzCurrentFile, pxfc->wzFile))
        {
            // Remember the file we're currently working on
            hr = StrAllocString(&pwzCurrentFile, pxfc->wzFile, 0);
            ExitOnFailure(hr, "failed to copy file name");

            fCurrentFileChanged = TRUE;
        }

        //
        // Figure out what action to take
        //
        xa = xaUnknown;

        // If it's being installed or reinstalled or uninstalled and that matches
        // what we are doing then calculate the right action.
        if ((XMLCONFIG_INSTALL & pxfc->iXmlFlags && (WcaIsInstalling(pxfc->isInstalled, pxfc->isAction) || WcaIsReInstalling(pxfc->isInstalled, pxfc->isAction))) ||
            (XMLCONFIG_UNINSTALL & pxfc->iXmlFlags && WcaIsUninstalling(pxfc->isInstalled, pxfc->isAction)))
        {
            if (XMLCONFIG_CREATE & pxfc->iXmlFlags && XMLCONFIG_ELEMENT & pxfc->iXmlFlags)
            {
                xa = xaCreateElement;
            }
            else if (XMLCONFIG_DELETE & pxfc->iXmlFlags && XMLCONFIG_ELEMENT & pxfc->iXmlFlags)
            {
                xa = xaDeleteElement;
            }
            else if (XMLCONFIG_DELETE & pxfc->iXmlFlags && XMLCONFIG_VALUE & pxfc->iXmlFlags)
            {
                xa = xaDeleteValue;
            }
            else if (XMLCONFIG_CREATE & pxfc->iXmlFlags && XMLCONFIG_VALUE & pxfc->iXmlFlags)
            {
                xa = xaWriteValue;
            }
            else if (XMLCONFIG_CREATE & pxfc->iXmlFlags && XMLCONFIG_DOCUMENT & pxfc->iXmlFlags)
            {
                xa = xaWriteDocument;
            }
            else if (XMLCONFIG_DELETE & pxfc->iXmlFlags && XMLCONFIG_DOCUMENT & pxfc->iXmlFlags)
            {
                hr = E_INVALIDARG;
                ExitOnFailure(hr, "Invalid flag configuration.  Cannot delete a fragment node.");
            }
        }

        if (XMLCONFIG_PRESERVE_MODIFIED & pxfc->iXmlFlags)
        {
            xd = xdPreserve;
        }
        else
        {
            xd= xdDontPreserve;
        }

        if (xaUnknown != xa)
        {
            if (fCurrentFileChanged)
            {
                hr = BeginChangeFile(pwzCurrentFile, pxfc->iCompAttributes, &pwzCustomActionData);
                ExitOnFailure1(hr, "failed to begin file change for file: %ls", pwzCurrentFile);

                fCurrentFileChanged = FALSE;
                ++cFiles;
            }

            hr = WcaWriteIntegerToCaData((int)xa, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write action indicator custom action data");

            hr = WcaWriteIntegerToCaData((int)xd, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write Preserve Date indicator to custom action data");

            hr = WriteChangeData(pxfc, xa, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write change data");
        }
    }

    // If we looped through all records all is well
    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "failed while looping through all objects to secure");

    // Schedule the custom action and add to progress bar
    if (pwzCustomActionData && *pwzCustomActionData)
    {
        Assert(0 < cFiles);

        hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"ExecXmlConfig"), pwzCustomActionData, cFiles * COST_XMLFILE);
        ExitOnFailure(hr, "failed to schedule ExecXmlConfig action");
    }

LExit:
    ReleaseStr(pwzCurrentFile);
    ReleaseStr(pwzCustomActionData);

    FreeXmlConfigChangeList(pxfcHead);

    if (FAILED(hr))
    {
        er = ERROR_INSTALL_FAILURE;
    }
    return WcaFinalize(er);
}
Exemplo n.º 4
0
/********************************************************************
ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings

********************************************************************/
extern "C" UINT __stdcall ConfigureIIs7Exec(
    __in MSIHANDLE hInstall
    )
{
    //AssertSz(FALSE, "debug ConfigureIIs7Exec here");
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    LPWSTR pwzScriptKey = NULL;
    LPWSTR pwzCustomActionData = NULL;

    SCA_WEB7* pswList = NULL;
    SCA_WEBDIR7* pswdList = NULL;
    SCA_VDIR7* psvdList = NULL;
    SCA_FILTER* psfList = NULL;
    SCA_APPPOOL *psapList = NULL;
    SCA_MIMEMAP* psmmList = NULL;
    SCA_HTTP_HEADER* pshhList = NULL;
    SCA_PROPERTY *pspList = NULL;
    SCA_WEBSVCEXT* psWseList = NULL;
    SCA_WEB_ERROR* psweList = NULL;

    WCA_WRAPQUERY_HANDLE hUserQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL;
    WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL;

    // initialize
    hr = WcaInitialize(hInstall, "ConfigureIIs7Exec");
    ExitOnFailure(hr, "Failed to initialize");

    hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
    ExitOnFailure(hr, "failed to get CustomActionData");

    // Get the CaScript key
    hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey);
    ExitOnFailure(hr, "Failed to get CaScript key from custom action data");

    // read the msi tables
    hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap user query");

    hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions");

    hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools");

    // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read
    hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps");

    hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders");

    hr = ScaWebErrorRead(&psweList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors");

    hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web dir properties query");

    hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap ssl certificate query");

    hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web log query");

    hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web application query");

    hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web application extension query");

    hr = ScaWebsRead7(&pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites");

    hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web base query");

    hr = ScaWebDirsRead7(pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList);
    MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs");

    hr = ScaVirtualDirsRead7(pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs");

    hr = ScaFiltersRead7(pswList, hWebBaseQuery, &psfList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters");

    hr = ScaPropertyRead(&pspList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties");

    // do uninstall actions (order is important!)
    hr = ScaPropertyUninstall7(pspList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties");

    hr = ScaFiltersUninstall7(psfList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters");

    hr = ScaVirtualDirsUninstall7(psvdList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories");

    hr = ScaWebDirsUninstall7(pswdList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories");

    hr = ScaWebsUninstall7(pswList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs");

    hr = ScaAppPoolUninstall7(psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools");


    // do install actions (order is important!)
    // ScaWebSvcExtCommit contains both uninstall and install actions.
    hr = ScaWebSvcExtCommit7(psWseList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt");

    hr = ScaAppPoolInstall7(psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools");

    hr = ScaWebsInstall7(pswList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs");

    hr = ScaWebDirsInstall7(pswdList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories");

    hr = ScaVirtualDirsInstall7(psvdList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories");

    hr = ScaFiltersInstall7(psfList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters");

    hr = ScaPropertyInstall7(pspList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties");

    hr = ScaWriteConfigurationScript(pwzScriptKey);
    ExitOnFailure(hr, "failed to schedule metabase configuration");

LExit:
    ReleaseNullStr(pwzScriptKey);
    ReleaseNullStr(pwzCustomActionData);

    WcaFinishUnwrapQuery(hUserQuery);
    WcaFinishUnwrapQuery(hWebBaseQuery);
    WcaFinishUnwrapQuery(hWebDirPropQuery);
    WcaFinishUnwrapQuery(hSslCertQuery);
    WcaFinishUnwrapQuery(hWebLogQuery);
    WcaFinishUnwrapQuery(hWebAppQuery);
    WcaFinishUnwrapQuery(hWebAppExtQuery);

    if (psWseList)
    {
        ScaWebSvcExtFreeList(psWseList);
    }

    if (psfList)
    {
        ScaFiltersFreeList(psfList);
    }

    if (psvdList)
    {
        ScaVirtualDirsFreeList7(psvdList);
    }

    if (pswdList)
    {
        ScaWebDirsFreeList7(pswdList);
    }

    if (pswList)
    {
        ScaWebsFreeList7(pswList);
    }

    if (psmmList)
    {
        ScaMimeMapFreeList(psmmList);
    }

    if (pshhList)
    {
        ScaHttpHeaderCheckList(pshhList);
        ScaHttpHeaderFreeList(pshhList);
    }

    if (psweList)
    {
        ScaWebErrorCheckList(psweList);
        ScaWebErrorFreeList(psweList);
    }

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Exemplo n.º 5
0
/********************************************************************
ConfigureIIsExec - custom action for installing IIs settings - table
data will be wrapped and passed in from immediate CA
ReadIIsTables

********************************************************************/
extern "C" UINT __stdcall ConfigureIIsExec(
    __in MSIHANDLE hInstall
    )
{
    //AssertSz(FALSE, "debug ConfigureIIsExec here");
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    BOOL fInitializedCom = FALSE;
    IMSAdminBase* piMetabase = NULL;

    SCA_WEB* pswList = NULL;
    SCA_WEBDIR* pswdList = NULL;
    SCA_VDIR* psvdList = NULL;
    SCA_FILTER* psfList = NULL;
    SCA_APPPOOL *psapList = NULL;
    SCA_MIMEMAP* psmmList = NULL;
    SCA_HTTP_HEADER* pshhList = NULL;
    SCA_PROPERTY *pspList = NULL;
    SCA_WEBSVCEXT* psWseList = NULL;
    SCA_WEB_ERROR* psweList = NULL;

    LPWSTR pwzScriptKey = NULL;
    LPWSTR pwzCustomActionData = NULL;

    WCA_WRAPQUERY_HANDLE hUserQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL;
    WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL;
    WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL;

    // initialize
    hr = WcaInitialize(hInstall, "ConfigureIIsExec");
    ExitOnFailure(hr, "Failed to initialize");

    hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
    ExitOnFailure(hr, "failed to get CustomActionData");

    // Get the CaScript key
    hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey);
    ExitOnFailure(hr, "Failed to get CaScript key from custom action data");

    hr = ::CoInitialize(NULL);
    ExitOnFailure(hr, "failed to initialize COM");
    fInitializedCom = TRUE;

    // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the
    // user to still uninstall this package by clicking "Ignore"
    do
    {
        hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)&piMetabase);
        if (FAILED(hr))
        {
            WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object");
            er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
            switch (er)
            {
            case IDABORT:
                ExitFunction();   // bail with the error result from the CoCreate to kick off a rollback
            case IDRETRY:
                hr = S_FALSE;   // hit me, baby, one more time
                break;
            case IDIGNORE:
                __fallthrough;
            default:
                WcaLog(LOGMSG_STANDARD, "ignoring absent IIS");
                // We need to write the empty script to communicate to other deferred CA that there is noting to do.
                hr = ScaWriteConfigurationScript(pwzScriptKey);
                ExitOnFailure(hr, "failed to schedule metabase configuration");

                ExitFunction1(hr = S_OK);  // pretend everything is okay
                break;
            }
        }
    } while (S_FALSE == hr);

    // read the msi tables
    hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap user query");

    hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions");

    hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools");

    // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read
    hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps");

    hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders");

    hr = ScaWebErrorRead(&psweList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors");

    hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web dir properties query");

    hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap ssl certificate query");

    hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web log query");

    hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web application query");

    hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web application extension query");

    hr = ScaWebsRead(piMetabase, &psmmList, &pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites");

    hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap web base query");

    hr = ScaWebDirsRead(piMetabase, pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList);
    MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs");

    hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs");

    hr = ScaFiltersRead(piMetabase, pswList, hWebBaseQuery, &psfList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters");

    hr = ScaPropertyRead(&pspList, &pwzCustomActionData);
    MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties");

    // do uninstall actions (order is important!)
    hr = ScaPropertyUninstall(piMetabase, pspList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties");

    hr = ScaFiltersUninstall(piMetabase, psfList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters");

    hr = ScaVirtualDirsUninstall(piMetabase, psvdList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories");

    hr = ScaWebDirsUninstall(piMetabase, pswdList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories");

    hr = ScaWebsUninstall(piMetabase, pswList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs");

    hr = ScaAppPoolUninstall(piMetabase, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools");


    // do install actions (order is important!)
    // ScaWebSvcExtCommit contains both uninstall and install actions.
    hr = ScaWebSvcExtCommit(piMetabase, psWseList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt");

    hr = ScaAppPoolInstall(piMetabase, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools");

    hr = ScaWebsInstall(piMetabase, pswList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs");

    hr = ScaWebDirsInstall(piMetabase, pswdList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories");

    hr = ScaVirtualDirsInstall(piMetabase, psvdList, psapList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories");

    hr = ScaFiltersInstall(piMetabase, psfList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters");

    hr = ScaPropertyInstall(piMetabase, pspList);
    MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties");

    hr = ScaWriteConfigurationScript(pwzScriptKey);
    ExitOnFailure(hr, "failed to schedule metabase configuration");

LExit:
    ReleaseStr(pwzScriptKey);
    ReleaseStr(pwzCustomActionData);

    WcaFinishUnwrapQuery(hUserQuery);
    WcaFinishUnwrapQuery(hWebBaseQuery);
    WcaFinishUnwrapQuery(hWebDirPropQuery);
    WcaFinishUnwrapQuery(hSslCertQuery);
    WcaFinishUnwrapQuery(hWebLogQuery);
    WcaFinishUnwrapQuery(hWebAppQuery);
    WcaFinishUnwrapQuery(hWebAppExtQuery);

    if (psWseList)
    {
        ScaWebSvcExtFreeList(psWseList);
    }

    if (psfList)
    {
        ScaFiltersFreeList(psfList);
    }

    if (psvdList)
    {
        ScaVirtualDirsFreeList(psvdList);
    }

    if (pswdList)
    {
        ScaWebDirsFreeList(pswdList);
    }

    if (pswList)
    {
        ScaWebsFreeList(pswList);
    }

    if (psmmList)
    {
        ScaMimeMapCheckList(psmmList);
        ScaMimeMapFreeList(psmmList);
    }

    if (pshhList)
    {
        ScaHttpHeaderCheckList(pshhList);
        ScaHttpHeaderFreeList(pshhList);
    }

    if (psweList)
    {
        ScaWebErrorCheckList(psweList);
        ScaWebErrorFreeList(psweList);
    }

    ReleaseObject(piMetabase);

    if (fInitializedCom)
    {
        ::CoUninitialize();
    }

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Exemplo n.º 6
0
/********************************************************************
ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings

********************************************************************/
extern "C" UINT __stdcall ConfigureIIs(
    __in MSIHANDLE hInstall
    )
{
    //AssertSz(FALSE, "debug ConfigureIIs here");
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;
    LPWSTR pwzScriptKey = NULL;
    LPWSTR pwzBackupId = NULL;
    LPWSTR pwzCustomActionData = NULL; // CustomActionData for ConfigureIIs custom action

    // initialize
    hr = WcaInitialize(hInstall, "ConfigureIIs");
    ExitOnFailure(hr, "Failed to initialize");

    // check for the prerequsite tables
    if (S_OK != WcaTableExists(L"IIsWebSite") && S_OK != WcaTableExists(L"IIsFilter") && S_OK != WcaTableExists(L"IIsProperty") && 
        S_OK != WcaTableExists(L"IIsWebServiceExtension") && S_OK != WcaTableExists(L"IIsAppPool"))
    {
        WcaLog(LOGMSG_VERBOSE, "skipping IIs CustomAction, no IIsWebSite table, no IIsFilter table, no IIsProperty table, no IIsWebServiceExtension, and no IIsAppPool table");
        ExitFunction1(hr = S_FALSE);
    }

    // Get a CaScript key
    hr = WcaCaScriptCreateKey(&pwzScriptKey);
    ExitOnFailure(hr, "Failed to get encoding key.");

    // Generate a unique string to be used for this product's transaction
    // This prevents a name collision when doing a major upgrade
    hr = WcaGetProperty(L"ProductCode", &pwzBackupId);
    ExitOnFailure(hr, "failed to get ProductCode");

    hr = StrAllocConcat(&pwzBackupId, L"ScaConfigureIIs", 0);
    ExitOnFailure(hr, "failed to concat ScaConfigureIIs");

    // make sure the operations below are wrapped in a "transaction"
    // use IIS7 transaction logic even if using Iis6 compat because Backup/Restore don't work with metabase compatibility
    if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, IIS7CONDITION))
    {
        hr = ScaIIS7ConfigTransaction(pwzBackupId);
        MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS7 transaction");
    }
    else
    {
        hr = ScaMetabaseTransaction(pwzBackupId);
        MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS transaction");
    }

    // Write the CaScript key to the ConfigureIIS custom action data
    hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to add encoding key to CustomActionData.");

    // Wrap vcsUserDeferredQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"User"))
    {
        hr = WcaWrapQuery(vcsUserDeferredQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap User query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap User empty query");
    }

    // Wrap vcsWebSvcExtQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebServiceExtension"))
    {
        hr = WcaWrapQuery(vcsWebSvcExtQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4, 1, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension empty query");
    }

    // Wrap vcsAppPoolQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsAppPool"))
    {
        hr = WcaWrapQuery(vcsAppPoolQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn15 | efmcColumn16, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsAppPool query");

        hr = WcaWrapQuery(vcsComponentAttrQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap Component query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsAppPool empty query");
    }

    // Wrap vcsMimeMapQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsMimeMap"))
    {
        hr = WcaWrapQuery(vcsMimeMapQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsMimeMap query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsMimeMap empty query");
    }

    // Wrap vcsHttpHeaderQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsHttpHeader"))
    {
        hr = WcaWrapQuery(vcsHttpHeaderQuery, &pwzCustomActionData, efmcColumn1 | efmcColumn4, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsHttpHeader query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsHttpHeader empty query");
    }

    // Wrap vcsWebErrorQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebError"))
    {
        hr = WcaWrapQuery(vcsWebErrorQuery, &pwzCustomActionData, efmcColumn5 | efmcColumn6, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebError query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebError empty query");
    }

    // Wrap vcsWebDirPropertiesQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebDirProperties"))
    {
        hr = WcaWrapQuery(vcsWebDirPropertiesQuery, &pwzCustomActionData, efmcColumn8 | efmcColumn10 | efmcColumn12 | efmcColumn15, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties empty query");
    }

    // Wrap vcsSslCertificateQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"Certificate") && S_OK == WcaTableExists(L"CertificateHash") && S_OK == WcaTableExists(L"IIsWebSiteCertificates"))
    {
        hr = WcaWrapQuery(vcsSslCertificateQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap SslCertificate query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap SslCertificate empty query");
    }

    // Wrap vcsWebLogQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebLog"))
    {
        hr = WcaWrapQuery(vcsWebLogQuery, &pwzCustomActionData, efmcColumn2, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebLog query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebLog empty query");
    }

    // Wrap vcsWebApplicationQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebApplication"))
    {
        hr = WcaWrapQuery(vcsWebApplicationQuery, &pwzCustomActionData, efmcColumn1, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplication query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplication empty query");
    }

    // Wrap vcsWebAppExtensionQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebApplicationExtension"))
    {
        hr = WcaWrapQuery(vcsWebAppExtensionQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension empty query");
    }

    // Wrap vcsWebQuery, vcsWebAddressQuery, and vcsWebBaseQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebAddress") && S_OK == WcaTableExists(L"IIsWebSite"))
    {
        hr = WcaWrapQuery(vcsWebQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn12 | efmcColumn13 | efmcColumn14, 2, 6);
        ExitOnFailure(hr, "Failed to wrap IIsWebSite query");

        hr = WcaWrapQuery(vcsWebAddressQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebAddress query");

        hr = WcaWrapQuery(vcsWebBaseQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4 | efmcColumn5 | efmcColumn7, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebBase query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebSite empty query");

        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebAddress empty query");

        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebBase empty query");
    }

    // Wrap vcsWebDirQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebDir"))
    {
        hr = WcaWrapQuery(vcsWebDirQuery, &pwzCustomActionData, efmcColumn4, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebDir query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebDir empty query");
    }

    // Wrap vcsVDirQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebVirtualDir"))
    {
        hr = WcaWrapQuery(vcsVDirQuery, &pwzCustomActionData, efmcColumn4, 3, 5);
        ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir empty query");
    }

    // Wrap vcsFilterQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsFilter"))
    {
        hr = WcaWrapQuery(vcsFilterQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsFilter query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsFilter empty query");
    }

    // Wrap vcsPropertyQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsProperty"))
    {
        hr = WcaWrapQuery(vcsPropertyQuery, &pwzCustomActionData, efmcColumn4, 2, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsProperty query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsProperty empty query");
    }

    if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, USEIIS7CONDITION))
    {
        // This must remain trace only, CA data may contain password
        WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIIS7Exec will be: %ls", pwzCustomActionData);

        hr = WcaDoDeferredAction(L"ConfigureIIs7Exec", pwzCustomActionData, ConfigureIIsCost);
        ExitOnFailure(hr, "Failed to schedule ConfigureIIs7Exec custom action");

        ReleaseNullStr(pwzCustomActionData);

        // Write the CaScript key to the ConfigureIIS custom action data
        hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
        ExitOnFailure(hr, "Failed to add script key to CustomActionData.");

        hr = WcaDoDeferredAction(L"WriteIIS7ConfigChanges", pwzCustomActionData, WriteIIS7ConfigChangesCost);
        ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action");
    }
    else
    {
        // This must remain trace only, CA data may contain password
        WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIISExec will be: %ls", pwzCustomActionData);

        hr = WcaDoDeferredAction(L"ConfigureIIsExec", pwzCustomActionData, ConfigureIIsCost);
        ExitOnFailure(hr, "Failed to schedule ConfigureIISExec custom action");

        ReleaseNullStr(pwzCustomActionData);

        // Write the CaScript key to the ConfigureIIS custom action data
        hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
        ExitOnFailure(hr, "Failed to add script key to CustomActionData.");

        hr = WcaDoDeferredAction(L"WriteMetabaseChanges", pwzCustomActionData, WriteMetabaseChangesCost);
        ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action");
    }

LExit:
    ReleaseStr(pwzScriptKey);
    ReleaseStr(pwzBackupId);
    ReleaseStr(pwzCustomActionData);

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Exemplo n.º 7
0
/********************************************************************
 ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components

********************************************************************/
extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall)
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    BOOL fInitializedCom = FALSE;

    ICOMAdminCatalog* piCatalog = NULL;

    CPI_PARTITION_LIST partList;
    CPI_PARTITION_ROLE_LIST partRoleList;
    CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList;
    CPI_PARTITION_USER_LIST partUsrList;
    CPI_APPLICATION_LIST appList;
    CPI_APPLICATION_ROLE_LIST appRoleList;
    CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList;
    CPI_ASSEMBLY_LIST asmList;
    CPI_SUBSCRIPTION_LIST subList;

    LPWSTR pwzRollbackFileName = NULL;
    LPWSTR pwzActionData = NULL;
    LPWSTR pwzRollbackActionData = NULL;
    LPWSTR pwzCommitActionData = NULL;

    int iVersionNT = 0;
    int iProgress = 0;
    int iCommitProgress = 0;

    ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST));
    ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST));
    ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST));
    ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST));
    ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST));
    ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST));
    ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST));
    ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST));
    ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST));

    // initialize
    hr = WcaInitialize(hInstall, "ConfigureComPlusInstall");
    ExitOnFailure(hr, "Failed to initialize");

    hr = ::CoInitialize(NULL);
    ExitOnFailure(hr, "Failed to initialize COM");
    fInitializedCom = TRUE;

    CpiInitialize();

    // check for the prerequsite tables
    if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly))
    {
        WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present");
        ExitFunction1(hr = S_FALSE);
    }

    // make sure we can access the COM+ admin catalog
    do {
        hr = CpiGetAdminCatalog(&piCatalog);
        if (FAILED(hr))
        {
            WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog");
            er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
            switch (er)
            {
            case IDABORT:
                ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback
            case IDRETRY:
                hr = S_FALSE;
                break;
            case IDIGNORE:
            default:
                ExitFunction1(hr = S_OK); // pretend everything is okay and bail
            }
        }
    } while (S_FALSE == hr);

    // get NT version
    hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
    ExitOnFailure(hr, "Failed to get VersionNT property");

    // read elements
    if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition))
    {
        hr = CpiPartitionsRead(&partList);
        MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table");
    }

    if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole))
    {
        hr = CpiPartitionRolesRead(&partList, &partRoleList);
        MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table");
    }

    if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole)))
    {
        hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList);
        MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table");
    }

    if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser))
    {
        hr = CpiPartitionUsersRead(&partList, &partUsrList);
        MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table");
    }

    if (CpiTableExists(cptComPlusApplication))
    {
        hr = CpiApplicationsRead(&partList, &appList);
        MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table");
    }

    if (CpiTableExists(cptComPlusApplicationRole))
    {
        hr = CpiApplicationRolesRead(&appList, &appRoleList);
        MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table");
    }

    if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole))
    {
        hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList);
        MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table");
    }

    if (CpiTableExists(cptComPlusAssembly))
    {
        hr = CpiAssembliesRead(&appList, &appRoleList, &asmList);
        MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table");
    }

    if (CpiTableExists(cptComPlusSubscription))
    {
        hr = CpiSubscriptionsRead(&asmList, &subList);
        MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table");
    }

    // verify elements
    hr = CpiPartitionsVerifyInstall(&partList);
    ExitOnFailure(hr, "Failed to verify partitions");

    hr = CpiApplicationsVerifyInstall(&appList);
    ExitOnFailure(hr, "Failed to verify applications");

    hr = CpiApplicationRolesVerifyInstall(&appRoleList);
    ExitOnFailure(hr, "Failed to verify application roles");

    hr = CpiAssembliesVerifyInstall(&asmList);
    ExitOnFailure(hr, "Failed to verify assemblies");

    if (subList.iInstallCount)
    {
        hr = CpiSubscriptionsVerifyInstall(&subList);
        ExitOnFailure(hr, "Failed to verify subscriptions");
    }

    // schedule
    if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount ||
        appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount)
    {
        // create rollback file name
        hr = CpiGetTempFileName(&pwzRollbackFileName);
        ExitOnFailure(hr, "Failed to get rollback file name");

        // schedule rollback prepare custom action
        hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0);
        ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare");

        // schedule prepare custom action
        hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0);
        ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare");

        // schedule rollback custom action
        hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData);
        ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data");

        hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install subscriptions");
        hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install users in application roles");
        hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install application roles");
        hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install applications");
        hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install partition users");
        hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install users in partition roles");
        hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL);
        ExitOnFailure(hr, "Failed to install partitions");

        hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0);
        ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute");

        // schedule install custom action
        hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData);
        ExitOnFailure(hr, "Failed to add rollback file name to custom action data");

        hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install partitions");
        hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install users in partition roles");
        hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install partition users");
        hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install applications");
        hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install application roles");
        hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install users in application roles");
        hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress);
        ExitOnFailure(hr, "Failed to install subscriptions");

        hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress);
        ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute");

        // schedule install commit custom action
        hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData);
        ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data");

        hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
        ExitOnFailure(hr, "Failed to install assemblies");
        hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress);
        ExitOnFailure(hr, "Failed to install subscriptions");

        hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress);
        ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit");

        // schedule commit custom action
        hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0);
        ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit");
    }

    hr = S_OK;

LExit:
    // clean up
    ReleaseObject(piCatalog);

    ReleaseStr(pwzRollbackFileName);
    ReleaseStr(pwzActionData);
    ReleaseStr(pwzRollbackActionData);
    ReleaseStr(pwzCommitActionData);

    CpiPartitionListFree(&partList);
    CpiPartitionRoleListFree(&partRoleList);
    CpiUserInPartitionRoleListFree(&usrInPartRoleList);
    CpiPartitionUserListFree(&partUsrList);
    CpiApplicationListFree(&appList);
    CpiApplicationRoleListFree(&appRoleList);
    CpiUserInApplicationRoleListFree(&usrInAppRoleList);
    CpiAssemblyListFree(&asmList);
    CpiSubscriptionListFree(&subList);

    // unitialize
    CpiFinalize();

    if (fInitializedCom)
        ::CoUninitialize();

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}