aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Iis/ca/scamimemap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Iis/ca/scamimemap.cpp')
-rw-r--r--src/ext/Iis/ca/scamimemap.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/ext/Iis/ca/scamimemap.cpp b/src/ext/Iis/ca/scamimemap.cpp
new file mode 100644
index 00000000..8afe99f9
--- /dev/null
+++ b/src/ext/Iis/ca/scamimemap.cpp
@@ -0,0 +1,200 @@
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
5enum eMimeMapQuery { mmqMimeMap = 1, mmqParentType, mmqParentValue,
6 mmqMimeType, mmqExtension};
7
8// prototypes
9static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList);
10
11
12void ScaMimeMapFreeList(SCA_MIMEMAP* psmmList)
13{
14 SCA_MIMEMAP* psmmDelete = psmmList;
15 while (psmmList)
16 {
17 psmmDelete = psmmList;
18 psmmList = psmmList->psmmNext;
19
20 MemFree(psmmDelete);
21 }
22}
23
24
25HRESULT __stdcall ScaMimeMapRead(
26 SCA_MIMEMAP** ppsmmList,
27 __inout LPWSTR *ppwzCustomActionData
28 )
29{
30 HRESULT hr = S_OK;
31 MSIHANDLE hRec;
32 LPWSTR pwzData = NULL;
33 SCA_MIMEMAP* psmm;
34 WCA_WRAPQUERY_HANDLE hWrapQuery = NULL;
35
36 hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData);
37 ExitOnFailure(hr, "Failed to unwrap query for ScaMimeMapRead");
38
39 if (0 == WcaGetQueryRecords(hWrapQuery))
40 {
41 WcaLog(LOGMSG_VERBOSE, "Skipping ScaMimeMapRead() - required table not present");
42 ExitFunction1(hr = S_FALSE);
43 }
44
45 // loop through all the mimemappings
46 while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec)))
47 {
48 hr = AddMimeMapToList(ppsmmList);
49 ExitOnFailure(hr, "failed to add mime map to list");
50
51 psmm = *ppsmmList;
52
53 hr = WcaGetRecordString(hRec, mmqMimeMap, &pwzData);
54 ExitOnFailure(hr, "Failed to get MimeMap.MimeMap");
55 hr = ::StringCchCopyW(psmm->wzMimeMap, countof(psmm->wzMimeMap), pwzData);
56 ExitOnFailure(hr, "Failed to copy mimemap string to mimemap object");
57
58 hr = WcaGetRecordInteger(hRec, mmqParentType, &psmm->iParentType);
59 ExitOnFailure(hr, "Failed to get MimeMap.iParentType");
60
61 hr = WcaGetRecordString(hRec, mmqParentValue, &pwzData);
62 ExitOnFailure(hr, "Failed to get MimeMap.ParentValue");
63 hr = ::StringCchCopyW(psmm->wzParentValue, countof(psmm->wzParentValue), pwzData);
64 ExitOnFailure(hr, "Failed to copy parent value string to mimemap object");
65
66 hr = WcaGetRecordString(hRec, mmqExtension, &pwzData);
67 ExitOnFailure(hr, "Failed to get MimeMap.Extension");
68 hr = ::StringCchCopyW(psmm->wzExtension, countof(psmm->wzExtension), pwzData);
69 ExitOnFailure(hr, "Failed to copy extension string to mimemap object");
70
71 hr = WcaGetRecordString(hRec, mmqMimeType, &pwzData);
72 ExitOnFailure(hr, "Failed to get MimeMap.MimeType");
73 hr = ::StringCchCopyW(psmm->wzMimeType, countof(psmm->wzMimeType), pwzData);
74 ExitOnFailure(hr, "Failed to copy mimetype string to mimemap object");
75 }
76
77 if (E_NOMOREITEMS == hr)
78 hr = S_OK;
79 ExitOnFailure(hr, "Failure while processing mimemappings");
80
81LExit:
82 WcaFinishUnwrapQuery(hWrapQuery);
83
84 ReleaseStr(pwzData);
85
86 return hr;
87}
88
89
90HRESULT ScaGetMimeMap(int iParentType, LPCWSTR wzParentValue, SCA_MIMEMAP **ppsmmList, SCA_MIMEMAP **ppsmmOut)
91{
92 HRESULT hr = S_OK;
93 SCA_MIMEMAP* psmmAdd = NULL;
94 SCA_MIMEMAP* psmmLast = NULL;
95
96 *ppsmmOut = NULL;
97
98 if (!*ppsmmList)
99 return hr;
100
101 SCA_MIMEMAP* psmm = *ppsmmList;
102 while (psmm)
103 {
104 if (iParentType == psmm->iParentType && 0 == lstrcmpW(wzParentValue, psmm->wzParentValue))
105 {
106 // Found a match, take this one out of the list and add it to the matched out list
107 psmmAdd = psmm;
108
109 if (psmmLast)
110 {
111 // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next)
112 psmmLast->psmmNext = psmmAdd->psmmNext;
113 }
114 else
115 {
116 // If we are at the beginning (no psmmLast) update the beginning (since we're taking it)
117 *ppsmmList = psmm->psmmNext;
118 }
119 psmm = psmm->psmmNext; // move on
120
121 // Add the one we've removed to the beginning of the out list
122 psmmAdd->psmmNext = *ppsmmOut;
123 *ppsmmOut = psmmAdd;
124 }
125 else
126 {
127 psmmLast = psmm; // remember the last we that didn't match
128 psmm = psmm->psmmNext; // move on
129 }
130 }
131
132 return hr;
133}
134
135HRESULT ScaMimeMapCheckList(SCA_MIMEMAP* psmmList)
136{
137 if (!psmmList)
138 return S_OK;
139
140 while (psmmList)
141 {
142 WcaLog(LOGMSG_STANDARD, "MimeMapping of %ls with ParentType=%d and ParentValue=%ls not used!", psmmList->wzMimeMap, psmmList->iParentType, psmmList->wzParentValue);
143 psmmList = psmmList->psmmNext;
144 }
145
146 return E_FAIL;
147}
148
149
150HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb,
151 SCA_MIMEMAP* psmmList)
152{
153 HRESULT hr = S_OK;
154
155 WCHAR wzMimeMap[8192];
156 WCHAR *pwzNext = wzMimeMap;
157 const WCHAR *pwzMac = wzMimeMap + countof(wzMimeMap); // used to properly create the MULTI_SZ
158
159 // fill the MULTI_SZ wzMimeMap buffer for the MimeMap attribute
160 ::ZeroMemory(wzMimeMap, sizeof(wzMimeMap));
161
162 for (SCA_MIMEMAP* psmm = psmmList; psmm; psmm = psmm->psmmNext)
163 {
164 hr = ::StringCchPrintfW(pwzNext, max(0, pwzMac - pwzNext), L"%s,%s", psmm->wzExtension, psmm->wzMimeType);
165 ExitOnFailure(hr, "Failed to set MimeMap string");
166
167 pwzNext += lstrlenW(pwzNext) + 1; // reserve space for null
168 Assert(pwzNext <= pwzMac);
169 }
170
171 if (pwzNext != wzMimeMap)
172 {
173 // now write the CustomErrors to the metabase
174 hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_MIME_MAP, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzMimeMap);
175 ExitOnFailure(hr, "Failed to write MimeMap");
176 }
177 else
178 {
179 WcaLog(LOGMSG_VERBOSE, "Skipping ScaWriteMimeMap() - no mappings found.");
180 ExitFunction1(hr = S_FALSE);
181 }
182
183LExit:
184 return hr;
185}
186
187
188static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList)
189{
190 HRESULT hr = S_OK;
191
192 SCA_MIMEMAP* psmm = static_cast<SCA_MIMEMAP*>(MemAlloc(sizeof(SCA_MIMEMAP), TRUE));
193 ExitOnNull(psmm, hr, E_OUTOFMEMORY, "failed to allocate memory for new mime map list element");
194
195 psmm->psmmNext = *ppsmmList;
196 *ppsmmList = psmm;
197
198LExit:
199 return hr;
200}