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