diff options
author | Rob Mensching <rob@firegiant.com> | 2017-09-03 11:22:38 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-09-03 13:33:33 -0700 |
commit | 5d8375007754101ff2889d0e79486c8f9b7cf5ab (patch) | |
tree | a76d6fb6a38dd9f04a93ffcfd9d64e76779b3414 /src/dutil/iis7util.cpp | |
parent | 8e8da6dbc051ec884b5d439bb4f44dc027d05bbf (diff) | |
download | wix-5d8375007754101ff2889d0e79486c8f9b7cf5ab.tar.gz wix-5d8375007754101ff2889d0e79486c8f9b7cf5ab.tar.bz2 wix-5d8375007754101ff2889d0e79486c8f9b7cf5ab.zip |
Initial commit
Diffstat (limited to 'src/dutil/iis7util.cpp')
-rw-r--r-- | src/dutil/iis7util.cpp | 518 |
1 files changed, 518 insertions, 0 deletions
diff --git a/src/dutil/iis7util.cpp b/src/dutil/iis7util.cpp new file mode 100644 index 00000000..04165a8d --- /dev/null +++ b/src/dutil/iis7util.cpp | |||
@@ -0,0 +1,518 @@ | |||
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 | #include "iis7util.h" | ||
5 | |||
6 | #define ISSTRINGVARIANT(vt) (VT_BSTR == vt || VT_LPWSTR == vt) | ||
7 | |||
8 | extern "C" HRESULT DAPI Iis7PutPropertyVariant( | ||
9 | __in IAppHostElement *pElement, | ||
10 | __in LPCWSTR wzPropName, | ||
11 | __in VARIANT vtPut | ||
12 | ) | ||
13 | { | ||
14 | HRESULT hr = S_OK; | ||
15 | IAppHostProperty *pProperty = NULL; | ||
16 | BSTR bstrPropName = NULL; | ||
17 | |||
18 | bstrPropName = ::SysAllocString(wzPropName); | ||
19 | ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "failed SysAllocString"); | ||
20 | |||
21 | hr = pElement->GetPropertyByName(bstrPropName, &pProperty); | ||
22 | ExitOnFailure(hr, "Failed to get property object for %ls", wzPropName); | ||
23 | |||
24 | hr = pProperty->put_Value(vtPut); | ||
25 | ExitOnFailure(hr, "Failed to set property value for %ls", wzPropName); | ||
26 | |||
27 | LExit: | ||
28 | ReleaseBSTR(bstrPropName); | ||
29 | // caller responsible for cleaning up variant vtPut | ||
30 | ReleaseObject(pProperty); | ||
31 | |||
32 | return hr; | ||
33 | } | ||
34 | |||
35 | extern "C" HRESULT DAPI Iis7PutPropertyString( | ||
36 | __in IAppHostElement *pElement, | ||
37 | __in LPCWSTR wzPropName, | ||
38 | __in LPCWSTR wzString | ||
39 | ) | ||
40 | { | ||
41 | HRESULT hr = S_OK; | ||
42 | VARIANT vtPut; | ||
43 | |||
44 | ::VariantInit(&vtPut); | ||
45 | vtPut.vt = VT_BSTR; | ||
46 | vtPut.bstrVal = ::SysAllocString(wzString); | ||
47 | ExitOnNull(vtPut.bstrVal, hr, E_OUTOFMEMORY, "failed SysAllocString"); | ||
48 | |||
49 | hr = Iis7PutPropertyVariant(pElement, wzPropName, vtPut); | ||
50 | |||
51 | LExit: | ||
52 | ReleaseVariant(vtPut); | ||
53 | |||
54 | return hr; | ||
55 | } | ||
56 | |||
57 | extern "C" HRESULT DAPI Iis7PutPropertyInteger( | ||
58 | __in IAppHostElement *pElement, | ||
59 | __in LPCWSTR wzPropName, | ||
60 | __in DWORD dValue | ||
61 | ) | ||
62 | { | ||
63 | VARIANT vtPut; | ||
64 | |||
65 | ::VariantInit(&vtPut); | ||
66 | vtPut.vt = VT_I4; | ||
67 | vtPut.lVal = dValue; | ||
68 | return Iis7PutPropertyVariant(pElement, wzPropName, vtPut); | ||
69 | } | ||
70 | |||
71 | extern "C" HRESULT DAPI Iis7PutPropertyBool( | ||
72 | __in IAppHostElement *pElement, | ||
73 | __in LPCWSTR wzPropName, | ||
74 | __in BOOL fValue) | ||
75 | { | ||
76 | VARIANT vtPut; | ||
77 | |||
78 | ::VariantInit(&vtPut); | ||
79 | vtPut.vt = VT_BOOL; | ||
80 | vtPut.boolVal = (fValue == FALSE) ? VARIANT_FALSE : VARIANT_TRUE; | ||
81 | return Iis7PutPropertyVariant(pElement, wzPropName, vtPut); | ||
82 | } | ||
83 | |||
84 | extern "C" HRESULT DAPI Iis7GetPropertyVariant( | ||
85 | __in IAppHostElement *pElement, | ||
86 | __in LPCWSTR wzPropName, | ||
87 | __in VARIANT* vtGet | ||
88 | ) | ||
89 | { | ||
90 | HRESULT hr = S_OK; | ||
91 | IAppHostProperty *pProperty = NULL; | ||
92 | BSTR bstrPropName = NULL; | ||
93 | |||
94 | bstrPropName = ::SysAllocString(wzPropName); | ||
95 | ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "failed SysAllocString"); | ||
96 | |||
97 | hr = pElement->GetPropertyByName(bstrPropName, &pProperty); | ||
98 | ExitOnFailure(hr, "Failed to get property object for %ls", wzPropName); | ||
99 | |||
100 | hr = pProperty->get_Value(vtGet); | ||
101 | ExitOnFailure(hr, "Failed to get property value for %ls", wzPropName); | ||
102 | |||
103 | LExit: | ||
104 | ReleaseBSTR(bstrPropName); | ||
105 | // caller responsible for cleaning up variant vtGet | ||
106 | ReleaseObject(pProperty); | ||
107 | |||
108 | return hr; | ||
109 | } | ||
110 | |||
111 | extern "C" HRESULT DAPI Iis7GetPropertyString( | ||
112 | __in IAppHostElement *pElement, | ||
113 | __in LPCWSTR wzPropName, | ||
114 | __in LPWSTR* psczGet | ||
115 | ) | ||
116 | { | ||
117 | HRESULT hr = S_OK; | ||
118 | VARIANT vtGet; | ||
119 | |||
120 | ::VariantInit(&vtGet); | ||
121 | hr = Iis7GetPropertyVariant(pElement, wzPropName, &vtGet); | ||
122 | ExitOnFailure(hr, "Failed to get iis7 property variant with name: %ls", wzPropName); | ||
123 | |||
124 | if (!ISSTRINGVARIANT(vtGet.vt)) | ||
125 | { | ||
126 | hr = E_UNEXPECTED; | ||
127 | ExitOnFailure(hr, "Tried to get property as a string, but type was %d instead.", vtGet.vt); | ||
128 | } | ||
129 | |||
130 | hr = StrAllocString(psczGet, vtGet.bstrVal, 0); | ||
131 | |||
132 | LExit: | ||
133 | ReleaseVariant(vtGet); | ||
134 | |||
135 | return hr; | ||
136 | } | ||
137 | |||
138 | BOOL DAPI CompareVariantDefault( | ||
139 | __in VARIANT* pVariant1, | ||
140 | __in VARIANT* pVariant2 | ||
141 | ) | ||
142 | { | ||
143 | BOOL fEqual = FALSE; | ||
144 | |||
145 | switch (pVariant1->vt) | ||
146 | { | ||
147 | // VarCmp doesn't work for unsigned ints | ||
148 | // We'd like to allow signed/unsigned comparison as well since | ||
149 | // IIS doesn't document variant type for integer fields | ||
150 | case VT_I1: | ||
151 | case VT_UI1: | ||
152 | if (VT_I1 == pVariant2->vt || VT_UI1 == pVariant2->vt) | ||
153 | { | ||
154 | fEqual = pVariant1->bVal == pVariant2->bVal; | ||
155 | } | ||
156 | break; | ||
157 | case VT_I2: | ||
158 | case VT_UI2: | ||
159 | if (VT_I2 == pVariant2->vt || VT_UI2 == pVariant2->vt) | ||
160 | { | ||
161 | fEqual = pVariant1->uiVal == pVariant2->uiVal; | ||
162 | } | ||
163 | break; | ||
164 | case VT_UI4: | ||
165 | case VT_I4: | ||
166 | if (VT_I4 == pVariant2->vt || VT_UI4 == pVariant2->vt) | ||
167 | { | ||
168 | fEqual = pVariant1->ulVal == pVariant2->ulVal; | ||
169 | } | ||
170 | break; | ||
171 | case VT_UI8: | ||
172 | case VT_I8: | ||
173 | if (VT_I8 == pVariant2->vt || VT_UI8 == pVariant2->vt) | ||
174 | { | ||
175 | fEqual = pVariant1->ullVal == pVariant2->ullVal; | ||
176 | } | ||
177 | break; | ||
178 | default: | ||
179 | fEqual = VARCMP_EQ == ::VarCmp(pVariant1, | ||
180 | pVariant2, | ||
181 | LOCALE_INVARIANT, | ||
182 | NORM_IGNORECASE); | ||
183 | } | ||
184 | |||
185 | return fEqual; | ||
186 | } | ||
187 | |||
188 | BOOL DAPI CompareVariantPath( | ||
189 | __in VARIANT* pVariant1, | ||
190 | __in VARIANT* pVariant2 | ||
191 | ) | ||
192 | { | ||
193 | HRESULT hr = S_OK; | ||
194 | BOOL fEqual = FALSE; | ||
195 | LPWSTR wzValue1 = NULL; | ||
196 | LPWSTR wzValue2 = NULL; | ||
197 | |||
198 | if (ISSTRINGVARIANT(pVariant1->vt)) | ||
199 | { | ||
200 | hr = PathExpand(&wzValue1, pVariant1->bstrVal, PATH_EXPAND_ENVIRONMENT | PATH_EXPAND_FULLPATH); | ||
201 | ExitOnFailure(hr, "Failed to expand path %ls", pVariant1->bstrVal); | ||
202 | } | ||
203 | |||
204 | if (ISSTRINGVARIANT(pVariant2->vt)) | ||
205 | { | ||
206 | hr = PathExpand(&wzValue2, pVariant2->bstrVal, PATH_EXPAND_ENVIRONMENT | PATH_EXPAND_FULLPATH); | ||
207 | ExitOnFailure(hr, "Failed to expand path %ls", pVariant2->bstrVal); | ||
208 | } | ||
209 | |||
210 | fEqual = CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzValue1, -1, wzValue2, -1); | ||
211 | |||
212 | LExit: | ||
213 | ReleaseNullStr(wzValue1); | ||
214 | ReleaseNullStr(wzValue2); | ||
215 | return fEqual; | ||
216 | } | ||
217 | |||
218 | BOOL DAPI IsMatchingAppHostElementCallback( | ||
219 | __in IAppHostElement *pElement, | ||
220 | __in_bcount(sizeof(IIS7_APPHOSTELEMENTCOMPARISON)) LPVOID pContext | ||
221 | ) | ||
222 | { | ||
223 | IIS7_APPHOSTELEMENTCOMPARISON* pComparison = (IIS7_APPHOSTELEMENTCOMPARISON*) pContext; | ||
224 | |||
225 | return Iis7IsMatchingAppHostElement(pElement, pComparison); | ||
226 | } | ||
227 | |||
228 | extern "C" BOOL DAPI Iis7IsMatchingAppHostElement( | ||
229 | __in IAppHostElement *pElement, | ||
230 | __in IIS7_APPHOSTELEMENTCOMPARISON* pComparison | ||
231 | ) | ||
232 | { | ||
233 | HRESULT hr = S_OK; | ||
234 | BOOL fResult = FALSE; | ||
235 | IAppHostProperty *pProperty = NULL; | ||
236 | BSTR bstrElementName = NULL; | ||
237 | |||
238 | VARIANT vPropValue; | ||
239 | ::VariantInit(&vPropValue); | ||
240 | |||
241 | // Use the default comparator if a comparator is not specified | ||
242 | VARIANTCOMPARATORPROC pComparator = pComparison->pComparator ? pComparison->pComparator : CompareVariantDefault; | ||
243 | |||
244 | hr = pElement->get_Name(&bstrElementName); | ||
245 | ExitOnFailure(hr, "Failed to get name of element"); | ||
246 | if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pComparison->sczElementName, -1, bstrElementName, -1)) | ||
247 | { | ||
248 | ExitFunction(); | ||
249 | } | ||
250 | |||
251 | hr = Iis7GetPropertyVariant(pElement, pComparison->sczAttributeName, &vPropValue); | ||
252 | ExitOnFailure(hr, "Failed to get value of %ls attribute of %ls element", pComparison->sczAttributeName, pComparison->sczElementName); | ||
253 | |||
254 | if (TRUE == pComparator(pComparison->pvAttributeValue, &vPropValue)) | ||
255 | { | ||
256 | fResult = TRUE; | ||
257 | } | ||
258 | |||
259 | LExit: | ||
260 | ReleaseBSTR(bstrElementName); | ||
261 | ReleaseVariant(vPropValue); | ||
262 | ReleaseObject(pProperty); | ||
263 | |||
264 | return fResult; | ||
265 | } | ||
266 | |||
267 | BOOL DAPI IsMatchingAppHostMethod( | ||
268 | __in IAppHostMethod *pMethod, | ||
269 | __in LPCWSTR wzMethodName | ||
270 | ) | ||
271 | { | ||
272 | HRESULT hr = S_OK; | ||
273 | BOOL fResult = FALSE; | ||
274 | BSTR bstrName = NULL; | ||
275 | |||
276 | hr = pMethod->get_Name(&bstrName); | ||
277 | ExitOnFailure(hr, "Failed to get name of element"); | ||
278 | |||
279 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzMethodName, -1, bstrName, -1)) | ||
280 | { | ||
281 | fResult = TRUE; | ||
282 | } | ||
283 | |||
284 | LExit: | ||
285 | ReleaseBSTR(bstrName); | ||
286 | |||
287 | return fResult; | ||
288 | } | ||
289 | |||
290 | extern "C" HRESULT DAPI Iis7FindAppHostElementPath( | ||
291 | __in IAppHostElementCollection *pCollection, | ||
292 | __in LPCWSTR wzElementName, | ||
293 | __in LPCWSTR wzAttributeName, | ||
294 | __in LPCWSTR wzAttributeValue, | ||
295 | __out IAppHostElement** ppElement, | ||
296 | __out DWORD* pdwIndex | ||
297 | ) | ||
298 | { | ||
299 | HRESULT hr = S_OK; | ||
300 | IIS7_APPHOSTELEMENTCOMPARISON comparison = { }; | ||
301 | VARIANT vtValue = { }; | ||
302 | ::VariantInit(&vtValue); | ||
303 | |||
304 | vtValue.vt = VT_BSTR; | ||
305 | vtValue.bstrVal = ::SysAllocString(wzAttributeValue); | ||
306 | ExitOnNull(vtValue.bstrVal, hr, E_OUTOFMEMORY, "failed SysAllocString"); | ||
307 | |||
308 | comparison.sczElementName = wzElementName; | ||
309 | comparison.sczAttributeName = wzAttributeName; | ||
310 | comparison.pvAttributeValue = &vtValue; | ||
311 | comparison.pComparator = CompareVariantPath; | ||
312 | |||
313 | hr = Iis7EnumAppHostElements(pCollection, | ||
314 | IsMatchingAppHostElementCallback, | ||
315 | &comparison, | ||
316 | ppElement, | ||
317 | pdwIndex); | ||
318 | |||
319 | LExit: | ||
320 | ReleaseVariant(vtValue); | ||
321 | |||
322 | return hr; | ||
323 | } | ||
324 | |||
325 | extern "C" HRESULT DAPI Iis7FindAppHostElementString( | ||
326 | __in IAppHostElementCollection *pCollection, | ||
327 | __in LPCWSTR wzElementName, | ||
328 | __in LPCWSTR wzAttributeName, | ||
329 | __in LPCWSTR wzAttributeValue, | ||
330 | __out IAppHostElement** ppElement, | ||
331 | __out DWORD* pdwIndex | ||
332 | ) | ||
333 | { | ||
334 | HRESULT hr = S_OK; | ||
335 | VARIANT vtValue; | ||
336 | ::VariantInit(&vtValue); | ||
337 | |||
338 | vtValue.vt = VT_BSTR; | ||
339 | vtValue.bstrVal = ::SysAllocString(wzAttributeValue); | ||
340 | ExitOnNull(vtValue.bstrVal, hr, E_OUTOFMEMORY, "failed SysAllocString"); | ||
341 | |||
342 | hr = Iis7FindAppHostElementVariant(pCollection, | ||
343 | wzElementName, | ||
344 | wzAttributeName, | ||
345 | &vtValue, | ||
346 | ppElement, | ||
347 | pdwIndex); | ||
348 | |||
349 | LExit: | ||
350 | ReleaseVariant(vtValue); | ||
351 | |||
352 | return hr; | ||
353 | } | ||
354 | |||
355 | extern "C" HRESULT DAPI Iis7FindAppHostElementInteger( | ||
356 | __in IAppHostElementCollection *pCollection, | ||
357 | __in LPCWSTR wzElementName, | ||
358 | __in LPCWSTR wzAttributeName, | ||
359 | __in DWORD dwAttributeValue, | ||
360 | __out IAppHostElement** ppElement, | ||
361 | __out DWORD* pdwIndex | ||
362 | ) | ||
363 | { | ||
364 | HRESULT hr = S_OK; | ||
365 | VARIANT vtValue; | ||
366 | ::VariantInit(&vtValue); | ||
367 | |||
368 | vtValue.vt = VT_UI4; | ||
369 | vtValue.ulVal = dwAttributeValue; | ||
370 | |||
371 | hr = Iis7FindAppHostElementVariant(pCollection, | ||
372 | wzElementName, | ||
373 | wzAttributeName, | ||
374 | &vtValue, | ||
375 | ppElement, | ||
376 | pdwIndex); | ||
377 | |||
378 | ReleaseVariant(vtValue); | ||
379 | |||
380 | return hr; | ||
381 | } | ||
382 | |||
383 | extern "C" HRESULT DAPI Iis7FindAppHostElementVariant( | ||
384 | __in IAppHostElementCollection *pCollection, | ||
385 | __in LPCWSTR wzElementName, | ||
386 | __in LPCWSTR wzAttributeName, | ||
387 | __in VARIANT* pvAttributeValue, | ||
388 | __out IAppHostElement** ppElement, | ||
389 | __out DWORD* pdwIndex | ||
390 | ) | ||
391 | { | ||
392 | IIS7_APPHOSTELEMENTCOMPARISON comparison = { }; | ||
393 | comparison.sczElementName = wzElementName; | ||
394 | comparison.sczAttributeName = wzAttributeName; | ||
395 | comparison.pvAttributeValue = pvAttributeValue; | ||
396 | comparison.pComparator = CompareVariantDefault; | ||
397 | |||
398 | return Iis7EnumAppHostElements(pCollection, | ||
399 | IsMatchingAppHostElementCallback, | ||
400 | &comparison, | ||
401 | ppElement, | ||
402 | pdwIndex); | ||
403 | } | ||
404 | |||
405 | extern "C" HRESULT DAPI Iis7EnumAppHostElements( | ||
406 | __in IAppHostElementCollection *pCollection, | ||
407 | __in ENUMAPHOSTELEMENTPROC pCallback, | ||
408 | __in LPVOID pContext, | ||
409 | __out IAppHostElement** ppElement, | ||
410 | __out DWORD* pdwIndex | ||
411 | ) | ||
412 | { | ||
413 | HRESULT hr = S_OK; | ||
414 | IAppHostElement *pElement = NULL; | ||
415 | DWORD dwElements = 0; | ||
416 | |||
417 | VARIANT vtIndex; | ||
418 | ::VariantInit(&vtIndex); | ||
419 | |||
420 | if (NULL != ppElement) | ||
421 | { | ||
422 | *ppElement = NULL; | ||
423 | } | ||
424 | if (NULL != pdwIndex) | ||
425 | { | ||
426 | *pdwIndex = MAXDWORD; | ||
427 | } | ||
428 | |||
429 | hr = pCollection->get_Count(&dwElements); | ||
430 | ExitOnFailure(hr, "Failed get application IAppHostElementCollection count"); | ||
431 | |||
432 | vtIndex.vt = VT_UI4; | ||
433 | for (DWORD i = 0; i < dwElements; ++i) | ||
434 | { | ||
435 | vtIndex.ulVal = i; | ||
436 | hr = pCollection->get_Item(vtIndex , &pElement); | ||
437 | ExitOnFailure(hr, "Failed get IAppHostElement element"); | ||
438 | |||
439 | if (pCallback(pElement, pContext)) | ||
440 | { | ||
441 | if (NULL != ppElement) | ||
442 | { | ||
443 | *ppElement = pElement; | ||
444 | pElement = NULL; | ||
445 | } | ||
446 | if (NULL != pdwIndex) | ||
447 | { | ||
448 | *pdwIndex = i; | ||
449 | } | ||
450 | break; | ||
451 | } | ||
452 | |||
453 | ReleaseNullObject(pElement); | ||
454 | } | ||
455 | |||
456 | LExit: | ||
457 | ReleaseObject(pElement); | ||
458 | ReleaseVariant(vtIndex); | ||
459 | |||
460 | return hr; | ||
461 | } | ||
462 | |||
463 | extern "C" HRESULT DAPI Iis7FindAppHostMethod( | ||
464 | __in IAppHostMethodCollection *pCollection, | ||
465 | __in LPCWSTR wzMethodName, | ||
466 | __out IAppHostMethod** ppMethod, | ||
467 | __out DWORD* pdwIndex | ||
468 | ) | ||
469 | { | ||
470 | HRESULT hr = S_OK; | ||
471 | IAppHostMethod *pMethod = NULL; | ||
472 | DWORD dwMethods = 0; | ||
473 | |||
474 | VARIANT vtIndex; | ||
475 | ::VariantInit(&vtIndex); | ||
476 | |||
477 | if (NULL != ppMethod) | ||
478 | { | ||
479 | *ppMethod = NULL; | ||
480 | } | ||
481 | if (NULL != pdwIndex) | ||
482 | { | ||
483 | *pdwIndex = MAXDWORD; | ||
484 | } | ||
485 | |||
486 | hr = pCollection->get_Count(&dwMethods); | ||
487 | ExitOnFailure(hr, "Failed get application IAppHostMethodCollection count"); | ||
488 | |||
489 | vtIndex.vt = VT_UI4; | ||
490 | for (DWORD i = 0; i < dwMethods; ++i) | ||
491 | { | ||
492 | vtIndex.ulVal = i; | ||
493 | hr = pCollection->get_Item(vtIndex , &pMethod); | ||
494 | ExitOnFailure(hr, "Failed get IAppHostMethod element"); | ||
495 | |||
496 | if (IsMatchingAppHostMethod(pMethod, wzMethodName)) | ||
497 | { | ||
498 | if (NULL != ppMethod) | ||
499 | { | ||
500 | *ppMethod = pMethod; | ||
501 | pMethod = NULL; | ||
502 | } | ||
503 | if (NULL != pdwIndex) | ||
504 | { | ||
505 | *pdwIndex = i; | ||
506 | } | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | ReleaseNullObject(pMethod); | ||
511 | } | ||
512 | |||
513 | LExit: | ||
514 | ReleaseObject(pMethod); | ||
515 | ReleaseVariant(vtIndex); | ||
516 | |||
517 | return hr; | ||
518 | } | ||