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.

3879 lines
77 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. w3scfg.h
  5. Abstract:
  6. WWW Configuration Module
  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 "wincrypt.h"
  18. #include <process.h>
  19. #include <afxtempl.h>
  20. #include "w3scfg.h"
  21. #include "w3servic.h"
  22. #include "w3accts.h"
  23. #include "vdir.h"
  24. #include "perform.h"
  25. #include "docum.h"
  26. #include "security.h"
  27. #include "httppage.h"
  28. #include "defws.h"
  29. #include "fltdlg.h"
  30. #include "filters.h"
  31. #include "errors.h"
  32. #include "wizard.h"
  33. #include "iisfilt.h"
  34. #include "..\mmc\constr.h"
  35. #define CDELETE(x) {if (x != NULL) delete x;}
  36. //
  37. // Standard configuration Information
  38. //
  39. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  40. #define SVC_ID INET_HTTP_SVC_ID
  41. //
  42. // Is this server discoverable by INETSLOC?
  43. //
  44. #define INETSLOC_DISCOVERY TRUE
  45. #if (INETSLOC_DISCOVERY) && !defined(_SVCLOC_)
  46. #error You must include svcloc.h.
  47. #endif
  48. //
  49. // If INETSLOC_DISCOVERY == TRUE, define the discovery MASK here.
  50. //
  51. #if (INETSLOC_DISCOVERY)
  52. #define INETSLOC_MASK INET_W3_SVCLOC_ID
  53. #else // (!INETSLOC_DISCOVERY)
  54. #define INETSLOC_MASK (ULONGLONG)(0x00000000)
  55. #endif // (INETSLOC_DISCOVERY)
  56. #ifdef NO_SERVICE_CONTROLLER
  57. #define CAN_CHANGE_SERVICE_STATE FALSE
  58. #define CAN_PAUSE_SERVICE FALSE
  59. #else
  60. //
  61. // Can we change the service state (start/pause/continue)?
  62. //
  63. #define CAN_CHANGE_SERVICE_STATE TRUE
  64. //
  65. // Can we pause this service?
  66. //
  67. #define CAN_PAUSE_SERVICE TRUE
  68. #endif // NO_SERVICE_CONTROLLER
  69. //
  70. // Name used for this service by the service controller manager.
  71. //
  72. #define SERVICE_SC_NAME _T("W3Svc")
  73. //
  74. // Longer name. This is the text that shows up in
  75. // the tooltips text on the internet manager
  76. // tool. This probably should be localised.
  77. //
  78. #define SERVICE_LONG_NAME _T("Web Service")
  79. //
  80. // Web browser protocol name. e.g. xxxxx://address
  81. // A blank string if this is not supported.
  82. //
  83. #define SERVICE_PROTOCOL _T("http")
  84. //
  85. // Use normal colour mapping.
  86. //
  87. #define NORMAL_TB_MAPPING TRUE
  88. //
  89. // Toolbar button background mask. This is
  90. // the colour that gets masked out in
  91. // the bitmap file and replaced with the
  92. // actual button background. This setting
  93. // is automatically assumed to be lt. gray
  94. // if NORMAL_TB_MAPPING (above) is TRUE
  95. //
  96. #define BUTTON_BMP_BACKGROUND RGB(192, 192, 192) // Lt. Gray
  97. //
  98. // Resource ID of the toolbar button bitmap.
  99. //
  100. // The bitmap must be 16x16
  101. //
  102. #define BUTTON_BMP_ID IDB_WWW
  103. //
  104. // Similar to BUTTON_BMP_BACKGROUND, this is the
  105. // background mask for the service ID
  106. //
  107. #define SERVICE_BMP_BACKGROUND RGB(255, 0, 255) // Magenta
  108. //
  109. // Bitmap id which is used in the service view
  110. // of the service manager. It may be the same
  111. // bitmap as the BUTTON_BMP_ID bitmap.
  112. //
  113. // The bitmap must be 16x16.
  114. //
  115. #define SERVICE_BMP_ID IDB_WWW
  116. //
  117. // /* K2 */
  118. //
  119. // Similar to BUTTON_BMP_BACKGROUND, this is the
  120. // background mask for the child bitmap
  121. //
  122. #define CHILD_BMP_BACKGROUND RGB(255, 0, 255) // Magenta
  123. //
  124. // /* K2 */
  125. //
  126. // Bitmap id which is used for the child
  127. //
  128. // The bitmap must be 16x16
  129. //
  130. #define CHILD_BMP_ID IDB_WWWVDIR
  131. //
  132. // Large child bitmap ID
  133. //
  134. #define CHILD_BMP32_ID IDB_WWWVDIR32
  135. //
  136. // /* K2 */
  137. //
  138. // Large bitmap (32x32) id
  139. //
  140. #define SERVICE_BMP32_ID IDB_WWW32
  141. //
  142. // Help IDs
  143. //
  144. #define HIDD_DIRECTORY_PROPERTIES (0x207DB)
  145. #define HIDD_HOME_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20000)
  146. #define HIDD_FS_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20001)
  147. #define HIDD_FS_FILE_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20002)
  148. //
  149. // Metabase node ID
  150. //
  151. const LPCTSTR g_cszSvc = _T("W3SVC");
  152. const LPCTSTR g_cszFilters = _T("Filters");
  153. const LPCTSTR g_cszSSLKeys = _T("SSLKeys");
  154. //
  155. // End Of Standard configuration Information
  156. //
  157. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  158. CW3InstanceProps::CW3InstanceProps(
  159. IN LPCTSTR lpszServerName,
  160. IN DWORD dwInstance OPTIONAL
  161. )
  162. /*++
  163. Routine Description:
  164. Constructor for WWW instance properties
  165. Arguments:
  166. LPCTSTR lpszServerName : Server name
  167. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  168. Return Value:
  169. None.
  170. --*/
  171. : CInstanceProps(lpszServerName, g_cszSvc, dwInstance, 80U),
  172. /**/
  173. m_nMaxConnections(INITIAL_MAX_CONNECTIONS),
  174. m_nConnectionTimeOut((LONG)900L),
  175. m_strlSecureBindings(),
  176. m_dwLogType(MD_LOG_TYPE_DISABLED),
  177. /**/
  178. m_fUseKeepAlives(TRUE),
  179. m_fEnableCPUAccounting(FALSE),
  180. m_nServerSize(MD_SERVER_SIZE_MEDIUM),
  181. m_nMaxNetworkUse(INFINITE_BANDWIDTH),
  182. /**/
  183. m_dwCPULimitLogEventRaw(INFINITE_CPU_RAW),
  184. m_dwCPULimitPriorityRaw(0),
  185. m_dwCPULimitPauseRaw(0),
  186. m_dwCPULimitProcStopRaw(0),
  187. /**/
  188. m_acl(),
  189. /**/
  190. m_dwDownlevelInstance(1),
  191. m_CertHash()
  192. {
  193. //
  194. // Fetch everything
  195. //
  196. m_dwMDUserType = ALL_METADATA;
  197. m_dwMDDataType = ALL_METADATA;
  198. }
  199. /* virtual */
  200. void
  201. CW3InstanceProps::ParseFields()
  202. /*++
  203. Routine Description:
  204. Break into fields.
  205. Arguments:
  206. None.
  207. Return Value:
  208. None.
  209. --*/
  210. {
  211. //
  212. // Fetch base properties
  213. //
  214. CInstanceProps::ParseFields();
  215. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  216. //
  217. // Service Page
  218. //
  219. HANDLE_META_RECORD(MD_MAX_CONNECTIONS, m_nMaxConnections)
  220. HANDLE_META_RECORD(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  221. HANDLE_META_RECORD(MD_SECURE_BINDINGS, m_strlSecureBindings)
  222. HANDLE_META_RECORD(MD_LOG_TYPE, m_dwLogType)
  223. //
  224. // Performance Page
  225. //
  226. HANDLE_META_RECORD(MD_SERVER_SIZE, m_nServerSize)
  227. HANDLE_META_RECORD(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  228. HANDLE_META_RECORD(MD_MAX_BANDWIDTH, m_nMaxNetworkUse)
  229. HANDLE_META_RECORD(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting)
  230. HANDLE_META_RECORD(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw)
  231. HANDLE_META_RECORD(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw)
  232. HANDLE_META_RECORD(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw)
  233. HANDLE_META_RECORD(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw)
  234. //
  235. // Operators Page
  236. //
  237. HANDLE_META_RECORD(MD_ADMIN_ACL, m_acl)
  238. //
  239. // Certificate and CTL information
  240. //
  241. HANDLE_META_RECORD(MD_SSL_CERT_HASH, m_CertHash)
  242. HANDLE_META_RECORD(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
  243. HANDLE_META_RECORD(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  244. HANDLE_META_RECORD(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  245. END_PARSE_META_RECORDS
  246. }
  247. /* virtual */
  248. HRESULT
  249. CW3InstanceProps::WriteDirtyProps()
  250. /*++
  251. Routine Description:
  252. Write the dirty properties to the metabase
  253. Arguments:
  254. None
  255. Return Value:
  256. HRESULT
  257. --*/
  258. {
  259. CError err(CInstanceProps::WriteDirtyProps());
  260. if (err.Failed())
  261. {
  262. return err;
  263. }
  264. BEGIN_META_WRITE()
  265. //
  266. // Service Page
  267. //
  268. META_WRITE(MD_MAX_CONNECTIONS, m_nMaxConnections)
  269. META_WRITE(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  270. META_WRITE(MD_SECURE_BINDINGS, m_strlSecureBindings)
  271. META_WRITE(MD_LOG_TYPE, m_dwLogType)
  272. //
  273. // Performance Page
  274. //
  275. META_WRITE(MD_SERVER_SIZE, m_nServerSize)
  276. META_WRITE(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives)
  277. META_WRITE(MD_MAX_BANDWIDTH, m_nMaxNetworkUse)
  278. META_WRITE(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting)
  279. META_WRITE(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw)
  280. META_WRITE(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw)
  281. META_WRITE(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw)
  282. META_WRITE(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw)
  283. //
  284. // Operators Page
  285. //
  286. META_WRITE(MD_ADMIN_ACL, m_acl)
  287. //
  288. // Certificate and CTL information
  289. //
  290. //META_WRITE(MD_SSL_CERT_HASH, m_CertHash)
  291. //META_WRITE(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
  292. META_WRITE(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier)
  293. META_WRITE(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName)
  294. END_META_WRITE(err);
  295. return err;
  296. }
  297. CW3DirProps::CW3DirProps(
  298. IN LPCTSTR lpszServerName,
  299. IN DWORD dwInstance, OPTIONAL
  300. IN LPCTSTR lpszParent, OPTIONAL
  301. IN LPCTSTR lpszAlias OPTIONAL
  302. )
  303. /*++
  304. Routine Description:
  305. WWW Directory Properties Constructor
  306. Arguments:
  307. LPCTSTR lpszServerName : Server Name
  308. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  309. LPCTSTR lpszParent : Parent path (could be NULL or "")
  310. LPCTSTR lpszAlias : Alias name (could be NULL or "")
  311. --*/
  312. : CChildNodeProps(
  313. lpszServerName,
  314. g_cszSvc,
  315. dwInstance,
  316. lpszParent,
  317. lpszAlias,
  318. WITH_INHERITANCE,
  319. FALSE // Full information
  320. ),
  321. /**/
  322. m_strUserName(),
  323. m_strPassword(),
  324. m_strDefaultDocument(),
  325. m_strFooter(),
  326. m_dwDirBrowsing(0L),
  327. m_fEnableFooter(FALSE),
  328. m_fDontLog(FALSE),
  329. m_fIndexed(FALSE),
  330. /**/
  331. m_strExpiration(),
  332. m_strlCustomHeaders(),
  333. /**/
  334. m_strlCustomErrors(),
  335. /**/
  336. m_strAnonUserName(),
  337. m_strAnonPassword(),
  338. m_fPasswordSync(TRUE),
  339. m_fU2Installed(FALSE),
  340. m_fUseNTMapper(FALSE),
  341. m_dwAuthFlags(MD_AUTH_ANONYMOUS),
  342. m_dwSSLAccessPermissions(0L),
  343. m_strBasicDomain(),
  344. m_ipl()
  345. {
  346. //
  347. // Fetch everything
  348. //
  349. m_dwMDUserType = ALL_METADATA;
  350. m_dwMDDataType = ALL_METADATA;
  351. }
  352. /* virtual */
  353. void
  354. CW3DirProps::ParseFields()
  355. /*++
  356. Routine Description:
  357. Break into fields.
  358. Arguments:
  359. None.
  360. Return Value:
  361. None.
  362. --*/
  363. {
  364. //
  365. // Fetch base properties
  366. //
  367. CChildNodeProps::ParseFields();
  368. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  369. //
  370. // VDir Page
  371. //
  372. HANDLE_META_RECORD(MD_VR_USERNAME, m_strUserName)
  373. HANDLE_META_RECORD(MD_VR_PASSWORD, m_strPassword)
  374. HANDLE_META_RECORD(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument);
  375. HANDLE_META_RECORD(MD_FOOTER_ENABLED, m_fEnableFooter);
  376. HANDLE_META_RECORD(MD_FOOTER_DOCUMENT, m_strFooter);
  377. HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing);
  378. HANDLE_META_RECORD(MD_DONT_LOG, m_fDontLog);
  379. HANDLE_META_RECORD(MD_IS_CONTENT_INDEXED, m_fIndexed);
  380. //
  381. // HTTP Page
  382. //
  383. HANDLE_META_RECORD(MD_HTTP_EXPIRES, m_strExpiration);
  384. HANDLE_META_RECORD(MD_HTTP_CUSTOM, m_strlCustomHeaders);
  385. //
  386. // Custom Errors
  387. //
  388. HANDLE_META_RECORD(MD_CUSTOM_ERROR, m_strlCustomErrors);
  389. //
  390. // Security page
  391. //
  392. HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthFlags);
  393. HANDLE_META_RECORD(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions);
  394. HANDLE_META_RECORD(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain);
  395. HANDLE_META_RECORD(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  396. HANDLE_META_RECORD(MD_ANONYMOUS_PWD, m_strAnonPassword)
  397. HANDLE_META_RECORD(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  398. HANDLE_META_RECORD(MD_U2_AUTH, m_fU2Installed)
  399. HANDLE_META_RECORD(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper);
  400. HANDLE_META_RECORD(MD_IP_SEC, m_ipl);
  401. END_PARSE_META_RECORDS
  402. }
  403. /* virtual */
  404. HRESULT
  405. CW3DirProps::WriteDirtyProps()
  406. /*++
  407. Routine Description:
  408. Write the dirty properties to the metabase
  409. Arguments:
  410. None
  411. Return Value:
  412. HRESULT
  413. --*/
  414. {
  415. CError err(CChildNodeProps::WriteDirtyProps());
  416. if (err.Failed())
  417. {
  418. return err;
  419. }
  420. //
  421. // CODEWORK: Consider DDX/DDV like methods which do both
  422. // ParseFields and WriteDirtyProps in a single method. Must
  423. // take care not to write data which should only be read, not
  424. // written
  425. //
  426. BEGIN_META_WRITE()
  427. //
  428. // VDir Page
  429. //
  430. META_WRITE(MD_VR_USERNAME, m_strUserName)
  431. META_WRITE(MD_VR_PASSWORD, m_strPassword)
  432. META_WRITE(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument)
  433. META_WRITE(MD_FOOTER_ENABLED, m_fEnableFooter)
  434. META_WRITE(MD_FOOTER_DOCUMENT, m_strFooter)
  435. META_WRITE(MD_DIRECTORY_BROWSING, m_dwDirBrowsing)
  436. META_WRITE(MD_DONT_LOG, m_fDontLog)
  437. META_WRITE(MD_IS_CONTENT_INDEXED, m_fIndexed)
  438. //
  439. // HTTP Page
  440. //
  441. META_WRITE(MD_HTTP_EXPIRES, m_strExpiration)
  442. META_WRITE(MD_HTTP_CUSTOM, m_strlCustomHeaders)
  443. //
  444. // Custom Errors
  445. //
  446. META_WRITE(MD_CUSTOM_ERROR, m_strlCustomErrors)
  447. //
  448. // Security page
  449. //
  450. META_WRITE(MD_AUTHORIZATION, m_dwAuthFlags)
  451. META_WRITE(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions)
  452. META_WRITE(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain)
  453. META_WRITE(MD_ANONYMOUS_USER_NAME, m_strAnonUserName)
  454. META_WRITE(MD_ANONYMOUS_PWD, m_strAnonPassword)
  455. META_WRITE(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  456. META_WRITE(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper)
  457. META_WRITE(MD_IP_SEC, m_ipl)
  458. END_META_WRITE(err);
  459. return err;
  460. }
  461. CIISFilter::CIISFilter()
  462. /*++
  463. Routine Description:
  464. Filter contructor for a new filter
  465. Arguments:
  466. None
  467. Return Value:
  468. N/A
  469. --*/
  470. : CObjectPlus(),
  471. m_strName(),
  472. //
  473. // Default Values
  474. //
  475. m_strExecutable(),
  476. m_nPriority(FLTR_PR_INVALID),
  477. m_nOrder(-1),
  478. m_dwState(MD_FILTER_STATE_UNLOADED),
  479. m_dwFlags(0L),
  480. m_hrResult(S_OK),
  481. m_dwWin32Error(ERROR_SUCCESS),
  482. m_fEnabled(TRUE),
  483. m_fDirty(FALSE),
  484. m_fFlaggedForDeletion(FALSE)
  485. {
  486. }
  487. CIISFilter::CIISFilter(
  488. IN CMetaKey * pKey,
  489. IN LPCTSTR lpszName
  490. )
  491. /*++
  492. Routine Description:
  493. Fully defined constructor
  494. Arguments:
  495. CMetaKey * pKey : Open key to read from
  496. LPCTSTR lpszName : Name of the filter
  497. Return Value:
  498. N/A
  499. --*/
  500. : m_strName(lpszName),
  501. //
  502. // Default Values
  503. //
  504. m_strExecutable(),
  505. m_nPriority(FLTR_PR_INVALID),
  506. m_nOrder(-1),
  507. m_dwState(MD_FILTER_STATE_UNLOADED),
  508. m_dwFlags(0L),
  509. m_hrResult(S_OK),
  510. m_dwWin32Error(ERROR_SUCCESS),
  511. m_fEnabled(TRUE),
  512. m_fDirty(FALSE),
  513. m_fFlaggedForDeletion(FALSE)
  514. {
  515. ASSERT(pKey != NULL);
  516. m_hrResult = pKey->QueryValue(
  517. MD_FILTER_IMAGE_PATH,
  518. m_strExecutable,
  519. NULL,
  520. m_strName
  521. );
  522. pKey->QueryValue(MD_FILTER_ENABLED, m_fEnabled, NULL, m_strName);
  523. pKey->QueryValue(MD_FILTER_STATE, m_dwState, NULL, m_strName);
  524. pKey->QueryValue(MD_FILTER_FLAGS, m_dwFlags, NULL, m_strName);
  525. if (m_dwFlags & SF_NOTIFY_ORDER_HIGH)
  526. {
  527. m_nPriority = FLTR_PR_HIGH;
  528. }
  529. else if (m_dwFlags & SF_NOTIFY_ORDER_MEDIUM)
  530. {
  531. m_nPriority = FLTR_PR_MEDIUM;
  532. }
  533. else if (m_dwFlags & SF_NOTIFY_ORDER_LOW)
  534. {
  535. m_nPriority = FLTR_PR_LOW;
  536. }
  537. else
  538. {
  539. m_nPriority = FLTR_PR_INVALID;
  540. }
  541. }
  542. CIISFilter::CIISFilter(
  543. IN const CIISFilter & flt
  544. )
  545. /*++
  546. Routine Description:
  547. Copy Constructor
  548. Arguments:
  549. const CIISFilter & flt : Source filter object
  550. Return Value:
  551. N/A
  552. --*/
  553. : m_strName(flt.m_strName),
  554. m_strExecutable(flt.m_strExecutable),
  555. m_nPriority(flt.m_nPriority),
  556. m_nOrder(flt.m_nOrder),
  557. m_hrResult(flt.m_hrResult),
  558. m_dwState(flt.m_dwState),
  559. m_dwFlags(flt.m_dwFlags),
  560. m_dwWin32Error(flt.m_dwWin32Error),
  561. m_fEnabled(flt.m_fEnabled),
  562. m_fDirty(FALSE),
  563. m_fFlaggedForDeletion(FALSE)
  564. {
  565. }
  566. HRESULT
  567. CIISFilter::Write(
  568. IN CMetaKey * pKey
  569. )
  570. /*++
  571. Routine Description:
  572. Write the current value to the metabase
  573. Arguments:
  574. CMetaKey * pKey : Open key
  575. Return Value:
  576. HRESULT
  577. --*/
  578. {
  579. ASSERT(pKey != NULL);
  580. CError err;
  581. CString strKey(_T("IIsFilter"));
  582. err = pKey->SetValue(MD_KEY_TYPE, strKey, NULL, QueryName());
  583. if (err.Succeeded())
  584. {
  585. err = pKey->SetValue(
  586. MD_FILTER_IMAGE_PATH,
  587. m_strExecutable,
  588. NULL,
  589. QueryName()
  590. );
  591. }
  592. return err;
  593. }
  594. int
  595. CIISFilter::OrderByPriority(
  596. IN const CObjectPlus * pobAccess
  597. ) const
  598. /*++
  599. Routine Description:
  600. Compare two filters against each other, and sort on priority first, and
  601. order secondarily.
  602. Arguments:
  603. const CObjectPlus * pobAccess : This really refers to another
  604. CIISFilter to be compared to.
  605. Return Value:
  606. Sort (+1, 0, -1) return value
  607. --*/
  608. {
  609. const CIISFilter * pob = (CIISFilter *)pobAccess;
  610. if (pob->m_nPriority != m_nPriority)
  611. {
  612. return pob->m_nPriority - m_nPriority;
  613. }
  614. //
  615. // Sort by order in reverse order
  616. //
  617. return m_nOrder - pob->m_nOrder;
  618. }
  619. //
  620. // Static initialization
  621. //
  622. const LPCTSTR CIISFilterList::s_lpszSep = _T(",");
  623. CIISFilterList::CIISFilterList(
  624. IN LPCTSTR lpszServerName,
  625. IN LPCTSTR lpszService,
  626. IN DWORD dwInstance OPTIONAL
  627. )
  628. /*++
  629. Routine Description:
  630. Constructor for filter list
  631. Arguments:
  632. LPCTSTR lpszServerName : Server name
  633. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  634. Return Value:
  635. N/A
  636. --*/
  637. : CMetaKey(
  638. lpszServerName,
  639. METADATA_PERMISSION_READ,
  640. lpszService,
  641. dwInstance,
  642. g_cszFilters
  643. ),
  644. m_dwInstance(dwInstance),
  645. m_hrResult(S_OK),
  646. //
  647. // Default properties
  648. //
  649. m_strFilterOrder(),
  650. m_fFiltersLoaded(FALSE)
  651. {
  652. m_hrResult = CMetaKey::QueryResult();
  653. if (SUCCEEDED(m_hrResult))
  654. {
  655. m_hrResult = QueryValue(MD_FILTER_LOAD_ORDER, m_strFilterOrder);
  656. }
  657. if (m_hrResult == CError::HResult(ERROR_PATH_NOT_FOUND))
  658. {
  659. //
  660. // Harmless
  661. //
  662. m_hrResult = S_OK;
  663. }
  664. if (IsOpen())
  665. {
  666. Close();
  667. }
  668. }
  669. HRESULT
  670. CIISFilterList::LoadAllFilters()
  671. /*++
  672. Routine Description:
  673. Loop through the filter order string, and load information
  674. about each filter in turn.
  675. Arguments:
  676. None.
  677. Return Value:
  678. HRESULT. The first error stops filter loading.
  679. --*/
  680. {
  681. ASSERT(SUCCEEDED(m_hrResult));
  682. if (m_fFiltersLoaded)
  683. {
  684. //
  685. // Already done
  686. //
  687. return S_OK;
  688. }
  689. int cItems = 0;
  690. CError err(ReOpen(METADATA_PERMISSION_READ));
  691. if (err.Failed())
  692. {
  693. return err;
  694. }
  695. try
  696. {
  697. CString strSrc(m_strFilterOrder);
  698. LPTSTR lp = strSrc.GetBuffer(0);
  699. lp = StringTok(lp, s_lpszSep);
  700. int nOrder = 0;
  701. while (lp)
  702. {
  703. CString str(lp);
  704. str.TrimLeft();
  705. str.TrimRight();
  706. TRACEEOLID("Adding filter: " << str);
  707. CIISFilter * pFilter = new CIISFilter(this, str);
  708. err = pFilter->QueryResult();
  709. if (err.Failed())
  710. {
  711. break;
  712. }
  713. pFilter->m_nOrder = nOrder++;
  714. m_oblFilters.AddTail(pFilter);
  715. lp = StringTok(NULL, s_lpszSep);
  716. ++cItems;
  717. }
  718. //
  719. // Sort filters list
  720. //
  721. m_oblFilters.Sort(
  722. (CObjectPlus::PCOBJPLUS_ORDER_FUNC)
  723. &CIISFilter::OrderByPriority
  724. );
  725. }
  726. catch(CMemoryException * e)
  727. {
  728. e->Delete();
  729. err = ERROR_NOT_ENOUGH_MEMORY;
  730. }
  731. m_fFiltersLoaded = err.Succeeded();
  732. if (IsOpen())
  733. {
  734. Close();
  735. }
  736. return err;
  737. }
  738. HRESULT
  739. CIISFilterList::WriteIfDirty()
  740. /*++
  741. Routine Description:
  742. Write all the changes in the filters list to the metabase
  743. Arguments:
  744. None.
  745. Return Value:
  746. HRESULT
  747. --*/
  748. {
  749. CError err;
  750. CString strNewOrder;
  751. VERIFY(BuildFilterOrderString(strNewOrder));
  752. //
  753. // Check to see if this new list is different
  754. //
  755. if (!strNewOrder.CompareNoCase(m_strFilterOrder) && !HasDirtyFilter())
  756. {
  757. //
  758. // The priority list hasn't changed, and no filter is marked
  759. // as dirty, so all done.
  760. //
  761. return err;
  762. }
  763. //
  764. // It's dirty -- save it
  765. //
  766. do
  767. {
  768. err = ReOpen(METADATA_PERMISSION_WRITE);
  769. if (err.Failed())
  770. {
  771. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  772. {
  773. //
  774. // Path didn't exist yet, create it and reopen
  775. // it.
  776. //
  777. err = CreatePathFromFailedOpen();
  778. if (err.Succeeded())
  779. {
  780. err = ReOpen(METADATA_PERMISSION_WRITE);
  781. }
  782. }
  783. if (err.Failed())
  784. {
  785. break;
  786. }
  787. }
  788. //
  789. // Delete deleted filters
  790. //
  791. POSITION pos1, pos2;
  792. for (pos1 = m_oblFilters.GetHeadPosition(); (pos2 = pos1) != NULL; )
  793. {
  794. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos1);
  795. ASSERT(pFilter != NULL);
  796. if (pFilter->IsFlaggedForDeletion())
  797. {
  798. TRACEEOLID("Deleting filter " << pFilter->QueryName());
  799. err = DeleteKey(pFilter->QueryName());
  800. if (err.Failed())
  801. {
  802. break;
  803. }
  804. m_oblFilters.RemoveAt(pos2);
  805. }
  806. }
  807. if (err.Failed())
  808. {
  809. break;
  810. }
  811. //
  812. // Two passes are necessary, because the filter may
  813. // have been re-added after it was deleted from the
  814. // list as new entry. This could be somewhat improved
  815. //
  816. ResetEnumerator();
  817. while(MoreFilters())
  818. {
  819. CIISFilter * pFilter = GetNextFilter();
  820. ASSERT(pFilter != NULL);
  821. if (pFilter->IsDirty())
  822. {
  823. TRACEEOLID("Writing filter " << pFilter->QueryName());
  824. err = pFilter->Write(this);
  825. if (err.Failed())
  826. {
  827. break;
  828. }
  829. pFilter->Dirty(FALSE);
  830. }
  831. }
  832. if (err.Failed())
  833. {
  834. break;
  835. }
  836. //
  837. // Write the new filter load order
  838. //
  839. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  840. if (err.Failed())
  841. {
  842. break;
  843. }
  844. CString strKey(_T("IIsFilters"));
  845. err = SetValue(MD_KEY_TYPE, strKey);
  846. err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
  847. m_strFilterOrder = strNewOrder;
  848. }
  849. while(FALSE);
  850. if (IsOpen())
  851. {
  852. Close();
  853. }
  854. return err;
  855. }
  856. POSITION
  857. CIISFilterList::GetFilterPositionByIndex(
  858. IN int nSel
  859. )
  860. /*++
  861. Routine Description:
  862. Return the position of a filter object by index, skipping filters
  863. marked for deletion.
  864. Arguments:
  865. int nSel - 0 based index into the list
  866. Return Value:
  867. The POSITION into the filters ObList of the filter at the index
  868. specified, or NULL if the filter is not found.
  869. --*/
  870. {
  871. int nIndex = -1;
  872. CIISFilter * pFilter;
  873. POSITION pos,
  874. posReturn = NULL;
  875. pos = m_oblFilters.GetHeadPosition();
  876. while(pos && nIndex < nSel)
  877. {
  878. posReturn = pos;
  879. pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  880. //
  881. // Skipping deleted filters
  882. //
  883. if (!pFilter->IsFlaggedForDeletion())
  884. {
  885. ++nIndex;
  886. }
  887. }
  888. return posReturn;
  889. }
  890. BOOL
  891. CIISFilterList::ExchangePositions(
  892. IN int nSel1,
  893. IN int nSel2,
  894. OUT CIISFilter *& p1,
  895. OUT CIISFilter *& p2
  896. )
  897. /*++
  898. Routine Description:
  899. Exchange the positions of two filters in the list
  900. Arguments:
  901. int nSel1 : Item 1
  902. int nSel2 : Item 2
  903. CIISFilter *& p1 : Returns the item moved to position 1
  904. CIISFilter *& p2 : Returns the item moved to position 2
  905. Return Value:
  906. TRUE for success, FALSE for failure.
  907. --*/
  908. {
  909. ASSERT(SUCCEEDED(m_hrResult));
  910. //
  911. // Fetch filters at the two positions (deleted filters are
  912. // skipped in the index count)
  913. //
  914. POSITION pos1 = GetFilterPositionByIndex(nSel1);
  915. POSITION pos2 = GetFilterPositionByIndex(nSel2);
  916. p1 = pos2 ? (CIISFilter *)m_oblFilters.GetAt(pos2) : NULL;
  917. p2 = pos1 ? (CIISFilter *)m_oblFilters.GetAt(pos1) : NULL;
  918. if (!p1 || !p2)
  919. {
  920. TRACEEOLID("Invalid internal state -- filter exchange impossible");
  921. ASSERT(FALSE);
  922. return FALSE;
  923. }
  924. TRACEEOLID("Filter (1) name is " << p1->m_strName);
  925. TRACEEOLID("Filter (2) name is " << p2->m_strName);
  926. //
  927. // Exchange
  928. //
  929. m_oblFilters.SetAt(pos1, p1);
  930. m_oblFilters.SetAt(pos2, p2);
  931. //
  932. // Success
  933. //
  934. return TRUE;
  935. }
  936. LPCTSTR
  937. CIISFilterList::BuildFilterOrderString(
  938. OUT CString & strFilterOrder
  939. )
  940. /*++
  941. Routine Description:
  942. Convert the oblist of filters to a single filter order string
  943. fit to be stuffed into the metabase
  944. Arguments:
  945. CString & strFilterOrder : Output to receive the order string
  946. Return Value:
  947. A pointer to the new filter order string.
  948. --*/
  949. {
  950. BOOL fFirst = TRUE;
  951. POSITION pos = m_oblFilters.GetHeadPosition();
  952. strFilterOrder.Empty();
  953. while(pos)
  954. {
  955. CIISFilter * pFlt = (CIISFilter *)m_oblFilters.GetNext(pos);
  956. if (!pFlt->IsFlaggedForDeletion())
  957. {
  958. if (!fFirst)
  959. {
  960. strFilterOrder += s_lpszSep;
  961. }
  962. else
  963. {
  964. fFirst = FALSE;
  965. }
  966. strFilterOrder += pFlt->m_strName;
  967. }
  968. }
  969. return (LPCTSTR)strFilterOrder;
  970. }
  971. BOOL
  972. CIISFilterList::HasDirtyFilter() const
  973. /*++
  974. Routine Description:
  975. Go through the list of filters, and return TRUE if any filter
  976. in the list is dirty or flagged for deletion
  977. Arguments:
  978. None
  979. Return Value:
  980. TRUE if any filter is dirty or flagged for deletion.
  981. --*/
  982. {
  983. ASSERT(SUCCEEDED(m_hrResult));
  984. POSITION pos = m_oblFilters.GetHeadPosition();
  985. while(pos)
  986. {
  987. CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
  988. if (pFilter->IsFlaggedForDeletion() || pFilter->IsDirty())
  989. {
  990. return TRUE;
  991. }
  992. }
  993. return FALSE;
  994. }
  995. //
  996. // Message Map
  997. //
  998. BEGIN_MESSAGE_MAP(CW3Sheet, CInetPropertySheet)
  999. //{{AFX_MSG_MAP(CInetPropertySheet)
  1000. //}}AFX_MSG_MAP
  1001. END_MESSAGE_MAP()
  1002. CW3Sheet::CW3Sheet(
  1003. LPCTSTR pszCaption,
  1004. DWORD dwAttributes,
  1005. LPCTSTR lpszServer,
  1006. DWORD dwInstance,
  1007. LPCTSTR lpszParent,
  1008. LPCTSTR lpszAlias,
  1009. CWnd * pParentWnd,
  1010. LPARAM lParam,
  1011. LONG_PTR handle,
  1012. UINT iSelectPage
  1013. )
  1014. /*++
  1015. Routine Description:
  1016. WWW Property sheet constructor
  1017. Arguments:
  1018. LPCTSTR pszCaption : Sheet caption
  1019. LPCTSTR lpszServer : Server name
  1020. DWORD dwInstance : Instance number
  1021. LPCTSTR lpszParent : Parent path
  1022. LPCTSTR lpszAlias : Alias name
  1023. CWnd * pParentWnd : Parent window
  1024. LPARAM lParam : Parameter for MMC console
  1025. LONG_PTR handle : MMC console handle
  1026. UINT iSelectPage : Initial page selected or -1
  1027. Return Value:
  1028. N/A
  1029. --*/
  1030. : CInetPropertySheet(
  1031. pszCaption,
  1032. lpszServer,
  1033. g_cszSvc,
  1034. dwInstance,
  1035. lpszParent,
  1036. lpszAlias,
  1037. pParentWnd,
  1038. lParam,
  1039. handle,
  1040. iSelectPage
  1041. ),
  1042. m_fNew(FALSE),
  1043. m_dwAttributes(dwAttributes),
  1044. m_ppropInst(NULL),
  1045. m_ppropDir(NULL)
  1046. {
  1047. }
  1048. CW3Sheet::~CW3Sheet()
  1049. /*++
  1050. Routine Description:
  1051. Sheet destructor
  1052. Arguments:
  1053. N/A
  1054. Return Value:
  1055. N/A
  1056. --*/
  1057. {
  1058. FreeConfigurationParameters();
  1059. //
  1060. // Must be deleted by now
  1061. //
  1062. ASSERT(m_ppropInst == NULL);
  1063. ASSERT(m_ppropDir == NULL);
  1064. }
  1065. void
  1066. CW3Sheet::WinHelp(
  1067. IN DWORD dwData,
  1068. IN UINT nCmd
  1069. )
  1070. /*++
  1071. Routine Description:
  1072. WWW Property sheet help handler
  1073. Arguments:
  1074. DWORD dwData : WinHelp data (dialog ID)
  1075. UINT nCmd : WinHelp command
  1076. Return Value:
  1077. None
  1078. Notes:
  1079. Replace the dialog ID if this is the directory tab. We have
  1080. different help depending on virtual directory, home, file, directory.
  1081. --*/
  1082. {
  1083. if (dwData == HIDD_DIRECTORY_PROPERTIES)
  1084. {
  1085. if (IS_FILE(m_dwAttributes))
  1086. {
  1087. dwData = HIDD_FS_FILE_PROPERTIES;
  1088. }
  1089. else if (IS_DIR(m_dwAttributes))
  1090. {
  1091. dwData = HIDD_FS_DIRECTORY_PROPERTIES;
  1092. }
  1093. else
  1094. {
  1095. ASSERT(IS_VROOT(m_dwAttributes));
  1096. ASSERT(m_ppropDir != NULL);
  1097. if (!::lstrcmpi(m_ppropDir->m_strAlias, g_cszRoot))
  1098. {
  1099. //
  1100. // It's a home virtual directory -- change the ID
  1101. //
  1102. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  1103. }
  1104. }
  1105. }
  1106. CInetPropertySheet::WinHelp(dwData, nCmd);
  1107. }
  1108. /* virtual */
  1109. HRESULT
  1110. CW3Sheet::LoadConfigurationParameters()
  1111. /*++
  1112. Routine Description:
  1113. Load configuration parameters information
  1114. Arguments:
  1115. None
  1116. Return Value:
  1117. HRESULT
  1118. --*/
  1119. {
  1120. CError err;
  1121. if (m_ppropInst == NULL)
  1122. {
  1123. ASSERT(m_ppropDir == NULL);
  1124. m_ppropInst = new CW3InstanceProps(m_strServer, m_dwInstance);
  1125. m_ppropDir = new CW3DirProps(
  1126. m_strServer,
  1127. m_dwInstance,
  1128. m_strParent,
  1129. m_strAlias
  1130. );
  1131. if (!m_ppropInst || !m_ppropDir)
  1132. {
  1133. err = ERROR_NOT_ENOUGH_MEMORY;
  1134. return err;
  1135. }
  1136. err = m_ppropInst->LoadData();
  1137. if (err.Succeeded())
  1138. {
  1139. err = m_ppropDir->LoadData();
  1140. }
  1141. }
  1142. return err;
  1143. }
  1144. /* virtual */
  1145. void
  1146. CW3Sheet::FreeConfigurationParameters()
  1147. /*++
  1148. Routine Description:
  1149. Clean up configuration data
  1150. Arguments:
  1151. None
  1152. Return Value:
  1153. None
  1154. --*/
  1155. {
  1156. //
  1157. // Must be deleted by now
  1158. //
  1159. ASSERT(m_ppropInst != NULL);
  1160. ASSERT(m_ppropDir != NULL);
  1161. SAFE_DELETE(m_ppropInst);
  1162. SAFE_DELETE(m_ppropDir);
  1163. }
  1164. //
  1165. // Global DLL instance
  1166. //
  1167. HINSTANCE hInstance;
  1168. //
  1169. // ISM API Functions
  1170. //
  1171. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1172. extern "C" DWORD APIENTRY
  1173. ISMQueryServiceInfo(
  1174. OUT ISMSERVICEINFO * psi
  1175. )
  1176. /*++
  1177. Routine Description:
  1178. Return service-specific information back to to the application. This
  1179. function is called by the service manager immediately after
  1180. LoadLibary(); The size element must be set prior to calling this API.
  1181. Arguments:
  1182. ISMSERVICEINFO * psi : Service information returned.
  1183. Return Value:
  1184. Error return value
  1185. --*/
  1186. {
  1187. AFX_MANAGE_STATE(AfxGetStaticModuleState() );
  1188. ASSERT(psi != NULL);
  1189. ASSERT(psi->dwSize == ISMSERVICEINFO_SIZE);
  1190. psi->dwSize = ISMSERVICEINFO_SIZE;
  1191. psi->dwVersion = ISM_VERSION;
  1192. psi->flServiceInfoFlags = 0
  1193. | ISMI_INETSLOCDISCOVER
  1194. | ISMI_CANCONTROLSERVICE
  1195. | ISMI_CANPAUSESERVICE
  1196. | ISMI_UNDERSTANDINSTANCE
  1197. | ISMI_NORMALTBMAPPING
  1198. | ISMI_INSTANCES
  1199. | ISMI_CHILDREN
  1200. | ISMI_FILESYSTEM
  1201. | ISMI_TASKPADS
  1202. | ISMI_SECURITYWIZARD
  1203. | ISMI_HASWEBPROTOCOL
  1204. | ISMI_SUPPORTSMETABASE
  1205. | ISMI_SUPPORTSMASTER
  1206. ; /**/
  1207. ASSERT(::lstrlen(SERVICE_LONG_NAME) <= MAX_LNLEN);
  1208. ASSERT(::lstrlen(SERVICE_SHORT_NAME) <= MAX_SNLEN);
  1209. psi->ullDiscoveryMask = INETSLOC_MASK;
  1210. psi->rgbButtonBkMask = BUTTON_BMP_BACKGROUND;
  1211. psi->nButtonBitmapID = BUTTON_BMP_ID;
  1212. psi->rgbServiceBkMask = SERVICE_BMP_BACKGROUND;
  1213. psi->nServiceBitmapID = SERVICE_BMP_ID;
  1214. psi->rgbLargeServiceBkMask = SERVICE_BMP_BACKGROUND;
  1215. psi->nLargeServiceBitmapID = SERVICE_BMP32_ID;
  1216. ::lstrcpy(psi->atchShortName, SERVICE_SHORT_NAME);
  1217. ::lstrcpy(psi->atchLongName, SERVICE_LONG_NAME);
  1218. //
  1219. // /* K2 */
  1220. //
  1221. psi->rgbChildBkMask = CHILD_BMP_BACKGROUND;
  1222. psi->nChildBitmapID = CHILD_BMP_ID ;
  1223. psi->rgbLargeChildBkMask = CHILD_BMP_BACKGROUND;
  1224. psi->nLargeChildBitmapID = CHILD_BMP32_ID;
  1225. //
  1226. // IIS 5
  1227. //
  1228. ASSERT(::lstrlen(SERVICE_PROTOCOL) <= MAX_SNLEN);
  1229. ASSERT(::lstrlen(g_cszSvc) <= MAX_SNLEN);
  1230. ::lstrcpy(psi->atchProtocol, SERVICE_PROTOCOL);
  1231. ::lstrcpy(psi->atchMetaBaseName, g_cszSvc);
  1232. return ERROR_SUCCESS;
  1233. }
  1234. extern "C" DWORD APIENTRY
  1235. ISMDiscoverServers(
  1236. OUT ISMSERVERINFO * psi,
  1237. IN DWORD * pdwBufferSize,
  1238. IN OUT int * cServers
  1239. )
  1240. /*++
  1241. Routine Description:
  1242. Discover machines running this service. This is only necessary for
  1243. services not discovered with inetscloc (which don't give a mask)
  1244. Arguments:
  1245. ISMSERVERINFO * psi : Server info buffer.
  1246. DWORD * pdwBufferSize : Size required/available.
  1247. OUT int * cServers : Number of servers in buffer.
  1248. Return Value:
  1249. Error return code
  1250. --*/
  1251. {
  1252. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1253. *cServers = 0;
  1254. *pdwBufferSize = 0L;
  1255. //
  1256. // We're an inetsloc service
  1257. //
  1258. TRACEEOLID("Warning: service manager called bogus ISMDiscoverServers");
  1259. ASSERT(FALSE);
  1260. return ERROR_SUCCESS;
  1261. }
  1262. extern "C" DWORD APIENTRY
  1263. ISMQueryServerInfo(
  1264. IN LPCTSTR lpszServerName,
  1265. OUT ISMSERVERINFO * psi
  1266. )
  1267. /*++
  1268. Routine Description:
  1269. Get information about a specific server with regards to this service.
  1270. Arguments:
  1271. LPCTSTR lpszServerName : Name of server.
  1272. ISMSERVERINFO * psi : Server information returned.
  1273. Return Value:
  1274. Error return code
  1275. --*/
  1276. {
  1277. AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
  1278. ASSERT(psi != NULL);
  1279. ASSERT(psi->dwSize == ISMSERVERINFO_SIZE);
  1280. ASSERT(::lstrlen(lpszServerName) <= MAX_SERVERNAME_LEN);
  1281. psi->dwSize = ISMSERVERINFO_SIZE;
  1282. ::lstrcpy(psi->atchServerName, lpszServerName);
  1283. //
  1284. // Start with NULL comment
  1285. //
  1286. *psi->atchComment = _T('\0');
  1287. //
  1288. // First look at the SC
  1289. //
  1290. CError err(::QueryInetServiceStatus(
  1291. psi->atchServerName,
  1292. SERVICE_SC_NAME,
  1293. &(psi->nState)
  1294. ));
  1295. if (err.Failed())
  1296. {
  1297. psi->nState = INetServiceUnknown;
  1298. return err.Win32Error();
  1299. }
  1300. //
  1301. // Check the metabase to see if the service is installed
  1302. //
  1303. CMetaKey mk(lpszServerName, METADATA_PERMISSION_READ, g_cszSvc);
  1304. err = mk.QueryResult();
  1305. if (err.Failed())
  1306. {
  1307. if (err == REGDB_E_CLASSNOTREG)
  1308. {
  1309. //
  1310. // Ok, the service is there, but the metabase is not.
  1311. // This must be the old IIS 1-3 version of this service,
  1312. // which doesn't count as having the service installed.
  1313. //
  1314. return ERROR_SERVICE_DOES_NOT_EXIST;
  1315. }
  1316. return err;
  1317. }
  1318. //
  1319. // If not exist, return bogus acceptable error
  1320. //
  1321. return (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1322. ? ERROR_SERVICE_DOES_NOT_EXIST
  1323. : err;
  1324. }
  1325. extern "C" DWORD APIENTRY
  1326. ISMChangeServiceState(
  1327. IN int nNewState,
  1328. OUT int * pnCurrentState,
  1329. IN DWORD dwInstance,
  1330. IN LPCTSTR lpszServers
  1331. )
  1332. /*++
  1333. Routine Description:
  1334. Change the service state of the servers (to paused/continue, started,
  1335. stopped, etc)
  1336. Arguments:
  1337. int nNewState : INetService definition.
  1338. int * pnCurrentState : Ptr to current state (will be changed
  1339. DWORD dwInstance : Instance or 0 for the service itself
  1340. LPCTSTR lpszServers : Double NULL terminated list of servers.
  1341. Return Value:
  1342. Error return code
  1343. --*/
  1344. {
  1345. AFX_MANAGE_STATE(AfxGetStaticModuleState() );
  1346. ASSERT(nNewState >= INetServiceStopped
  1347. && nNewState <= INetServicePaused);
  1348. if (IS_MASTER_INSTANCE(dwInstance))
  1349. {
  1350. return ChangeInetServiceState(
  1351. lpszServers,
  1352. SERVICE_SC_NAME,
  1353. nNewState,
  1354. pnCurrentState
  1355. );
  1356. }
  1357. //
  1358. // Change the state of the instance
  1359. //
  1360. CInstanceProps inst(lpszServers, g_cszSvc, dwInstance);
  1361. inst.LoadData();
  1362. CError err(inst.ChangeState(nNewState));
  1363. *pnCurrentState = inst.m_nISMState;
  1364. return err.Win32Error();
  1365. }
  1366. extern "C" DWORD APIENTRY
  1367. ISMConfigureServers(
  1368. IN HWND hWnd,
  1369. IN DWORD dwInstance,
  1370. IN LPCTSTR lpszServers
  1371. )
  1372. /*++
  1373. Routine Description:
  1374. Display configuration property sheet.
  1375. Arguments:
  1376. HWND hWnd : Main app window handle
  1377. DWORD dwInstance : Instance number
  1378. LPCTSTR lpszServers : Double NULL terminated list of servers
  1379. Return Value:
  1380. Error return code
  1381. --*/
  1382. {
  1383. AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
  1384. DWORD err = ERROR_SUCCESS;
  1385. //
  1386. // Convert the list of servers to a
  1387. // more manageable CStringList.
  1388. //
  1389. CStringList strlServers;
  1390. err = ConvertDoubleNullListToStringList(lpszServers, strlServers);
  1391. if (err != ERROR_SUCCESS)
  1392. {
  1393. TRACEEOLID("Error building server string list");
  1394. return err;
  1395. }
  1396. CString strCaption;
  1397. if (strlServers.GetCount() == 1)
  1398. {
  1399. CString str;
  1400. LPCTSTR lpComputer = PURE_COMPUTER_NAME(lpszServers);
  1401. if (IS_MASTER_INSTANCE(dwInstance))
  1402. {
  1403. VERIFY(str.LoadString(IDS_CAPTION_DEFAULT));
  1404. strCaption.Format(str, lpComputer);
  1405. }
  1406. else
  1407. {
  1408. VERIFY(str.LoadString(IDS_CAPTION));
  1409. strCaption.Format(str, dwInstance, lpComputer);
  1410. }
  1411. }
  1412. else // Multiple server caption
  1413. {
  1414. VERIFY(strCaption.LoadString(IDS_CAPTION_MULTIPLE));
  1415. }
  1416. ASSERT(strlServers.GetCount() == 1);
  1417. //
  1418. // Get the server name
  1419. //
  1420. LPCTSTR lpszServer = strlServers.GetHead();
  1421. DWORD dwAttributes = FILE_ATTRIBUTE_VIRTUAL_DIRECTORY;
  1422. CW3Sheet * pSheet = NULL;
  1423. try
  1424. {
  1425. //
  1426. // Call the APIs and build the property pages
  1427. //
  1428. pSheet = new CW3Sheet(
  1429. strCaption,
  1430. dwAttributes,
  1431. lpszServer,
  1432. dwInstance,
  1433. NULL,
  1434. g_cszRoot,
  1435. CWnd::FromHandlePermanent(hWnd)
  1436. );
  1437. pSheet->AddRef();
  1438. if (SUCCEEDED(pSheet->QueryInstanceResult()))
  1439. {
  1440. //
  1441. // Add instance pages
  1442. //
  1443. pSheet->AddPage(new CW3ServicePage(pSheet));
  1444. if (pSheet->cap().HasOperatorList() && pSheet->HasAdminAccess())
  1445. {
  1446. pSheet->AddPage(new CW3AccountsPage(pSheet));
  1447. }
  1448. pSheet->AddPage(new CW3PerfPage(pSheet));
  1449. pSheet->AddPage(new CW3FiltersPage(pSheet));
  1450. }
  1451. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  1452. {
  1453. //
  1454. // Add directory pages
  1455. //
  1456. pSheet->AddPage(new CW3DirectoryPage(pSheet, TRUE));
  1457. pSheet->AddPage(new CW3DocumentsPage(pSheet));
  1458. pSheet->AddPage(new CW3SecurityPage(pSheet, TRUE, dwAttributes));
  1459. pSheet->AddPage(new CW3HTTPPage(pSheet));
  1460. pSheet->AddPage(new CW3ErrorsPage(pSheet));
  1461. }
  1462. if(dwInstance == MASTER_INSTANCE)
  1463. {
  1464. pSheet->AddPage(new CDefWebSitePage(pSheet));
  1465. }
  1466. }
  1467. catch(CMemoryException * e)
  1468. {
  1469. TRACEEOLID("Aborting due to exception");
  1470. err = ERROR_NOT_ENOUGH_MEMORY;
  1471. e->Delete();
  1472. }
  1473. if (err == ERROR_SUCCESS)
  1474. {
  1475. ASSERT(pSheet != NULL);
  1476. pSheet->DoModal();
  1477. pSheet->Release();
  1478. }
  1479. //
  1480. // Sheet and pages clean themselves up
  1481. //
  1482. return err;
  1483. }
  1484. //
  1485. // K2 Functions
  1486. //
  1487. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1488. HRESULT
  1489. AddMMCPage(
  1490. IN LPPROPERTYSHEETCALLBACK lpProvider,
  1491. IN CPropertyPage * pg
  1492. )
  1493. /*++
  1494. Routine Description:
  1495. Helper function to add MFC property page using callback provider
  1496. to MMC.
  1497. Arguments:
  1498. LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider
  1499. CPropertyPage * pg : MFC property page object
  1500. Return Value:
  1501. HRESULT
  1502. --*/
  1503. {
  1504. ASSERT(pg != NULL);
  1505. //
  1506. // Patch MFC property page class.
  1507. //
  1508. MMCPropPageCallback(&pg->m_psp);
  1509. HPROPSHEETPAGE hPage = CreatePropertySheetPage(
  1510. (LPCPROPSHEETPAGE)&pg->m_psp
  1511. );
  1512. if (hPage == NULL)
  1513. {
  1514. return E_UNEXPECTED;
  1515. }
  1516. lpProvider->AddPage(hPage);
  1517. return S_OK;
  1518. }
  1519. extern "C" HRESULT APIENTRY
  1520. ISMBind(
  1521. IN LPCTSTR lpszServer,
  1522. OUT HANDLE * phServer
  1523. )
  1524. /*++
  1525. Routine Description:
  1526. Generate a handle for the server name.
  1527. Arguments:
  1528. LPCTSTR lpszServer : Server name
  1529. HANDLE * phServer : Returns a handle
  1530. Return Value:
  1531. HRESULT
  1532. --*/
  1533. {
  1534. return COMDLL_ISMBind(lpszServer, phServer);
  1535. }
  1536. extern "C" HRESULT APIENTRY
  1537. ISMUnbind(
  1538. IN HANDLE hServer
  1539. )
  1540. /*++
  1541. Routine Description:
  1542. Free up the server handle
  1543. Arguments:
  1544. HANDLE hServer : Server handle
  1545. Return Value:
  1546. HRESULT
  1547. --*/
  1548. {
  1549. return COMDLL_ISMUnbind(hServer);
  1550. }
  1551. extern "C" HRESULT APIENTRY
  1552. ISMMMCConfigureServers(
  1553. IN HANDLE hServer,
  1554. IN PVOID lpfnMMCCallbackProvider,
  1555. IN LPARAM param,
  1556. IN LONG_PTR handle,
  1557. IN DWORD dwInstance
  1558. )
  1559. /*++
  1560. Routine Description:
  1561. Display configuration property sheet.
  1562. Arguments:
  1563. HANDLE hServer : Server handle
  1564. PVOID lpfnMMCCallbackProvider : MMC Callback provider
  1565. LPARAM param : MMC LPARAM
  1566. LONG_PTR handle : MMC Console handle
  1567. DWORD dwInstance : Instance number
  1568. Return Value:
  1569. HRESULT
  1570. --*/
  1571. {
  1572. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1573. CError err;
  1574. LPPROPERTYSHEETCALLBACK lpProvider =
  1575. (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
  1576. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  1577. ASSERT(lpszServer != NULL);
  1578. CString str, strCaption;
  1579. LPCTSTR lpszComputer = PURE_COMPUTER_NAME(lpszServer);
  1580. if(IS_MASTER_INSTANCE(dwInstance))
  1581. {
  1582. VERIFY(str.LoadString(IDS_CAPTION_DEFAULT));
  1583. strCaption.Format(str, lpszComputer);
  1584. }
  1585. else
  1586. {
  1587. VERIFY(str.LoadString(IDS_CAPTION));
  1588. strCaption.Format(str, dwInstance, lpszComputer);
  1589. }
  1590. DWORD dwAttributes = FILE_ATTRIBUTE_VIRTUAL_DIRECTORY;
  1591. CW3Sheet * pSheet = NULL;
  1592. try
  1593. {
  1594. //
  1595. // Call the APIs and build the property pages
  1596. //
  1597. pSheet = new CW3Sheet(
  1598. strCaption,
  1599. dwAttributes,
  1600. lpszServer,
  1601. dwInstance,
  1602. NULL,
  1603. g_cszRoot,
  1604. NULL,
  1605. param,
  1606. handle
  1607. );
  1608. pSheet->SetModeless();
  1609. if (SUCCEEDED(pSheet->QueryInstanceResult()))
  1610. {
  1611. //
  1612. // Add instance pages
  1613. //
  1614. AddMMCPage(lpProvider, new CW3ServicePage(pSheet));
  1615. if (pSheet->cap().HasOperatorList() && pSheet->HasAdminAccess())
  1616. {
  1617. AddMMCPage(lpProvider, new CW3AccountsPage(pSheet));
  1618. }
  1619. AddMMCPage(lpProvider, new CW3PerfPage(pSheet));
  1620. AddMMCPage(lpProvider, new CW3FiltersPage(pSheet));
  1621. }
  1622. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  1623. {
  1624. //
  1625. // Add directory pages
  1626. //
  1627. AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, TRUE));
  1628. AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  1629. AddMMCPage(lpProvider, new CW3SecurityPage(pSheet,TRUE, dwAttributes));
  1630. AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1631. AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1632. }
  1633. if(dwInstance == MASTER_INSTANCE)
  1634. {
  1635. AddMMCPage(lpProvider, new CDefWebSitePage(pSheet));
  1636. }
  1637. }
  1638. catch(CMemoryException * e)
  1639. {
  1640. TRACEEOLID("Aborting due to exception");
  1641. err = ERROR_NOT_ENOUGH_MEMORY;
  1642. e->Delete();
  1643. }
  1644. //
  1645. // Sheet and pages clean themselves up
  1646. //
  1647. return err;
  1648. }
  1649. extern "C" HRESULT APIENTRY
  1650. ISMMMCConfigureChild(
  1651. IN HANDLE hServer,
  1652. IN PVOID lpfnMMCCallbackProvider,
  1653. IN LPARAM param,
  1654. IN LONG_PTR handle,
  1655. IN DWORD dwAttributes,
  1656. IN DWORD dwInstance,
  1657. IN LPCTSTR lpszParent,
  1658. IN LPCTSTR lpszAlias
  1659. )
  1660. /*++
  1661. Routine Description:
  1662. Display configuration property sheet for child object.
  1663. Arguments:
  1664. HANDLE hServer : Server handle
  1665. PVOID lpfnMMCCallbackProvider : MMC Callback provider
  1666. LPARAM param : MMC parameter passed to sheet
  1667. LONG_PTR handle : MMC console handle
  1668. DWORD dwAttributes : Must be FILE_ATTRIBUTE_VIRTUAL_DIRECTORY
  1669. DWORD dwInstance : Parent instance number
  1670. LPCTSTR lpszParent : Parent path
  1671. LPCTSTR lpszAlias : Child to configure
  1672. Return Value:
  1673. Error return code
  1674. --*/
  1675. {
  1676. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1677. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  1678. CError err;
  1679. LPPROPERTYSHEETCALLBACK lpProvider =
  1680. (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
  1681. CString strCaption;
  1682. {
  1683. CString str;
  1684. VERIFY(str.LoadString(IDS_DIR_TITLE));
  1685. strCaption.Format(str, lpszAlias);
  1686. }
  1687. CW3Sheet * pSheet = NULL;
  1688. try
  1689. {
  1690. pSheet = new CW3Sheet(
  1691. strCaption,
  1692. dwAttributes,
  1693. lpszServer,
  1694. dwInstance,
  1695. lpszParent,
  1696. lpszAlias,
  1697. NULL,
  1698. param,
  1699. handle
  1700. );
  1701. pSheet->SetModeless();
  1702. //
  1703. // Do not allow editing of a file/dir which is overridden
  1704. // by an alias.
  1705. //
  1706. #pragma message("Warning: file/vroot check stubbed out")
  1707. /*
  1708. if (!IS_VROOT(dwAttributes)
  1709. && !pSheet->GetDirectoryProperties().IsPathInherited())
  1710. {
  1711. ::AfxMessageBox(IDS_ERR_VROOT_OVERRIDE);
  1712. pSheet->Release();
  1713. return S_OK;
  1714. }
  1715. */
  1716. //
  1717. // Call the APIs and build the property pages
  1718. //
  1719. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  1720. {
  1721. AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, FALSE, dwAttributes));
  1722. if (!IS_FILE(dwAttributes))
  1723. {
  1724. AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  1725. }
  1726. AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, dwAttributes));
  1727. AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1728. AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1729. }
  1730. }
  1731. catch(CMemoryException * e)
  1732. {
  1733. TRACEEOLID("Aborting due to exception");
  1734. err = ERROR_NOT_ENOUGH_MEMORY;
  1735. e->Delete();
  1736. }
  1737. //
  1738. // Sheet and pages will delete themselves
  1739. //
  1740. return err;
  1741. }
  1742. extern "C" HRESULT APIENTRY
  1743. ISMEnumerateInstances(
  1744. IN HANDLE hServer,
  1745. OUT ISMINSTANCEINFO * pii,
  1746. OUT IN HANDLE * phEnum
  1747. )
  1748. /*++
  1749. Routine Description:
  1750. Enumerate Instances. First call with *phEnum == NULL.
  1751. Arguments:
  1752. HANDLE hServer : Server handle
  1753. ISMINSTANCEINFO * pii : Instance info buffer
  1754. HANDLE * phEnum : Enumeration handle.
  1755. Return Value:
  1756. Error return code
  1757. --*/
  1758. {
  1759. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1760. CError err;
  1761. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1762. ASSERT(pInterface != NULL);
  1763. BEGIN_ASSURE_BINDING_SECTION
  1764. err = COMDLL_ISMEnumerateInstances(
  1765. pInterface,
  1766. pii,
  1767. phEnum,
  1768. g_cszSvc
  1769. );
  1770. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS)
  1771. return err;
  1772. }
  1773. extern "C" HRESULT APIENTRY
  1774. ISMAddInstance(
  1775. IN HANDLE hServer,
  1776. IN DWORD dwSourceInstance,
  1777. OUT ISMINSTANCEINFO * pii, OPTIONAL
  1778. IN DWORD dwBufferSize
  1779. )
  1780. /*++
  1781. Routine Description:
  1782. Add an instance.
  1783. Arguments:
  1784. HANDLE hServer : Server handle
  1785. DWORD dwSourceInstance : Source instance ID to clone
  1786. ISMINSTANCEINFO * pii : Instance info buffer. May be NULL
  1787. DWORD dwBufferSize : Size of buffer
  1788. Return Value:
  1789. Error return code.
  1790. --*/
  1791. {
  1792. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1793. CIISWizardSheet sheet(IDB_WIZ_LEFT, IDB_WIZ_HEAD);
  1794. CIISWebWizSettings ws(hServer, g_cszSvc);
  1795. CIISWizardBookEnd pgWelcome(
  1796. IDS_SITE_WELCOME,
  1797. IDS_NEW_SITE_WIZARD,
  1798. IDS_SITE_BODY
  1799. );
  1800. CVDWPDescription pgDescr(&ws);
  1801. CVDWPBindings pgBindings(&ws);
  1802. CVDWPPath pgHome(&ws, FALSE);
  1803. CVDWPUserName pgUserName(&ws, FALSE);
  1804. CVDWPPermissions pgPerms(&ws, FALSE);
  1805. CIISWizardBookEnd pgCompletion(
  1806. &ws.m_hrResult,
  1807. IDS_SITE_SUCCESS,
  1808. IDS_SITE_FAILURE,
  1809. IDS_NEW_SITE_WIZARD
  1810. );
  1811. sheet.AddPage(&pgWelcome);
  1812. sheet.AddPage(&pgDescr);
  1813. sheet.AddPage(&pgBindings);
  1814. sheet.AddPage(&pgHome);
  1815. sheet.AddPage(&pgUserName);
  1816. sheet.AddPage(&pgPerms);
  1817. sheet.AddPage(&pgCompletion);
  1818. if (sheet.DoModal() == IDCANCEL)
  1819. {
  1820. return CError::HResult(ERROR_CANCELLED);
  1821. }
  1822. CError err(ws.m_hrResult);
  1823. if (err.Succeeded())
  1824. {
  1825. //
  1826. // Get info on it to be returned.
  1827. //
  1828. ISMQueryInstanceInfo(
  1829. hServer,
  1830. WITHOUT_INHERITANCE,
  1831. pii,
  1832. ws.m_dwInstance
  1833. );
  1834. }
  1835. return err;
  1836. }
  1837. extern "C" HRESULT APIENTRY
  1838. ISMDeleteInstance(
  1839. IN HANDLE hServer,
  1840. IN DWORD dwInstance
  1841. )
  1842. /*++
  1843. Routine Description:
  1844. Delete an instance
  1845. Arguments:
  1846. HANDLE hServer : Server handle
  1847. DWORD dwInstance : Instance to be deleted
  1848. Return Value:
  1849. Error return code.
  1850. --*/
  1851. {
  1852. AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
  1853. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  1854. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  1855. //
  1856. // First, attempt to delete the applications that might live
  1857. // here
  1858. //
  1859. CIISApplication app(lpszServer, g_cszSvc, dwInstance, g_cszRoot);
  1860. CError err(app.QueryResult());
  1861. if(err.Succeeded())
  1862. {
  1863. //
  1864. // Recursively delete all app info
  1865. //
  1866. err = app.DeleteRecoverable(TRUE);
  1867. }
  1868. if (err.Succeeded())
  1869. {
  1870. BEGIN_ASSURE_BINDING_SECTION
  1871. err = CInstanceProps::Delete(
  1872. pKey,
  1873. g_cszSvc,
  1874. dwInstance
  1875. );
  1876. END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
  1877. if (err.Failed())
  1878. {
  1879. //
  1880. // Failed to delete the instance -- recover application
  1881. // information recursively
  1882. //
  1883. app.Recover(TRUE);
  1884. }
  1885. }
  1886. return err;
  1887. }
  1888. extern "C" HRESULT APIENTRY
  1889. ISMEnumerateChildren(
  1890. IN HANDLE hServer,
  1891. OUT ISMCHILDINFO * pii,
  1892. OUT IN HANDLE * phEnum,
  1893. IN DWORD dwInstance,
  1894. IN LPCTSTR lpszParent
  1895. )
  1896. /*++
  1897. Routine Description:
  1898. Enumerate children. First call with *phEnum == NULL;
  1899. Arguments:
  1900. HANDLE hServer : Server handle
  1901. ISMCHILDINFO * pii : Child info buffer
  1902. HANDLE * phEnum : Enumeration handle.
  1903. DWORD dwInstance : Parent instance
  1904. LPCTSTR lpszParent : Parent path
  1905. Return Value:
  1906. Error return code.
  1907. --*/
  1908. {
  1909. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1910. CError err;
  1911. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1912. ASSERT(pInterface != NULL);
  1913. BEGIN_ASSURE_BINDING_SECTION
  1914. err = COMDLL_ISMEnumerateChildren(
  1915. pInterface,
  1916. pii,
  1917. phEnum,
  1918. g_cszSvc,
  1919. dwInstance,
  1920. lpszParent
  1921. );
  1922. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS);
  1923. return err;
  1924. }
  1925. extern "C" HRESULT APIENTRY
  1926. ISMAddChild(
  1927. IN HANDLE hServer,
  1928. OUT ISMCHILDINFO * pii,
  1929. IN DWORD dwBufferSize,
  1930. IN DWORD dwInstance,
  1931. IN LPCTSTR lpszParent
  1932. )
  1933. /*++
  1934. Routine Description:
  1935. Add a child.
  1936. Arguments:
  1937. HANDLE hServer : Server handle
  1938. ISMCHILDINFO * pii : Child info buffer. May be NULL
  1939. DWORD dwBufferSize : Size of info buffer
  1940. DWORD dwInstance : Parent instance
  1941. LPCTSTR lpszParent : Parent path
  1942. Return Value:
  1943. Error return code.
  1944. --*/
  1945. {
  1946. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1947. CIISWizardSheet sheet(IDB_WIZ_LEFT_DIR, IDB_WIZ_HEAD_DIR);
  1948. CIISWebWizSettings ws(hServer, g_cszSvc, dwInstance, lpszParent);
  1949. CIISWizardBookEnd pgWelcome(
  1950. IDS_VDIR_WELCOME,
  1951. IDS_NEW_VDIR_WIZARD,
  1952. IDS_VDIR_BODY
  1953. );
  1954. CVDWPAlias pgAlias(&ws);
  1955. CVDWPPath pgPath(&ws, TRUE);
  1956. CVDWPUserName pgUserName(&ws, TRUE);
  1957. CVDWPPermissions pgPerms(&ws, TRUE);
  1958. CIISWizardBookEnd pgCompletion(
  1959. &ws.m_hrResult,
  1960. IDS_VDIR_SUCCESS,
  1961. IDS_VDIR_FAILURE,
  1962. IDS_NEW_VDIR_WIZARD
  1963. );
  1964. sheet.AddPage(&pgWelcome);
  1965. sheet.AddPage(&pgAlias);
  1966. sheet.AddPage(&pgPath);
  1967. sheet.AddPage(&pgUserName);
  1968. sheet.AddPage(&pgPerms);
  1969. sheet.AddPage(&pgCompletion);
  1970. if (sheet.DoModal() == IDCANCEL)
  1971. {
  1972. return ERROR_CANCELLED;
  1973. }
  1974. CError err(ws.m_hrResult);
  1975. if (err.Succeeded())
  1976. {
  1977. err = ISMQueryChildInfo(
  1978. ws.m_pKey,
  1979. WITH_INHERITANCE,
  1980. pii,
  1981. ws.m_dwInstance,
  1982. ws.m_strParent,
  1983. ws.m_strAlias
  1984. );
  1985. }
  1986. return err;
  1987. }
  1988. extern "C" HRESULT APIENTRY
  1989. ISMDeleteChild(
  1990. IN HANDLE hServer,
  1991. IN DWORD dwInstance,
  1992. IN LPCTSTR lpszParent,
  1993. IN LPCTSTR lpszAlias
  1994. )
  1995. /*++
  1996. Routine Description:
  1997. Delete a child.
  1998. Arguments:
  1999. HANDLE hServer : Server handle
  2000. DWORD dwInstance : Parent instance
  2001. LPCTSTR lpszParent : Parent path
  2002. LPCTSTR lpszAlias : Alias of child to be deleted
  2003. Return Value:
  2004. Error return code.
  2005. --*/
  2006. {
  2007. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2008. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  2009. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  2010. ASSERT(lpszServer != NULL);
  2011. //
  2012. // First, attempt to delete the applications that might live
  2013. // here.
  2014. //
  2015. CIISApplication app(
  2016. lpszServer,
  2017. g_cszSvc,
  2018. dwInstance,
  2019. lpszParent,
  2020. lpszAlias
  2021. );
  2022. CError err(app.QueryResult());
  2023. if (err.Succeeded())
  2024. {
  2025. err = app.DeleteRecoverable(TRUE);
  2026. }
  2027. if (err.Succeeded())
  2028. {
  2029. BEGIN_ASSURE_BINDING_SECTION
  2030. err = CChildNodeProps::Delete(
  2031. pKey,
  2032. g_cszSvc,
  2033. dwInstance,
  2034. lpszParent,
  2035. lpszAlias
  2036. );
  2037. END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
  2038. if (err.Failed())
  2039. {
  2040. //
  2041. // Failed to delete the child node -- recover application
  2042. // information
  2043. //
  2044. app.Recover(TRUE);
  2045. }
  2046. }
  2047. return err;
  2048. }
  2049. extern "C" HRESULT APIENTRY
  2050. ISMRenameChild(
  2051. IN HANDLE hServer,
  2052. IN DWORD dwInstance,
  2053. IN LPCTSTR lpszParent,
  2054. IN LPCTSTR lpszAlias,
  2055. IN LPCTSTR lpszNewName
  2056. )
  2057. /*++
  2058. Routine Description:
  2059. Rename a child.
  2060. Arguments:
  2061. HANDLE hServer : Server handle
  2062. DWORD dwInstance : Parent instance
  2063. LPCTSTR lpszParent : Parent path
  2064. LPCTSTR lpszAlias : Alias of child to be renamed
  2065. LPCTSTR lpszNewName : New alias name
  2066. Return Value:
  2067. Error return code.
  2068. --*/
  2069. {
  2070. AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
  2071. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  2072. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  2073. ASSERT(lpszServer != NULL);
  2074. //
  2075. // First, attempt to delete the applications that might live
  2076. // here.
  2077. //
  2078. CIISApplication app(
  2079. lpszServer,
  2080. g_cszSvc,
  2081. dwInstance,
  2082. lpszParent,
  2083. lpszAlias
  2084. );
  2085. CError err(app.QueryResult());
  2086. if (err.Succeeded())
  2087. {
  2088. //
  2089. // Delete recursively
  2090. //
  2091. err = app.DeleteRecoverable(TRUE);
  2092. }
  2093. if (err.Succeeded())
  2094. {
  2095. BEGIN_ASSURE_BINDING_SECTION
  2096. err = CChildNodeProps::Rename(
  2097. pKey,
  2098. g_cszSvc,
  2099. dwInstance,
  2100. lpszParent,
  2101. lpszAlias,
  2102. lpszNewName
  2103. );
  2104. END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
  2105. if (err.Succeeded())
  2106. {
  2107. //
  2108. // Rename succeeded -- recover application information
  2109. // on the _new_ metabase path.
  2110. //
  2111. CIISApplication appNew(
  2112. lpszServer,
  2113. g_cszSvc,
  2114. dwInstance,
  2115. lpszParent,
  2116. lpszNewName
  2117. );
  2118. err = appNew.QueryResult();
  2119. if (err.Succeeded())
  2120. {
  2121. err = appNew.Recover(TRUE);
  2122. }
  2123. }
  2124. else
  2125. {
  2126. //
  2127. // Failed to delete the child node -- recover application
  2128. // information on the _old_ metabase path (don't disturb the
  2129. // error code).
  2130. //
  2131. app.Recover(TRUE);
  2132. }
  2133. }
  2134. return err;
  2135. }
  2136. extern "C" HRESULT APIENTRY
  2137. ISMQueryInstanceInfo(
  2138. IN HANDLE hServer,
  2139. IN BOOL fInherit,
  2140. OUT ISMINSTANCEINFO * pii,
  2141. IN DWORD dwInstance
  2142. )
  2143. /*++
  2144. Routine Description:
  2145. Get instance specific information.
  2146. Arguments:
  2147. HANDLE hServer : Server handle
  2148. BOOL fInherit : TRUE to inherit, FALSE otherwise
  2149. ISMINSTANCEINFO * pii : Instance info buffer
  2150. LPCTSTR lpszServer : A single server
  2151. DWORD dwInstance : Instance number
  2152. Return Value:
  2153. Error return code.
  2154. --*/
  2155. {
  2156. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2157. ASSERT(pii != NULL);
  2158. CError err;
  2159. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  2160. BEGIN_ASSURE_BINDING_SECTION
  2161. CInstanceProps inst(pKey, g_cszSvc, dwInstance);
  2162. err = inst.LoadData();
  2163. if (err.Succeeded())
  2164. {
  2165. //
  2166. // Set the output structure
  2167. //
  2168. pii->dwSize = ISMINSTANCEINFO_SIZE;
  2169. inst.FillInstanceInfo(pii);
  2170. //
  2171. // Get properties on the home directory
  2172. //
  2173. CChildNodeProps home(
  2174. &inst,
  2175. g_cszSvc,
  2176. dwInstance,
  2177. NULL,
  2178. g_cszRoot,
  2179. fInherit,
  2180. TRUE // Path only
  2181. );
  2182. err = home.LoadData();
  2183. home.FillInstanceInfo(pii);
  2184. }
  2185. END_ASSURE_BINDING_SECTION(err, pKey, err);
  2186. return err.Failed() ? err : S_OK;
  2187. }
  2188. extern "C" HRESULT APIENTRY
  2189. ISMQueryChildInfo(
  2190. IN HANDLE hServer,
  2191. IN BOOL fInherit,
  2192. OUT ISMCHILDINFO * pii,
  2193. IN DWORD dwInstance,
  2194. IN LPCTSTR lpszParent,
  2195. IN LPCTSTR lpszAlias
  2196. )
  2197. /*++
  2198. Routine Description:
  2199. Get child-specific info.
  2200. Arguments:
  2201. HANDLE hServer : Server handle
  2202. BOOL fInherit : TRUE to inherit, FALSE otherwise
  2203. ISMCHILDINFO * pii : Child info buffer
  2204. DWORD dwInstance : Parent instance
  2205. LPCTSTR lpszParent : Parent Path ("" for root)
  2206. LPCTSTR lpszAlias : Alias of child to be deleted
  2207. Return Value:
  2208. Error return code.
  2209. --*/
  2210. {
  2211. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2212. //
  2213. // Get all the inherited properties
  2214. //
  2215. CChildNodeProps node(
  2216. GetMetaKeyFromHandle(hServer),
  2217. g_cszSvc,
  2218. dwInstance,
  2219. lpszParent,
  2220. lpszAlias,
  2221. fInherit,
  2222. FALSE // Everything
  2223. );
  2224. CError err(node.LoadData());
  2225. //
  2226. // Set the output structure
  2227. //
  2228. pii->dwSize = ISMCHILDINFO_SIZE;
  2229. node.FillChildInfo(pii);
  2230. return err;
  2231. }
  2232. extern "C" HRESULT APIENTRY
  2233. ISMConfigureChild(
  2234. IN HANDLE hServer,
  2235. IN HWND hWnd,
  2236. IN DWORD dwAttributes,
  2237. IN DWORD dwInstance,
  2238. IN LPCTSTR lpszParent,
  2239. IN LPCTSTR lpszAlias
  2240. )
  2241. /*++
  2242. Routine Description:
  2243. Configure child.
  2244. Arguments:
  2245. HANDLE hServer : Server handle
  2246. HWND hWnd : Main app window handle
  2247. DWORD dwAttributes : File attributes
  2248. DWORD dwInstance : Parent instance
  2249. LPCTSTR lpszParent : Parent path
  2250. LPCTSTR lpszAlias : Child to configure or NULL
  2251. Return Value:
  2252. Error return code.
  2253. --*/
  2254. {
  2255. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2256. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  2257. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  2258. ASSERT(lpszServer != NULL);
  2259. CError err;
  2260. CString strCaption;
  2261. {
  2262. CString str;
  2263. VERIFY(str.LoadString(IDS_DIR_TITLE));
  2264. strCaption.Format(str, lpszAlias);
  2265. }
  2266. CW3Sheet * pSheet = NULL;
  2267. try
  2268. {
  2269. pSheet = new CW3Sheet(
  2270. strCaption,
  2271. dwAttributes,
  2272. lpszServer,
  2273. dwInstance,
  2274. lpszParent,
  2275. lpszAlias,
  2276. CWnd::FromHandlePermanent(hWnd)
  2277. );
  2278. pSheet->AddRef();
  2279. //
  2280. // Do not allow editing of a file/dir which is overridden
  2281. // by an alias.
  2282. //
  2283. if (!IS_VROOT(dwAttributes)
  2284. && !pSheet->GetDirectoryProperties().IsPathInherited())
  2285. {
  2286. ::AfxMessageBox(IDS_ERR_VROOT_OVERRIDE);
  2287. pSheet->Release();
  2288. return S_OK;
  2289. }
  2290. //
  2291. // Call the APIs and build the property pages
  2292. //
  2293. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  2294. {
  2295. pSheet->AddPage(new CW3DirectoryPage(pSheet, FALSE, dwAttributes));
  2296. if (!IS_FILE(dwAttributes))
  2297. {
  2298. pSheet->AddPage(new CW3DocumentsPage(pSheet));
  2299. }
  2300. pSheet->AddPage(new CW3SecurityPage(pSheet, FALSE, dwAttributes));
  2301. pSheet->AddPage(new CW3HTTPPage(pSheet));
  2302. pSheet->AddPage(new CW3ErrorsPage(pSheet));
  2303. }
  2304. }
  2305. catch(CMemoryException * e)
  2306. {
  2307. TRACEEOLID("Aborting due to exception");
  2308. err = ERROR_NOT_ENOUGH_MEMORY;
  2309. e->Delete();
  2310. }
  2311. if (err.Succeeded())
  2312. {
  2313. ASSERT(pSheet != NULL);
  2314. pSheet->DoModal();
  2315. pSheet->Release();
  2316. }
  2317. //
  2318. // Sheet and pages will delete themselves
  2319. //
  2320. return err;
  2321. }
  2322. //
  2323. // Authentication bit strings
  2324. //
  2325. FLAGTOSTRING fsAuthentications[] =
  2326. {
  2327. { MD_AUTH_ANONYMOUS, IDS_AUTHENTICATION_ANONYMOUS, TRUE },
  2328. { MD_AUTH_ANONYMOUS, IDS_AUTHENTICATION_NO_ANONYMOUS, FALSE },
  2329. { MD_AUTH_BASIC, IDS_AUTHENTICATION_BASIC, TRUE },
  2330. { MD_AUTH_MD5, IDS_AUTHENTICATION_DIGEST, TRUE },
  2331. { MD_AUTH_NT, IDS_AUTHENTICATION_NT, TRUE },
  2332. };
  2333. class CWebSecurityTemplate : public CIISSecurityTemplate
  2334. /*++
  2335. Class Description:
  2336. Web Security template class
  2337. Public Interface:
  2338. CWebSecurityTemplate : Constructor
  2339. ApplySettings : Apply template to destination path
  2340. GenerateSummary : Generate text summary
  2341. --*/
  2342. {
  2343. //
  2344. // Constructor
  2345. //
  2346. public:
  2347. CWebSecurityTemplate(
  2348. IN const CMetaKey * pKey,
  2349. IN LPCTSTR lpszMDPath,
  2350. IN BOOL fInherit
  2351. );
  2352. public:
  2353. //
  2354. // Apply settings to destination path
  2355. //
  2356. virtual HRESULT ApplySettings(
  2357. IN BOOL fUseTemplates,
  2358. IN LPCTSTR lpszServerName,
  2359. IN LPCTSTR lpszService,
  2360. IN DWORD dwInstance = MASTER_INSTANCE,
  2361. IN LPCTSTR lpszParent = NULL,
  2362. IN LPCTSTR lpszAlias = NULL
  2363. );
  2364. virtual void GenerateSummary(
  2365. IN BOOL fUseTemplates,
  2366. IN LPCTSTR lpszServerName,
  2367. IN LPCTSTR lpszService,
  2368. IN DWORD dwInstance = MASTER_INSTANCE,
  2369. IN LPCTSTR lpszParent = NULL,
  2370. IN LPCTSTR lpszAlias = NULL
  2371. );
  2372. protected:
  2373. //
  2374. // Break out GetAllData() data to data fields
  2375. //
  2376. virtual void ParseFields();
  2377. public:
  2378. MP_DWORD m_dwAuthentication;
  2379. MP_DWORD m_dwDirBrowsing;
  2380. };
  2381. CWebSecurityTemplate::CWebSecurityTemplate(
  2382. IN const CMetaKey * pKey,
  2383. IN LPCTSTR lpszMDPath,
  2384. IN BOOL fInherit
  2385. )
  2386. /*++
  2387. Routine Description:
  2388. Construct from open key
  2389. Arguments:
  2390. const CMetaKey * pKey : Open key
  2391. LPCTSTR lpszMDPath : Path
  2392. BOOL fInherit : TRUE to inherit values, FALSE if not
  2393. Return Value:
  2394. N/A
  2395. --*/
  2396. : CIISSecurityTemplate(pKey, lpszMDPath, fInherit),
  2397. m_dwAuthentication(MD_AUTH_ANONYMOUS),
  2398. m_dwDirBrowsing(
  2399. MD_DIRBROW_SHOW_DATE |
  2400. MD_DIRBROW_SHOW_TIME |
  2401. MD_DIRBROW_SHOW_SIZE |
  2402. MD_DIRBROW_SHOW_EXTENSION
  2403. )
  2404. {
  2405. //
  2406. // Managed Properties
  2407. //
  2408. m_dlProperties.AddTail(MD_AUTHORIZATION);
  2409. // m_dlProperties.AddTail(MD_DIRECTORY_BROWSING); // out of IIS 5
  2410. }
  2411. /* virtual */
  2412. void
  2413. CWebSecurityTemplate::ParseFields()
  2414. /*++
  2415. Routine Description:
  2416. Break into fields.
  2417. Arguments:
  2418. None.
  2419. Return Value:
  2420. None.
  2421. --*/
  2422. {
  2423. //
  2424. // Fetch base class values
  2425. //
  2426. CIISSecurityTemplate::ParseFields();
  2427. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  2428. HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthentication)
  2429. //HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing) // Out of IIS 5
  2430. END_PARSE_META_RECORDS
  2431. }
  2432. /* virtual */
  2433. HRESULT
  2434. CWebSecurityTemplate::ApplySettings(
  2435. IN BOOL fUseTemplate,
  2436. IN LPCTSTR lpszServerName,
  2437. IN LPCTSTR lpszService,
  2438. IN DWORD dwInstance,
  2439. IN LPCTSTR lpszParent,
  2440. IN LPCTSTR lpszAlias
  2441. )
  2442. /*++
  2443. Routine Description:
  2444. Apply the settings to the specified destination path
  2445. Arguments:
  2446. BOOL fUseTemplates : TRUE if the source is from a template,
  2447. FALSE if using inheritance.
  2448. LPCTSTR lpszServerName : Server name
  2449. LPCTSTR lpszService : Service name
  2450. DWORD dwInstance : Instance
  2451. LPCTSTR lpszParent : Parent path (or NULL)
  2452. LPCTSTR lpszAlias : Alias name (or NULL)
  2453. Return Value:
  2454. HRESULT
  2455. --*/
  2456. {
  2457. //
  2458. // Write base class properties
  2459. //
  2460. CError err(CIISSecurityTemplate::ApplySettings(
  2461. fUseTemplate,
  2462. lpszServerName,
  2463. lpszService,
  2464. dwInstance,
  2465. lpszParent,
  2466. lpszAlias
  2467. ));
  2468. if (err.Failed())
  2469. {
  2470. return err;
  2471. }
  2472. BOOL fWriteProperties = TRUE;
  2473. CMetaKey mk(
  2474. lpszServerName,
  2475. METADATA_PERMISSION_WRITE,
  2476. lpszService,
  2477. dwInstance,
  2478. lpszParent,
  2479. lpszAlias
  2480. );
  2481. err = mk.QueryResult();
  2482. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  2483. {
  2484. if (!fUseTemplate)
  2485. {
  2486. //
  2487. // No need to delete properties; everything's already
  2488. // inherited. Note that this is the only legit failure
  2489. // case. If using a template, the base class must have
  2490. // created the path by now.
  2491. //
  2492. fWriteProperties = FALSE;
  2493. err.Reset();
  2494. }
  2495. }
  2496. if (fWriteProperties)
  2497. {
  2498. do
  2499. {
  2500. BREAK_ON_ERR_FAILURE(err);
  2501. if (fUseTemplate)
  2502. {
  2503. //
  2504. // Write values from template
  2505. //
  2506. err = mk.SetValue(
  2507. MD_AUTHORIZATION,
  2508. m_dwAuthentication
  2509. );
  2510. BREAK_ON_ERR_FAILURE(err);
  2511. //
  2512. // dir browsing out of iis 5
  2513. //
  2514. /*
  2515. err = mk.SetValue(
  2516. MD_DIRECTORY_BROWSING,
  2517. m_dwDirBrowsing
  2518. );
  2519. BREAK_ON_ERR_FAILURE(err);
  2520. */
  2521. }
  2522. //
  2523. // Nothing to do in the inheritance case, because the
  2524. // base class knows which properties should be deleted
  2525. //
  2526. }
  2527. while(FALSE);
  2528. }
  2529. return err;
  2530. }
  2531. /* virtual */
  2532. void
  2533. CWebSecurityTemplate::GenerateSummary(
  2534. IN BOOL fUseTemplate,
  2535. IN LPCTSTR lpszServerName,
  2536. IN LPCTSTR lpszService,
  2537. IN DWORD dwInstance,
  2538. IN LPCTSTR lpszParent,
  2539. IN LPCTSTR lpszAlias
  2540. )
  2541. /*++
  2542. Routine Description:
  2543. Generate text summary of what's in the security template. Arguments are
  2544. the same as ApplySettings(), so that the summary can reflect what will
  2545. actually be set.
  2546. Arguments:
  2547. BOOL fUseTemplates : TRUE if the source is from a template,
  2548. FALSE if using inheritance.
  2549. LPCTSTR lpszServerName : Server name
  2550. LPCTSTR lpszService : Service name
  2551. DWORD dwInstance : Instance
  2552. LPCTSTR lpszParent : Parent path (or NULL)
  2553. LPCTSTR lpszAlias : Alias name (or NULL)
  2554. Return Value:
  2555. None
  2556. --*/
  2557. {
  2558. AddSummaryString(IDS_AUTHENTICATION_METHODS);
  2559. int i;
  2560. //
  2561. // Summarize Authentication Methods:
  2562. //
  2563. if (m_dwAuthentication == 0L)
  2564. {
  2565. AddSummaryString(IDS_SUMMARY_NONE, 1);
  2566. }
  2567. else
  2568. {
  2569. for (i = 0; i < ARRAY_SIZE(fsAuthentications); ++i)
  2570. {
  2571. if (IS_FLAG_SET(
  2572. m_dwAuthentication,
  2573. fsAuthentications[i].dwFlag
  2574. ) == fsAuthentications[i].fSet)
  2575. {
  2576. AddSummaryString(fsAuthentications[i].nID, 1);
  2577. }
  2578. }
  2579. }
  2580. //
  2581. // CODEWORK: Dir browsing settings in the security wizards are postponed
  2582. // to post IIS 5
  2583. //
  2584. /*
  2585. if (IS_FLAG_SET(m_dwDirBrowsing, MD_DIRBROW_ENABLED))
  2586. {
  2587. AddSummaryString(IDS_DIR_BROWSE_ON, 1);
  2588. }
  2589. else
  2590. {
  2591. AddSummaryString(IDS_DIR_BROWSE_OFF, 1);
  2592. }
  2593. if (IS_FLAG_SET(m_dwDirBrowsing, MD_DIRBROW_LOADDEFAULT))
  2594. {
  2595. AddSummaryString(IDS_LOAD_DEFAULT_ON, 1);
  2596. }
  2597. else
  2598. {
  2599. AddSummaryString(IDS_LOAD_DEFAULT_OFF, 1);
  2600. }
  2601. */
  2602. //
  2603. // Add base class summary
  2604. //
  2605. CIISSecurityTemplate::GenerateSummary(
  2606. fUseTemplate,
  2607. lpszServerName,
  2608. lpszService,
  2609. dwInstance,
  2610. lpszParent,
  2611. lpszAlias
  2612. );
  2613. }
  2614. CIISSecurityTemplate *
  2615. AllocateSecurityTemplate(
  2616. IN const CMetaKey * pKey,
  2617. IN LPCTSTR lpszMDPath,
  2618. IN BOOL fInherit
  2619. )
  2620. /*++
  2621. Routine Description:
  2622. Security template allocator function
  2623. Arguments:
  2624. IN const CMetaKey * pKey : Open key
  2625. IN LPCTSTR lpszMDPath : Path
  2626. IN BOOL fInherit : TRUE to inherit properties
  2627. Return Value:
  2628. Pointer to newly allocated security object
  2629. --*/
  2630. {
  2631. return new CWebSecurityTemplate(pKey, lpszMDPath, fInherit);
  2632. }
  2633. extern "C" HRESULT APIENTRY
  2634. ISMSecurityWizard(
  2635. IN HANDLE hServer,
  2636. IN DWORD dwInstance,
  2637. IN LPCTSTR lpszParent,
  2638. IN LPCTSTR lpszAlias
  2639. )
  2640. /*++
  2641. Routine Description:
  2642. Launch the security wizard
  2643. Arguments:
  2644. HANDLE hServer : Server handle
  2645. DWORD dwInstance : Parent instance
  2646. LPCTSTR lpszParent : Parent path
  2647. LPCTSTR lpszAlias : Child to configure or NULL
  2648. Return Value:
  2649. HRESULT
  2650. --*/
  2651. {
  2652. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2653. return COMDLL_ISMSecurityWizard(
  2654. &AllocateSecurityTemplate,
  2655. GetMetaKeyFromHandle(hServer),
  2656. IDB_WIZ_LEFT_SEC,
  2657. IDB_WIZ_HEAD_SEC,
  2658. g_cszSvc,
  2659. dwInstance,
  2660. lpszParent,
  2661. lpszAlias
  2662. );
  2663. }
  2664. //
  2665. // End of ISM API Functions
  2666. //
  2667. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2668. DWORD
  2669. IsSSLEnabledOnServer(
  2670. IN LPCTSTR lpszServer,
  2671. OUT BOOL & fInstalled,
  2672. OUT BOOL & fEnabled
  2673. )
  2674. /*++
  2675. Routine Description:
  2676. Determine if SSL is installed on the server.
  2677. Arguments:
  2678. LPCTSTR lpszServer : Server name
  2679. BOOL & fInstalled : Returns TRUE if SSL is installed
  2680. BOOL & fEnabled : Returns TRUE if SSL is enabled
  2681. Return Value:
  2682. Error return code.
  2683. --*/
  2684. {
  2685. /*
  2686. LPW3_CONFIG_INFO lp = NULL;
  2687. CString str;
  2688. DWORD err = ::W3GetAdminInformation((LPTSTR)lpszServer, &lp);
  2689. if (err != ERROR_SUCCESS)
  2690. {
  2691. TRACEEOLID("Failed to determine if SSL is installed");
  2692. return err;
  2693. }
  2694. fInstalled = (lp->dwEncCaps & ENC_CAPS_NOT_INSTALLED) == 0;
  2695. fEnabled = (lp->dwEncCaps & ENC_CAPS_DISABLED) == 0;
  2696. NETAPIBUFFERFREE(lp);
  2697. */
  2698. //
  2699. // Above doesn't work for Beta I -- hack to assume true.
  2700. //
  2701. fInstalled = fEnabled = TRUE;
  2702. return ERROR_SUCCESS;
  2703. }
  2704. BOOL
  2705. IsCertInstalledOnServer(
  2706. IN LPCTSTR lpszServerName,
  2707. IN DWORD dwInstance
  2708. )
  2709. /*++
  2710. Routine Description:
  2711. Check to see if a certificate is installed on this virtual server.
  2712. This routine only checks that the cert metabase key was read in.
  2713. by boydm
  2714. Arguments:
  2715. None
  2716. Return Value:
  2717. TRUE if a certificate are installed, FALSE otherwise
  2718. --*/
  2719. {
  2720. CError err;
  2721. BOOL fCertInstalled = FALSE;
  2722. CW3InstanceProps * ppropInst;
  2723. //
  2724. // Get the instance properties
  2725. //
  2726. ppropInst = new CW3InstanceProps(lpszServerName, dwInstance);
  2727. //
  2728. // If it succeeded, load the data, then check the answer
  2729. //
  2730. if (ppropInst)
  2731. {
  2732. err = ppropInst->LoadData();
  2733. if (err.Succeeded())
  2734. {
  2735. //
  2736. // Get the specific data to a local holder
  2737. // weird. You have to declare and assign the blob
  2738. // on different lines. Otherwise it gets constructed
  2739. // wrong and it tries to free an invalid
  2740. // memory block and bad things happen.
  2741. //
  2742. CBlob blobHash;
  2743. blobHash = ppropInst->m_CertHash;
  2744. // CString strStore = ppropInst->m_strCertStoreName;
  2745. //
  2746. // If the certificate hash is there,
  2747. // then we have a certificate
  2748. //
  2749. if (!blobHash.IsEmpty())
  2750. {
  2751. fCertInstalled = TRUE;
  2752. }
  2753. }
  2754. }
  2755. //
  2756. // Clean up since we don't really need the ppropInst after this.
  2757. //
  2758. if (ppropInst)
  2759. {
  2760. delete ppropInst;
  2761. ppropInst = NULL;
  2762. }
  2763. //
  2764. // If that test failed, we may be admining a downlevel IIS4 machine.
  2765. // Unfortunately we can't tell by examining the capability bits,
  2766. // so look to see if the old certs are there.
  2767. //
  2768. if (!fCertInstalled)
  2769. {
  2770. CString strKey;
  2771. CMetaEnumerator me(lpszServerName, g_cszSvc);
  2772. HRESULT err = me.Next(strKey, g_cszSSLKeys);
  2773. fCertInstalled = SUCCEEDED(err);
  2774. }
  2775. return fCertInstalled;
  2776. }
  2777. void
  2778. RunKeyManager(
  2779. IN LPCTSTR lpszServer OPTIONAL
  2780. )
  2781. /*++
  2782. Routine Description:
  2783. Helper function to run the key manager application.
  2784. Arguments:
  2785. None
  2786. Return Value:
  2787. None
  2788. Notes:
  2789. Key manager is run synchronously.
  2790. --*/
  2791. {
  2792. //
  2793. // Want to start key manager. I'm assuming
  2794. // here that the keyring app will be in the
  2795. // same directory as w3scfg.dll (safe assumption
  2796. // for the near future at least)
  2797. //
  2798. // CODEWORK: Move this to a registry key, so
  2799. // it can be changed later.
  2800. //
  2801. CString strPath;
  2802. CError err;
  2803. if (::GetModuleFileName(hInstance, strPath.GetBuffer(MAX_PATH), MAX_PATH))
  2804. {
  2805. int nLen = strPath.ReverseFind(_T('\\'));
  2806. if (nLen == -1)
  2807. {
  2808. TRACEEOLID("Bad module path");
  2809. err = ERROR_PATH_NOT_FOUND;
  2810. }
  2811. else
  2812. {
  2813. strPath.ReleaseBuffer(nLen);
  2814. strPath += _T("\\keyring.exe");
  2815. TRACEEOLID("Spawning " << strPath);
  2816. CString strParm;
  2817. if (lpszServer != NULL)
  2818. {
  2819. strParm.Format(_T("/remote:%s"), lpszServer);
  2820. }
  2821. TRACEEOLID(strParm);
  2822. TRACEEOLID(strPath);
  2823. if (_tspawnl(_P_WAIT, strPath, strPath, strParm, NULL) != 0)
  2824. {
  2825. err.GetLastWinError();
  2826. }
  2827. }
  2828. }
  2829. else
  2830. {
  2831. err.GetLastWinError();
  2832. }
  2833. err.MessageBoxOnFailure();
  2834. }
  2835. void
  2836. InitializeDLL()
  2837. /*++
  2838. Routine Description:
  2839. Perform additional initialisation as necessary
  2840. Arguments:
  2841. None
  2842. Return Value:
  2843. None
  2844. */
  2845. {
  2846. #ifdef _DEBUG
  2847. afxMemDF |= checkAlwaysMemDF;
  2848. #endif // _DEBUG
  2849. #ifdef UNICODE
  2850. TRACEEOLID("Loading UNICODE w3scfg.dll");
  2851. #else
  2852. TRACEEOLID("Loading ANSI w3scfg.dll");
  2853. #endif UNICODE
  2854. ::AfxEnableControlContainer();
  2855. #ifndef _COMSTATIC
  2856. //
  2857. // Initialize IISUI extension DLL
  2858. //
  2859. InitIISUIDll();
  2860. #endif // _COMSTATIC
  2861. }
  2862. CConfigDll NEAR theApp;
  2863. //
  2864. // Message Map
  2865. //
  2866. BEGIN_MESSAGE_MAP(CConfigDll, CWinApp)
  2867. //{{AFX_MSG_MAP(CConfigDll)
  2868. //}}AFX_MSG_MAP
  2869. //
  2870. // Global Help Commands
  2871. //
  2872. ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  2873. ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp)
  2874. END_MESSAGE_MAP()
  2875. BOOL
  2876. CConfigDll::InitInstance()
  2877. /*++
  2878. Routine Description:
  2879. Initialize the instance
  2880. Arguments:
  2881. None
  2882. Return Value:
  2883. TRUE for success, FALSE for failure
  2884. --*/
  2885. {
  2886. BOOL bInit = CWinApp::InitInstance();
  2887. hInstance = ::AfxGetInstanceHandle();
  2888. ASSERT(hInstance);
  2889. InitializeDLL();
  2890. try
  2891. {
  2892. //
  2893. // Get the help path
  2894. //
  2895. ASSERT(m_pszHelpFilePath != NULL);
  2896. m_lpOldHelpPath = m_pszHelpFilePath;
  2897. CString strFile(_tcsrchr(m_pszHelpFilePath, _T('\\')));
  2898. CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ);
  2899. rk.QueryValue(SZ_HELPPATH, m_strHelpPath, EXPANSION_ON);
  2900. m_strHelpPath += strFile;
  2901. }
  2902. catch(CException * e)
  2903. {
  2904. e->ReportError();
  2905. e->Delete();
  2906. }
  2907. if (!m_strHelpPath.IsEmpty())
  2908. {
  2909. m_pszHelpFilePath = m_strHelpPath;
  2910. }
  2911. return bInit;
  2912. }
  2913. int
  2914. CConfigDll::ExitInstance()
  2915. /*++
  2916. Routine Description:
  2917. Exit instance handler
  2918. Arguments:
  2919. None
  2920. Return Value:
  2921. 0 for success, or an error return code
  2922. --*/
  2923. {
  2924. m_pszHelpFilePath = m_lpOldHelpPath;
  2925. return CWinApp::ExitInstance();
  2926. }
  2927. CConfigDll::CConfigDll(
  2928. IN LPCTSTR pszAppName OPTIONAL
  2929. )
  2930. /*++
  2931. Routine Description:
  2932. DLL CWinApp constructor
  2933. Arguments:
  2934. None
  2935. Return Value:
  2936. N/A
  2937. --*/
  2938. : CWinApp(pszAppName)
  2939. {
  2940. }