Leaked source code of windows server 2003
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.

1485 lines
37 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name :
  4. iisservice.cpp
  5. Abstract:
  6. IISService Object
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. 10/28/2000 sergeia Split from iisobj.cpp
  14. --*/
  15. #include "stdafx.h"
  16. #include "common.h"
  17. #include "inetprop.h"
  18. #include "InetMgrApp.h"
  19. #include "supdlgs.h"
  20. #include "connects.h"
  21. #include "iisobj.h"
  22. #include "ftpsht.h"
  23. #include "fservic.h"
  24. #include "facc.h"
  25. #include "fmessage.h"
  26. #include "fvdir.h"
  27. #include "fsecure.h"
  28. #include "w3sht.h"
  29. #include "wservic.h"
  30. #include "wvdir.h"
  31. #include "wsecure.h"
  32. #include "fltdlg.h"
  33. #include "filters.h"
  34. #include "perform.h"
  35. #include "docum.h"
  36. #include "httppage.h"
  37. #include "defws.h"
  38. #include "deffs.h"
  39. #include "errors.h"
  40. #include "util.h"
  41. #ifdef _DEBUG
  42. #undef THIS_FILE
  43. static char BASED_CODE THIS_FILE[] = __FILE__;
  44. #endif
  45. #define new DEBUG_NEW
  46. //
  47. // CIISService Implementation
  48. //
  49. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  50. /* static */
  51. HRESULT
  52. __cdecl
  53. CIISService::ShowFTPSiteProperties(
  54. LPPROPERTYSHEETCALLBACK lpProvider,
  55. CComAuthInfo * pAuthInfo,
  56. LPCTSTR lpszMDPath,
  57. CWnd * pMainWnd,
  58. LPARAM lParam,
  59. LPARAM lParamParent,
  60. LONG_PTR handle
  61. )
  62. /*++
  63. Routine Description:
  64. Callback function to display FTP site properties.
  65. Arguments:
  66. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  67. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  68. LPCTSTR lpszMDPath Metabase path
  69. CWnd * pMainWnd Parent window
  70. LPARAM lParam LPARAM to pass to MMC
  71. LONG handle handle to pass to MMC
  72. Return Value:
  73. HRESULT
  74. --*/
  75. {
  76. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  77. ASSERT_PTR(lpProvider);
  78. CError err;
  79. CFtpSheet * pSheet = new CFtpSheet(
  80. pAuthInfo,
  81. lpszMDPath,
  82. pMainWnd,
  83. lParam,
  84. lParamParent
  85. );
  86. if (pSheet)
  87. {
  88. pSheet->SetModeless();
  89. pSheet->SetSheetType(pSheet->SHEET_TYPE_SITE);
  90. CIISMachine * pOwner = ((CIISMBNode *)lParam)->GetOwner();
  91. ASSERT(pOwner != NULL);
  92. CFTPInstanceProps ip(pSheet->QueryAuthInfo(), pSheet->QueryMetaPath());
  93. ip.LoadData();
  94. //
  95. // Add instance pages
  96. //
  97. if (pOwner->IsServiceLevelConfigurable() || !CMetabasePath::IsMasterInstance(lpszMDPath))
  98. {
  99. err = AddMMCPage(lpProvider, new CFtpServicePage(pSheet));
  100. }
  101. if (!ip.HasADUserIsolation())
  102. {
  103. err = AddMMCPage(lpProvider, new CFtpAccountsPage(pSheet));
  104. }
  105. err = AddMMCPage(lpProvider, new CFtpMessagePage(pSheet));
  106. //
  107. // Add directory pages
  108. //
  109. if (!ip.HasADUserIsolation())
  110. {
  111. err = AddMMCPage(lpProvider, new CFtpDirectoryPage(pSheet, TRUE));
  112. }
  113. // BUG:639135
  114. // 1. enabled for remote admin to iis5,
  115. // 2. NOT enabled for remote admin to iis5.1
  116. // 3. enabled for iis6
  117. if (pOwner->QueryMajorVersion() >= 5)
  118. {
  119. if (pOwner->QueryMajorVersion() == 5 && pOwner->QueryMinorVersion() == 1)
  120. {
  121. // if it's iis5.1 then don't show it.
  122. }
  123. else
  124. {
  125. err = AddMMCPage(lpProvider, new CFtpSecurityPage(pSheet));
  126. }
  127. }
  128. //
  129. // Add master site pages
  130. //
  131. //if (CMetabasePath::IsMasterInstance(lpszMDPath) && pOwner->QueryMajorVersion() >= 6)
  132. //{
  133. // err = AddMMCPage(lpProvider, new CDefFtpSitePage(pSheet));
  134. //}
  135. }
  136. else
  137. {
  138. err = ERROR_NOT_ENOUGH_MEMORY;
  139. }
  140. return err;
  141. }
  142. /* static */
  143. HRESULT
  144. __cdecl
  145. CIISService::ShowFTPDirProperties(
  146. LPPROPERTYSHEETCALLBACK lpProvider,
  147. CComAuthInfo * pAuthInfo,
  148. LPCTSTR lpszMDPath,
  149. CWnd * pMainWnd,
  150. LPARAM lParam,
  151. LPARAM lParamParent,
  152. LONG_PTR handle
  153. )
  154. /*++
  155. Routine Description:
  156. Callback function to display FTP dir properties.
  157. Arguments:
  158. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  159. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  160. LPCTSTR lpszMDPath Metabase path
  161. CWnd * pMainWnd Parent window
  162. LPARAM lParam LPARAM to pass to MMC
  163. LONG handle handle to pass to MMC
  164. Return Value:
  165. HRESULT
  166. --*/
  167. {
  168. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  169. ASSERT_PTR(lpProvider);
  170. CError err;
  171. CFtpSheet * pSheet = new CFtpSheet(
  172. pAuthInfo,
  173. lpszMDPath,
  174. pMainWnd,
  175. lParam,
  176. lParamParent
  177. );
  178. if (pSheet)
  179. {
  180. pSheet->SetModeless();
  181. pSheet->SetSheetType(pSheet->SHEET_TYPE_VDIR);
  182. CIISMachine * pOwner = ((CIISMBNode *)lParam)->GetOwner();
  183. ASSERT(pOwner != NULL);
  184. //
  185. // Add directory pages
  186. //
  187. err = AddMMCPage(lpProvider, new CFtpDirectoryPage(pSheet, FALSE));
  188. // BUG:639135
  189. // 1. enabled for remote admin to iis5,
  190. // 2. NOT enabled for remote admin to iis5.1
  191. // 3. enabled for iis6
  192. if (pOwner->QueryMajorVersion() >= 5)
  193. {
  194. if (pOwner->QueryMajorVersion() == 5 && pOwner->QueryMinorVersion() == 1)
  195. {
  196. // if it's iis5.1 then don't show it.
  197. }
  198. else
  199. {
  200. err = AddMMCPage(lpProvider, new CFtpSecurityPage(pSheet));
  201. }
  202. }
  203. }
  204. else
  205. {
  206. err = ERROR_NOT_ENOUGH_MEMORY;
  207. }
  208. return err;
  209. }
  210. /* static */
  211. HRESULT
  212. __cdecl
  213. CIISService::ShowWebSiteProperties(
  214. LPPROPERTYSHEETCALLBACK lpProvider,
  215. CComAuthInfo * pAuthInfo,
  216. LPCTSTR lpszMDPath,
  217. CWnd * pMainWnd,
  218. LPARAM lParam,
  219. LPARAM lParamParent,
  220. LONG_PTR handle
  221. )
  222. /*++
  223. Routine Description:
  224. Callback function to display Web site properties.
  225. Arguments:
  226. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  227. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  228. LPCTSTR lpszMDPath Metabase path
  229. CWnd * pMainWnd Parent window
  230. LPARAM lParam LPARAM to pass to MMC
  231. LONG handle handle to pass to MMC
  232. Return Value:
  233. HRESULT
  234. --*/
  235. {
  236. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  237. ASSERT_PTR(lpProvider);
  238. CError err;
  239. CW3Sheet * pSheet = new CW3Sheet(
  240. pAuthInfo,
  241. lpszMDPath,
  242. 0,
  243. pMainWnd,
  244. lParam,
  245. lParamParent
  246. );
  247. if (pSheet)
  248. {
  249. pSheet->SetModeless();
  250. pSheet->SetSheetType(pSheet->SHEET_TYPE_SITE);
  251. CIISMachine * pOwner = ((CIISMBNode *)lParam)->GetOwner();
  252. ASSERT(pOwner != NULL);
  253. BOOL bMaster = CMetabasePath::IsMasterInstance(lpszMDPath);
  254. BOOL bClient = pOwner->IsWorkstation();
  255. BOOL bServiceLevelConfig = pOwner->IsServiceLevelConfigurable();
  256. BOOL bAddPerformancePage = FALSE;
  257. BOOL bDownlevel = (pOwner->QueryMajorVersion() == 5 && pOwner->QueryMinorVersion() == 0);
  258. //
  259. // Add instance pages
  260. //
  261. if (bServiceLevelConfig || !bMaster)
  262. {
  263. err = AddMMCPage(lpProvider, new CW3ServicePage(pSheet));
  264. }
  265. // see if we need to add the performance page...
  266. bAddPerformancePage = pOwner->IsPerformanceConfigurable();
  267. if (!bClient)
  268. {
  269. bAddPerformancePage = TRUE;
  270. if (bDownlevel)
  271. {
  272. bAddPerformancePage = FALSE;
  273. if (!bMaster)
  274. {
  275. bAddPerformancePage = TRUE;
  276. }
  277. }
  278. }
  279. // iis6 allows this page for workstation.
  280. if (bAddPerformancePage)
  281. {
  282. err = AddMMCPage(lpProvider, new CW3PerfPage(pSheet));
  283. }
  284. err = AddMMCPage(lpProvider, new CW3FiltersPage(pSheet));
  285. //
  286. // Add directory pages
  287. //
  288. err = AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, TRUE));
  289. err = AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  290. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, TRUE, FILE_ATTRIBUTE_VIRTUAL_DIRECTORY));
  291. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  292. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  293. if (bMaster && pOwner->QueryMajorVersion() >= 6)
  294. {
  295. err = AddMMCPage(lpProvider, new CDefWebSitePage(pSheet));
  296. }
  297. else
  298. {
  299. if (bMaster && bDownlevel)
  300. {
  301. err = AddMMCPage(lpProvider, new CDefWebSitePage(pSheet));
  302. }
  303. }
  304. }
  305. else
  306. {
  307. err = ERROR_NOT_ENOUGH_MEMORY;
  308. }
  309. return S_OK;
  310. }
  311. /* static */
  312. HRESULT
  313. __cdecl
  314. CIISService::ShowWebDirProperties(
  315. LPPROPERTYSHEETCALLBACK lpProvider,
  316. CComAuthInfo * pAuthInfo,
  317. LPCTSTR lpszMDPath,
  318. CWnd * pMainWnd,
  319. LPARAM lParam,
  320. LPARAM lParamParent,
  321. LONG_PTR handle
  322. )
  323. /*++
  324. Routine Description:
  325. Callback function to display Web dir properties.
  326. Arguments:
  327. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  328. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  329. LPCTSTR lpszMDPath Metabase path
  330. CWnd * pMainWnd Parent window
  331. LPARAM lParam LPARAM to pass to MMC
  332. LONG handle handle to pass to MMC
  333. Return Value:
  334. HRESULT
  335. --*/
  336. {
  337. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  338. ASSERT_PTR(lpProvider);
  339. CError err;
  340. CW3Sheet * pSheet = new CW3Sheet(
  341. pAuthInfo,
  342. lpszMDPath,
  343. 0,
  344. pMainWnd,
  345. lParam,
  346. lParamParent
  347. );
  348. if (pSheet)
  349. {
  350. pSheet->SetModeless();
  351. pSheet->SetSheetType(pSheet->SHEET_TYPE_VDIR);
  352. //
  353. // Add directory pages
  354. //
  355. err = AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, FALSE));
  356. err = AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  357. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, FILE_ATTRIBUTE_VIRTUAL_DIRECTORY));
  358. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  359. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  360. }
  361. else
  362. {
  363. err = ERROR_NOT_ENOUGH_MEMORY;
  364. }
  365. return err;
  366. }
  367. //
  368. // Administrable services
  369. //
  370. /* static */ CIISService::SERVICE_DEF CIISService::_rgServices[] =
  371. {
  372. {
  373. _T("MSFTPSVC"),
  374. _T("ftp://"),
  375. IDS_SVC_FTP,
  376. iFolder, // TODO: Need service bitmap
  377. iFolderStop,// TODO: Need service bitmap
  378. iFTPSite,
  379. iFTPSiteStop,
  380. iFTPSiteErr,
  381. iFTPDir,
  382. iFTPDirErr,
  383. iFolder,
  384. iFile,
  385. IIS_CLASS_FTP_SERVICE_W,
  386. IIS_CLASS_FTP_SERVER_W,
  387. IIS_CLASS_FTP_VDIR_W,
  388. &CIISService::ShowFTPSiteProperties,
  389. &CIISService::ShowFTPDirProperties,
  390. },
  391. {
  392. _T("W3SVC"),
  393. _T("http://"),
  394. IDS_SVC_WEB,
  395. iFolder, // TODO: Need service bitmap
  396. iFolderStop,// TODO: Need service bitmap
  397. iWWWSite,
  398. iWWWSiteStop,
  399. iWWWSiteErr,
  400. iWWWDir,
  401. iWWWDirErr,
  402. iFolder,
  403. iFile,
  404. IIS_CLASS_WEB_SERVICE_W,
  405. IIS_CLASS_WEB_SERVER_W,
  406. IIS_CLASS_WEB_VDIR_W,
  407. &CIISService::ShowWebSiteProperties,
  408. &CIISService::ShowWebDirProperties,
  409. },
  410. };
  411. /* static */
  412. int
  413. CIISService::ResolveServiceName(
  414. LPCTSTR szServiceName
  415. )
  416. /*++
  417. Routine Description:
  418. Look up the service name in the table. Return table index.
  419. Arguments:
  420. LPCTSTR szServiceName : Metabase node name
  421. Return Value:
  422. Table index or -1 if not found.
  423. --*/
  424. {
  425. int iDef = -1;
  426. //
  427. // Sequential search because we expect just a few entries
  428. //
  429. for (int i = 0; i < ARRAY_SIZE(_rgServices); ++i)
  430. {
  431. if (!_tcsicmp(szServiceName, _rgServices[i].szNodeName))
  432. {
  433. iDef = i;
  434. break;
  435. }
  436. }
  437. return iDef;
  438. }
  439. CIISService::CIISService(
  440. CIISMachine * pOwner,
  441. LPCTSTR szServiceName
  442. )
  443. : CIISMBNode(pOwner, szServiceName)
  444. {
  445. m_iServiceDef = ResolveServiceName(QueryNodeName());
  446. m_fManagedService = (m_iServiceDef >= 0);
  447. m_fCanAddInstance = pOwner->CanAddInstance();
  448. m_dwServiceState = 0;
  449. m_dwServiceStateDisplayed = 0;
  450. if (m_fManagedService)
  451. {
  452. ASSERT(m_iServiceDef < ARRAY_SIZE(_rgServices));
  453. VERIFY(m_bstrDisplayName.LoadString(
  454. _rgServices[m_iServiceDef].nDescriptiveName
  455. ));
  456. CString buf = m_bstrDisplayName;
  457. buf.Format(IDS_DISABLED_SERVICE_FMT, m_bstrDisplayName);
  458. m_bstrDisplayNameStatus = buf;
  459. }
  460. }
  461. /* virtual */
  462. CIISService::~CIISService()
  463. {
  464. }
  465. int
  466. CIISService::_rgnLabels[COL_TOTAL] =
  467. {
  468. IDS_RESULT_NAME,
  469. IDS_RESULT_STATUS,
  470. };
  471. int CIISService::_rgnWidths[COL_TOTAL] =
  472. {
  473. 200,
  474. 300,
  475. };
  476. /* static */ CComBSTR CIISService::_bstrServiceDisabled;
  477. /* static */ CComBSTR CIISService::_bstrServiceRunning;
  478. /* static */ CComBSTR CIISService::_bstrServiceStopped;
  479. /* static */ CComBSTR CIISService::_bstrServicePaused;
  480. /* static */ CComBSTR CIISService::_bstrServiceStopPending;
  481. /* static */ CComBSTR CIISService::_bstrServiceStartPending;
  482. /* static */ CComBSTR CIISService::_bstrServicePausePending;
  483. /* static */ CComBSTR CIISService::_bstrServiceContPending;
  484. /* static */ BOOL CIISService::_fStaticsLoaded = FALSE;
  485. /* static */
  486. void
  487. CIISService::InitializeHeaders(LPHEADERCTRL lpHeader)
  488. {
  489. CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
  490. if (!_fStaticsLoaded)
  491. {
  492. _fStaticsLoaded =
  493. _bstrServiceDisabled.LoadString(IDS_SERVICE_DISABLED)&&
  494. _bstrServiceRunning.LoadString(IDS_SERVICE_RUNNING) &&
  495. _bstrServiceStopped.LoadString(IDS_SERVICE_STOPPED) &&
  496. _bstrServicePaused.LoadString(IDS_SERVICE_PAUSED) &&
  497. _bstrServiceStopPending.LoadString(IDS_SERVICE_STOP_PENDING) &&
  498. _bstrServiceStartPending.LoadString(IDS_SERVICE_START_PENDING) &&
  499. _bstrServicePausePending.LoadString(IDS_SERVICE_PAUSE_PENDING) &&
  500. _bstrServiceContPending.LoadString(IDS_SERVICE_CONT_PENDING);
  501. }
  502. }
  503. /* virtual */
  504. void
  505. CIISService::InitializeChildHeaders(
  506. LPHEADERCTRL lpHeader
  507. )
  508. {
  509. BOOL IsFtpType = _tcsicmp(QueryServiceName(), SZ_MBN_FTP) == 0;
  510. if (IsFtpType)
  511. {
  512. CIISSite::InitializeHeaders2(lpHeader);
  513. }
  514. else
  515. {
  516. CIISSite::InitializeHeaders(lpHeader);
  517. }
  518. }
  519. #define SERVICE_CONFIG_BUF 2048
  520. HRESULT
  521. CIISService::GetServiceState(DWORD& mode, DWORD& state, CString& name)
  522. {
  523. HRESULT hr = S_OK;
  524. state = SERVICE_STOPPED;
  525. CString strComputerNameToUse;
  526. strComputerNameToUse = QueryMachineName();
  527. CIISMachine * pMachineObj = GetOwner();
  528. if (!pMachineObj)
  529. {
  530. return E_FAIL;
  531. }
  532. if (pMachineObj->IsLocalHost())
  533. {
  534. // Use the local machine name.
  535. TCHAR szLocalServer[MAX_PATH + 1];
  536. DWORD dwSize = MAX_PATH;
  537. if (::GetComputerName(szLocalServer, &dwSize))
  538. {
  539. strComputerNameToUse = _T("\\\\");
  540. strComputerNameToUse += szLocalServer;
  541. }
  542. }
  543. SC_HANDLE sm = OpenSCManager(strComputerNameToUse, NULL, GENERIC_READ);
  544. if (sm != NULL)
  545. {
  546. SC_HANDLE service = OpenService(sm, QueryServiceName(),
  547. SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
  548. if (service != NULL)
  549. {
  550. QUERY_SERVICE_CONFIG * conf;
  551. DWORD cb;
  552. conf = (QUERY_SERVICE_CONFIG *)LocalAlloc(LPTR, SERVICE_CONFIG_BUF);
  553. if (conf != NULL)
  554. {
  555. if (QueryServiceConfig(service, conf, SERVICE_CONFIG_BUF, &cb))
  556. {
  557. mode = conf->dwStartType;
  558. name = conf->lpDisplayName;
  559. SERVICE_STATUS status;
  560. if (QueryServiceStatus(service, &status))
  561. {
  562. state = status.dwCurrentState;
  563. }
  564. else
  565. hr = HRESULT_FROM_WIN32(GetLastError());
  566. }
  567. else
  568. hr = HRESULT_FROM_WIN32(GetLastError());
  569. LocalFree(conf);
  570. }
  571. else
  572. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  573. CloseServiceHandle(service);
  574. }
  575. else
  576. hr = HRESULT_FROM_WIN32(GetLastError());
  577. CloseServiceHandle(sm);
  578. }
  579. else
  580. hr = HRESULT_FROM_WIN32(GetLastError());
  581. if (SUCCEEDED(hr))
  582. {
  583. if (SERVICE_DISABLED == mode)
  584. {
  585. m_dwServiceState = -1;
  586. }
  587. else
  588. {
  589. m_dwServiceState = state;
  590. }
  591. }
  592. else
  593. {
  594. // Calling service api's failed
  595. // could be because in remote scenario
  596. m_dwServiceState = SERVICE_RUNNING;
  597. }
  598. return hr;
  599. }
  600. HRESULT
  601. CIISService::GetServiceState()
  602. {
  603. DWORD mode,state;
  604. CString name;
  605. return GetServiceState(mode,state,name);
  606. }
  607. HRESULT
  608. CIISService::EnableService()
  609. {
  610. HRESULT hr = S_OK;
  611. CString strComputerNameToUse;
  612. strComputerNameToUse = QueryMachineName();
  613. CIISMachine * pMachineObj = GetOwner();
  614. if (!pMachineObj)
  615. {
  616. return E_FAIL;
  617. }
  618. if (pMachineObj->IsLocalHost())
  619. {
  620. // Use the local machine name.
  621. TCHAR szLocalServer[MAX_PATH + 1];
  622. DWORD dwSize = MAX_PATH;
  623. if (::GetComputerName(szLocalServer, &dwSize))
  624. {
  625. strComputerNameToUse = _T("\\\\");
  626. strComputerNameToUse += szLocalServer;
  627. }
  628. }
  629. SC_HANDLE sm = OpenSCManager(strComputerNameToUse, NULL, GENERIC_READ);
  630. if (sm != NULL)
  631. {
  632. SC_HANDLE service = OpenService(sm, QueryServiceName(),
  633. SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG);
  634. if (service != NULL)
  635. {
  636. hr = ChangeServiceConfig(
  637. service,
  638. SERVICE_NO_CHANGE,
  639. SERVICE_AUTO_START,
  640. SERVICE_NO_CHANGE,
  641. NULL,
  642. NULL,
  643. NULL,
  644. NULL,
  645. NULL,
  646. _T(""),
  647. NULL);
  648. #if 0
  649. QUERY_SERVICE_CONFIG * conf;
  650. DWORD cb;
  651. conf = (QUERY_SERVICE_CONFIG *)LocalAlloc(LPTR, SERVICE_CONFIG_BUF);
  652. if (conf != NULL)
  653. {
  654. if (QueryServiceConfig(service, conf, SERVICE_CONFIG_BUF, &cb))
  655. {
  656. mode = conf->dwStartType;
  657. SERVICE_STATUS status;
  658. if (QueryServiceStatus(service, &status))
  659. {
  660. state = status.dwCurrentState;
  661. }
  662. else
  663. hr = HRESULT_FROM_WIN32(GetLastError());
  664. }
  665. else
  666. hr = HRESULT_FROM_WIN32(GetLastError());
  667. LocalFree(conf);
  668. }
  669. else
  670. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  671. #endif
  672. CloseServiceHandle(service);
  673. }
  674. else
  675. hr = HRESULT_FROM_WIN32(GetLastError());
  676. CloseServiceHandle(sm);
  677. }
  678. else
  679. hr = HRESULT_FROM_WIN32(GetLastError());
  680. return hr;
  681. }
  682. HRESULT
  683. CIISService::StartService()
  684. {
  685. HRESULT hr = S_OK;
  686. const DWORD dwSvcSleepInterval = 500 ;
  687. DWORD dwSvcMaxSleep = 180000 ;
  688. SC_HANDLE hScManager = NULL;
  689. SC_HANDLE hService = NULL;
  690. CString strComputerNameToUse;
  691. strComputerNameToUse = QueryMachineName();
  692. CIISMachine * pMachineObj = GetOwner();
  693. if (!pMachineObj)
  694. {
  695. return E_FAIL;
  696. }
  697. if (pMachineObj->IsLocalHost())
  698. {
  699. // Use the local machine name.
  700. TCHAR szLocalServer[MAX_PATH + 1];
  701. DWORD dwSize = MAX_PATH;
  702. if (::GetComputerName(szLocalServer, &dwSize))
  703. {
  704. strComputerNameToUse = _T("\\\\");
  705. strComputerNameToUse += szLocalServer;
  706. }
  707. }
  708. do
  709. {
  710. // set up the service first
  711. if ((hScManager = OpenSCManager( strComputerNameToUse, NULL, GENERIC_READ )) == NULL || (hService = ::OpenService( hScManager, QueryServiceName(), SERVICE_START )) == NULL )
  712. {
  713. hr = HRESULT_FROM_WIN32(GetLastError());
  714. break;
  715. }
  716. SERVICE_STATUS svcStatus;
  717. if ( !QueryServiceStatus( hService, &svcStatus ))
  718. {
  719. hr = HRESULT_FROM_WIN32(GetLastError());
  720. break;
  721. }
  722. if ( svcStatus.dwCurrentState == SERVICE_RUNNING )
  723. {
  724. break; // service already started and running
  725. }
  726. if ( !::StartService( hService, 0, NULL ))
  727. {
  728. hr = HRESULT_FROM_WIN32(GetLastError());
  729. break;
  730. }
  731. // Wait for the service to attain "running" status; but
  732. // wait no more than 3 minute.
  733. DWORD dwSleepTotal;
  734. for ( dwSleepTotal = 0 ; dwSleepTotal < dwSvcMaxSleep
  735. && (QueryServiceStatus( hService, &svcStatus ))
  736. && svcStatus.dwCurrentState == SERVICE_START_PENDING ;
  737. dwSleepTotal += dwSvcSleepInterval )
  738. {
  739. ::Sleep( dwSvcSleepInterval ) ;
  740. }
  741. if ( svcStatus.dwCurrentState != SERVICE_RUNNING )
  742. {
  743. hr = dwSleepTotal > dwSvcMaxSleep ? HRESULT_FROM_WIN32(ERROR_SERVICE_REQUEST_TIMEOUT) : HRESULT_FROM_WIN32(svcStatus.dwWin32ExitCode);
  744. break;
  745. }
  746. } while ( FALSE );
  747. if (hService){CloseServiceHandle(hService);}
  748. if (hScManager){CloseServiceHandle(hScManager);}
  749. return hr;
  750. }
  751. /* virtual */
  752. LPOLESTR
  753. CIISService::GetResultPaneColInfo(int nCol)
  754. {
  755. DWORD mode, state;
  756. CString name;
  757. CError err;
  758. switch (nCol)
  759. {
  760. case COL_DESCRIPTION:
  761. return QueryDisplayName();
  762. case COL_STATE:
  763. err = GetServiceState(mode, state, name);
  764. if (err.Succeeded())
  765. {
  766. if (m_dwServiceState)
  767. {
  768. if (m_dwServiceStateDisplayed != m_dwServiceState)
  769. {
  770. RefreshDisplay();
  771. break;
  772. }
  773. switch (m_dwServiceState)
  774. {
  775. case -1:
  776. return _bstrServiceDisabled;
  777. case SERVICE_STOPPED:
  778. return _bstrServiceStopped;
  779. case SERVICE_RUNNING:
  780. return _bstrServiceRunning;
  781. case SERVICE_PAUSED:
  782. return _bstrServicePaused;
  783. case SERVICE_START_PENDING:
  784. return _bstrServiceStartPending;
  785. case SERVICE_STOP_PENDING:
  786. return _bstrServiceStopPending;
  787. case SERVICE_PAUSE_PENDING:
  788. return _bstrServicePausePending;
  789. case SERVICE_CONTINUE_PENDING:
  790. return _bstrServiceContPending;
  791. default:
  792. break;
  793. }
  794. }
  795. }
  796. break;
  797. }
  798. return OLESTR("");
  799. }
  800. /* virtual */
  801. HRESULT
  802. CIISService::RefreshData()
  803. {
  804. CError err = GetServiceState();
  805. return S_OK;
  806. }
  807. /* virtual */
  808. HRESULT
  809. CIISService::EnumerateScopePane(HSCOPEITEM hParent)
  810. {
  811. CError err;
  812. DWORD dwInstance;
  813. CString strInstance;
  814. CMetaEnumerator * pme = NULL;
  815. CIISSite * psite = NULL;
  816. if (!IsAdministrator())
  817. {
  818. return err;
  819. }
  820. if (QueryMajorVersion() < 6)
  821. {
  822. err = CreateEnumerator(pme);
  823. while (err.Succeeded())
  824. {
  825. err = pme->Next(dwInstance, strInstance);
  826. if (err.Succeeded())
  827. {
  828. if (NULL != (psite = new CIISSite(m_pOwner, this, strInstance)))
  829. {
  830. psite->AddRef();
  831. err = psite->AddToScopePane(hParent);
  832. }
  833. else
  834. {
  835. err = ERROR_NOT_ENOUGH_MEMORY;
  836. break;
  837. }
  838. }
  839. }
  840. SAFE_DELETE(pme);
  841. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  842. {
  843. err.Reset();
  844. }
  845. if (err.Failed())
  846. {
  847. DisplayError(err);
  848. }
  849. }
  850. else
  851. {
  852. do
  853. {
  854. CComBSTR bstrPath;
  855. err = BuildMetaPath(bstrPath);
  856. BREAK_ON_ERR_FAILURE(err)
  857. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
  858. BREAK_ON_ERR_FAILURE(err)
  859. if (err.Succeeded())
  860. {
  861. CMetaKey mk(QueryInterface(), bstrPath, METADATA_PERMISSION_READ);
  862. err = mk.QueryResult();
  863. if (err.Succeeded())
  864. {
  865. CStringListEx list;
  866. err = mk.GetChildPaths(list);
  867. if (err.Succeeded())
  868. {
  869. CString key_type;
  870. POSITION pos = list.GetHeadPosition();
  871. while (err.Succeeded() && pos != NULL)
  872. {
  873. strInstance = list.GetNext(pos);
  874. err = mk.QueryValue(MD_KEY_TYPE, key_type, NULL, strInstance);
  875. if (err.Succeeded()
  876. && (key_type.CompareNoCase(_T(IIS_CLASS_WEB_SERVER)) == 0
  877. || key_type.CompareNoCase(_T(IIS_CLASS_FTP_SERVER)) == 0)
  878. )
  879. {
  880. if (NULL != (psite = new CIISSite(m_pOwner, this, strInstance)))
  881. {
  882. psite->AddRef();
  883. err = psite->AddToScopePane(hParent);
  884. }
  885. else
  886. {
  887. err = ERROR_NOT_ENOUGH_MEMORY;
  888. break;
  889. }
  890. }
  891. else if (err == (HRESULT)MD_ERROR_DATA_NOT_FOUND)
  892. {
  893. err.Reset();
  894. }
  895. }
  896. }
  897. }
  898. }
  899. } while (FALSE);
  900. if (err.Failed())
  901. {
  902. DisplayError(err);
  903. }
  904. }
  905. return err;
  906. }
  907. /* virtual */
  908. HRESULT
  909. CIISService::AddMenuItems(
  910. LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  911. long * pInsertionAllowed,
  912. DATA_OBJECT_TYPES type
  913. )
  914. {
  915. ASSERT_READ_PTR(lpContextMenuCallback);
  916. //
  917. // Add base menu items
  918. //
  919. HRESULT hr = CIISObject::AddMenuItems(
  920. lpContextMenuCallback,
  921. pInsertionAllowed,
  922. type
  923. );
  924. if (SUCCEEDED(hr) && m_fCanAddInstance)
  925. {
  926. ASSERT(pInsertionAllowed != NULL);
  927. if (IsAdministrator())
  928. {
  929. #if 0
  930. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) != 0)
  931. {
  932. DWORD state = 0;
  933. hr = GetServiceState(state);
  934. if (SUCCEEDED(hr))
  935. {
  936. AddMenuSeparator(lpContextMenuCallback);
  937. AddMenuItemByCommand(lpContextMenuCallback,
  938. IDM_SERVICE_START,
  939. state == SERVICE_STOPPED ? 0 : MF_GRAYED);
  940. AddMenuItemByCommand(lpContextMenuCallback,
  941. IDM_SERVICE_STOP,
  942. state == SERVICE_RUNNING ? 0 : MF_GRAYED);
  943. AddMenuItemByCommand(lpContextMenuCallback,
  944. IDM_SERVICE_ENABLE,
  945. state == IIS_SERVICE_DISABLED ? 0 : MF_GRAYED);
  946. }
  947. }
  948. #endif
  949. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
  950. {
  951. AddMenuSeparator(lpContextMenuCallback);
  952. if (_tcsicmp(GetNodeName(), SZ_MBN_FTP) == 0)
  953. {
  954. AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_FTP_SITE);
  955. if (IsConfigImportExportable())
  956. {
  957. AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_FTP_SITE_FROM_FILE);
  958. }
  959. }
  960. else if (_tcsicmp(GetNodeName(), SZ_MBN_WEB) == 0)
  961. {
  962. AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_WEB_SITE);
  963. if (IsConfigImportExportable())
  964. {
  965. AddMenuItemByCommand(lpContextMenuCallback, IDM_NEW_WEB_SITE_FROM_FILE);
  966. }
  967. }
  968. }
  969. // Don't enable export at this level
  970. // since we won't be able to import from the file that is created...
  971. if (IsConfigImportExportable() && (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0)
  972. {
  973. AddMenuSeparator(lpContextMenuCallback);
  974. AddMenuItemByCommand(lpContextMenuCallback, IDM_TASK_EXPORT_CONFIG_WIZARD);
  975. }
  976. }
  977. //
  978. // CODEWORK: Add new instance commands for each of the services
  979. // keeping in mind which ones are installed and all.
  980. // add that info to the table, remembering that this
  981. // is per service.
  982. //
  983. }
  984. return hr;
  985. }
  986. HRESULT
  987. CIISService::InsertNewInstance(DWORD inst)
  988. {
  989. CError err;
  990. TCHAR buf[16];
  991. CIISSite * pSite = NULL;
  992. // WAS needs some time to update status of new site as started
  993. Sleep(1000);
  994. // If service is not expanded we will get error and no effect
  995. if (!IsExpanded())
  996. {
  997. // In this case selecting the parent will enumerate all the nodes including new one,
  998. // which is already in metabase
  999. SelectScopeItem();
  1000. IConsoleNameSpace2 * pConsoleNameSpace
  1001. = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1002. pConsoleNameSpace->Expand(QueryScopeItem());
  1003. HSCOPEITEM hChildItem = NULL;
  1004. LONG_PTR cookie;
  1005. HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie);
  1006. while(SUCCEEDED(hr) && hChildItem)
  1007. {
  1008. pSite = (CIISSite *)cookie;
  1009. ASSERT_PTR(pSite);
  1010. if (pSite->GetInstance() == inst)
  1011. {
  1012. pSite->SelectScopeItem();
  1013. break;
  1014. }
  1015. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1016. }
  1017. }
  1018. else
  1019. {
  1020. // Now we should insert and select this new site
  1021. pSite = new CIISSite(m_pOwner, this, _itot(inst, buf, 10));
  1022. if (pSite != NULL)
  1023. {
  1024. pSite->AddRef();
  1025. err = pSite->AddToScopePaneSorted(QueryScopeItem(), FALSE);
  1026. //err = pSite->AddToScopePane(QueryScopeItem(), TRUE, FALSE, TRUE);
  1027. if (err.Succeeded())
  1028. {
  1029. VERIFY(SUCCEEDED(pSite->SelectScopeItem()));
  1030. }
  1031. else
  1032. {
  1033. pSite->Release();
  1034. }
  1035. }
  1036. else
  1037. {
  1038. err = ERROR_NOT_ENOUGH_MEMORY;
  1039. }
  1040. }
  1041. if (err.Succeeded() && pSite)
  1042. {
  1043. if (!pSite->IsFtpSite())
  1044. {
  1045. // Also, if we add a w3svc site, it's probably using
  1046. // a application, so we have to refresh that stuff too
  1047. // this CAppPoolsContainer will only be here if it's iis6
  1048. CIISMachine * pOwner = GetOwner();
  1049. if (pOwner)
  1050. {
  1051. CAppPoolsContainer * pPools = pOwner->QueryAppPoolsContainer();
  1052. if (pPools)
  1053. {
  1054. pPools->RefreshData();
  1055. if (pPools->IsExpanded())
  1056. {
  1057. pPools->RefreshDataChildren(_T(""),FALSE); // refresh all app pools, who knows
  1058. }
  1059. }
  1060. }
  1061. }
  1062. }
  1063. return err;
  1064. }
  1065. HRESULT
  1066. CIISService::Command(
  1067. long lCommandID,
  1068. CSnapInObjectRootBase * pObj,
  1069. DATA_OBJECT_TYPES type
  1070. )
  1071. {
  1072. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1073. HRESULT hr = S_OK;
  1074. DWORD inst = 0;
  1075. DWORD dwCommand = 0;
  1076. DWORD state = -1;
  1077. CError err;
  1078. CComBSTR bstrMetaPath;
  1079. switch (lCommandID)
  1080. {
  1081. #if 0
  1082. case IDM_SERVICE_STOP:
  1083. dwCommand = SERVICE_COMMAND_STOP;
  1084. break;
  1085. case IDM_SERVICE_START:
  1086. dwCommand = SERVICE_COMMAND_START;
  1087. break;
  1088. case IDM_SERVICE_ENABLE:
  1089. dwCommand = SERVICE_COMMAND_ENABLE;
  1090. break;
  1091. #endif
  1092. case IDM_NEW_FTP_SITE:
  1093. BuildMetaPath(bstrMetaPath);
  1094. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  1095. if (!IsLostInterface(err))
  1096. {
  1097. // reset error if an other error other than No interface
  1098. err.Reset();
  1099. }
  1100. if (err.Succeeded())
  1101. {
  1102. hr = AddFTPSite(pObj, type, &inst);
  1103. if (inst != 0)
  1104. {
  1105. hr = InsertNewInstance(inst);
  1106. }
  1107. }
  1108. break;
  1109. case IDM_NEW_WEB_SITE:
  1110. BuildMetaPath(bstrMetaPath);
  1111. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  1112. if (!IsLostInterface(err))
  1113. {
  1114. // reset error if an other error other than No interface
  1115. err.Reset();
  1116. }
  1117. if (err.Succeeded())
  1118. {
  1119. hr = AddWebSite(pObj, type, &inst,
  1120. m_pOwner->QueryMajorVersion(), m_pOwner->QueryMinorVersion());
  1121. if (inst != 0)
  1122. {
  1123. hr = InsertNewInstance(inst);
  1124. }
  1125. }
  1126. break;
  1127. default:
  1128. hr = CIISMBNode::Command(lCommandID, pObj, type);
  1129. break;
  1130. }
  1131. if (dwCommand != 0)
  1132. {
  1133. hr = ChangeServiceState(dwCommand);
  1134. }
  1135. return hr;
  1136. }
  1137. HRESULT
  1138. CIISService::ChangeServiceState(DWORD command)
  1139. {
  1140. CError err = GetServiceState();
  1141. return err;
  1142. }
  1143. /* virtual */
  1144. HRESULT
  1145. CIISService::BuildURL(
  1146. CComBSTR & bstrURL
  1147. ) const
  1148. /*++
  1149. Routine Description:
  1150. Recursively build up the URL from the current node
  1151. and its parents.
  1152. Arguments:
  1153. CComBSTR & bstrURL : Returns URL
  1154. --*/
  1155. {
  1156. ASSERT(m_iServiceDef < ARRAY_SIZE(_rgServices));
  1157. bstrURL = _rgServices[m_iServiceDef].szProtocol;
  1158. return S_OK;
  1159. }
  1160. HRESULT
  1161. CIISService::ShowSitePropertiesDlg(
  1162. LPPROPERTYSHEETCALLBACK lpProvider,
  1163. CComAuthInfo * pAuthInfo,
  1164. LPCTSTR lpszMDPath,
  1165. CWnd * pMainWnd,
  1166. LPARAM lParam,
  1167. LPARAM lParamParent,
  1168. LONG_PTR handle
  1169. )
  1170. /*++
  1171. Routine Description:
  1172. Display site properties dialog
  1173. Arguments:
  1174. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  1175. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  1176. LPCTSTR lpszMDPath Metabase path
  1177. CWnd * pMainWnd Parent window
  1178. LPARAM lParam LPARAM to pass to MMC
  1179. LONG handle handle to pass to MMC
  1180. Return Value:
  1181. HRESULT
  1182. --*/
  1183. {
  1184. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1185. ASSERT(m_iServiceDef >= 0 && m_iServiceDef < ARRAY_SIZE(_rgServices));
  1186. return (*_rgServices[m_iServiceDef].pfnSitePropertiesDlg)(
  1187. lpProvider,
  1188. pAuthInfo,
  1189. lpszMDPath,
  1190. pMainWnd,
  1191. lParam,
  1192. lParamParent,
  1193. handle
  1194. );
  1195. }
  1196. HRESULT
  1197. CIISService::ShowDirPropertiesDlg(
  1198. LPPROPERTYSHEETCALLBACK lpProvider,
  1199. CComAuthInfo * pAuthInfo,
  1200. LPCTSTR lpszMDPath,
  1201. CWnd * pMainWnd,
  1202. LPARAM lParam,
  1203. LPARAM lParamParent,
  1204. LONG_PTR handle
  1205. )
  1206. /*++
  1207. Routine Description:
  1208. Display directory properties dialog
  1209. Arguments:
  1210. LPPROPERTYSHEETCALLBACK lpProvider Property sheet provider
  1211. CComAuthInfo * pAuthInfo COM Authentication info or NULL.
  1212. LPCTSTR lpszMDPath Metabase path
  1213. CWnd * pMainWnd Parent window
  1214. LPARAM lParam LPARAM to pass to MMC
  1215. LONG handle handle to pass to MMC
  1216. Return Value:
  1217. HRESULT
  1218. --*/
  1219. {
  1220. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1221. ASSERT(m_iServiceDef >= 0 && m_iServiceDef < ARRAY_SIZE(_rgServices));
  1222. return (*_rgServices[m_iServiceDef].pfnDirPropertiesDlg)(
  1223. lpProvider,
  1224. pAuthInfo,
  1225. lpszMDPath,
  1226. pMainWnd,
  1227. lParam,
  1228. lParamParent,
  1229. handle
  1230. );
  1231. }
  1232. /* virtual */
  1233. HRESULT
  1234. CIISService::CreatePropertyPages(
  1235. LPPROPERTYSHEETCALLBACK lpProvider,
  1236. LONG_PTR handle,
  1237. IUnknown * pUnk,
  1238. DATA_OBJECT_TYPES type
  1239. )
  1240. /*++
  1241. Routine Description:
  1242. Create the property pages for the given object
  1243. Arguments:
  1244. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  1245. LONG_PTR handle : Handle.
  1246. IUnknown * pUnk,
  1247. DATA_OBJECT_TYPES type
  1248. Return Value:
  1249. HRESULT
  1250. --*/
  1251. {
  1252. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1253. CError err;
  1254. if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type)))
  1255. {
  1256. return S_OK;
  1257. }
  1258. if (ERROR_ALREADY_EXISTS == err.Win32Error())
  1259. {
  1260. return S_FALSE;
  1261. }
  1262. if (ERROR_NO_NETWORK == err.Win32Error())
  1263. {
  1264. return S_FALSE;
  1265. }
  1266. CComBSTR bstrPath;
  1267. err = BuildMetaPath(bstrPath);
  1268. if (err.Succeeded())
  1269. {
  1270. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,(LPCTSTR) bstrPath);
  1271. if (err.Succeeded())
  1272. {
  1273. // cache handle for user in MMCPropertyChangeNotify
  1274. m_ppHandle = handle;
  1275. //
  1276. // Show master properties
  1277. //
  1278. err = ShowSitePropertiesDlg(
  1279. lpProvider, QueryAuthInfo(), bstrPath,
  1280. GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM) GetOwner(), handle
  1281. );
  1282. }
  1283. }
  1284. err.MessageBoxOnFailure();
  1285. return err;
  1286. }