Example #1
0
static HRESULT CreatePartition(
    CPI_PARTITION_ATTRIBUTES* pAttrs
    )
{
    HRESULT hr = S_OK;

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

    long lChanges = 0;

    // log
    WcaLog(LOGMSG_VERBOSE, "Creating partition, key: %S", pAttrs->pwzKey);

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

    // check if partition exists
    hr = CpiFindCollectionObjectByStringKey(piPartColl, pAttrs->pwzID, &piPartObj);
    ExitOnFailure(hr, "Failed to find partition");

    if (S_FALSE == hr)
    {
        // create partition
        hr = CpiAddCollectionObject(piPartColl, &piPartObj);
        ExitOnFailure(hr, "Failed to add partition to collection");

        hr = CpiPutCollectionObjectValue(piPartObj, L"ID", pAttrs->pwzID);
        ExitOnFailure(hr, "Failed to set partition id property");

        hr = CpiPutCollectionObjectValue(piPartObj, L"Name", pAttrs->pwzName);
        ExitOnFailure(hr, "Failed to set partition name property");
    }

    // properties
    hr = CpiPutCollectionObjectValues(piPartObj, pAttrs->pPropList);
    ExitOnFailure(hr, "Failed to write properties");

    // save changes
    hr = piPartColl->SaveChanges(&lChanges);
    if (COMADMIN_E_OBJECTERRORS == hr)
        CpiLogCatalogErrorInfo();
    ExitOnFailure(hr, "Failed to save changes");

    // log
    WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);

    hr = S_OK;

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

    return hr;
}
Example #2
0
HRESULT CpiPartitionsVerifyUninstall(
    CPI_PARTITION_LIST* pList
    )
{
    HRESULT hr = S_OK;
    ICatalogCollection* piPartColl = NULL;
    ICatalogObject* piPartObj = NULL;

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

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

        // 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
        {
            pItm->fObjectNotFound = TRUE;
            if (pItm->fHasComponent)
                pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
        }

        // clean up
        ReleaseNullObject(piPartObj);
    }

    hr = S_OK;

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

    return hr;
}
Example #3
0
HRESULT CpiGetApplicationsCollForPartition(
    CPI_PARTITION* pPart,
    ICatalogCollection** ppiAppColl
    )
{
    HRESULT hr = S_OK;

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

    // if a previous attempt to locate the collection object failed
    if (pPart->fObjectNotFound)
        ExitFunction1(hr = S_FALSE);

    // get applications collection
    if (!pPart->piApplicationsColl)
    {
        // get partitions collection from catalog
        hr = CpiGetPartitionsCollection(&piPartColl);
        ExitOnFailure(hr, "Failed to get partitions collection");

        // find application object
        hr = CpiFindCollectionObject(piPartColl, pPart->wzID, *pPart->wzID ? NULL : pPart->wzName, &piPartObj);
        ExitOnFailure(hr, "Failed to find partition object");

        if (S_FALSE == hr)
        {
            pPart->fObjectNotFound = TRUE;
            ExitFunction(); // exit with hr = S_FALSE
        }

        // get roles collection
        hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", &pPart->piApplicationsColl);
        ExitOnFailure(hr, "Failed to get applications collection");
    }

    // return value
    *ppiAppColl = pPart->piApplicationsColl;
    (*ppiAppColl)->AddRef();

    hr = S_OK;

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

    return hr;
}
Example #4
0
static HRESULT RemovePartition(
    CPI_PARTITION_ATTRIBUTES* pAttrs
    )
{
    HRESULT hr = S_OK;

    ICatalogCollection* piPartColl = NULL;

    long lChanges = 0;

    // log
    WcaLog(LOGMSG_VERBOSE, "Removing partition, key: %S", pAttrs->pwzKey);

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

    // remove
    hr = CpiRemoveCollectionObject(piPartColl, pAttrs->pwzID, NULL, TRUE);
    ExitOnFailure(hr, "Failed to remove partition");

    if (S_FALSE == hr)
    {
        // partition not found
        WcaLog(LOGMSG_VERBOSE, "Partition not found, nothing to delete, key: %S", pAttrs->pwzKey);
        ExitFunction1(hr = S_OK);
    }

    // save changes
    hr = piPartColl->SaveChanges(&lChanges);
    if (COMADMIN_E_OBJECTERRORS == hr)
        CpiLogCatalogErrorInfo();
    ExitOnFailure(hr, "Failed to save changes");

    // log
    WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);

    hr = S_OK;

LExit:
    // clean up
    ReleaseObject(piPartColl);

    return hr;
}
Example #5
0
HRESULT CpiGetPartitionRolesCollection(
	LPCWSTR pwzPartID,
	ICatalogCollection** ppiRolesColl
	)
{
	HRESULT hr = S_OK;

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

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

	if (S_FALSE == hr)
		ExitFunction(); // partitions collection not found, exit with hr = S_FALSE

	// find object
	hr = CpiFindCollectionObjectByStringKey(piPartColl, pwzPartID, &piPartObj);
	ExitOnFailure(hr, "Failed to find collection object");

	if (S_FALSE == hr)
		ExitFunction(); // partition not found, exit with hr = S_FALSE

	// get roles collection
	hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"RolesForPartition", ppiRolesColl);
	ExitOnFailure(hr, "Failed to get catalog collection");

	hr = S_OK;

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

	return hr;
}
Example #6
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;
}
Example #7
0
HRESULT CpiGetApplicationsCollection(
    ICatalogCollection** ppiAppColl
    )
{
    HRESULT hr = S_OK;

    ICOMAdminCatalog* piCatalog = NULL;
    ICOMAdminCatalog2* piCatalog2 = NULL;
    ICatalogCollection* piPartColl = NULL;
    ICatalogObject* piPartObj = NULL;
    BSTR bstrGlobPartID = NULL;

    if (!gpiAppColl)
    {
        // get catalog
        hr = CpiGetAdminCatalog(&piCatalog);
        ExitOnFailure(hr, "Failed to get COM+ admin catalog");

        // get ICOMAdminCatalog2 interface
        hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);

        // COM+ 1.5 or later
        if (E_NOINTERFACE != hr)
        {
            ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");

            // get global partition id
            hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
            ExitOnFailure(hr, "Failed to get global partition id");

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

            // find object
            hr = CpiFindCollectionObject(piPartColl, bstrGlobPartID, NULL, &piPartObj);
            ExitOnFailure(hr, "Failed to find collection object");

            if (S_FALSE == hr)
                ExitFunction(); // partition not found, exit with hr = S_FALSE

            // get applications collection
            hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", &gpiAppColl);
            ExitOnFailure(hr, "Failed to get applications collection");
        }

        // COM+ pre 1.5
        else
        {
            // get applications collection
            hr = CpiGetCatalogCollection(L"Applications", &gpiAppColl);
            ExitOnFailure(hr, "Failed to get applications collection");
        }
    }

    // return value
    gpiAppColl->AddRef();
    *ppiAppColl = gpiAppColl;

    hr = S_OK;

LExit:
    // clean up
    ReleaseObject(piCatalog);
    ReleaseObject(piCatalog2);
    ReleaseObject(piPartColl);
    ReleaseObject(piPartObj);
    ReleaseBSTR(bstrGlobPartID);

    return hr;
}
Example #8
0
HRESULT CpiGetApplicationsCollection(
	LPCWSTR pwzPartID,
	ICatalogCollection** ppiAppColl
	)
{
	HRESULT hr = S_OK;

	ICOMAdminCatalog* piCatalog = NULL;
	ICOMAdminCatalog2* piCatalog2 = NULL;
	BSTR bstrGlobPartID = NULL;

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

	// get catalog
	hr = CpiGetAdminCatalog(&piCatalog);
	ExitOnFailure(hr, "Failed to get COM+ admin catalog");

	// get ICOMAdminCatalog2 interface
	hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);

	// COM+ 1.5 or later
	if (E_NOINTERFACE != hr)
	{
		ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");

		// partition id
		if (!pwzPartID || !*pwzPartID)
		{
			// get global partition id
			hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
			ExitOnFailure(hr, "Failed to get global partition id");
		}

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

		// find object
		hr = CpiFindCollectionObjectByStringKey(piPartColl, bstrGlobPartID ? bstrGlobPartID : pwzPartID, &piPartObj);
		ExitOnFailure(hr, "Failed to find collection object");

		if (S_FALSE == hr)
			ExitFunction(); // partition not found, exit with hr = S_FALSE

		// get applications collection
		hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", ppiAppColl);
		ExitOnFailure(hr, "Failed to get catalog collection for partition");
	}

	// COM+ pre 1.5
	else
	{
		// this version of COM+ does not support partitions, make sure a partition was not specified
		if (pwzPartID && *pwzPartID)
			ExitOnFailure(hr = E_FAIL, "Partitions are not supported by this version of COM+");

		// get applications collection
		hr = CpiGetCatalogCollection(L"Applications", ppiAppColl);
		ExitOnFailure(hr, "Failed to get catalog collection");
	}

	hr = S_OK;

LExit:
	// clean up
	ReleaseObject(piCatalog);
	ReleaseObject(piCatalog2);
	ReleaseBSTR(bstrGlobPartID);

	ReleaseObject(piPartColl);
	ReleaseObject(piPartObj);

	return hr;
}