diff options
Diffstat (limited to 'src/ext/Iis/ca/scawebdir.cpp')
-rw-r--r-- | src/ext/Iis/ca/scawebdir.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/ext/Iis/ca/scawebdir.cpp b/src/ext/Iis/ca/scawebdir.cpp new file mode 100644 index 00000000..26a7b32b --- /dev/null +++ b/src/ext/Iis/ca/scawebdir.cpp | |||
@@ -0,0 +1,241 @@ | |||
1 | // 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. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | // sql queries | ||
6 | enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; | ||
7 | |||
8 | // prototypes | ||
9 | static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd); | ||
10 | |||
11 | static SCA_WEBDIR* NewWebDir(); | ||
12 | static void FreeWebDir(SCA_WEBDIR *pswd); | ||
13 | |||
14 | |||
15 | UINT __stdcall ScaWebDirsRead( | ||
16 | __in IMSAdminBase* piMetabase, | ||
17 | __in SCA_WEB* pswList, | ||
18 | __in WCA_WRAPQUERY_HANDLE hUserQuery, | ||
19 | __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, | ||
20 | __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, | ||
21 | __in WCA_WRAPQUERY_HANDLE hWebAppQuery, | ||
22 | __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, | ||
23 | __inout LPWSTR *ppwzCustomActionData, | ||
24 | __out SCA_WEBDIR** ppswdList | ||
25 | ) | ||
26 | { | ||
27 | Assert(piMetabase && ppswdList); | ||
28 | |||
29 | HRESULT hr = S_OK; | ||
30 | MSIHANDLE hRec; | ||
31 | |||
32 | LPWSTR pwzData = NULL; | ||
33 | SCA_WEBDIR* pswd; | ||
34 | WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; | ||
35 | |||
36 | hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); | ||
37 | ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead"); | ||
38 | |||
39 | if (0 == WcaGetQueryRecords(hWrapQuery)) | ||
40 | { | ||
41 | WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs() because IIsWebDir table not present"); | ||
42 | ExitFunction1(hr = S_FALSE); | ||
43 | } | ||
44 | |||
45 | // loop through all the web directories | ||
46 | while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) | ||
47 | { | ||
48 | pswd = NewWebDir(); | ||
49 | ExitOnNull(pswd, hr, E_OUTOFMEMORY, "Failed to allocate memory for web dir object in memory"); | ||
50 | |||
51 | // get component install state | ||
52 | hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); | ||
53 | ExitOnFailure(hr, "Failed to get Component for WebDirs"); | ||
54 | hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); | ||
55 | ExitOnFailure(hr, "Failed to copy component string to webdir object"); | ||
56 | |||
57 | hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); | ||
58 | ExitOnFailure(hr, "Failed to get Component installed state for webdir"); | ||
59 | |||
60 | hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); | ||
61 | ExitOnFailure(hr, "Failed to get Component action state for webdir"); | ||
62 | |||
63 | // If this record has a component and no action is being taken for it, skip processing it entirely | ||
64 | if (0 < lstrlenW(pswd->wzComponent) && !WcaIsInstalling(pswd->isInstalled, pswd->isAction) | ||
65 | && !WcaIsUninstalling(pswd->isInstalled, pswd->isAction) && !WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) | ||
66 | { | ||
67 | FreeWebDir(pswd); | ||
68 | pswd = NULL; | ||
69 | continue; | ||
70 | } | ||
71 | |||
72 | hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); | ||
73 | ExitOnFailure(hr, "Failed to get Web for WebDir"); | ||
74 | |||
75 | hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pswd->wzWebBase, countof(pswd->wzWebBase), hWebBaseQuery); | ||
76 | if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) | ||
77 | { | ||
78 | // If we're uninstalling, ignore any failure to find the existing web | ||
79 | hr = S_OK; | ||
80 | } | ||
81 | |||
82 | ExitOnFailure(hr, "Failed to get base of web for WebDir"); | ||
83 | |||
84 | hr = WcaGetRecordString(hRec, wdqPath, &pwzData); | ||
85 | ExitOnFailure(hr, "Failed to get Path for WebDir"); | ||
86 | |||
87 | hr = ::StringCchPrintfW(pswd->wzWebDirRoot, countof(pswd->wzWebDirRoot), L"%s/Root/%s", pswd->wzWebBase, pwzData); | ||
88 | ExitOnFailure(hr, "Failed to format webdir root string"); | ||
89 | |||
90 | // get the directory properties for this web | ||
91 | hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); | ||
92 | ExitOnFailure(hr, "Failed to get security identifier for WebDir"); | ||
93 | if (*pwzData) | ||
94 | { | ||
95 | hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); | ||
96 | ExitOnFailure(hr, "Failed to get properties for WebDir"); | ||
97 | |||
98 | pswd->fHasProperties = TRUE; | ||
99 | } | ||
100 | |||
101 | // get the application information for this web directory | ||
102 | hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); | ||
103 | ExitOnFailure(hr, "Failed to get application identifier for WebDir"); | ||
104 | if (*pwzData) | ||
105 | { | ||
106 | hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); | ||
107 | ExitOnFailure(hr, "Failed to get application for WebDir"); | ||
108 | |||
109 | pswd->fHasApplication = TRUE; | ||
110 | } | ||
111 | |||
112 | AddWebDirToList(ppswdList, pswd); | ||
113 | } | ||
114 | |||
115 | if (E_NOMOREITEMS == hr) | ||
116 | { | ||
117 | hr = S_OK; | ||
118 | } | ||
119 | ExitOnFailure(hr, "Failure while processing WebDirs"); | ||
120 | |||
121 | LExit: | ||
122 | WcaFinishUnwrapQuery(hWrapQuery); | ||
123 | |||
124 | ReleaseStr(pwzData); | ||
125 | |||
126 | return hr; | ||
127 | } | ||
128 | |||
129 | |||
130 | HRESULT ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList) | ||
131 | { | ||
132 | HRESULT hr = S_OK; | ||
133 | SCA_WEBDIR* pswd = pswdList; | ||
134 | int i; | ||
135 | |||
136 | while (pswd) | ||
137 | { | ||
138 | // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created | ||
139 | if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) | ||
140 | { | ||
141 | if (pswd->fHasApplication) | ||
142 | { | ||
143 | hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); | ||
144 | ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // if we are installing the web site | ||
149 | if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) | ||
150 | { | ||
151 | hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); | ||
152 | ExitOnFailure(hr, "Failed to create key for WebDir"); | ||
153 | hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory"); | ||
154 | ExitOnFailure(hr, "Failed to write key type for for WebDir"); | ||
155 | i = 0x4000003e; // 1073741886: default directory browsing rights | ||
156 | hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); | ||
157 | ExitOnFailure(hr, "Failed to set directory browsing for WebDir"); | ||
158 | |||
159 | // get the security information for this web | ||
160 | if (pswd->fHasProperties) | ||
161 | { | ||
162 | ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp); | ||
163 | ExitOnFailure(hr, "Failed to write properties for WebDir"); | ||
164 | } | ||
165 | |||
166 | // get the application information for this web directory | ||
167 | if (pswd->fHasApplication) | ||
168 | { | ||
169 | hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList); | ||
170 | ExitOnFailure(hr, "Failed to write application for WebDir"); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | pswd = pswd->pswdNext; | ||
175 | } | ||
176 | |||
177 | LExit: | ||
178 | return hr; | ||
179 | } | ||
180 | |||
181 | |||
182 | HRESULT ScaWebDirsUninstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList) | ||
183 | { | ||
184 | Assert(piMetabase); | ||
185 | |||
186 | HRESULT hr = S_OK; | ||
187 | SCA_WEBDIR* pswd = pswdList; | ||
188 | |||
189 | while (pswd) | ||
190 | { | ||
191 | if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) | ||
192 | { | ||
193 | // remove the application from this web directory | ||
194 | if (pswd->fHasApplication) | ||
195 | { | ||
196 | hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); | ||
197 | ExitOnFailure(hr, "Failed to remove application for WebDir"); | ||
198 | } | ||
199 | |||
200 | hr = ScaDeleteMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); | ||
201 | ExitOnFailure(hr, "Failed to remove WebDir '%ls' from metabase", pswd->wzKey); | ||
202 | } | ||
203 | |||
204 | pswd = pswd->pswdNext; | ||
205 | } | ||
206 | |||
207 | LExit: | ||
208 | return hr; | ||
209 | } | ||
210 | |||
211 | |||
212 | static SCA_WEBDIR* NewWebDir() | ||
213 | { | ||
214 | SCA_WEBDIR* pswd = static_cast<SCA_WEBDIR*>(MemAlloc(sizeof(SCA_WEBDIR), TRUE)); | ||
215 | Assert(pswd); | ||
216 | return pswd; | ||
217 | } | ||
218 | |||
219 | static void FreeWebDir(SCA_WEBDIR *pswd) | ||
220 | { | ||
221 | MemFree(pswd); | ||
222 | } | ||
223 | |||
224 | void ScaWebDirsFreeList(SCA_WEBDIR* pswdList) | ||
225 | { | ||
226 | SCA_WEBDIR* pswdDelete = pswdList; | ||
227 | while (pswdList) | ||
228 | { | ||
229 | pswdDelete = pswdList; | ||
230 | pswdList = pswdList->pswdNext; | ||
231 | |||
232 | FreeWebDir(pswdDelete); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | |||
237 | static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd) | ||
238 | { | ||
239 | pswd->pswdNext = *ppswdList; | ||
240 | *ppswdList = pswd; | ||
241 | } | ||