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

1351 lines
27 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name :
  4. iisdirectory.cpp
  5. Abstract:
  6. IIS Directory node 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 "w3sht.h"
  24. #include "wdir.h"
  25. #include "docum.h"
  26. #include "wfile.h"
  27. #include "wsecure.h"
  28. #include "httppage.h"
  29. #include "errors.h"
  30. #include "fltdlg.h"
  31. #include <lm.h>
  32. #ifdef _DEBUG
  33. #undef THIS_FILE
  34. static char BASED_CODE THIS_FILE[] = __FILE__;
  35. #endif
  36. #define new DEBUG_NEW
  37. //
  38. // CIISDirectory Implementation
  39. //
  40. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  41. //
  42. // Site Result View definition
  43. //
  44. /* static */ int
  45. CIISDirectory::_rgnLabels[COL_TOTAL] =
  46. {
  47. IDS_RESULT_NAME,
  48. IDS_RESULT_PATH,
  49. IDS_RESULT_STATUS,
  50. };
  51. /* static */ int
  52. CIISDirectory::_rgnWidths[COL_TOTAL] =
  53. {
  54. 180,
  55. 200,
  56. 200,
  57. };
  58. #if 0
  59. /* static */ CComBSTR CIISDirectory::_bstrName;
  60. /* static */ CComBSTR CIISDirectory::_bstrPath;
  61. /* static */ BOOL CIISDirectory::_fStaticsLoaded = FALSE;
  62. #endif
  63. CIISDirectory::CIISDirectory(
  64. IN CIISMachine * pOwner,
  65. IN CIISService * pService,
  66. IN LPCTSTR szNodeName
  67. )
  68. /*++
  69. Routine Description:
  70. Constructor which does not resolve all display information at
  71. construction time.
  72. Arguments:
  73. CIISMachine * pOwner : Owner machine
  74. CIISService * pService : Service type
  75. LPCTSTR szNodeName : Node name
  76. Return Value:
  77. N/A
  78. --*/
  79. : CIISMBNode(pOwner, szNodeName),
  80. m_pService(pService),
  81. m_bstrDisplayName(szNodeName),
  82. m_fResolved(FALSE),
  83. //
  84. // Default Data
  85. //
  86. m_fEnabledApplication(FALSE),
  87. m_dwWin32Error(ERROR_SUCCESS)
  88. {
  89. ASSERT_PTR(m_pService);
  90. }
  91. CIISDirectory::CIISDirectory(
  92. CIISMachine * pOwner,
  93. CIISService * pService,
  94. LPCTSTR szNodeName,
  95. BOOL fEnabledApplication,
  96. DWORD dwWin32Error,
  97. LPCTSTR strRedirPath
  98. )
  99. /*++
  100. Routine Description:
  101. Constructor that takes full information
  102. Arguments:
  103. CIISMachine * pOwner : Owner machine
  104. CIISService * pService : Service type
  105. LPCTSTR szNodeName : Node name
  106. Return Value:
  107. N/A
  108. --*/
  109. : CIISMBNode(pOwner, szNodeName),
  110. m_pService(pService),
  111. m_bstrDisplayName(szNodeName),
  112. m_fResolved(TRUE),
  113. //
  114. // Data
  115. //
  116. m_fEnabledApplication(fEnabledApplication),
  117. m_dwWin32Error(dwWin32Error)
  118. {
  119. m_strRedirectPath = strRedirPath;
  120. ASSERT_PTR(m_pService);
  121. }
  122. /* virtual */
  123. CIISDirectory::~CIISDirectory()
  124. /*++
  125. Routine Description:
  126. Destructor
  127. Arguments:
  128. N/A
  129. Return Value:
  130. N/A
  131. --*/
  132. {
  133. }
  134. /* virtual */
  135. HRESULT
  136. CIISDirectory::RefreshData()
  137. /*++
  138. Routine Description:
  139. Refresh relevant configuration data required for display.
  140. Arguments:
  141. None
  142. Return Value:
  143. HRESULT
  144. --*/
  145. {
  146. CError err;
  147. CWaitCursor wait;
  148. CComBSTR bstrPath;
  149. CMetaKey * pKey = NULL;
  150. do
  151. {
  152. ASSERT_PTR(_lpConsoleNameSpace);
  153. err = BuildMetaPath(bstrPath);
  154. BREAK_ON_ERR_FAILURE(err)
  155. BOOL fContinue = TRUE;
  156. while (fContinue)
  157. {
  158. fContinue = FALSE;
  159. pKey = new CMetaKey(QueryInterface(), bstrPath);
  160. if (!pKey)
  161. {
  162. TRACEEOLID("RefreshData: OOM");
  163. err = ERROR_NOT_ENOUGH_MEMORY;
  164. break;
  165. }
  166. err = pKey->QueryResult();
  167. if (IsLostInterface(err))
  168. {
  169. SAFE_DELETE(pKey);
  170. fContinue = OnLostInterface(err);
  171. }
  172. }
  173. BREAK_ON_ERR_FAILURE(err)
  174. CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
  175. err = child.LoadData();
  176. if (err.Failed())
  177. {
  178. //
  179. // Filter out the non-fatal errors
  180. //
  181. switch(err.Win32Error())
  182. {
  183. case ERROR_ACCESS_DENIED:
  184. case ERROR_FILE_NOT_FOUND:
  185. case ERROR_PATH_NOT_FOUND:
  186. err.Reset();
  187. break;
  188. default:
  189. TRACEEOLID("Fatal error occurred " << err);
  190. }
  191. }
  192. if (err.Succeeded())
  193. {
  194. m_dwWin32Error = child.QueryWin32Error();
  195. m_fEnabledApplication = child.IsEnabledApplication();
  196. }
  197. else
  198. {
  199. m_dwWin32Error = err.Win32Error();
  200. }
  201. if (!child.IsRedirected())
  202. {
  203. CString dir;
  204. CString alias;
  205. if (GetPhysicalPath(bstrPath, alias, dir))
  206. {
  207. m_bstrPath = dir;
  208. if (PathIsUNCServerShare(dir))
  209. {
  210. CString server, share;
  211. int idx = dir.ReverseFind(_T('\\'));
  212. ASSERT(idx != -1);
  213. server = dir.Left(idx);
  214. share = dir.Mid(++idx);
  215. LPBYTE pbuf = NULL;
  216. NET_API_STATUS rc = NetShareGetInfo((LPTSTR)(LPCTSTR)server, (LPTSTR)(LPCTSTR)share, 0, &pbuf);
  217. if (NERR_Success == rc)
  218. {
  219. NetApiBufferFree(pbuf);
  220. }
  221. else
  222. {
  223. m_dwWin32Error = ERROR_BAD_NETPATH;
  224. break;
  225. }
  226. }
  227. else if (!PathIsDirectory(dir))
  228. {
  229. m_dwWin32Error = ERROR_PATH_NOT_FOUND;
  230. break;
  231. }
  232. }
  233. }
  234. }
  235. while(FALSE);
  236. SAFE_DELETE(pKey);
  237. if (m_dwWin32Error == ERROR_SUCCESS)
  238. {
  239. m_dwWin32Error = err.Win32Error();
  240. }
  241. return err;
  242. }
  243. /* virtual */
  244. HRESULT
  245. CIISDirectory::EnumerateScopePane(HSCOPEITEM hParent)
  246. /*++
  247. Routine Description:
  248. Enumerate scope child items.
  249. Arguments:
  250. HSCOPEITEM hParent : Parent console handle
  251. Return Value:
  252. HRESULT
  253. --*/
  254. {
  255. CError err = EnumerateVDirs(hParent, m_pService);
  256. if (err.Succeeded() && IsWebDir() && m_strRedirectPath.IsEmpty())
  257. {
  258. if (m_dwWin32Error == ERROR_SUCCESS)
  259. {
  260. err = EnumerateWebDirs(hParent, m_pService);
  261. }
  262. }
  263. if (err.Failed())
  264. {
  265. m_dwWin32Error = err.Win32Error();
  266. RefreshDisplay();
  267. }
  268. return err;
  269. }
  270. /* virtual */
  271. int
  272. CIISDirectory::QueryImage() const
  273. /*++
  274. Routine Description:
  275. Return bitmap index for the site
  276. Arguments:
  277. None
  278. Return Value:
  279. Bitmap index
  280. --*/
  281. {
  282. ASSERT_PTR(m_pService);
  283. if (!m_fResolved)
  284. {
  285. if (m_hScopeItem == NULL)
  286. {
  287. return iError;
  288. }
  289. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  290. CIISDirectory * that = (CIISDirectory *)this;
  291. CError err = that->RefreshData();
  292. that->m_fResolved = err.Succeeded();
  293. }
  294. if (m_dwWin32Error || !m_pService)
  295. {
  296. return iError;
  297. }
  298. return IsEnabledApplication()
  299. ? iApplication : m_pService->QueryVDirImage();
  300. }
  301. void
  302. CIISDirectory::InitializeChildHeaders(LPHEADERCTRL lpHeader)
  303. {
  304. CIISDirectory::InitializeHeaders(lpHeader);
  305. }
  306. /* static */
  307. void
  308. CIISDirectory::InitializeHeaders(LPHEADERCTRL lpHeader)
  309. {
  310. CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
  311. // if (!_fStaticsLoaded)
  312. // {
  313. // _fStaticsLoaded =
  314. // _bstrName.LoadString(IDS_RESULT_NAME) &&
  315. // _bstrPath.LoadString(IDS_RESULT_PATH);
  316. // }
  317. }
  318. /* virtual */
  319. LPOLESTR
  320. CIISDirectory::GetResultPaneColInfo(int nCol)
  321. /*++
  322. Routine Description:
  323. Return result pane string for the given column number
  324. Arguments:
  325. int nCol : Column number
  326. Return Value:
  327. String
  328. --*/
  329. {
  330. switch(nCol)
  331. {
  332. case COL_ALIAS:
  333. return QueryDisplayName();
  334. case COL_PATH:
  335. if (!m_strRedirectPath.IsEmpty())
  336. {
  337. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  338. CString buf;
  339. buf.Format(IDS_REDIRECT_FORMAT, m_strRedirectPath);
  340. return (LPOLESTR)(LPCTSTR)buf;
  341. }
  342. if (m_bstrPath.Length() == 0)
  343. {
  344. CComBSTR mp;
  345. BuildMetaPath(mp);
  346. CString name, pp;
  347. GetPhysicalPath(mp, name, pp);
  348. m_bstrPath = pp;
  349. }
  350. return m_bstrPath;
  351. case COL_STATUS:
  352. {
  353. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  354. CError err(m_dwWin32Error);
  355. if (err.Succeeded())
  356. {
  357. return OLESTR("");
  358. }
  359. _bstrResult = err;
  360. return _bstrResult;
  361. }
  362. }
  363. TRACEEOLID("CIISDirectory: Bad column number" << nCol);
  364. return OLESTR("");
  365. }
  366. /*virtual*/
  367. HRESULT
  368. CIISDirectory::AddMenuItems(
  369. LPCONTEXTMENUCALLBACK piCallback,
  370. long * pInsertionAllowed,
  371. DATA_OBJECT_TYPES type
  372. )
  373. {
  374. ASSERT_READ_PTR(piCallback);
  375. //
  376. // Add base menu items
  377. //
  378. HRESULT hr = CIISObject::AddMenuItems(
  379. piCallback,
  380. pInsertionAllowed,
  381. type
  382. );
  383. if (SUCCEEDED(hr))
  384. {
  385. ASSERT(pInsertionAllowed != NULL);
  386. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
  387. {
  388. AddMenuSeparator(piCallback);
  389. if (IsFtpDir())
  390. {
  391. AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
  392. }
  393. else if (IsWebDir())
  394. {
  395. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
  396. }
  397. }
  398. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0)
  399. {
  400. AddMenuSeparator(piCallback);
  401. AddMenuItemByCommand(piCallback, IDM_TASK_SECURITY_WIZARD);
  402. }
  403. }
  404. return hr;
  405. }
  406. HRESULT
  407. CIISDirectory::InsertNewAlias(CString alias)
  408. {
  409. CError err;
  410. // Now we should insert and select this new site
  411. CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
  412. if (pAlias != NULL)
  413. {
  414. // If item is not expanded we will get error and no effect
  415. if (!IsExpanded())
  416. {
  417. SelectScopeItem();
  418. IConsoleNameSpace2 * pConsole
  419. = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  420. pConsole->Expand(QueryScopeItem());
  421. }
  422. err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
  423. if (err.Succeeded())
  424. {
  425. VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
  426. }
  427. }
  428. else
  429. {
  430. err = ERROR_NOT_ENOUGH_MEMORY;
  431. }
  432. return err;
  433. }
  434. /* virtual */
  435. HRESULT
  436. CIISDirectory::Command(
  437. IN long lCommandID,
  438. IN CSnapInObjectRootBase * pObj,
  439. IN DATA_OBJECT_TYPES type
  440. )
  441. /*++
  442. Routine Description:
  443. Handle command from context menu.
  444. Arguments:
  445. long lCommandID : Command ID
  446. CSnapInObjectRootBase * pObj : Base object
  447. DATA_OBJECT_TYPES type : Data object type
  448. Return Value:
  449. HRESULT
  450. --*/
  451. {
  452. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  453. HRESULT hr = S_OK;
  454. CString alias;
  455. switch (lCommandID)
  456. {
  457. case IDM_NEW_FTP_VDIR:
  458. if (SUCCEEDED(hr = CIISMBNode::AddFTPVDir(pObj, type, alias)))
  459. {
  460. hr = InsertNewAlias(alias);
  461. }
  462. break;
  463. case IDM_NEW_WEB_VDIR:
  464. if (SUCCEEDED(hr = CIISMBNode::AddWebVDir(pObj, type, alias)))
  465. {
  466. hr = InsertNewAlias(alias);
  467. }
  468. break;
  469. //
  470. // Pass on to base class
  471. //
  472. default:
  473. hr = CIISMBNode::Command(lCommandID, pObj, type);
  474. }
  475. return hr;
  476. }
  477. /* virtual */
  478. HRESULT
  479. CIISDirectory::CreatePropertyPages(
  480. IN LPPROPERTYSHEETCALLBACK lpProvider,
  481. IN LONG_PTR handle,
  482. IN IUnknown * pUnk,
  483. IN DATA_OBJECT_TYPES type
  484. )
  485. /*++
  486. Routine Description:
  487. Create the property pages for the given object
  488. Arguments:
  489. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  490. LONG_PTR handle : Handle.
  491. IUnknown * pUnk,
  492. DATA_OBJECT_TYPES type
  493. Return Value:
  494. HRESULT
  495. --*/
  496. {
  497. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  498. CComBSTR bstrPath;
  499. //
  500. // CODEWORK: What to do with m_err? This might be
  501. // a bad machine object in the first place. Aborting
  502. // when the machine object has an error code isn't
  503. // such a bad solution here.
  504. //
  505. /*
  506. if (m_err.Failed())
  507. {
  508. m_err.MessageBox();
  509. return m_err;
  510. }
  511. */
  512. CError err(BuildMetaPath(bstrPath));
  513. if (err.Succeeded())
  514. {
  515. err = ShowPropertiesDlg(
  516. lpProvider,
  517. QueryAuthInfo(),
  518. bstrPath,
  519. GetMainWindow(),
  520. (LPARAM)this,
  521. handle
  522. );
  523. }
  524. err.MessageBoxOnFailure();
  525. return err;
  526. }
  527. ///////////////////////////////////////////////////////////////////
  528. CIISFileName::CIISFileName(
  529. CIISMachine * pOwner,
  530. CIISService * pService,
  531. const DWORD dwAttributes,
  532. LPCTSTR alias,
  533. LPCTSTR redirect
  534. )
  535. : CIISMBNode(pOwner, alias),
  536. m_dwAttribute(dwAttributes),
  537. m_pService(pService),
  538. m_bstrFileName(alias),
  539. m_RedirectString(redirect),
  540. m_fEnabledApplication(FALSE),
  541. m_dwWin32Error(0),
  542. m_fResolved(FALSE)
  543. {
  544. }
  545. /* virtual */
  546. LPOLESTR
  547. CIISFileName::GetResultPaneColInfo(int nCol)
  548. /*++
  549. Routine Description:
  550. Return result pane string for the given column number
  551. Arguments:
  552. int nCol : Column number
  553. Return Value:
  554. String
  555. --*/
  556. {
  557. switch(nCol)
  558. {
  559. case COL_ALIAS:
  560. return QueryDisplayName();
  561. case COL_PATH:
  562. return OLESTR("");
  563. case COL_STATUS:
  564. {
  565. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  566. CError err(m_dwWin32Error);
  567. if (err.Succeeded())
  568. {
  569. return OLESTR("");
  570. }
  571. _bstrResult = err;
  572. return _bstrResult;
  573. }
  574. }
  575. TRACEEOLID("CIISFileName: Bad column number" << nCol);
  576. return OLESTR("");
  577. }
  578. void
  579. CIISFileName::InitializeChildHeaders(LPHEADERCTRL lpHeader)
  580. {
  581. CIISDirectory::InitializeHeaders(lpHeader);
  582. }
  583. /* virtual */
  584. HRESULT
  585. CIISFileName::EnumerateScopePane(
  586. IN HSCOPEITEM hParent
  587. )
  588. /*++
  589. Routine Description:
  590. Enumerate scope child items.
  591. Arguments:
  592. HSCOPEITEM hParent : Parent console handle
  593. Return Value:
  594. HRESULT
  595. --*/
  596. {
  597. return EnumerateWebDirs(hParent, m_pService);
  598. }
  599. /* virtual */
  600. int
  601. CIISFileName::QueryImage() const
  602. {
  603. ASSERT_PTR(m_pService);
  604. if (!m_fResolved)
  605. {
  606. if (m_hScopeItem == NULL)
  607. {
  608. TRACEEOLID("BUGBUG: Prematurely asked for display information");
  609. return MMC_IMAGECALLBACK;
  610. }
  611. //
  612. // Required for the wait cursor
  613. //
  614. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  615. CIISFileName * that = (CIISFileName *)this;
  616. CError err = that->RefreshData();
  617. that->m_fResolved = err.Succeeded();
  618. }
  619. if (m_dwWin32Error || !m_pService)
  620. {
  621. return iError;
  622. }
  623. if (IsDir())
  624. {
  625. return IsEnabledApplication() ? iApplication : iFolder;
  626. }
  627. return iFile;
  628. }
  629. HRESULT
  630. CIISFileName::DeleteNode(IResultData * pResult)
  631. {
  632. CString path;
  633. CComBSTR root;
  634. BuildMetaPath(root);
  635. CString physPath, alias;
  636. GetPhysicalPath(CString(root), alias, physPath);
  637. physPath.TrimRight(_T("/"));
  638. if (m_pService->IsLocal() || PathIsUNC(physPath))
  639. {
  640. //
  641. // Local directory, or already a unc path
  642. //
  643. path = physPath;
  644. }
  645. else
  646. {
  647. ::MakeUNCPath(path, m_pService->QueryMachineName(), physPath);
  648. }
  649. LPTSTR p = path.GetBuffer(MAX_PATH);
  650. PathRemoveBlanks(p);
  651. PathRemoveBackslash(p);
  652. path += _T('\0');
  653. TRACEEOLID("Attempting to remove file/directory: " << path);
  654. CWnd * pWnd = AfxGetMainWnd();
  655. //
  656. // Attempt to delete using shell APIs
  657. //
  658. SHFILEOPSTRUCT sos;
  659. ZeroMemory(&sos, sizeof(sos));
  660. sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
  661. sos.wFunc = FO_DELETE;
  662. sos.pFrom = path;
  663. sos.fFlags = FOF_ALLOWUNDO;
  664. CError err;
  665. // Use assignment to avoid conversion and wrong constructor call
  666. err = ::SHFileOperation(&sos);
  667. if (err.Succeeded() && !sos.fAnyOperationsAborted)
  668. {
  669. CComBSTR p;
  670. CMetaInterface * pInterface = QueryInterface();
  671. ASSERT(pInterface != NULL);
  672. err = BuildMetaPath(p);
  673. if (err.Succeeded())
  674. {
  675. CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
  676. if (mk.Succeeded())
  677. {
  678. err = mk.DeleteKey(p);
  679. }
  680. }
  681. if (IsDir())
  682. {
  683. err = RemoveScopeItem();
  684. }
  685. else
  686. {
  687. CIISMBNode * pParent = GetParentNode();
  688. ASSERT(pParent != NULL);
  689. err = pParent->RemoveResultNode(this, pResult);
  690. }
  691. }
  692. if (err.Failed())
  693. {
  694. DisplayError(err);
  695. }
  696. path.ReleaseBuffer();
  697. return err;
  698. }
  699. HRESULT
  700. CIISFileName::RenameItem(LPOLESTR new_name)
  701. {
  702. if (new_name == NULL || lstrlen(new_name) == 0)
  703. {
  704. return S_OK;
  705. }
  706. CString pathFrom, pathTo;
  707. CComBSTR root;
  708. BuildMetaPath(root);
  709. CString physPath, alias;
  710. GetPhysicalPath(CString(root), alias, physPath);
  711. physPath.TrimRight(_T("/"));
  712. if (m_pService->IsLocal() || PathIsUNC(physPath))
  713. {
  714. //
  715. // Local directory, or already a unc path
  716. //
  717. pathFrom = physPath;
  718. }
  719. else
  720. {
  721. ::MakeUNCPath(pathFrom, m_pService->QueryMachineName(), physPath);
  722. }
  723. LPTSTR p = pathFrom.GetBuffer(MAX_PATH);
  724. PathRemoveBlanks(p);
  725. PathRemoveBackslash(p);
  726. pathFrom.ReleaseBuffer();
  727. pathFrom += _T('\0');
  728. pathTo = pathFrom;
  729. p = pathTo.GetBuffer(MAX_PATH);
  730. PathRemoveFileSpec(p);
  731. PathAppend(p, new_name);
  732. pathTo.ReleaseBuffer();
  733. pathTo += _T('\0');
  734. CWnd * pWnd = AfxGetMainWnd();
  735. //
  736. // Attempt to delete using shell APIs
  737. //
  738. SHFILEOPSTRUCT sos;
  739. ZeroMemory(&sos, sizeof(sos));
  740. sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
  741. sos.wFunc = FO_RENAME;
  742. sos.pFrom = pathFrom;
  743. sos.pTo = pathTo;
  744. sos.fFlags = FOF_ALLOWUNDO;
  745. CError err;
  746. // Use assignment to avoid conversion and wrong constructor call
  747. err = ::SHFileOperation(&sos);
  748. if (err.Succeeded() && !sos.fAnyOperationsAborted)
  749. {
  750. CComQIPtr<IResultData, &IID_IResultData> lpResultData(_lpConsole);
  751. m_bstrFileName = new_name;
  752. err = lpResultData->UpdateItem(m_hResultItem);
  753. m_bstrNode = new_name;
  754. }
  755. return err;
  756. }
  757. /* virtual */
  758. HRESULT
  759. CIISFileName::RefreshData()
  760. /*++
  761. Routine Description:
  762. Refresh relevant configuration data required for display.
  763. Arguments:
  764. None
  765. Return Value:
  766. HRESULT
  767. --*/
  768. {
  769. CError err;
  770. CWaitCursor wait;
  771. CComBSTR bstrPath;
  772. CMetaKey * pKey = NULL;
  773. do
  774. {
  775. ASSERT_PTR(_lpConsoleNameSpace);
  776. err = BuildMetaPath(bstrPath);
  777. if (err.Failed())
  778. {
  779. break;
  780. }
  781. BOOL fContinue = TRUE;
  782. while (fContinue)
  783. {
  784. fContinue = FALSE;
  785. pKey = new CMetaKey(QueryInterface(), bstrPath);
  786. if (!pKey)
  787. {
  788. TRACEEOLID("RefreshData: OOM");
  789. err = ERROR_NOT_ENOUGH_MEMORY;
  790. break;
  791. }
  792. err = pKey->QueryResult();
  793. if (IsLostInterface(err))
  794. {
  795. SAFE_DELETE(pKey);
  796. fContinue = OnLostInterface(err);
  797. }
  798. }
  799. if (err.Succeeded())
  800. {
  801. CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
  802. err = child.LoadData();
  803. if (err.Succeeded())
  804. {
  805. m_dwWin32Error = child.QueryWin32Error();
  806. CString buf = child.m_strAppRoot;
  807. m_fEnabledApplication = (buf.CompareNoCase(bstrPath) == 0);
  808. }
  809. else
  810. {
  811. m_dwWin32Error = err.Win32Error();
  812. }
  813. }
  814. if (err.Failed())
  815. {
  816. //
  817. // Filter out the non-fatal errors
  818. //
  819. switch(err.Win32Error())
  820. {
  821. case ERROR_ACCESS_DENIED:
  822. case ERROR_FILE_NOT_FOUND:
  823. case ERROR_PATH_NOT_FOUND:
  824. err.Reset();
  825. break;
  826. default:
  827. TRACEEOLID("Fatal error occurred " << err);
  828. }
  829. }
  830. }
  831. while(FALSE);
  832. SAFE_DELETE(pKey);
  833. if (SUCCEEDED(m_dwWin32Error))
  834. {
  835. m_dwWin32Error = err.Win32Error();
  836. }
  837. ASSERT(err.Succeeded());
  838. return err;
  839. }
  840. /*virtual*/
  841. HRESULT
  842. CIISFileName::AddMenuItems(
  843. LPCONTEXTMENUCALLBACK piCallback,
  844. long * pInsertionAllowed,
  845. DATA_OBJECT_TYPES type
  846. )
  847. {
  848. ASSERT_READ_PTR(piCallback);
  849. //
  850. // Add base menu items
  851. //
  852. HRESULT hr = CIISObject::AddMenuItems(
  853. piCallback,
  854. pInsertionAllowed,
  855. type
  856. );
  857. if (SUCCEEDED(hr))
  858. {
  859. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
  860. {
  861. AddMenuSeparator(piCallback);
  862. if (lstrcmpi(m_pService->QueryServiceName(), SZ_MBN_FTP) == 0)
  863. {
  864. AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
  865. }
  866. else if (lstrcmpi(m_pService->QueryServiceName(), SZ_MBN_WEB) == 0)
  867. {
  868. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
  869. }
  870. }
  871. ASSERT(pInsertionAllowed != NULL);
  872. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0)
  873. {
  874. AddMenuSeparator(piCallback);
  875. AddMenuItemByCommand(piCallback, IDM_TASK_SECURITY_WIZARD);
  876. }
  877. }
  878. return hr;
  879. }
  880. /* virtual */
  881. HRESULT
  882. CIISFileName::Command(
  883. IN long lCommandID,
  884. IN CSnapInObjectRootBase * pObj,
  885. IN DATA_OBJECT_TYPES type
  886. )
  887. /*++
  888. Routine Description:
  889. Handle command from context menu.
  890. Arguments:
  891. long lCommandID : Command ID
  892. CSnapInObjectRootBase * pObj : Base object
  893. DATA_OBJECT_TYPES type : Data object type
  894. Return Value:
  895. HRESULT
  896. --*/
  897. {
  898. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  899. HRESULT hr = S_OK;
  900. CString alias;
  901. switch (lCommandID)
  902. {
  903. case IDM_NEW_FTP_VDIR:
  904. if (SUCCEEDED(hr = CIISMBNode::AddFTPVDir(pObj, type, alias)))
  905. {
  906. hr = InsertNewAlias(alias);
  907. }
  908. break;
  909. case IDM_NEW_WEB_VDIR:
  910. if (SUCCEEDED(hr = CIISMBNode::AddWebVDir(pObj, type, alias)))
  911. {
  912. hr = InsertNewAlias(alias);
  913. }
  914. break;
  915. case IDM_BROWSE:
  916. if (m_hResultItem != 0)
  917. {
  918. BuildURL(m_bstrURL);
  919. if (m_bstrURL.Length())
  920. {
  921. ShellExecute(GetMainWindow()->m_hWnd, _T("open"), m_bstrURL, NULL, NULL, SW_SHOWNORMAL);
  922. }
  923. }
  924. else
  925. {
  926. hr = CIISMBNode::Command(lCommandID, pObj, type);
  927. }
  928. break;
  929. //
  930. // Pass on to base class
  931. //
  932. default:
  933. hr = CIISMBNode::Command(lCommandID, pObj, type);
  934. }
  935. ASSERT(SUCCEEDED(hr));
  936. return hr;
  937. }
  938. HRESULT
  939. CIISFileName::InsertNewAlias(CString alias)
  940. {
  941. CError err;
  942. // Now we should insert and select this new site
  943. CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
  944. if (pAlias != NULL)
  945. {
  946. // If item is not expanded we will get error and no effect
  947. if (!IsExpanded())
  948. {
  949. SelectScopeItem();
  950. IConsoleNameSpace2 * pConsole
  951. = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  952. pConsole->Expand(QueryScopeItem());
  953. }
  954. err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
  955. if (err.Succeeded())
  956. {
  957. VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
  958. }
  959. }
  960. else
  961. {
  962. err = ERROR_NOT_ENOUGH_MEMORY;
  963. }
  964. return err;
  965. }
  966. /* virtual */
  967. HRESULT
  968. CIISFileName::CreatePropertyPages(
  969. IN LPPROPERTYSHEETCALLBACK lpProvider,
  970. IN LONG_PTR handle,
  971. IN IUnknown * pUnk,
  972. IN DATA_OBJECT_TYPES type
  973. )
  974. /*++
  975. Routine Description:
  976. Create the property pages for the given object
  977. Arguments:
  978. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  979. LONG_PTR handle : Handle.
  980. IUnknown * pUnk,
  981. DATA_OBJECT_TYPES type
  982. Return Value:
  983. HRESULT
  984. --*/
  985. {
  986. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  987. CComBSTR bstrPath;
  988. CError err(BuildMetaPath(bstrPath));
  989. if (err.Succeeded())
  990. {
  991. if (IsDir())
  992. {
  993. err = ShowDirPropertiesDlg(
  994. lpProvider,
  995. QueryAuthInfo(),
  996. bstrPath,
  997. GetMainWindow(),
  998. (LPARAM)this,
  999. handle
  1000. );
  1001. }
  1002. else
  1003. {
  1004. err = ShowFilePropertiesDlg(
  1005. lpProvider,
  1006. QueryAuthInfo(),
  1007. bstrPath,
  1008. GetMainWindow(),
  1009. (LPARAM)this,
  1010. handle
  1011. );
  1012. }
  1013. }
  1014. err.MessageBoxOnFailure();
  1015. return err;
  1016. }
  1017. HRESULT
  1018. CIISFileName::ShowDirPropertiesDlg(
  1019. LPPROPERTYSHEETCALLBACK lpProvider,
  1020. CComAuthInfo * pAuthInfo,
  1021. LPCTSTR lpszMDPath,
  1022. CWnd * pMainWnd,
  1023. LPARAM lParam,
  1024. LONG_PTR handle
  1025. )
  1026. {
  1027. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1028. ASSERT_PTR(lpProvider);
  1029. CError err;
  1030. CW3Sheet * pSheet = new CW3Sheet(
  1031. pAuthInfo,
  1032. lpszMDPath,
  1033. 0,
  1034. pMainWnd,
  1035. lParam,
  1036. handle
  1037. );
  1038. if (pSheet)
  1039. {
  1040. pSheet->SetModeless();
  1041. //
  1042. // Add file pages
  1043. //
  1044. pSheet->SetSheetType(pSheet->SHEET_TYPE_DIR);
  1045. err = AddMMCPage(lpProvider, new CW3DirPage(pSheet));
  1046. err = AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  1047. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, FILE_ATTRIBUTE_DIRECTORY));
  1048. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1049. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1050. }
  1051. else
  1052. {
  1053. err = ERROR_NOT_ENOUGH_MEMORY;
  1054. }
  1055. return err;
  1056. }
  1057. HRESULT
  1058. CIISFileName::ShowFilePropertiesDlg(
  1059. LPPROPERTYSHEETCALLBACK lpProvider,
  1060. CComAuthInfo * pAuthInfo,
  1061. LPCTSTR lpszMDPath,
  1062. CWnd * pMainWnd,
  1063. LPARAM lParam,
  1064. LONG_PTR handle
  1065. )
  1066. {
  1067. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1068. ASSERT_PTR(lpProvider);
  1069. CError err;
  1070. CW3Sheet * pSheet = new CW3Sheet(
  1071. pAuthInfo,
  1072. lpszMDPath,
  1073. 0,
  1074. pMainWnd,
  1075. lParam,
  1076. handle
  1077. );
  1078. if (pSheet)
  1079. {
  1080. pSheet->SetModeless();
  1081. //
  1082. // Add file pages
  1083. //
  1084. pSheet->SetSheetType(pSheet->SHEET_TYPE_FILE);
  1085. err = AddMMCPage(lpProvider, new CW3FilePage(pSheet));
  1086. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, 0));
  1087. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1088. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1089. }
  1090. else
  1091. {
  1092. err = ERROR_NOT_ENOUGH_MEMORY;
  1093. }
  1094. return err;
  1095. }
  1096. HRESULT
  1097. CIISFileName::OnPropertyChange(BOOL fScope, IResultData * pResult)
  1098. {
  1099. CError err;
  1100. // We cannot change anything visible in file
  1101. if (IsDir())
  1102. {
  1103. // We cannot change path, therefore we don't need to reenumerate
  1104. err = Refresh(FALSE);
  1105. }
  1106. return err;
  1107. }