aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Iis/ca/scavdir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Iis/ca/scavdir.cpp')
-rw-r--r--src/ext/Iis/ca/scavdir.cpp331
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
6static HRESULT AddVirtualDirToList(
7 __in SCA_VDIR** psvdList
8 );
9
10
11HRESULT __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
173LExit:
174 WcaFinishUnwrapQuery(hWrapQuery);
175
176 ReleaseStr(pwzData);
177 return hr;
178}
179
180
181HRESULT 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
252LExit:
253 return hr;
254}
255
256
257HRESULT 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
288LExit:
289 return hr;
290}
291
292
293void 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
318static 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
329LExit:
330 return hr;
331}