From 95a5a8f9efef02ddcec5b3f69be99a00d71a802a Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 16 Dec 2018 21:19:24 -0600 Subject: Import implementation of IisCA from old repo's scasched/scaexec. --- src/ca/scawebdir.cpp | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 src/ca/scawebdir.cpp (limited to 'src/ca/scawebdir.cpp') diff --git a/src/ca/scawebdir.cpp b/src/ca/scawebdir.cpp new file mode 100644 index 00000000..26a7b32b --- /dev/null +++ b/src/ca/scawebdir.cpp @@ -0,0 +1,241 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// sql queries +enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; + +// prototypes +static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd); + +static SCA_WEBDIR* NewWebDir(); +static void FreeWebDir(SCA_WEBDIR *pswd); + + +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 ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList) +{ + HRESULT hr = S_OK; + SCA_WEBDIR* pswd = pswdList; + int i; + + while (pswd) + { + // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created + if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) + { + if (pswd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); + } + } + + // if we are installing the web site + if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) + { + hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); + ExitOnFailure(hr, "Failed to create key for WebDir"); + hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory"); + ExitOnFailure(hr, "Failed to write key type for for WebDir"); + i = 0x4000003e; // 1073741886: default directory browsing rights + hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); + ExitOnFailure(hr, "Failed to set directory browsing for WebDir"); + + // get the security information for this web + if (pswd->fHasProperties) + { + ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp); + ExitOnFailure(hr, "Failed to write properties for WebDir"); + } + + // get the application information for this web directory + if (pswd->fHasApplication) + { + hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList); + ExitOnFailure(hr, "Failed to write application for WebDir"); + } + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +HRESULT ScaWebDirsUninstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + SCA_WEBDIR* pswd = pswdList; + + while (pswd) + { + if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) + { + // remove the application from this web directory + if (pswd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebDir"); + } + + hr = ScaDeleteMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); + ExitOnFailure(hr, "Failed to remove WebDir '%ls' from metabase", pswd->wzKey); + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +static SCA_WEBDIR* NewWebDir() +{ + SCA_WEBDIR* pswd = static_cast(MemAlloc(sizeof(SCA_WEBDIR), TRUE)); + Assert(pswd); + return pswd; +} + +static void FreeWebDir(SCA_WEBDIR *pswd) +{ + MemFree(pswd); +} + +void ScaWebDirsFreeList(SCA_WEBDIR* pswdList) +{ + SCA_WEBDIR* pswdDelete = pswdList; + while (pswdList) + { + pswdDelete = pswdList; + pswdList = pswdList->pswdNext; + + FreeWebDir(pswdDelete); + } +} + + +static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd) +{ + pswd->pswdNext = *ppswdList; + *ppswdList = pswd; +} -- cgit v1.2.3-55-g6feb