diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/iis7util.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/iis7util.cpp | 535 |
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 | |||
23 | extern "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 | |||
42 | LExit: | ||
43 | ReleaseBSTR(bstrPropName); | ||
44 | // caller responsible for cleaning up variant vtPut | ||
45 | ReleaseObject(pProperty); | ||
46 | |||
47 | return hr; | ||
48 | } | ||
49 | |||
50 | extern "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 | |||
66 | LExit: | ||
67 | ReleaseVariant(vtPut); | ||
68 | |||
69 | return hr; | ||
70 | } | ||
71 | |||
72 | extern "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 | |||
86 | extern "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 | |||
99 | extern "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 | |||
118 | LExit: | ||
119 | ReleaseBSTR(bstrPropName); | ||
120 | // caller responsible for cleaning up variant vtGet | ||
121 | ReleaseObject(pProperty); | ||
122 | |||
123 | return hr; | ||
124 | } | ||
125 | |||
126 | extern "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 | |||
147 | LExit: | ||
148 | ReleaseVariant(vtGet); | ||
149 | |||
150 | return hr; | ||
151 | } | ||
152 | |||
153 | BOOL 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 | |||
203 | BOOL 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 | |||
227 | LExit: | ||
228 | ReleaseNullStr(wzValue1); | ||
229 | ReleaseNullStr(wzValue2); | ||
230 | return fEqual; | ||
231 | } | ||
232 | |||
233 | BOOL 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 | |||
243 | extern "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 | |||
274 | LExit: | ||
275 | ReleaseBSTR(bstrElementName); | ||
276 | ReleaseVariant(vPropValue); | ||
277 | ReleaseObject(pProperty); | ||
278 | |||
279 | return fResult; | ||
280 | } | ||
281 | |||
282 | BOOL 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 | |||
301 | LExit: | ||
302 | ReleaseBSTR(bstrName); | ||
303 | |||
304 | return fResult; | ||
305 | } | ||
306 | |||
307 | extern "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 | |||
336 | LExit: | ||
337 | ReleaseVariant(vtValue); | ||
338 | |||
339 | return hr; | ||
340 | } | ||
341 | |||
342 | extern "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 | |||
366 | LExit: | ||
367 | ReleaseVariant(vtValue); | ||
368 | |||
369 | return hr; | ||
370 | } | ||
371 | |||
372 | extern "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 | |||
400 | extern "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 | |||
422 | extern "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 | |||
473 | LExit: | ||
474 | ReleaseObject(pElement); | ||
475 | ReleaseVariant(vtIndex); | ||
476 | |||
477 | return hr; | ||
478 | } | ||
479 | |||
480 | extern "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 | |||
530 | LExit: | ||
531 | ReleaseObject(pMethod); | ||
532 | ReleaseVariant(vtIndex); | ||
533 | |||
534 | return hr; | ||
535 | } | ||