Beispiel #1
0
HRESULT ScaDbsInstall(
    __in SCA_DB* psdList
    )
{
    HRESULT hr = S_FALSE; // assume nothing will be done
    SCA_DB* psd = NULL;

    for (psd = psdList; psd; psd = psd->psdNext)
    {
        if (psd->fHasComponent)
        {
            // if we need to drop, do that first
            if (((psd->iAttributes & SCADB_DROP_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) ||
                ((psd->iAttributes & SCADB_DROP_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction)))
            {
                hr = SchedDropDatabase(psd->wzKey, psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->iAttributes, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword);
                ExitOnFailure1(hr, "Failed to drop database %ls", psd->wzKey);
            }

            // if installing this component
            if (((psd->iAttributes & SCADB_CREATE_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) ||
                ((psd->iAttributes & SCADB_CREATE_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction)))
            {
                hr = SchedCreateDatabase(psd);
                ExitOnFailure1(hr, "Failed to ensure database %ls exists", psd->wzKey);
            }
        }
    }

LExit:
    return hr;
}
Beispiel #2
0
/********************************************************************
WcaGetComponentToDo() - gets a component's install states and
determines if they mean install, uninstall, or reinstall.
********************************************************************/
extern "C" WCA_TODO WIXAPI WcaGetComponentToDo(
    __in_z LPCWSTR wzComponentId
    )
{
    INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN;
    INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN;
    if (ERROR_SUCCESS != ::MsiGetComponentStateW(WcaGetInstallHandle(), wzComponentId, &isInstalled, &isAction))
    {
        return WCA_TODO_UNKNOWN;
    }

    if (WcaIsReInstalling(isInstalled, isAction))
    {
        return WCA_TODO_REINSTALL;
    }
    else if (WcaIsUninstalling(isInstalled, isAction))
    {
        return WCA_TODO_UNINSTALL;
    }
    else if (WcaIsInstalling(isInstalled, isAction))
    {
        return WCA_TODO_INSTALL;
    }
    else
    {
        return WCA_TODO_UNKNOWN;
    }
}
Beispiel #3
0
HRESULT ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList)
{
    HRESULT hr = S_OK;
    SCA_WEBDIR* pswd = pswdList;
    int i;

    while (pswd)
    {
        // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created
        if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction))
        {
            if (pswd->fHasApplication)
            {
                hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot);
                ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall");
            }
        }

        // if we are installing the web site
        if (WcaIsInstalling(pswd->isInstalled, pswd->isAction))
        {
            hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L"");
            ExitOnFailure(hr, "Failed to create key for WebDir");
            hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory");
            ExitOnFailure(hr, "Failed to write key type for for WebDir");
            i = 0x4000003e; // 1073741886: default directory browsing rights
            hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i));
            ExitOnFailure(hr, "Failed to set directory browsing for WebDir");

            // get the security information for this web
            if (pswd->fHasProperties)
            {
                ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp);
                ExitOnFailure(hr, "Failed to write properties for WebDir");
            }

            // get the application information for this web directory
            if (pswd->fHasApplication)
            {
                hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList);
                ExitOnFailure(hr, "Failed to write application for WebDir");
            }
        }

        pswd = pswd->pswdNext;
    }

LExit:
    return hr;
}
Beispiel #4
0
/* ****************************************************************
ScaUserExecute - Schedules user account creation or removal based on
component state.

******************************************************************/
HRESULT ScaUserExecute(
    __in SCA_USER *psuList
    )
{
    HRESULT hr = S_OK;
    DWORD er = 0;
    PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL;

    USER_INFO_0 *pUserInfo = NULL;
    LPWSTR pwzActionData = NULL;
    LPWSTR pwzRollbackData = NULL;

    for (SCA_USER *psu = psuList; psu; psu = psu->psuNext)
    {
        USER_EXISTS ueUserExists = USER_EXISTS_INDETERMINATE;

        // Always put the User Name and Domain plus Attributes on the front of the CustomAction
        // data.  Sometimes we'll add more data.
        Assert(psu->wzName);
        hr = WcaWriteStringToCaData(psu->wzName, &pwzActionData);
        ExitOnFailure1(hr, "Failed to add user name to custom action data: %ls", psu->wzName);
        hr = WcaWriteStringToCaData(psu->wzDomain, &pwzActionData);
        ExitOnFailure1(hr, "Failed to add user domain to custom action data: %ls", psu->wzDomain);
        hr = WcaWriteIntegerToCaData(psu->iAttributes, &pwzActionData);
        ExitOnFailure1(hr, "failed to add user attributes to custom action data for user: %ls", psu->wzKey);

        // Check to see if the user already exists since we have to be very careful when adding
        // and removing users.  Note: MSDN says that it is safe to call these APIs from any
        // user, so we should be safe calling it during immediate mode.
        er = ::NetApiBufferAllocate(sizeof(USER_INFO_0), reinterpret_cast<LPVOID*>(&pUserInfo));
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure1(hr, "Failed to allocate memory to check existence of user: %ls", psu->wzName);

        LPCWSTR wzDomain = psu->wzDomain;
        if (wzDomain && *wzDomain)
        {
            er = ::DsGetDcNameW(NULL, wzDomain, NULL, NULL, NULL, &pDomainControllerInfo);
            if (HRESULT_FROM_WIN32(er) == RPC_S_SERVER_UNAVAILABLE)
            {
                // MSDN says, if we get the above error code, try again with the "DS_FORCE_REDISCOVERY" flag
                er = ::DsGetDcNameW(NULL, wzDomain, NULL, NULL, DS_FORCE_REDISCOVERY, &pDomainControllerInfo);
            }
            if (ERROR_SUCCESS == er)
            {
                wzDomain = pDomainControllerInfo->DomainControllerName + 2;  //Add 2 so that we don't get the \\ prefix
            }
        }

        er = ::NetUserGetInfo(wzDomain, psu->wzName, 0, reinterpret_cast<LPBYTE*>(pUserInfo));
        if (NERR_Success == er)
        {
            ueUserExists = USER_EXISTS_YES;
        }
        else if (NERR_UserNotFound == er)
        {
            ueUserExists = USER_EXISTS_NO;
        }
        else
        {
            ueUserExists = USER_EXISTS_INDETERMINATE;
            hr = HRESULT_FROM_WIN32(er);
            WcaLog(LOGMSG_VERBOSE, "Failed to check existence of domain: %ls, user: %ls (error code 0x%x) - continuing", wzDomain, psu->wzName, hr);
        }

        if (WcaIsInstalling(psu->isInstalled, psu->isAction))
        {
            // If the user exists, check to see if we are supposed to fail if user the exists before
            // the install.
            if (USER_EXISTS_YES == ueUserExists)
            {
                // Reinstalls will always fail if we don't remove the check for "fail if exists".
                if (WcaIsReInstalling(psu->isInstalled, psu->isAction))
                {
                    psu->iAttributes &= ~SCAU_FAIL_IF_EXISTS;
                }

                if ((SCAU_FAIL_IF_EXISTS & (psu->iAttributes)) && !(SCAU_UPDATE_IF_EXISTS & (psu->iAttributes)))
                {
                    hr = HRESULT_FROM_WIN32(NERR_UserExists);
                    MessageExitOnFailure1(hr, msierrUSRFailedUserCreateExists, "Failed to create user: %ls because user already exists.", psu->wzName);
                }
            }

            // Rollback only if the user already exists, we couldn't determine if the user exists, or we are going to create the user
            if ((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists) || !(psu->iAttributes & SCAU_DONT_CREATE_USER))
            {
                INT iRollbackUserAttributes = psu->iAttributes;

                // If the user already exists, ensure this is accounted for in rollback
                if (USER_EXISTS_YES == ueUserExists)
                {
                    iRollbackUserAttributes |= SCAU_DONT_CREATE_USER;
                }
                else
                {
                    iRollbackUserAttributes &= ~SCAU_DONT_CREATE_USER;
                }

                hr = WcaWriteStringToCaData(psu->wzName, &pwzRollbackData);
                ExitOnFailure1(hr, "Failed to add user name to rollback custom action data: %ls", psu->wzName);
                hr = WcaWriteStringToCaData(psu->wzDomain, &pwzRollbackData);
                ExitOnFailure1(hr, "Failed to add user domain to rollback custom action data: %ls", psu->wzDomain);
                hr = WcaWriteIntegerToCaData(iRollbackUserAttributes, &pwzRollbackData);
                ExitOnFailure1(hr, "failed to add user attributes to rollback custom action data for user: %ls", psu->wzKey);

                // If the user already exists, add relevant group information to rollback data
                if (USER_EXISTS_YES == ueUserExists || USER_EXISTS_INDETERMINATE == ueUserExists)
                {
                    hr = WriteGroupRollbackInfo(psu->wzName, psu->wzDomain, psu->psgGroups, &pwzRollbackData);
                    ExitOnFailure(hr, "failed to add group information to rollback custom action data");
                }

                hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"CreateUserRollback"), pwzRollbackData, COST_USER_DELETE);
                ExitOnFailure(hr, "failed to schedule CreateUserRollback");
            }

            //
            // Schedule the creation now.
            //
            hr = WcaWriteStringToCaData(psu->wzPassword, &pwzActionData);
            ExitOnFailure1(hr, "failed to add user password to custom action data for user: %ls", psu->wzKey);

            // Add user's group information to custom action data
            hr = WriteGroupInfo(psu->psgGroups, &pwzActionData);
            ExitOnFailure(hr, "failed to add group information to custom action data");

            hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"CreateUser"), pwzActionData, COST_USER_ADD);
            ExitOnFailure(hr, "failed to schedule CreateUser");
        }
        else if (((USER_EXISTS_YES == ueUserExists) || (USER_EXISTS_INDETERMINATE == ueUserExists)) && WcaIsUninstalling(psu->isInstalled, psu->isAction) && !(psu->iAttributes & SCAU_DONT_REMOVE_ON_UNINSTALL))
        {
            // Add user's group information - this will ensure the user can be removed from any groups they were added to, if the user isn't be deleted
            hr = WriteGroupInfo(psu->psgGroups, &pwzActionData);
            ExitOnFailure(hr, "failed to add group information to custom action data");

            //
            // Schedule the removal because the user exists and we don't have any flags set
            // that say, don't remove the user on uninstall.
            //
            // Note: We can't rollback the removal of a user which is why RemoveUser is a commit 
            // CustomAction.
            hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"RemoveUser"), pwzActionData, COST_USER_DELETE);
            ExitOnFailure(hr, "failed to schedule RemoveUser");
        }

        ReleaseNullStr(pwzActionData);
        ReleaseNullStr(pwzRollbackData);
        if (pUserInfo)
        {
            ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo));
            pUserInfo = NULL;
        }
        if (pDomainControllerInfo)
        {
            ::NetApiBufferFree(static_cast<LPVOID>(pDomainControllerInfo));
            pDomainControllerInfo = NULL;
        }
    }

LExit:
    ReleaseStr(pwzActionData);
    ReleaseStr(pwzRollbackData);
    if (pUserInfo)
    {
        ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo));
    }
    if (pDomainControllerInfo)
    {
        ::NetApiBufferFree(static_cast<LPVOID>(pDomainControllerInfo));
    }

    return hr;
}
Beispiel #5
0
HRESULT ScaWebsRead(
    __in IMSAdminBase* piMetabase,
    __in SCA_MIMEMAP** ppsmmList,
    __in SCA_WEB** ppswList,
    __in SCA_HTTP_HEADER** ppshhList,
    __in SCA_WEB_ERROR** ppsweList,
    __in WCA_WRAPQUERY_HANDLE hUserQuery,
    __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery,
    __in WCA_WRAPQUERY_HANDLE hSslCertQuery,
    __in WCA_WRAPQUERY_HANDLE hWebLogQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery,
    __inout LPWSTR *ppwzCustomActionData
    )
{
    Assert(piMetabase && ppswList);

    HRESULT hr = S_OK;

    MSIHANDLE hRec;
    MSIHANDLE hRecAddresses;

    SCA_WEB* psw = NULL;
    LPWSTR pwzData = NULL;
    int iSiteId;

    DWORD dwLen = 0;
    WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL;
    WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL;

    hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead");

    hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead");

    if (0 == WcaGetQueryRecords(hQueryWebSite))
    {
        WcaLog(LOGMSG_VERBOSE, "Required tables not present");
        ExitFunction1(hr = S_FALSE);
    }

    // loop through all the webs
    while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec)))
    {
        psw = NewWeb();
        ExitOnNull(psw, hr, E_OUTOFMEMORY, "Failed to allocate memory for web object in memory");

        // get the darwin information
        hr = WcaGetRecordString(hRec, wqWeb, &pwzData);
        ExitOnFailure(hr, "Failed to get Web");
        hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData);
        ExitOnFailure(hr, "Failed to copy key string to web object");

        if (*pwzData && *ppsmmList)
        {
            hr = ScaGetMimeMap(mmptWeb, pwzData, ppsmmList, &psw->psmm);
            ExitOnFailure(hr, "Failed to get mimemap for VirtualDir");
        }

        // get component install state
        hr = WcaGetRecordString(hRec, wqComponent, &pwzData);
        ExitOnFailure(hr, "Failed to get Component for Web");
        hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData);
        ExitOnFailure(hr, "Failed to copy component string to web object");
        if (*(psw->wzComponent))
        {
            psw->fHasComponent = TRUE;

            hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled);
            ExitOnFailure(hr, "Failed to get web Component's installed state");

            WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction);
            ExitOnFailure(hr, "Failed to get web Component's action state");

            if (!WcaIsInstalling(psw->isInstalled, psw->isAction) && !WcaIsUninstalling(psw->isInstalled, psw->isAction)
                && !WcaIsReInstalling(psw->isInstalled, psw->isAction))
            {
                FreeWeb(psw);
                psw = NULL;

                continue; // If we aren't acting on this component, skip it
            }
        }

        hr = WcaGetRecordInteger(hRec, wqId, &iSiteId);
        ExitOnFailure(hr, "Failed to get SiteId for Web");

        // Get the web's key address.
        hr = WcaGetRecordString(hRec, wqAddress, &pwzData);
        ExitOnFailure(hr, "Failed to get Address for Web");
        hr = ::StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData);
        ExitOnFailure(hr, "Failed to copy key string to web object");

        hr = WcaGetRecordString(hRec, wqIP, &pwzData);
        ExitOnFailure(hr, "Failed to get IP for Web");
        hr = ::StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData);
        ExitOnFailure(hr, "Failed to copy IP string to web object");

        hr = WcaGetRecordString(hRec, wqPort, &pwzData);
        ExitOnFailure(hr, "Failed to get Web Address port");
        psw->swaKey.iPort = wcstol(pwzData, NULL, 10);

        hr = WcaGetRecordString(hRec, wqHeader, &pwzData);
        ExitOnFailure(hr, "Failed to get Header for Web");
        hr = ::StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData);
        ExitOnFailure(hr, "Failed to copy header string to web object");

        hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure);
        ExitOnFailure(hr, "Failed to get if Web is secure");
        if (S_FALSE == hr)
        {
            psw->swaKey.fSecure = FALSE;
        }

        // Get the web's description.
        hr = WcaGetRecordString(hRec, wqDescription, &pwzData);
        ExitOnFailure(hr, "Failed to get Description for Web");
        hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData);
        ExitOnFailure(hr, "Failed to copy description string to web object");

        // Try to find the web root in case it already exists.
        dwLen = METADATA_MAX_NAME_LEN;
        hr = ScaWebFindBase(piMetabase, *ppswList,
                            psw->wzKey,
                            iSiteId,
                            psw->swaKey.wzIP,
                            psw->swaKey.iPort,
                            psw->swaKey.wzHeader,
                            psw->swaKey.fSecure,
                            psw->wzDescription,
                            psw->wzWebBase, dwLen);
        if (S_OK == hr)
        {
            psw->fBaseExists = TRUE;
        }
        else if (S_FALSE == hr) // didn't find the web site.
        {
            psw->fBaseExists = FALSE;

            // If we're actually configuring the web site.
            if (psw->fHasComponent)
            {
                if (WcaIsInstalling(psw->isInstalled, psw->isAction))
                {
                    hr = ScaWebFindFreeBase(piMetabase, *ppswList, iSiteId, psw->wzDescription, psw->wzWebBase, countof(psw->wzWebBase));
                    ExitOnFailure(hr, "Failed to find free web root.");
                }
                else if (WcaIsUninstalling(psw->isInstalled, psw->isAction))
                {
                    WcaLog(LOGMSG_VERBOSE, "Web site: '%ls' was already removed, skipping.", psw->wzKey);

                    hr = S_OK;
                    continue;
                }
            }
        }
        ExitOnFailure(hr, "Failed to find web root");

        // get any extra web addresses
        WcaFetchWrappedReset(hQueryWebAddress);
        while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses)))
        {
            if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses)
            {
                hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded.");
            }

            hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData);
            ExitOnFailure(hr, "Failed to get extra web Address");

            // if this isn't the key address add it
            if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey))
            {
                hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData);
                ExitOnFailure(hr, "Failed to copy extra addresses key string to web object");

                hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData);
                ExitOnFailure(hr, "Failed to get extra web IP");
                hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData);
                ExitOnFailure(hr, "Failed to copy extra addresses IP string to web object");

                hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData);
                ExitOnFailure(hr, "Failed to get port for extra web IP");
                psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10);

                hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData);
                ExitOnFailure(hr, "Failed to get header for extra web IP");
                hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData);
                ExitOnFailure(hr, "Failed to copy extra addresses header string to web object");

                hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure);
                ExitOnFailure(hr, "Failed to get if secure extra web IP");
                if (S_FALSE == hr)
                    psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE;

                ++psw->cExtraAddresses;
            }
        }

        if (E_NOMOREITEMS == hr)
            hr = S_OK;
        ExitOnFailure(hr, "Failure occured while getting extra web addresses");

        hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout);
        ExitOnFailure(hr, "Failed to get connection timeout for Web");

        if (psw->fHasComponent) // If we're installing it, it needs a dir
        {
            // get the web's directory
            if (INSTALLSTATE_SOURCE == psw->isAction)
            {
                hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData);
            }
            else
            {
                hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData);
            }
            ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory");

            // remove trailing backslashes
            while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\')
            {
                pwzData[lstrlenW(pwzData)-1] = 0;
            }
            hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData);
            ExitOnFailure(hr, "Failed to copy directory string to web object");
        }

        hr = WcaGetRecordInteger(hRec, wqState, &psw->iState);
        ExitOnFailure(hr, "Failed to get state for Web");

        hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes);
        ExitOnFailure(hr, "Failed to get attributes for Web");

        // get the dir properties for this web
        hr = WcaGetRecordString(hRec, wqProperties, &pwzData);
        ExitOnFailure(hr, "Failed to get directory property record for Web");
        if (*pwzData)
        {
            hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp);
            ExitOnFailure(hr, "Failed to get directory properties for Web");

            psw->fHasProperties = TRUE;
        }

        // get the application information for this web
        hr = WcaGetRecordString(hRec, wqApplication, &pwzData);
        ExitOnFailure(hr, "Failed to get application identifier for Web");
        if (*pwzData)
        {
            hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp);
            ExitOnFailure(hr, "Failed to get application for Web");

            psw->fHasApplication = TRUE;
        }

        // get the SSL certificates
        hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList));
        ExitOnFailure(hr, "Failed to get SSL Certificates.");

        // get the custom headers
        if (*ppshhList)
        {
            hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList));
            ExitOnFailure(hr, "Failed to get Custom HTTP Headers");
        }

        // get the errors
        if (*ppsweList)
        {
            hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList));
            ExitOnFailure(hr, "Failed to get Custom Errors");
        }

        // get the log information for this web
        hr = WcaGetRecordString(hRec, wqLog, &pwzData);
        ExitOnFailure(hr, "Failed to get log identifier for Web");
        if (*pwzData)
        {
            hr = ScaGetWebLog(piMetabase, pwzData, hWebLogQuery, &psw->swl);
            ExitOnFailure(hr, "Failed to get Log for Web.");

            psw->fHasLog = TRUE;
        }

        *ppswList = AddWebToList(*ppswList, psw);
        psw = NULL; // set the web NULL so it doesn't accidentally get freed below
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }

LExit:
    // if anything was left over after an error clean it all up
    WcaFinishUnwrapQuery(hQueryWebSite);
    WcaFinishUnwrapQuery(hQueryWebAddress);

    if (psw)
    {
        ScaWebsFreeList(psw);
    }

    ReleaseStr(pwzData);

    return hr;
}
Beispiel #6
0
HRESULT ScaVirtualDirsInstall(
    __in IMSAdminBase* piMetabase,
    __in SCA_VDIR* psvdList,
    __in SCA_APPPOOL * psapList
    )
{
    Assert(piMetabase);

    HRESULT hr = S_OK;
    SCA_VDIR* psvd = psvdList;
    int i;

    while (psvd)
    {
        // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created
        if (WcaIsReInstalling(psvd->isInstalled, psvd->isAction))
        {
            if (psvd->fHasApplication)
            {
                hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot);
                ExitOnFailure(hr, "Failed to remove application for WebVDir as part of a reinstall");
            }
        }

        if (WcaIsInstalling(psvd->isInstalled, psvd->isAction))
        {
            hr = ScaCreateMetabaseKey(piMetabase, psvd->wzVDirRoot, L"");
            ExitOnFailure(hr, "Failed to create key for VirtualDir");
            hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir");
            ExitOnFailure(hr, "Failed to write key type for for VirtualDir");
            i = 0x4000003e; // 1073741886;	// default directory browsing rights
            hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i));
            ExitOnFailure(hr, "Failed to set directory browsing for VirtualDir");

            hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psvd->wzDirectory);
            ExitOnFailure(hr, "Failed to write Directory for VirtualDir");

            if (psvd->fHasProperties)
            {
                ScaWriteWebDirProperties(piMetabase, psvd->wzVDirRoot, &psvd->swp);
                ExitOnFailure(hr, "Failed to write directory properties for VirtualDir");
            }

            if (psvd->fHasApplication)
            {
                hr = ScaWriteWebApplication(piMetabase, psvd->wzVDirRoot, &psvd->swapp, psapList);
                ExitOnFailure(hr, "Failed to write application for VirtualDir");
            }

            if (psvd->psmm)
            {
                hr = ScaWriteMimeMap(piMetabase, psvd->wzVDirRoot, psvd->psmm);
                ExitOnFailure(hr, "Failed to write mimemap for VirtualDir");
            }

            if (psvd->pshh)
            {
                hr = ScaWriteHttpHeader(piMetabase, psvd->wzVDirRoot, psvd->pshh);
                ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir");
            }

            if (psvd->pswe)
            {
                hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe);
                ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir");
            }
        }

        psvd = psvd->psvdNext;
    }

LExit:
    return hr;
}
Beispiel #7
0
HRESULT __stdcall ScaVirtualDirsRead(
    __in IMSAdminBase* piMetabase,
    __in SCA_WEB* pswList,
    __in SCA_VDIR** ppsvdList,
    __in SCA_MIMEMAP** ppsmmList,
    __in SCA_HTTP_HEADER** ppshhList,
    __in SCA_WEB_ERROR** ppsweList,
    __in WCA_WRAPQUERY_HANDLE hUserQuery,
    __in WCA_WRAPQUERY_HANDLE hWebBaseQuery,
    __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery,
    __inout LPWSTR *ppwzCustomActionData
    )
{
    Assert(piMetabase && ppsvdList);

    HRESULT hr = S_OK;
    MSIHANDLE hRec;
    INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN;
    INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN;

    SCA_VDIR* pvdir = NULL;
    LPWSTR pwzData = NULL;

    WCA_WRAPQUERY_HANDLE hWrapQuery = NULL;

    hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead");

    if (0 == WcaGetQueryRecords(hWrapQuery))
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present");
        ExitFunction1(hr = S_FALSE);
    }

    // loop through all the vdirs
    while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec)))
    {
        // Get the Component first.  If there is a Component and it is not being modified during
        // this transaction, skip processing this whole record.
        hr = WcaGetRecordString(hRec, vdqComponent, &pwzData);
        ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component");

        hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&isInstalled);
        ExitOnFailure(hr, "Failed to get Component installed state for virtual dir");

        hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&isAction);
        ExitOnFailure(hr, "Failed to get Component action state for virtual dir");

        if (!WcaIsInstalling(isInstalled, isAction) &&
            !WcaIsReInstalling(isInstalled, isAction) &&
            !WcaIsUninstalling(isInstalled, isAction))
        {
            continue; // skip this record.
        }

        hr = AddVirtualDirToList(ppsvdList);
        ExitOnFailure(hr, "failed to add virtual dir to list");

        pvdir = *ppsvdList;

        hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData);
        ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData);

        pvdir->isInstalled = isInstalled;
        pvdir->isAction = isAction;

        // get the web key
        hr = WcaGetRecordString(hRec, vdqWeb, &pwzData);
        ExitOnFailure(hr, "Failed to get Web for VirtualDir");

        hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pvdir->wzWebBase, countof(pvdir->wzWebBase), hWebBaseQuery);
        if (WcaIsUninstalling(isInstalled, isAction))
        {
            // If we're uninstalling, ignore any failure to find the existing web
            hr = S_OK;
        }
        ExitOnFailure1(hr, "Failed to get base of web: %ls for VirtualDir", pwzData);

        hr = WcaGetRecordString(hRec, vdqAlias, &pwzData);
        ExitOnFailure(hr, "Failed to get Alias for VirtualDir");

        if (0 != lstrlenW(pvdir->wzWebBase))
        {
            hr = ::StringCchPrintfW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), L"%s/Root/%s", pvdir->wzWebBase, pwzData);
            ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir");
        }

        // get the vdir's directory
        hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData);
        ExitOnFailure(hr, "Failed to get Directory for VirtualDir");

        // get the web's directory
        if (INSTALLSTATE_SOURCE == pvdir->isAction)
        {
            hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData);
        }
        else
        {
            hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData);
        }
        ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory");

        // remove trailing backslash(es)
        while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\')
        {
            pwzData[lstrlenW(pwzData)-1] = 0;
        }
        hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData);
        ExitOnFailure(hr, "Failed to copy directory string to vdir object");

        // get the security information for this web
        hr = WcaGetRecordString(hRec, vdqProperties, &pwzData);
        ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir");
        if (*pwzData)
        {
            hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp);
            ExitOnFailure(hr, "Failed to get web directory for VirtualDir");

            pvdir->fHasProperties = TRUE;
        }

        // get the application information for this web
        hr = WcaGetRecordString(hRec, vdqApplication, &pwzData);
        ExitOnFailure(hr, "Failed to get application identifier for VirtualDir");
        if (*pwzData)
        {
            hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp);
            ExitOnFailure(hr, "Failed to get application for VirtualDir");

            pvdir->fHasApplication = TRUE;
        }

        hr = WcaGetRecordString(hRec, vdqVDir, &pwzData);
        ExitOnFailure(hr, "Failed to get VDir for VirtualDir");

        if (*pwzData && *ppsmmList)
        {
            hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm);
            ExitOnFailure(hr, "Failed to get mimemap for VirtualDir");
        }

        if (*pwzData && *ppshhList)
        {
            hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh);
            ExitOnFailure1(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData);
        }

        if (*pwzData && *ppsweList)
        {
            hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe);
            ExitOnFailure1(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData);
        }
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure while processing VirtualDirs");

LExit:
    WcaFinishUnwrapQuery(hWrapQuery);

    ReleaseStr(pwzData);
    return hr;
}
Beispiel #8
0
static HRESULT ExecuteStrings(
    __in SCA_DB* psdList,
    __in SCA_SQLSTR* psssList,
    __in BOOL fInstall
    )
{
    HRESULT hr = S_FALSE; // assume nothing will be done

    int iRollback = -1;
    int iOldRollback = iRollback;

    LPCWSTR wzOldDb = NULL;
    UINT uiCost = 0;
    WCHAR* pwzCustomActionData = NULL;
    WCHAR wzNumber[64];

    // loop through all sql strings
    for (SCA_SQLSTR* psss = psssList; psss; psss = psss->psssNext)
    {
        // if installing this component
        if ((fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_INSTALL) && WcaIsInstalling(psss->isInstalled, psss->isAction) && !WcaIsReInstalling(psss->isInstalled, psss->isAction)) ||
            (fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_REINSTALL) && WcaIsReInstalling(psss->isInstalled, psss->isAction)) ||
            (!fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_UNINSTALL) && WcaIsUninstalling(psss->isInstalled, psss->isAction)))
        {
            // determine if this is a rollback scheduling or normal deferred scheduling
            if (psss->iAttributes & SCASQL_ROLLBACK)
            {
                iRollback = 1;
            }
            else
            {
                iRollback = 0;
            }

            // if we need to create a connection to a new server\database
            if (!wzOldDb || 0 != lstrcmpW(wzOldDb, psss->wzSqlDb) || iOldRollback != iRollback)
            {
                const SCA_DB* psd = ScaDbsFindDatabase(psss->wzSqlDb, psdList);
                if (!psd)
                {
                    ExitOnFailure1(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "failed to find data for Database: %ls", psss->wzSqlDb);
                }

                if (-1 == iOldRollback)
                {
                    iOldRollback = iRollback;
                }
                Assert(0 == iOldRollback || 1 == iOldRollback);

                // if there was custom action data before, schedule the action to write it
                if (pwzCustomActionData && *pwzCustomActionData)
                {
                    Assert(pwzCustomActionData && *pwzCustomActionData && uiCost);

                    hr = WcaDoDeferredAction(1 == iOldRollback ? L"RollbackExecuteSqlStrings" : L"ExecuteSqlStrings", pwzCustomActionData, uiCost);
                    ExitOnFailure1(hr, "failed to schedule ExecuteSqlStrings action, rollback: %d", iOldRollback);
                    iOldRollback = iRollback;

                    *pwzCustomActionData = L'\0';
                    uiCost = 0;
                }

                Assert(!pwzCustomActionData  || (pwzCustomActionData && 0 == *pwzCustomActionData) && 0 == uiCost);

                hr = WcaWriteStringToCaData(psd->wzKey, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Server Database String to CustomActionData for Database String: %ls", psd->wzKey);

                hr = WcaWriteStringToCaData(psd->wzServer, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Server to CustomActionData for Database String: %ls", psd->wzKey);

                hr = WcaWriteStringToCaData(psd->wzInstance, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Instance to CustomActionData for Database String: %ls", psd->wzKey);

                hr = WcaWriteStringToCaData(psd->wzDatabase, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Database to CustomActionData for Database String: %ls", psd->wzKey);

                hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->iAttributes);
                ExitOnFailure(hr, "Failed to format attributes integer value to string");
                hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Attributes to CustomActionData for Database String: %ls", psd->wzKey);

                hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->fUseIntegratedAuth);
                ExitOnFailure(hr, "Failed to format UseIntegratedAuth integer value to string");
                hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL IntegratedAuth flag to CustomActionData for Database String: %ls", psd->wzKey);

                hr = WcaWriteStringToCaData(psd->scau.wzName, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL UserName to CustomActionData for Database String: %ls", psd->wzKey);

                hr = WcaWriteStringToCaData(psd->scau.wzPassword, &pwzCustomActionData);
                ExitOnFailure1(hr, "Failed to add SQL Password to CustomActionData for Database String: %ls", psd->wzKey);

                uiCost += COST_SQL_CONNECTDB;

                wzOldDb = psss->wzSqlDb;
            }

            WcaLog(LOGMSG_VERBOSE, "Scheduling SQL string: %ls", psss->pwzSql);

            hr = WcaWriteStringToCaData(psss->wzKey, &pwzCustomActionData);
            ExitOnFailure1(hr, "Failed to add SQL Key to CustomActionData for SQL string: %ls", psss->wzKey);

            hr = WcaWriteIntegerToCaData(psss->iAttributes, &pwzCustomActionData);
            ExitOnFailure1(hr, "failed to add attributes to CustomActionData for SQL string: %ls", psss->wzKey);

            hr = WcaWriteStringToCaData(psss->pwzSql, &pwzCustomActionData);
            ExitOnFailure1(hr, "Failed to to add SQL Query to CustomActionData for SQL string: %ls", psss->wzKey);
            uiCost += COST_SQL_STRING;
        }
    }

    if (pwzCustomActionData && *pwzCustomActionData)
    {
        Assert(pwzCustomActionData && *pwzCustomActionData && uiCost);
        hr = WcaDoDeferredAction(1 == iRollback ? L"RollbackExecuteSqlStrings" : L"ExecuteSqlStrings", pwzCustomActionData, uiCost);
        ExitOnFailure(hr, "Failed to schedule ExecuteSqlStrings action");

        *pwzCustomActionData = L'\0';
        uiCost = 0;
    }

LExit:
    ReleaseStr(pwzCustomActionData);

    return hr;
}
Beispiel #9
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);
}
Beispiel #10
0
UINT __stdcall ScaWebDirsRead(
    __in IMSAdminBase* piMetabase,
    __in SCA_WEB* pswList,
    __in WCA_WRAPQUERY_HANDLE hUserQuery,
    __in WCA_WRAPQUERY_HANDLE hWebBaseQuery,
    __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppQuery,
    __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery,
    __inout LPWSTR *ppwzCustomActionData,
    __out SCA_WEBDIR** ppswdList
    )
{
    Assert(piMetabase && ppswdList);

    HRESULT hr = S_OK;
    MSIHANDLE hRec;

    LPWSTR pwzData = NULL;
    SCA_WEBDIR* pswd;
    WCA_WRAPQUERY_HANDLE hWrapQuery = NULL;

    hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead");

    if (0 == WcaGetQueryRecords(hWrapQuery))
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs() because IIsWebDir table not present");
        ExitFunction1(hr = S_FALSE);
    }

    // loop through all the web directories
    while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec)))
    {
        pswd = NewWebDir();
        ExitOnNull(pswd, hr, E_OUTOFMEMORY, "Failed to allocate memory for web dir object in memory");

        // get component install state
        hr = WcaGetRecordString(hRec, wdqComponent, &pwzData);
        ExitOnFailure(hr, "Failed to get Component for WebDirs");
        hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData);
        ExitOnFailure(hr, "Failed to copy component string to webdir object");

        hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled);
        ExitOnFailure(hr, "Failed to get Component installed state for webdir");

        hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction);
        ExitOnFailure(hr, "Failed to get Component action state for webdir");

        // If this record has a component and no action is being taken for it, skip processing it entirely
        if (0 < lstrlenW(pswd->wzComponent) && !WcaIsInstalling(pswd->isInstalled, pswd->isAction)
            && !WcaIsUninstalling(pswd->isInstalled, pswd->isAction) && !WcaIsReInstalling(pswd->isInstalled, pswd->isAction))
        {
            FreeWebDir(pswd);
            pswd = NULL;
            continue;
        }

        hr = WcaGetRecordString(hRec, wdqWeb, &pwzData);
        ExitOnFailure(hr, "Failed to get Web for WebDir");

        hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pswd->wzWebBase, countof(pswd->wzWebBase), hWebBaseQuery);
        if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction))
        {
            // If we're uninstalling, ignore any failure to find the existing web
            hr = S_OK;
        }

        ExitOnFailure(hr, "Failed to get base of web for WebDir");

        hr = WcaGetRecordString(hRec, wdqPath, &pwzData);
        ExitOnFailure(hr, "Failed to get Path for WebDir");

        hr = ::StringCchPrintfW(pswd->wzWebDirRoot, countof(pswd->wzWebDirRoot), L"%s/Root/%s", pswd->wzWebBase, pwzData);
        ExitOnFailure(hr, "Failed to format webdir root string");

        // get the directory properties for this web
        hr = WcaGetRecordString(hRec, wdqProperties, &pwzData);
        ExitOnFailure(hr, "Failed to get security identifier for WebDir");
        if (*pwzData)
        {
            hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp);
            ExitOnFailure(hr, "Failed to get properties for WebDir");

            pswd->fHasProperties = TRUE;
        }

        // get the application information for this web directory
        hr = WcaGetRecordString(hRec, wdqApplication, &pwzData);
        ExitOnFailure(hr, "Failed to get application identifier for WebDir");
        if (*pwzData)
        {
            hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp);
            ExitOnFailure(hr, "Failed to get application for WebDir");

            pswd->fHasApplication = TRUE;
        }

        AddWebDirToList(ppswdList, pswd);
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure while processing WebDirs");

LExit:
    WcaFinishUnwrapQuery(hWrapQuery);

    ReleaseStr(pwzData);

    return hr;
}
Beispiel #11
0
UINT __stdcall ScaFiltersRead7(
    __in SCA_WEB7* pswList,
    __in WCA_WRAPQUERY_HANDLE hWebBaseQuery,
    __inout SCA_FILTER** ppsfList,
    __inout LPWSTR *ppwzCustomActionData
    )
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;
    MSIHANDLE hRec;
    INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN;
    INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN;
    SCA_FILTER* psf;

    LPWSTR pwzData = NULL;
    WCA_WRAPQUERY_HANDLE hWrapQuery = NULL;
    hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData);
    ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead");

    if (0 == WcaGetQueryRecords(hWrapQuery))
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table");
        ExitFunction1(hr = S_FALSE);
    }

    // loop through all the filters
    while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec)))
    {
        // Get the Component first.  If the component is not being modified during
        // this transaction, skip processing this whole record.
        // get the darwin information
        hr = WcaGetRecordString(hRec, fqComponent, &pwzData);
        ExitOnFailure(hr, "failed to get IIsFilter.Component");

        hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled);
        ExitOnFailure(hr, "Failed to get Component installed state for IIs filter");

        hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction);
        ExitOnFailure(hr, "Failed to get Component action state for IIs filter");

        if (!WcaIsInstalling(isInstalled, isAction) &&
            !WcaIsReInstalling(isInstalled, isAction) &&
            !WcaIsUninstalling(isInstalled, isAction))
        {
            continue; // skip this record.
        }

        hr = AddFilterToList(ppsfList);
        ExitOnFailure(hr, "failed to add filter to list");

        psf = *ppsfList;

        hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData);
        ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData);

        psf->isInstalled = isInstalled;
        psf->isAction = isAction;

        hr = WcaGetRecordString(hRec, fqWeb, &pwzData);
        ExitOnFailure(hr, "Failed to get Web for VirtualDir");

        if (*pwzData)
        {
            hr = ScaWebsGetBase7(pswList, pwzData, psf->wzFilterRoot, countof(psf->wzFilterRoot));
            if (FAILED(hr))
            {
                WcaLog(LOGMSG_VERBOSE, "Could not find site for filter: %ls. Result 0x%x ", psf->wzFilterRoot, hr);
                hr = S_OK;
            }
        }
        else
        {
            hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/");
            ExitOnFailure(hr, "Failed to allocate global filter base string");
        }

        // filter Name key
        hr = WcaGetRecordString(hRec, fqFilter, &pwzData);
        ExitOnFailure(hr, "Failed to get Filter.Filter");
        hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData);
        ExitOnFailure(hr, "Failed to copy key string to filter object");

        // filter path
        hr = WcaGetRecordString(hRec, fqPath, &pwzData);
        ExitOnFailure(hr, "Failed to get Filter.Path");
        hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData);
        ExitOnFailure(hr, "Failed to copy path string to filter object");

        // filter description -- not supported in iis 7
        hr = WcaGetRecordString(hRec, fqDescription, &pwzData);
        ExitOnFailure(hr, "Failed to get Filter.Description");
        hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData);
        ExitOnFailure(hr, "Failed to copy description string to filter object");

        // filter flags
        //What are these
        hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags);
        ExitOnFailure(hr, "Failed to get Filter.Flags");

        // filter load order
        hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder);
        ExitOnFailure(hr, "Failed to get Filter.LoadOrder");
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure while processing filters");

LExit:
    WcaFinishUnwrapQuery(hWrapQuery);

    ReleaseStr(pwzData);

    return hr;
}
Beispiel #12
0
/******************************************************************
 SchedNetFx - entry point for NetFx Custom Action

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

    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    LPWSTR pwzInstallCustomActionData = NULL;
    LPWSTR pwzUninstallCustomActionData = NULL;
    UINT uiCost = 0;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRec = NULL;
    PMSIHANDLE hViewGac = NULL;
    PMSIHANDLE hRecGac = NULL;

    LPWSTR pwzId = NULL;
    LPWSTR pwzData = NULL;
    LPWSTR pwzTemp = NULL;
    LPWSTR pwzFile = NULL;
    int iPriority = 0;
    int iAssemblyCost = 0;
    int iAttributes = 0;
    LPWSTR pwzFileApp = NULL;
    LPWSTR pwzDirAppBase = NULL;
    LPWSTR pwzComponent = NULL;

    INSTALLSTATE isInstalled;
    INSTALLSTATE isAction;

    LPWSTR pwz32Ngen = NULL;
    LPWSTR pwz64Ngen = NULL;

    BOOL f32NgenExeExists = FALSE;
    BOOL f64NgenExeExists = FALSE;

    BOOL fNeedInstallUpdate32 = FALSE;
    BOOL fNeedUninstallUpdate32 = FALSE;
    BOOL fNeedInstallUpdate64 = FALSE;
    BOOL fNeedUninstallUpdate64 = FALSE;

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

    hr = GetNgenPath(&pwz32Ngen, FALSE);
    f32NgenExeExists = SUCCEEDED(hr);
    if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
    {
        hr = ERROR_SUCCESS;
        WcaLog(LOGMSG_STANDARD, "Failed to find 32bit ngen. No actions will be scheduled to create native images for 32bit.");
    }
    ExitOnFailure(hr, "failed to get 32bit ngen.exe path");

    hr = GetNgenPath(&pwz64Ngen, TRUE);
    f64NgenExeExists = SUCCEEDED(hr);
    if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
    {
        hr = ERROR_SUCCESS;
        WcaLog(LOGMSG_STANDARD, "Failed to find 64bit ngen. No actions will be scheduled to create native images for 64bit.");
    }
    ExitOnFailure(hr, "failed to get 64bit ngen.exe path");

    // loop through all the NetFx records
    hr = WcaOpenExecuteView(vcsNgenQuery, &hView);
    ExitOnFailure(hr, "failed to open view on NetFxNativeImage table");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        // Get Id
        hr = WcaGetRecordString(hRec, ngqId, &pwzId);
        ExitOnFailure(hr, "failed to get NetFxNativeImage.NetFxNativeImage");

        // Get File
        hr = WcaGetRecordString(hRec, ngqFile, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.File_ for record: %ls", pwzId);
        hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedFile, pwzData);
        ExitOnFailure1(hr, "failed to format file string for file: %ls", pwzData);
        hr = WcaGetFormattedString(pwzTemp, &pwzFile);
        ExitOnFailure1(hr, "failed to get formatted string for file: %ls", pwzData);

        // Get Priority
        hr = WcaGetRecordInteger(hRec, ngqPriority, &iPriority);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Priority for record: %ls", pwzId);

        if (0 == iPriority)
            iAssemblyCost = COST_NGEN_BLOCKING;
        else
            iAssemblyCost = COST_NGEN_NONBLOCKING;

        // Get Attributes
        hr = WcaGetRecordInteger(hRec, ngqAttributes, &iAttributes);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Attributes for record: %ls", pwzId);

        // Get File_Application or leave pwzFileApp NULL.
        hr = WcaGetRecordFormattedString(hRec, ngqFileApp, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.File_Application for record: %ls", pwzId);

        // Check if the value resolves to a valid file ID.
        if (S_OK == FileIdExists(pwzData))
        {
            // Resolve the file ID to a path.
            hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedFile, pwzData);
            ExitOnFailure1(hr, "failed to format file application string for file: %ls", pwzData);

            hr = WcaGetFormattedString(pwzTemp, &pwzFileApp);
            ExitOnFailure1(hr, "failed to get formatted string for file application: %ls", pwzData);
        }
        else
        {
            // Assume record formatted to a path already.
            hr = StrAllocString(&pwzFileApp, pwzData, 0);
            ExitOnFailure1(hr, "failed to allocate string for file path: %ls", pwzData);

            hr = PathEnsureQuoted(&pwzFileApp, FALSE);
            ExitOnFailure1(hr, "failed to quote file path: %ls", pwzData);
        }

        // Get Directory_ApplicationBase or leave pwzDirAppBase NULL.
        hr = WcaGetRecordFormattedString(hRec, ngqDirAppBase, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Directory_ApplicationBase for record: %ls", pwzId);

        if (WcaIsUnicodePropertySet(pwzData))
        {
            // Resolve the directory ID to a path.
            hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedDirectory, pwzData);
            ExitOnFailure1(hr, "failed to format directory application base string for property: %ls", pwzData);

            hr = WcaGetFormattedString(pwzTemp, &pwzDirAppBase);
            ExitOnFailure1(hr, "failed to get formatted string for directory application base: %ls", pwzData);
        }
        else
        {
            // Assume record formatted to a path already.
            hr = StrAllocString(&pwzDirAppBase, pwzData, 0);
            ExitOnFailure1(hr, "failed to allocate string for directory path: %ls", pwzData);

            hr = PathEnsureQuoted(&pwzDirAppBase, TRUE);
            ExitOnFailure1(hr, "failed to quote and backslashify directory: %ls", pwzData);
        }

        // Get Component
        hr = WcaGetRecordString(hRec, ngqComponent, &pwzComponent);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Directory_ApplicationBase for record: %ls", pwzId);
        er = ::MsiGetComponentStateW(hInstall, pwzComponent, &isInstalled, &isAction);
        ExitOnWin32Error1(er, hr, "failed to get install state for Component: %ls", pwzComponent);

        //
        // Figure out if it's going to be GAC'd.  The possibility exists that no assemblies are going to be GAC'd 
        // so we have to check for the MsiAssembly table first.
        //
        if (S_OK == WcaTableExists(L"MsiAssembly"))
        {
            hr = WcaOpenView(vcsNgenGac, &hViewGac);
            ExitOnFailure(hr, "failed to open view on File/MsiAssembly table");

            hr = WcaExecuteView(hViewGac, hRec);
            ExitOnFailure(hr, "failed to execute view on File/MsiAssembly table");

            hr = WcaFetchSingleRecord(hViewGac, &hRecGac);
            ExitOnFailure(hr, "failed to fetch File_Assembly from File/MsiAssembly table");

            if (S_FALSE != hr)
            {
                hr = WcaGetRecordString(hRecGac, nggApplication, &pwzData);
                ExitOnFailure(hr, "failed to get MsiAssembly.File_Application");

                // If it's in the GAC replace the file name with the strong name
                if (L'\0' == pwzData[0])
                {
                    hr = GetStrongName(&pwzFile, pwzComponent);
                    ExitOnFailure1(hr, "failed to get strong name for component: %ls", pwzData);
                }
            }
        }

        //
        // Schedule the work
        //
        if (!(iAttributes & NGEN_32BIT) && !(iAttributes & NGEN_64BIT))
            ExitOnFailure1(hr = E_INVALIDARG, "Neither 32bit nor 64bit is specified for NGEN of file: %ls", pwzFile);

        if (WcaIsInstalling(isInstalled, isAction) || WcaIsReInstalling(isInstalled, isAction))
        {
            if (iAttributes & NGEN_32BIT && f32NgenExeExists)
            {
                // Assemble the install command line
                hr = CreateInstallCommand(&pwzData, pwz32Ngen, pwzFile, iPriority, iAttributes, pwzFileApp, pwzDirAppBase);
                ExitOnFailure(hr, "failed to create install command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData);
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(iAssemblyCost, &pwzInstallCustomActionData);
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += iAssemblyCost;

                fNeedInstallUpdate32 = TRUE;
            }

            if (iAttributes & NGEN_64BIT && f64NgenExeExists)
            {
                // Assemble the install command line
                hr = CreateInstallCommand(&pwzData, pwz64Ngen, pwzFile, iPriority, iAttributes, pwzFileApp, pwzDirAppBase);
                ExitOnFailure(hr, "failed to create install command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(iAssemblyCost, &pwzInstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += iAssemblyCost;

                fNeedInstallUpdate64 = TRUE;
            }
        }
        else if (WcaIsUninstalling(isInstalled, isAction))
        {
            if (iAttributes & NGEN_32BIT && f32NgenExeExists)
            {
                hr = StrAllocFormatted(&pwzData, L"%s uninstall %s", pwz32Ngen, pwzFile);
                ExitOnFailure(hr, "failed to create update 32 command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += COST_NGEN_NONBLOCKING;

                fNeedUninstallUpdate32 = TRUE;
            }

            if (iAttributes & NGEN_64BIT && f64NgenExeExists)
            {
                hr = StrAllocFormatted(&pwzData, L"%s uninstall %s", pwz64Ngen, pwzFile);
                ExitOnFailure(hr, "failed to create update 64 command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += COST_NGEN_NONBLOCKING;

                fNeedUninstallUpdate64 = TRUE;
            }
        }
    }
    if (E_NOMOREITEMS == hr)
        hr = S_OK;
    ExitOnFailure(hr, "failed while looping through all files to create native images for");

    // If we need 32 bit install update
    if (fNeedInstallUpdate32)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz32Ngen);
        ExitOnFailure(hr, "failed to create install update 32 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to install custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzInstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to install custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 32 bit uninstall update
    if (fNeedUninstallUpdate32)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz32Ngen);
        ExitOnFailure(hr, "failed to create uninstall update 32 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to uninstall custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to uninstall custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 64 bit install update
    if (fNeedInstallUpdate64)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz64Ngen);
        ExitOnFailure(hr, "failed to create install update 64 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to install custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzInstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to install custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 64 bit install update
    if (fNeedUninstallUpdate64)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz64Ngen);
        ExitOnFailure(hr, "failed to create uninstall update 64 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to uninstall custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to uninstall custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // Add to progress bar
    if ((pwzInstallCustomActionData && *pwzInstallCustomActionData) || (pwzUninstallCustomActionData && *pwzUninstallCustomActionData))
    {
        hr = WcaProgressMessage(uiCost, TRUE);
        ExitOnFailure(hr, "failed to extend progress bar for NetFxExecuteNativeImage");
    }

    // Schedule the install custom action
    if (pwzInstallCustomActionData && *pwzInstallCustomActionData)
    {
        hr = WcaSetProperty(L"NetFxExecuteNativeImageInstall", pwzInstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageInstall action");

        hr = WcaSetProperty(L"NetFxExecuteNativeImageCommitInstall", pwzInstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageCommitInstall action");
    }

    // Schedule the uninstall custom action
    if (pwzUninstallCustomActionData && *pwzUninstallCustomActionData)
    {
        hr = WcaSetProperty(L"NetFxExecuteNativeImageUninstall", pwzUninstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageUninstall action");

        hr = WcaSetProperty(L"NetFxExecuteNativeImageCommitUninstall", pwzUninstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageCommitUninstall action");
    }


LExit:
    ReleaseStr(pwzInstallCustomActionData);
    ReleaseStr(pwzUninstallCustomActionData);
    ReleaseStr(pwzId);
    ReleaseStr(pwzData);
    ReleaseStr(pwzTemp);
    ReleaseStr(pwzFile);
    ReleaseStr(pwzFileApp);
    ReleaseStr(pwzDirAppBase);
    ReleaseStr(pwzComponent);
    ReleaseStr(pwz32Ngen);
    ReleaseStr(pwz64Ngen);

    if (FAILED(hr))
        er = ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Beispiel #13
0
/********************************************************************
 ConfigureEventManifestRegister - CUSTOM ACTION ENTRY POINT for scheduling
 Event manifest registering
 
********************************************************************/
extern "C" UINT __stdcall ConfigureEventManifestUnregister(
    __in MSIHANDLE hInstall
    )
{
    HRESULT hr;
    UINT er = ERROR_SUCCESS;

    PMSIHANDLE hView, hRec;
    LPWSTR pwzData = NULL, pwzFile = NULL, pwzCommand = NULL;
    INSTALLSTATE isInstalled, isAction;

    hr = WcaInitialize(hInstall, "ConfigureEventManifestUnreg");
    ExitOnFailure(hr, "Failed to initialize");
    
    if (!IsVistaOrAbove())
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ConfigureEventManifestUnregister() because the target system does not support event manifest");
        ExitFunction1(hr = S_FALSE);
    }
    // check to see if necessary tables are specified
    if (S_OK != WcaTableExists(L"EventManifest"))
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ConfigureEventManifestUnregister() because EventManifest table not present");
        ExitFunction1(hr = S_FALSE);
    }

    hr = WcaOpenExecuteView(vcsEventManifestQuery, &hView);
    ExitOnFailure(hr, "failed to open view on EventManifest table");
    while ((hr = WcaFetchRecord(hView, &hRec)) == S_OK)
    {
        // get component install state
        hr = WcaGetRecordString(hRec, emComponent, &pwzData);
        ExitOnFailure(hr, "failed to get Component for EventManifest");
        er = ::MsiGetComponentStateW(hInstall, pwzData, &isInstalled, &isAction);
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure(hr, "failed to get Component state for EventManifest");

        // nothing to do on an install
        // schedule the rollback action when reinstalling to re-register pre-patch manifest
        if (!WcaIsUninstalling(isInstalled, isAction) && !WcaIsReInstalling(isInstalled, isAction))
        {
            continue;
        }

        hr = WcaGetRecordFormattedString(hRec, emFile, &pwzFile);
        ExitOnFailure(hr, "failed to get File for EventManifest");

        hr = StrAllocFormatted(&pwzCommand, L"\"wevtutil.exe\" im \"%s\"", pwzFile);
        ExitOnFailure(hr, "failed to copy string in EventManifest");

        hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"RollbackUnregisterEventManifest"), pwzCommand, COST_PERFMONMANIFEST_REGISTER);
        ExitOnFailure(hr, "failed to schedule RollbackUnregisterEventManifest action");

        // no need to uninstall on a repair/patch.  Register action will re-register and update the manifest.
        if (!WcaIsReInstalling(isInstalled, isAction))
        {
            hr = StrAllocFormatted(&pwzCommand, L"\"wevtutil.exe\" um \"%s\"", pwzFile);
            ExitOnFailure(hr, "failed to copy string in EventManifest");
            WcaLog(LOGMSG_VERBOSE, "UnregisterEventManifest's CustomActionData: '%ls'", pwzCommand);
            
            hr = WcaDoDeferredAction(PLATFORM_DECORATION(L"UnregisterEventManifest"), pwzCommand, COST_PERFMONMANIFEST_UNREGISTER);
            ExitOnFailure(hr, "failed to schedule UnregisterEventManifest action");
        }
    }

    if (hr == E_NOMOREITEMS)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure while processing EventManifest");

    hr = S_OK;

LExit:
    ReleaseStr(pwzData);
    ReleaseStr(pwzFile);
    ReleaseStr(pwzCommand);

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