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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }