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.

2633 lines
51 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. fscfg.cpp
  5. Abstract:
  6. FTP 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 "fscfg.h"
  18. #include "fservic.h"
  19. #include "facc.h"
  20. #include "fmessage.h"
  21. #include "vdir.h"
  22. #include "security.h"
  23. #include "wizard.h"
  24. #include "..\mmc\constr.h"
  25. //
  26. // Standard Configuration Information
  27. //
  28. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  29. #define SVC_ID INET_FTP_SVC_ID
  30. #define INETSLOC_MASK (INET_FTP_SVCLOC_ID)
  31. //
  32. // Service capabilities flags
  33. //
  34. #define SERVICE_INFO_FLAGS (\
  35. ISMI_UNDERSTANDINSTANCE | \
  36. ISMI_INSTANCES | \
  37. ISMI_CHILDREN | \
  38. ISMI_INETSLOCDISCOVER | \
  39. ISMI_CANCONTROLSERVICE | \
  40. ISMI_CANPAUSESERVICE | \
  41. ISMI_TASKPADS | \
  42. ISMI_SECURITYWIZARD | \
  43. ISMI_HASWEBPROTOCOL | \
  44. ISMI_SUPPORTSMETABASE | \
  45. ISMI_SUPPORTSMASTER | \
  46. ISMI_NORMALTBMAPPING)
  47. //
  48. // Name used for this service by the service controller manager.
  49. //
  50. #define SERVICE_SC_NAME _T("MSFTPSVC")
  51. //
  52. // Short descriptive name of the service. This
  53. // is what will show up as the name of the service
  54. // in the internet manager tool.
  55. //
  56. // Issue: I'm assuming here that this name does NOT
  57. // require localisation.
  58. //
  59. #define SERVICE_SHORT_NAME _T("FTP")
  60. //
  61. // Longer name. This is the text that shows up in
  62. // the tooltips text on the internet manager
  63. // tool. This probably should be localised.
  64. //
  65. #define SERVICE_LONG_NAME _T("FTP Service")
  66. //
  67. // Web browser protocol name. e.g. xxxxx://address
  68. // A blank string if this is not supported.
  69. //
  70. #define SERVICE_PROTOCOL _T("ftp")
  71. //
  72. // Toolbar button background mask. This is
  73. // the colour that gets masked out in
  74. // the bitmap file and replaced with the
  75. // actual button background. This setting
  76. // is automatically assumed to be lt. gray
  77. // if NORMAL_TB_MAPPING (above) is TRUE
  78. //
  79. #define BUTTON_BMP_BACKGROUND RGB(192, 192, 192) // Lt. Gray
  80. //
  81. // Resource ID of the toolbar button bitmap.
  82. //
  83. // The bitmap must be 16x16
  84. //
  85. #define BUTTON_BMP_ID IDB_FTP
  86. //
  87. // Similar to BUTTON_BMP_BACKGROUND, this is the
  88. // background mask for the service ID
  89. //
  90. #define SERVICE_BMP_BACKGROUND RGB(255,0,255) // Purple
  91. //
  92. // Bitmap id which is used in the service view
  93. // of the service manager. This may be the same
  94. // bitmap as BUTTON_BMP_BACKGROUND.
  95. //
  96. // The bitmap must be 16x16.
  97. //
  98. #define SERVICE_BMP_ID IDB_FTPVIEW
  99. //
  100. // /* K2 */
  101. //
  102. // Similar to BUTTON_BMP_BACKGROUND, this is the
  103. // background mask for the child bitmap
  104. //
  105. #define CHILD_BMP_BACKGROUND RGB(255, 0, 255) // Purple
  106. //
  107. // /* K2 */
  108. //
  109. // Bitmap id which is used for the child bitmap
  110. //
  111. // The bitmap must be 16x16.
  112. //
  113. #define CHILD_BMP_ID IDB_FTPDIR
  114. #define CHILD_BMP32_ID IDB_FTPDIR32
  115. //
  116. // /* K2 */
  117. //
  118. // Large bitmap (32x32) id
  119. //
  120. #define SERVICE_BMP32_ID IDB_FTPVIEW32
  121. //
  122. // Service Name
  123. //
  124. const LPCTSTR g_cszSvc = _T("MSFTPSVC");
  125. //
  126. // Help IDs
  127. //
  128. #define HIDD_DIRECTORY_PROPERTIES (0x207DB)
  129. #define HIDD_HOME_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20000)
  130. //
  131. // End Of Standard configuration Information
  132. //
  133. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  134. CFTPInstanceProps::CFTPInstanceProps(
  135. IN LPCTSTR lpszServerName,
  136. IN DWORD dwInstance OPTIONAL
  137. )
  138. /*++
  139. Routine Description:
  140. Constructor for FTP instance properties
  141. Arguments:
  142. LPCTSTR lpszServerName : Server name
  143. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  144. Return Value:
  145. N/A
  146. --*/
  147. : CInstanceProps(lpszServerName, g_cszSvc, dwInstance, 21U),
  148. m_nMaxConnections((LONG)0L),
  149. m_nConnectionTimeOut((LONG)0L),
  150. m_dwLogType(MD_LOG_TYPE_DISABLED),
  151. /**/
  152. m_strUserName(),
  153. m_strPassword(),
  154. m_fAllowAnonymous(FALSE),
  155. m_fOnlyAnonymous(FALSE),
  156. m_fPasswordSync(TRUE),
  157. m_acl(),
  158. /**/
  159. m_strExitMessage(),
  160. m_strMaxConMsg(),
  161. m_strlWelcome(),
  162. /**/
  163. m_fDosDirOutput(TRUE),
  164. /**/
  165. m_dwDownlevelInstance(1)
  166. {
  167. //
  168. // Fetch everything
  169. //
  170. m_dwMDUserType = ALL_METADATA;
  171. m_dwMDDataType = ALL_METADATA;
  172. }
  173. /* virtual */
  174. void
  175. CFTPInstanceProps::ParseFields()
  176. /*++
  177. Routine Description:
  178. Break into fields.
  179. Arguments:
  180. None.
  181. Return Value:
  182. None.
  183. --*/
  184. {
  185. //
  186. // Fetch base properties
  187. //
  188. CInstanceProps::ParseFields();
  189. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  190. //
  191. // Service Page
  192. //
  193. HANDLE_META_RECORD(MD_MAX_CONNECTIONS, m_nMaxConnections)
  194. HANDLE_META_RECORD(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  195. HANDLE_META_RECORD(MD_LOG_TYPE, m_dwLogType)
  196. //
  197. // Accounts Page
  198. //
  199. HANDLE_META_RECORD(MD_ANONYMOUS_USER_NAME, m_strUserName)
  200. HANDLE_META_RECORD(MD_ANONYMOUS_PWD, m_strPassword)
  201. HANDLE_META_RECORD(MD_ANONYMOUS_ONLY, m_fOnlyAnonymous)
  202. HANDLE_META_RECORD(MD_ALLOW_ANONYMOUS, m_fAllowAnonymous)
  203. HANDLE_META_RECORD(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  204. HANDLE_META_RECORD(MD_ADMIN_ACL, m_acl)
  205. //
  206. // Message Page
  207. //
  208. HANDLE_META_RECORD(MD_EXIT_MESSAGE, m_strExitMessage)
  209. HANDLE_META_RECORD(MD_MAX_CLIENTS_MESSAGE, m_strMaxConMsg)
  210. HANDLE_META_RECORD(MD_GREETING_MESSAGE, m_strlWelcome)
  211. //
  212. // Directory Properties Page
  213. //
  214. HANDLE_META_RECORD(MD_MSDOS_DIR_OUTPUT, m_fDosDirOutput);
  215. END_PARSE_META_RECORDS
  216. }
  217. /* virtual */
  218. HRESULT
  219. CFTPInstanceProps::WriteDirtyProps()
  220. /*++
  221. Routine Description:
  222. Write the dirty properties to the metabase
  223. Arguments:
  224. None
  225. Return Value:
  226. HRESULT
  227. --*/
  228. {
  229. CError err(CInstanceProps::WriteDirtyProps());
  230. if (err.Failed())
  231. {
  232. return err;
  233. }
  234. BEGIN_META_WRITE()
  235. //
  236. // Service Page
  237. //
  238. META_WRITE(MD_MAX_CONNECTIONS, m_nMaxConnections)
  239. META_WRITE(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut)
  240. META_WRITE(MD_LOG_TYPE, m_dwLogType)
  241. //
  242. // Accounts Page
  243. //
  244. META_WRITE(MD_ANONYMOUS_USER_NAME, m_strUserName)
  245. META_WRITE(MD_ANONYMOUS_PWD, m_strPassword)
  246. META_WRITE(MD_ANONYMOUS_ONLY, m_fOnlyAnonymous)
  247. META_WRITE(MD_ALLOW_ANONYMOUS, m_fAllowAnonymous)
  248. META_WRITE(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync)
  249. META_WRITE(MD_ADMIN_ACL, m_acl)
  250. //
  251. // Message Page
  252. //
  253. META_WRITE(MD_EXIT_MESSAGE, m_strExitMessage)
  254. META_WRITE(MD_MAX_CLIENTS_MESSAGE, m_strMaxConMsg)
  255. META_WRITE(MD_GREETING_MESSAGE, m_strlWelcome)
  256. //
  257. // Directory Properties Page
  258. //
  259. META_WRITE(MD_MSDOS_DIR_OUTPUT, m_fDosDirOutput);
  260. END_META_WRITE(err);
  261. return err;
  262. }
  263. CFTPDirProps::CFTPDirProps(
  264. IN LPCTSTR lpszServerName,
  265. IN DWORD dwInstance, OPTIONAL
  266. IN LPCTSTR lpszParent, OPTIONAL
  267. IN LPCTSTR lpszAlias OPTIONAL
  268. )
  269. /*++
  270. Routine Description:
  271. FTP Directory properties object
  272. Arguments:
  273. LPCTSTR lpszServerName : Server name
  274. DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
  275. LPCTSTR lpszParent : Parent path (could be NULL)
  276. LPCTSTR lpszAlias : Alias name (could be NULL)
  277. Return Value:
  278. N/A.
  279. --*/
  280. : CChildNodeProps(
  281. lpszServerName,
  282. g_cszSvc,
  283. dwInstance,
  284. lpszParent,
  285. lpszAlias,
  286. WITH_INHERITANCE,
  287. FALSE // Complete information
  288. ),
  289. /**/
  290. m_fDontLog(FALSE),
  291. m_ipl()
  292. {
  293. //
  294. // Fetch everything
  295. //
  296. m_dwMDUserType = ALL_METADATA;
  297. m_dwMDDataType = ALL_METADATA;
  298. }
  299. /* virtual */
  300. void
  301. CFTPDirProps::ParseFields()
  302. /*++
  303. Routine Description:
  304. Break into fields.
  305. Arguments:
  306. None.
  307. Return Value:
  308. None.
  309. --*/
  310. {
  311. //
  312. // Fetch base properties
  313. //
  314. CChildNodeProps::ParseFields();
  315. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  316. HANDLE_META_RECORD(MD_VR_USERNAME, m_strUserName)
  317. HANDLE_META_RECORD(MD_VR_PASSWORD, m_strPassword)
  318. HANDLE_META_RECORD(MD_DONT_LOG, m_fDontLog);
  319. HANDLE_META_RECORD(MD_IP_SEC, m_ipl);
  320. END_PARSE_META_RECORDS
  321. }
  322. /* virtual */
  323. HRESULT
  324. CFTPDirProps::WriteDirtyProps()
  325. /*++
  326. Routine Description:
  327. Write the dirty properties to the metabase
  328. Arguments:
  329. None
  330. Return Value:
  331. HRESULT
  332. --*/
  333. {
  334. CError err(CChildNodeProps::WriteDirtyProps());
  335. if (err.Failed())
  336. {
  337. return err;
  338. }
  339. //
  340. // CODEWORK: Consider DDX/DDV like methods which do both
  341. // ParseFields and WriteDirtyProps in a single method. Must
  342. // take care not to write data which should only be read, not
  343. // written
  344. //
  345. BEGIN_META_WRITE()
  346. META_WRITE(MD_VR_USERNAME, m_strUserName)
  347. META_WRITE(MD_VR_PASSWORD, m_strPassword)
  348. META_WRITE(MD_DONT_LOG, m_fDontLog);
  349. META_WRITE(MD_IP_SEC, m_ipl);
  350. END_META_WRITE(err);
  351. return err;
  352. }
  353. CFtpSheet::CFtpSheet(
  354. LPCTSTR pszCaption,
  355. LPCTSTR lpszServer,
  356. DWORD dwInstance,
  357. LPCTSTR lpszParent,
  358. LPCTSTR lpszAlias,
  359. CWnd * pParentWnd,
  360. LPARAM lParam,
  361. LONG_PTR handle,
  362. UINT iSelectPage
  363. )
  364. /*++
  365. Routine Description:
  366. FTP Property sheet constructor
  367. Arguments:
  368. LPCTSTR pszCaption : Sheet caption
  369. LPCTSTR lpszServer : Server name
  370. DWORD dwInstance : Instance number
  371. LPCTSTR lpszParent : Parent path
  372. LPCTSTR lpszAlias : Alias name
  373. CWnd * pParentWnd : Parent window
  374. LPARAM lParam : Parameter for MMC console
  375. LONG_PTR handle : MMC console handle
  376. UINT iSelectPage : Initial page selected or -1
  377. Return Value:
  378. N/A
  379. --*/
  380. : CInetPropertySheet(
  381. pszCaption,
  382. lpszServer,
  383. g_cszSvc,
  384. dwInstance,
  385. lpszParent,
  386. lpszAlias,
  387. pParentWnd,
  388. lParam,
  389. handle,
  390. iSelectPage
  391. ),
  392. m_ppropInst(NULL),
  393. m_ppropDir(NULL)
  394. {
  395. }
  396. CFtpSheet::~CFtpSheet()
  397. /*++
  398. Routine Description:
  399. FTP Sheet destructor
  400. Arguments:
  401. N/A
  402. Return Value:
  403. N/A
  404. --*/
  405. {
  406. FreeConfigurationParameters();
  407. //
  408. // Must be deleted by now
  409. //
  410. ASSERT(m_ppropInst == NULL);
  411. ASSERT(m_ppropDir == NULL);
  412. }
  413. void
  414. CFtpSheet::WinHelp(
  415. IN DWORD dwData,
  416. IN UINT nCmd
  417. )
  418. /*++
  419. Routine Description:
  420. FTP Property sheet help handler
  421. Arguments:
  422. DWORD dwData : WinHelp data (dialog ID)
  423. UINT nCmd : WinHelp command
  424. Return Value:
  425. None
  426. Notes:
  427. Replace the dialog ID if this is the directory tab. We have
  428. different help depending on virtual directory, home, file, directory.
  429. --*/
  430. {
  431. ASSERT(m_ppropDir != NULL);
  432. if (::lstrcmpi(m_ppropDir->QueryAlias(), g_cszRoot) == 0
  433. && dwData == HIDD_DIRECTORY_PROPERTIES)
  434. {
  435. //
  436. // It's a home virtual directory -- change the ID
  437. //
  438. dwData = HIDD_HOME_DIRECTORY_PROPERTIES;
  439. }
  440. CInetPropertySheet::WinHelp(dwData, nCmd);
  441. }
  442. /* virtual */
  443. HRESULT
  444. CFtpSheet::LoadConfigurationParameters()
  445. /*++
  446. Routine Description:
  447. Load configuration parameters information
  448. Arguments:
  449. None
  450. Return Value:
  451. HRESULT
  452. --*/
  453. {
  454. CError err;
  455. if (m_ppropInst == NULL)
  456. {
  457. ASSERT(m_ppropDir == NULL);
  458. m_ppropInst = new CFTPInstanceProps(m_strServer, m_dwInstance);
  459. m_ppropDir = new CFTPDirProps(
  460. m_strServer,
  461. m_dwInstance,
  462. m_strParent,
  463. m_strAlias
  464. );
  465. if (!m_ppropInst || !m_ppropDir)
  466. {
  467. err = ERROR_NOT_ENOUGH_MEMORY;
  468. return err;
  469. }
  470. err = m_ppropInst->LoadData();
  471. if (err.Succeeded())
  472. {
  473. err = m_ppropDir->LoadData();
  474. }
  475. }
  476. return err;
  477. }
  478. /* virtual */
  479. void
  480. CFtpSheet::FreeConfigurationParameters()
  481. /*++
  482. Routine Description:
  483. Clean up configuration data
  484. Arguments:
  485. None
  486. Return Value:
  487. None
  488. --*/
  489. {
  490. //
  491. // Must be deleted by now
  492. //
  493. ASSERT(m_ppropInst != NULL);
  494. ASSERT(m_ppropDir != NULL);
  495. SAFE_DELETE(m_ppropInst);
  496. SAFE_DELETE(m_ppropDir);
  497. }
  498. //
  499. // Message Map
  500. //
  501. BEGIN_MESSAGE_MAP(CFtpSheet, CInetPropertySheet)
  502. //{{AFX_MSG_MAP(CInetPropertySheet)
  503. //}}AFX_MSG_MAP
  504. END_MESSAGE_MAP()
  505. //
  506. // Global DLL instance
  507. //
  508. HINSTANCE hInstance;
  509. //
  510. // ISM API Functions
  511. //
  512. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  513. extern "C" DWORD APIENTRY
  514. ISMQueryServiceInfo(
  515. OUT ISMSERVICEINFO * psi
  516. )
  517. /*++
  518. Routine Description:
  519. Return service-specific information back to the application. This
  520. function is called by the service manager immediately after LoadLibary();
  521. The size element must be set prior to calling this API.
  522. Arguments:
  523. ISMSERVICEINFO * psi : Service information returned.
  524. Return Value:
  525. Error return code
  526. --*/
  527. {
  528. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  529. ASSERT(psi != NULL);
  530. ASSERT(psi->dwSize == ISMSERVICEINFO_SIZE);
  531. psi->dwSize = ISMSERVICEINFO_SIZE;
  532. psi->dwVersion = ISM_VERSION;
  533. psi->flServiceInfoFlags = SERVICE_INFO_FLAGS;
  534. psi->ullDiscoveryMask = INETSLOC_MASK;
  535. psi->rgbButtonBkMask = BUTTON_BMP_BACKGROUND;
  536. psi->nButtonBitmapID = BUTTON_BMP_ID;
  537. psi->rgbServiceBkMask = SERVICE_BMP_BACKGROUND;
  538. psi->nServiceBitmapID = SERVICE_BMP_ID;
  539. psi->rgbServiceBkMask = SERVICE_BMP_BACKGROUND;
  540. psi->nLargeServiceBitmapID = SERVICE_BMP32_ID;
  541. ASSERT(::lstrlen(SERVICE_LONG_NAME) <= MAX_LNLEN);
  542. ASSERT(::lstrlen(SERVICE_SHORT_NAME) <= MAX_SNLEN);
  543. ::lstrcpy(psi->atchShortName, SERVICE_SHORT_NAME);
  544. ::lstrcpy(psi->atchLongName, SERVICE_LONG_NAME);
  545. //
  546. // /* K2 */
  547. //
  548. psi->rgbChildBkMask = CHILD_BMP_BACKGROUND;
  549. psi->nChildBitmapID = CHILD_BMP_ID ;
  550. psi->rgbLargeChildBkMask = CHILD_BMP_BACKGROUND;
  551. psi->nLargeChildBitmapID = CHILD_BMP32_ID;
  552. //
  553. // IIS 5
  554. //
  555. ASSERT(::lstrlen(SERVICE_PROTOCOL) <= MAX_SNLEN);
  556. ASSERT(::lstrlen(g_cszSvc) <= MAX_SNLEN);
  557. ::lstrcpy(psi->atchProtocol, SERVICE_PROTOCOL);
  558. ::lstrcpy(psi->atchMetaBaseName, g_cszSvc);
  559. return ERROR_SUCCESS;
  560. }
  561. DWORD APIENTRY
  562. ISMDiscoverServers(
  563. OUT ISMSERVERINFO * psi,
  564. IN DWORD * pdwBufferSize,
  565. IN int * cServers
  566. )
  567. /*++
  568. Routine Description:
  569. Discover machines running this service. This is only necessary
  570. for services not discovered with inetsloc (which don't give a mask)
  571. Arguments:
  572. ISMSERVERINFO * psi : Server info buffer.
  573. DWORD * pdwBufferSize : Size required/available.
  574. int * cServers : Number of servers in buffer.
  575. Return Value:
  576. Error return code
  577. --*/
  578. {
  579. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  580. *cServers = 0;
  581. *pdwBufferSize = 0L;
  582. //
  583. // We're an inetsloc service
  584. //
  585. TRACEEOLID("Warning: service manager called bogus ISMDiscoverServers");
  586. ASSERT(FALSE);
  587. return ERROR_SUCCESS;
  588. }
  589. extern "C" DWORD APIENTRY
  590. ISMQueryServerInfo(
  591. IN LPCTSTR lpszServerName,
  592. OUT ISMSERVERINFO * psi
  593. )
  594. /*++
  595. Routine Description:
  596. Get information about a specific server with regards to this service.
  597. Arguments:
  598. LPCTSTR lpszServerName : Name of server.
  599. ISMSERVERINFO * psi : Server information returned.
  600. Return Value:
  601. Error return code
  602. --*/
  603. {
  604. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  605. ASSERT(psi != NULL);
  606. ASSERT(psi->dwSize == ISMSERVERINFO_SIZE);
  607. ASSERT(::lstrlen(lpszServerName) <= MAX_SERVERNAME_LEN);
  608. psi->dwSize = ISMSERVERINFO_SIZE;
  609. ::lstrcpy(psi->atchServerName, lpszServerName);
  610. //
  611. // Start with NULL comment
  612. //
  613. *psi->atchComment = _T('\0');
  614. //
  615. // First look at the SC
  616. //
  617. CError err(::QueryInetServiceStatus(
  618. psi->atchServerName,
  619. SERVICE_SC_NAME,
  620. &(psi->nState)
  621. ));
  622. if (err.Failed())
  623. {
  624. psi->nState = INetServiceUnknown;
  625. return err;
  626. }
  627. //
  628. // Check the metabase to see if the service is installed
  629. //
  630. CMetaKey mk(lpszServerName, METADATA_PERMISSION_READ, g_cszSvc);
  631. err = mk.QueryResult();
  632. if (err.Failed())
  633. {
  634. if (err == REGDB_E_CLASSNOTREG)
  635. {
  636. //
  637. // Ok, the service is there, but the metabase is not.
  638. // This must be the old IIS 1-3 version of this service,
  639. // which doesn't count as having the service installed.
  640. //
  641. return ERROR_SERVICE_DOES_NOT_EXIST;
  642. }
  643. return err;
  644. }
  645. //
  646. // If not exist, return bogus acceptable error
  647. //
  648. return (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  649. ? ERROR_SERVICE_DOES_NOT_EXIST
  650. : err.Win32Error();
  651. }
  652. extern "C" DWORD APIENTRY
  653. ISMChangeServiceState(
  654. IN int nNewState,
  655. OUT int * pnCurrentState,
  656. IN DWORD dwInstance,
  657. IN LPCTSTR lpszServers
  658. )
  659. /*++
  660. Routine Description:
  661. Change the service state of the servers (to paused/continue, started,
  662. stopped, etc)
  663. Arguments:
  664. int nNewState : INetService definition.
  665. int * pnCurrentState : Ptr to current state (will be changed
  666. DWORD dwInstance : Instance or 0 for the service itself
  667. LPCTSTR lpszServers : Double NULL terminated list of servers.
  668. Return Value:
  669. Error return code
  670. --*/
  671. {
  672. AFX_MANAGE_STATE(AfxGetStaticModuleState() );
  673. ASSERT(nNewState >= INetServiceStopped
  674. && nNewState <= INetServicePaused);
  675. if (IS_MASTER_INSTANCE(dwInstance))
  676. {
  677. //
  678. // Service itself is referred to here
  679. //
  680. return ChangeInetServiceState(
  681. lpszServers,
  682. SERVICE_SC_NAME,
  683. nNewState,
  684. pnCurrentState
  685. );
  686. }
  687. //
  688. // Change the state of the instance
  689. //
  690. CInstanceProps inst(lpszServers, g_cszSvc, dwInstance);
  691. inst.LoadData();
  692. CError err(inst.ChangeState(nNewState));
  693. *pnCurrentState = inst.QueryISMState();
  694. return err;
  695. }
  696. extern "C" DWORD APIENTRY
  697. ISMConfigureServers(
  698. IN HWND hWnd,
  699. IN DWORD dwInstance,
  700. IN LPCTSTR lpszServers
  701. )
  702. /*++
  703. Routine Description:
  704. Display configuration property sheet.
  705. Arguments:
  706. HWND hWnd : Main app window handle
  707. DWORD dwInstance : Instance number
  708. LPCTSTR lpszServers : Double NULL terminated list of servers
  709. Return Value:
  710. Error return code
  711. --*/
  712. {
  713. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  714. DWORD err = ERROR_SUCCESS;
  715. //
  716. // Convert the list of servers to a
  717. // more manageable CStringList.
  718. //
  719. CStringList strlServers;
  720. err = ConvertDoubleNullListToStringList(lpszServers, strlServers);
  721. if (err != ERROR_SUCCESS)
  722. {
  723. TRACEEOLID("Error building server string list");
  724. return err;
  725. }
  726. CString strCaption;
  727. if (strlServers.GetCount() == 1)
  728. {
  729. CString str;
  730. LPCTSTR lpComputer = PURE_COMPUTER_NAME(lpszServers);
  731. if(IS_MASTER_INSTANCE(dwInstance))
  732. {
  733. VERIFY(str.LoadString(IDS_CAPTION_DEFAULT));
  734. strCaption.Format(str, lpComputer);
  735. }
  736. else
  737. {
  738. VERIFY(str.LoadString(IDS_CAPTION));
  739. strCaption.Format(str, dwInstance, lpComputer);
  740. }
  741. }
  742. else // Multiple server caption
  743. {
  744. VERIFY(strCaption.LoadString(IDS_CAPTION_MULTIPLE));
  745. }
  746. ASSERT(strlServers.GetCount() == 1);
  747. //
  748. // Get the server name
  749. //
  750. LPCTSTR lpszServer = strlServers.GetHead();
  751. CFtpSheet * pSheet = NULL;
  752. try
  753. {
  754. pSheet = new CFtpSheet(
  755. strCaption,
  756. lpszServer,
  757. dwInstance,
  758. NULL,
  759. g_cszRoot,
  760. CWnd::FromHandlePermanent(hWnd)
  761. );
  762. pSheet->AddRef();
  763. if (SUCCEEDED(pSheet->QueryInstanceResult()))
  764. {
  765. //
  766. // Add instance pages
  767. //
  768. pSheet->AddPage(new CFtpServicePage(pSheet));
  769. pSheet->AddPage(new CFtpAccountsPage(pSheet));
  770. pSheet->AddPage(new CFtpMessagePage(pSheet));
  771. }
  772. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  773. {
  774. //
  775. // Add home directory pages for the home directory
  776. //
  777. pSheet->AddPage(new CFtpDirectoryPage(pSheet, TRUE));
  778. pSheet->AddPage(new CFtpSecurityPage(pSheet));
  779. }
  780. }
  781. catch(CMemoryException * e)
  782. {
  783. TRACEEOLID("Aborting because of exception");
  784. err = ERROR_NOT_ENOUGH_MEMORY;
  785. e->Delete();
  786. }
  787. if (err == ERROR_SUCCESS)
  788. {
  789. ASSERT(pSheet != NULL);
  790. pSheet->DoModal();
  791. pSheet->Release();
  792. }
  793. //
  794. // Sheet and pages clean themselves up
  795. //
  796. return err;
  797. }
  798. //
  799. // K2 Functions
  800. //
  801. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  802. HRESULT
  803. AddMMCPage(
  804. IN LPPROPERTYSHEETCALLBACK lpProvider,
  805. IN CPropertyPage * pg
  806. )
  807. /*++
  808. Routine Description:
  809. Helper function to add MFC property page using callback provider
  810. to MMC.
  811. Arguments:
  812. LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider
  813. CPropertyPage * pg : MFC property page object
  814. Return Value:
  815. HRESULT
  816. --*/
  817. {
  818. ASSERT(pg != NULL);
  819. //
  820. // Patch MFC property page class.
  821. //
  822. MMCPropPageCallback(&pg->m_psp);
  823. HPROPSHEETPAGE hPage = CreatePropertySheetPage(
  824. (LPCPROPSHEETPAGE)&pg->m_psp
  825. );
  826. if (hPage == NULL)
  827. {
  828. return E_UNEXPECTED;
  829. }
  830. lpProvider->AddPage(hPage);
  831. return S_OK;
  832. }
  833. extern "C" HRESULT APIENTRY
  834. ISMBind(
  835. IN LPCTSTR lpszServer,
  836. OUT HANDLE * phServer
  837. )
  838. /*++
  839. Routine Description:
  840. Generate a handle for the server name.
  841. Arguments:
  842. LPCTSTR lpszServer : Server name
  843. HANDLE * phServer : Returns a handle
  844. Return Value:
  845. HRESULT
  846. --*/
  847. {
  848. return COMDLL_ISMBind(lpszServer, phServer);
  849. }
  850. extern "C" HRESULT APIENTRY
  851. ISMUnbind(
  852. IN HANDLE hServer
  853. )
  854. /*++
  855. Routine Description:
  856. Free up the server handle
  857. Arguments:
  858. HANDLE hServer : Server handle
  859. Return Value:
  860. HRESULT
  861. --*/
  862. {
  863. return COMDLL_ISMUnbind(hServer);
  864. }
  865. extern "C" HRESULT APIENTRY
  866. ISMMMCConfigureServers(
  867. IN HANDLE hServer,
  868. IN PVOID lpfnMMCCallbackProvider,
  869. IN LPARAM param,
  870. IN LONG_PTR handle,
  871. IN DWORD dwInstance
  872. )
  873. /*++
  874. Routine Description:
  875. Display configuration property sheet.
  876. Arguments:
  877. HANDLE hServer : Server handle
  878. PVOID lpfnMMCCallbackProvider : MMC Callback provider
  879. LPARAM param : MMC LPARAM
  880. LONG_PTR handle : MMC Console handle
  881. DWORD dwInstance : Instance number
  882. Return Value:
  883. HRESULT
  884. --*/
  885. {
  886. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  887. CError err;
  888. LPPROPERTYSHEETCALLBACK lpProvider =
  889. (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
  890. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  891. ASSERT(lpszServer != NULL);
  892. CString str, strCaption;
  893. LPCTSTR lpszComputer = PURE_COMPUTER_NAME(lpszServer);
  894. if(IS_MASTER_INSTANCE(dwInstance))
  895. {
  896. VERIFY(str.LoadString(IDS_CAPTION_DEFAULT));
  897. strCaption.Format(str, lpszComputer);
  898. }
  899. else
  900. {
  901. VERIFY(str.LoadString(IDS_CAPTION));
  902. strCaption.Format(str, dwInstance, lpszComputer);
  903. }
  904. CFtpSheet * pSheet = NULL;
  905. try
  906. {
  907. pSheet = new CFtpSheet(
  908. strCaption,
  909. lpszServer,
  910. dwInstance,
  911. NULL,
  912. g_cszRoot,
  913. NULL,
  914. param,
  915. handle
  916. );
  917. pSheet->SetModeless();
  918. CFtpServicePage * pServPage = NULL;
  919. CFtpAccountsPage * pAccPage = NULL;
  920. CFtpMessagePage * pMessPage = NULL;
  921. CFtpDirectoryPage * pDirPage = NULL;
  922. CFtpSecurityPage * pSecPage = NULL;
  923. if (SUCCEEDED(pSheet->QueryInstanceResult()))
  924. {
  925. //
  926. // Add instance pages
  927. //
  928. AddMMCPage(lpProvider, new CFtpServicePage(pSheet));
  929. AddMMCPage(lpProvider, new CFtpAccountsPage(pSheet));
  930. AddMMCPage(lpProvider, new CFtpMessagePage(pSheet));
  931. }
  932. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  933. {
  934. //
  935. // Add home directory pages for the home directory
  936. //
  937. AddMMCPage(lpProvider, new CFtpDirectoryPage(pSheet, TRUE));
  938. AddMMCPage(lpProvider, new CFtpSecurityPage(pSheet));
  939. }
  940. }
  941. catch(CMemoryException * e)
  942. {
  943. TRACEEOLID("Aborting because of exception");
  944. err = ERROR_NOT_ENOUGH_MEMORY;
  945. e->Delete();
  946. }
  947. //
  948. // Sheet and pages clean themselves up
  949. //
  950. return err;
  951. }
  952. extern "C" HRESULT APIENTRY
  953. ISMMMCConfigureChild(
  954. IN HANDLE hServer,
  955. IN PVOID lpfnMMCCallbackProvider,
  956. IN LPARAM param,
  957. IN LONG_PTR handle,
  958. IN DWORD dwAttributes,
  959. IN DWORD dwInstance,
  960. IN LPCTSTR lpszParent,
  961. IN LPCTSTR lpszAlias
  962. )
  963. /*++
  964. Routine Description:
  965. Display configuration property sheet for child object.
  966. Arguments:
  967. HANDLE hServer : Server handle
  968. PVOID lpfnMMCCallbackProvider : MMC Callback provider
  969. LPARAM param : MMC parameter passed to sheet
  970. LONG_PTR handle : MMC console handle
  971. DWORD dwAttributes : Must be FILE_ATTRIBUTE_VIRTUAL_DIRECTORY
  972. DWORD dwInstance : Parent instance number
  973. LPCTSTR lpszParent : Parent path
  974. LPCTSTR lpszAlias : Child to configure
  975. Return Value:
  976. Error return code
  977. --*/
  978. {
  979. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  980. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  981. CError err;
  982. LPPROPERTYSHEETCALLBACK lpProvider =
  983. (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
  984. CString strCaption;
  985. {
  986. CString str;
  987. VERIFY(str.LoadString(IDS_DIR_TITLE));
  988. strCaption.Format(str, lpszAlias);
  989. }
  990. ASSERT(dwAttributes == FILE_ATTRIBUTE_VIRTUAL_DIRECTORY);
  991. //
  992. // Call the APIs and build the property pages
  993. //
  994. CFtpSheet * pSheet = NULL;
  995. try
  996. {
  997. pSheet = new CFtpSheet(
  998. strCaption,
  999. lpszServer,
  1000. dwInstance,
  1001. lpszParent,
  1002. lpszAlias,
  1003. NULL,
  1004. param,
  1005. handle
  1006. );
  1007. pSheet->SetModeless();
  1008. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  1009. {
  1010. CFtpDirectoryPage * pDirPage = NULL;
  1011. CFtpSecurityPage * pSecPage = NULL;
  1012. //
  1013. // Add private pages
  1014. //
  1015. AddMMCPage(lpProvider, new CFtpDirectoryPage(pSheet));
  1016. AddMMCPage(lpProvider, new CFtpSecurityPage(pSheet));
  1017. }
  1018. }
  1019. catch(CMemoryException * e)
  1020. {
  1021. TRACEEOLID("Aborting due to exception");
  1022. err = ERROR_NOT_ENOUGH_MEMORY;
  1023. e->Delete();
  1024. }
  1025. //
  1026. // Sheet and pages clean themselves up
  1027. //
  1028. return err;
  1029. }
  1030. extern "C" HRESULT APIENTRY
  1031. ISMEnumerateInstances(
  1032. IN HANDLE hServer,
  1033. OUT ISMINSTANCEINFO * pii,
  1034. OUT IN HANDLE * phEnum
  1035. )
  1036. /*++
  1037. Routine Description:
  1038. Enumerate Instances. First call with *phEnum == NULL.
  1039. Arguments:
  1040. HANDLE hServer : Server handle
  1041. ISMINSTANCEINFO * pii : Instance info buffer
  1042. HANDLE * phEnum : Enumeration handle.
  1043. Return Value:
  1044. Error return code
  1045. --*/
  1046. {
  1047. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1048. CError err;
  1049. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1050. ASSERT(pInterface != NULL);
  1051. BEGIN_ASSURE_BINDING_SECTION
  1052. err = COMDLL_ISMEnumerateInstances(
  1053. pInterface,
  1054. pii,
  1055. phEnum,
  1056. g_cszSvc
  1057. );
  1058. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS);
  1059. return err;
  1060. }
  1061. extern "C" HRESULT APIENTRY
  1062. ISMAddInstance(
  1063. IN HANDLE hServer,
  1064. IN DWORD dwSourceInstance,
  1065. OUT ISMINSTANCEINFO * pii, OPTIONAL
  1066. IN DWORD dwBufferSize
  1067. )
  1068. /*++
  1069. Routine Description:
  1070. Add an instance.
  1071. Arguments:
  1072. HANDLE hServer : Server handle
  1073. DWORD dwSourceInstance : Source instance ID to clone
  1074. ISMINSTANCEINFO * pii : Instance info buffer. May be NULL
  1075. DWORD dwBufferSize : Size of buffer
  1076. Return Value:
  1077. Error return code.
  1078. --*/
  1079. {
  1080. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1081. CIISWizardSheet sheet(IDB_WIZ_LEFT, IDB_WIZ_HEAD);
  1082. CIISFtpWizSettings ws(hServer, g_cszSvc);
  1083. CIISWizardBookEnd pgWelcome(
  1084. IDS_SITE_WELCOME,
  1085. IDS_NEW_SITE_WIZARD,
  1086. IDS_SITE_BODY
  1087. );
  1088. CVDWPDescription pgDescr(&ws);
  1089. CVDWPBindings pgBindings(&ws);
  1090. CVDWPPath pgHome(&ws, FALSE);
  1091. CVDWPUserName pgUserName(&ws, FALSE);
  1092. CVDWPPermissions pgPerms(&ws, FALSE);
  1093. CIISWizardBookEnd pgCompletion(
  1094. &ws.m_hrResult,
  1095. IDS_SITE_SUCCESS,
  1096. IDS_SITE_FAILURE,
  1097. IDS_NEW_SITE_WIZARD
  1098. );
  1099. sheet.AddPage(&pgWelcome);
  1100. sheet.AddPage(&pgDescr);
  1101. sheet.AddPage(&pgBindings);
  1102. sheet.AddPage(&pgHome);
  1103. sheet.AddPage(&pgUserName);
  1104. sheet.AddPage(&pgPerms);
  1105. sheet.AddPage(&pgCompletion);
  1106. if (sheet.DoModal() == IDCANCEL)
  1107. {
  1108. return ERROR_CANCELLED;
  1109. }
  1110. CError err(ws.m_hrResult);
  1111. if (err.Succeeded())
  1112. {
  1113. //
  1114. // Get info on it to be returned.
  1115. //
  1116. ISMQueryInstanceInfo(
  1117. ws.m_pKey,
  1118. WITHOUT_INHERITANCE,
  1119. pii,
  1120. ws.m_dwInstance
  1121. );
  1122. }
  1123. return err;
  1124. }
  1125. extern "C" HRESULT APIENTRY
  1126. ISMDeleteInstance(
  1127. IN HANDLE hServer,
  1128. IN DWORD dwInstance
  1129. )
  1130. /*++
  1131. Routine Description:
  1132. Delete an instance
  1133. Arguments:
  1134. HANDLE hServer : Server handle
  1135. DWORD dwInstance : Instance to be deleted
  1136. Return Value:
  1137. Error return code.
  1138. --*/
  1139. {
  1140. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1141. CError err;
  1142. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1143. BEGIN_ASSURE_BINDING_SECTION
  1144. err = CInstanceProps::Delete(
  1145. pInterface,
  1146. g_cszSvc,
  1147. dwInstance
  1148. );
  1149. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_CANCELLED);
  1150. return err;
  1151. }
  1152. extern "C" HRESULT APIENTRY
  1153. ISMEnumerateChildren(
  1154. IN HANDLE hServer,
  1155. OUT ISMCHILDINFO * pii,
  1156. OUT IN HANDLE * phEnum,
  1157. IN DWORD dwInstance,
  1158. IN LPCTSTR lpszParent
  1159. )
  1160. /*++
  1161. Routine Description:
  1162. Enumerate children. First call with *phEnum == NULL;
  1163. Arguments:
  1164. HANDLE hServer : Server handle
  1165. ISMCHILDINFO * pii : Child info buffer
  1166. HANDLE * phEnum : Enumeration handle.
  1167. DWORD dwInstance : Parent instance
  1168. LPCTSTR lpszParent : Parent path
  1169. Return Value:
  1170. Error return code.
  1171. --*/
  1172. {
  1173. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1174. CError err;
  1175. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1176. BEGIN_ASSURE_BINDING_SECTION
  1177. err = COMDLL_ISMEnumerateChildren(
  1178. pInterface,
  1179. pii,
  1180. phEnum,
  1181. g_cszSvc,
  1182. dwInstance,
  1183. lpszParent
  1184. );
  1185. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS);
  1186. return err;
  1187. }
  1188. extern "C" HRESULT APIENTRY
  1189. ISMAddChild(
  1190. IN HANDLE hServer,
  1191. OUT ISMCHILDINFO * pii,
  1192. IN DWORD dwBufferSize,
  1193. IN DWORD dwInstance,
  1194. IN LPCTSTR lpszParent
  1195. )
  1196. /*++
  1197. Routine Description:
  1198. Add a child.
  1199. Arguments:
  1200. HANDLE hServer : Server handle
  1201. ISMCHILDINFO * pii : Child info buffer. May be NULL
  1202. DWORD dwBufferSize : Size of info buffer
  1203. DWORD dwInstance : Parent instance
  1204. LPCTSTR lpszParent : Parent path
  1205. Return Value:
  1206. Error return code.
  1207. --*/
  1208. {
  1209. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1210. CIISFtpWizSettings ws(hServer, g_cszSvc, dwInstance, lpszParent);
  1211. CIISWizardSheet sheet(IDB_WIZ_LEFT_DIR, IDB_WIZ_HEAD_DIR);
  1212. CIISWizardBookEnd pgWelcome(
  1213. IDS_VDIR_WELCOME,
  1214. IDS_NEW_VDIR_WIZARD,
  1215. IDS_VDIR_BODY
  1216. );
  1217. CVDWPAlias pgAlias(&ws);
  1218. CVDWPPath pgPath(&ws, TRUE);
  1219. CVDWPUserName pgUserName(&ws, TRUE);
  1220. CVDWPPermissions pgPerms(&ws, TRUE);
  1221. CIISWizardBookEnd pgCompletion(
  1222. &ws.m_hrResult,
  1223. IDS_VDIR_SUCCESS,
  1224. IDS_VDIR_FAILURE,
  1225. IDS_NEW_VDIR_WIZARD
  1226. );
  1227. sheet.AddPage(&pgWelcome);
  1228. sheet.AddPage(&pgAlias);
  1229. sheet.AddPage(&pgPath);
  1230. sheet.AddPage(&pgUserName);
  1231. sheet.AddPage(&pgPerms);
  1232. sheet.AddPage(&pgCompletion);
  1233. if (sheet.DoModal() == IDCANCEL)
  1234. {
  1235. return ERROR_CANCELLED;
  1236. }
  1237. CError err(ws.m_hrResult);
  1238. if (err.Succeeded())
  1239. {
  1240. //
  1241. // Refresh child info
  1242. //
  1243. err = ISMQueryChildInfo(
  1244. ws.m_pKey,
  1245. WITH_INHERITANCE,
  1246. pii,
  1247. ws.m_dwInstance,
  1248. ws.m_strParent,
  1249. ws.m_strAlias
  1250. );
  1251. }
  1252. return err;
  1253. }
  1254. extern "C" HRESULT APIENTRY
  1255. ISMDeleteChild(
  1256. IN HANDLE hServer,
  1257. IN DWORD dwInstance,
  1258. IN LPCTSTR lpszParent,
  1259. IN LPCTSTR lpszAlias
  1260. )
  1261. /*++
  1262. Routine Description:
  1263. Delete a child.
  1264. Arguments:
  1265. HANDLE hServer : Server handle
  1266. DWORD dwInstance : Parent instance
  1267. LPCTSTR lpszParent : Parent path
  1268. LPCTSTR lpszAlias : Alias of child to be deleted
  1269. Return Value:
  1270. Error return code.
  1271. --*/
  1272. {
  1273. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1274. CError err;
  1275. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1276. BEGIN_ASSURE_BINDING_SECTION
  1277. err = CChildNodeProps::Delete(
  1278. pInterface,
  1279. g_cszSvc,
  1280. dwInstance,
  1281. lpszParent,
  1282. lpszAlias
  1283. );
  1284. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_CANCELLED);
  1285. return err;
  1286. }
  1287. extern "C" HRESULT APIENTRY
  1288. ISMRenameChild(
  1289. IN HANDLE hServer,
  1290. IN DWORD dwInstance,
  1291. IN LPCTSTR lpszParent,
  1292. IN LPCTSTR lpszAlias,
  1293. IN LPCTSTR lpszNewName
  1294. )
  1295. /*++
  1296. Routine Description:
  1297. Rename a child.
  1298. Arguments:
  1299. HANDLE hServer : Server handle
  1300. DWORD dwInstance : Parent instance
  1301. LPCTSTR lpszParent : Parent path
  1302. LPCTSTR lpszAlias : Alias of child to be renamed
  1303. LPCTSTR lpszNewName : New alias name
  1304. Return Value:
  1305. Error return code.
  1306. --*/
  1307. {
  1308. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1309. CError err;
  1310. CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer);
  1311. BEGIN_ASSURE_BINDING_SECTION
  1312. err = CChildNodeProps::Rename(
  1313. pInterface,
  1314. g_cszSvc,
  1315. dwInstance,
  1316. lpszParent,
  1317. lpszAlias,
  1318. lpszNewName
  1319. );
  1320. END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_CANCELLED)
  1321. return err;
  1322. }
  1323. extern "C" HRESULT APIENTRY
  1324. ISMQueryInstanceInfo(
  1325. IN HANDLE hServer,
  1326. IN BOOL fInherit,
  1327. OUT ISMINSTANCEINFO * pii,
  1328. IN DWORD dwInstance
  1329. )
  1330. /*++
  1331. Routine Description:
  1332. Get instance specific information.
  1333. Arguments:
  1334. HANDLE hServer : Server handle
  1335. BOOL fInherit : TRUE to inherit, FALSE otherwise
  1336. ISMINSTANCEINFO * pii : Instance info buffer
  1337. LPCTSTR lpszServer : A single server
  1338. DWORD dwInstance : Instance number
  1339. Return Value:
  1340. Error return code.
  1341. --*/
  1342. {
  1343. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1344. ASSERT(pii != NULL);
  1345. CError err;
  1346. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  1347. BEGIN_ASSURE_BINDING_SECTION
  1348. CInstanceProps inst(pKey, g_cszSvc, dwInstance);
  1349. err = inst.LoadData();
  1350. if (err.Succeeded())
  1351. {
  1352. pii->dwSize = ISMINSTANCEINFO_SIZE;
  1353. inst.FillInstanceInfo(pii);
  1354. //
  1355. // Get properties on the home directory
  1356. //
  1357. CChildNodeProps home(
  1358. &inst,
  1359. g_cszSvc,
  1360. dwInstance,
  1361. NULL,
  1362. g_cszRoot,
  1363. fInherit,
  1364. TRUE // Path only
  1365. );
  1366. err = home.LoadData();
  1367. home.FillInstanceInfo(pii);
  1368. }
  1369. END_ASSURE_BINDING_SECTION(err, pKey, err);
  1370. return err.Failed() ? err : S_OK;
  1371. }
  1372. extern "C" HRESULT APIENTRY
  1373. ISMQueryChildInfo(
  1374. IN HANDLE hServer,
  1375. IN BOOL fInherit,
  1376. OUT ISMCHILDINFO * pii,
  1377. IN DWORD dwInstance,
  1378. IN LPCTSTR lpszParent,
  1379. IN LPCTSTR lpszAlias
  1380. )
  1381. /*++
  1382. Routine Description:
  1383. Get child-specific info.
  1384. Arguments:
  1385. HANDLE hServer : Server handle
  1386. BOOL fInherit : TRUE to inherit, FALSE otherwise
  1387. ISMCHILDINFO * pii : Child info buffer
  1388. DWORD dwInstance : Parent instance
  1389. LPCTSTR lpszParent : Parent Path ("" for root)
  1390. LPCTSTR lpszAlias : Alias of child to be deleted
  1391. Return Value:
  1392. Error return code.
  1393. --*/
  1394. {
  1395. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1396. //
  1397. // Get all the inherited properties
  1398. //
  1399. CChildNodeProps node(
  1400. GetMetaKeyFromHandle(hServer),
  1401. g_cszSvc,
  1402. dwInstance,
  1403. lpszParent,
  1404. lpszAlias,
  1405. fInherit,
  1406. FALSE // Complete information
  1407. );
  1408. CError err(node.LoadData());
  1409. //
  1410. // Set the output structure
  1411. //
  1412. pii->dwSize = ISMCHILDINFO_SIZE;
  1413. node.FillChildInfo(pii);
  1414. //
  1415. // Not supported for FTP
  1416. //
  1417. ASSERT(!node.IsRedirected());
  1418. ASSERT(!*pii->szRedirPath);
  1419. ASSERT(!pii->fEnabledApplication);
  1420. return err;
  1421. }
  1422. extern "C" HRESULT APIENTRY
  1423. ISMConfigureChild(
  1424. IN HANDLE hServer,
  1425. IN HWND hWnd,
  1426. IN DWORD dwAttributes,
  1427. IN DWORD dwInstance,
  1428. IN LPCTSTR lpszParent,
  1429. IN LPCTSTR lpszAlias
  1430. )
  1431. /*++
  1432. Routine Description:
  1433. Configure child.
  1434. Arguments:
  1435. HANDLE hServer : Server handle
  1436. HWND hWnd : Main app window handle
  1437. DWORD dwAttributes : File attributes
  1438. DWORD dwInstance : Parent instance
  1439. LPCTSTR lpszParent : Parent path
  1440. LPCTSTR lpszAlias : Child to configure or NULL
  1441. Return Value:
  1442. Error return code.
  1443. --*/
  1444. {
  1445. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1446. CMetaKey * pKey = GetMetaKeyFromHandle(hServer);
  1447. LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
  1448. CError err;
  1449. CString strCaption;
  1450. {
  1451. CString str;
  1452. VERIFY(str.LoadString(IDS_DIR_TITLE));
  1453. strCaption.Format(str, lpszAlias);
  1454. }
  1455. ASSERT(dwAttributes == FILE_ATTRIBUTE_VIRTUAL_DIRECTORY);
  1456. //
  1457. // Call the APIs and build the property pages
  1458. //
  1459. CFtpSheet * pSheet = NULL;
  1460. try
  1461. {
  1462. pSheet = new CFtpSheet(
  1463. strCaption,
  1464. lpszServer,
  1465. dwInstance,
  1466. lpszParent,
  1467. lpszAlias,
  1468. CWnd::FromHandlePermanent(hWnd)
  1469. );
  1470. pSheet->AddRef();
  1471. if (SUCCEEDED(pSheet->QueryDirectoryResult()))
  1472. {
  1473. CFtpDirectoryPage * pDirPage = NULL;
  1474. CFtpSecurityPage * pSecPage = NULL;
  1475. //
  1476. // Add private pages
  1477. //
  1478. pSheet->AddPage(new CFtpDirectoryPage(pSheet));
  1479. pSheet->AddPage(new CFtpSecurityPage(pSheet));
  1480. }
  1481. }
  1482. catch(CMemoryException * e)
  1483. {
  1484. TRACEEOLID("Aborting due to exception");
  1485. err = ERROR_NOT_ENOUGH_MEMORY;
  1486. e->Delete();
  1487. }
  1488. if (err.Succeeded())
  1489. {
  1490. ASSERT(pSheet != NULL);
  1491. pSheet->DoModal();
  1492. pSheet->Release();
  1493. }
  1494. //
  1495. // Sheet and pages clean themselves up
  1496. //
  1497. return err;
  1498. }
  1499. class CFTPSecurityTemplate : public CIISSecurityTemplate
  1500. /*++
  1501. Class Description:
  1502. FTP Security template class
  1503. Public Interface:
  1504. CFTPSecurityTemplate : Constructor
  1505. ApplySettings : Apply template to destination path
  1506. GenerateSummary : Generate text summary
  1507. --*/
  1508. {
  1509. //
  1510. // Constructor
  1511. //
  1512. public:
  1513. CFTPSecurityTemplate(
  1514. IN const CMetaKey * pKey,
  1515. IN LPCTSTR lpszMDPath,
  1516. IN BOOL fInherit
  1517. );
  1518. public:
  1519. //
  1520. // Apply settings to destination path
  1521. //
  1522. virtual HRESULT ApplySettings(
  1523. IN BOOL fUseTemplates,
  1524. IN LPCTSTR lpszServerName,
  1525. IN LPCTSTR lpszService,
  1526. IN DWORD dwInstance = MASTER_INSTANCE,
  1527. IN LPCTSTR lpszParent = NULL,
  1528. IN LPCTSTR lpszAlias = NULL
  1529. );
  1530. //
  1531. // Load and parse source data
  1532. //
  1533. virtual HRESULT LoadData();
  1534. virtual void GenerateSummary(
  1535. IN BOOL fUseTemplates,
  1536. IN LPCTSTR lpszServerName,
  1537. IN LPCTSTR lpszService,
  1538. IN DWORD dwInstance = MASTER_INSTANCE,
  1539. IN LPCTSTR lpszParent = NULL,
  1540. IN LPCTSTR lpszAlias = NULL
  1541. );
  1542. protected:
  1543. //
  1544. // Break out GetAllData() data to data fields
  1545. //
  1546. virtual void ParseFields();
  1547. public:
  1548. MP_BOOL m_fAllowAnonymous;
  1549. MP_BOOL m_fAnonymousOnly;
  1550. };
  1551. CFTPSecurityTemplate::CFTPSecurityTemplate(
  1552. IN const CMetaKey * pKey,
  1553. IN LPCTSTR lpszMDPath,
  1554. IN BOOL fInherit
  1555. )
  1556. /*++
  1557. Routine Description:
  1558. Construct from open key
  1559. Arguments:
  1560. const CMetaKey * pKey : Open key
  1561. LPCTSTR lpszMDPath : Path
  1562. BOOL fInherit : TRUE to inherit values, FALSE if not
  1563. Return Value:
  1564. N/A
  1565. --*/
  1566. : CIISSecurityTemplate(pKey, lpszMDPath, fInherit),
  1567. m_fAllowAnonymous(FALSE),
  1568. m_fAnonymousOnly(FALSE)
  1569. {
  1570. //
  1571. // Managed Properties
  1572. //
  1573. m_dlProperties.AddTail(MD_ALLOW_ANONYMOUS);
  1574. m_dlProperties.AddTail(MD_ANONYMOUS_ONLY);
  1575. }
  1576. /* virtual */
  1577. HRESULT
  1578. CFTPSecurityTemplate::LoadData()
  1579. /*++
  1580. Routine Description:
  1581. LoadData() base class override
  1582. Arguments:
  1583. None
  1584. Return Value:
  1585. HRESULT
  1586. Notes:
  1587. The FTP wizard has an annoying idiosynchrasy: access authentication
  1588. settings are per site, not per vdir. Therefore, they need to be set
  1589. and fetched in a separate path, and not be set at all if not
  1590. setting props on a site. What a pain...
  1591. --*/
  1592. {
  1593. TRACEEOLID(m_strMetaPath);
  1594. CError err(CIISSecurityTemplate::LoadData());
  1595. if (lstrcmpi(m_strMetaRoot, g_cszRoot) == 0)
  1596. {
  1597. //
  1598. // Fetch the anonymous access settings from
  1599. // the instance node. Note: This explicit step
  1600. // should only be necessary for templates, because
  1601. // this would otherwise be picked up on inheritance.
  1602. //
  1603. ASSERT(!m_fInherit);
  1604. m_strMetaRoot.Empty();
  1605. err = CIISSecurityTemplate::LoadData();
  1606. }
  1607. return err;
  1608. }
  1609. /* virtual */
  1610. void
  1611. CFTPSecurityTemplate::ParseFields()
  1612. /*++
  1613. Routine Description:
  1614. Break into fields.
  1615. Arguments:
  1616. None.
  1617. Return Value:
  1618. None.
  1619. --*/
  1620. {
  1621. //
  1622. // Fetch base class values
  1623. //
  1624. CIISSecurityTemplate::ParseFields();
  1625. BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData)
  1626. HANDLE_META_RECORD(MD_ALLOW_ANONYMOUS, m_fAllowAnonymous)
  1627. HANDLE_META_RECORD(MD_ANONYMOUS_ONLY, m_fAnonymousOnly)
  1628. END_PARSE_META_RECORDS
  1629. }
  1630. /* virtual */
  1631. HRESULT
  1632. CFTPSecurityTemplate::ApplySettings(
  1633. IN BOOL fUseTemplate,
  1634. IN LPCTSTR lpszServerName,
  1635. IN LPCTSTR lpszService,
  1636. IN DWORD dwInstance,
  1637. IN LPCTSTR lpszParent,
  1638. IN LPCTSTR lpszAlias
  1639. )
  1640. /*++
  1641. Routine Description:
  1642. Apply the settings to the specified destination path
  1643. Arguments:
  1644. BOOL fUseTemplates : TRUE if the source is from a template,
  1645. FALSE if using inheritance.
  1646. LPCTSTR lpszServerName : Server name
  1647. LPCTSTR lpszService : Service name
  1648. DWORD dwInstance : Instance
  1649. LPCTSTR lpszParent : Parent path (or NULL)
  1650. LPCTSTR lpszAlias : Alias name (or NULL)
  1651. Return Value:
  1652. HRESULT
  1653. --*/
  1654. {
  1655. //
  1656. // Write base class properties
  1657. //
  1658. CError err(CIISSecurityTemplate::ApplySettings(
  1659. fUseTemplate,
  1660. lpszServerName,
  1661. lpszService,
  1662. dwInstance,
  1663. lpszParent,
  1664. lpszAlias
  1665. ));
  1666. if (err.Failed())
  1667. {
  1668. return err;
  1669. }
  1670. BOOL fWriteProperties = TRUE;
  1671. CMetaKey mk(
  1672. lpszServerName,
  1673. METADATA_PERMISSION_WRITE,
  1674. lpszService,
  1675. dwInstance,
  1676. lpszParent,
  1677. lpszAlias
  1678. );
  1679. err = mk.QueryResult();
  1680. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1681. {
  1682. if (!fUseTemplate)
  1683. {
  1684. //
  1685. // No need to delete properties; everything's already
  1686. // inherited. Note that this is the only legit failure
  1687. // case. If using a template, the base class must have
  1688. // created the path by now.
  1689. //
  1690. fWriteProperties = FALSE;
  1691. err.Reset();
  1692. }
  1693. }
  1694. if (fWriteProperties)
  1695. {
  1696. do
  1697. {
  1698. if (mk.IsHomeDirectoryPath())
  1699. {
  1700. BREAK_ON_ERR_FAILURE(err);
  1701. //
  1702. // Path describes an instance path, which is the only
  1703. // time we need to do anything here
  1704. //
  1705. err = mk.ConvertToParentPath(TRUE);
  1706. BREAK_ON_ERR_FAILURE(err);
  1707. if (fUseTemplate)
  1708. {
  1709. //
  1710. // Write values from template
  1711. //
  1712. err = mk.SetValue(
  1713. MD_ALLOW_ANONYMOUS,
  1714. m_fAllowAnonymous
  1715. );
  1716. BREAK_ON_ERR_FAILURE(err);
  1717. err = mk.SetValue(
  1718. MD_ANONYMOUS_ONLY,
  1719. m_fAnonymousOnly
  1720. );
  1721. }
  1722. else
  1723. {
  1724. //
  1725. // Inheritance case: delete authentication
  1726. // values
  1727. //
  1728. mk.DeleteValue(MD_ALLOW_ANONYMOUS);
  1729. mk.DeleteValue(MD_ANONYMOUS_ONLY);
  1730. }
  1731. }
  1732. }
  1733. while(FALSE);
  1734. }
  1735. return err;
  1736. }
  1737. /* virtual */
  1738. void
  1739. CFTPSecurityTemplate::GenerateSummary(
  1740. IN BOOL fUseTemplate,
  1741. IN LPCTSTR lpszServerName,
  1742. IN LPCTSTR lpszService,
  1743. IN DWORD dwInstance,
  1744. IN LPCTSTR lpszParent,
  1745. IN LPCTSTR lpszAlias
  1746. )
  1747. /*++
  1748. Routine Description:
  1749. Generate text summary of what's in the security template, and is about to
  1750. be applied to the given path.
  1751. Arguments:
  1752. BOOL fUseTemplates : TRUE if the source is from a template,
  1753. FALSE if using inheritance.
  1754. LPCTSTR lpszServerName : Server name
  1755. LPCTSTR lpszService : Service name
  1756. DWORD dwInstance : Instance
  1757. LPCTSTR lpszParent : Parent path (or NULL)
  1758. LPCTSTR lpszAlias : Alias name (or NULL)
  1759. Return Value:
  1760. None
  1761. --*/
  1762. {
  1763. CString strPath;
  1764. CMetaKey::BuildMetaPath(
  1765. strPath,
  1766. lpszService,
  1767. dwInstance,
  1768. lpszParent,
  1769. lpszAlias
  1770. );
  1771. //
  1772. // Authentication methods apply to instances only
  1773. //
  1774. if (CMetaKey::IsHomeDirectoryPath(strPath))
  1775. {
  1776. //
  1777. // Add private summary items
  1778. //
  1779. AddSummaryString(IDS_AUTHENTICATION_METHODS);
  1780. //
  1781. // Summarize Authentication Methods:
  1782. //
  1783. AddSummaryString(
  1784. m_fAllowAnonymous
  1785. ? IDS_AUTHENTICATION_ANONYMOUS
  1786. : IDS_AUTHENTICATION_NO_ANONYMOUS,
  1787. 1
  1788. );
  1789. if (m_fAllowAnonymous && m_fAnonymousOnly)
  1790. {
  1791. AddSummaryString(IDS_AUTHENTICATION_ANONYMOUS_ONLY, 1);
  1792. }
  1793. }
  1794. //
  1795. // Add base class summary
  1796. //
  1797. CIISSecurityTemplate::GenerateSummary(
  1798. fUseTemplate,
  1799. lpszServerName,
  1800. lpszService,
  1801. dwInstance,
  1802. lpszParent,
  1803. lpszAlias
  1804. );
  1805. }
  1806. CIISSecurityTemplate *
  1807. AllocateSecurityTemplate(
  1808. IN const CMetaKey * pKey,
  1809. IN LPCTSTR lpszMDPath,
  1810. IN BOOL fInherit
  1811. )
  1812. /*++
  1813. Routine Description:
  1814. Security template allocator function
  1815. Arguments:
  1816. IN const CMetaKey * pKey : Open key
  1817. IN LPCTSTR lpszMDPath : Path
  1818. IN BOOL fInherit : TRUE to inherit properties
  1819. Return Value:
  1820. Pointer to newly allocated security object
  1821. --*/
  1822. {
  1823. return new CFTPSecurityTemplate(pKey, lpszMDPath, fInherit);
  1824. }
  1825. extern "C" HRESULT APIENTRY
  1826. ISMSecurityWizard(
  1827. IN HANDLE hServer,
  1828. IN DWORD dwInstance,
  1829. IN LPCTSTR lpszParent,
  1830. IN LPCTSTR lpszAlias
  1831. )
  1832. /*++
  1833. Routine Description:
  1834. Launch the security wizard
  1835. Arguments:
  1836. HANDLE hServer : Server handle
  1837. DWORD dwInstance : Parent instance
  1838. LPCTSTR lpszParent : Parent path
  1839. LPCTSTR lpszAlias : Child to configure or NULL
  1840. Return Value:
  1841. HRESULT
  1842. --*/
  1843. {
  1844. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1845. return COMDLL_ISMSecurityWizard(
  1846. &AllocateSecurityTemplate,
  1847. GetMetaKeyFromHandle(hServer),
  1848. IDB_WIZ_LEFT_SEC,
  1849. IDB_WIZ_HEAD_SEC,
  1850. g_cszSvc,
  1851. dwInstance,
  1852. lpszParent,
  1853. lpszAlias
  1854. );
  1855. }
  1856. //
  1857. // End of ISM API Functions
  1858. //
  1859. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1860. void
  1861. InitializeDLL()
  1862. /*++
  1863. Routine Description:
  1864. Perform additional DLL initialisation as necessary
  1865. Arguments:
  1866. None
  1867. Return Value:
  1868. None
  1869. --*/
  1870. {
  1871. #ifdef _DEBUG
  1872. afxMemDF |= checkAlwaysMemDF;
  1873. #endif // _DEBUG
  1874. #ifdef UNICODE
  1875. TRACEEOLID("Loading UNICODE fscfg.dll");
  1876. #else
  1877. TRACEEOLID("Loading ANSI fscfg.dll");
  1878. #endif UNICODE
  1879. ::AfxEnableControlContainer();
  1880. #ifndef _COMSTATIC
  1881. //
  1882. // Initialize IISUI extension DLL
  1883. //
  1884. InitIISUIDll();
  1885. #endif // _COMSTATIC
  1886. }
  1887. //
  1888. // Declare the one and only dll object
  1889. //
  1890. CConfigDll NEAR theApp;
  1891. CConfigDll::CConfigDll(
  1892. IN LPCTSTR pszAppName OPTIONAL
  1893. )
  1894. /*++
  1895. Routine Description:
  1896. Constructor for USRDLL
  1897. Arguments:
  1898. LPCTSTR pszAppName : Name of the app or NULL to load from resources
  1899. Return Value:
  1900. N/A
  1901. --*/
  1902. : CWinApp(pszAppName),
  1903. m_lpOldHelpPath(NULL)
  1904. {
  1905. }
  1906. BOOL
  1907. CConfigDll::InitInstance()
  1908. /*++
  1909. Routine Description:
  1910. Initialise current instance of the DLL
  1911. Arguments:
  1912. None
  1913. Return Value:
  1914. TRUE for successful initialisation, FALSE otherwise
  1915. --*/
  1916. {
  1917. BOOL bInit = CWinApp::InitInstance();
  1918. hInstance = ::AfxGetInstanceHandle();
  1919. ASSERT(hInstance);
  1920. InitializeDLL();
  1921. try
  1922. {
  1923. //
  1924. // Get the help path
  1925. //
  1926. m_lpOldHelpPath = m_pszHelpFilePath;
  1927. ASSERT(m_pszHelpFilePath != NULL);
  1928. CString strFile(_tcsrchr(m_pszHelpFilePath, _T('\\')));
  1929. CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ);
  1930. rk.QueryValue(SZ_HELPPATH, m_strHelpPath, EXPANSION_ON);
  1931. m_strHelpPath += strFile;
  1932. }
  1933. catch(CException * e)
  1934. {
  1935. e->ReportError();
  1936. e->Delete();
  1937. }
  1938. if (!m_strHelpPath.IsEmpty())
  1939. {
  1940. m_pszHelpFilePath = m_strHelpPath;
  1941. }
  1942. return bInit;
  1943. }
  1944. int
  1945. CConfigDll::ExitInstance()
  1946. /*++
  1947. Routine Description:
  1948. Clean up current instance
  1949. Arguments:
  1950. None
  1951. Return Value:
  1952. The application's exit code; 0 indicates no errors, and values greater
  1953. than 0 indicate an error.
  1954. --*/
  1955. {
  1956. m_pszHelpFilePath = m_lpOldHelpPath;
  1957. return CWinApp::ExitInstance();
  1958. }
  1959. //
  1960. // Message Map
  1961. //
  1962. BEGIN_MESSAGE_MAP(CConfigDll, CWinApp)
  1963. //{{AFX_MSG_MAP(CConfigDll)
  1964. //}}AFX_MSG_MAP
  1965. //
  1966. // Global Help Commands
  1967. //
  1968. ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  1969. ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp)
  1970. END_MESSAGE_MAP()