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.

2515 lines
68 KiB

  1. /*++
  2. Copyright (c) 1994-2001 Microsoft Corporation
  3. Module Name :
  4. iismbnode.cpp
  5. Abstract:
  6. CIISMBNode 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 "iisobj.h"
  21. #include "ftpsht.h"
  22. #include "w3sht.h"
  23. #include "fltdlg.h"
  24. #include "aclpage.h"
  25. #include "impexp.h"
  26. #include "util.h"
  27. #include "tracker.h"
  28. #include <lm.h>
  29. #ifdef _DEBUG
  30. #undef THIS_FILE
  31. static char BASED_CODE THIS_FILE[] = __FILE__;
  32. #endif
  33. #define new DEBUG_NEW
  34. extern INT g_iDebugOutputLevel;
  35. extern CPropertySheetTracker g_OpenPropertySheetTracker;
  36. //
  37. // CIISMBNode implementation
  38. //
  39. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  40. /* static */ LPOLESTR CIISMBNode::_cszSeparator = _T("/");
  41. /* static */ CComBSTR CIISMBNode::_bstrRedirectPathBuf;
  42. CIISMBNode::CIISMBNode(
  43. IN CIISMachine * pOwner,
  44. IN LPCTSTR szNode
  45. )
  46. /*++
  47. Routine Description:
  48. Constructor
  49. Arguments:
  50. CIISMachine * pOwner : Owner machine object
  51. LPCTSTR szNode : Node name
  52. Return Value:
  53. N/A
  54. --*/
  55. : m_bstrNode(szNode),
  56. m_bstrURL(NULL),
  57. m_pOwner(pOwner)
  58. {
  59. ASSERT_READ_PTR(szNode);
  60. ASSERT_READ_PTR(pOwner);
  61. if (this != m_pOwner)
  62. {
  63. m_pOwner->AddRef();
  64. }
  65. m_pMachineObject = m_pOwner;
  66. if (g_iDebugOutputLevel & DEBUG_FLAG_CIISMBNODE)
  67. {
  68. TRACEEOL("AddRef to m_pOwner: node " << szNode << " count " << m_pOwner->UseCount())
  69. }
  70. }
  71. CIISMBNode::~CIISMBNode()
  72. {
  73. if (this != m_pOwner)
  74. {
  75. m_pOwner->Release();
  76. }
  77. if (g_iDebugOutputLevel & DEBUG_FLAG_CIISMBNODE)
  78. {
  79. TRACEEOL("Released m_pOwner: node " << m_bstrNode << " count " << m_pOwner->UseCount())
  80. }
  81. }
  82. CIISMBNode::CreateTag()
  83. {
  84. CIISMachine * pMachine = GetOwner();
  85. if (pMachine)
  86. {
  87. CComBSTR bstrPath;
  88. BuildMetaPath(bstrPath);
  89. m_strTag = pMachine->QueryDisplayName();
  90. m_strTag += bstrPath;
  91. }
  92. }
  93. void
  94. CIISMBNode::SetErrorOverrides(
  95. IN OUT CError & err,
  96. IN BOOL fShort
  97. ) const
  98. /*++
  99. Routine Description:
  100. Set error message overrides
  101. Arguments:
  102. CError err : Error message object
  103. BOOL fShort : TRUE to use only single-line errors
  104. Return Value:
  105. None
  106. --*/
  107. {
  108. //
  109. // Substitute friendly message for some ID codes.
  110. //
  111. // CODEWORK: Add global overrides as well.
  112. //
  113. err.AddOverride(EPT_S_NOT_REGISTERED,
  114. fShort ? IDS_ERR_RPC_NA_SHORT : IDS_ERR_RPC_NA);
  115. err.AddOverride(RPC_S_SERVER_UNAVAILABLE,
  116. fShort ? IDS_ERR_RPC_NA_SHORT : IDS_ERR_RPC_NA);
  117. err.AddOverride(RPC_S_UNKNOWN_IF, IDS_ERR_INTERFACE);
  118. err.AddOverride(RPC_S_PROCNUM_OUT_OF_RANGE, IDS_ERR_INTERFACE);
  119. err.AddOverride(REGDB_E_CLASSNOTREG, IDS_ERR_NO_INTERFACE);
  120. err.AddOverride(ERROR_DUP_NAME, fShort ? IDS_ERR_BINDING_SHORT : IDS_ERR_BINDING_LONG);
  121. if (!fShort)
  122. {
  123. err.AddOverride(ERROR_ACCESS_DENIED, IDS_ERR_ACCESS_DENIED);
  124. }
  125. }
  126. BOOL
  127. CIISMBNode::IsAdministrator() const
  128. {
  129. CIISMBNode * that = (CIISMBNode *)this;
  130. return that->GetOwner()->HasAdministratorAccess();
  131. }
  132. void
  133. CIISMBNode::DisplayError(CError& err, HWND hWnd) const
  134. /*++
  135. Routine Description:
  136. Display error message box. Substituting some friendly messages for
  137. some specific error codes
  138. Arguments:
  139. CError & err : Error object contains code to be displayed
  140. --*/
  141. {
  142. if (err == E_POINTER)
  143. {
  144. err.Reset();
  145. }
  146. if (err.Failed())
  147. {
  148. SetErrorOverrides(err);
  149. err.MessageBox(hWnd);
  150. }
  151. }
  152. CIISMBNode *
  153. CIISMBNode::GetParentNode() const
  154. /*++
  155. Routine Description:
  156. Helper function to return the parent node in the scope tree
  157. Arguments:
  158. None
  159. Return Value:
  160. Parent CIISMBNode or NULL.
  161. --*/
  162. {
  163. LONG_PTR cookie = NULL;
  164. HSCOPEITEM hParent;
  165. CIISMBNode * pNode = NULL;
  166. HRESULT hr = S_OK;
  167. SCOPEDATAITEM si;
  168. ::ZeroMemory(&si, sizeof(SCOPEDATAITEM));
  169. CIISObject * ThisConst = (CIISObject *)this;
  170. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)ThisConst->GetConsoleNameSpace();
  171. if (m_hResultItem != 0)
  172. {
  173. si.mask = SDI_PARAM;
  174. si.ID = m_hScopeItem;
  175. hr = pConsoleNameSpace->GetItem(&si);
  176. if (SUCCEEDED(hr))
  177. {
  178. cookie = si.lParam;
  179. }
  180. }
  181. else
  182. {
  183. // Get our Item
  184. si.mask = SDI_PARAM;
  185. si.ID = m_hScopeItem;
  186. // if we can get our item, then try to get our parents
  187. // we need to do this because MMC will AV if we don't exist first...
  188. if (SUCCEEDED(pConsoleNameSpace->GetItem(&si)))
  189. {
  190. hr = pConsoleNameSpace->GetParentItem(
  191. m_hScopeItem,
  192. &hParent,
  193. &cookie
  194. );
  195. }
  196. }
  197. if (SUCCEEDED(hr))
  198. {
  199. pNode = (CIISMBNode *)cookie;
  200. ASSERT_PTR(pNode);
  201. }
  202. return pNode;
  203. }
  204. /* virtual */
  205. HRESULT
  206. CIISMBNode::BuildMetaPath(
  207. OUT CComBSTR & bstrPath
  208. ) const
  209. /*++
  210. Routine Description:
  211. Recursively build up the metabase path from the current node
  212. and its parents
  213. Arguments:
  214. CComBSTR & bstrPath : Returns metabase path
  215. Return Value:
  216. HRESULT
  217. --*/
  218. {
  219. HRESULT hr = S_OK;
  220. CIISMBNode * pNode = GetParentNode();
  221. if (pNode)
  222. {
  223. hr = pNode->BuildMetaPath(bstrPath);
  224. if (SUCCEEDED(hr))
  225. {
  226. bstrPath.Append(_cszSeparator);
  227. bstrPath.Append(QueryNodeName());
  228. }
  229. return hr;
  230. }
  231. //
  232. // No parent node
  233. //
  234. // ASSERT_MSG("No parent node");
  235. return E_UNEXPECTED;
  236. }
  237. HRESULT
  238. CIISMBNode::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream)
  239. {
  240. HRESULT hr = DV_E_CLIPFORMAT;
  241. ULONG uWritten;
  242. if (cf == m_CCF_MachineName)
  243. {
  244. hr = pStream->Write(
  245. QueryMachineName(),
  246. (ocslen((OLECHAR*)QueryMachineName()) + 1) * sizeof(OLECHAR),
  247. &uWritten
  248. );
  249. ASSERT(SUCCEEDED(hr));
  250. return hr;
  251. }
  252. //
  253. // Generate complete metabase path for this node
  254. //
  255. CString strField;
  256. CString strMetaPath;
  257. CComBSTR bstr;
  258. if (FAILED(hr = BuildMetaPath(bstr)))
  259. {
  260. ASSERT(FALSE);
  261. return hr;
  262. }
  263. strMetaPath = bstr;
  264. if (cf == m_CCF_MetaPath)
  265. {
  266. //
  267. // Whole metabase path requested
  268. //
  269. //BUG:670171
  270. // Path from BuildMetaPath() is returning something like
  271. // /LM/W3SVC/1/ROOT
  272. //
  273. // however, it should be returned as LM/W3SVC/1/ROOT to be
  274. // backwards compatible with how iis5 used to work...
  275. if (_T("/") == strMetaPath.Left(1))
  276. {
  277. strField = strMetaPath.Right(strMetaPath.GetLength() - 1);
  278. }
  279. else
  280. {
  281. strField = strMetaPath;
  282. }
  283. }
  284. else
  285. {
  286. //
  287. // A portion of the metabase is requested. Return the requested
  288. // portion
  289. //
  290. LPCTSTR lpMetaPath = (LPCTSTR)strMetaPath;
  291. LPCTSTR lpEndPath = lpMetaPath + strMetaPath.GetLength() + 1;
  292. LPCTSTR lpLM = NULL;
  293. LPCTSTR lpSvc = NULL;
  294. LPCTSTR lpInstance = NULL;
  295. LPCTSTR lpParent = NULL;
  296. LPCTSTR lpNode = NULL;
  297. //
  298. // Break up the metabase path in portions
  299. //
  300. if (lpLM = _tcschr(lpMetaPath, _T('/')))
  301. {
  302. ++lpLM;
  303. if (lpSvc = _tcschr(lpLM, _T('/')))
  304. {
  305. ++lpSvc;
  306. if (lpInstance = _tcschr(lpSvc, _T('/')))
  307. {
  308. ++lpInstance;
  309. if (lpParent = _tcschr(lpInstance, _T('/')))
  310. {
  311. ++lpParent;
  312. lpNode = _tcsrchr(lpParent, _T('/'));
  313. if (lpNode)
  314. {
  315. ++lpNode;
  316. }
  317. }
  318. }
  319. }
  320. }
  321. int n1, n2;
  322. if (cf == m_CCF_Service)
  323. {
  324. //
  325. // Requested the service string
  326. //
  327. if (lpSvc)
  328. {
  329. n1 = DIFF(lpSvc - lpMetaPath);
  330. n2 = lpInstance ? DIFF(lpInstance - lpSvc) : DIFF(lpEndPath - lpSvc);
  331. strField = strMetaPath.Mid(n1, n2 - 1);
  332. }
  333. }
  334. else if (cf == m_CCF_Instance)
  335. {
  336. //
  337. // Requested the instance number
  338. //
  339. if (lpInstance)
  340. {
  341. n1 = DIFF(lpInstance - lpMetaPath);
  342. n2 = lpParent ? DIFF(lpParent - lpInstance) : DIFF(lpEndPath - lpInstance);
  343. strField = strMetaPath.Mid(n1, n2 - 1);
  344. }
  345. }
  346. else if (cf == m_CCF_ParentPath)
  347. {
  348. //
  349. // Requestd the parent path
  350. //
  351. if (lpParent)
  352. {
  353. n1 = DIFF(lpParent - lpMetaPath);
  354. n2 = lpNode ? DIFF(lpNode - lpParent) : DIFF(lpEndPath - lpParent);
  355. strField = strMetaPath.Mid(n1, n2 - 1);
  356. }
  357. }
  358. else if (cf == m_CCF_Node)
  359. {
  360. //
  361. // Requested the node name
  362. //
  363. if (lpNode)
  364. {
  365. n1 = DIFF(lpNode - lpMetaPath);
  366. n2 = DIFF(lpEndPath - lpNode);
  367. strField = strMetaPath.Mid(n1, n2 - 1);
  368. }
  369. }
  370. else
  371. {
  372. ASSERT(FALSE);
  373. DV_E_CLIPFORMAT;
  374. }
  375. }
  376. TRACEEOLID("Requested metabase path data: " << strField);
  377. int len = strField.GetLength() + 1;
  378. hr = pStream->Write(strField,
  379. (ocslen(strField) + 1) * sizeof(OLECHAR), &uWritten);
  380. ASSERT(SUCCEEDED(hr));
  381. return hr;
  382. }
  383. HRESULT
  384. CIISMBNode::BuildURL(
  385. OUT CComBSTR & bstrURL
  386. ) const
  387. /*++
  388. Routine Description:
  389. Recursively build up the URL from the current node
  390. and its parents.
  391. Arguments:
  392. CComBSTR & bstrURL : Returns URL
  393. Return Value:
  394. HRESULT
  395. --*/
  396. {
  397. HRESULT hr = S_OK;
  398. //
  399. // Prepend parent portion
  400. //
  401. CIISMBNode * pNode = GetParentNode();
  402. if (pNode)
  403. {
  404. hr = pNode->BuildURL(bstrURL);
  405. //
  406. // And our portion
  407. //
  408. if (SUCCEEDED(hr))
  409. {
  410. bstrURL.Append(_cszSeparator);
  411. bstrURL.Append(QueryNodeName());
  412. }
  413. return hr;
  414. }
  415. //
  416. // No parent node
  417. //
  418. ASSERT_MSG("No parent node");
  419. return E_UNEXPECTED;
  420. }
  421. BOOL
  422. CIISMBNode::OnLostInterface(
  423. IN OUT CError & err
  424. )
  425. /*++
  426. Routine Description:
  427. Deal with lost interface. Ask the user to reconnect.
  428. Arguments:
  429. CError & err : Error object
  430. Return Value:
  431. TRUE if the interface was successfully recreated.
  432. FALSE otherwise. If it tried and failed the error will
  433. --*/
  434. {
  435. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  436. CString str;
  437. str.Format(IDS_RECONNECT_WARNING, QueryMachineName());
  438. if (YesNoMessageBox(str))
  439. {
  440. //
  441. // Attempt to recreate the interface
  442. //
  443. err = CreateInterface(TRUE);
  444. return err.Succeeded();
  445. }
  446. return FALSE;
  447. }
  448. HRESULT
  449. CIISMBNode::DeleteNode(IResultData * pResult)
  450. {
  451. CError err;
  452. // check if they have the property sheet open on it.
  453. if (IsMyPropertySheetOpen())
  454. {
  455. ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
  456. return S_OK;
  457. }
  458. // this could be an orphaned property sheet
  459. // check if an orphaned property sheet is open on this item.
  460. CIISObject * pAlreadyOpenProp = NULL;
  461. if (TRUE == g_OpenPropertySheetTracker.FindAlreadyOpenPropertySheet(this,&pAlreadyOpenProp))
  462. {
  463. // Bring it to the foreground, and bail
  464. HWND hHwnd = 0;
  465. if (pAlreadyOpenProp)
  466. {
  467. if (hHwnd = pAlreadyOpenProp->IsMyPropertySheetOpen())
  468. {
  469. if (hHwnd && (hHwnd != (HWND) 1))
  470. {
  471. // Perhapse we should cancel the already
  472. // opened property sheet...just a thought
  473. if (!SetForegroundWindow(hHwnd))
  474. {
  475. // wasn't able to bring this property sheet to
  476. // the foreground, the propertysheet must not
  477. // exist anymore. let's just clean the hwnd
  478. // so that the user will be able to open propertysheet
  479. pAlreadyOpenProp->SetMyPropertySheetOpen(0);
  480. }
  481. else
  482. {
  483. ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
  484. return S_OK;
  485. }
  486. }
  487. }
  488. }
  489. }
  490. CComBSTR path;
  491. err = BuildMetaPath(path);
  492. if (err.Succeeded())
  493. {
  494. err = CheckForMetabaseAccess(METADATA_PERMISSION_WRITE,this,TRUE,path);
  495. if (!IsLostInterface(err))
  496. {
  497. // reset error if an other error other than No interface
  498. err.Reset();
  499. }
  500. }
  501. if (err.Succeeded())
  502. {
  503. if (!NoYesMessageBox(IDS_CONFIRM_DELETE))
  504. return err;
  505. do
  506. {
  507. CMetaInterface * pInterface = QueryInterface();
  508. ASSERT(pInterface != NULL);
  509. CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
  510. if (!mk.Succeeded())
  511. break;
  512. err = mk.DeleteKey(path);
  513. if (err.Failed())
  514. break;
  515. // don't hold the Metabasekey open
  516. // (RemoveScopeItem may do a lot of things,and lock the metabase for other read requests)
  517. mk.Close();
  518. m_fFlaggedForDeletion = TRUE;
  519. err = RemoveScopeItem();
  520. } while (FALSE);
  521. }
  522. if (err.Failed())
  523. {
  524. DisplayError(err);
  525. }
  526. return err;
  527. }
  528. HRESULT
  529. CIISMBNode::EnumerateVDirs(
  530. HSCOPEITEM hParent, CIISService * pService, BOOL bDisplayError)
  531. /*++
  532. Routine Description:
  533. Enumerate scope child items.
  534. Arguments:
  535. HSCOPEITEM hParent : Parent console handle
  536. CIISService * pService : Service type
  537. --*/
  538. {
  539. ASSERT_PTR(pService);
  540. CError err;
  541. CString strVRoot;
  542. CIISDirectory * pDir;
  543. if (pService->QueryMajorVersion() < 6)
  544. {
  545. CMetaEnumerator * pme = NULL;
  546. err = CreateEnumerator(pme);
  547. while (err.Succeeded())
  548. {
  549. err = pme->Next(strVRoot);
  550. if (err.Succeeded())
  551. {
  552. CChildNodeProps child(pme, strVRoot, WITH_INHERITANCE, FALSE);
  553. err = child.LoadData();
  554. DWORD dwWin32Error = err.Win32Error();
  555. if (err.Failed())
  556. {
  557. //
  558. // Filter out the non-fatal errors
  559. //
  560. switch(err.Win32Error())
  561. {
  562. case ERROR_ACCESS_DENIED:
  563. case ERROR_FILE_NOT_FOUND:
  564. case ERROR_PATH_NOT_FOUND:
  565. err.Reset();
  566. break;
  567. default:
  568. TRACEEOLID("Fatal error occurred " << err);
  569. }
  570. }
  571. if (err.Succeeded())
  572. {
  573. //
  574. // Skip non-virtual directories (that is, those with
  575. // inherited vrpaths)
  576. //
  577. if (!child.IsPathInherited())
  578. {
  579. //
  580. // Construct with full information.
  581. //
  582. pDir = new CIISDirectory(
  583. m_pOwner,
  584. pService,
  585. strVRoot,
  586. child.IsEnabledApplication(),
  587. child.QueryWin32Error(),
  588. child.GetRedirectedPath()
  589. );
  590. if (!pDir)
  591. {
  592. err = ERROR_NOT_ENOUGH_MEMORY;
  593. break;
  594. }
  595. pDir->AddRef();
  596. err = pDir->AddToScopePane(hParent);
  597. }
  598. }
  599. }
  600. }
  601. SAFE_DELETE(pme);
  602. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  603. {
  604. err.Reset();
  605. }
  606. }
  607. else
  608. {
  609. do
  610. {
  611. CComBSTR bstrPath;
  612. err = BuildMetaPath(bstrPath);
  613. BREAK_ON_ERR_FAILURE(err);
  614. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
  615. if (!IsLostInterface(err))
  616. {
  617. // reset error if an other error other than No interface
  618. err.Reset();
  619. }
  620. BREAK_ON_ERR_FAILURE(err);
  621. CMetaKey mk(QueryInterface(), bstrPath, METADATA_PERMISSION_READ);
  622. err = mk.QueryResult();
  623. BREAK_ON_ERR_FAILURE(err);
  624. CStringListEx list;
  625. err = mk.GetChildPaths(list);
  626. BREAK_ON_ERR_FAILURE(err);
  627. CString key_type;
  628. BOOL bPossbileVDir = FALSE;
  629. POSITION pos = list.GetHeadPosition();
  630. while (err.Succeeded() && pos != NULL)
  631. {
  632. strVRoot = list.GetNext(pos);
  633. err = mk.QueryValue(MD_KEY_TYPE, key_type, NULL, strVRoot);
  634. bPossbileVDir = FALSE;
  635. if (err.Succeeded())
  636. {
  637. if (key_type.CompareNoCase(_T(IIS_CLASS_WEB_VDIR)) == 0 || key_type.CompareNoCase(_T(IIS_CLASS_FTP_VDIR)) == 0)
  638. {
  639. bPossbileVDir = TRUE;
  640. }
  641. }
  642. else
  643. {
  644. if (err == (HRESULT)MD_ERROR_DATA_NOT_FOUND)
  645. {
  646. // there is no KeyType
  647. // for backward compatibility reasons -- this could be a VDir!
  648. bPossbileVDir = TRUE;
  649. }
  650. }
  651. if (bPossbileVDir)
  652. {
  653. CChildNodeProps child(&mk, strVRoot, WITH_INHERITANCE, FALSE);
  654. err = child.LoadData();
  655. DWORD dwWin32Error = err.Win32Error();
  656. if (err.Failed())
  657. {
  658. //
  659. // Filter out the non-fatal errors
  660. //
  661. switch(err.Win32Error())
  662. {
  663. case ERROR_ACCESS_DENIED:
  664. case ERROR_FILE_NOT_FOUND:
  665. case ERROR_PATH_NOT_FOUND:
  666. err.Reset();
  667. break;
  668. default:
  669. TRACEEOLID("Fatal error occurred " << err);
  670. }
  671. }
  672. if (err.Succeeded())
  673. {
  674. //
  675. // Skip non-virtual directories (that is, those with
  676. // inherited vrpaths)
  677. //
  678. if (!child.IsPathInherited())
  679. {
  680. pDir = new CIISDirectory(
  681. m_pOwner,
  682. pService,
  683. strVRoot,
  684. child.IsEnabledApplication(),
  685. child.QueryWin32Error(),
  686. child.GetRedirectedPath()
  687. );
  688. if (!pDir)
  689. {
  690. err = ERROR_NOT_ENOUGH_MEMORY;
  691. break;
  692. }
  693. pDir->AddRef();
  694. err = pDir->AddToScopePane(hParent);
  695. }
  696. }
  697. }
  698. if (err == (HRESULT)MD_ERROR_DATA_NOT_FOUND)
  699. {
  700. err.Reset();
  701. }
  702. }
  703. } while (FALSE);
  704. }
  705. if (err.Failed() && bDisplayError)
  706. {
  707. DisplayError(err);
  708. }
  709. return err;
  710. }
  711. BOOL
  712. CIISMBNode::GetPhysicalPath(
  713. LPCTSTR metaPath,
  714. CString & alias,
  715. CString & physicalPath
  716. )
  717. /*++
  718. Routine Description:
  719. Build a physical path for the current node. Starting with the current
  720. node, walk up the tree appending node names until a virtual directory
  721. with a real physical path is found
  722. Arguments:
  723. CString & physicalPath : Returns file path
  724. Return Value:
  725. Pointer to path
  726. --*/
  727. {
  728. if (CMetabasePath::IsMasterInstance(metaPath))
  729. return FALSE;
  730. BOOL fInherit = FALSE;
  731. CMetaInterface * pInterface = QueryInterface();
  732. CError err;
  733. ASSERT(pInterface != NULL);
  734. if (pInterface)
  735. {
  736. CMetaKey mk(pInterface);
  737. err = mk.QueryValue(
  738. MD_VR_PATH,
  739. physicalPath,
  740. &fInherit,
  741. metaPath
  742. );
  743. if (err.Succeeded())
  744. {
  745. physicalPath.TrimRight();
  746. physicalPath.TrimLeft();
  747. }
  748. }
  749. if (err.Failed())
  750. {
  751. CString lastNode;
  752. CMetabasePath::GetLastNodeName(metaPath, lastNode);
  753. PathAppend(lastNode.GetBuffer(MAX_PATH), alias);
  754. lastNode.ReleaseBuffer();
  755. CString buf(metaPath);
  756. if (NULL == CMetabasePath::ConvertToParentPath(buf))
  757. {
  758. return FALSE;
  759. }
  760. else
  761. {
  762. if (GetPhysicalPath(buf, lastNode, physicalPath))
  763. {
  764. return TRUE;
  765. }
  766. }
  767. }
  768. if (!alias.IsEmpty())
  769. {
  770. // Check if physicalPath is \\.\ (device type)
  771. // PathAppend will hose on this and get rid of the \\.\ part
  772. // example: before \\.\c:\temp, after \\c:\temp
  773. // obviously this is bad if there are Device path's in there
  774. if (IsDevicePath(physicalPath))
  775. {
  776. CString csTemp;
  777. csTemp = physicalPath;
  778. physicalPath = AppendToDevicePath(csTemp, alias);
  779. }
  780. else
  781. {
  782. PathAppend(physicalPath.GetBuffer(MAX_PATH), alias);
  783. physicalPath.ReleaseBuffer();
  784. }
  785. }
  786. return TRUE;
  787. }
  788. HRESULT
  789. CIISMBNode::CleanResult(IResultData * lpResultData)
  790. {
  791. CError err;
  792. POSITION pos = m_ResultViewList.GetHeadPosition();
  793. while (pos != NULL)
  794. {
  795. POSITION pos_current = pos;
  796. ResultViewEntry e = m_ResultViewList.GetNext(pos);
  797. if (e._ResultData == (DWORD_PTR)lpResultData)
  798. {
  799. if (!e._ResultItems->IsEmpty())
  800. {
  801. // We should do this MMC cleaning before we delete our data
  802. err = lpResultData->DeleteAllRsltItems();
  803. POSITION p = e._ResultItems->GetHeadPosition();
  804. while (p != NULL)
  805. {
  806. CIISFileName * pNode = e._ResultItems->GetNext(p);
  807. // err = lpResultData->DeleteItem(pNode->m_hResultItem, 0);
  808. if (err.Failed())
  809. {
  810. ASSERT(FALSE);
  811. break;
  812. }
  813. pNode->Release();
  814. }
  815. e._ResultItems->RemoveAll();
  816. }
  817. delete e._ResultItems;
  818. // pos was updated above in GetNext
  819. m_ResultViewList.RemoveAt(pos_current);
  820. }
  821. }
  822. return err;
  823. }
  824. HRESULT
  825. CIISMBNode::EnumerateResultPane_(
  826. BOOL fExpand,
  827. IHeaderCtrl * lpHeader,
  828. IResultData * lpResultData,
  829. CIISService * pService
  830. )
  831. {
  832. CError err;
  833. CIISMachine * pMachine = (CIISMachine *) GetMachineObject();
  834. WIN32_FIND_DATA w32data;
  835. HANDLE hFind = INVALID_HANDLE_VALUE;
  836. CString dir;
  837. CComBSTR root;
  838. CString physPath, alias, csPathMunged;
  839. if (m_fFlaggedForDeletion)
  840. {
  841. return S_OK;
  842. }
  843. if (!HasFileSystemFiles())
  844. {
  845. goto EnumerateResultPane__Exit;
  846. }
  847. if (!fExpand)
  848. {
  849. err = CleanResult(lpResultData);
  850. goto EnumerateResultPane__Exit;
  851. }
  852. BuildMetaPath(root);
  853. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,root);
  854. if (!IsLostInterface(err))
  855. {
  856. // reset error if an other error other than No interface
  857. err.Reset();
  858. }
  859. if (err.Failed())
  860. {
  861. goto EnumerateResultPane__Exit;
  862. }
  863. GetPhysicalPath(CString(root), alias, physPath);
  864. // -------------------------------------------------------------
  865. // Before we do anything we need to see if it's a "special" path
  866. //
  867. // Everything after this function must validate against csPathMunged...
  868. // this is because IsSpecialPath could have munged it...
  869. // -------------------------------------------------------------
  870. csPathMunged = physPath;
  871. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  872. GetSpecialPathRealPath(0,physPath,csPathMunged);
  873. #endif
  874. // Prepare for target machine metabase lookup
  875. BOOL fCheckMetabase = FALSE;
  876. if (PathIsUNC(csPathMunged))
  877. {
  878. fCheckMetabase = TRUE;
  879. CMetaKey mk(QueryInterface(), root, METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE);
  880. CError errMB(mk.QueryResult());
  881. if (errMB.Win32Error() == ERROR_PATH_NOT_FOUND)
  882. {
  883. //
  884. // Metabase path not found, not a problem.
  885. //
  886. fCheckMetabase = FALSE;
  887. errMB.Reset();
  888. }
  889. }
  890. if (IsDevicePath(csPathMunged))
  891. {
  892. // check if the device path
  893. // points to an actual dir/file
  894. // if it does then enumerate it.
  895. if (IsSpecialPath(csPathMunged,TRUE,TRUE))
  896. {
  897. // Remunge this one more time!
  898. CString csBefore;
  899. csBefore = csPathMunged;
  900. GetSpecialPathRealPath(1,csBefore,csPathMunged);
  901. }
  902. else
  903. {
  904. return err;
  905. }
  906. }
  907. // WARNING:physPath could be empty!
  908. csPathMunged.TrimLeft();
  909. csPathMunged.TrimRight();
  910. if (csPathMunged.IsEmpty()){goto EnumerateResultPane__Exit;}
  911. if (pService->IsLocal() || PathIsUNC(csPathMunged))
  912. {
  913. dir = csPathMunged;
  914. }
  915. else
  916. {
  917. ::MakeUNCPath(dir, pService->QueryMachineName(), csPathMunged);
  918. }
  919. dir.TrimLeft();
  920. dir.TrimRight();
  921. if (dir.IsEmpty()){goto EnumerateResultPane__Exit;}
  922. if (PathIsUNC(dir))
  923. {
  924. CString server, user, password;
  925. CString MyTestDir;
  926. MyTestDir = dir;
  927. MyTestDir += _T("\\*");
  928. // we are trying to get the servername portion
  929. // PathFindNextComponent should return something like "servername\mydir\myfile.txt"
  930. // trim off everything after the 1st slash
  931. server = PathFindNextComponent(dir);
  932. int n = server.Find(_T('\\'));
  933. if (n != -1)
  934. {
  935. server = server.Left(n);
  936. }
  937. user = QueryInterface()->QueryAuthInfo()->QueryUserName();
  938. password = QueryInterface()->QueryAuthInfo()->QueryPassword();
  939. // we need to compare the servername that we want to get to
  940. // with the servername of the local computer.
  941. // this way we know if we need to net use to the machine!
  942. TCHAR szLocalMachineName[MAX_PATH + 1];
  943. DWORD dwSize = MAX_PATH;
  944. if (0 == ::GetComputerName(szLocalMachineName, &dwSize))
  945. {
  946. err.GetLastWinError();
  947. goto EnumerateResultPane__Exit;
  948. }
  949. //
  950. // As it turned out in some cases we cannot get access to file system
  951. // even if we are connected to metabase. We will add connection in this
  952. // case also.
  953. //
  954. if (!pService->IsLocal()
  955. || server.CompareNoCase(szLocalMachineName) != 0
  956. )
  957. {
  958. BOOL bEmptyPassword = FALSE;
  959. // non-local resource, get connection credentials
  960. if (fCheckMetabase)
  961. {
  962. CMetaKey mk(QueryInterface(), root,
  963. METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE);
  964. err = mk.QueryResult();
  965. if (err.Succeeded())
  966. {
  967. err = mk.QueryValue(MD_VR_USERNAME, user);
  968. if (err.Succeeded())
  969. {
  970. err = mk.QueryValue(MD_VR_PASSWORD, password);
  971. bEmptyPassword = (err.Failed() ? TRUE : err.Succeeded() && password.IsEmpty());
  972. }
  973. // these credentials could be empty. try defaults
  974. err.Reset();
  975. }
  976. }
  977. // Add net use for this resource
  978. NETRESOURCE nr;
  979. nr.dwType = RESOURCETYPE_DISK;
  980. nr.lpLocalName = NULL;
  981. nr.lpRemoteName = (LPTSTR)(LPCTSTR)dir;
  982. nr.lpProvider = NULL;
  983. CString dir_ipc;
  984. dir_ipc = _T("\\\\");
  985. dir_ipc += server;
  986. dir_ipc += _T("\\ipc$");
  987. // Ensure we have a connection to this network file
  988. // if it already exists, it won't create another one
  989. // these Connections will be cleaned up in ~CIISMachine or when the machine is disconnected.
  990. // Empty strings below mean no password, which is wrong. NULLs mean
  991. // default user and default password -- this could work better for local case.
  992. LPCTSTR p1 = password, p2 = user;
  993. // In case when password is really was set empty, passing NULL will fail.
  994. if (password.IsEmpty() && !bEmptyPassword){p1 = NULL;}
  995. if (user.IsEmpty()){p2 = NULL;}
  996. // Check if we have access
  997. // to the resource without netuse
  998. BOOL bNeedToNetUse = FALSE;
  999. hFind = INVALID_HANDLE_VALUE;
  1000. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1001. if (hFind != INVALID_HANDLE_VALUE)
  1002. {
  1003. // successfull access
  1004. FindClose(hFind);
  1005. }
  1006. else
  1007. {
  1008. // if we failed then we probably need to
  1009. // net use to this resource!
  1010. bNeedToNetUse = TRUE;
  1011. }
  1012. // --------------------
  1013. // Ensure we have a connection to this network file
  1014. // if it already exists, it won't create another one
  1015. // these Connections will be cleaned up in ~CIISMachine or when the machine is disconnected.
  1016. // --------------------
  1017. if (pMachine && bNeedToNetUse)
  1018. {
  1019. // try to setup a "net use \\computername\$ipc" connection
  1020. // that everyone can use
  1021. // set the share name to
  1022. // \\machine\IPC$
  1023. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir_ipc;
  1024. //ERROR_LOGON_FAILURE
  1025. DWORD dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1026. if (NO_ERROR == dwRet)
  1027. {
  1028. bNeedToNetUse = FALSE;
  1029. }
  1030. else
  1031. {
  1032. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet || ERROR_ACCESS_DENIED == dwRet)
  1033. {
  1034. pMachine->m_MachineWNetConnections.Disconnect(dir_ipc);
  1035. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1036. }
  1037. }
  1038. }
  1039. // Check if we have access after the 1st net use.
  1040. // We are connecting to a remote machine...
  1041. // Check if we have access
  1042. // to the resource without netuse
  1043. hFind = INVALID_HANDLE_VALUE;
  1044. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1045. if (hFind != INVALID_HANDLE_VALUE)
  1046. {
  1047. // successfull access
  1048. FindClose(hFind);
  1049. }
  1050. else
  1051. {
  1052. // if we failed then we probably need to
  1053. // net use to this resource!
  1054. bNeedToNetUse = TRUE;
  1055. }
  1056. if (bNeedToNetUse)
  1057. {
  1058. if (pMachine)
  1059. {
  1060. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir;
  1061. DWORD dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1062. if (NO_ERROR != dwRet)
  1063. {
  1064. if (ERROR_ALREADY_ASSIGNED != dwRet)
  1065. {
  1066. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet || ERROR_ACCESS_DENIED == dwRet)
  1067. {
  1068. // Errored with already assigned
  1069. // check if we have accesss...
  1070. hFind = INVALID_HANDLE_VALUE;
  1071. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1072. if (hFind != INVALID_HANDLE_VALUE)
  1073. {
  1074. // successfull access
  1075. FindClose(hFind);
  1076. }
  1077. else
  1078. {
  1079. // stil don't have access
  1080. // kill the current connection and the ipc$ resource
  1081. pMachine->m_MachineWNetConnections.Disconnect(dir);
  1082. pMachine->m_MachineWNetConnections.Disconnect(dir_ipc);
  1083. // try to reconnect with the new path...
  1084. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir;
  1085. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1086. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet)
  1087. {
  1088. // Clean all connections to this machine and try again.
  1089. pMachine->m_MachineWNetConnections.Clear();
  1090. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1091. }
  1092. }
  1093. }
  1094. else
  1095. {
  1096. err = dwRet;
  1097. goto EnumerateResultPane__Exit;
  1098. }
  1099. }
  1100. }
  1101. }
  1102. }
  1103. }
  1104. }
  1105. if (PathIsUNCServerShare(dir))
  1106. {
  1107. if (FALSE == DoesUNCShareExist(dir))
  1108. {
  1109. err = ERROR_BAD_NETPATH;
  1110. goto EnumerateResultPane__Exit;
  1111. }
  1112. }
  1113. dir += _T("\\*");
  1114. hFind = INVALID_HANDLE_VALUE;
  1115. hFind = ::FindFirstFile(dir, &w32data);
  1116. // Bug:756402, revert previous change. we need to display if hidden or system.
  1117. const DWORD attr_skip = FILE_ATTRIBUTE_DIRECTORY; // | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
  1118. if (hFind == INVALID_HANDLE_VALUE)
  1119. {
  1120. err.GetLastWinError();
  1121. goto EnumerateResultPane__Exit;
  1122. }
  1123. ResultItemsList * pResList = AddResultItems(lpResultData);
  1124. do
  1125. {
  1126. LPCTSTR name = w32data.cFileName;
  1127. if ((w32data.dwFileAttributes & attr_skip) == 0)
  1128. {
  1129. CIISFileName * pNode = new CIISFileName(
  1130. GetOwner(), pService, w32data.dwFileAttributes,
  1131. name, NULL);
  1132. if (!pNode)
  1133. {
  1134. err = ERROR_NOT_ENOUGH_MEMORY;
  1135. break;
  1136. }
  1137. RESULTDATAITEM ri;
  1138. ::ZeroMemory(&ri, sizeof(ri));
  1139. ri.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  1140. ri.str = MMC_CALLBACK;
  1141. ri.nImage = pNode->QueryImage();
  1142. ri.lParam = (LPARAM)pNode;
  1143. pNode->AddRef();
  1144. err = lpResultData->InsertItem(&ri);
  1145. if (err.Succeeded())
  1146. {
  1147. pNode->SetScopeItem(m_hScopeItem);
  1148. pNode->SetResultItem(ri.itemID);
  1149. pResList->AddTail(pNode);
  1150. }
  1151. else
  1152. {
  1153. pNode->Release();
  1154. }
  1155. // commenting out this refreshdata
  1156. // this is waaay too much of a performance hit
  1157. // and slows down everything drastically.
  1158. //pNode->RefreshData();
  1159. }
  1160. } while (err.Succeeded() && FindNextFile(hFind, &w32data));
  1161. FindClose(hFind);
  1162. EnumerateResultPane__Exit:
  1163. return err;
  1164. }
  1165. ResultItemsList *
  1166. CIISMBNode::AddResultItems(IResultData * pResultData)
  1167. {
  1168. ResultViewEntry e;
  1169. e._ResultData = (DWORD_PTR)pResultData;
  1170. e._ResultItems = new ResultItemsList;
  1171. m_ResultViewList.AddTail(e);
  1172. POSITION pos = m_ResultViewList.GetTailPosition();
  1173. return m_ResultViewList.GetAt(pos)._ResultItems;
  1174. }
  1175. HRESULT
  1176. CIISMBNode::EnumerateWebDirs(HSCOPEITEM hParent, CIISService * pService)
  1177. /*++
  1178. Routine Description:
  1179. Enumerate scope file system child items.
  1180. Arguments:
  1181. HSCOPEITEM hParent : Parent console handle
  1182. CIISService * pService : Service type
  1183. Return Value:
  1184. HRESULT
  1185. --*/
  1186. {
  1187. ASSERT_PTR(pService);
  1188. CError err;
  1189. CIISMachine * pMachine = (CIISMachine *) GetMachineObject();
  1190. WIN32_FIND_DATA w32data;
  1191. HANDLE hFind = INVALID_HANDLE_VALUE;
  1192. CString dir;
  1193. CComBSTR root;
  1194. BuildMetaPath(root);
  1195. CString physPath, alias, csPathMunged;
  1196. GetPhysicalPath(CString(root), alias, physPath);
  1197. // -------------------------------------------------------------
  1198. // Before we do anything we need to see if it's a "special" path
  1199. //
  1200. // Everything after this function must validate against csPathMunged...
  1201. // this is because IsSpecialPath could have munged it...
  1202. // -------------------------------------------------------------
  1203. csPathMunged = physPath;
  1204. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  1205. GetSpecialPathRealPath(0,physPath,csPathMunged);
  1206. #endif
  1207. // Prepare for target machine metabase lookup
  1208. BOOL fCheckMetabase = TRUE;
  1209. CMetaKey mk(QueryInterface(), root, METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE);
  1210. CError errMB(mk.QueryResult());
  1211. if (errMB.Win32Error() == ERROR_PATH_NOT_FOUND)
  1212. {
  1213. //
  1214. // Metabase path not found, not a problem.
  1215. //
  1216. fCheckMetabase = FALSE;
  1217. errMB.Reset();
  1218. }
  1219. if (IsDevicePath(csPathMunged))
  1220. {
  1221. // check if the device path
  1222. // points to an actual dir/file
  1223. // if it does then enumerate it.
  1224. if (IsSpecialPath(csPathMunged,TRUE,TRUE))
  1225. {
  1226. // Remunge this one more time!
  1227. CString csBefore;
  1228. csBefore = csPathMunged;
  1229. GetSpecialPathRealPath(1,csBefore,csPathMunged);
  1230. }
  1231. else
  1232. {
  1233. goto EnumerateWebDirs_Exit;
  1234. }
  1235. }
  1236. // WARNING:physPath could be empty!
  1237. csPathMunged.TrimLeft();
  1238. csPathMunged.TrimRight();
  1239. if (csPathMunged.IsEmpty()){goto EnumerateWebDirs_Exit;}
  1240. if (pService->IsLocal() || PathIsUNC(csPathMunged))
  1241. {
  1242. dir = csPathMunged;
  1243. }
  1244. else
  1245. {
  1246. ::MakeUNCPath(dir, pService->QueryMachineName(), csPathMunged);
  1247. }
  1248. dir.TrimLeft();
  1249. dir.TrimRight();
  1250. if (dir.IsEmpty()){goto EnumerateWebDirs_Exit;}
  1251. // ------------------------------
  1252. // Check if we need to "net use"
  1253. // to the file resource on a remote machine
  1254. // so we can enum it...
  1255. // ------------------------------
  1256. if (PathIsUNC(dir))
  1257. {
  1258. CString server, user, password;
  1259. CString MyTestDir;
  1260. MyTestDir = dir;
  1261. MyTestDir += _T("\\*");
  1262. // we are trying to get the servername portion
  1263. // PathFindNextComponent should return something like "servername\mydir\myfile.txt"
  1264. // trim off everything after the 1st slash
  1265. server = PathFindNextComponent(dir);
  1266. int n = server.Find(_T('\\'));
  1267. if (n != -1)
  1268. {server = server.Left(n);}
  1269. user = QueryInterface()->QueryAuthInfo()->QueryUserName();
  1270. password = QueryInterface()->QueryAuthInfo()->QueryPassword();
  1271. // we need to compare the servername that we want to get to
  1272. // with the servername of the local computer.
  1273. // this way we know if we need to net use to the machine!
  1274. TCHAR szLocalMachineName[MAX_PATH + 1];
  1275. DWORD dwSize = MAX_PATH;
  1276. if (0 == ::GetComputerName(szLocalMachineName, &dwSize))
  1277. {
  1278. err.GetLastWinError();
  1279. goto EnumerateWebDirs_Exit;
  1280. }
  1281. // Check to see if the localmachine is different that the
  1282. // machine we want to connect to to enum it's files upon...
  1283. if (!pService->IsLocal()
  1284. || server.CompareNoCase(szLocalMachineName) != 0
  1285. )
  1286. {
  1287. // We are connecting to a path which is different from the computer name!
  1288. BOOL bEmptyPassword = FALSE;
  1289. // non-local resource, get connection credentials
  1290. if (fCheckMetabase && PathIsUNC(csPathMunged))
  1291. {
  1292. err = mk.QueryValue(MD_VR_USERNAME, user);
  1293. if (err.Succeeded())
  1294. {
  1295. err = mk.QueryValue(MD_VR_PASSWORD, password);
  1296. bEmptyPassword = (err.Failed() ? TRUE : err.Succeeded() && password.IsEmpty());
  1297. }
  1298. // these credentials could be empty. try defaults
  1299. err.Reset();
  1300. }
  1301. // Add use for this resource
  1302. NETRESOURCE nr;
  1303. nr.dwType = RESOURCETYPE_DISK;
  1304. nr.lpLocalName = NULL;
  1305. nr.lpRemoteName = (LPTSTR)(LPCTSTR)dir;
  1306. nr.lpProvider = NULL;
  1307. CString dir_ipc;
  1308. dir_ipc = _T("\\\\");
  1309. dir_ipc += server;
  1310. dir_ipc += _T("\\ipc$");
  1311. // Empty strings below mean no password, which is wrong. NULLs mean
  1312. // default user and default password -- this could work better for local case.
  1313. LPCTSTR p1 = password, p2 = user;
  1314. // In case when password is really was set empty, passing NULL will fail.
  1315. if (password.IsEmpty() && !bEmptyPassword){p1 = NULL;}
  1316. if (user.IsEmpty()){p2 = NULL;}
  1317. // Check if we have access
  1318. // to the resource without netuse
  1319. BOOL bNeedToNetUse = FALSE;
  1320. hFind = INVALID_HANDLE_VALUE;
  1321. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1322. if (hFind != INVALID_HANDLE_VALUE)
  1323. {
  1324. // successfull access
  1325. FindClose(hFind);
  1326. }
  1327. else
  1328. {
  1329. // if we failed then we probably need to
  1330. // net use to this resource!
  1331. bNeedToNetUse = TRUE;
  1332. }
  1333. // --------------------
  1334. // Ensure we have a connection to this network file
  1335. // if it already exists, it won't create another one
  1336. // these Connections will be cleaned up in ~CIISMachine or when the machine is disconnected.
  1337. // --------------------
  1338. if (pMachine && bNeedToNetUse)
  1339. {
  1340. // try to setup a "net use \\computername\$ipc" connection
  1341. // that everyone can use
  1342. // set the share name to
  1343. // \\machine\IPC$
  1344. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir_ipc;
  1345. DWORD dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1346. if (NO_ERROR == dwRet)
  1347. {
  1348. bNeedToNetUse = FALSE;
  1349. }
  1350. else
  1351. {
  1352. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet || ERROR_ACCESS_DENIED == dwRet)
  1353. {
  1354. pMachine->m_MachineWNetConnections.Disconnect(dir_ipc);
  1355. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1356. }
  1357. }
  1358. }
  1359. // Check if we have access after the 1st net use.
  1360. // We are connecting to a remote machine...
  1361. // Check if we have access
  1362. // to the resource without netuse
  1363. hFind = INVALID_HANDLE_VALUE;
  1364. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1365. if (hFind != INVALID_HANDLE_VALUE)
  1366. {
  1367. // successfull access
  1368. FindClose(hFind);
  1369. }
  1370. else
  1371. {
  1372. // if we failed then we probably need to
  1373. // net use to this resource!
  1374. bNeedToNetUse = TRUE;
  1375. }
  1376. if (bNeedToNetUse)
  1377. {
  1378. if (pMachine)
  1379. {
  1380. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir;
  1381. DWORD dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1382. if (NO_ERROR != dwRet)
  1383. {
  1384. if (ERROR_ALREADY_ASSIGNED != dwRet)
  1385. {
  1386. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet || ERROR_ACCESS_DENIED == dwRet)
  1387. {
  1388. // Errored with already assigned
  1389. // check if we have accesss...
  1390. hFind = INVALID_HANDLE_VALUE;
  1391. hFind = ::FindFirstFile(MyTestDir, &w32data);
  1392. if (hFind != INVALID_HANDLE_VALUE)
  1393. {
  1394. // successfull access
  1395. FindClose(hFind);
  1396. }
  1397. else
  1398. {
  1399. // stil don't have access
  1400. // kill the current connection and the ipc$ resource
  1401. pMachine->m_MachineWNetConnections.Disconnect(dir);
  1402. pMachine->m_MachineWNetConnections.Disconnect(dir_ipc);
  1403. // try to reconnect with the new path...
  1404. nr.lpRemoteName = (LPTSTR)(LPCTSTR) dir;
  1405. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1406. if (ERROR_SESSION_CREDENTIAL_CONFLICT == dwRet)
  1407. {
  1408. // Clean all connections to this machine and try again.
  1409. pMachine->m_MachineWNetConnections.Clear();
  1410. dwRet = pMachine->m_MachineWNetConnections.Connect(&nr,p1,p2,0);
  1411. }
  1412. else
  1413. {
  1414. if (NO_ERROR != dwRet)
  1415. {
  1416. // Final failure, what now?
  1417. }
  1418. }
  1419. }
  1420. }
  1421. else
  1422. {
  1423. err = dwRet;
  1424. goto EnumerateWebDirs_Exit;
  1425. }
  1426. }
  1427. }
  1428. }
  1429. }
  1430. }
  1431. }
  1432. // -----------------------------------
  1433. // Enum thru the Physical file path...
  1434. // -----------------------------------
  1435. dir += _T("\\*");
  1436. hFind = INVALID_HANDLE_VALUE;
  1437. hFind = ::FindFirstFile(dir, &w32data);
  1438. // Bug:756402, revert previous change. we need to display if hidden or system.
  1439. // const DWORD attr_skip = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
  1440. if (hFind == INVALID_HANDLE_VALUE)
  1441. {
  1442. err.GetLastWinError();
  1443. goto EnumerateWebDirs_Exit;
  1444. }
  1445. do
  1446. {
  1447. LPCTSTR name = w32data.cFileName;
  1448. if ( (w32data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
  1449. // Bug:756402, revert previous change. we need to display if hidden or system.
  1450. // && (w32data.dwFileAttributes & attr_skip) == 0
  1451. && lstrcmp(name, _T(".")) != 0
  1452. && lstrcmp(name, _T("..")) != 0
  1453. )
  1454. {
  1455. CIISFileName * pNode = new CIISFileName(m_pOwner,
  1456. pService, w32data.dwFileAttributes, name, NULL);
  1457. if (!pNode)
  1458. {
  1459. err = ERROR_NOT_ENOUGH_MEMORY;
  1460. goto EnumerateWebDirs_Exit;
  1461. }
  1462. if (fCheckMetabase)
  1463. {
  1464. errMB = mk.DoesPathExist(w32data.cFileName);
  1465. if (errMB.Succeeded())
  1466. {
  1467. //
  1468. // Match up with metabase properties. If the item
  1469. // is found in the metabase with a non-inherited vrpath,
  1470. // than a virtual root with this name exists, and this
  1471. // file/directory should not be shown.
  1472. //
  1473. CString vrpath;
  1474. BOOL f = FALSE;
  1475. DWORD attr = 0;
  1476. errMB = mk.QueryValue(MD_VR_PATH, vrpath, NULL, w32data.cFileName, &attr);
  1477. if (errMB.Succeeded() && (attr & METADATA_ISINHERITED) == 0)
  1478. {
  1479. TRACEEOLID("file/directory exists as vroot -- tossing" << w32data.cFileName);
  1480. pNode->Release();
  1481. continue;
  1482. }
  1483. }
  1484. }
  1485. pNode->AddRef();
  1486. err = pNode->AddToScopePane(hParent);
  1487. }
  1488. } while (err.Succeeded() && FindNextFile(hFind, &w32data));
  1489. FindClose(hFind);
  1490. EnumerateWebDirs_Exit:
  1491. if (err.Failed())
  1492. {
  1493. DisplayError(err);
  1494. }
  1495. return err;
  1496. }
  1497. HRESULT
  1498. CIISMBNode::CreateEnumerator(CMetaEnumerator *& pEnum)
  1499. /*++
  1500. Routine Description:
  1501. Create enumerator object for the current path. Requires interface
  1502. to already be initialized
  1503. Arguments:
  1504. CMetaEnumerator *& pEnum : Returns enumerator
  1505. Return Value:
  1506. HRESULT
  1507. --*/
  1508. {
  1509. ASSERT(pEnum == NULL);
  1510. ASSERT(m_hScopeItem != NULL);
  1511. CComBSTR bstrPath;
  1512. CError err(BuildMetaPath(bstrPath));
  1513. if (err.Succeeded())
  1514. {
  1515. TRACEEOLID("Build metabase path: " << bstrPath);
  1516. BOOL fContinue = TRUE;
  1517. while(fContinue)
  1518. {
  1519. fContinue = FALSE;
  1520. pEnum = new CMetaEnumerator(QueryInterface(), bstrPath);
  1521. err = pEnum ? pEnum->QueryResult() : ERROR_NOT_ENOUGH_MEMORY;
  1522. if (IsLostInterface(err))
  1523. {
  1524. SAFE_DELETE(pEnum);
  1525. fContinue = OnLostInterface(err);
  1526. }
  1527. }
  1528. }
  1529. return err;
  1530. }
  1531. /* virtual */
  1532. HRESULT
  1533. CIISMBNode::Refresh(BOOL fReEnumerate)
  1534. /*++
  1535. Routine Description:
  1536. Refresh current node, and optionally re-enumerate child objects
  1537. Arguments:
  1538. BOOL fReEnumerate : If true, kill child objects, and re-enumerate
  1539. --*/
  1540. {
  1541. CError err;
  1542. //
  1543. // Set MFC state for wait cursor
  1544. //
  1545. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1546. CWaitCursor wait;
  1547. err = RefreshData();
  1548. if (err.Succeeded())
  1549. {
  1550. if (fReEnumerate)
  1551. {
  1552. //
  1553. // Kill child objects
  1554. //
  1555. TRACEEOLID("Killing child objects");
  1556. ASSERT(m_hScopeItem != NULL);
  1557. if (m_hScopeItem != NULL)
  1558. {
  1559. err = RemoveChildren(m_hScopeItem);
  1560. if (err.Succeeded())
  1561. {
  1562. err = EnumerateScopePane(m_hScopeItem);
  1563. }
  1564. }
  1565. }
  1566. err = RefreshDisplay();
  1567. }
  1568. return err;
  1569. }
  1570. /* virtual */
  1571. HRESULT
  1572. CIISMBNode::GetResultViewType(
  1573. OUT LPOLESTR * lplpViewType,
  1574. OUT long * lpViewOptions
  1575. )
  1576. /*++
  1577. Routine Description:
  1578. If we have an URL built up, display our result view as that URL,
  1579. and destroy it. This is done when 'browsing' a metabase node.
  1580. The derived class will build the URL, and reselect the node.
  1581. Arguments:
  1582. BSTR * lplpViewType : Return view type here
  1583. long * lpViewOptions : View options
  1584. Return Value:
  1585. S_FALSE to use default view type, S_OK indicates the
  1586. view type is returned in *ppViewType
  1587. --*/
  1588. {
  1589. if (m_bstrURL.Length())
  1590. {
  1591. *lpViewOptions = MMC_VIEW_OPTIONS_NONE;
  1592. *lplpViewType = (LPOLESTR)::CoTaskMemAlloc(
  1593. (m_bstrURL.Length() + 1) * sizeof(WCHAR)
  1594. );
  1595. if (*lplpViewType)
  1596. {
  1597. lstrcpy(*lplpViewType, m_bstrURL);
  1598. //
  1599. // Destroy URL so we get a normal result view next time
  1600. //
  1601. m_bstrURL.Empty();
  1602. m_fSkipEnumResult = TRUE;
  1603. return S_OK;
  1604. }
  1605. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  1606. }
  1607. //
  1608. // No URL waiting -- use standard result view
  1609. //
  1610. return CIISObject::GetResultViewType(lplpViewType, lpViewOptions);
  1611. }
  1612. HRESULT
  1613. ShellExecuteDirectory(
  1614. LPCTSTR lpszCommand,
  1615. LPCTSTR lpszOwner,
  1616. LPCTSTR lpszDirectory,
  1617. HWND hWnd
  1618. )
  1619. /*++
  1620. Routine Description:
  1621. Shell Open or explore on a given directory path
  1622. Arguments:
  1623. LPCTSTR lpszCommand : "open" or "explore"
  1624. LPCTSTR lpszOwner : Owner server
  1625. LPCTSTR lpszDirectory : Directory path
  1626. Return Value:
  1627. Error return code.
  1628. --*/
  1629. {
  1630. CString strDir;
  1631. if (::IsServerLocal(lpszOwner) || ::IsUNCName(lpszDirectory))
  1632. {
  1633. //
  1634. // Local directory, or already a unc path
  1635. //
  1636. strDir = lpszDirectory;
  1637. }
  1638. else
  1639. {
  1640. ::MakeUNCPath(strDir, lpszOwner, lpszDirectory);
  1641. }
  1642. TRACEEOLID("Attempting to " << lpszCommand << " Path: " << strDir);
  1643. CError err;
  1644. {
  1645. //
  1646. // AFX_MANAGE_STATE required for wait cursor
  1647. //
  1648. AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
  1649. CWaitCursor wait;
  1650. if (::ShellExecute(NULL, lpszCommand, strDir, NULL,_T(""), SW_SHOW) <= (HINSTANCE)32)
  1651. {
  1652. err.GetLastWinError();
  1653. if (err.Win32Error() == ERROR_NO_ASSOCIATION)
  1654. {
  1655. // Open shell OpenAs dialog
  1656. SHELLEXECUTEINFO ei = {0};
  1657. ei.cbSize = sizeof(ei);
  1658. ei.fMask = SEE_MASK_NOQUERYCLASSSTORE;
  1659. RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("Unknown"), 0, MAXIMUM_ALLOWED, &ei.hkeyClass);
  1660. if (ei.hkeyClass != NULL)
  1661. {
  1662. ei.fMask |= SEE_MASK_NOQUERYCLASSSTORE;
  1663. }
  1664. ei.lpFile = strDir;
  1665. ei.nShow = SW_SHOW;
  1666. ei.lpVerb = _T("openas");
  1667. ei.hwnd = hWnd;
  1668. err = ShellExecuteEx(&ei);
  1669. if (ei.hkeyClass != NULL)
  1670. {
  1671. RegCloseKey(ei.hkeyClass);
  1672. }
  1673. }
  1674. }
  1675. }
  1676. return err;
  1677. }
  1678. HRESULT
  1679. CIISMBNode::CreatePropertyPages(
  1680. LPPROPERTYSHEETCALLBACK lpProvider,
  1681. LONG_PTR handle,
  1682. IUnknown * pUnk,
  1683. DATA_OBJECT_TYPES type
  1684. )
  1685. {
  1686. CError err = CIISObject::CreatePropertyPages(lpProvider, handle, pUnk, type);
  1687. if (err == S_FALSE)
  1688. {
  1689. return S_FALSE;
  1690. }
  1691. // Set this objects Tag to compare with something already opened
  1692. CreateTag();
  1693. CIISObject * pAlreadyOpenProp = NULL;
  1694. if (TRUE == g_OpenPropertySheetTracker.FindAlreadyOpenPropertySheet(this,&pAlreadyOpenProp))
  1695. {
  1696. // Bring it to the foreground, and bail
  1697. HWND hHwnd = 0;
  1698. if (pAlreadyOpenProp)
  1699. {
  1700. if (hHwnd = pAlreadyOpenProp->IsMyPropertySheetOpen())
  1701. {
  1702. if (hHwnd && (hHwnd != (HWND) 1))
  1703. {
  1704. // Perhapse we should cancel the already
  1705. // opened property sheet...just a thought
  1706. if (!SetForegroundWindow(hHwnd))
  1707. {
  1708. // wasn't able to bring this property sheet to
  1709. // the foreground, the propertysheet must not
  1710. // exist anymore. let's just clean the hwnd
  1711. // so that the user will be able to open propertysheet
  1712. pAlreadyOpenProp->SetMyPropertySheetOpen(0);
  1713. }
  1714. else
  1715. {
  1716. return ERROR_ALREADY_EXISTS;
  1717. }
  1718. }
  1719. }
  1720. }
  1721. }
  1722. // Check if we are still connected
  1723. if (!GetOwner()->IsLocal())
  1724. {
  1725. // Problem here could be that lpszOwner is not a computername but rather
  1726. // an IP Address!!!!
  1727. LPCTSTR lpszServer = PURE_COMPUTER_NAME(GetOwner()->QueryServerName());
  1728. if (LooksLikeIPAddress(lpszServer))
  1729. {
  1730. //
  1731. // Get by ip address
  1732. //
  1733. CString strTemp;
  1734. CIPAddress ia(lpszServer);
  1735. if (NOERROR != MyGetHostName((DWORD)ia, strTemp))
  1736. {
  1737. // network is down!!!
  1738. err = ERROR_NO_NETWORK;
  1739. return err;
  1740. }
  1741. }
  1742. do
  1743. {
  1744. // WARNING:QueryInterface() Can return NULL
  1745. // and if the CMetakey is created with a NULL
  1746. // pointer, it will AV.
  1747. if (!GetOwner()->QueryInterface())
  1748. {
  1749. return RPC_S_SERVER_UNAVAILABLE;
  1750. }
  1751. CMetaKey mk(GetOwner()->QueryInterface());
  1752. err = mk.QueryResult();
  1753. BREAK_ON_ERR_FAILURE(err);
  1754. CComBSTR path;
  1755. err = BuildMetaPath(path);
  1756. BREAK_ON_ERR_FAILURE(err);
  1757. CString buf = path;
  1758. while (FAILED(mk.DoesPathExist(buf)))
  1759. {
  1760. // Goto parent
  1761. if (NULL == CMetabasePath::ConvertToParentPath(buf))
  1762. {
  1763. break;
  1764. }
  1765. }
  1766. err = mk.Open(
  1767. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  1768. buf
  1769. );
  1770. BREAK_ON_ERR_FAILURE(err);
  1771. //
  1772. // Write some nonsense
  1773. //
  1774. DWORD dwDummy = 0x1234;
  1775. err = mk.SetValue(MD_ISM_ACCESS_CHECK, dwDummy);
  1776. BREAK_ON_ERR_FAILURE(err);
  1777. //
  1778. // And delete it again
  1779. //
  1780. err = mk.DeleteValue(MD_ISM_ACCESS_CHECK);
  1781. } while (FALSE);
  1782. }
  1783. return err;
  1784. }
  1785. HRESULT
  1786. CIISMBNode::Command(
  1787. IN long lCommandID,
  1788. IN CSnapInObjectRootBase * pObj,
  1789. IN DATA_OBJECT_TYPES type
  1790. )
  1791. /*++
  1792. Routine Description:
  1793. Handle command from context menu.
  1794. Arguments:
  1795. long lCommandID : Command ID
  1796. CSnapInObjectRootBase * pObj : Base object
  1797. DATA_OBJECT_TYPES type : Data object type
  1798. Return Value:
  1799. HRESULT
  1800. --*/
  1801. {
  1802. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1803. HRESULT hr = S_OK;
  1804. CError err = ERROR_NOT_ENOUGH_MEMORY;
  1805. CComBSTR bstrMetaPath;
  1806. BOOL bNeedMetabase = FALSE;
  1807. BOOL bHaveMetabase = FALSE;
  1808. switch (lCommandID)
  1809. {
  1810. case IDM_BROWSE:
  1811. case IDM_OPEN:
  1812. case IDM_PERMISSION:
  1813. case IDM_EXPLORE:
  1814. case IDM_NEW_FTP_SITE_FROM_FILE:
  1815. case IDM_NEW_FTP_VDIR_FROM_FILE:
  1816. case IDM_NEW_WEB_SITE_FROM_FILE:
  1817. case IDM_NEW_WEB_VDIR_FROM_FILE:
  1818. case IDM_NEW_APP_POOL_FROM_FILE:
  1819. case IDM_TASK_EXPORT_CONFIG_WIZARD:
  1820. bNeedMetabase = TRUE;
  1821. break;
  1822. default:
  1823. bNeedMetabase = FALSE;
  1824. }
  1825. if (bNeedMetabase)
  1826. {
  1827. // WARNING:bstrMetaPath will be used by switch statement below
  1828. VERIFY(SUCCEEDED(BuildMetaPath(bstrMetaPath)));
  1829. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  1830. if (!IsLostInterface(err))
  1831. {
  1832. // reset error if an other error other than No interface
  1833. err.Reset();
  1834. }
  1835. if (err.Succeeded())
  1836. {
  1837. bHaveMetabase = TRUE;
  1838. }
  1839. }
  1840. switch (lCommandID)
  1841. {
  1842. case IDM_BROWSE:
  1843. {
  1844. if (bHaveMetabase)
  1845. {
  1846. //
  1847. // Build URL for this node, and force a re-select so as to change
  1848. // the result view
  1849. //
  1850. BuildURL(m_bstrURL);
  1851. if (m_bstrURL.Length())
  1852. {
  1853. //
  1854. // After selection, the browsed URL will come up in the result view
  1855. //
  1856. SelectScopeItem();
  1857. }
  1858. }
  1859. }
  1860. break;
  1861. //
  1862. // CODEWORK: Build path, and, using the explorer URL, put this stuff
  1863. // in the result view.
  1864. //
  1865. case IDM_OPEN:
  1866. {
  1867. if (bHaveMetabase)
  1868. {
  1869. CString phys_path, alias;
  1870. if (GetPhysicalPath(bstrMetaPath, alias, phys_path))
  1871. {
  1872. hr = ShellExecuteDirectory(_T("open"), QueryMachineName(), phys_path, GetMainWindow(GetConsole())->m_hWnd);
  1873. }
  1874. }
  1875. }
  1876. break;
  1877. case IDM_PERMISSION:
  1878. {
  1879. if (bHaveMetabase)
  1880. {
  1881. CString phys_path, alias, csPathMunged;
  1882. if (GetPhysicalPath(bstrMetaPath, alias, phys_path))
  1883. {
  1884. // -------------------------------------------------------------
  1885. // Before we do anything we need to see if it's a "special" path
  1886. //
  1887. // Everything after this function must validate against csPathMunged...
  1888. // this is because IsSpecialPath could have munged it...
  1889. // -------------------------------------------------------------
  1890. csPathMunged = phys_path;
  1891. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  1892. GetSpecialPathRealPath(0,phys_path,csPathMunged);
  1893. #endif
  1894. if (!IsDevicePath(csPathMunged))
  1895. {
  1896. INT_PTR iReturn = PopupPermissionDialog(
  1897. GetMainWindow(GetConsole())->m_hWnd,
  1898. QueryMachineName(),
  1899. csPathMunged);
  1900. }
  1901. }
  1902. }
  1903. }
  1904. break;
  1905. case IDM_EXPLORE:
  1906. {
  1907. if (bHaveMetabase)
  1908. {
  1909. CString phys_path, alias;
  1910. if (GetPhysicalPath(bstrMetaPath, alias, phys_path))
  1911. {
  1912. TCHAR url[MAX_PATH];
  1913. DWORD len = MAX_PATH;
  1914. hr = UrlCreateFromPath(phys_path, url, &len, NULL);
  1915. m_bstrURL = url;
  1916. SelectScopeItem();
  1917. }
  1918. }
  1919. }
  1920. break;
  1921. case IDM_NEW_FTP_SITE_FROM_FILE:
  1922. {
  1923. if (bHaveMetabase)
  1924. {
  1925. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  1926. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  1927. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  1928. if (ERROR_SUCCESS == (hr = DoNodeImportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath,IIS_CLASS_FTP_SERVER_W)))
  1929. {
  1930. // check if we need to just refresh this node or the node above us...
  1931. CIISMBNode * pNode = GetParentNode();
  1932. if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cServiceCollectorNode))
  1933. {
  1934. pNode->Refresh(TRUE);
  1935. }
  1936. else
  1937. {
  1938. BOOL bExpand = !IsLeafNode();Refresh(bExpand);
  1939. }
  1940. }
  1941. }
  1942. }
  1943. break;
  1944. case IDM_NEW_FTP_VDIR_FROM_FILE:
  1945. {
  1946. if (bHaveMetabase)
  1947. {
  1948. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  1949. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  1950. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  1951. if (ERROR_SUCCESS == (hr = DoNodeImportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath,IIS_CLASS_FTP_VDIR_W)))
  1952. {
  1953. // check if we need to just refresh this node or the node above us...
  1954. CIISMBNode * pNode = GetParentNode();
  1955. if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cInstanceNode))
  1956. {
  1957. pNode->Refresh(TRUE);
  1958. }
  1959. else
  1960. {
  1961. BOOL bExpand = !IsLeafNode();Refresh(bExpand);
  1962. }
  1963. }
  1964. }
  1965. }
  1966. break;
  1967. case IDM_NEW_WEB_SITE_FROM_FILE:
  1968. {
  1969. if (bHaveMetabase)
  1970. {
  1971. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  1972. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  1973. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  1974. if (ERROR_SUCCESS == (hr = DoNodeImportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath,IIS_CLASS_WEB_SERVER_W)))
  1975. {
  1976. // check if we need to just refresh this node or the node above us...
  1977. CIISMBNode * pNode = GetParentNode();
  1978. if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cServiceCollectorNode))
  1979. {
  1980. pNode->Refresh(TRUE);
  1981. }
  1982. else
  1983. {
  1984. BOOL bExpand = !IsLeafNode();Refresh(bExpand);
  1985. }
  1986. }
  1987. }
  1988. }
  1989. break;
  1990. case IDM_NEW_WEB_VDIR_FROM_FILE:
  1991. {
  1992. if (bHaveMetabase)
  1993. {
  1994. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  1995. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  1996. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  1997. if (ERROR_SUCCESS == (hr = DoNodeImportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath,IIS_CLASS_WEB_VDIR_W)))
  1998. {
  1999. // check if we need to just refresh this node or the node above us...
  2000. CIISMBNode * pNode = GetParentNode();
  2001. if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cInstanceNode))
  2002. {
  2003. pNode->Refresh(TRUE);
  2004. }
  2005. else
  2006. {
  2007. BOOL bExpand = !IsLeafNode();Refresh(bExpand);
  2008. }
  2009. }
  2010. }
  2011. }
  2012. break;
  2013. case IDM_NEW_APP_POOL_FROM_FILE:
  2014. {
  2015. if (bHaveMetabase)
  2016. {
  2017. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  2018. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  2019. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  2020. if (ERROR_SUCCESS == (hr = DoNodeImportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath,L"IIsApplicationPool")))
  2021. {
  2022. // check if we need to just refresh this node or the node above us...
  2023. CIISMBNode * pNode = GetParentNode();
  2024. if (IsEqualGUID(* (GUID *)pNode->GetNodeType(),cAppPoolsNode))
  2025. {
  2026. pNode->Refresh(TRUE);
  2027. }
  2028. else
  2029. {
  2030. BOOL bExpand = !IsLeafNode();Refresh(bExpand);
  2031. }
  2032. }
  2033. }
  2034. }
  2035. break;
  2036. case IDM_TASK_EXPORT_CONFIG_WIZARD:
  2037. {
  2038. if (bHaveMetabase)
  2039. {
  2040. CString strNewPath, strRemainder;
  2041. CComBSTR bstrServerName(QueryInterface()->QueryAuthInfo()->QueryServerName());
  2042. CComBSTR bstrUserName(QueryInterface()->QueryAuthInfo()->QueryUserName());
  2043. CComBSTR bstrUserPass(QueryInterface()->QueryAuthInfo()->QueryPassword());
  2044. // Is this the root??
  2045. LPCTSTR lpPath = CMetabasePath::GetRootPath(bstrMetaPath, strNewPath, &strRemainder);
  2046. if (lpPath && (0 == _tcsicmp(lpPath,bstrMetaPath)))
  2047. {
  2048. CString strNewMetaPath;
  2049. //
  2050. // Get the instance properties
  2051. //
  2052. CMetabasePath::GetInstancePath(bstrMetaPath,strNewMetaPath);
  2053. CComBSTR bstrNewMetaPath((LPCTSTR) strNewMetaPath);
  2054. // if empty or if this is an app pool...
  2055. if (IsEqualGUID(* (GUID *) GetNodeType(),cAppPoolNode))
  2056. {
  2057. hr = DoNodeExportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath);
  2058. }
  2059. else
  2060. {
  2061. if (strNewMetaPath.IsEmpty())
  2062. {
  2063. hr = DoNodeExportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath);
  2064. }
  2065. else
  2066. {
  2067. hr = DoNodeExportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrNewMetaPath);
  2068. }
  2069. }
  2070. }
  2071. else
  2072. {
  2073. hr = DoNodeExportConfig(bstrServerName,bstrUserName,bstrUserPass,bstrMetaPath);
  2074. }
  2075. }
  2076. }
  2077. break;
  2078. //
  2079. // Pass on to base class
  2080. //
  2081. default:
  2082. {
  2083. hr = CIISObject::Command(lCommandID, pObj, type);
  2084. }
  2085. } // end switch
  2086. return hr;
  2087. }
  2088. #if 0
  2089. HRESULT
  2090. CIISMBNode::OnPropertyChange(BOOL fScope, IResultData * pResult)
  2091. {
  2092. CError err;
  2093. err = Refresh(fScope);
  2094. if (err.Succeeded())
  2095. {
  2096. if ( fScope
  2097. && HasFileSystemFiles()
  2098. && !m_ResultItems.IsEmpty()
  2099. )
  2100. {
  2101. err = CleanResult(pResult);
  2102. if (err.Succeeded())
  2103. {
  2104. err = EnumerateResultPane(fScope, NULL, pResult);
  2105. }
  2106. }
  2107. else if (!fScope)
  2108. {
  2109. pResult->UpdateItem(m_hResultItem);
  2110. }
  2111. }
  2112. return err;
  2113. }
  2114. #endif
  2115. HRESULT
  2116. CIISMBNode::OnViewChange(BOOL fScope, IResultData * pResult, IHeaderCtrl * pHeader, DWORD hint)
  2117. {
  2118. CError err;
  2119. BOOL bReenumResult = 0 != (hint & PROP_CHANGE_REENUM_FILES);
  2120. BOOL bReenumScope =
  2121. 0 != (hint & PROP_CHANGE_REENUM_VDIR) || 0 != (hint & PROP_CHANGE_REENUM_FILES);
  2122. if (QueryScopeItem() || QueryResultItem())
  2123. {
  2124. BOOL bExpand = fScope
  2125. && !IsLeafNode()
  2126. && bReenumScope
  2127. // && IsExpanded()
  2128. ;
  2129. BOOL bHasResult = HasResultItems(pResult);
  2130. if (bHasResult && bReenumResult)
  2131. {
  2132. // Remove files that could be in result pane
  2133. err = CleanResult(pResult);
  2134. }
  2135. // after error this node could be not expanded, we should expand it anyway
  2136. err = Refresh(bExpand);
  2137. if (err.Succeeded())
  2138. {
  2139. if (fScope && HasFileSystemFiles() && bReenumResult && bHasResult)
  2140. {
  2141. err = EnumerateResultPane(TRUE, pHeader, pResult);
  2142. }
  2143. else if (!fScope && (bReenumResult || 0 != (hint & PROP_CHANGE_DISPLAY_ONLY)))
  2144. {
  2145. pResult->UpdateItem(m_hResultItem);
  2146. }
  2147. }
  2148. }
  2149. return err;
  2150. }
  2151. HRESULT
  2152. CIISMBNode::RemoveResultNode(CIISMBNode * pNode, IResultData * pResult)
  2153. {
  2154. CError err;
  2155. ASSERT(HasFileSystemFiles());
  2156. err = pResult->DeleteItem(pNode->m_hResultItem, 0);
  2157. if (err.Succeeded())
  2158. {
  2159. POSITION pos = m_ResultViewList.GetHeadPosition();
  2160. while (pos != NULL)
  2161. {
  2162. ResultViewEntry e = m_ResultViewList.GetNext(pos);
  2163. if (e._ResultData == (DWORD_PTR)pResult)
  2164. {
  2165. BOOL found = FALSE;
  2166. POSITION p = e._ResultItems->GetHeadPosition();
  2167. POSITION pcur;
  2168. while (p != NULL)
  2169. {
  2170. pcur = p;
  2171. if (e._ResultItems->GetNext(p) == pNode)
  2172. {
  2173. found = TRUE;
  2174. break;
  2175. }
  2176. }
  2177. if (found)
  2178. {
  2179. e._ResultItems->RemoveAt(pcur);
  2180. pNode->Release();
  2181. }
  2182. }
  2183. }
  2184. }
  2185. return err;
  2186. }
  2187. // See FtpAddNew.cpp for the method CIISMBNode::AddFTPSite
  2188. // See WebAddNew.cpp for the method CIISMBNode::AddWebSite
  2189. // See add_app_pool.cpp for the method CIISMBNode::AddAppPool