HRESULT ScaWebsRead( __in IMSAdminBase* piMetabase, __in SCA_MIMEMAP** ppsmmList, __in SCA_WEB** ppswList, __in SCA_HTTP_HEADER** ppshhList, __in SCA_WEB_ERROR** ppsweList, __in WCA_WRAPQUERY_HANDLE hUserQuery, __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, __in WCA_WRAPQUERY_HANDLE hSslCertQuery, __in WCA_WRAPQUERY_HANDLE hWebLogQuery, __in WCA_WRAPQUERY_HANDLE hWebAppQuery, __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, __inout LPWSTR *ppwzCustomActionData ) { Assert(piMetabase && ppswList); HRESULT hr = S_OK; MSIHANDLE hRec; MSIHANDLE hRecAddresses; SCA_WEB* psw = NULL; LPWSTR pwzData = NULL; int iSiteId; DWORD dwLen = 0; WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); if (0 == WcaGetQueryRecords(hQueryWebSite)) { WcaLog(LOGMSG_VERBOSE, "Required tables not present"); ExitFunction1(hr = S_FALSE); } // loop through all the webs while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) { psw = NewWeb(); ExitOnNull(psw, hr, E_OUTOFMEMORY, "Failed to allocate memory for web object in memory"); // get the darwin information hr = WcaGetRecordString(hRec, wqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web"); hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); ExitOnFailure(hr, "Failed to copy key string to web object"); if (*pwzData && *ppsmmList) { hr = ScaGetMimeMap(mmptWeb, pwzData, ppsmmList, &psw->psmm); ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); } // get component install state hr = WcaGetRecordString(hRec, wqComponent, &pwzData); ExitOnFailure(hr, "Failed to get Component for Web"); hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); ExitOnFailure(hr, "Failed to copy component string to web object"); if (*(psw->wzComponent)) { psw->fHasComponent = TRUE; hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); ExitOnFailure(hr, "Failed to get web Component's installed state"); WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); ExitOnFailure(hr, "Failed to get web Component's action state"); if (!WcaIsInstalling(psw->isInstalled, psw->isAction) && !WcaIsUninstalling(psw->isInstalled, psw->isAction) && !WcaIsReInstalling(psw->isInstalled, psw->isAction)) { FreeWeb(psw); psw = NULL; continue; // If we aren't acting on this component, skip it } } hr = WcaGetRecordInteger(hRec, wqId, &iSiteId); ExitOnFailure(hr, "Failed to get SiteId for Web"); // Get the web's key address. hr = WcaGetRecordString(hRec, wqAddress, &pwzData); ExitOnFailure(hr, "Failed to get Address for Web"); hr = ::StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData); ExitOnFailure(hr, "Failed to copy key string to web object"); hr = WcaGetRecordString(hRec, wqIP, &pwzData); ExitOnFailure(hr, "Failed to get IP for Web"); hr = ::StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData); ExitOnFailure(hr, "Failed to copy IP string to web object"); hr = WcaGetRecordString(hRec, wqPort, &pwzData); ExitOnFailure(hr, "Failed to get Web Address port"); psw->swaKey.iPort = wcstol(pwzData, NULL, 10); hr = WcaGetRecordString(hRec, wqHeader, &pwzData); ExitOnFailure(hr, "Failed to get Header for Web"); hr = ::StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData); ExitOnFailure(hr, "Failed to copy header string to web object"); hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure); ExitOnFailure(hr, "Failed to get if Web is secure"); if (S_FALSE == hr) { psw->swaKey.fSecure = FALSE; } // Get the web's description. hr = WcaGetRecordString(hRec, wqDescription, &pwzData); ExitOnFailure(hr, "Failed to get Description for Web"); hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); ExitOnFailure(hr, "Failed to copy description string to web object"); // Try to find the web root in case it already exists. dwLen = METADATA_MAX_NAME_LEN; hr = ScaWebFindBase(piMetabase, *ppswList, psw->wzKey, iSiteId, psw->swaKey.wzIP, psw->swaKey.iPort, psw->swaKey.wzHeader, psw->swaKey.fSecure, psw->wzDescription, psw->wzWebBase, dwLen); if (S_OK == hr) { psw->fBaseExists = TRUE; } else if (S_FALSE == hr) // didn't find the web site. { psw->fBaseExists = FALSE; // If we're actually configuring the web site. if (psw->fHasComponent) { if (WcaIsInstalling(psw->isInstalled, psw->isAction)) { hr = ScaWebFindFreeBase(piMetabase, *ppswList, iSiteId, psw->wzDescription, psw->wzWebBase, countof(psw->wzWebBase)); ExitOnFailure(hr, "Failed to find free web root."); } else if (WcaIsUninstalling(psw->isInstalled, psw->isAction)) { WcaLog(LOGMSG_VERBOSE, "Web site: '%ls' was already removed, skipping.", psw->wzKey); hr = S_OK; continue; } } } ExitOnFailure(hr, "Failed to find web root"); // get any extra web addresses WcaFetchWrappedReset(hQueryWebAddress); while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) { if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) { hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); } hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); ExitOnFailure(hr, "Failed to get extra web Address"); // if this isn't the key address add it if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey)) { hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); ExitOnFailure(hr, "Failed to copy extra addresses key string to web object"); hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); ExitOnFailure(hr, "Failed to get extra web IP"); hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); ExitOnFailure(hr, "Failed to copy extra addresses IP string to web object"); hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); ExitOnFailure(hr, "Failed to get port for extra web IP"); psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); ExitOnFailure(hr, "Failed to get header for extra web IP"); hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); ExitOnFailure(hr, "Failed to copy extra addresses header string to web object"); hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); ExitOnFailure(hr, "Failed to get if secure extra web IP"); if (S_FALSE == hr) psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; ++psw->cExtraAddresses; } } if (E_NOMOREITEMS == hr) hr = S_OK; ExitOnFailure(hr, "Failure occured while getting extra web addresses"); hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); ExitOnFailure(hr, "Failed to get connection timeout for Web"); if (psw->fHasComponent) // If we're installing it, it needs a dir { // get the web's directory if (INSTALLSTATE_SOURCE == psw->isAction) { hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); } else { hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); } ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); // remove trailing backslashes while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') { pwzData[lstrlenW(pwzData)-1] = 0; } hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); ExitOnFailure(hr, "Failed to copy directory string to web object"); } hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); ExitOnFailure(hr, "Failed to get state for Web"); hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); ExitOnFailure(hr, "Failed to get attributes for Web"); // get the dir properties for this web hr = WcaGetRecordString(hRec, wqProperties, &pwzData); ExitOnFailure(hr, "Failed to get directory property record for Web"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); ExitOnFailure(hr, "Failed to get directory properties for Web"); psw->fHasProperties = TRUE; } // get the application information for this web hr = WcaGetRecordString(hRec, wqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for Web"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); ExitOnFailure(hr, "Failed to get application for Web"); psw->fHasApplication = TRUE; } // get the SSL certificates hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); ExitOnFailure(hr, "Failed to get SSL Certificates."); // get the custom headers if (*ppshhList) { hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); } // get the errors if (*ppsweList) { hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); ExitOnFailure(hr, "Failed to get Custom Errors"); } // get the log information for this web hr = WcaGetRecordString(hRec, wqLog, &pwzData); ExitOnFailure(hr, "Failed to get log identifier for Web"); if (*pwzData) { hr = ScaGetWebLog(piMetabase, pwzData, hWebLogQuery, &psw->swl); ExitOnFailure(hr, "Failed to get Log for Web."); psw->fHasLog = TRUE; } *ppswList = AddWebToList(*ppswList, psw); psw = NULL; // set the web NULL so it doesn't accidentally get freed below } if (E_NOMOREITEMS == hr) { hr = S_OK; } LExit: // if anything was left over after an error clean it all up WcaFinishUnwrapQuery(hQueryWebSite); WcaFinishUnwrapQuery(hQueryWebAddress); if (psw) { ScaWebsFreeList(psw); } ReleaseStr(pwzData); return hr; }
HRESULT __stdcall ScaVirtualDirsRead7( __in SCA_WEB7* pswList, __in SCA_VDIR7** ppsvdList, __in SCA_MIMEMAP** ppsmmList, __in SCA_HTTP_HEADER** ppshhList, __in SCA_WEB_ERROR** ppsweList, __in WCA_WRAPQUERY_HANDLE hUserQuery, __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, __in WCA_WRAPQUERY_HANDLE hWebAppQuery, __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, __inout LPWSTR *ppwzCustomActionData ) { Assert(ppsvdList); HRESULT hr = S_OK; MSIHANDLE hRec; SCA_VDIR7* pvdir = NULL; LPWSTR pwzData = NULL; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the vdirs while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { // Add this record's information into the list of things to process. hr = AddVirtualDirToList7(ppsvdList); ExitOnFailure(hr, "failed to add vdir to vdir list"); pvdir = *ppsvdList; // get the darwin information hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&pvdir->isInstalled); ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&pvdir->isAction); ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); // get vdir properties hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); ExitOnFailure(hr, "failed to copy vdir component name: %ls", pwzData); hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web for VirtualDir"); hr = ScaWebsGetBase7(pswList, pwzData, pvdir->wzWebName , countof(pvdir->wzWebName)); if (S_FALSE == hr) { hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure(hr, "Failed to get Web Base for VirtualDir"); } if (WcaIsUninstalling(pvdir->isInstalled, pvdir->isAction)) { // If we're uninstalling, ignore any failure to find the existing web hr = S_OK; } hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); hr = ::StringCchCopyW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), pwzData); ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); // get the vdir's directory hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); // get the web's directory if (INSTALLSTATE_SOURCE == pvdir->isAction) { hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); } else { hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); } ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); // remove trailing backslash(es) while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') { pwzData[lstrlenW(pwzData)-1] = 0; } hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); ExitOnFailure(hr, "Failed to copy directory string to vdir object"); // get the security information for this web hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); pvdir->fHasProperties = TRUE; } // get the application information for this web hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); ExitOnFailure(hr, "Failed to get application for VirtualDir"); pvdir->fHasApplication = TRUE; } hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); if (*pwzData && *ppsmmList) { hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); } if (*pwzData && *ppshhList) { hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); } if (*pwzData && *ppsweList) { hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); } } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure while processing VirtualDirs"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
HRESULT __stdcall ScaVirtualDirsRead( __in IMSAdminBase* piMetabase, __in SCA_WEB* pswList, __in SCA_VDIR** ppsvdList, __in SCA_MIMEMAP** ppsmmList, __in SCA_HTTP_HEADER** ppshhList, __in SCA_WEB_ERROR** ppsweList, __in WCA_WRAPQUERY_HANDLE hUserQuery, __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, __in WCA_WRAPQUERY_HANDLE hWebAppQuery, __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, __inout LPWSTR *ppwzCustomActionData ) { Assert(piMetabase && ppsvdList); HRESULT hr = S_OK; MSIHANDLE hRec; INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; SCA_VDIR* pvdir = NULL; LPWSTR pwzData = NULL; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the vdirs while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { // Get the Component first. If there is a Component and it is not being modified during // this transaction, skip processing this whole record. hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&isInstalled); ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&isAction); ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); if (!WcaIsInstalling(isInstalled, isAction) && !WcaIsReInstalling(isInstalled, isAction) && !WcaIsUninstalling(isInstalled, isAction)) { continue; // skip this record. } hr = AddVirtualDirToList(ppsvdList); ExitOnFailure(hr, "failed to add virtual dir to list"); pvdir = *ppsvdList; hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData); pvdir->isInstalled = isInstalled; pvdir->isAction = isAction; // get the web key hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web for VirtualDir"); hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pvdir->wzWebBase, countof(pvdir->wzWebBase), hWebBaseQuery); if (WcaIsUninstalling(isInstalled, isAction)) { // If we're uninstalling, ignore any failure to find the existing web hr = S_OK; } ExitOnFailure1(hr, "Failed to get base of web: %ls for VirtualDir", pwzData); hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); if (0 != lstrlenW(pvdir->wzWebBase)) { hr = ::StringCchPrintfW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), L"%s/Root/%s", pvdir->wzWebBase, pwzData); ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); } // get the vdir's directory hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); // get the web's directory if (INSTALLSTATE_SOURCE == pvdir->isAction) { hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); } else { hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); } ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); // remove trailing backslash(es) while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') { pwzData[lstrlenW(pwzData)-1] = 0; } hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); ExitOnFailure(hr, "Failed to copy directory string to vdir object"); // get the security information for this web hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); pvdir->fHasProperties = TRUE; } // get the application information for this web hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); ExitOnFailure(hr, "Failed to get application for VirtualDir"); pvdir->fHasApplication = TRUE; } hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); if (*pwzData && *ppsmmList) { hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); } if (*pwzData && *ppshhList) { hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); ExitOnFailure1(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); } if (*pwzData && *ppsweList) { hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); ExitOnFailure1(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); } } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure while processing VirtualDirs"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
HRESULT ScaWebErrorRead( SCA_WEB_ERROR **ppsweList, __inout LPWSTR *ppwzCustomActionData ) { // AssertSz(0, "Debug ScaWebErrorRead here"); HRESULT hr = S_OK; MSIHANDLE hRec; LPWSTR pwzData = NULL; SCA_WEB_ERROR* pswe; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; ExitOnNull(ppsweList, hr, E_INVALIDARG, "Failed to read web error, because no web error was provided to read"); hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebErrorRead() - required tables not present."); ExitFunction1(hr = S_FALSE); } // loop through all the web errors while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { hr = AddWebErrorToList(ppsweList); ExitOnFailure(hr, "failed to add web error to list"); pswe = *ppsweList; hr = WcaGetRecordInteger(hRec, weqErrorCode, &(pswe->iErrorCode)); ExitOnFailure(hr, "failed to get IIsWebError.ErrorCode"); hr = WcaGetRecordInteger(hRec, weqSubCode, &(pswe->iSubCode)); ExitOnFailure(hr, "failed to get IIsWebError.SubCode"); hr = WcaGetRecordInteger(hRec, weqParentType, &(pswe->iParentType)); ExitOnFailure(hr, "failed to get IIsWebError.ParentType"); hr = WcaGetRecordString(hRec, weqParentValue, &pwzData); ExitOnFailure(hr, "Failed to get IIsWebError.ParentValue"); hr = ::StringCchCopyW(pswe->wzParentValue, countof(pswe->wzParentValue), pwzData); ExitOnFailure(hr, "Failed to copy IIsWebError.ParentValue"); hr = WcaGetRecordString(hRec, weqFile, &pwzData); ExitOnFailure(hr, "Failed to get IIsWebError.File"); hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), pwzData); ExitOnFailure(hr, "Failed to copy IIsWebError.File"); hr = WcaGetRecordString(hRec, weqURL, &pwzData); ExitOnFailure(hr, "Failed to get IIsWebError.URL"); hr = ::StringCchCopyW(pswe->wzURL, countof(pswe->wzURL), pwzData); ExitOnFailure(hr, "Failed to copy IIsWebError.URL"); // If they've specified both a file and a URL, that's invalid if (*(pswe->wzFile) && *(pswe->wzURL)) ExitOnFailure2(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Both File and URL specified for web error. File: %ls, URL: %ls", pswe->wzFile, pswe->wzURL); } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure while processing web errors"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
UINT __stdcall ScaFiltersRead7( __in SCA_WEB7* pswList, __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, __inout SCA_FILTER** ppsfList, __inout LPWSTR *ppwzCustomActionData ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; MSIHANDLE hRec; INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; SCA_FILTER* psf; LPWSTR pwzData = NULL; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table"); ExitFunction1(hr = S_FALSE); } // loop through all the filters while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { // Get the Component first. If the component is not being modified during // this transaction, skip processing this whole record. // get the darwin information hr = WcaGetRecordString(hRec, fqComponent, &pwzData); ExitOnFailure(hr, "failed to get IIsFilter.Component"); hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled); ExitOnFailure(hr, "Failed to get Component installed state for IIs filter"); hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction); ExitOnFailure(hr, "Failed to get Component action state for IIs filter"); if (!WcaIsInstalling(isInstalled, isAction) && !WcaIsReInstalling(isInstalled, isAction) && !WcaIsUninstalling(isInstalled, isAction)) { continue; // skip this record. } hr = AddFilterToList(ppsfList); ExitOnFailure(hr, "failed to add filter to list"); psf = *ppsfList; hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData); ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData); psf->isInstalled = isInstalled; psf->isAction = isAction; hr = WcaGetRecordString(hRec, fqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web for VirtualDir"); if (*pwzData) { hr = ScaWebsGetBase7(pswList, pwzData, psf->wzFilterRoot, countof(psf->wzFilterRoot)); if (FAILED(hr)) { WcaLog(LOGMSG_VERBOSE, "Could not find site for filter: %ls. Result 0x%x ", psf->wzFilterRoot, hr); hr = S_OK; } } else { hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/"); ExitOnFailure(hr, "Failed to allocate global filter base string"); } // filter Name key hr = WcaGetRecordString(hRec, fqFilter, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Filter"); hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); ExitOnFailure(hr, "Failed to copy key string to filter object"); // filter path hr = WcaGetRecordString(hRec, fqPath, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Path"); hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); ExitOnFailure(hr, "Failed to copy path string to filter object"); // filter description -- not supported in iis 7 hr = WcaGetRecordString(hRec, fqDescription, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Description"); hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); ExitOnFailure(hr, "Failed to copy description string to filter object"); // filter flags //What are these hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); ExitOnFailure(hr, "Failed to get Filter.Flags"); // filter load order hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure while processing filters"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
UINT __stdcall ScaWebDirsRead( __in IMSAdminBase* piMetabase, __in SCA_WEB* pswList, __in WCA_WRAPQUERY_HANDLE hUserQuery, __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, __in WCA_WRAPQUERY_HANDLE hWebAppQuery, __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, __inout LPWSTR *ppwzCustomActionData, __out SCA_WEBDIR** ppswdList ) { Assert(piMetabase && ppswdList); HRESULT hr = S_OK; MSIHANDLE hRec; LPWSTR pwzData = NULL; SCA_WEBDIR* pswd; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs() because IIsWebDir table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the web directories while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { pswd = NewWebDir(); ExitOnNull(pswd, hr, E_OUTOFMEMORY, "Failed to allocate memory for web dir object in memory"); // get component install state hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); ExitOnFailure(hr, "Failed to get Component for WebDirs"); hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); ExitOnFailure(hr, "Failed to copy component string to webdir object"); hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); ExitOnFailure(hr, "Failed to get Component installed state for webdir"); hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); ExitOnFailure(hr, "Failed to get Component action state for webdir"); // If this record has a component and no action is being taken for it, skip processing it entirely if (0 < lstrlenW(pswd->wzComponent) && !WcaIsInstalling(pswd->isInstalled, pswd->isAction) && !WcaIsUninstalling(pswd->isInstalled, pswd->isAction) && !WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) { FreeWebDir(pswd); pswd = NULL; continue; } hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web for WebDir"); hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pswd->wzWebBase, countof(pswd->wzWebBase), hWebBaseQuery); if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) { // If we're uninstalling, ignore any failure to find the existing web hr = S_OK; } ExitOnFailure(hr, "Failed to get base of web for WebDir"); hr = WcaGetRecordString(hRec, wdqPath, &pwzData); ExitOnFailure(hr, "Failed to get Path for WebDir"); hr = ::StringCchPrintfW(pswd->wzWebDirRoot, countof(pswd->wzWebDirRoot), L"%s/Root/%s", pswd->wzWebBase, pwzData); ExitOnFailure(hr, "Failed to format webdir root string"); // get the directory properties for this web hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); ExitOnFailure(hr, "Failed to get security identifier for WebDir"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); ExitOnFailure(hr, "Failed to get properties for WebDir"); pswd->fHasProperties = TRUE; } // get the application information for this web directory hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for WebDir"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); ExitOnFailure(hr, "Failed to get application for WebDir"); pswd->fHasApplication = TRUE; } AddWebDirToList(ppswdList, pswd); } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure while processing WebDirs"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
HRESULT __stdcall ScaMimeMapRead( SCA_MIMEMAP** ppsmmList, __inout LPWSTR *ppwzCustomActionData ) { HRESULT hr = S_OK; MSIHANDLE hRec; BOOL fIIsWebMimeMapTable = FALSE; LPWSTR pwzData = NULL; SCA_MIMEMAP* psmm; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaMimeMapRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaMimeMapRead() - required table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the mimemappings while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { hr = AddMimeMapToList(ppsmmList); ExitOnFailure(hr, "failed to add mime map to list"); psmm = *ppsmmList; hr = WcaGetRecordString(hRec, mmqMimeMap, &pwzData); ExitOnFailure(hr, "Failed to get MimeMap.MimeMap"); hr = ::StringCchCopyW(psmm->wzMimeMap, countof(psmm->wzMimeMap), pwzData); ExitOnFailure(hr, "Failed to copy mimemap string to mimemap object"); hr = WcaGetRecordInteger(hRec, mmqParentType, &psmm->iParentType); ExitOnFailure(hr, "Failed to get MimeMap.iParentType"); hr = WcaGetRecordString(hRec, mmqParentValue, &pwzData); ExitOnFailure(hr, "Failed to get MimeMap.ParentValue"); hr = ::StringCchCopyW(psmm->wzParentValue, countof(psmm->wzParentValue), pwzData); ExitOnFailure(hr, "Failed to copy parent value string to mimemap object"); hr = WcaGetRecordString(hRec, mmqExtension, &pwzData); ExitOnFailure(hr, "Failed to get MimeMap.Extension"); hr = ::StringCchCopyW(psmm->wzExtension, countof(psmm->wzExtension), pwzData); ExitOnFailure(hr, "Failed to copy extension string to mimemap object"); hr = WcaGetRecordString(hRec, mmqMimeType, &pwzData); ExitOnFailure(hr, "Failed to get MimeMap.MimeType"); hr = ::StringCchCopyW(psmm->wzMimeType, countof(psmm->wzMimeType), pwzData); ExitOnFailure(hr, "Failed to copy mimetype string to mimemap object"); } if (E_NOMOREITEMS == hr) hr = S_OK; ExitOnFailure(hr, "Failure while processing mimemappings"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }
/******************************************************************** 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); }
HRESULT ScaWebsRead7( __in SCA_WEB7** ppswList, __in SCA_HTTP_HEADER** ppshhList, __in SCA_WEB_ERROR** ppsweList, __in WCA_WRAPQUERY_HANDLE hUserQuery, __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, __in WCA_WRAPQUERY_HANDLE hSslCertQuery, __in WCA_WRAPQUERY_HANDLE hWebLogQuery, __in WCA_WRAPQUERY_HANDLE hWebAppQuery, __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, __inout LPWSTR *ppwzCustomActionData ) { Assert(ppswList); WcaLog(LOGMSG_VERBOSE, "Entering ScaWebsRead7()"); HRESULT hr = S_OK; MSIHANDLE hRec; MSIHANDLE hRecAddresses; WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; SCA_WEB7* psw = NULL; LPWSTR pwzData = NULL; DWORD dwLen = 0; errno_t error = EINVAL; // check to see what tables are available hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); if (0 == WcaGetQueryRecords(hQueryWebSite) || 0 == WcaGetQueryRecords(hQueryWebAddress)) { WcaLog(LOGMSG_VERBOSE, "Required tables not present"); ExitFunction1(hr = S_FALSE); } // loop through all the webs while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) { psw = NewWeb7(); if (!psw) { hr = E_OUTOFMEMORY; break; } // get the darwin information hr = WcaGetRecordString(hRec, wqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web"); hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); ExitOnFailure(hr, "Failed to copy key string to web object"); // get component install state hr = WcaGetRecordString(hRec, wqComponent, &pwzData); ExitOnFailure(hr, "Failed to get Component for Web"); hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); ExitOnFailure(hr, "Failed to copy component string to web object"); if (*(psw->wzComponent)) { psw->fHasComponent = TRUE; hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); ExitOnFailure(hr, "Failed to get web Component's installed state"); WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); ExitOnFailure(hr, "Failed to get web Component's action state"); } // Get the web's description. hr = WcaGetRecordString(hRec, wqDescription, &pwzData); ExitOnFailure(hr, "Failed to get Description for Web"); hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); ExitOnFailure(hr, "Failed to copy description string to web object"); //get web's site Id hr = WcaGetRecordInteger(hRec, wqId, &psw->iSiteId); ExitOnFailure(hr, "Failed to get SiteId for Web"); // get the web's key address (Bindings) hr = WcaGetRecordString(hRec, wqAddress, &pwzData); ExitOnFailure(hr, "Failed to get Address for Web"); hr = ::StringCchCopyW(psw->swaBinding.wzKey, countof(psw->swaBinding.wzKey), pwzData); ExitOnFailure(hr, "Failed to copy web binding key"); hr = WcaGetRecordString(hRec, wqIP, &pwzData); ExitOnFailure(hr, "Failed to get IP for Web"); hr = ::StringCchCopyW(psw->swaBinding.wzIP, countof(psw->swaBinding.wzIP), pwzData); ExitOnFailure(hr, "Failed to copy web IP"); hr = WcaGetRecordString(hRec, wqPort, &pwzData); ExitOnFailure(hr, "Failed to get Web Address port"); psw->swaBinding.iPort = wcstol(pwzData, NULL, 10); hr = WcaGetRecordString(hRec, wqHeader, &pwzData); ExitOnFailure(hr, "Failed to get Header for Web"); hr = ::StringCchCopyW(psw->swaBinding.wzHeader, countof(psw->swaBinding.wzHeader), pwzData); ExitOnFailure(hr, "Failed to copy web header"); hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaBinding.fSecure); ExitOnFailure(hr, "Failed to get if Web is secure"); if (S_FALSE == hr) { psw->swaBinding.fSecure = FALSE; } // look to see if site exists dwLen = METADATA_MAX_NAME_LEN; hr = ScaWebFindBase7(*ppswList, psw->wzDescription); // If we didn't find a web in memory, ignore it - during execute CA // if the site truly does not exist then there will be an error. if (S_OK == hr) { // site exists in config psw->fBaseExists = TRUE; } else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK; // site does not exists in config psw->fBaseExists = FALSE; } ExitOnFailure(hr, "Failed to find web site"); // get any extra web addresses WcaFetchWrappedReset(hQueryWebAddress); while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) { if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) { hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); } hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); ExitOnFailure(hr, "Failed to get extra web Address"); // if this isn't the key address add it if (0 != lstrcmpW(pwzData, psw->swaBinding.wzKey)) { hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); ExitOnFailure(hr, "Failed to copy web binding key"); hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); ExitOnFailure(hr, "Failed to get extra web IP"); hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); ExitOnFailure(hr, "Failed to copy web binding IP"); hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); ExitOnFailure(hr, "Failed to get port for extra web IP"); psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); // errno is set to ERANGE if overflow or underflow occurs _get_errno(&error); if (ERANGE == error) { hr = E_INVALIDARG; ExitOnFailure(hr, "Failed to convert web Port address"); } hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); ExitOnFailure(hr, "Failed to get header for extra web IP"); hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); ExitOnFailure(hr, "Failed to copy web binding header"); hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); ExitOnFailure(hr, "Failed to get if secure extra web IP"); if (S_FALSE == hr) { psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; } ++psw->cExtraAddresses; } } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure occured while getting extra web addresses"); // // Connection time out // hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); ExitOnFailure(hr, "Failed to get connection timeout for Web"); if (psw->fHasComponent) // If we're installing it, it needs a dir { // get the web's directory if (INSTALLSTATE_SOURCE == psw->isAction) { hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); } else { hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); } ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); dwLen = lstrlenW(pwzData); // remove trailing backslash if (dwLen > 0 && pwzData[dwLen-1] == L'\\') { pwzData[dwLen-1] = 0; } hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); ExitOnFailure1(hr, "Failed to copy web dir: '%ls'", pwzData); } hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); ExitOnFailure(hr, "Failed to get state for Web"); hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); ExitOnFailure(hr, "Failed to get attributes for Web"); // get the dir properties for this web hr = WcaGetRecordString(hRec, wqProperties, &pwzData); ExitOnFailure(hr, "Failed to get directory properties for Web"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); ExitOnFailure(hr, "Failed to get directory properties for Web"); psw->fHasProperties = TRUE; } // get the application information for this web hr = WcaGetRecordString(hRec, wqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for Web"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); ExitOnFailure(hr, "Failed to get application for Web"); psw->fHasApplication = TRUE; } // get the SSL certificates hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); ExitOnFailure(hr, "Failed to get SSL Certificates."); // get the custom headers if (*ppshhList) { hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); } // get the errors if (*ppsweList) { hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); ExitOnFailure(hr, "Failed to get Custom Errors"); } // get the log information for this web hr = WcaGetRecordString(hRec, wqLog, &pwzData); ExitOnFailure(hr, "Failed to get log identifier for Web"); if (*pwzData) { hr = ScaGetWebLog7(pwzData, hWebLogQuery, &psw->swl); ExitOnFailure(hr, "Failed to get Log for Web."); psw->fHasLog = TRUE; } *ppswList = AddWebToList7(*ppswList, psw); psw = NULL; // set the web NULL so it doesn't accidentally get freed below } if (E_NOMOREITEMS == hr) { hr = S_OK; } LExit: // if anything was left over after an error clean it all up WcaFinishUnwrapQuery(hQueryWebSite); WcaFinishUnwrapQuery(hQueryWebAddress); ScaWebsFreeList7(psw); ReleaseStr(pwzData); WcaLog(LOGMSG_VERBOSE, "Exiting ScaWebsRead7()"); return hr; }
HRESULT ScaPropertyRead( SCA_PROPERTY** ppspList, __inout LPWSTR *ppwzCustomActionData ) { HRESULT hr = S_OK; MSIHANDLE hRec; LPWSTR pwzData = NULL; SCA_PROPERTY* pss; WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; ExitOnNull(ppspList, hr, E_INVALIDARG, "Failed to read property, because no property to read was provided"); hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); if (0 == WcaGetQueryRecords(hWrapQuery)) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallProperty() - required table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the Settings while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) { hr = AddPropertyToList(ppspList); ExitOnFailure(hr, "failed to add property to list"); pss = *ppspList; hr = WcaGetRecordString(hRec, pqProperty, &pwzData); ExitOnFailure(hr, "failed to get IIsProperty.Property"); hr = ::StringCchCopyW(pss->wzProperty, countof(pss->wzProperty), pwzData); ExitOnFailure1(hr, "failed to copy Property name: %ls", pwzData); hr = WcaGetRecordString(hRec, pqValue, &pwzData); ExitOnFailure(hr, "failed to get IIsProperty.Value"); hr = ::StringCchCopyW(pss->wzValue, countof(pss->wzValue), pwzData); ExitOnFailure1(hr, "failed to copy Property value: %ls", pwzData); hr = WcaGetRecordInteger(hRec, pqAttributes, &pss->iAttributes); ExitOnFailure(hr, "failed to get IIsProperty.Attributes"); hr = WcaGetRecordString(hRec, pqComponent, &pwzData); ExitOnFailure(hr, "failed to get IIsProperty.Component"); hr = ::StringCchCopyW(pss->wzComponent, countof(pss->wzComponent), pwzData); ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData); hr = WcaGetRecordInteger(hRec, pqInstalled, (int *)&pss->isInstalled); ExitOnFailure(hr, "Failed to get Component installed state for filter"); hr = WcaGetRecordInteger(hRec, pqAction, (int *)&pss->isAction); ExitOnFailure(hr, "Failed to get Component action state for filter"); } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "failure while processing IIsProperty table"); LExit: WcaFinishUnwrapQuery(hWrapQuery); ReleaseStr(pwzData); return hr; }