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