aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Iis/ca/scaapppool.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-04 22:48:12 -0700
committerRob Mensching <rob@firegiant.com>2021-05-04 22:48:12 -0700
commit7c8e34de56b3348c5a421cd0cced183e1394c5c7 (patch)
treec2f17867b49e33e0833eae2e1841a00b009c1a15 /src/ext/Iis/ca/scaapppool.cpp
parentc5c87377d99beefe83a3470aab326d12bdf0f8a4 (diff)
downloadwix-7c8e34de56b3348c5a421cd0cced183e1394c5c7.tar.gz
wix-7c8e34de56b3348c5a421cd0cced183e1394c5c7.tar.bz2
wix-7c8e34de56b3348c5a421cd0cced183e1394c5c7.zip
Move Iis.wixext into ext
Diffstat (limited to 'src/ext/Iis/ca/scaapppool.cpp')
-rw-r--r--src/ext/Iis/ca/scaapppool.cpp594
1 files changed, 594 insertions, 0 deletions
diff --git a/src/ext/Iis/ca/scaapppool.cpp b/src/ext/Iis/ca/scaapppool.cpp
new file mode 100644
index 00000000..781c55ca
--- /dev/null
+++ b/src/ext/Iis/ca/scaapppool.cpp
@@ -0,0 +1,594 @@
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/*------------------------------------------------------------------
6AppPool table:
7
8Column Type Nullable Example Value
9AppPool s72 No TestPool
10Name s72 No "TestPool"
11Component_ s72 No ComponentName
12Attributes i2 No 8 (APATTR_OTHERUSER)
13User_ s72 Yes UserKey
14RecycleMinutes i2 Yes 500
15RecycleRequests i2 Yes 5000
16RecycleTimes s72 Yes "1:45,13:30,22:00"
17IdleTimeout i2 Yes 15
18QueueLimit i2 Yes 500
19CPUMon s72 Yes "65,500,1" (65% CPU usage, 500 minutes, Shutdown Action)
20MaxProc i2 Yes 5
21ManagedRuntimeVersion s72 Yes "v2.0"
22ManagedPipelineMode s72 Yes "Integrated"
23
24Notes:
25RecycleTimes is a comma delimeted list of times. CPUMon is a
26comma delimeted list of the following format:
27<percent CPU usage>,<refress minutes>,<Action>. The values for
28Action are 1 (Shutdown) and 0 (No Action).
29
30------------------------------------------------------------------*/
31
32enum eAppPoolQuery { apqAppPool = 1, apqName, apqComponent, apqAttributes, apqUser, apqRecycleMinutes, apqRecycleRequests, apqRecycleTimes, apqVirtualMemory, apqPrivateMemory, apqIdleTimeout, apqQueueLimit, apqCpuMon, apqMaxProc, apqManagedRuntimeVersion, apqManagedPipelineMode, apqInstalled, apqAction };
33
34enum eComponentAttrQuery { caqComponent = 1, caqAttributes };
35
36// prototypes
37static HRESULT AppPoolExists(
38 __in IMSAdminBase* piMetabase,
39 __in LPCWSTR wzAppPool
40 );
41
42// functions
43
44void ScaAppPoolFreeList(
45 __in SCA_APPPOOL* psapList
46 )
47{
48 SCA_APPPOOL* psapDelete = psapList;
49 while (psapList)
50 {
51 psapDelete = psapList;
52 psapList = psapList->psapNext;
53
54 MemFree(psapDelete);
55 }
56}
57
58
59HRESULT ScaAppPoolRead(
60 __inout SCA_APPPOOL** ppsapList,
61 __in WCA_WRAPQUERY_HANDLE hUserQuery,
62 __inout LPWSTR *ppwzCustomActionData
63 )
64{
65 Assert(ppsapList);
66
67 HRESULT hr = S_OK;
68
69 MSIHANDLE hRec, hRecComp;
70 LPWSTR pwzData = NULL;
71 SCA_APPPOOL* psap = NULL;
72 WCA_WRAPQUERY_HANDLE hAppPoolQuery = NULL;
73 WCA_WRAPQUERY_HANDLE hComponentQuery = NULL;
74
75 hr = WcaBeginUnwrapQuery(&hAppPoolQuery, ppwzCustomActionData);
76 ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead");
77
78 if (0 == WcaGetQueryRecords(hAppPoolQuery))
79 {
80 WcaLog(LOGMSG_VERBOSE, "Skipping ScaAppPoolRead() - required table not present");
81 ExitFunction1(hr = S_FALSE);
82 }
83
84 hr = WcaBeginUnwrapQuery(&hComponentQuery, ppwzCustomActionData);
85 ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead");
86
87 // loop through all the AppPools
88 while (S_OK == (hr = WcaFetchWrappedRecord(hAppPoolQuery, &hRec)))
89 {
90 // Add this record's information into the list of things to process.
91 hr = AddAppPoolToList(ppsapList);
92 ExitOnFailure(hr, "failed to add app pool to app pool list");
93
94 psap = *ppsapList;
95
96 hr = WcaGetRecordString(hRec, apqComponent, &pwzData);
97 ExitOnFailure(hr, "failed to get AppPool.Component");
98
99 if (pwzData && *pwzData)
100 {
101 psap->fHasComponent = TRUE;
102
103 hr = ::StringCchCopyW(psap->wzComponent, countof(psap->wzComponent), pwzData);
104 ExitOnFailure(hr, "failed to copy component name: %ls", pwzData);
105
106 hr = WcaGetRecordInteger(hRec, apqInstalled, (int *)&psap->isInstalled);
107 ExitOnFailure(hr, "Failed to get Component installed state for app pool");
108
109 hr = WcaGetRecordInteger(hRec, apqAction, (int *)&psap->isAction);
110 ExitOnFailure(hr, "Failed to get Component action state for app pool");
111
112 WcaFetchWrappedReset(hComponentQuery);
113 hr = WcaFetchWrappedRecordWhereString(hComponentQuery, caqComponent, psap->wzComponent, &hRecComp);
114 ExitOnFailure(hr, "Failed to fetch Component.Attributes for Component '%ls'", psap->wzComponent);
115
116 hr = WcaGetRecordInteger(hRecComp, caqAttributes, &psap->iCompAttributes);
117 ExitOnFailure(hr, "failed to get Component.Attributes");
118 }
119
120 hr = WcaGetRecordString(hRec, apqAppPool, &pwzData);
121 ExitOnFailure(hr, "failed to get AppPool.AppPool");
122 hr = ::StringCchCopyW(psap->wzAppPool, countof(psap->wzAppPool), pwzData);
123 ExitOnFailure(hr, "failed to copy AppPool name: %ls", pwzData);
124
125 hr = WcaGetRecordString(hRec, apqName, &pwzData);
126 ExitOnFailure(hr, "failed to get AppPool.Name");
127 hr = ::StringCchCopyW(psap->wzName, countof(psap->wzName), pwzData);
128 ExitOnFailure(hr, "failed to copy app pool name: %ls", pwzData);
129 hr = ::StringCchPrintfW(psap->wzKey, countof(psap->wzKey), L"/LM/W3SVC/AppPools/%s", pwzData);
130 ExitOnFailure(hr, "failed to format app pool key name");
131
132 hr = WcaGetRecordInteger(hRec, apqAttributes, &psap->iAttributes);
133 ExitOnFailure(hr, "failed to get AppPool.Attributes");
134
135 hr = WcaGetRecordString(hRec, apqUser, &pwzData);
136 ExitOnFailure(hr, "failed to get AppPool.User");
137 hr = ScaGetUserDeferred(pwzData, hUserQuery, &psap->suUser);
138 ExitOnFailure(hr, "failed to get user: %ls", pwzData);
139
140 hr = WcaGetRecordInteger(hRec, apqRecycleRequests, &psap->iRecycleRequests);
141 ExitOnFailure(hr, "failed to get AppPool.RecycleRequests");
142
143 hr = WcaGetRecordInteger(hRec, apqRecycleMinutes, &psap->iRecycleMinutes);
144 ExitOnFailure(hr, "failed to get AppPool.Minutes");
145
146 hr = WcaGetRecordString(hRec, apqRecycleTimes, &pwzData);
147 ExitOnFailure(hr, "failed to get AppPool.RecycleTimes");
148 hr = ::StringCchCopyW(psap->wzRecycleTimes, countof(psap->wzRecycleTimes), pwzData);
149 ExitOnFailure(hr, "failed to copy recycle value: %ls", pwzData);
150
151 hr = WcaGetRecordInteger(hRec, apqVirtualMemory, &psap->iVirtualMemory);
152 ExitOnFailure(hr, "failed to get AppPool.VirtualMemory");
153
154 hr = WcaGetRecordInteger(hRec, apqPrivateMemory, &psap->iPrivateMemory);
155 ExitOnFailure(hr, "failed to get AppPool.PrivateMemory");
156
157 hr = WcaGetRecordInteger(hRec, apqIdleTimeout, &psap->iIdleTimeout);
158 ExitOnFailure(hr, "failed to get AppPool.IdleTimeout");
159
160 hr = WcaGetRecordInteger(hRec, apqQueueLimit, &psap->iQueueLimit);
161 ExitOnFailure(hr, "failed to get AppPool.QueueLimit");
162
163 hr = WcaGetRecordString(hRec, apqCpuMon, &pwzData);
164 ExitOnFailure(hr, "failed to get AppPool.CPUMon");
165 hr = ::StringCchCopyW(psap->wzCpuMon, countof(psap->wzCpuMon), pwzData);
166 ExitOnFailure(hr, "failed to copy cpu monitor value: %ls", pwzData);
167
168 hr = WcaGetRecordInteger(hRec, apqMaxProc, &psap->iMaxProcesses);
169 ExitOnFailure(hr, "failed to get AppPool.MaxProc");
170
171 hr = WcaGetRecordString(hRec, apqManagedRuntimeVersion, &pwzData);
172 ExitOnFailure(hr, "failed to get AppPool.ManagedRuntimeVersion");
173 hr = ::StringCchCopyW(psap->wzManagedRuntimeVersion, countof(psap->wzManagedRuntimeVersion), pwzData);
174 ExitOnFailure(hr, "failed to copy ManagedRuntimeVersion value: %ls", pwzData);
175
176 hr = WcaGetRecordString(hRec, apqManagedPipelineMode, &pwzData);
177 ExitOnFailure(hr, "failed to get AppPool.ManagedPipelineMode");
178 hr = ::StringCchCopyW(psap->wzManagedPipelineMode, countof(psap->wzManagedPipelineMode), pwzData);
179 ExitOnFailure(hr, "failed to copy ManagedPipelineMode value: %ls", pwzData);
180
181 }
182
183 if (E_NOMOREITEMS == hr)
184 {
185 hr = S_OK;
186 }
187 ExitOnFailure(hr, "failure while processing AppPools");
188
189LExit:
190 WcaFinishUnwrapQuery(hAppPoolQuery);
191 WcaFinishUnwrapQuery(hComponentQuery);
192
193 ReleaseStr(pwzData);
194 return hr;
195}
196
197
198HRESULT ScaFindAppPool(
199 __in IMSAdminBase* piMetabase,
200 __in LPCWSTR wzAppPool,
201 __out_ecount(cchName) LPWSTR wzName,
202 __in DWORD cchName,
203 __in SCA_APPPOOL *psapList
204 )
205{
206 Assert(piMetabase && wzAppPool && *wzAppPool && wzName && *wzName);
207
208 HRESULT hr = S_OK;
209
210 // check memory first
211 SCA_APPPOOL* psap = psapList;
212 for (; psap; psap = psap->psapNext)
213 {
214 if (0 == lstrcmpW(psap->wzAppPool, wzAppPool))
215 {
216 break;
217 }
218 }
219 ExitOnNull(psap, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Could not find the app pool: %ls", wzAppPool);
220
221 // copy the web app pool name
222 hr = ::StringCchCopyW(wzName, cchName, psap->wzName);
223 ExitOnFailure(hr, "failed to copy app pool name while finding app pool: %ls", psap->wzName);
224
225 // if it's not being installed now, check if it exists already
226 if (!psap->fHasComponent)
227 {
228 hr = AppPoolExists(piMetabase, psap->wzName);
229 ExitOnFailure(hr, "failed to check for existence of app pool: %ls", psap->wzName);
230 }
231
232LExit:
233 return hr;
234}
235
236
237static HRESULT AppPoolExists(
238 __in IMSAdminBase* piMetabase,
239 __in LPCWSTR wzAppPool
240 )
241{
242 Assert(piMetabase && wzAppPool && *wzAppPool);
243
244 HRESULT hr = S_OK;
245 WCHAR wzSubKey[METADATA_MAX_NAME_LEN];
246
247 for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex)
248 {
249 hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/AppPools", wzSubKey, dwIndex);
250 if (SUCCEEDED(hr) && 0 == lstrcmpW(wzSubKey, wzAppPool))
251 {
252 hr = S_OK;
253 break;
254 }
255 }
256
257 if (E_NOMOREITEMS == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
258 {
259 hr = S_FALSE;
260 }
261
262 return hr;
263}
264
265
266HRESULT ScaAppPoolInstall(
267 __in IMSAdminBase* piMetabase,
268 __in SCA_APPPOOL* psapList
269 )
270{
271 Assert(piMetabase);
272
273 HRESULT hr = S_OK;
274
275 for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext)
276 {
277 // if we are installing the app pool
278 if (psap->fHasComponent && WcaIsInstalling(psap->isInstalled, psap->isAction))
279 {
280 hr = ScaWriteAppPool(piMetabase, psap);
281 ExitOnFailure(hr, "failed to write AppPool '%ls' to metabase", psap->wzAppPool);
282 }
283 }
284
285LExit:
286 return hr;
287}
288
289
290HRESULT ScaAppPoolUninstall(
291 __in IMSAdminBase* piMetabase,
292 __in SCA_APPPOOL* psapList
293 )
294{
295 Assert(piMetabase);
296
297 HRESULT hr = S_OK;
298
299 for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext)
300 {
301 // if we are uninstalling the app pool
302 if (psap->fHasComponent && WcaIsUninstalling(psap->isInstalled, psap->isAction))
303 {
304 hr = ScaRemoveAppPool(piMetabase, psap);
305 ExitOnFailure(hr, "Failed to remove AppPool '%ls' from metabase", psap->wzAppPool);
306 }
307 }
308
309LExit:
310 return hr;
311}
312
313
314HRESULT ScaWriteAppPool(
315 __in IMSAdminBase* piMetabase,
316 __in SCA_APPPOOL* psap
317 )
318{
319 Assert(piMetabase && psap);
320
321 HRESULT hr = S_OK;
322 DWORD dwIdentity = 0xFFFFFFFF;
323 BOOL fExists = FALSE;
324 LPWSTR pwzValue = NULL;
325 LPWSTR wz = NULL;
326
327 hr = AppPoolExists(piMetabase, psap->wzName);
328 ExitOnFailure(hr, "failed to check if app pool already exists");
329 if (S_FALSE == hr)
330 {
331 // didn't find the AppPool key, so we need to create it
332 hr = ScaCreateMetabaseKey(piMetabase, psap->wzKey, L"");
333 ExitOnFailure(hr, "failed to create AppPool key: %ls", psap->wzKey);
334
335 // mark it as an AppPool
336 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsApplicationPool");
337 ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey);
338
339 // TODO: Make this an Attribute?
340 // set autostart value
341 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_AUTO_START, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)1);
342 ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey);
343 }
344 else
345 {
346 fExists = TRUE;
347 }
348
349 //
350 // Set the AppPool Recycling Tab
351 //
352 if (MSI_NULL_INTEGER != psap->iRecycleMinutes)
353 {
354 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_TIME, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleMinutes));
355 ExitOnFailure(hr, "failed to set periodic restart time");
356 }
357
358 if (MSI_NULL_INTEGER != psap->iRecycleRequests)
359 {
360 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_REQUEST_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleRequests));
361 ExitOnFailure(hr, "failed to set periodic restart request count");
362 }
363
364 if (*psap->wzRecycleTimes)
365 {
366 // Add another NULL' onto pwz since it's a 'MULTISZ'
367 hr = StrAllocString(&pwzValue, psap->wzRecycleTimes, 0);
368 ExitOnFailure(hr, "failed to allocate string for MULTISZ");
369 hr = StrAllocConcat(&pwzValue, L"\0", 1);
370 ExitOnFailure(hr, "failed to add second null to RecycleTime multisz");
371
372 // Replace the commas with NULLs
373 wz = pwzValue;
374 while (NULL != (wz = wcschr(wz, L',')))
375 {
376 *wz = L'\0';
377 ++wz;
378 }
379
380 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_SCHEDULE, METADATA_INHERIT, IIS_MD_UT_SERVER, MULTISZ_METADATA, (LPVOID)pwzValue);
381 ExitOnFailure(hr, "failed to set periodic restart schedule");
382 }
383
384 if (MSI_NULL_INTEGER != psap->iVirtualMemory)
385 {
386 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iVirtualMemory));
387 ExitOnFailure(hr, "failed to set periodic restart memory count");
388 }
389
390 if (MSI_NULL_INTEGER != psap->iPrivateMemory)
391 {
392 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_PRIVATE_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iPrivateMemory));
393 ExitOnFailure(hr, "failed to set periodic restart private memory count");
394 }
395
396
397 //
398 // Set AppPool Performance Tab
399 //
400 if (MSI_NULL_INTEGER != psap->iIdleTimeout)
401 {
402 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDLE_TIMEOUT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iIdleTimeout));
403 ExitOnFailure(hr, "failed to set idle timeout value");
404 }
405
406 if (MSI_NULL_INTEGER != psap->iQueueLimit)
407 {
408 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_UL_APPPOOL_QUEUE_LENGTH, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iQueueLimit));
409 ExitOnFailure(hr, "failed to set request queue limit value");
410 }
411
412 if (*psap->wzCpuMon)
413 {
414 hr = StrAllocString(&pwzValue, psap->wzCpuMon, 0);
415 ExitOnFailure(hr, "failed to allocate CPUMonitor string");
416
417 DWORD dwPercent = 0;
418 DWORD dwRefreshMinutes = 0;
419 DWORD dwAction = 0;
420
421 dwPercent = wcstoul(pwzValue, &wz, 10);
422 if (100 < dwPercent)
423 {
424 ExitOnFailure(hr = E_INVALIDARG, "invalid maximum cpu percentage value: %d", dwPercent);
425 }
426 if (wz && L',' == *wz)
427 {
428 ++wz;
429 dwRefreshMinutes = wcstoul(wz, &wz, 10);
430 if (wz && L',' == *wz)
431 {
432 ++wz;
433 dwAction = wcstoul(wz, &wz, 10);
434 }
435 }
436
437 if (dwPercent)
438 {
439 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_LIMIT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)(dwPercent * 1000)));
440 ExitOnFailure(hr, "failed to set CPU percentage max");
441 }
442 if (dwRefreshMinutes)
443 {
444 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_RESET_INTERVAL, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwRefreshMinutes));
445 ExitOnFailure(hr, "failed to set refresh CPU minutes");
446 }
447 if (dwAction)
448 {
449 // 0 = No Action
450 // 1 = Shutdown
451 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_ACTION, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwAction));
452 ExitOnFailure(hr, "failed to set CPU action");
453 }
454 }
455
456 if (MSI_NULL_INTEGER != psap->iMaxProcesses)
457 {
458 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_MAX_PROCESS_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iMaxProcesses));
459 ExitOnFailure(hr, "failed to set web garden maximum worker processes");
460 }
461
462 // TODO: Health Tab if anyone wants it?
463
464 //
465 // Set the AppPool Identity tab
466 //
467 if (psap->iAttributes & APATTR_NETSERVICE)
468 {
469 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE;
470 }
471 else if (psap->iAttributes & APATTR_LOCSERVICE)
472 {
473 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE;
474 }
475 else if (psap->iAttributes & APATTR_LOCSYSTEM)
476 {
477 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM;
478 }
479 else if (psap->iAttributes & APATTR_OTHERUSER)
480 {
481 if (!*psap->suUser.wzDomain || CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L".", -1))
482 {
483 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NetworkService", -1))
484 {
485 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE;
486 }
487 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalService", -1))
488 {
489 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE;
490 }
491 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalSystem", -1))
492 {
493 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM;
494 }
495 else
496 {
497 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER;
498 }
499 }
500 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L"NT AUTHORITY", -1))
501 {
502 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NETWORK SERVICE", -1))
503 {
504 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE;
505 }
506 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SERVICE", -1))
507 {
508 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE;
509 }
510 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SYSTEM", -1))
511 {
512 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM;
513 }
514 else
515 {
516 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER;
517 }
518 }
519 else
520 {
521 dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER;
522 }
523 }
524
525 if (-1 != dwIdentity)
526 {
527 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDENTITY_TYPE, METADATA_INHERIT , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwIdentity));
528 ExitOnFailure(hr, "failed to set app pool identity");
529
530 if (MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER == dwIdentity)
531 {
532 if (*psap->suUser.wzDomain)
533 {
534 hr = StrAllocFormatted(&pwzValue, L"%s\\%s", psap->suUser.wzDomain, psap->suUser.wzName);
535 ExitOnFailure(hr, "failed to format user name: %ls domain: %ls", psap->suUser.wzName, psap->suUser.wzDomain);
536 }
537 else
538 {
539 hr = StrAllocFormatted(&pwzValue, L"%s", psap->suUser.wzName);
540 ExitOnFailure(hr, "failed to format user name: %ls", psap->suUser.wzName);
541 }
542
543 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_USER_NAME, METADATA_INHERIT , IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pwzValue);
544 ExitOnFailure(hr, "failed to set app pool identity name");
545
546 hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psap->suUser.wzPassword);
547 ExitOnFailure(hr, "failed to set app pool identity password");
548 }
549 }
550
551LExit:
552 ReleaseStr(pwzValue);
553
554 return hr;
555}
556
557
558HRESULT ScaRemoveAppPool(
559 __in IMSAdminBase* piMetabase,
560 __in SCA_APPPOOL* psap
561 )
562{
563 Assert(piMetabase && psap);
564
565 HRESULT hr = S_OK;
566
567 // simply remove the root key and everything else is pulled at the same time
568 if (0 != lstrlenW(psap->wzKey))
569 {
570 hr = ScaDeleteMetabaseKey(piMetabase, psap->wzKey, L"");
571 ExitOnFailure(hr, "failed to delete AppPool key: %ls", psap->wzKey);
572 }
573
574 // TODO: Maybe check to make sure any web sites that are using this AppPool are put back in the 'DefaultAppPool'
575
576LExit:
577 return hr;
578}
579
580
581HRESULT AddAppPoolToList(
582 __in SCA_APPPOOL** ppsapList
583 )
584{
585 HRESULT hr = S_OK;
586 SCA_APPPOOL* psap = static_cast<SCA_APPPOOL*>(MemAlloc(sizeof(SCA_APPPOOL), TRUE));
587 ExitOnNull(psap, hr, E_OUTOFMEMORY, "failed to allocate memory for new element in app pool list");
588
589 psap->psapNext = *ppsapList;
590 *ppsapList = psap;
591
592LExit:
593 return hr;
594}