Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1718 lines
35 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. w3sht.cpp
  5. Abstract:
  6. WWW Property Sheet
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "common.h"
  18. #include "inetprop.h"
  19. #include "InetMgrApp.h"
  20. #include "shts.h"
  21. #include "w3sht.h"
  22. #include "iisfilt.h"
  23. #include "fltdlg.h"
  24. #include "iisobj.h"
  25. // from pshed.cpp
  26. HRESULT CallINetCfg(BOOL Install);
  27. //
  28. // Help IDs
  29. //
  30. #define HIDD_DIRECTORY_PROPERTIES (IDD_WEB_DIRECTORY_PROPERTIES + 0x20000)
  31. #define HIDD_HOME_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20000)
  32. #define HIDD_FS_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20001)
  33. #define HIDD_FS_FILE_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20002)
  34. //
  35. // Metabase node ID
  36. //
  37. const LPCTSTR g_cszSvc = _T("W3SVC");
  38. const LPCTSTR g_cszFilters = _T("Filters");
  39. const LPCTSTR g_cszSSLKeys = _T("SSLKeys");
  40. //
  41. // Helper Functions
  42. //
  43. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  44. BOOL
  45. IsCertInstalledOnServer(
  46. IN CComAuthInfo * pAuthInfo,
  47. IN LPCTSTR lpszMDPath
  48. )
  49. /*++
  50. Routine Description:
  51. Check to see if a certificate is installed on this virtual server.
  52. This routine only checks that the cert metabase key was read in.
  53. by boydm
  54. Arguments:
  55. None
  56. Return Value:
  57. TRUE if a certificate are installed, FALSE otherwise
  58. --*/
  59. {
  60. CError err;
  61. BOOL fCertInstalled = FALSE;
  62. CW3InstanceProps * ppropInst;
  63. CString strNewPath;
  64. //
  65. // Get the instance properties
  66. //
  67. CMetabasePath::GetInstancePath(lpszMDPath,strNewPath);
  68. ppropInst = new CW3InstanceProps(pAuthInfo, strNewPath);
  69. //
  70. // If it succeeded, load the data, then check the answer
  71. //
  72. if (ppropInst)
  73. {
  74. err = ppropInst->LoadData();
  75. if (err.Succeeded())
  76. {
  77. fCertInstalled = !(MP_V(ppropInst->m_CertHash).IsEmpty());
  78. }
  79. }
  80. //
  81. // Clean up since we don't really need the ppropInst after this.
  82. //
  83. if (ppropInst)
  84. {
  85. delete ppropInst;
  86. ppropInst = NULL;
  87. }
  88. //
  89. // if that test failed. we want to check the metabase key itself
  90. // since the above check is all cached information and won't reflect
  91. // any certificates which are removed/added via scripts, while mmc is open
  92. //
  93. if (!fCertInstalled)
  94. {
  95. CMetaKey key(pAuthInfo,strNewPath,METADATA_PERMISSION_READ);
  96. if (key.Succeeded())
  97. {
  98. CBlob hash;
  99. if (SUCCEEDED(key.QueryValue(MD_SSL_CERT_HASH, hash)))
  100. {
  101. fCertInstalled = TRUE;
  102. }
  103. }
  104. }
  105. //
  106. // If that test failed, we may be admining a downlevel IIS4 machine.
  107. // Unfortunately we can't tell by examining the capability bits,
  108. // so look to see if the old certs are there.
  109. //
  110. if (!fCertInstalled)
  111. {
  112. CString strKey;
  113. CMetaEnumerator me(pAuthInfo, CMetabasePath(SZ_MBN_WEB));
  114. HRESULT err = me.Next(strKey, g_cszSSLKeys);
  115. fCertInstalled = SUCCEEDED(err);
  116. }
  117. return fCertInstalled;
  118. }
  119. //
  120. // CW3InstanceProps implementation
  121. //
  122. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  123. CW3InstanceProps::CW3InstanceProps(
  124. IN CComAuthInfo * pAuthInfo,
  125. IN LPCTSTR lpszMDPath
  126. )
  127. /*++
  128. Routine Description:
  129. Constructor for WWW instance properties
  130. Arguments:
  131. CComAuthInfo * pAuthInfo : COM Authentication info
  132. LPCTSTR lpszMDPath : MD Path
  133. Return Value:
  134. None.
  135. --*/
  136. : CInstanceProps(pAuthInfo, lpszMDPath, 80U),
  137. /**/
  138. m_nMaxConnections(INITIAL_MAX_CONNECTIONS),
  139. m_nConnectionTimeOut((LONG)900L),
  140. m_strlSecureBindings(),
  141. m_dwLogType(MD_LOG_TYPE_DISABLED),
  142. /**/
  143. m_fUseKeepAlives(TRUE),
  144. m_fEnableCPUAccounting(FALSE),
  145. m_nServerSize(MD_SERVER_SIZE_MEDIUM),
  146. m_dwMaxBandwidth(INFINITE_BANDWIDTH),
  147. /**/
  148. m_dwCPULimitLogEventRaw(INFINITE_CPU_RAW),
  149. m_dwCPULimitPriorityRaw(0),
  150. m_dwCPULimitPauseRaw(0),
  151. m_dwCPULimitProcStopRaw(0),
  152. /**/
  153. m_acl(),
  154. /**/
  155. m_dwDownlevelInstance(1),
  156. m_CertHash()
  157. {
  158. //
  159. // Fetch everything
  160. //
  161. m_dwMDUserType = ALL_METADATA;
  162. m_dwMDDataType = ALL_METADATA;
  163. }
  164. /* virtual */
  165. void
  166. CW3InstanceProps::ParseFields()
  167. /*++
  168. Routine Description:
  169. Break into fields.
  170. Arguments:
  171. None.
  172. Return Value:
  173. None.
  174. --*/
  175. {
  176. //
  177. // Fetch base properties
  178. //
  179. CInstanceProps::ParseFields();
  180. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  181. HANDLE_META_RECORD(MD_MAX_GLOBAL_CONNECTIONS, m_nMaxConnections)
  182. HANDLE_META_RECORD(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  183. HANDLE_META_RECORD(MD_SECURE_BINDINGS, m_strlSecureBindings)
  184. HANDLE_META_RECORD(MD_LOG_TYPE, m_dwLogType)
  185. HANDLE_META_RECORD(MD_SERVER_SIZE, m_nServerSize)
  186. HANDLE_META_RECORD(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  187. HANDLE_META_RECORD(MD_MAX_BANDWIDTH, m_dwMaxBandwidth)
  188. HANDLE_META_RECORD(MD_MAX_GLOBAL_BANDWIDTH,m_dwMaxGlobalBandwidth)
  189. HANDLE_META_RECORD(MD_GLOBAL_LOG_IN_UTF_8, m_fLogUTF8)
  190. HANDLE_META_RECORD(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting)
  191. HANDLE_META_RECORD(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw)
  192. HANDLE_META_RECORD(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw)
  193. HANDLE_META_RECORD(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw)
  194. HANDLE_META_RECORD(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw)
  195. HANDLE_META_RECORD(MD_ADMIN_ACL, m_acl)
  196. HANDLE_META_RECORD(MD_DOWNLEVEL_ADMIN_INSTANCE, m_dwDownlevelInstance);
  197. HANDLE_META_RECORD(MD_SSL_CERT_HASH, m_CertHash)
  198. HANDLE_META_RECORD(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
  199. HANDLE_META_RECORD(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  200. HANDLE_META_RECORD(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  201. END_PARSE_META_RECORDS
  202. if (CMetabasePath::IsMasterInstance(QueryMetaRoot()))
  203. {
  204. m_dwMaxBandwidth = m_dwMaxGlobalBandwidth;
  205. }
  206. }
  207. /* virtual */
  208. HRESULT
  209. CW3InstanceProps::WriteDirtyProps()
  210. /*++
  211. Routine Description:
  212. Write the dirty properties to the metabase
  213. Arguments:
  214. None
  215. Return Value:
  216. HRESULT
  217. --*/
  218. {
  219. CError err(CInstanceProps::WriteDirtyProps());
  220. if (err.Failed())
  221. {
  222. return err;
  223. }
  224. BEGIN_META_WRITE()
  225. META_WRITE(MD_MAX_GLOBAL_CONNECTIONS, m_nMaxConnections)
  226. META_WRITE(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  227. META_WRITE(MD_SECURE_BINDINGS, m_strlSecureBindings)
  228. META_WRITE(MD_LOG_TYPE, m_dwLogType)
  229. META_WRITE(MD_SERVER_SIZE, m_nServerSize)
  230. META_WRITE(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  231. META_WRITE(MD_GLOBAL_LOG_IN_UTF_8, m_fLogUTF8)
  232. if (CMetabasePath::IsMasterInstance(QueryMetaRoot()))
  233. {
  234. META_WRITE(MD_MAX_GLOBAL_BANDWIDTH,m_dwMaxBandwidth)
  235. }
  236. else
  237. {
  238. META_WRITE(MD_MAX_BANDWIDTH, m_dwMaxBandwidth)
  239. }
  240. META_WRITE(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting)
  241. META_WRITE(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw)
  242. META_WRITE(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw)
  243. META_WRITE(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw)
  244. META_WRITE(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw)
  245. META_WRITE(MD_ADMIN_ACL, m_acl)
  246. META_WRITE(MD_DOWNLEVEL_ADMIN_INSTANCE, m_dwDownlevelInstance);
  247. //META_WRITE(MD_SSL_CERT_HASH, m_CertHash)
  248. //META_WRITE(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
  249. META_WRITE(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  250. META_WRITE(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  251. END_META_WRITE(err);
  252. if (err.Succeeded())
  253. {
  254. if (m_dwMaxBandwidth == INFINITE_BANDWIDTH && m_fUninstallPSHED)
  255. {
  256. err = CallINetCfg(FALSE);
  257. }
  258. else if (m_dwMaxBandwidth != INFINITE_BANDWIDTH)
  259. {
  260. err = CallINetCfg(TRUE);
  261. }
  262. }
  263. return err;
  264. }
  265. //
  266. // CW3DirProps Implementation
  267. //
  268. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  269. CW3DirProps::CW3DirProps(
  270. IN CComAuthInfo * pAuthInfo,
  271. IN LPCTSTR lpszMDPath
  272. )
  273. /*++
  274. Routine Description:
  275. WWW Directory Properties Constructor
  276. Arguments:
  277. CComAuthInfo * pAuthInfo : COM Authentication info
  278. LPCTSTR lpszMDPath : MD Path
  279. Return Value:
  280. N/A
  281. --*/
  282. : CChildNodeProps(
  283. pAuthInfo,
  284. lpszMDPath,
  285. WITH_INHERITANCE,
  286. FALSE // Complete information
  287. ),
  288. /**/
  289. m_strUserName(),
  290. m_strPassword(),
  291. m_strDefaultDocument(),
  292. m_strFooter(),
  293. m_dwDirBrowsing(0L),
  294. m_fEnableFooter(FALSE),
  295. m_fDontLog(FALSE),
  296. m_fIndexed(FALSE),
  297. /**/
  298. m_strExpiration(),
  299. m_strlCustomHeaders(),
  300. /**/
  301. m_strlCustomErrors(),
  302. /**/
  303. m_strAnonUserName(),
  304. m_strAnonPassword(),
  305. m_fPasswordSync(TRUE),
  306. m_fU2Installed(FALSE),
  307. m_fUseNTMapper(FALSE),
  308. m_dwAuthFlags(MD_AUTH_ANONYMOUS),
  309. m_dwSSLAccessPermissions(0L),
  310. m_strBasicDomain(),
  311. m_strRealm(),
  312. m_ipl()
  313. {
  314. //
  315. // Fetch everything
  316. //
  317. m_dwMDUserType = ALL_METADATA;
  318. m_dwMDDataType = ALL_METADATA;
  319. }
  320. /* virtual */
  321. void
  322. CW3DirProps::ParseFields()
  323. /*++
  324. Routine Description:
  325. Break into fields.
  326. Arguments:
  327. None.
  328. Return Value:
  329. None.
  330. --*/
  331. {
  332. //
  333. // Fetch base properties
  334. //
  335. CChildNodeProps::ParseFields();
  336. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  337. //
  338. // VDir Page
  339. //
  340. HANDLE_META_RECORD(MD_VR_USERNAME, m_strUserName)
  341. HANDLE_META_RECORD(MD_VR_PASSWORD, m_strPassword)
  342. HANDLE_META_RECORD(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument);
  343. HANDLE_META_RECORD(MD_FOOTER_ENABLED, m_fEnableFooter);
  344. HANDLE_META_RECORD(MD_FOOTER_DOCUMENT, m_strFooter);
  345. HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing);
  346. HANDLE_META_RECORD(MD_DONT_LOG, m_fDontLog);
  347. HANDLE_META_RECORD(MD_IS_CONTENT_INDEXED, m_fIndexed);
  348. //
  349. // HTTP Page
  350. //
  351. HANDLE_META_RECORD(MD_HTTP_EXPIRES, m_strExpiration);
  352. HANDLE_META_RECORD(MD_HTTP_CUSTOM, m_strlCustomHeaders);
  353. //
  354. // Custom Errors
  355. //
  356. HANDLE_META_RECORD(MD_CUSTOM_ERROR, m_strlCustomErrors);
  357. //
  358. // Security page
  359. //
  360. HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthFlags);
  361. HANDLE_META_RECORD(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions);
  362. HANDLE_META_RECORD(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain);
  363. HANDLE_META_RECORD(MD_REALM, m_strRealm);
  364. HANDLE_META_RECORD(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  365. HANDLE_META_RECORD(MD_ANONYMOUS_PWD, m_strAnonPassword)
  366. HANDLE_META_RECORD(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  367. HANDLE_META_RECORD(MD_U2_AUTH, m_fU2Installed)
  368. HANDLE_META_RECORD(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper);
  369. HANDLE_META_RECORD(MD_IP_SEC, m_ipl);
  370. END_PARSE_META_RECORDS
  371. }
  372. /* virtual */
  373. HRESULT
  374. CW3DirProps::WriteDirtyProps()
  375. /*++
  376. Routine Description:
  377. Write the dirty properties to the metabase
  378. Arguments:
  379. None
  380. Return Value:
  381. HRESULT
  382. --*/
  383. {
  384. CError err(CChildNodeProps::WriteDirtyProps());
  385. if (err.Failed())
  386. {
  387. return err;
  388. }
  389. //
  390. // CODEWORK: Consider DDX/DDV like methods which do both
  391. // ParseFields and WriteDirtyProps in a single method. Must
  392. // take care not to write data which should only be read, not
  393. // written
  394. //
  395. BEGIN_META_WRITE()
  396. //
  397. // VDir Page
  398. //
  399. META_WRITE(MD_VR_USERNAME, m_strUserName)
  400. META_WRITE(MD_VR_PASSWORD, m_strPassword)
  401. META_WRITE(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument)
  402. META_WRITE(MD_FOOTER_ENABLED, m_fEnableFooter)
  403. META_WRITE(MD_FOOTER_DOCUMENT, m_strFooter)
  404. META_WRITE(MD_DIRECTORY_BROWSING, m_dwDirBrowsing)
  405. META_WRITE(MD_DONT_LOG, m_fDontLog)
  406. META_WRITE(MD_IS_CONTENT_INDEXED, m_fIndexed)
  407. //
  408. // HTTP Page
  409. //
  410. META_WRITE(MD_HTTP_EXPIRES, m_strExpiration)
  411. META_WRITE(MD_HTTP_CUSTOM, m_strlCustomHeaders)
  412. //
  413. // Custom Errors
  414. //
  415. META_WRITE(MD_CUSTOM_ERROR, m_strlCustomErrors)
  416. //
  417. // Security page
  418. //
  419. META_WRITE(MD_AUTHORIZATION, m_dwAuthFlags)
  420. META_WRITE(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions)
  421. META_WRITE(MD_REALM, m_strRealm)
  422. META_WRITE(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain)
  423. META_WRITE(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  424. META_WRITE(MD_ANONYMOUS_PWD, m_strAnonPassword)
  425. META_WRITE(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  426. META_WRITE(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper)
  427. META_WRITE(MD_IP_SEC, m_ipl)
  428. END_META_WRITE(err);
  429. return err;
  430. }
  431. //
  432. // CIISFilter Implementation
  433. //
  434. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  435. CIISFilter::CIISFilter()
  436. /*++
  437. Routine Description:
  438. Filter contructor for a new filter
  439. Arguments:
  440. None
  441. Return Value:
  442. N/A
  443. --*/
  444. : CObjectPlus(),
  445. m_strName(),
  446. //
  447. // Default Values
  448. //
  449. m_strExecutable(),
  450. m_nPriority(FLTR_PR_INVALID),
  451. m_nOrder(-1),
  452. m_dwState(MD_FILTER_STATE_UNLOADED),
  453. m_dwFlags(0L),
  454. m_hrResult(S_OK),
  455. m_dwWin32Error(ERROR_SUCCESS),
  456. m_fEnabled(TRUE),
  457. m_fDirty(FALSE),
  458. m_fFlaggedForDeletion(FALSE)
  459. {
  460. }
  461. CIISFilter::CIISFilter(
  462. IN CMetaKey * pKey,
  463. IN LPCTSTR lpszName
  464. )
  465. /*++
  466. Routine Description:
  467. Fully defined constructor
  468. Arguments:
  469. CMetaKey * pKey : Open key to read from
  470. LPCTSTR lpszName : Name of the filter
  471. Return Value:
  472. N/A
  473. --*/
  474. : m_strName(lpszName),
  475. //
  476. // Default Values
  477. //
  478. m_strExecutable(),
  479. m_nPriority(FLTR_PR_INVALID),
  480. m_nOrder(-1),
  481. m_dwState(MD_FILTER_STATE_UNLOADED),
  482. m_dwFlags(0L),
  483. m_hrResult(S_OK),
  484. m_dwWin32Error(ERROR_SUCCESS),
  485. m_fEnabled(TRUE),
  486. m_fDirty(FALSE),
  487. m_fFlaggedForDeletion(FALSE)
  488. {
  489. ASSERT(pKey != NULL);
  490. m_hrResult = pKey->QueryValue(
  491. MD_FILTER_IMAGE_PATH,
  492. m_strExecutable,
  493. NULL,
  494. m_strName
  495. );
  496. pKey->QueryValue(MD_FILTER_ENABLED, m_fEnabled, NULL, m_strName);
  497. pKey->QueryValue(MD_FILTER_STATE, m_dwState, NULL, m_strName);
  498. pKey->QueryValue(MD_FILTER_FLAGS, m_dwFlags, NULL, m_strName);
  499. if (m_dwFlags & SF_NOTIFY_ORDER_HIGH)
  500. {
  501. m_nPriority = FLTR_PR_HIGH;
  502. }
  503. else if (m_dwFlags & SF_NOTIFY_ORDER_MEDIUM)
  504. {
  505. m_nPriority = FLTR_PR_MEDIUM;
  506. }
  507. else if (m_dwFlags & SF_NOTIFY_ORDER_LOW)
  508. {
  509. m_nPriority = FLTR_PR_LOW;
  510. }
  511. else
  512. {
  513. m_nPriority = FLTR_PR_INVALID;
  514. }
  515. }
  516. CIISFilter::CIISFilter(
  517. IN const CIISFilter & flt
  518. )
  519. /*++
  520. Routine Description:
  521. Copy Constructor
  522. Arguments:
  523. const CIISFilter & flt : Source filter object
  524. Return Value:
  525. N/A
  526. --*/
  527. : m_strName(flt.m_strName),
  528. m_strExecutable(flt.m_strExecutable),
  529. m_nPriority(flt.m_nPriority),
  530. m_nOrder(flt.m_nOrder),
  531. m_hrResult(flt.m_hrResult),
  532. m_dwState(flt.m_dwState),
  533. m_dwFlags(flt.m_dwFlags),
  534. m_dwWin32Error(flt.m_dwWin32Error),
  535. m_fEnabled(flt.m_fEnabled),
  536. m_fDirty(FALSE),
  537. m_fFlaggedForDeletion(FALSE)
  538. {
  539. }
  540. HRESULT
  541. CIISFilter::Write(
  542. IN CMetaKey * pKey
  543. )
  544. /*++
  545. Routine Description:
  546. Write the current value to the metabase
  547. Arguments:
  548. CMetaKey * pKey : Open key
  549. Return Value:
  550. HRESULT
  551. --*/
  552. {
  553. ASSERT(pKey != NULL);
  554. CError err;
  555. CString strKey(_T("IIsFilter"));
  556. err = pKey->SetValue(MD_KEY_TYPE, strKey, NULL, QueryName());
  557. if (err.Succeeded())
  558. {
  559. err = pKey->SetValue(
  560. MD_FILTER_IMAGE_PATH,
  561. m_strExecutable,
  562. NULL,
  563. QueryName()
  564. );
  565. }
  566. return err;
  567. }
  568. int
  569. CIISFilter::OrderByPriority(
  570. IN const CObjectPlus * pobAccess
  571. ) const
  572. /*++
  573. Routine Description:
  574. Compare two filters against each other, and sort on priority first, and
  575. order secondarily.
  576. Arguments:
  577. const CObjectPlus * pobAccess : This really refers to another
  578. CIISFilter to be compared to.
  579. Return Value:
  580. Sort (+1, 0, -1) return value
  581. --*/
  582. {
  583. const CIISFilter * pob = (CIISFilter *)pobAccess;
  584. if (pob->m_nPriority != m_nPriority)
  585. {
  586. return pob->m_nPriority - m_nPriority;
  587. }
  588. //
  589. // Sort by order in reverse order
  590. //
  591. return m_nOrder - pob->m_nOrder;
  592. }
  593. //
  594. // Static initialization
  595. //
  596. const LPCTSTR CIISFilterList::s_lpszSep = _T(",");
  597. //
  598. // CIISFilterList implementation
  599. //
  600. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  601. CIISFilterList::CIISFilterList(
  602. IN CComAuthInfo * pAuthInfo,
  603. IN LPCTSTR lpszMetaPath
  604. )
  605. /*++
  606. Routine Description:
  607. Constructor for filter list
  608. Arguments:
  609. LPCTSTR lpszServerName : Server name
  610. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  611. Return Value:
  612. N/A
  613. --*/
  614. : CMetaKey(
  615. pAuthInfo,
  616. CMetabasePath(FALSE, lpszMetaPath, g_cszFilters),
  617. METADATA_PERMISSION_READ
  618. ),
  619. m_hrResult(S_OK),
  620. m_strFilterOrder(),
  621. m_fFiltersLoaded(FALSE)
  622. {
  623. m_hrResult = CMetaKey::QueryResult();
  624. if (SUCCEEDED(m_hrResult))
  625. {
  626. m_hrResult = QueryValue(MD_FILTER_LOAD_ORDER, m_strFilterOrder);
  627. }
  628. if ( m_hrResult == CError::HResult(ERROR_PATH_NOT_FOUND)
  629. || m_hrResult == MD_ERROR_DATA_NOT_FOUND
  630. )
  631. {
  632. //
  633. // Harmless
  634. //
  635. m_hrResult = S_OK;
  636. }
  637. if (IsOpen())
  638. {
  639. Close();
  640. }
  641. }
  642. HRESULT
  643. CIISFilterList::LoadAllFilters()
  644. /*++
  645. Routine Description:
  646. Loop through the filter order string, and load information
  647. about each filter in turn.
  648. Arguments:
  649. None.
  650. Return Value:
  651. HRESULT. The first error stops filter loading.
  652. --*/
  653. {
  654. ASSERT(SUCCEEDED(m_hrResult));
  655. if (m_fFiltersLoaded)
  656. {
  657. //
  658. // Already done
  659. //
  660. return S_OK;
  661. }
  662. int cItems = 0;
  663. CError err(ReOpen(METADATA_PERMISSION_READ));
  664. if (err.Failed())
  665. {
  666. return err;
  667. }
  668. try
  669. {
  670. CString strSrc(m_strFilterOrder);
  671. LPTSTR lp = strSrc.GetBuffer(0);
  672. while (isspace(*lp) || *lp == (TCHAR)s_lpszSep)
  673. lp++;
  674. lp = _tcstok(lp, s_lpszSep);
  675. int nOrder = 0;
  676. while (lp)
  677. {
  678. CString str(lp);
  679. str.TrimLeft();
  680. str.TrimRight();
  681. TRACEEOLID("Adding filter: " << str);
  682. CIISFilter * pFilter = new CIISFilter(this, str);
  683. err = pFilter->QueryResult();
  684. if (err.Failed())
  685. {
  686. break;
  687. }
  688. pFilter->m_nOrder = nOrder++;
  689. m_oblFilters.AddTail(pFilter);
  690. lp = _tcstok(NULL, s_lpszSep);
  691. ++cItems;
  692. }
  693. //
  694. // Sort filters list
  695. //
  696. m_oblFilters.Sort(
  697. (CObjectPlus::PCOBJPLUS_ORDER_FUNC)
  698. &CIISFilter::OrderByPriority
  699. );
  700. }
  701. catch(CMemoryException * e)
  702. {
  703. e->Delete();
  704. err = ERROR_NOT_ENOUGH_MEMORY;
  705. }
  706. m_fFiltersLoaded = err.Succeeded();
  707. if (IsOpen())
  708. {
  709. Close();
  710. }
  711. return err;
  712. }
  713. HRESULT
  714. CIISFilterList::WriteIfDirty()
  715. /*++
  716. Routine Description:
  717. Write all the changes in the filters list to the metabase
  718. Arguments:
  719. None.
  720. Return Value:
  721. HRESULT
  722. --*/
  723. {
  724. CError err;
  725. CString strNewOrder;
  726. VERIFY(BuildFilterOrderString(strNewOrder));
  727. //
  728. // Check to see if this new list is different
  729. //
  730. if (!strNewOrder.CompareNoCase(m_strFilterOrder) && !HasDirtyFilter())
  731. {
  732. //
  733. // The priority list hasn't changed, and no filter is marked
  734. // as dirty, so all done.
  735. //
  736. return err;
  737. }
  738. //
  739. // It's dirty -- save it
  740. //
  741. do
  742. {
  743. err = ReOpen(METADATA_PERMISSION_WRITE);
  744. if (err.Failed())
  745. {
  746. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  747. {
  748. //
  749. // Path didn't exist yet, create it and reopen
  750. // it.
  751. //
  752. err = CreatePathFromFailedOpen();
  753. if (err.Succeeded())
  754. {
  755. err = ReOpen(METADATA_PERMISSION_WRITE);
  756. }
  757. }
  758. if (err.Failed())
  759. {
  760. break;
  761. }
  762. }
  763. //
  764. // Delete deleted filters
  765. //
  766. POSITION pos1, pos2;
  767. for (pos1 = m_oblFilters.GetHeadPosition(); (pos2 = pos1) != NULL; )
  768. {
  769. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos1);
  770. ASSERT(pFilter != NULL);
  771. if (pFilter->IsFlaggedForDeletion())
  772. {
  773. TRACEEOLID("Deleting filter " << pFilter->QueryName());
  774. err = DeleteKey(pFilter->QueryName());
  775. if (err.Failed())
  776. {
  777. break;
  778. }
  779. m_oblFilters.RemoveAt(pos2);
  780. }
  781. }
  782. if (err.Failed())
  783. {
  784. break;
  785. }
  786. //
  787. // Two passes are necessary, because the filter may
  788. // have been re-added after it was deleted from the
  789. // list as new entry. This could be somewhat improved
  790. //
  791. ResetEnumerator();
  792. while(MoreFilters())
  793. {
  794. CIISFilter * pFilter = GetNextFilter();
  795. ASSERT(pFilter != NULL);
  796. if (pFilter->IsDirty())
  797. {
  798. TRACEEOLID("Writing filter " << pFilter->QueryName());
  799. err = pFilter->Write(this);
  800. if (err.Failed())
  801. {
  802. break;
  803. }
  804. pFilter->Dirty(FALSE);
  805. }
  806. }
  807. if (err.Failed())
  808. {
  809. break;
  810. }
  811. //
  812. // Write the new filter load order
  813. //
  814. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  815. if (err.Failed())
  816. {
  817. break;
  818. }
  819. CString strKey(_T("IIsFilters"));
  820. err = SetValue(MD_KEY_TYPE, strKey);
  821. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  822. m_strFilterOrder = strNewOrder;
  823. }
  824. while(FALSE);
  825. if (IsOpen())
  826. {
  827. Close();
  828. }
  829. return err;
  830. }
  831. POSITION
  832. CIISFilterList::GetFilterPositionByIndex(
  833. IN int nSel
  834. )
  835. /*++
  836. Routine Description:
  837. Return the position of a filter object by index, skipping filters
  838. marked for deletion.
  839. Arguments:
  840. int nSel - 0 based index into the list
  841. Return Value:
  842. The POSITION into the filters ObList of the filter at the index
  843. specified, or NULL if the filter is not found.
  844. --*/
  845. {
  846. int nIndex = -1;
  847. CIISFilter * pFilter;
  848. POSITION pos,
  849. posReturn = NULL;
  850. pos = m_oblFilters.GetHeadPosition();
  851. while(pos && nIndex < nSel)
  852. {
  853. posReturn = pos;
  854. pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  855. //
  856. // Skipping deleted filters
  857. //
  858. if (!pFilter->IsFlaggedForDeletion())
  859. {
  860. ++nIndex;
  861. }
  862. }
  863. return posReturn;
  864. }
  865. BOOL
  866. CIISFilterList::ExchangePositions(
  867. IN int nSel1,
  868. IN int nSel2,
  869. OUT CIISFilter *& p1,
  870. OUT CIISFilter *& p2
  871. )
  872. /*++
  873. Routine Description:
  874. Exchange the positions of two filters in the list
  875. Arguments:
  876. int nSel1 : Item 1
  877. int nSel2 : Item 2
  878. CIISFilter *& p1 : Returns the item moved to position 1
  879. CIISFilter *& p2 : Returns the item moved to position 2
  880. Return Value:
  881. TRUE for success, FALSE for failure.
  882. --*/
  883. {
  884. ASSERT(SUCCEEDED(m_hrResult));
  885. //
  886. // Fetch filters at the two positions (deleted filters are
  887. // skipped in the index count)
  888. //
  889. POSITION pos1 = GetFilterPositionByIndex(nSel1);
  890. POSITION pos2 = GetFilterPositionByIndex(nSel2);
  891. p1 = pos2 ? (CIISFilter *)m_oblFilters.GetAt(pos2) : NULL;
  892. p2 = pos1 ? (CIISFilter *)m_oblFilters.GetAt(pos1) : NULL;
  893. if (!p1 || !p2)
  894. {
  895. TRACEEOLID("Invalid internal state -- filter exchange impossible");
  896. ASSERT(FALSE);
  897. return FALSE;
  898. }
  899. TRACEEOLID("Filter (1) name is " << p1->m_strName);
  900. TRACEEOLID("Filter (2) name is " << p2->m_strName);
  901. //
  902. // Exchange
  903. //
  904. m_oblFilters.SetAt(pos1, p1);
  905. m_oblFilters.SetAt(pos2, p2);
  906. //
  907. // Success
  908. //
  909. return TRUE;
  910. }
  911. LPCTSTR
  912. CIISFilterList::BuildFilterOrderString(
  913. OUT CString & strFilterOrder
  914. )
  915. /*++
  916. Routine Description:
  917. Convert the oblist of filters to a single filter order string
  918. fit to be stuffed into the metabase
  919. Arguments:
  920. CString & strFilterOrder : Output to receive the order string
  921. Return Value:
  922. A pointer to the new filter order string.
  923. --*/
  924. {
  925. BOOL fFirst = TRUE;
  926. POSITION pos = m_oblFilters.GetHeadPosition();
  927. strFilterOrder.Empty();
  928. while(pos)
  929. {
  930. CIISFilter * pFlt = (CIISFilter *)m_oblFilters.GetNext(pos);
  931. if (!pFlt->IsFlaggedForDeletion())
  932. {
  933. if (!fFirst)
  934. {
  935. strFilterOrder += s_lpszSep;
  936. }
  937. else
  938. {
  939. fFirst = FALSE;
  940. }
  941. strFilterOrder += pFlt->m_strName;
  942. }
  943. }
  944. return (LPCTSTR)strFilterOrder;
  945. }
  946. BOOL
  947. CIISFilterList::HasDirtyFilter() const
  948. /*++
  949. Routine Description:
  950. Go through the list of filters, and return TRUE if any filter
  951. in the list is dirty or flagged for deletion
  952. Arguments:
  953. None
  954. Return Value:
  955. TRUE if any filter is dirty or flagged for deletion.
  956. --*/
  957. {
  958. ASSERT(SUCCEEDED(m_hrResult));
  959. POSITION pos = m_oblFilters.GetHeadPosition();
  960. while(pos)
  961. {
  962. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  963. if (pFilter->IsFlaggedForDeletion() || pFilter->IsDirty())
  964. {
  965. return TRUE;
  966. }
  967. }
  968. return FALSE;
  969. }
  970. //
  971. // CW3Sheet implementation
  972. //
  973. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  974. CW3Sheet::CW3Sheet(
  975. IN CComAuthInfo * pAuthInfo,
  976. IN LPCTSTR lpszMetaPath,
  977. IN DWORD dwAttributes,
  978. IN CWnd * pParentWnd, OPTIONAL
  979. IN LPARAM lParam, OPTIONAL
  980. IN LONG_PTR handle, OPTIONAL
  981. IN UINT iSelectPage
  982. )
  983. /*++
  984. Routine Description:
  985. WWW Property sheet constructor
  986. Arguments:
  987. CComAuthInfo * pAuthInfo : Authentication information
  988. LPCTSTR lpszMetPath : Metabase path
  989. DWORD dwAttributes : File attributes
  990. CWnd * pParentWnd : Optional parent window
  991. LPARAM lParam : MMC Console parameter
  992. LONG_PTR handle : MMC Console handle
  993. UINT iSelectPage : Initial page to be selected
  994. Return Value:
  995. N/A
  996. --*/
  997. : CInetPropertySheet(
  998. pAuthInfo,
  999. lpszMetaPath,
  1000. pParentWnd,
  1001. lParam,
  1002. handle,
  1003. iSelectPage
  1004. ),
  1005. m_ppropInst(NULL),
  1006. m_ppropDir(NULL),
  1007. m_fNew(FALSE),
  1008. m_dwAttributes(dwAttributes),
  1009. m_fCompatMode(FALSE)
  1010. {
  1011. }
  1012. CW3Sheet::~CW3Sheet()
  1013. /*++
  1014. Routine Description:
  1015. Sheet destructor
  1016. Arguments:
  1017. N/A
  1018. Return Value:
  1019. N/A
  1020. --*/
  1021. {
  1022. FreeConfigurationParameters();
  1023. }
  1024. HRESULT
  1025. CW3Sheet::SetKeyType()
  1026. {
  1027. CError err;
  1028. CIISObject * pNode = (CIISObject *)GetParameter();
  1029. ASSERT(pNode != NULL);
  1030. if (pNode == NULL)
  1031. {
  1032. return E_FAIL;
  1033. }
  1034. CMetaKey mk(QueryAuthInfo(), m_ppropDir->QueryMetaRoot(), METADATA_PERMISSION_WRITE);
  1035. err = mk.QueryResult();
  1036. if (err.Succeeded())
  1037. {
  1038. err = mk.SetValue(MD_KEY_TYPE, CString(pNode->GetKeyType(m_ppropDir->QueryMetaRoot())));
  1039. }
  1040. else if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1041. {
  1042. err.Reset();
  1043. }
  1044. return err;
  1045. }
  1046. HRESULT
  1047. CW3Sheet::SetSheetType(int fSheetType)
  1048. {
  1049. m_fSheetType = fSheetType;
  1050. return S_OK;
  1051. }
  1052. void
  1053. CW3Sheet::WinHelp(
  1054. IN DWORD dwData,
  1055. IN UINT nCmd
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. WWW Property sheet help handler
  1060. Arguments:
  1061. DWORD dwData : WinHelp data (dialog ID)
  1062. UINT nCmd : WinHelp command
  1063. Return Value:
  1064. None
  1065. Notes:
  1066. Replace the dialog ID if this is the directory tab. We have
  1067. different help depending on virtual directory, home, file, directory.
  1068. --*/
  1069. {
  1070. if (dwData == HIDD_DIRECTORY_PROPERTIES)
  1071. {
  1072. if (m_fSheetType == SHEET_TYPE_FILE)
  1073. {
  1074. dwData = HIDD_FS_FILE_PROPERTIES;
  1075. }
  1076. else if (m_fSheetType == SHEET_TYPE_DIR)
  1077. {
  1078. dwData = HIDD_FS_DIRECTORY_PROPERTIES;
  1079. }
  1080. else if (m_fSheetType == SHEET_TYPE_VDIR)
  1081. {
  1082. dwData = HIDD_DIRECTORY_PROPERTIES;
  1083. }
  1084. else if (m_fSheetType == SHEET_TYPE_SERVER)
  1085. {
  1086. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1087. }
  1088. else if (m_fSheetType == SHEET_TYPE_SITE)
  1089. {
  1090. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1091. }
  1092. else
  1093. {
  1094. ASSERT(m_ppropDir != NULL);
  1095. if (!::lstrcmpi(m_ppropDir->m_strAlias, g_cszRoot))
  1096. {
  1097. //
  1098. // It's a home virtual directory -- change the ID
  1099. //
  1100. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1101. }
  1102. }
  1103. }
  1104. CInetPropertySheet::WinHelp(dwData, nCmd);
  1105. }
  1106. /* virtual */
  1107. HRESULT
  1108. CW3Sheet::LoadConfigurationParameters()
  1109. /*++
  1110. Routine Description:
  1111. Load configuration parameters information
  1112. Arguments:
  1113. None
  1114. Return Value:
  1115. HRESULT
  1116. --*/
  1117. {
  1118. //
  1119. // Load base properties
  1120. //
  1121. CError err(CInetPropertySheet::LoadConfigurationParameters());
  1122. if (err.Failed())
  1123. {
  1124. return err;
  1125. }
  1126. if (m_ppropInst == NULL)
  1127. {
  1128. //
  1129. // First call -- load values
  1130. //
  1131. ASSERT(m_ppropDir == NULL);
  1132. m_ppropInst = new CW3InstanceProps(QueryAuthInfo(), QueryInstancePath());
  1133. m_ppropDir = new CW3DirProps(QueryAuthInfo(), QueryDirectoryPath());
  1134. if (!m_ppropInst || !m_ppropDir)
  1135. {
  1136. TRACEEOLID("LoadConfigurationParameters: OOM");
  1137. SAFE_DELETE(m_ppropDir);
  1138. SAFE_DELETE(m_ppropInst);
  1139. err = ERROR_NOT_ENOUGH_MEMORY;
  1140. return err;
  1141. }
  1142. err = m_ppropInst->LoadData();
  1143. if (err.Succeeded())
  1144. {
  1145. err = m_ppropDir->LoadData();
  1146. if (err.Succeeded() && QueryMajorVersion() >= 6)
  1147. {
  1148. CMetaKey mk(QueryAuthInfo(), QueryServicePath(), METADATA_PERMISSION_READ);
  1149. err = mk.QueryResult();
  1150. if (err.Succeeded())
  1151. {
  1152. err = mk.QueryValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  1153. }
  1154. }
  1155. else if (err.Succeeded())
  1156. {
  1157. // We will enable this for IIS5.1 and lower
  1158. m_fCompatMode = TRUE;
  1159. }
  1160. }
  1161. }
  1162. return err;
  1163. }
  1164. /* virtual */
  1165. void
  1166. CW3Sheet::FreeConfigurationParameters()
  1167. /*++
  1168. Routine Description:
  1169. Clean up configuration data
  1170. Arguments:
  1171. None
  1172. Return Value:
  1173. None
  1174. --*/
  1175. {
  1176. //
  1177. // Base class
  1178. //
  1179. CInetPropertySheet::FreeConfigurationParameters();
  1180. ASSERT(m_ppropInst != NULL);
  1181. ASSERT(m_ppropDir != NULL);
  1182. SAFE_DELETE(m_ppropInst);
  1183. SAFE_DELETE(m_ppropDir);
  1184. }
  1185. DWORD
  1186. IsSSLEnabledOnServer(
  1187. IN CComAuthInfo * pAuthInfo,
  1188. OUT BOOL & fInstalled,
  1189. OUT BOOL & fEnabled
  1190. )
  1191. /*++
  1192. Routine Description:
  1193. Determine if SSL is installed on the server.
  1194. Arguments:
  1195. LPCTSTR lpszServer : Server name
  1196. BOOL & fInstalled : Returns TRUE if SSL is installed
  1197. BOOL & fEnabled : Returns TRUE if SSL is enabled
  1198. Return Value:
  1199. Error return code.
  1200. --*/
  1201. {
  1202. /*
  1203. LPW3_CONFIG_INFO lp = NULL;
  1204. CString str;
  1205. DWORD err = ::W3GetAdminInformation((LPTSTR)lpszServer, &lp);
  1206. if (err != ERROR_SUCCESS)
  1207. {
  1208. TRACEEOLID("Failed to determine if SSL is installed");
  1209. return err;
  1210. }
  1211. fInstalled = (lp->dwEncCaps & ENC_CAPS_NOT_INSTALLED) == 0;
  1212. fEnabled = (lp->dwEncCaps & ENC_CAPS_DISABLED) == 0;
  1213. NETAPIBUFFERFREE(lp);
  1214. */
  1215. //
  1216. // Above doesn't work for Beta I -- hack to assume true.
  1217. //
  1218. fInstalled = fEnabled = TRUE;
  1219. return ERROR_SUCCESS;
  1220. }
  1221. //
  1222. // Message Map
  1223. //
  1224. BEGIN_MESSAGE_MAP(CW3Sheet, CInetPropertySheet)
  1225. //{{AFX_MSG_MAP(CInetPropertySheet)
  1226. //}}AFX_MSG_MAP
  1227. END_MESSAGE_MAP()
  1228. HRESULT
  1229. CW3Sheet::EnumAppPools(CMapStringToString& pools)
  1230. {
  1231. CError err;
  1232. CIISMBNode * p = (CIISMBNode *)GetParameter();
  1233. ASSERT(p != NULL);
  1234. CIISMachine * pMachine = p->GetOwner();
  1235. ASSERT(pMachine != NULL);
  1236. IConsoleNameSpace2 * pConsole
  1237. = (IConsoleNameSpace2 *)pMachine->GetConsoleNameSpace();
  1238. ASSERT(pConsole != NULL);
  1239. // Get machine handle from pOwner
  1240. // then find handle to app pools container
  1241. // and use cookie from this node to enumerate pools
  1242. HSCOPEITEM hChild = NULL, hCurrent;
  1243. LONG_PTR cookie;
  1244. CIISMBNode * pNode = NULL;
  1245. err = pConsole->GetChildItem(pMachine->QueryScopeItem(), &hChild, &cookie);
  1246. while (err.Succeeded() && hChild != NULL)
  1247. {
  1248. pNode = (CIISMBNode *)cookie;
  1249. ASSERT(pNode != NULL);
  1250. if (lstrcmpi(pNode->GetNodeName(), SZ_MBN_APP_POOLS) == 0)
  1251. {
  1252. break;
  1253. }
  1254. hCurrent = hChild;
  1255. err = pConsole->GetNextItem(hCurrent, &hChild, &cookie);
  1256. }
  1257. CAppPoolsContainer * pCont = (CAppPoolsContainer *)pNode;
  1258. // expand container to enumerate pools
  1259. err = pConsole->Expand(pCont->QueryScopeItem());
  1260. // MMC returns Incorrect function error (0x80070001) instead of S_FALSE
  1261. // if (err == S_FALSE)
  1262. // {
  1263. // already expanded
  1264. err.Reset();
  1265. // }
  1266. if (err.Succeeded())
  1267. {
  1268. pConsole->GetChildItem(pCont->QueryScopeItem(), &hChild, &cookie);
  1269. CAppPoolNode * pPool;
  1270. while (err.Succeeded() && hChild != NULL)
  1271. {
  1272. pPool = (CAppPoolNode *)cookie;
  1273. ASSERT(pPool != NULL);
  1274. pools.SetAt(pPool->QueryDisplayName(), pPool->QueryNodeName());
  1275. hCurrent = hChild;
  1276. err = pConsole->GetNextItem(hCurrent, &hChild, &cookie);
  1277. }
  1278. }
  1279. err.Reset();
  1280. return err;
  1281. }
  1282. HRESULT
  1283. CW3Sheet::QueryDefaultPoolId(CString& id)
  1284. {
  1285. CError err;
  1286. CIISMBNode * p = (CIISMBNode *)GetParameter();
  1287. ASSERT(p != NULL);
  1288. CIISMachine * pMachine = p->GetOwner();
  1289. ASSERT(pMachine != NULL);
  1290. IConsoleNameSpace2 * pConsole
  1291. = (IConsoleNameSpace2 *)pMachine->GetConsoleNameSpace();
  1292. ASSERT(pConsole != NULL);
  1293. // Get machine handle from pOwner
  1294. // then find handle to app pools container
  1295. // and use cookie from this node to enumerate pools
  1296. HSCOPEITEM hChild = NULL, hCurrent;
  1297. LONG_PTR cookie;
  1298. CIISMBNode * pNode = NULL;
  1299. err = pConsole->GetChildItem(pMachine->QueryScopeItem(), &hChild, &cookie);
  1300. while (err.Succeeded() && hChild != NULL)
  1301. {
  1302. pNode = (CIISMBNode *)cookie;
  1303. ASSERT(pNode != NULL);
  1304. if (lstrcmpi(pNode->GetNodeName(), SZ_MBN_APP_POOLS) == 0)
  1305. {
  1306. break;
  1307. }
  1308. hCurrent = hChild;
  1309. err = pConsole->GetNextItem(hCurrent, &hChild, &cookie);
  1310. }
  1311. CAppPoolsContainer * pCont = (CAppPoolsContainer *)pNode;
  1312. ASSERT(pCont != NULL);
  1313. return pCont->QueryDefaultPoolId(id);
  1314. }