static HRESULT InstallCertificatePackage( __in HCERTSTORE hStore, __in BOOL fUserCertificateStore, __in LPCWSTR wzName, __in_opt BYTE* rgbData, __in DWORD cbData, __in_opt LPCWSTR wzPFXPassword ) { HRESULT hr = S_OK; HCERTSTORE hPfxCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; CERT_BLOB blob = { 0 }; DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; DWORD dwEncodingType; DWORD dwContentType; DWORD dwFormatType; LPWSTR pwzUniqueName = NULL; int iUniqueId = 0; // Figure out what type of blob (certificate or PFX) we're dealing with here. blob.pbData = rgbData; blob.cbData = cbData; if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) { ExitWithLastError1(hr, "Failed to parse the certificate blob: %ls", wzName); } hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); ExitOnFailure(hr, "Failed to format unique name"); if (!pCertContext) { // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. if (dwContentType & CERT_QUERY_CONTENT_PFX) { ExitOnNull(wzPFXPassword, hr, E_INVALIDARG, "Failed to import PFX blob because no password was provided"); // If we fail and our password is blank, also try passing in NULL for the password (according to the docs) hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset); if (NULL == hPfxCertStore && !*wzPFXPassword) { hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset); } ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file."); // Install all certificates in the PFX for (pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext); pCertContext; pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext)) { WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", pwzUniqueName); hr = CertInstallSingleCertificate(hStore, pCertContext, pwzUniqueName); MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); ExitOnFailure(hr, "Failed to format unique name"); } } else { hr = E_UNEXPECTED; ExitOnFailure(hr, "Unexpected certificate type processed."); } } else { WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", pwzUniqueName); hr = CertInstallSingleCertificate(hStore, pCertContext, pwzUniqueName); MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); } hr = WcaProgressMessage(COST_CERT_ADD, FALSE); ExitOnFailure(hr, "Failed to send install progress message."); LExit: ReleaseStr(pwzUniqueName); if (pCertContext) { ::CertFreeCertificateContext(pCertContext); } // Close the stores after the context's are released. if (hPfxCertStore) { if (!::CertCloseStore(hPfxCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) { WcaLog(LOGMSG_VERBOSE, "PFX cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); } } 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; }
/****************************************************************** 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); }
/******************************************************************** ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings ********************************************************************/ extern "C" UINT __stdcall ConfigureIIs7Exec( __in MSIHANDLE hInstall ) { //AssertSz(FALSE, "debug ConfigureIIs7Exec here"); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; LPWSTR pwzScriptKey = NULL; LPWSTR pwzCustomActionData = NULL; SCA_WEB7* pswList = NULL; SCA_WEBDIR7* pswdList = NULL; SCA_VDIR7* psvdList = NULL; SCA_FILTER* psfList = NULL; SCA_APPPOOL *psapList = NULL; SCA_MIMEMAP* psmmList = NULL; SCA_HTTP_HEADER* pshhList = NULL; SCA_PROPERTY *pspList = NULL; SCA_WEBSVCEXT* psWseList = NULL; SCA_WEB_ERROR* psweList = NULL; WCA_WRAPQUERY_HANDLE hUserQuery = NULL; WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; // initialize hr = WcaInitialize(hInstall, "ConfigureIIs7Exec"); ExitOnFailure(hr, "Failed to initialize"); hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); ExitOnFailure(hr, "failed to get CustomActionData"); // Get the CaScript key hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); // read the msi tables hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap user query"); hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web dir properties query"); hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web log query"); hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web application query"); hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web application extension query"); hr = ScaWebsRead7(&pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web base query"); hr = ScaWebDirsRead7(pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); hr = ScaVirtualDirsRead7(pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); hr = ScaFiltersRead7(pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); hr = ScaPropertyRead(&pspList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); // do uninstall actions (order is important!) hr = ScaPropertyUninstall7(pspList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); hr = ScaFiltersUninstall7(psfList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); hr = ScaVirtualDirsUninstall7(psvdList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); hr = ScaWebDirsUninstall7(pswdList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); hr = ScaWebsUninstall7(pswList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); hr = ScaAppPoolUninstall7(psapList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); // do install actions (order is important!) // ScaWebSvcExtCommit contains both uninstall and install actions. hr = ScaWebSvcExtCommit7(psWseList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); hr = ScaAppPoolInstall7(psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); hr = ScaWebsInstall7(pswList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); hr = ScaWebDirsInstall7(pswdList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); hr = ScaVirtualDirsInstall7(psvdList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); hr = ScaFiltersInstall7(psfList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); hr = ScaPropertyInstall7(pspList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); hr = ScaWriteConfigurationScript(pwzScriptKey); ExitOnFailure(hr, "failed to schedule metabase configuration"); LExit: ReleaseNullStr(pwzScriptKey); ReleaseNullStr(pwzCustomActionData); WcaFinishUnwrapQuery(hUserQuery); WcaFinishUnwrapQuery(hWebBaseQuery); WcaFinishUnwrapQuery(hWebDirPropQuery); WcaFinishUnwrapQuery(hSslCertQuery); WcaFinishUnwrapQuery(hWebLogQuery); WcaFinishUnwrapQuery(hWebAppQuery); WcaFinishUnwrapQuery(hWebAppExtQuery); if (psWseList) { ScaWebSvcExtFreeList(psWseList); } if (psfList) { ScaFiltersFreeList(psfList); } if (psvdList) { ScaVirtualDirsFreeList7(psvdList); } if (pswdList) { ScaWebDirsFreeList7(pswdList); } if (pswList) { ScaWebsFreeList7(pswList); } if (psmmList) { ScaMimeMapFreeList(psmmList); } if (pshhList) { ScaHttpHeaderCheckList(pshhList); ScaHttpHeaderFreeList(pshhList); } if (psweList) { ScaWebErrorCheckList(psweList); ScaWebErrorFreeList(psweList); } er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }
/******************************************************************** ConfigureIIsExec - custom action for installing IIs settings - table data will be wrapped and passed in from immediate CA ReadIIsTables ********************************************************************/ extern "C" UINT __stdcall ConfigureIIsExec( __in MSIHANDLE hInstall ) { //AssertSz(FALSE, "debug ConfigureIIsExec here"); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; BOOL fInitializedCom = FALSE; IMSAdminBase* piMetabase = NULL; SCA_WEB* pswList = NULL; SCA_WEBDIR* pswdList = NULL; SCA_VDIR* psvdList = NULL; SCA_FILTER* psfList = NULL; SCA_APPPOOL *psapList = NULL; SCA_MIMEMAP* psmmList = NULL; SCA_HTTP_HEADER* pshhList = NULL; SCA_PROPERTY *pspList = NULL; SCA_WEBSVCEXT* psWseList = NULL; SCA_WEB_ERROR* psweList = NULL; LPWSTR pwzScriptKey = NULL; LPWSTR pwzCustomActionData = NULL; WCA_WRAPQUERY_HANDLE hUserQuery = NULL; WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; // initialize hr = WcaInitialize(hInstall, "ConfigureIIsExec"); ExitOnFailure(hr, "Failed to initialize"); hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); ExitOnFailure(hr, "failed to get CustomActionData"); // Get the CaScript key hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); hr = ::CoInitialize(NULL); ExitOnFailure(hr, "failed to initialize COM"); fInitializedCom = TRUE; // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the // user to still uninstall this package by clicking "Ignore" do { hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)&piMetabase); if (FAILED(hr)) { WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback case IDRETRY: hr = S_FALSE; // hit me, baby, one more time break; case IDIGNORE: __fallthrough; default: WcaLog(LOGMSG_STANDARD, "ignoring absent IIS"); // We need to write the empty script to communicate to other deferred CA that there is noting to do. hr = ScaWriteConfigurationScript(pwzScriptKey); ExitOnFailure(hr, "failed to schedule metabase configuration"); ExitFunction1(hr = S_OK); // pretend everything is okay break; } } } while (S_FALSE == hr); // read the msi tables hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap user query"); hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web dir properties query"); hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web log query"); hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web application query"); hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web application extension query"); hr = ScaWebsRead(piMetabase, &psmmList, &pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap web base query"); hr = ScaWebDirsRead(piMetabase, pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); hr = ScaFiltersRead(piMetabase, pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); hr = ScaPropertyRead(&pspList, &pwzCustomActionData); MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); // do uninstall actions (order is important!) hr = ScaPropertyUninstall(piMetabase, pspList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); hr = ScaFiltersUninstall(piMetabase, psfList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); hr = ScaVirtualDirsUninstall(piMetabase, psvdList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); hr = ScaWebDirsUninstall(piMetabase, pswdList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); hr = ScaWebsUninstall(piMetabase, pswList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); hr = ScaAppPoolUninstall(piMetabase, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); // do install actions (order is important!) // ScaWebSvcExtCommit contains both uninstall and install actions. hr = ScaWebSvcExtCommit(piMetabase, psWseList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); hr = ScaAppPoolInstall(piMetabase, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); hr = ScaWebsInstall(piMetabase, pswList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); hr = ScaWebDirsInstall(piMetabase, pswdList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); hr = ScaVirtualDirsInstall(piMetabase, psvdList, psapList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); hr = ScaFiltersInstall(piMetabase, psfList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); hr = ScaPropertyInstall(piMetabase, pspList); MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); hr = ScaWriteConfigurationScript(pwzScriptKey); ExitOnFailure(hr, "failed to schedule metabase configuration"); LExit: ReleaseStr(pwzScriptKey); ReleaseStr(pwzCustomActionData); WcaFinishUnwrapQuery(hUserQuery); WcaFinishUnwrapQuery(hWebBaseQuery); WcaFinishUnwrapQuery(hWebDirPropQuery); WcaFinishUnwrapQuery(hSslCertQuery); WcaFinishUnwrapQuery(hWebLogQuery); WcaFinishUnwrapQuery(hWebAppQuery); WcaFinishUnwrapQuery(hWebAppExtQuery); if (psWseList) { ScaWebSvcExtFreeList(psWseList); } if (psfList) { ScaFiltersFreeList(psfList); } if (psvdList) { ScaVirtualDirsFreeList(psvdList); } if (pswdList) { ScaWebDirsFreeList(pswdList); } if (pswList) { ScaWebsFreeList(pswList); } if (psmmList) { ScaMimeMapCheckList(psmmList); ScaMimeMapFreeList(psmmList); } if (pshhList) { ScaHttpHeaderCheckList(pshhList); ScaHttpHeaderFreeList(pshhList); } if (psweList) { ScaWebErrorCheckList(psweList); ScaWebErrorFreeList(psweList); } ReleaseObject(piMetabase); if (fInitializedCom) { ::CoUninitialize(); } er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }
/******************************************************************** ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings ********************************************************************/ extern "C" UINT __stdcall ConfigureIIs( __in MSIHANDLE hInstall ) { //AssertSz(FALSE, "debug ConfigureIIs here"); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; LPWSTR pwzScriptKey = NULL; LPWSTR pwzBackupId = NULL; LPWSTR pwzCustomActionData = NULL; // CustomActionData for ConfigureIIs custom action // initialize hr = WcaInitialize(hInstall, "ConfigureIIs"); ExitOnFailure(hr, "Failed to initialize"); // check for the prerequsite tables if (S_OK != WcaTableExists(L"IIsWebSite") && S_OK != WcaTableExists(L"IIsFilter") && S_OK != WcaTableExists(L"IIsProperty") && S_OK != WcaTableExists(L"IIsWebServiceExtension") && S_OK != WcaTableExists(L"IIsAppPool")) { WcaLog(LOGMSG_VERBOSE, "skipping IIs CustomAction, no IIsWebSite table, no IIsFilter table, no IIsProperty table, no IIsWebServiceExtension, and no IIsAppPool table"); ExitFunction1(hr = S_FALSE); } // Get a CaScript key hr = WcaCaScriptCreateKey(&pwzScriptKey); ExitOnFailure(hr, "Failed to get encoding key."); // Generate a unique string to be used for this product's transaction // This prevents a name collision when doing a major upgrade hr = WcaGetProperty(L"ProductCode", &pwzBackupId); ExitOnFailure(hr, "failed to get ProductCode"); hr = StrAllocConcat(&pwzBackupId, L"ScaConfigureIIs", 0); ExitOnFailure(hr, "failed to concat ScaConfigureIIs"); // make sure the operations below are wrapped in a "transaction" // use IIS7 transaction logic even if using Iis6 compat because Backup/Restore don't work with metabase compatibility if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, IIS7CONDITION)) { hr = ScaIIS7ConfigTransaction(pwzBackupId); MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS7 transaction"); } else { hr = ScaMetabaseTransaction(pwzBackupId); MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS transaction"); } // Write the CaScript key to the ConfigureIIS custom action data hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); ExitOnFailure(hr, "Failed to add encoding key to CustomActionData."); // Wrap vcsUserDeferredQuery to send to deferred CA if (S_OK == WcaTableExists(L"User")) { hr = WcaWrapQuery(vcsUserDeferredQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap User query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap User empty query"); } // Wrap vcsWebSvcExtQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebServiceExtension")) { hr = WcaWrapQuery(vcsWebSvcExtQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4, 1, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension empty query"); } // Wrap vcsAppPoolQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsAppPool")) { hr = WcaWrapQuery(vcsAppPoolQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn15 | efmcColumn16, 3, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsAppPool query"); hr = WcaWrapQuery(vcsComponentAttrQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap Component query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsAppPool empty query"); } // Wrap vcsMimeMapQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsMimeMap")) { hr = WcaWrapQuery(vcsMimeMapQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsMimeMap query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsMimeMap empty query"); } // Wrap vcsHttpHeaderQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsHttpHeader")) { hr = WcaWrapQuery(vcsHttpHeaderQuery, &pwzCustomActionData, efmcColumn1 | efmcColumn4, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsHttpHeader query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsHttpHeader empty query"); } // Wrap vcsWebErrorQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebError")) { hr = WcaWrapQuery(vcsWebErrorQuery, &pwzCustomActionData, efmcColumn5 | efmcColumn6, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebError query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebError empty query"); } // Wrap vcsWebDirPropertiesQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebDirProperties")) { hr = WcaWrapQuery(vcsWebDirPropertiesQuery, &pwzCustomActionData, efmcColumn8 | efmcColumn10 | efmcColumn12 | efmcColumn15, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties empty query"); } // Wrap vcsSslCertificateQuery to send to deferred CA if (S_OK == WcaTableExists(L"Certificate") && S_OK == WcaTableExists(L"CertificateHash") && S_OK == WcaTableExists(L"IIsWebSiteCertificates")) { hr = WcaWrapQuery(vcsSslCertificateQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap SslCertificate query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap SslCertificate empty query"); } // Wrap vcsWebLogQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebLog")) { hr = WcaWrapQuery(vcsWebLogQuery, &pwzCustomActionData, efmcColumn2, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebLog query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebLog empty query"); } // Wrap vcsWebApplicationQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebApplication")) { hr = WcaWrapQuery(vcsWebApplicationQuery, &pwzCustomActionData, efmcColumn1, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebApplication query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebApplication empty query"); } // Wrap vcsWebAppExtensionQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebApplicationExtension")) { hr = WcaWrapQuery(vcsWebAppExtensionQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension empty query"); } // Wrap vcsWebQuery, vcsWebAddressQuery, and vcsWebBaseQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebAddress") && S_OK == WcaTableExists(L"IIsWebSite")) { hr = WcaWrapQuery(vcsWebQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn12 | efmcColumn13 | efmcColumn14, 2, 6); ExitOnFailure(hr, "Failed to wrap IIsWebSite query"); hr = WcaWrapQuery(vcsWebAddressQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebAddress query"); hr = WcaWrapQuery(vcsWebBaseQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4 | efmcColumn5 | efmcColumn7, 0xFFFFFFFF, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebBase query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebSite empty query"); hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebAddress empty query"); hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebBase empty query"); } // Wrap vcsWebDirQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebDir")) { hr = WcaWrapQuery(vcsWebDirQuery, &pwzCustomActionData, efmcColumn4, 3, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsWebDir query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebDir empty query"); } // Wrap vcsVDirQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsWebVirtualDir")) { hr = WcaWrapQuery(vcsVDirQuery, &pwzCustomActionData, efmcColumn4, 3, 5); ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir empty query"); } // Wrap vcsFilterQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsFilter")) { hr = WcaWrapQuery(vcsFilterQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 3, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsFilter query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsFilter empty query"); } // Wrap vcsPropertyQuery to send to deferred CA if (S_OK == WcaTableExists(L"IIsProperty")) { hr = WcaWrapQuery(vcsPropertyQuery, &pwzCustomActionData, efmcColumn4, 2, 0xFFFFFFFF); ExitOnFailure(hr, "Failed to wrap IIsProperty query"); } else { hr = WcaWrapEmptyQuery(&pwzCustomActionData); ExitOnFailure(hr, "Failed to wrap IIsProperty empty query"); } if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, USEIIS7CONDITION)) { // This must remain trace only, CA data may contain password WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIIS7Exec will be: %ls", pwzCustomActionData); hr = WcaDoDeferredAction(L"ConfigureIIs7Exec", pwzCustomActionData, ConfigureIIsCost); ExitOnFailure(hr, "Failed to schedule ConfigureIIs7Exec custom action"); ReleaseNullStr(pwzCustomActionData); // Write the CaScript key to the ConfigureIIS custom action data hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); ExitOnFailure(hr, "Failed to add script key to CustomActionData."); hr = WcaDoDeferredAction(L"WriteIIS7ConfigChanges", pwzCustomActionData, WriteIIS7ConfigChangesCost); ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); } else { // This must remain trace only, CA data may contain password WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIISExec will be: %ls", pwzCustomActionData); hr = WcaDoDeferredAction(L"ConfigureIIsExec", pwzCustomActionData, ConfigureIIsCost); ExitOnFailure(hr, "Failed to schedule ConfigureIISExec custom action"); ReleaseNullStr(pwzCustomActionData); // Write the CaScript key to the ConfigureIIS custom action data hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); ExitOnFailure(hr, "Failed to add script key to CustomActionData."); hr = WcaDoDeferredAction(L"WriteMetabaseChanges", pwzCustomActionData, WriteMetabaseChangesCost); ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); } LExit: ReleaseStr(pwzScriptKey); ReleaseStr(pwzBackupId); ReleaseStr(pwzCustomActionData); er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }
/******************************************************************** ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components ********************************************************************/ extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; BOOL fInitializedCom = FALSE; ICOMAdminCatalog* piCatalog = NULL; CPI_PARTITION_LIST partList; CPI_PARTITION_ROLE_LIST partRoleList; CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList; CPI_PARTITION_USER_LIST partUsrList; CPI_APPLICATION_LIST appList; CPI_APPLICATION_ROLE_LIST appRoleList; CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList; CPI_ASSEMBLY_LIST asmList; CPI_SUBSCRIPTION_LIST subList; LPWSTR pwzRollbackFileName = NULL; LPWSTR pwzActionData = NULL; LPWSTR pwzRollbackActionData = NULL; LPWSTR pwzCommitActionData = NULL; int iVersionNT = 0; int iProgress = 0; int iCommitProgress = 0; ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST)); ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST)); ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST)); ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST)); ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST)); ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST)); ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST)); ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST)); ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST)); // initialize hr = WcaInitialize(hInstall, "ConfigureComPlusInstall"); ExitOnFailure(hr, "Failed to initialize"); hr = ::CoInitialize(NULL); ExitOnFailure(hr, "Failed to initialize COM"); fInitializedCom = TRUE; CpiInitialize(); // check for the prerequsite tables if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly)) { WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present"); ExitFunction1(hr = S_FALSE); } // make sure we can access the COM+ admin catalog do { hr = CpiGetAdminCatalog(&piCatalog); if (FAILED(hr)) { WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog"); er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback case IDRETRY: hr = S_FALSE; break; case IDIGNORE: default: ExitFunction1(hr = S_OK); // pretend everything is okay and bail } } } while (S_FALSE == hr); // get NT version hr = WcaGetIntProperty(L"VersionNT", &iVersionNT); ExitOnFailure(hr, "Failed to get VersionNT property"); // read elements if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition)) { hr = CpiPartitionsRead(&partList); MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole)) { hr = CpiPartitionRolesRead(&partList, &partRoleList); MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table"); } if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole))) { hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList); MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table"); } if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser)) { hr = CpiPartitionUsersRead(&partList, &partUsrList); MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table"); } if (CpiTableExists(cptComPlusApplication)) { hr = CpiApplicationsRead(&partList, &appList); MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table"); } if (CpiTableExists(cptComPlusApplicationRole)) { hr = CpiApplicationRolesRead(&appList, &appRoleList); MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table"); } if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole)) { hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList); MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table"); } if (CpiTableExists(cptComPlusAssembly)) { hr = CpiAssembliesRead(&appList, &appRoleList, &asmList); MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table"); } if (CpiTableExists(cptComPlusSubscription)) { hr = CpiSubscriptionsRead(&asmList, &subList); MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table"); } // verify elements hr = CpiPartitionsVerifyInstall(&partList); ExitOnFailure(hr, "Failed to verify partitions"); hr = CpiApplicationsVerifyInstall(&appList); ExitOnFailure(hr, "Failed to verify applications"); hr = CpiApplicationRolesVerifyInstall(&appRoleList); ExitOnFailure(hr, "Failed to verify application roles"); hr = CpiAssembliesVerifyInstall(&asmList); ExitOnFailure(hr, "Failed to verify assemblies"); if (subList.iInstallCount) { hr = CpiSubscriptionsVerifyInstall(&subList); ExitOnFailure(hr, "Failed to verify subscriptions"); } // schedule if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount || appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount) { // create rollback file name hr = CpiGetTempFileName(&pwzRollbackFileName); ExitOnFailure(hr, "Failed to get rollback file name"); // schedule rollback prepare custom action hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare"); // schedule prepare custom action hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare"); // schedule rollback custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData); ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data"); hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install subscriptions"); hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install users in application roles"); hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install application roles"); hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install applications"); hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install partition users"); hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install users in partition roles"); hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL); ExitOnFailure(hr, "Failed to install partitions"); hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0); ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute"); // schedule install custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData); ExitOnFailure(hr, "Failed to add rollback file name to custom action data"); hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install partitions"); hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install users in partition roles"); hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install partition users"); hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install applications"); hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install application roles"); hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install users in application roles"); hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress); ExitOnFailure(hr, "Failed to install subscriptions"); hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress); ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute"); // schedule install commit custom action hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData); ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data"); hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install assemblies"); hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress); ExitOnFailure(hr, "Failed to install subscriptions"); hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress); ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit"); // schedule commit custom action hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0); ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit"); } hr = S_OK; LExit: // clean up ReleaseObject(piCatalog); ReleaseStr(pwzRollbackFileName); ReleaseStr(pwzActionData); ReleaseStr(pwzRollbackActionData); ReleaseStr(pwzCommitActionData); CpiPartitionListFree(&partList); CpiPartitionRoleListFree(&partRoleList); CpiUserInPartitionRoleListFree(&usrInPartRoleList); CpiPartitionUserListFree(&partUsrList); CpiApplicationListFree(&appList); CpiApplicationRoleListFree(&appRoleList); CpiUserInApplicationRoleListFree(&usrInAppRoleList); CpiAssemblyListFree(&asmList); CpiSubscriptionListFree(&subList); // unitialize CpiFinalize(); if (fInitializedCom) ::CoUninitialize(); er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); }