diff options
Diffstat (limited to 'src/ext/Iis/ca/scaiis.cpp')
-rw-r--r-- | src/ext/Iis/ca/scaiis.cpp | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/src/ext/Iis/ca/scaiis.cpp b/src/ext/Iis/ca/scaiis.cpp new file mode 100644 index 00000000..958051ed --- /dev/null +++ b/src/ext/Iis/ca/scaiis.cpp | |||
@@ -0,0 +1,481 @@ | |||
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 | // globals | ||
6 | LPWSTR vpwzCustomActionData = NULL; | ||
7 | DWORD vdwCustomActionCost = 0; | ||
8 | |||
9 | HRESULT ScaMetabaseTransaction(__in_z LPCWSTR wzBackup) | ||
10 | { | ||
11 | HRESULT hr = S_OK; | ||
12 | |||
13 | // TODO: These functions have been reported to hang IIS (O11:51709). They may have been fixed in IIS6, but if not, need to be re-written the hard way | ||
14 | |||
15 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"StartMetabaseTransaction"), wzBackup, COST_IIS_TRANSACTIONS); | ||
16 | ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); | ||
17 | |||
18 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackMetabaseTransaction"), wzBackup, 0); // rollback cost is irrelevant | ||
19 | ExitOnFailure(hr, "Failed to schedule RollbackMetabaseTransaction"); | ||
20 | |||
21 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CommitMetabaseTransaction"), wzBackup, 0); // commit is free | ||
22 | ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); | ||
23 | |||
24 | LExit: | ||
25 | return hr; | ||
26 | } | ||
27 | |||
28 | |||
29 | HRESULT ScaCreateWeb(IMSAdminBase* piMetabase, LPCWSTR /*wzWeb*/, LPCWSTR wzWebBase) | ||
30 | { | ||
31 | Assert(piMetabase); | ||
32 | |||
33 | HRESULT hr = S_OK; | ||
34 | UINT ui = 0; | ||
35 | |||
36 | hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L""); | ||
37 | ExitOnFailure(hr, "Failed to create web"); | ||
38 | |||
39 | hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebServer"); | ||
40 | ExitOnFailure(hr, "Failed to set key type for web"); | ||
41 | |||
42 | hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Root"); | ||
43 | ExitOnFailure(hr, "Failed to create web root"); | ||
44 | |||
45 | hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); | ||
46 | ExitOnFailure(hr, "Failed to set key type for web root"); | ||
47 | |||
48 | ui = 0x4000003e; // 1073741886; // default directory browsing rights | ||
49 | hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); | ||
50 | ExitOnFailure(hr, "Failed to set directory browsing for web"); | ||
51 | |||
52 | hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Filters"); | ||
53 | ExitOnFailure(hr, "Failed to create web filters root"); | ||
54 | |||
55 | hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilters"); | ||
56 | ExitOnFailure(hr, "Failed to set key for web filters root"); | ||
57 | |||
58 | hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L""); | ||
59 | ExitOnFailure(hr, "Failed to set empty load order for web"); | ||
60 | |||
61 | LExit: | ||
62 | return hr; | ||
63 | } | ||
64 | |||
65 | |||
66 | HRESULT ScaDeleteApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot) | ||
67 | { | ||
68 | Assert(piMetabase); | ||
69 | Unused(piMetabase); | ||
70 | |||
71 | HRESULT hr = S_OK; | ||
72 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
73 | |||
74 | WCHAR* pwzCustomActionData = NULL; | ||
75 | |||
76 | hr = WcaWriteIntegerToCaData(MBA_DELETEAPP, &pwzCustomActionData); | ||
77 | ExitOnFailure(hr, "Failed to add metabase delete app directive to CustomActionData"); | ||
78 | |||
79 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); | ||
80 | ExitOnFailure(hr, "Failed to copy webroot string to key"); | ||
81 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
82 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
83 | |||
84 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEAPP); | ||
85 | ExitOnFailure(hr, "Failed to add ScaDeleteApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEAPP); | ||
86 | |||
87 | LExit: | ||
88 | ReleaseStr(pwzCustomActionData); | ||
89 | |||
90 | return hr; | ||
91 | } | ||
92 | |||
93 | |||
94 | HRESULT ScaCreateApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot, | ||
95 | DWORD dwIsolation) | ||
96 | { | ||
97 | Assert(piMetabase); | ||
98 | Unused(piMetabase); | ||
99 | |||
100 | HRESULT hr = S_OK; | ||
101 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
102 | BOOL fInProc = FALSE; | ||
103 | |||
104 | WCHAR* pwzCustomActionData = NULL; | ||
105 | |||
106 | hr = WcaWriteIntegerToCaData(MBA_CREATEAPP, &pwzCustomActionData); | ||
107 | ExitOnFailure(hr, "Failed to add metabase create app directive to CustomActionData"); | ||
108 | |||
109 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); | ||
110 | ExitOnFailure(hr, "Failed to copy webroot string to key"); | ||
111 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
112 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
113 | |||
114 | if (0 == dwIsolation) | ||
115 | fInProc = TRUE; | ||
116 | else | ||
117 | fInProc = FALSE; | ||
118 | |||
119 | hr = WcaWriteIntegerToCaData(fInProc, &pwzCustomActionData); | ||
120 | ExitOnFailure(hr, "Failed to add isolation value to CustomActionData"); | ||
121 | |||
122 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEAPP); | ||
123 | ExitOnFailure(hr, "Failed to add ScaCreateApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEAPP); | ||
124 | |||
125 | LExit: | ||
126 | ReleaseStr(pwzCustomActionData); | ||
127 | |||
128 | return hr; | ||
129 | } | ||
130 | |||
131 | |||
132 | HRESULT ScaCreateMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, | ||
133 | LPCWSTR wzSubKey) | ||
134 | { | ||
135 | Assert(piMetabase); | ||
136 | Unused(piMetabase); | ||
137 | |||
138 | HRESULT hr = S_OK; | ||
139 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
140 | WCHAR* pwzCustomActionData = NULL; | ||
141 | |||
142 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); | ||
143 | ExitOnFailure(hr, "Failed to copy root key string to key"); | ||
144 | if (L'/' != *(wzKey + lstrlenW(wzRootKey))) | ||
145 | { | ||
146 | hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); | ||
147 | ExitOnFailure(hr, "Failed to concatenate / to key string"); | ||
148 | } | ||
149 | if (wzSubKey && *wzSubKey) | ||
150 | { | ||
151 | if (L'/' == *wzSubKey) | ||
152 | { | ||
153 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); | ||
154 | ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); | ||
159 | ExitOnFailure(hr, "Failed to concatenate subkey to key string"); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | hr = WcaWriteIntegerToCaData(MBA_CREATEKEY, &pwzCustomActionData); | ||
164 | ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); | ||
165 | |||
166 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
167 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
168 | |||
169 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEKEY); | ||
170 | ExitOnFailure(hr, "Failed to add ScaCreateMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEKEY); | ||
171 | |||
172 | LExit: | ||
173 | ReleaseStr(pwzCustomActionData); | ||
174 | |||
175 | return hr; | ||
176 | } | ||
177 | |||
178 | |||
179 | HRESULT ScaDeleteMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, | ||
180 | LPCWSTR wzSubKey) | ||
181 | { | ||
182 | Assert(piMetabase); | ||
183 | Unused(piMetabase); | ||
184 | |||
185 | HRESULT hr = S_OK; | ||
186 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
187 | WCHAR* pwzCustomActionData = NULL; | ||
188 | |||
189 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); | ||
190 | ExitOnFailure(hr, "Failed to copy root key string to key"); | ||
191 | if (L'/' != *(wzKey + lstrlenW(wzRootKey))) | ||
192 | { | ||
193 | hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); | ||
194 | ExitOnFailure(hr, "Failed to concatenate / to key string"); | ||
195 | } | ||
196 | if (*wzSubKey) | ||
197 | { | ||
198 | if (L'/' == *wzSubKey) | ||
199 | { | ||
200 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); | ||
201 | ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); | ||
206 | ExitOnFailure(hr, "Failed to concatenate subkey to key string"); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | hr = WcaWriteIntegerToCaData(MBA_DELETEKEY, &pwzCustomActionData); | ||
211 | ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); | ||
212 | |||
213 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
214 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
215 | |||
216 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEKEY); | ||
217 | ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEKEY); | ||
218 | |||
219 | LExit: | ||
220 | ReleaseStr(pwzCustomActionData); | ||
221 | |||
222 | return hr; | ||
223 | } | ||
224 | |||
225 | |||
226 | HRESULT ScaDeleteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, | ||
227 | LPCWSTR wzSubKey, DWORD dwIdentifier, | ||
228 | DWORD dwDataType) | ||
229 | { | ||
230 | Assert(piMetabase); | ||
231 | Unused(piMetabase); | ||
232 | |||
233 | HRESULT hr = S_OK; | ||
234 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
235 | WCHAR* pwzCustomActionData = NULL; | ||
236 | |||
237 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); | ||
238 | ExitOnFailure(hr, "Failed to copy root key string to key"); | ||
239 | if (L'/' != *(wzKey + lstrlenW(wzRootKey))) | ||
240 | { | ||
241 | hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); | ||
242 | ExitOnFailure(hr, "Failed to concatenate / to key string"); | ||
243 | } | ||
244 | |||
245 | if (wzSubKey && *wzSubKey) | ||
246 | { | ||
247 | if (L'/' == *wzSubKey) | ||
248 | { | ||
249 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); | ||
250 | ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); | ||
251 | } | ||
252 | else | ||
253 | { | ||
254 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); | ||
255 | ExitOnFailure(hr, "Failed to concatenate subkey to key string"); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | hr = WcaWriteIntegerToCaData(MBA_DELETEVALUE, &pwzCustomActionData); | ||
260 | ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); | ||
261 | |||
262 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
263 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
264 | |||
265 | hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); | ||
266 | ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); | ||
267 | |||
268 | hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); | ||
269 | ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); | ||
270 | |||
271 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEVALUE); | ||
272 | ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_DELETEVALUE); | ||
273 | |||
274 | LExit: | ||
275 | ReleaseStr(pwzCustomActionData); | ||
276 | |||
277 | return hr; | ||
278 | } | ||
279 | |||
280 | |||
281 | #pragma prefast(push) | ||
282 | #pragma prefast(disable:25120) // Disable "requires count parameter" warning - we do have a way to distinguish buffer sizes in all situations, | ||
283 | // it just depends on the dwDataType, and there's no way to annotate the situation in SAL | ||
284 | HRESULT ScaWriteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, | ||
285 | LPCWSTR wzSubKey, DWORD dwIdentifier, | ||
286 | DWORD dwAttributes, DWORD dwUserType, | ||
287 | DWORD dwDataType, LPVOID pvData) | ||
288 | #pragma prefast(pop) | ||
289 | { | ||
290 | Assert(piMetabase && (pvData || (DWORD_METADATA == dwDataType))); // pvData may be 0 if it is DWORD data | ||
291 | Unused(piMetabase); | ||
292 | |||
293 | HRESULT hr = S_OK; | ||
294 | WCHAR wzKey[METADATA_MAX_NAME_LEN]; | ||
295 | WCHAR* pwzCustomActionData = NULL; | ||
296 | |||
297 | if (BINARY_METADATA == dwDataType) | ||
298 | { | ||
299 | ExitOnNull(pvData, hr, E_INVALIDARG, "Failed to write binary metadata - no data available to write"); | ||
300 | } | ||
301 | |||
302 | hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); | ||
303 | ExitOnFailure(hr, "Failed to copy root key string to key"); | ||
304 | if (L'/' != *(wzKey + lstrlenW(wzRootKey))) | ||
305 | { | ||
306 | hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); | ||
307 | ExitOnFailure(hr, "Failed to concatenate / to key string"); | ||
308 | } | ||
309 | if (wzSubKey && *wzSubKey) | ||
310 | { | ||
311 | if (L'/' == *wzSubKey) | ||
312 | { | ||
313 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); | ||
314 | ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); | ||
319 | ExitOnFailure(hr, "Failed to concatenate subkey to key string"); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | hr = WcaWriteIntegerToCaData(MBA_WRITEVALUE, &pwzCustomActionData); | ||
324 | ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); | ||
325 | |||
326 | hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); | ||
327 | ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); | ||
328 | |||
329 | hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); | ||
330 | ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); | ||
331 | |||
332 | hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCustomActionData); | ||
333 | ExitOnFailure(hr, "Failed to add metabase attributes to CustomActionData"); | ||
334 | |||
335 | hr = WcaWriteIntegerToCaData(dwUserType, &pwzCustomActionData); | ||
336 | ExitOnFailure(hr, "Failed to add metabase user type to CustomActionData"); | ||
337 | |||
338 | hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); | ||
339 | ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); | ||
340 | |||
341 | switch (dwDataType) | ||
342 | { | ||
343 | case DWORD_METADATA: | ||
344 | hr = WcaWriteIntegerToCaData((DWORD)((DWORD_PTR)pvData), &pwzCustomActionData); | ||
345 | break; | ||
346 | case STRING_METADATA: | ||
347 | hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); | ||
348 | break; | ||
349 | case MULTISZ_METADATA: | ||
350 | { | ||
351 | // change NULLs to unprintable character to create a 'safe' MULTISZ string | ||
352 | LPWSTR pwz = (LPWSTR)pvData; | ||
353 | for (;;) | ||
354 | { | ||
355 | if ('\0' == *pwz) | ||
356 | { | ||
357 | *pwz = MAGIC_MULTISZ_CHAR; | ||
358 | if ('\0' == *(pwz + 1)) // second null back to back means end of string | ||
359 | break; | ||
360 | } | ||
361 | |||
362 | ++pwz; | ||
363 | } | ||
364 | |||
365 | hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); | ||
366 | } | ||
367 | break; | ||
368 | case BINARY_METADATA: | ||
369 | hr = WcaWriteStreamToCaData(((BLOB*) pvData)->pBlobData, ((BLOB*) pvData)->cbSize, &pwzCustomActionData); | ||
370 | break; | ||
371 | default: | ||
372 | hr = E_UNEXPECTED; | ||
373 | } | ||
374 | ExitOnFailure(hr, "Failed to add metabase data to CustomActionData"); | ||
375 | |||
376 | // TODO: maybe look the key up and make sure we're not just writing the same value that already there | ||
377 | |||
378 | hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEVALUE); | ||
379 | ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEVALUE); | ||
380 | |||
381 | LExit: | ||
382 | ReleaseStr(pwzCustomActionData); | ||
383 | |||
384 | return hr; | ||
385 | } | ||
386 | |||
387 | |||
388 | HRESULT ScaAddToIisConfiguration(LPCWSTR pwzData, DWORD dwCost) | ||
389 | { | ||
390 | HRESULT hr = S_OK; | ||
391 | |||
392 | hr = WcaWriteStringToCaData(pwzData, &vpwzCustomActionData); | ||
393 | ExitOnFailure(hr, "failed to add to metabase configuration data string: %ls", pwzData); | ||
394 | |||
395 | vdwCustomActionCost += dwCost; | ||
396 | |||
397 | LExit: | ||
398 | return hr; | ||
399 | } | ||
400 | |||
401 | |||
402 | HRESULT ScaWriteConfigurationScript(__in LPCWSTR pwzCaScriptKey) | ||
403 | { | ||
404 | HRESULT hr = S_OK; | ||
405 | WCA_CASCRIPT_HANDLE hScript = NULL; | ||
406 | LPWSTR pwzHashString = NULL; | ||
407 | BYTE rgbActualHash[SHA1_HASH_LEN] = { }; | ||
408 | DWORD dwHashedBytes = SHA1_HASH_LEN; | ||
409 | |||
410 | // Create CaScript for communication with WriteMetabaseChanges | ||
411 | hr = WcaCaScriptCreate(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzCaScriptKey, FALSE, &hScript); | ||
412 | ExitOnFailure(hr, "Failed to write ca script for WriteMetabaseChanges script."); | ||
413 | |||
414 | if (vpwzCustomActionData && *vpwzCustomActionData) | ||
415 | { | ||
416 | // Write the actual custom action data to the ca script | ||
417 | WcaCaScriptWriteString(hScript, vpwzCustomActionData); | ||
418 | |||
419 | hr = CrypHashBuffer((BYTE*)vpwzCustomActionData, sizeof(vpwzCustomActionData) * sizeof(WCHAR), PROV_RSA_AES, CALG_SHA1, rgbActualHash, dwHashedBytes); | ||
420 | ExitOnFailure(hr, "Failed to calculate hash of CustomAction data."); | ||
421 | |||
422 | hr = StrAlloc(&pwzHashString, ((dwHashedBytes * 2) + 1)); | ||
423 | ExitOnFailure(hr, "Failed to allocate string for script hash"); | ||
424 | |||
425 | hr = StrHexEncode(rgbActualHash, dwHashedBytes, pwzHashString, ((dwHashedBytes * 2) + 1)); | ||
426 | ExitOnFailure(hr, "Failed to convert hash bytes to string."); | ||
427 | |||
428 | WcaLog(LOGMSG_VERBOSE, "Custom action data hash: %ls", pwzHashString); | ||
429 | WcaLog(LOGMSG_TRACEONLY, "Custom action data being written to ca script: %ls", vpwzCustomActionData); | ||
430 | } | ||
431 | else | ||
432 | hr = S_FALSE; | ||
433 | |||
434 | LExit: | ||
435 | // Release the string | ||
436 | ReleaseStr(vpwzCustomActionData); | ||
437 | ReleaseStr(pwzHashString); | ||
438 | |||
439 | // Flush the ca script to disk as best we can | ||
440 | WcaCaScriptFlush(hScript); | ||
441 | |||
442 | WcaCaScriptClose(hScript, WCA_CASCRIPT_CLOSE_PRESERVE); | ||
443 | |||
444 | return hr; | ||
445 | } | ||
446 | |||
447 | |||
448 | HRESULT ScaLoadMetabase(IMSAdminBase** ppiMetabase) | ||
449 | { | ||
450 | HRESULT hr = S_OK; | ||
451 | UINT er = ERROR_SUCCESS; | ||
452 | |||
453 | // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the | ||
454 | // user to still uninstall this package by clicking "Ignore" | ||
455 | do | ||
456 | { | ||
457 | hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)ppiMetabase); | ||
458 | if (FAILED(hr)) | ||
459 | { | ||
460 | WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); | ||
461 | er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); | ||
462 | switch (er) | ||
463 | { | ||
464 | case IDABORT: | ||
465 | ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback | ||
466 | case IDRETRY: | ||
467 | hr = S_FALSE; // hit me, baby, one more time | ||
468 | break; | ||
469 | case IDIGNORE: | ||
470 | hr = S_OK; // pretend everything is okay and bail | ||
471 | break; | ||
472 | default: // For failure on uninstall continue | ||
473 | hr = S_OK; | ||
474 | break; | ||
475 | } | ||
476 | } | ||
477 | } while (S_FALSE == hr); | ||
478 | |||
479 | LExit: | ||
480 | return hr; | ||
481 | } | ||