Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
HRESULT CpiSubscriptionsVerifyInstall(
    CPI_SUBSCRIPTION_LIST* pList
    )
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    ICatalogObject* piSubsObj = NULL;

    for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
    {
        // subscriptions that are being installed
        if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
            continue;

        // subscription is supposed to exist
        if (CpiIsInstalled(pItm->isInstalled))
        {
            // if we don't have an id
            if (!*pItm->wzID)
            {
                // find subscriptions with conflicting name
                hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
                ExitOnFailure(hr, "Failed to find collection object for subscription");

                // if the subscription was found
                if (S_OK == hr)
                {
                    // get id from subscription object
                    hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
                    ExitOnFailure(hr, "Failed to get id");
                }

                // if the subscription was not found
                else
                {
                    // create a new id
                    hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
                    ExitOnFailure(hr, "Failed to create id");
                }
            }
        }

        // subscription is supposed to be created
        else
        {
            // check for conflicts
            do {
                if (*pItm->wzID)
                {
                    // find subscriptions with conflicting id
                    hr = FindObjectForSubscription(pItm, TRUE, FALSE, &piSubsObj);
                    ExitOnFailure(hr, "Failed to find collection object for subscription");

                    if (S_FALSE == hr)
                    {
                        // find subscriptions with conflicting name
                        hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
                        ExitOnFailure(hr, "Failed to find collection object for subscription");

                        if (S_OK == hr)
                            // "A subscription with a conflictiong name exists. retry cancel"
                            er = WcaErrorMessage(msierrComPlusSubscriptionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
                        else
                            break; // no conflicting entry found, break loop
                    }
                    else
                        // "A subscription with a conflicting id exists. abort retry ignore"
                        er = WcaErrorMessage(msierrComPlusSubscriptionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
                }
                else
                {
                    // find subscriptions with conflicting name
                    hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
                    ExitOnFailure(hr, "Failed to find collection object for subscription");

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

                switch (er)
                {
                case IDCANCEL:
                case IDABORT:
                    ExitOnFailure1(hr = E_FAIL, "A subscription 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(piSubsObj, 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(piSubsObj);
    }

    hr = S_OK;

LExit:
    // clean up
    ReleaseObject(piSubsObj);

    return hr;
}