diff options
Diffstat (limited to 'src/ext/Iis/ca/scavdir.cpp')
-rw-r--r-- | src/ext/Iis/ca/scavdir.cpp | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/src/ext/Iis/ca/scavdir.cpp b/src/ext/Iis/ca/scavdir.cpp new file mode 100644 index 00000000..d388ce97 --- /dev/null +++ b/src/ext/Iis/ca/scavdir.cpp | |||
@@ -0,0 +1,331 @@ | |||
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 | // prototypes | ||
6 | static HRESULT AddVirtualDirToList( | ||
7 | __in SCA_VDIR** psvdList | ||
8 | ); | ||
9 | |||
10 | |||
11 | HRESULT __stdcall ScaVirtualDirsRead( | ||
12 | __in IMSAdminBase* piMetabase, | ||
13 | __in SCA_WEB* pswList, | ||
14 | __in SCA_VDIR** ppsvdList, | ||
15 | __in SCA_MIMEMAP** ppsmmList, | ||
16 | __in SCA_HTTP_HEADER** ppshhList, | ||
17 | __in SCA_WEB_ERROR** ppsweList, | ||
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 | ) | ||
25 | { | ||
26 | Assert(piMetabase && ppsvdList); | ||
27 | |||
28 | HRESULT hr = S_OK; | ||
29 | MSIHANDLE hRec; | ||
30 | INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; | ||
31 | INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; | ||
32 | |||
33 | SCA_VDIR* pvdir = NULL; | ||
34 | LPWSTR pwzData = NULL; | ||
35 | |||
36 | WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; | ||
37 | |||
38 | hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); | ||
39 | ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); | ||
40 | |||
41 | if (0 == WcaGetQueryRecords(hWrapQuery)) | ||
42 | { | ||
43 | WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); | ||
44 | ExitFunction1(hr = S_FALSE); | ||
45 | } | ||
46 | |||
47 | // loop through all the vdirs | ||
48 | while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) | ||
49 | { | ||
50 | // Get the Component first. If there is a Component and it is not being modified during | ||
51 | // this transaction, skip processing this whole record. | ||
52 | hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); | ||
53 | ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); | ||
54 | |||
55 | hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&isInstalled); | ||
56 | ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); | ||
57 | |||
58 | hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&isAction); | ||
59 | ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); | ||
60 | |||
61 | if (!WcaIsInstalling(isInstalled, isAction) && | ||
62 | !WcaIsReInstalling(isInstalled, isAction) && | ||
63 | !WcaIsUninstalling(isInstalled, isAction)) | ||
64 | { | ||
65 | continue; // skip this record. | ||
66 | } | ||
67 | |||
68 | hr = AddVirtualDirToList(ppsvdList); | ||
69 | ExitOnFailure(hr, "failed to add virtual dir to list"); | ||
70 | |||
71 | pvdir = *ppsvdList; | ||
72 | |||
73 | hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); | ||
74 | ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); | ||
75 | |||
76 | pvdir->isInstalled = isInstalled; | ||
77 | pvdir->isAction = isAction; | ||
78 | |||
79 | // get the web key | ||
80 | hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); | ||
81 | ExitOnFailure(hr, "Failed to get Web for VirtualDir"); | ||
82 | |||
83 | hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pvdir->wzWebBase, countof(pvdir->wzWebBase), hWebBaseQuery); | ||
84 | if (WcaIsUninstalling(isInstalled, isAction)) | ||
85 | { | ||
86 | // If we're uninstalling, ignore any failure to find the existing web | ||
87 | hr = S_OK; | ||
88 | } | ||
89 | ExitOnFailure(hr, "Failed to get base of web: %ls for VirtualDir", pwzData); | ||
90 | |||
91 | hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); | ||
92 | ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); | ||
93 | |||
94 | if (0 != lstrlenW(pvdir->wzWebBase)) | ||
95 | { | ||
96 | hr = ::StringCchPrintfW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), L"%s/Root/%s", pvdir->wzWebBase, pwzData); | ||
97 | ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); | ||
98 | } | ||
99 | |||
100 | // get the vdir's directory | ||
101 | hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); | ||
102 | ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); | ||
103 | |||
104 | // get the web's directory | ||
105 | if (INSTALLSTATE_SOURCE == pvdir->isAction) | ||
106 | { | ||
107 | hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); | ||
112 | } | ||
113 | ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); | ||
114 | |||
115 | // remove trailing backslash(es) | ||
116 | while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') | ||
117 | { | ||
118 | pwzData[lstrlenW(pwzData)-1] = 0; | ||
119 | } | ||
120 | hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); | ||
121 | ExitOnFailure(hr, "Failed to copy directory string to vdir object"); | ||
122 | |||
123 | // get the security information for this web | ||
124 | hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); | ||
125 | ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); | ||
126 | if (*pwzData) | ||
127 | { | ||
128 | hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); | ||
129 | ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); | ||
130 | |||
131 | pvdir->fHasProperties = TRUE; | ||
132 | } | ||
133 | |||
134 | // get the application information for this web | ||
135 | hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); | ||
136 | ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); | ||
137 | if (*pwzData) | ||
138 | { | ||
139 | hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); | ||
140 | ExitOnFailure(hr, "Failed to get application for VirtualDir"); | ||
141 | |||
142 | pvdir->fHasApplication = TRUE; | ||
143 | } | ||
144 | |||
145 | hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); | ||
146 | ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); | ||
147 | |||
148 | if (*pwzData && *ppsmmList) | ||
149 | { | ||
150 | hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); | ||
151 | ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); | ||
152 | } | ||
153 | |||
154 | if (*pwzData && *ppshhList) | ||
155 | { | ||
156 | hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); | ||
157 | ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); | ||
158 | } | ||
159 | |||
160 | if (*pwzData && *ppsweList) | ||
161 | { | ||
162 | hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); | ||
163 | ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | if (E_NOMOREITEMS == hr) | ||
168 | { | ||
169 | hr = S_OK; | ||
170 | } | ||
171 | ExitOnFailure(hr, "Failure while processing VirtualDirs"); | ||
172 | |||
173 | LExit: | ||
174 | WcaFinishUnwrapQuery(hWrapQuery); | ||
175 | |||
176 | ReleaseStr(pwzData); | ||
177 | return hr; | ||
178 | } | ||
179 | |||
180 | |||
181 | HRESULT ScaVirtualDirsInstall( | ||
182 | __in IMSAdminBase* piMetabase, | ||
183 | __in SCA_VDIR* psvdList, | ||
184 | __in SCA_APPPOOL * psapList | ||
185 | ) | ||
186 | { | ||
187 | Assert(piMetabase); | ||
188 | |||
189 | HRESULT hr = S_OK; | ||
190 | SCA_VDIR* psvd = psvdList; | ||
191 | int i; | ||
192 | |||
193 | while (psvd) | ||
194 | { | ||
195 | // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created | ||
196 | if (WcaIsReInstalling(psvd->isInstalled, psvd->isAction)) | ||
197 | { | ||
198 | if (psvd->fHasApplication) | ||
199 | { | ||
200 | hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); | ||
201 | ExitOnFailure(hr, "Failed to remove application for WebVDir as part of a reinstall"); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) | ||
206 | { | ||
207 | hr = ScaCreateMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); | ||
208 | ExitOnFailure(hr, "Failed to create key for VirtualDir"); | ||
209 | hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); | ||
210 | ExitOnFailure(hr, "Failed to write key type for for VirtualDir"); | ||
211 | i = 0x4000003e; // 1073741886; // default directory browsing rights | ||
212 | hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); | ||
213 | ExitOnFailure(hr, "Failed to set directory browsing for VirtualDir"); | ||
214 | |||
215 | hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psvd->wzDirectory); | ||
216 | ExitOnFailure(hr, "Failed to write Directory for VirtualDir"); | ||
217 | |||
218 | if (psvd->fHasProperties) | ||
219 | { | ||
220 | ScaWriteWebDirProperties(piMetabase, psvd->wzVDirRoot, &psvd->swp); | ||
221 | ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); | ||
222 | } | ||
223 | |||
224 | if (psvd->fHasApplication) | ||
225 | { | ||
226 | hr = ScaWriteWebApplication(piMetabase, psvd->wzVDirRoot, &psvd->swapp, psapList); | ||
227 | ExitOnFailure(hr, "Failed to write application for VirtualDir"); | ||
228 | } | ||
229 | |||
230 | if (psvd->psmm) | ||
231 | { | ||
232 | hr = ScaWriteMimeMap(piMetabase, psvd->wzVDirRoot, psvd->psmm); | ||
233 | ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); | ||
234 | } | ||
235 | |||
236 | if (psvd->pshh) | ||
237 | { | ||
238 | hr = ScaWriteHttpHeader(piMetabase, psvd->wzVDirRoot, psvd->pshh); | ||
239 | ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); | ||
240 | } | ||
241 | |||
242 | if (psvd->pswe) | ||
243 | { | ||
244 | hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe); | ||
245 | ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | psvd = psvd->psvdNext; | ||
250 | } | ||
251 | |||
252 | LExit: | ||
253 | return hr; | ||
254 | } | ||
255 | |||
256 | |||
257 | HRESULT ScaVirtualDirsUninstall( | ||
258 | __in IMSAdminBase* piMetabase, | ||
259 | __in SCA_VDIR* psvdList | ||
260 | ) | ||
261 | { | ||
262 | Assert(piMetabase); | ||
263 | |||
264 | HRESULT hr = S_OK; | ||
265 | SCA_VDIR* psvd = psvdList; | ||
266 | |||
267 | while (psvd) | ||
268 | { | ||
269 | if (WcaIsUninstalling(psvd->isInstalled, psvd->isAction)) | ||
270 | { | ||
271 | // delete the application for this virtual directory | ||
272 | if (psvd->fHasApplication) | ||
273 | { | ||
274 | hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); | ||
275 | ExitOnFailure(hr, "Failed to remove application for WebVDir"); | ||
276 | } | ||
277 | |||
278 | if (0 != lstrlenW(psvd->wzVDirRoot)) | ||
279 | { | ||
280 | hr = ScaDeleteMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); | ||
281 | ExitOnFailure(hr, "Failed to remove VirtualDir '%ls' from metabase", psvd->wzKey); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | psvd = psvd->psvdNext; | ||
286 | } | ||
287 | |||
288 | LExit: | ||
289 | return hr; | ||
290 | } | ||
291 | |||
292 | |||
293 | void ScaVirtualDirsFreeList( | ||
294 | __in SCA_VDIR* psvdList | ||
295 | ) | ||
296 | { | ||
297 | SCA_VDIR* psvdDelete = psvdList; | ||
298 | while (psvdList) | ||
299 | { | ||
300 | psvdDelete = psvdList; | ||
301 | psvdList = psvdList->psvdNext; | ||
302 | |||
303 | if (psvdDelete->psmm) | ||
304 | { | ||
305 | ScaMimeMapFreeList(psvdDelete->psmm); | ||
306 | } | ||
307 | |||
308 | if (psvdDelete->pswe) | ||
309 | { | ||
310 | ScaWebErrorFreeList(psvdDelete->pswe); | ||
311 | } | ||
312 | |||
313 | MemFree(psvdDelete); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | |||
318 | static HRESULT AddVirtualDirToList( | ||
319 | __in SCA_VDIR** ppsvdList | ||
320 | ) | ||
321 | { | ||
322 | HRESULT hr = S_OK; | ||
323 | SCA_VDIR* psvd = static_cast<SCA_VDIR*>(MemAlloc(sizeof(SCA_VDIR), TRUE)); | ||
324 | ExitOnNull(psvd, hr, E_OUTOFMEMORY, "failed to allocate memory for new vdir list element"); | ||
325 | |||
326 | psvd->psvdNext= *ppsvdList; | ||
327 | *ppsvdList = psvd; | ||
328 | |||
329 | LExit: | ||
330 | return hr; | ||
331 | } | ||