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.

1830 lines
45 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 "tracker.h"
  32. #include <lm.h>
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37. #define new DEBUG_NEW
  38. extern CPropertySheetTracker g_OpenPropertySheetTracker;
  39. //
  40. // CIISDirectory Implementation
  41. //
  42. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  43. //
  44. // Site Result View definition
  45. //
  46. /* static */ int
  47. CIISDirectory::_rgnLabels[COL_TOTAL] =
  48. {
  49. IDS_RESULT_NAME,
  50. IDS_RESULT_PATH,
  51. IDS_RESULT_STATUS,
  52. };
  53. /* static */ int
  54. CIISDirectory::_rgnWidths[COL_TOTAL] =
  55. {
  56. 180,
  57. 200,
  58. 200,
  59. };
  60. #if 0
  61. /* static */ CComBSTR CIISDirectory::_bstrName;
  62. /* static */ CComBSTR CIISDirectory::_bstrPath;
  63. /* static */ BOOL CIISDirectory::_fStaticsLoaded = FALSE;
  64. #endif
  65. CIISDirectory::CIISDirectory(
  66. IN CIISMachine * pOwner,
  67. IN CIISService * pService,
  68. IN LPCTSTR szNodeName
  69. )
  70. /*++
  71. Routine Description:
  72. Constructor which does not resolve all display information at
  73. construction time.
  74. Arguments:
  75. CIISMachine * pOwner : Owner machine
  76. CIISService * pService : Service type
  77. LPCTSTR szNodeName : Node name
  78. Return Value:
  79. N/A
  80. --*/
  81. : CIISMBNode(pOwner, szNodeName),
  82. m_pService(pService),
  83. m_bstrDisplayName(szNodeName),
  84. m_fResolved(FALSE),
  85. //
  86. // Default Data
  87. //
  88. m_fEnabledApplication(FALSE),
  89. m_dwWin32Error(ERROR_SUCCESS),
  90. m_dwEnumError(ERROR_SUCCESS)
  91. {
  92. ASSERT_PTR(m_pService);
  93. m_pService->AddRef();
  94. }
  95. CIISDirectory::CIISDirectory(
  96. CIISMachine * pOwner,
  97. CIISService * pService,
  98. LPCTSTR szNodeName,
  99. BOOL fEnabledApplication,
  100. DWORD dwWin32Error,
  101. LPCTSTR strRedirPath
  102. )
  103. /*++
  104. Routine Description:
  105. Constructor that takes full information
  106. Arguments:
  107. CIISMachine * pOwner : Owner machine
  108. CIISService * pService : Service type
  109. LPCTSTR szNodeName : Node name
  110. Return Value:
  111. N/A
  112. --*/
  113. : CIISMBNode(pOwner, szNodeName),
  114. m_pService(pService),
  115. m_bstrDisplayName(szNodeName),
  116. m_fResolved(TRUE),
  117. //
  118. // Data
  119. //
  120. m_fEnabledApplication(fEnabledApplication),
  121. m_dwWin32Error(dwWin32Error),
  122. m_dwEnumError(ERROR_SUCCESS)
  123. {
  124. m_strRedirectPath = strRedirPath;
  125. ASSERT_PTR(m_pService);
  126. m_pService->AddRef();
  127. }
  128. /* virtual */
  129. CIISDirectory::~CIISDirectory()
  130. {
  131. m_pService->Release();
  132. }
  133. /* virtual */
  134. HRESULT
  135. CIISDirectory::RefreshData()
  136. /*++
  137. Refresh relevant configuration data required for display.
  138. --*/
  139. {
  140. CError err;
  141. CWaitCursor wait;
  142. CComBSTR bstrPath;
  143. CMetaKey * pKey = NULL;
  144. do
  145. {
  146. err = BuildMetaPath(bstrPath);
  147. BREAK_ON_ERR_FAILURE(err)
  148. BOOL fContinue = TRUE;
  149. while (fContinue)
  150. {
  151. fContinue = FALSE;
  152. pKey = new CMetaKey(QueryInterface(), bstrPath);
  153. if (!pKey)
  154. {
  155. TRACEEOLID("RefreshData: OOM");
  156. err = ERROR_NOT_ENOUGH_MEMORY;
  157. break;
  158. }
  159. err = pKey->QueryResult();
  160. if (IsLostInterface(err))
  161. {
  162. SAFE_DELETE(pKey);
  163. fContinue = OnLostInterface(err);
  164. }
  165. else
  166. {
  167. // reset error if an other error other than No interface
  168. err.Reset();
  169. }
  170. }
  171. BREAK_ON_ERR_FAILURE(err)
  172. CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
  173. err = child.LoadData();
  174. if (err.Failed())
  175. {
  176. //
  177. // Filter out the non-fatal errors
  178. //
  179. switch(err.Win32Error())
  180. {
  181. case ERROR_ACCESS_DENIED:
  182. case ERROR_FILE_NOT_FOUND:
  183. case ERROR_PATH_NOT_FOUND:
  184. err.Reset();
  185. break;
  186. default:
  187. TRACEEOLID("Fatal error occurred " << err);
  188. }
  189. }
  190. m_dwWin32Error = child.QueryWin32Error();
  191. m_fEnabledApplication = child.IsEnabledApplication();
  192. if (!child.IsRedirected())
  193. {
  194. CString dir;
  195. CString alias;
  196. if (GetPhysicalPath(bstrPath, alias, dir))
  197. {
  198. m_bstrPath = dir;
  199. if (PathIsUNCServerShare(dir))
  200. {
  201. if (FALSE == DoesUNCShareExist(dir))
  202. {
  203. err = ERROR_BAD_NETPATH;
  204. break;
  205. }
  206. }
  207. else if (!PathIsDirectory(dir))
  208. {
  209. err = ERROR_PATH_NOT_FOUND;
  210. break;
  211. }
  212. }
  213. m_strRedirectPath.Empty();
  214. }
  215. else
  216. {
  217. m_strRedirectPath = child.GetRedirectedPath();
  218. }
  219. }
  220. while(FALSE);
  221. SAFE_DELETE(pKey);
  222. m_dwEnumError = err.Win32Error();
  223. return err;
  224. }
  225. /* virtual */
  226. HRESULT
  227. CIISDirectory::EnumerateScopePane(HSCOPEITEM hParent)
  228. {
  229. CError err = EnumerateVDirs(hParent, m_pService);
  230. if (err.Succeeded() && IsWebDir() && m_strRedirectPath.IsEmpty())
  231. {
  232. if (m_dwEnumError == ERROR_SUCCESS)
  233. {
  234. err = EnumerateWebDirs(hParent, m_pService);
  235. }
  236. }
  237. if (err.Failed())
  238. {
  239. m_dwEnumError = err.Win32Error();
  240. RefreshDisplay();
  241. }
  242. return err;
  243. }
  244. /* virtual */
  245. int
  246. CIISDirectory::QueryImage() const
  247. /*++
  248. Routine Description:
  249. Return bitmap index for the site
  250. Arguments:
  251. None
  252. Return Value:
  253. Bitmap index
  254. --*/
  255. {
  256. ASSERT_PTR(m_pService);
  257. if (!m_fResolved)
  258. {
  259. if (m_hScopeItem == NULL)
  260. {
  261. return iError;
  262. }
  263. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  264. CIISDirectory * that = (CIISDirectory *)this;
  265. CError err = that->RefreshData();
  266. that->m_fResolved = err.Succeeded();
  267. }
  268. if (!m_pService)
  269. {
  270. return iError;
  271. }
  272. if (IsEnabledApplication())
  273. {
  274. return SUCCEEDED(m_dwWin32Error) ? iApplication : iApplicationErr;
  275. }
  276. else
  277. {
  278. return SUCCEEDED(m_dwWin32Error) ?
  279. m_pService->QueryVDirImage() : m_pService->QueryVDirImageErr();
  280. }
  281. }
  282. void
  283. CIISDirectory::InitializeChildHeaders(LPHEADERCTRL lpHeader)
  284. {
  285. CIISDirectory::InitializeHeaders(lpHeader);
  286. }
  287. /* static */
  288. void
  289. CIISDirectory::InitializeHeaders(LPHEADERCTRL lpHeader)
  290. {
  291. CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
  292. }
  293. /* virtual */
  294. LPOLESTR
  295. CIISDirectory::GetResultPaneColInfo(int nCol)
  296. /*++
  297. Routine Description:
  298. Return result pane string for the given column number
  299. Arguments:
  300. int nCol : Column number
  301. Return Value:
  302. String
  303. --*/
  304. {
  305. switch(nCol)
  306. {
  307. case COL_ALIAS:
  308. return QueryDisplayName();
  309. case COL_PATH:
  310. if (!m_strRedirectPath.IsEmpty())
  311. {
  312. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  313. CString buf;
  314. buf.Format(IDS_REDIRECT_FORMAT, m_strRedirectPath);
  315. _bstrRedirectPathBuf = buf;
  316. return _bstrRedirectPathBuf;
  317. }
  318. if (m_bstrPath.Length() == 0)
  319. {
  320. CComBSTR mp;
  321. BuildMetaPath(mp);
  322. CString name, pp;
  323. GetPhysicalPath(mp, name, pp);
  324. m_bstrPath = pp;
  325. }
  326. return m_bstrPath;
  327. case COL_STATUS:
  328. {
  329. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  330. CError err(m_dwWin32Error);
  331. if (err.Succeeded())
  332. {
  333. return OLESTR("");
  334. }
  335. _bstrResult = err;
  336. return _bstrResult;
  337. }
  338. }
  339. TRACEEOLID("CIISDirectory: Bad column number" << nCol);
  340. return OLESTR("");
  341. }
  342. /*virtual*/
  343. HRESULT
  344. CIISDirectory::AddMenuItems(
  345. LPCONTEXTMENUCALLBACK piCallback,
  346. long * pInsertionAllowed,
  347. DATA_OBJECT_TYPES type
  348. )
  349. {
  350. ASSERT_READ_PTR(piCallback);
  351. //
  352. // Add base menu items
  353. //
  354. HRESULT hr = CIISObject::AddMenuItems(
  355. piCallback,
  356. pInsertionAllowed,
  357. type
  358. );
  359. if (SUCCEEDED(hr))
  360. {
  361. ASSERT(pInsertionAllowed != NULL);
  362. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
  363. {
  364. AddMenuSeparator(piCallback);
  365. if (IsFtpDir())
  366. {
  367. AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
  368. if (IsConfigImportExportable())
  369. {
  370. AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR_FROM_FILE);
  371. }
  372. }
  373. else if (IsWebDir())
  374. {
  375. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
  376. if (IsConfigImportExportable())
  377. {
  378. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR_FROM_FILE);
  379. }
  380. }
  381. }
  382. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0)
  383. {
  384. AddMenuSeparator(piCallback);
  385. if (IsConfigImportExportable())
  386. {
  387. AddMenuItemByCommand(piCallback, IDM_TASK_EXPORT_CONFIG_WIZARD);
  388. }
  389. }
  390. }
  391. return hr;
  392. }
  393. HRESULT
  394. CIISDirectory::InsertNewAlias(CString alias)
  395. {
  396. CError err;
  397. if (!IsExpanded())
  398. {
  399. SelectScopeItem();
  400. IConsoleNameSpace2 * pConsoleNameSpace
  401. = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  402. pConsoleNameSpace->Expand(QueryScopeItem());
  403. HSCOPEITEM hChildItem = NULL;
  404. LONG_PTR cookie;
  405. HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie);
  406. while(SUCCEEDED(hr) && hChildItem)
  407. {
  408. CIISObject * pItem = (CIISObject *)cookie;
  409. ASSERT_PTR(pItem);
  410. if (0 == alias.Compare(pItem->QueryDisplayName()))
  411. {
  412. pItem->SelectScopeItem();
  413. break;
  414. }
  415. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  416. }
  417. }
  418. else
  419. {
  420. // Now we should insert and select this new site
  421. CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
  422. if (pAlias != NULL)
  423. {
  424. pAlias->AddRef();
  425. err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
  426. if (err.Succeeded())
  427. {
  428. VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
  429. }
  430. else
  431. {
  432. pAlias->Release();
  433. }
  434. }
  435. else
  436. {
  437. err = ERROR_NOT_ENOUGH_MEMORY;
  438. }
  439. }
  440. return err;
  441. }
  442. /* virtual */
  443. HRESULT
  444. CIISDirectory::Command(
  445. IN long lCommandID,
  446. IN CSnapInObjectRootBase * pObj,
  447. IN DATA_OBJECT_TYPES type
  448. )
  449. /*++
  450. Routine Description:
  451. Handle command from context menu.
  452. Arguments:
  453. long lCommandID : Command ID
  454. CSnapInObjectRootBase * pObj : Base object
  455. DATA_OBJECT_TYPES type : Data object type
  456. Return Value:
  457. HRESULT
  458. --*/
  459. {
  460. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  461. HRESULT hr = S_OK;
  462. CString alias;
  463. CError err;
  464. CComBSTR bstrMetaPath;
  465. switch (lCommandID)
  466. {
  467. case IDM_NEW_FTP_VDIR:
  468. BuildMetaPath(bstrMetaPath);
  469. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  470. if (!IsLostInterface(err))
  471. {
  472. // reset error if an other error other than No interface
  473. err.Reset();
  474. }
  475. if (err.Succeeded())
  476. {
  477. hr = CIISMBNode::AddFTPVDir(pObj, type, alias);
  478. if (!alias.IsEmpty())
  479. {
  480. hr = InsertNewAlias(alias);
  481. }
  482. }
  483. break;
  484. case IDM_NEW_WEB_VDIR:
  485. BuildMetaPath(bstrMetaPath);
  486. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  487. if (!IsLostInterface(err))
  488. {
  489. // reset error if an other error other than No interface
  490. err.Reset();
  491. }
  492. if (err.Succeeded())
  493. {
  494. hr = CIISMBNode::AddWebVDir(pObj, type, alias,
  495. m_pOwner->QueryMajorVersion(), m_pOwner->QueryMinorVersion());
  496. if (!alias.IsEmpty())
  497. {
  498. hr = InsertNewAlias(alias);
  499. }
  500. }
  501. break;
  502. //
  503. // Pass on to base class
  504. //
  505. default:
  506. hr = CIISMBNode::Command(lCommandID, pObj, type);
  507. }
  508. return hr;
  509. }
  510. /* virtual */
  511. HRESULT
  512. CIISDirectory::CreatePropertyPages(
  513. LPPROPERTYSHEETCALLBACK lpProvider,
  514. LONG_PTR handle,
  515. IUnknown * pUnk,
  516. DATA_OBJECT_TYPES type
  517. )
  518. /*++
  519. Routine Description:
  520. Create the property pages for the given object
  521. Arguments:
  522. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  523. LONG_PTR handle : Handle.
  524. IUnknown * pUnk,
  525. DATA_OBJECT_TYPES type
  526. Return Value:
  527. HRESULT
  528. --*/
  529. {
  530. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  531. CError err;
  532. if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type)))
  533. {
  534. return S_OK;
  535. }
  536. if (ERROR_ALREADY_EXISTS == err.Win32Error())
  537. {
  538. return S_FALSE;
  539. }
  540. if (err.Succeeded())
  541. {
  542. CComBSTR bstrPath;
  543. //
  544. // CODEWORK: What to do with m_err? This might be
  545. // a bad machine object in the first place. Aborting
  546. // when the machine object has an error code isn't
  547. // such a bad solution here.
  548. //
  549. /*
  550. if (m_err.Failed())
  551. {
  552. m_err.MessageBox();
  553. return m_err;
  554. }
  555. */
  556. err = BuildMetaPath(bstrPath);
  557. if (err.Succeeded())
  558. {
  559. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
  560. if (!IsLostInterface(err))
  561. {
  562. // reset error if an other error other than No interface
  563. err.Reset();
  564. }
  565. if (err.Succeeded())
  566. {
  567. // cache handle for user in MMCPropertyChangeNotify
  568. m_ppHandle = handle;
  569. err = ShowPropertiesDlg(lpProvider, QueryAuthInfo(),
  570. bstrPath, GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(),handle);
  571. }
  572. }
  573. }
  574. err.MessageBoxOnFailure();
  575. return err;
  576. }
  577. HRESULT
  578. CIISDirectory::OnViewChange(BOOL fScope,
  579. IResultData * pResult, IHeaderCtrl * pHeader, DWORD hint)
  580. {
  581. // If there is win32 error set, we should clear it to enable web dirs enumeration again
  582. m_dwWin32Error = ERROR_SUCCESS;
  583. CError err = CIISMBNode::OnViewChange(fScope, pResult, pHeader, hint);
  584. // If parent node is selected, this node will be displayed on result
  585. // pane, we may need to update the status, path, etc
  586. if (err.Succeeded() && 0 != (hint & PROP_CHANGE_DISPLAY_ONLY))
  587. {
  588. // This is a VDir, so it's a scope only item....
  589. RefreshDisplay(FALSE);
  590. }
  591. return err;
  592. }
  593. ///////////////////////////////////////////////////////////////////
  594. CIISFileName::CIISFileName(
  595. CIISMachine * pOwner,
  596. CIISService * pService,
  597. const DWORD dwAttributes,
  598. LPCTSTR alias,
  599. LPCTSTR redirect
  600. )
  601. : CIISMBNode(pOwner, alias),
  602. m_dwAttribute(dwAttributes),
  603. m_pService(pService),
  604. m_bstrFileName(alias),
  605. m_RedirectString(redirect),
  606. m_fEnabledApplication(FALSE),
  607. m_dwWin32Error(0),
  608. m_dwEnumError(ERROR_SUCCESS),
  609. m_fResolved(FALSE)
  610. {
  611. ASSERT_PTR(pService);
  612. m_pService->AddRef();
  613. }
  614. /* virtual */
  615. LPOLESTR
  616. CIISFileName::GetResultPaneColInfo(int nCol)
  617. /*++
  618. Routine Description:
  619. Return result pane string for the given column number
  620. Arguments:
  621. int nCol : Column number
  622. Return Value:
  623. String
  624. --*/
  625. {
  626. switch(nCol)
  627. {
  628. case COL_ALIAS:
  629. return QueryDisplayName();
  630. case COL_PATH:
  631. if (!m_strRedirectPath.IsEmpty())
  632. {
  633. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  634. CString buf;
  635. buf.Format(IDS_REDIRECT_FORMAT, m_strRedirectPath);
  636. _bstrRedirectPathBuf = buf;
  637. return _bstrRedirectPathBuf;
  638. }
  639. return OLESTR("");
  640. case COL_STATUS:
  641. {
  642. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  643. CError err(m_dwWin32Error);
  644. if (err.Succeeded())
  645. {
  646. return OLESTR("");
  647. }
  648. _bstrResult = err;
  649. return _bstrResult;
  650. }
  651. }
  652. TRACEEOLID("CIISFileName: Bad column number" << nCol);
  653. return OLESTR("");
  654. }
  655. void
  656. CIISFileName::InitializeChildHeaders(LPHEADERCTRL lpHeader)
  657. {
  658. CIISDirectory::InitializeHeaders(lpHeader);
  659. }
  660. /* virtual */
  661. HRESULT
  662. CIISFileName::EnumerateScopePane(HSCOPEITEM hParent)
  663. {
  664. CError err = EnumerateVDirs(hParent, m_pService, FALSE);
  665. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  666. {
  667. err.Reset();
  668. }
  669. if (err.Succeeded() && /*IsWebDir() &&*/ m_strRedirectPath.IsEmpty())
  670. {
  671. if (m_dwEnumError == ERROR_SUCCESS)
  672. {
  673. err = EnumerateWebDirs(hParent, m_pService);
  674. }
  675. }
  676. if (err.Failed())
  677. {
  678. m_dwEnumError = err.Win32Error();
  679. RefreshDisplay();
  680. }
  681. return err;
  682. }
  683. /* virtual */
  684. int
  685. CIISFileName::QueryImage() const
  686. {
  687. ASSERT_PTR(m_pService);
  688. if (!m_fResolved)
  689. {
  690. if (m_hScopeItem == NULL)
  691. {
  692. TRACEEOLID("BUGBUG: Prematurely asked for display information");
  693. return MMC_IMAGECALLBACK;
  694. }
  695. //
  696. // Required for the wait cursor
  697. //
  698. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  699. CIISFileName * that = (CIISFileName *)this;
  700. CError err = that->RefreshData();
  701. that->m_fResolved = err.Succeeded();
  702. }
  703. if (!m_pService)
  704. {
  705. return iError;
  706. }
  707. if (IsDir())
  708. {
  709. if (IsEnabledApplication())
  710. {
  711. return SUCCEEDED(m_dwWin32Error) ? iApplication : iApplicationErr;
  712. }
  713. else
  714. {
  715. return SUCCEEDED(m_dwWin32Error) ? iFolder : iError;
  716. }
  717. }
  718. return SUCCEEDED(m_dwWin32Error) ? iFile : iError;
  719. }
  720. HRESULT
  721. CIISFileName::DeleteNode(IResultData * pResult)
  722. {
  723. CError err;
  724. CString path;
  725. BOOL bDeletedPhysical = FALSE;
  726. // check if they have the property sheet open on it.
  727. if (IsMyPropertySheetOpen())
  728. {
  729. ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
  730. return S_OK;
  731. }
  732. // this could be an orphaned property sheet
  733. // check if an orphaned property sheet is open on this item.
  734. CIISObject * pAlreadyOpenProp = NULL;
  735. if (TRUE == g_OpenPropertySheetTracker.FindAlreadyOpenPropertySheet(this,&pAlreadyOpenProp))
  736. {
  737. // Bring it to the foreground, and bail
  738. HWND hHwnd = 0;
  739. if (pAlreadyOpenProp)
  740. {
  741. if (hHwnd = pAlreadyOpenProp->IsMyPropertySheetOpen())
  742. {
  743. if (hHwnd && (hHwnd != (HWND) 1))
  744. {
  745. // Perhapse we should cancel the already
  746. // opened property sheet...just a thought
  747. if (!SetForegroundWindow(hHwnd))
  748. {
  749. // wasn't able to bring this property sheet to
  750. // the foreground, the propertysheet must not
  751. // exist anymore. let's just clean the hwnd
  752. // so that the user will be able to open propertysheet
  753. pAlreadyOpenProp->SetMyPropertySheetOpen(0);
  754. }
  755. else
  756. {
  757. ::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
  758. return S_OK;
  759. }
  760. }
  761. }
  762. }
  763. }
  764. CComBSTR bstrMetaPath;
  765. err = BuildMetaPath(bstrMetaPath);
  766. if (err.Succeeded())
  767. {
  768. err = CheckForMetabaseAccess(METADATA_PERMISSION_WRITE,this,TRUE,bstrMetaPath);
  769. if (!IsLostInterface(err))
  770. {
  771. // reset error if an other error other than No interface
  772. err.Reset();
  773. }
  774. }
  775. if (err.Succeeded())
  776. {
  777. CString physPath, alias, csPathMunged;
  778. GetPhysicalPath(CString(bstrMetaPath), alias, physPath);
  779. physPath.TrimRight(_T("/"));
  780. csPathMunged = physPath;
  781. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  782. GetSpecialPathRealPath(0,physPath,csPathMunged);
  783. #endif
  784. if (IsDevicePath(csPathMunged))
  785. {
  786. // check if the device path
  787. // points to an actual dir/file
  788. // if it does then enumerate it.
  789. if (IsSpecialPath(csPathMunged,TRUE,TRUE))
  790. {
  791. // Remunge this one more time!
  792. CString csBefore;
  793. csBefore = csPathMunged;
  794. GetSpecialPathRealPath(1,csBefore,csPathMunged);
  795. }
  796. else
  797. {
  798. return E_FAIL;
  799. }
  800. }
  801. // WARNING:physPath could be empty!
  802. csPathMunged.TrimLeft();
  803. csPathMunged.TrimRight();
  804. if (csPathMunged.IsEmpty())
  805. {
  806. // Physical path is empty!
  807. bDeletedPhysical = TRUE;
  808. }
  809. else
  810. {
  811. if (m_pService->IsLocal() || PathIsUNC(csPathMunged))
  812. {
  813. //
  814. // Local directory, or already a unc path
  815. //
  816. path = csPathMunged;
  817. }
  818. else
  819. {
  820. ::MakeUNCPath(path, m_pService->QueryMachineName(), csPathMunged);
  821. }
  822. LPTSTR p = path.GetBuffer(MAX_PATH);
  823. PathRemoveBlanks(p);
  824. PathRemoveBackslash(p);
  825. path += _T('\0');
  826. TRACEEOLID("Attempting to remove file/directory: " << path);
  827. CWnd * pWnd = AfxGetMainWnd();
  828. //
  829. // Attempt to delete using shell APIs
  830. //
  831. SHFILEOPSTRUCT sos;
  832. ZeroMemory(&sos, sizeof(sos));
  833. sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
  834. sos.wFunc = FO_DELETE;
  835. sos.pFrom = path;
  836. sos.fFlags = (GetAsyncKeyState(VK_SHIFT) < 0) ? 0 : FOF_ALLOWUNDO;
  837. // Use assignment to avoid conversion and wrong constructor call
  838. err = ::SHFileOperation(&sos);
  839. if (err.Succeeded() && !sos.fAnyOperationsAborted)
  840. {
  841. bDeletedPhysical = TRUE;
  842. }
  843. }
  844. if (bDeletedPhysical)
  845. {
  846. CMetaInterface * pInterface = QueryInterface();
  847. ASSERT(pInterface != NULL);
  848. bstrMetaPath = _T("");
  849. err = BuildMetaPath(bstrMetaPath);
  850. if (err.Succeeded())
  851. {
  852. CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
  853. if (mk.Succeeded())
  854. {
  855. err = mk.DeleteKey(bstrMetaPath);
  856. }
  857. // don't hold the Metabasekey open
  858. // (RemoveScopeItem may do a lot of things,and lock the metabase for other read requests)
  859. mk.Close();
  860. }
  861. if (IsDir())
  862. {
  863. err = RemoveScopeItem();
  864. }
  865. else
  866. {
  867. CIISMBNode * pParent = GetParentNode();
  868. ASSERT(pParent != NULL);
  869. if (pParent)
  870. {
  871. err = pParent->RemoveResultNode(this, pResult);
  872. }
  873. }
  874. }
  875. }
  876. if (err.Failed())
  877. {
  878. DisplayError(err);
  879. }
  880. path.ReleaseBuffer();
  881. return err;
  882. }
  883. HRESULT
  884. CIISFileName::RenameItem(LPOLESTR new_name)
  885. {
  886. CError err;
  887. CComBSTR old_name;
  888. CComBSTR MetabaseParentPath;
  889. CComBSTR MetabasePathOld;
  890. CString PhysPathMetabase, PhysPathFrom, PhysPathTo;
  891. CString alias, csPathMunged;
  892. CIISMBNode * pParentNode = NULL;
  893. CMetaInterface * pInterface = NULL;
  894. SHFILEOPSTRUCT sos;
  895. BOOL bDeletedPhysical = FALSE;
  896. CWnd * pWnd = AfxGetMainWnd();
  897. if (new_name == NULL || lstrlen(new_name) == 0)
  898. {
  899. return S_OK;
  900. }
  901. // Make sure we have a metabase conneciton...
  902. err = BuildMetaPath(MetabasePathOld);
  903. if (err.Succeeded())
  904. {
  905. err = CheckForMetabaseAccess(METADATA_PERMISSION_WRITE,this,TRUE,MetabasePathOld);
  906. if (!IsLostInterface(err))
  907. {
  908. // reset error if an other error other than No interface
  909. err.Reset();
  910. }
  911. }
  912. pInterface = QueryInterface();
  913. if (!pInterface)
  914. {
  915. err = E_FAIL;
  916. goto RenameItem_Exit;
  917. }
  918. //
  919. // Get all of the needed paths we need..
  920. //
  921. // get old paths...
  922. old_name = QueryNodeName();
  923. if (err.Succeeded())
  924. {
  925. GetPhysicalPath(CString(MetabasePathOld), alias, PhysPathMetabase);
  926. PhysPathMetabase.TrimRight(_T("/"));
  927. }
  928. // get new paths...
  929. if (err.Succeeded())
  930. {
  931. err = E_FAIL;
  932. pParentNode = GetParentNode();
  933. if (pParentNode)
  934. {
  935. err = pParentNode->BuildMetaPath(MetabaseParentPath);
  936. }
  937. }
  938. // if anything fails up till this point, abort
  939. if (err.Succeeded())
  940. {
  941. //
  942. // Do the actual work
  943. //
  944. csPathMunged = PhysPathMetabase;
  945. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  946. GetSpecialPathRealPath(0,PhysPathMetabase,csPathMunged);
  947. #endif
  948. if (IsDevicePath(csPathMunged))
  949. {
  950. // check if the device path
  951. // points to an actual dir/file
  952. // if it does then enumerate it.
  953. if (IsSpecialPath(csPathMunged,TRUE,TRUE))
  954. {
  955. // Remunge this one more time!
  956. CString csBefore;
  957. csBefore = csPathMunged;
  958. GetSpecialPathRealPath(1,csBefore,csPathMunged);
  959. }
  960. else
  961. {
  962. err = E_FAIL;
  963. goto RenameItem_Exit;
  964. }
  965. }
  966. // WARNING:physPath could be empty!
  967. csPathMunged.TrimLeft();
  968. csPathMunged.TrimRight();
  969. if (csPathMunged.IsEmpty())
  970. {
  971. // Physical path is empty!
  972. bDeletedPhysical = TRUE;
  973. }
  974. else
  975. {
  976. if (m_pService->IsLocal() || PathIsUNC(csPathMunged))
  977. {
  978. //
  979. // Local directory, or already a unc path
  980. //
  981. PhysPathFrom = csPathMunged;
  982. }
  983. else
  984. {
  985. ::MakeUNCPath(PhysPathFrom, m_pService->QueryMachineName(), csPathMunged);
  986. }
  987. LPTSTR p = PhysPathFrom.GetBuffer(MAX_PATH);
  988. PathRemoveBlanks(p);
  989. PathRemoveBackslash(p);
  990. PhysPathFrom.ReleaseBuffer();
  991. PhysPathFrom += _T('\0');
  992. PhysPathTo = PhysPathFrom;
  993. p = PhysPathTo.GetBuffer(MAX_PATH);
  994. PathRemoveFileSpec(p);
  995. PathAppend(p, new_name);
  996. PhysPathTo.ReleaseBuffer();
  997. PhysPathTo += _T('\0');
  998. //
  999. // Attempt to delete using shell APIs
  1000. //
  1001. ZeroMemory(&sos, sizeof(sos));
  1002. sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
  1003. sos.wFunc = FO_RENAME;
  1004. sos.pFrom = PhysPathFrom;
  1005. sos.pTo = PhysPathTo;
  1006. sos.fFlags = FOF_ALLOWUNDO;
  1007. // Use assignment to avoid conversion and wrong constructor call
  1008. err = ::SHFileOperation(&sos);
  1009. if (err.Succeeded() && !sos.fAnyOperationsAborted)
  1010. {
  1011. bDeletedPhysical = TRUE;
  1012. }
  1013. }
  1014. if (bDeletedPhysical)
  1015. {
  1016. // rename the metabase path too...
  1017. if (pInterface)
  1018. {
  1019. err = CChildNodeProps::Rename(pInterface,
  1020. MetabaseParentPath,
  1021. old_name,
  1022. new_name
  1023. );
  1024. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1025. {
  1026. err.Reset();
  1027. }
  1028. if (err.Win32Error() == ERROR_ALREADY_EXISTS)
  1029. {
  1030. CComBSTR MetabasePathNew;
  1031. // perhapes the path we are renaming to
  1032. // already is there???
  1033. // what should we do then????
  1034. // if we got this far, then the filename that this is being renamed to.
  1035. // cannot exists, therefore the metabase properties that were there for
  1036. // it is invalid...
  1037. MetabasePathNew = MetabaseParentPath;
  1038. MetabasePathNew.Append(_cszSeparator);
  1039. MetabasePathNew.Append(new_name);
  1040. //delete key and try again...
  1041. CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
  1042. if (mk.Succeeded())
  1043. {
  1044. err = mk.DeleteKey(MetabasePathNew);
  1045. mk.Close();
  1046. }
  1047. err = CChildNodeProps::Rename(pInterface,
  1048. MetabaseParentPath,
  1049. old_name,
  1050. new_name
  1051. );
  1052. if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  1053. {
  1054. err.Reset();
  1055. }
  1056. }
  1057. }
  1058. else
  1059. {
  1060. err = E_FAIL;
  1061. }
  1062. if (err.Failed())
  1063. {
  1064. // if we failed to rename the metabase path in the
  1065. // metabase, then revert the file rename...
  1066. ZeroMemory(&sos, sizeof(sos));
  1067. sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
  1068. sos.wFunc = FO_RENAME;
  1069. sos.pFrom = PhysPathTo;
  1070. sos.pTo = PhysPathFrom;
  1071. sos.fFlags = FOF_ALLOWUNDO;
  1072. ::SHFileOperation(&sos);
  1073. DisplayError(err);
  1074. goto RenameItem_Exit;
  1075. }
  1076. if (err.Succeeded())
  1077. {
  1078. IConsole * pConsole = (IConsole *)GetConsole();
  1079. // Update result item in the mmc
  1080. CComQIPtr<IResultData, &IID_IResultData> lpResultData(pConsole);
  1081. m_bstrFileName = new_name;
  1082. err = lpResultData->UpdateItem(m_hResultItem);
  1083. m_bstrNode = new_name;
  1084. }
  1085. }
  1086. else
  1087. {
  1088. if (err.Failed())
  1089. {
  1090. DisplayError(err);
  1091. }
  1092. }
  1093. }
  1094. RenameItem_Exit:
  1095. return err;
  1096. }
  1097. /* virtual */
  1098. HRESULT
  1099. CIISFileName::RefreshData()
  1100. /*++
  1101. Refresh relevant configuration data required for display.
  1102. --*/
  1103. {
  1104. CError err;
  1105. CWaitCursor wait;
  1106. CComBSTR bstrPath;
  1107. CMetaKey * pKey = NULL;
  1108. do
  1109. {
  1110. err = BuildMetaPath(bstrPath);
  1111. if (err.Failed())
  1112. {
  1113. break;
  1114. }
  1115. BOOL fContinue = TRUE;
  1116. while (fContinue)
  1117. {
  1118. fContinue = FALSE;
  1119. pKey = new CMetaKey(QueryInterface(), bstrPath);
  1120. if (!pKey)
  1121. {
  1122. TRACEEOLID("RefreshData: OOM");
  1123. err = ERROR_NOT_ENOUGH_MEMORY;
  1124. break;
  1125. }
  1126. err = pKey->QueryResult();
  1127. if (IsLostInterface(err))
  1128. {
  1129. SAFE_DELETE(pKey);
  1130. fContinue = OnLostInterface(err);
  1131. }
  1132. }
  1133. if (err.Failed())
  1134. {
  1135. //
  1136. // Filter out the non-fatal errors
  1137. //
  1138. switch(err.Win32Error())
  1139. {
  1140. case ERROR_ACCESS_DENIED:
  1141. case ERROR_FILE_NOT_FOUND:
  1142. case ERROR_PATH_NOT_FOUND:
  1143. err.Reset();
  1144. break;
  1145. default:
  1146. TRACEEOLID("Fatal error occurred " << err);
  1147. }
  1148. // No metabase path: nothing more to do
  1149. break;
  1150. }
  1151. CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
  1152. err = child.LoadData();
  1153. m_dwWin32Error = child.QueryWin32Error();
  1154. if (err.Succeeded())
  1155. {
  1156. CString buf = child.m_strAppRoot;
  1157. m_fEnabledApplication = (buf.CompareNoCase(bstrPath) == 0) && child.IsEnabledApplication();
  1158. }
  1159. m_strRedirectPath.Empty();
  1160. if (child.IsRedirected())
  1161. {
  1162. m_strRedirectPath = child.GetRedirectedPath();
  1163. }
  1164. }
  1165. while(FALSE);
  1166. SAFE_DELETE(pKey);
  1167. m_dwEnumError = err.Win32Error();
  1168. return err;
  1169. }
  1170. /*virtual*/
  1171. HRESULT
  1172. CIISFileName::AddMenuItems(
  1173. LPCONTEXTMENUCALLBACK piCallback,
  1174. long * pInsertionAllowed,
  1175. DATA_OBJECT_TYPES type
  1176. )
  1177. {
  1178. ASSERT_READ_PTR(piCallback);
  1179. //
  1180. // Add base menu items
  1181. //
  1182. HRESULT hr = CIISObject::AddMenuItems(
  1183. piCallback,
  1184. pInsertionAllowed,
  1185. type
  1186. );
  1187. if (SUCCEEDED(hr))
  1188. {
  1189. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
  1190. {
  1191. AddMenuSeparator(piCallback);
  1192. if (_tcsicmp(m_pService->QueryServiceName(), SZ_MBN_FTP) == 0)
  1193. {
  1194. AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
  1195. }
  1196. else if (_tcsicmp(m_pService->QueryServiceName(), SZ_MBN_WEB) == 0)
  1197. {
  1198. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
  1199. if (_tcsicmp(GetKeyType(),IIS_CLASS_WEB_DIR_W) == 0)
  1200. {
  1201. if (IsConfigImportExportable())
  1202. {
  1203. AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR_FROM_FILE);
  1204. }
  1205. }
  1206. }
  1207. }
  1208. ASSERT(pInsertionAllowed != NULL);
  1209. }
  1210. return hr;
  1211. }
  1212. /* virtual */
  1213. HRESULT
  1214. CIISFileName::Command(
  1215. IN long lCommandID,
  1216. IN CSnapInObjectRootBase * pObj,
  1217. IN DATA_OBJECT_TYPES type
  1218. )
  1219. /*++
  1220. Routine Description:
  1221. Handle command from context menu.
  1222. Arguments:
  1223. long lCommandID : Command ID
  1224. CSnapInObjectRootBase * pObj : Base object
  1225. DATA_OBJECT_TYPES type : Data object type
  1226. Return Value:
  1227. HRESULT
  1228. --*/
  1229. {
  1230. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1231. HRESULT hr = S_OK;
  1232. CString alias;
  1233. CError err;
  1234. CComBSTR bstrMetaPath;
  1235. BOOL bNeedMetabase = FALSE;
  1236. BOOL bHaveMetabase = FALSE;
  1237. switch (lCommandID)
  1238. {
  1239. case IDM_NEW_FTP_VDIR:
  1240. case IDM_NEW_WEB_VDIR:
  1241. bNeedMetabase = TRUE;
  1242. break;
  1243. case IDM_BROWSE:
  1244. if (m_hResultItem != 0)
  1245. {
  1246. bNeedMetabase = TRUE;
  1247. }
  1248. break;
  1249. default:
  1250. bNeedMetabase = FALSE;
  1251. }
  1252. if (bNeedMetabase)
  1253. {
  1254. // WARNING:bstrMetaPath will be used by switch statement below
  1255. VERIFY(SUCCEEDED(BuildMetaPath(bstrMetaPath)));
  1256. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
  1257. if (!IsLostInterface(err))
  1258. {
  1259. // reset error if an other error other than No interface
  1260. err.Reset();
  1261. }
  1262. if (err.Succeeded())
  1263. {
  1264. bHaveMetabase = TRUE;
  1265. }
  1266. }
  1267. switch (lCommandID)
  1268. {
  1269. case IDM_NEW_FTP_VDIR:
  1270. if (bHaveMetabase)
  1271. {
  1272. hr = CIISMBNode::AddFTPVDir(pObj, type, alias);
  1273. if (!alias.IsEmpty())
  1274. {
  1275. hr = InsertNewAlias(alias);
  1276. }
  1277. }
  1278. break;
  1279. case IDM_NEW_WEB_VDIR:
  1280. if (bHaveMetabase)
  1281. {
  1282. hr = CIISMBNode::AddWebVDir(pObj, type, alias,
  1283. m_pOwner->QueryMajorVersion(), m_pOwner->QueryMinorVersion());
  1284. if (!alias.IsEmpty())
  1285. {
  1286. hr = InsertNewAlias(alias);
  1287. }
  1288. }
  1289. break;
  1290. case IDM_BROWSE:
  1291. if (m_hResultItem != 0)
  1292. {
  1293. if (bHaveMetabase)
  1294. {
  1295. BuildURL(m_bstrURL);
  1296. if (m_bstrURL.Length())
  1297. {
  1298. ShellExecute(GetMainWindow(GetConsole())->m_hWnd, _T("open"), m_bstrURL, NULL, NULL, SW_SHOWNORMAL);
  1299. }
  1300. }
  1301. }
  1302. else
  1303. {
  1304. hr = CIISMBNode::Command(lCommandID, pObj, type);
  1305. }
  1306. break;
  1307. //
  1308. // Pass on to base class
  1309. //
  1310. default:
  1311. hr = CIISMBNode::Command(lCommandID, pObj, type);
  1312. }
  1313. // ASSERT(SUCCEEDED(hr));
  1314. return hr;
  1315. }
  1316. HRESULT
  1317. CIISFileName::InsertNewAlias(CString alias)
  1318. {
  1319. CError err;
  1320. if (!IsExpanded())
  1321. {
  1322. SelectScopeItem();
  1323. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1324. pConsoleNameSpace->Expand(QueryScopeItem());
  1325. HSCOPEITEM hChildItem = NULL;
  1326. LONG_PTR cookie;
  1327. HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie);
  1328. while(SUCCEEDED(hr) && hChildItem)
  1329. {
  1330. CIISObject * pItem = (CIISObject *)cookie;
  1331. ASSERT_PTR(pItem);
  1332. if (0 == alias.Compare(pItem->QueryDisplayName()))
  1333. {
  1334. pItem->SelectScopeItem();
  1335. break;
  1336. }
  1337. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1338. }
  1339. }
  1340. else
  1341. {
  1342. // Now we should insert and select this new site
  1343. CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
  1344. if (pAlias != NULL)
  1345. {
  1346. pAlias->AddRef();
  1347. err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
  1348. if (err.Succeeded())
  1349. {
  1350. VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
  1351. }
  1352. else
  1353. {
  1354. pAlias->Release();
  1355. }
  1356. }
  1357. else
  1358. {
  1359. err = ERROR_NOT_ENOUGH_MEMORY;
  1360. }
  1361. }
  1362. return err;
  1363. }
  1364. /* virtual */
  1365. HRESULT
  1366. CIISFileName::CreatePropertyPages(
  1367. LPPROPERTYSHEETCALLBACK lpProvider,
  1368. LONG_PTR handle,
  1369. IUnknown * pUnk,
  1370. DATA_OBJECT_TYPES type
  1371. )
  1372. /*++
  1373. Routine Description:
  1374. Create the property pages for the given object
  1375. Arguments:
  1376. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  1377. LONG_PTR handle : Handle.
  1378. IUnknown * pUnk,
  1379. DATA_OBJECT_TYPES type
  1380. Return Value:
  1381. HRESULT
  1382. --*/
  1383. {
  1384. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1385. CError err;
  1386. if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type)))
  1387. {
  1388. return S_OK;
  1389. }
  1390. if (ERROR_ALREADY_EXISTS == err.Win32Error())
  1391. {
  1392. return S_FALSE;
  1393. }
  1394. if (err.Succeeded())
  1395. {
  1396. CComBSTR bstrPath;
  1397. CError err(BuildMetaPath(bstrPath));
  1398. if (err.Succeeded())
  1399. {
  1400. //
  1401. // If there's already a property sheet open on this item
  1402. // then make it the foreground window and bail.
  1403. HWND MyPropWindow = IsMyPropertySheetOpen();
  1404. if (MyPropWindow && (MyPropWindow != (HWND) 1))
  1405. {
  1406. if (SetForegroundWindow(MyPropWindow))
  1407. {
  1408. if (handle)
  1409. {
  1410. MMCFreeNotifyHandle(handle);
  1411. handle = 0;
  1412. }
  1413. return S_FALSE;
  1414. }
  1415. else
  1416. {
  1417. // wasn't able to bring this property sheet to
  1418. // the foreground, the propertysheet must not
  1419. // exist anymore. let's just clean the hwnd
  1420. // so that the user will be able to open propertysheet
  1421. SetMyPropertySheetOpen(0);
  1422. }
  1423. }
  1424. // cache handle for user in MMCPropertyChangeNotify
  1425. m_ppHandle = handle;
  1426. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
  1427. if (!IsLostInterface(err))
  1428. {
  1429. // reset error if an other error other than No interface
  1430. err.Reset();
  1431. }
  1432. if (err.Succeeded())
  1433. {
  1434. if (IsDir())
  1435. {
  1436. err = ShowDirPropertiesDlg(
  1437. lpProvider, QueryAuthInfo(), bstrPath,
  1438. GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(), handle
  1439. );
  1440. }
  1441. else
  1442. {
  1443. err = ShowFilePropertiesDlg(
  1444. lpProvider, QueryAuthInfo(), bstrPath,
  1445. GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(), handle
  1446. );
  1447. }
  1448. }
  1449. }
  1450. err.MessageBoxOnFailure();
  1451. }
  1452. return err;
  1453. }
  1454. HRESULT
  1455. CIISFileName::ShowDirPropertiesDlg(
  1456. LPPROPERTYSHEETCALLBACK lpProvider,
  1457. CComAuthInfo * pAuthInfo,
  1458. LPCTSTR lpszMDPath,
  1459. CWnd * pMainWnd,
  1460. LPARAM lParam,
  1461. LPARAM lParamParent,
  1462. LONG_PTR handle
  1463. )
  1464. {
  1465. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1466. ASSERT_PTR(lpProvider);
  1467. CError err;
  1468. if (TRUE == m_fFlaggedForDeletion)
  1469. {
  1470. // this item was marked for deletion during the RefreshData
  1471. // so don't display it's property page.
  1472. // instead popup an error.
  1473. err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1474. }
  1475. else
  1476. {
  1477. CW3Sheet * pSheet = new CW3Sheet(
  1478. pAuthInfo,
  1479. lpszMDPath,
  1480. 0,
  1481. pMainWnd,
  1482. lParam,
  1483. lParamParent
  1484. );
  1485. if (pSheet)
  1486. {
  1487. pSheet->SetModeless();
  1488. //
  1489. // Add file pages
  1490. //
  1491. pSheet->SetSheetType(pSheet->SHEET_TYPE_DIR);
  1492. err = AddMMCPage(lpProvider, new CW3DirPage(pSheet));
  1493. err = AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
  1494. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, FILE_ATTRIBUTE_DIRECTORY));
  1495. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1496. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1497. }
  1498. else
  1499. {
  1500. err = ERROR_NOT_ENOUGH_MEMORY;
  1501. }
  1502. }
  1503. return err;
  1504. }
  1505. HRESULT
  1506. CIISFileName::ShowFilePropertiesDlg(
  1507. LPPROPERTYSHEETCALLBACK lpProvider,
  1508. CComAuthInfo * pAuthInfo,
  1509. LPCTSTR lpszMDPath,
  1510. CWnd * pMainWnd,
  1511. LPARAM lParam,
  1512. LPARAM lParamParent,
  1513. LONG_PTR handle
  1514. )
  1515. {
  1516. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1517. ASSERT_PTR(lpProvider);
  1518. CError err;
  1519. if (TRUE == m_fFlaggedForDeletion)
  1520. {
  1521. // this item was marked for deletion during the RefreshData
  1522. // so don't display it's property page.
  1523. // instead popup an error.
  1524. err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1525. }
  1526. else
  1527. {
  1528. CW3Sheet * pSheet = new CW3Sheet(
  1529. pAuthInfo,
  1530. lpszMDPath,
  1531. 0,
  1532. pMainWnd,
  1533. lParam,
  1534. lParamParent
  1535. );
  1536. if (pSheet)
  1537. {
  1538. pSheet->SetModeless();
  1539. //
  1540. // Add file pages
  1541. //
  1542. pSheet->SetSheetType(pSheet->SHEET_TYPE_FILE);
  1543. err = AddMMCPage(lpProvider, new CW3FilePage(pSheet));
  1544. err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, 0));
  1545. err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
  1546. err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
  1547. }
  1548. else
  1549. {
  1550. err = ERROR_NOT_ENOUGH_MEMORY;
  1551. }
  1552. }
  1553. return err;
  1554. }
  1555. HRESULT
  1556. CIISFileName::OnViewChange(BOOL fScope,
  1557. IResultData * pResult, IHeaderCtrl * pHeader, DWORD hint)
  1558. {
  1559. // If there is win32 error set, we should clear it to enable web dirs enumeration again
  1560. m_dwWin32Error = ERROR_SUCCESS;
  1561. CError err = CIISMBNode::OnViewChange(fScope, pResult, pHeader, hint);
  1562. // If parent node is selected, this node will be displayed on result
  1563. // pane, we may need to update the status, path, etc
  1564. //if (err.Succeeded() && 0 != (hint & PROP_CHANGE_DISPLAY_ONLY))
  1565. //{
  1566. // pResult->UpdateItem(IsDir() ? m_hScopeItem : m_hResultItem);
  1567. //}
  1568. return err;
  1569. }
  1570. HRESULT
  1571. CIISFileName::OnDblClick(IComponentData * pcd, IComponent * pc)
  1572. {
  1573. if (IsDir())
  1574. {
  1575. return CIISMBNode::OnDblClick(pcd, pc);
  1576. }
  1577. else
  1578. {
  1579. CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> spProvider(GetConsole());
  1580. IDataObject * pdo = NULL;
  1581. GetDataObject(&pdo, CCT_RESULT);
  1582. CError err = spProvider->FindPropertySheet(reinterpret_cast<MMC_COOKIE>(this), 0, pdo);
  1583. if (err != S_OK)
  1584. {
  1585. err = spProvider->CreatePropertySheet(m_bstrFileName, TRUE, (MMC_COOKIE)this, pdo, MMC_PSO_HASHELP);
  1586. if (err.Succeeded())
  1587. {
  1588. err = spProvider->AddPrimaryPages(
  1589. pc,
  1590. TRUE, // we may want to get property change notifications
  1591. NULL, // according to docs
  1592. FALSE // for result item only
  1593. );
  1594. if (err.Succeeded())
  1595. {
  1596. err = spProvider->AddExtensionPages();
  1597. }
  1598. }
  1599. if (err.Succeeded())
  1600. {
  1601. HWND hWnd = NULL;
  1602. VERIFY(SUCCEEDED(GetConsole()->GetMainWindow(&hWnd)));
  1603. VERIFY(SUCCEEDED(spProvider->Show((LONG_PTR)hWnd, 0)));
  1604. }
  1605. else
  1606. {
  1607. spProvider->Show(-1, 0);
  1608. }
  1609. }
  1610. return err;
  1611. }
  1612. }