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.

811 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: DSCookie.cpp
  7. //
  8. // Contents: TBD
  9. //
  10. // History: 02-Oct-96 WayneSc Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "uinode.h"
  16. #include "dscmn.h" // CrackName()
  17. #include "ContextMenu.h"
  18. #include "dsfilter.h"
  19. #include "xmlutil.h"
  20. #include <notify.h>
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. ////////////////////////////////////////////////////////////////////
  27. // CUIFolderInfo
  28. const UINT CUIFolderInfo::nSerialNomberNotTouched = 0x7fffffff;
  29. CUIFolderInfo::CUIFolderInfo(CUINode* pUINode)
  30. {
  31. ASSERT(pUINode != NULL);
  32. m_pUINode = pUINode;
  33. m_hScopeItem = NULL;
  34. m_bExpandedOnce = FALSE;
  35. m_cObjectsContained = 0;
  36. m_SerialNumber = SERIALNUM_NOT_TOUCHED;
  37. m_pColumnSet = NULL;
  38. m_bTooMuchData = FALSE;
  39. m_nApproximateTotalContained = 0;
  40. m_bSortOnNextSelect = FALSE;
  41. }
  42. CUIFolderInfo::CUIFolderInfo(const CUIFolderInfo&)
  43. {
  44. //
  45. // The node is probably still being created so don't copy it
  46. //
  47. m_pUINode = NULL;
  48. //
  49. // Don't copy the scope item
  50. //
  51. m_hScopeItem = 0;
  52. //
  53. // Don't mark as expanded
  54. //
  55. m_bExpandedOnce = FALSE;
  56. //
  57. // Shouldn't contain any object either
  58. //
  59. m_cObjectsContained = 0;
  60. m_SerialNumber = SERIALNUM_NOT_TOUCHED;
  61. m_pColumnSet = NULL;
  62. m_bTooMuchData = FALSE;
  63. m_nApproximateTotalContained = 0;
  64. m_bSortOnNextSelect = FALSE;
  65. }
  66. CDSColumnSet* CUIFolderInfo::GetColumnSet(PCWSTR pszClass, CDSComponentData* pCD)
  67. {
  68. if (m_pColumnSet == NULL)
  69. {
  70. ASSERT(pCD != NULL);
  71. if (_wcsicmp(m_pUINode->GetName(), L"ForeignSecurityPrincipals") == 0)
  72. {
  73. m_pColumnSet = pCD->FindColumnSet(L"ForeignSecurityPrincipals");
  74. }
  75. else
  76. {
  77. m_pColumnSet = pCD->FindColumnSet(pszClass);
  78. }
  79. ASSERT(m_pColumnSet != NULL);
  80. }
  81. return m_pColumnSet;
  82. }
  83. void CUIFolderInfo::UpdateSerialNumber(CDSComponentData * pCD)
  84. {
  85. m_SerialNumber = pCD->GetSerialNumber();
  86. // TRACE(_T("cookie (%s)serial number updated: %d.\n"),
  87. // m_strName, m_SerialNumber);
  88. CUINode* pParentNode = GetParentNode();
  89. if (pParentNode != NULL)
  90. pParentNode->GetFolderInfo()->UpdateSerialNumber(pCD);
  91. }
  92. void CUIFolderInfo::AddToCount(UINT increment)
  93. {
  94. m_cObjectsContained += increment;
  95. // TRACE(_T("cookie (%s) count increased to: %d.\n"),
  96. // m_strName, m_cObjectsContained);
  97. CUINode* pParentNode = GetParentNode();
  98. if (pParentNode != NULL)
  99. pParentNode->GetFolderInfo()->AddToCount(increment);
  100. }
  101. void CUIFolderInfo::SubtractFromCount(UINT decrement)
  102. {
  103. if (m_cObjectsContained == 0)
  104. return;
  105. m_cObjectsContained -= decrement;
  106. // TRACE(_T("cookie (%s) count decreased to: %d.\n"),
  107. // m_strName, m_cObjectsContained);
  108. CUINode* pParentNode = GetParentNode();
  109. if (pParentNode != NULL)
  110. pParentNode->GetFolderInfo()->SubtractFromCount(decrement);
  111. }
  112. CUINode* CUIFolderInfo::GetParentNode()
  113. {
  114. ASSERT(m_pUINode != NULL);
  115. return m_pUINode->GetParent();
  116. }
  117. void CUIFolderInfo::DeleteAllLeafNodes(void)
  118. {
  119. SubtractFromCount ((UINT)m_LeafNodes.GetCount());
  120. while (!m_LeafNodes.IsEmpty())
  121. delete m_LeafNodes.RemoveTail();
  122. }
  123. void CUIFolderInfo::DeleteAllContainerNodes(void)
  124. {
  125. SubtractFromCount ((UINT)m_ContainerNodes.GetCount());
  126. while (!m_ContainerNodes.IsEmpty())
  127. delete m_ContainerNodes.RemoveTail();
  128. }
  129. HRESULT CUIFolderInfo::AddNode(CUINode* pUINode)
  130. {
  131. if (pUINode==NULL)
  132. {
  133. ASSERT(FALSE);
  134. return E_INVALIDARG;
  135. }
  136. if (pUINode->IsContainer())
  137. m_ContainerNodes.AddTail(pUINode);
  138. else
  139. m_LeafNodes.AddTail(pUINode);
  140. AddToCount(1);
  141. pUINode->SetParent(m_pUINode);
  142. return S_OK;
  143. }
  144. HRESULT CUIFolderInfo::AddListofNodes(CUINodeList* pNodeList)
  145. {
  146. HRESULT hr = S_OK;
  147. if (pNodeList == NULL)
  148. {
  149. ASSERT(FALSE);
  150. return E_INVALIDARG;
  151. }
  152. POSITION pos = pNodeList->GetHeadPosition();
  153. while (pos != NULL)
  154. {
  155. CUINode* pUINode = pNodeList->GetNext(pos);
  156. if (pUINode != NULL)
  157. {
  158. AddNode(pUINode);
  159. }
  160. else
  161. {
  162. hr = E_POINTER;
  163. }
  164. }
  165. return hr;
  166. }
  167. HRESULT CUIFolderInfo::DeleteNode(CUINode* pUINode)
  168. {
  169. if (pUINode==NULL)
  170. {
  171. ASSERT(FALSE);
  172. return E_INVALIDARG;
  173. }
  174. HRESULT hr = RemoveNode(pUINode);
  175. if (SUCCEEDED(hr))
  176. {
  177. delete pUINode;
  178. }
  179. return hr;
  180. }
  181. HRESULT CUIFolderInfo::RemoveNode(CUINode* pUINode)
  182. {
  183. if (pUINode==NULL)
  184. {
  185. ASSERT(FALSE);
  186. return E_INVALIDARG;
  187. }
  188. HRESULT hr=E_FAIL;
  189. POSITION pos;
  190. CUINodeList* pList=NULL;
  191. if (pUINode->IsContainer())
  192. {
  193. pList=&m_ContainerNodes;
  194. }
  195. else
  196. {
  197. pList=&m_LeafNodes;
  198. }
  199. pos = pList->Find(pUINode);
  200. if (pos != NULL)
  201. {
  202. pList->RemoveAt(pos);
  203. hr = S_OK;
  204. }
  205. SubtractFromCount(1);
  206. return hr;
  207. }
  208. void CUIFolderInfo::SetTooMuchData(BOOL bSet, UINT nApproximateTotal)
  209. {
  210. m_bTooMuchData = bSet;
  211. if (!bSet)
  212. {
  213. m_nApproximateTotalContained = 0;
  214. }
  215. else
  216. {
  217. m_nApproximateTotalContained = nApproximateTotal;
  218. }
  219. }
  220. ////////////////////////////////////////////////////////////////////
  221. // CUINode
  222. CUINode::CUINode(CUINode* pParentNode)
  223. {
  224. m_pParentNode = pParentNode;
  225. m_pNodeData = NULL;
  226. m_pFolderInfo = NULL;
  227. m_nSheetLockCount = 0;
  228. m_extension_op = 0;
  229. m_pMenuVerbs = NULL;
  230. }
  231. CUINode::CUINode(const CUINode& copyNode)
  232. {
  233. m_pParentNode = copyNode.m_pParentNode;
  234. if (copyNode.m_pNodeData != NULL)
  235. {
  236. m_pNodeData = new CNodeData(*(copyNode.m_pNodeData));
  237. }
  238. else
  239. {
  240. m_pNodeData = NULL;
  241. }
  242. if (copyNode.m_pFolderInfo != NULL)
  243. {
  244. m_pFolderInfo = new CUIFolderInfo(*(copyNode.m_pFolderInfo));
  245. m_pFolderInfo->SetNode(this);
  246. }
  247. else
  248. {
  249. m_pFolderInfo = NULL;
  250. }
  251. m_nSheetLockCount = copyNode.m_nSheetLockCount;
  252. m_extension_op = copyNode.m_extension_op;
  253. m_pMenuVerbs = NULL;
  254. }
  255. CUINode::~CUINode()
  256. {
  257. ASSERT(m_nSheetLockCount == 0);
  258. if (m_pNodeData != NULL)
  259. {
  260. delete m_pNodeData;
  261. }
  262. if (m_pFolderInfo != NULL)
  263. {
  264. delete m_pFolderInfo;
  265. }
  266. if (m_pMenuVerbs != NULL)
  267. {
  268. delete m_pMenuVerbs;
  269. }
  270. }
  271. BOOL CUINode::IsRelative(CUINode* pUINode)
  272. {
  273. BOOL bRet = FALSE;
  274. if (pUINode == this)
  275. {
  276. bRet = TRUE;
  277. }
  278. else
  279. {
  280. if (!IsSnapinRoot())
  281. {
  282. bRet = GetParent()->IsRelative(pUINode);
  283. }
  284. }
  285. return bRet;
  286. }
  287. void CUINode::IncrementSheetLockCount()
  288. {
  289. ++m_nSheetLockCount;
  290. if (m_pParentNode != NULL)
  291. m_pParentNode->IncrementSheetLockCount();
  292. }
  293. void CUINode::DecrementSheetLockCount()
  294. {
  295. ASSERT(m_nSheetLockCount > 0);
  296. --m_nSheetLockCount;
  297. if (m_pParentNode != NULL)
  298. m_pParentNode->DecrementSheetLockCount();
  299. }
  300. BOOL CUINode::IsDeleteAllowed(CDSComponentData*, BOOL* pbHide)
  301. {
  302. *pbHide = TRUE;
  303. return FALSE;
  304. }
  305. BOOL CUINode::IsRenameAllowed(CDSComponentData*, BOOL* pbHide)
  306. {
  307. *pbHide = TRUE;
  308. return FALSE;
  309. }
  310. BOOL CUINode::IsRefreshAllowed(CDSComponentData*, BOOL* pbHide)
  311. {
  312. *pbHide = TRUE;
  313. return FALSE;
  314. }
  315. BOOL CUINode::ArePropertiesAllowed(CDSComponentData*, BOOL* pbHide)
  316. {
  317. *pbHide = TRUE;
  318. return FALSE;
  319. }
  320. BOOL CUINode::IsCutAllowed(CDSComponentData*, BOOL* pbHide)
  321. {
  322. *pbHide = TRUE;
  323. return FALSE;
  324. }
  325. BOOL CUINode::IsCopyAllowed(CDSComponentData*, BOOL* pbHide)
  326. {
  327. *pbHide = TRUE;
  328. return FALSE;
  329. }
  330. BOOL CUINode::IsPasteAllowed(CDSComponentData*, BOOL* pbHide)
  331. {
  332. *pbHide = TRUE;
  333. return FALSE;
  334. }
  335. BOOL CUINode::IsPrintAllowed(CDSComponentData*, BOOL* pbHide)
  336. {
  337. *pbHide = TRUE;
  338. return FALSE;
  339. }
  340. CDSColumnSet* CUINode::GetColumnSet(CDSComponentData* pComponentData)
  341. {
  342. CDSColumnSet* pColumnSet = NULL;
  343. if (IsContainer())
  344. {
  345. pColumnSet = m_pFolderInfo->GetColumnSet(DEFAULT_COLUMN_SET, pComponentData);
  346. }
  347. return pColumnSet;
  348. }
  349. CContextMenuVerbs* CUINode::GetContextMenuVerbsObject(CDSComponentData* pComponentData)
  350. {
  351. if (m_pMenuVerbs == NULL)
  352. {
  353. if (pComponentData->QuerySnapinType() == SNAPINTYPE_SITE)
  354. {
  355. m_pMenuVerbs = new CSARContextMenuVerbs(pComponentData);
  356. }
  357. else
  358. {
  359. m_pMenuVerbs = new CDSAdminContextMenuVerbs(pComponentData);
  360. }
  361. }
  362. return m_pMenuVerbs;
  363. }
  364. HRESULT CUINode::Delete(CDSComponentData* pComponentData)
  365. {
  366. HRESULT hr = S_OK;
  367. if (IsContainer())
  368. {
  369. hr = pComponentData->RemoveContainerFromUI(this);
  370. delete this;
  371. }
  372. else
  373. {
  374. CUINode* pParentNode = GetParent();
  375. ASSERT(pParentNode->IsContainer());
  376. pParentNode->GetFolderInfo()->RemoveNode(this);
  377. //
  378. // The CDSEvent::_DeleteSingleSel() handles removing the node from the UI
  379. //
  380. }
  381. return hr;
  382. }
  383. HRESULT CUINode::DeleteMultiselect(CDSComponentData* pComponentData, CInternalFormatCracker* pObjCracker)
  384. {
  385. HRESULT hr = S_OK;
  386. //
  387. // Multiselection should always delegate to the container
  388. //
  389. ASSERT(IsContainer());
  390. if (IsContainer())
  391. {
  392. for (UINT nIdx = 0; nIdx < pObjCracker->GetCookieCount(); nIdx++)
  393. {
  394. CUINode* pUINode = pObjCracker->GetCookie(nIdx);
  395. if (pUINode != NULL)
  396. {
  397. if (pUINode->IsContainer())
  398. {
  399. hr = pComponentData->RemoveContainerFromUI(pUINode);
  400. delete pUINode;
  401. }
  402. else
  403. {
  404. GetFolderInfo()->RemoveNode(pUINode);
  405. }
  406. }
  407. }
  408. }
  409. else
  410. {
  411. hr = S_FALSE;
  412. }
  413. return hr;
  414. }
  415. HRESULT CUINode::Rename(LPCWSTR lpszNewName, CDSComponentData* pComponentData)
  416. {
  417. HRESULT hr = S_OK;
  418. SetName(lpszNewName);
  419. hr = pComponentData->UpdateItem(this);
  420. return hr;
  421. }
  422. ////////////////////////////////////////////////////////////////////
  423. // CUINodeTableBase
  424. #define NUMBER_OF_COOKIE_TABLE_ENTRIES 4 // default count, expandable at run time
  425. CUINodeTableBase::CUINodeTableBase()
  426. {
  427. m_nEntries = NUMBER_OF_COOKIE_TABLE_ENTRIES;
  428. m_pCookieArr =(CUINode**)malloc(m_nEntries*sizeof(CUINode*));
  429. if (m_pCookieArr != NULL)
  430. {
  431. ZeroMemory(m_pCookieArr, m_nEntries*sizeof(CUINode*));
  432. }
  433. }
  434. CUINodeTableBase::~CUINodeTableBase()
  435. {
  436. free(m_pCookieArr);
  437. }
  438. void CUINodeTableBase::Add(CUINode* pNode)
  439. {
  440. ASSERT(!IsPresent(pNode));
  441. for (UINT k=0; k<m_nEntries; k++)
  442. {
  443. if (m_pCookieArr[k] == NULL)
  444. {
  445. m_pCookieArr[k] = pNode;
  446. return;
  447. }
  448. }
  449. // not space left, need to allocate
  450. int nAlloc = m_nEntries*2;
  451. m_pCookieArr = (CUINode**)realloc(m_pCookieArr, sizeof(CUINode*)*nAlloc);
  452. ::ZeroMemory(&m_pCookieArr[m_nEntries], sizeof(CDSCookie*)*m_nEntries);
  453. m_pCookieArr[m_nEntries] = pNode;
  454. m_nEntries = nAlloc;
  455. }
  456. BOOL CUINodeTableBase::Remove(CUINode* pNode)
  457. {
  458. for (UINT k=0; k<m_nEntries; k++)
  459. {
  460. if (m_pCookieArr[k] == pNode)
  461. {
  462. m_pCookieArr[k] = NULL;
  463. return TRUE; // found
  464. }
  465. }
  466. return FALSE; // not found
  467. }
  468. BOOL CUINodeTableBase::IsPresent(CUINode* pNode)
  469. {
  470. for (UINT k=0; k<m_nEntries; k++)
  471. {
  472. if (m_pCookieArr[k] == pNode)
  473. return TRUE;
  474. }
  475. return FALSE;
  476. }
  477. void CUINodeTableBase::Reset()
  478. {
  479. for (UINT k=0; k<m_nEntries; k++)
  480. {
  481. m_pCookieArr[k] = NULL;
  482. }
  483. }
  484. UINT CUINodeTableBase::GetCount()
  485. {
  486. UINT nCount = 0;
  487. for (UINT k=0; k<m_nEntries; k++)
  488. {
  489. if (m_pCookieArr[k] != NULL)
  490. nCount++;
  491. }
  492. return nCount;
  493. }
  494. ////////////////////////////////////////////////////////////////////
  495. // CUINodeQueryTable
  496. void CUINodeQueryTable::RemoveDescendants(CUINode* pNode)
  497. {
  498. // cannot do this while the cookie has a pending operation
  499. ASSERT(!IsPresent(pNode));
  500. // remove all the cookies that have the given cookie as parent
  501. // or ancestor,
  502. for (UINT k=0; k<m_nEntries; k++)
  503. {
  504. if (m_pCookieArr[k] != NULL)
  505. {
  506. CUINode* pAncestorNode = m_pCookieArr[k]->GetParent();
  507. while (pAncestorNode != NULL)
  508. {
  509. if (pAncestorNode == pNode)
  510. {
  511. m_pCookieArr[k] = NULL;
  512. }
  513. pAncestorNode = pAncestorNode->GetParent();
  514. }
  515. }
  516. }
  517. }
  518. BOOL CUINodeQueryTable::IsLocked(CUINode* pNode)
  519. {
  520. for (UINT k=0; k<m_nEntries; k++)
  521. {
  522. if (m_pCookieArr[k] != NULL)
  523. {
  524. // found the cookie itself?
  525. if (pNode == m_pCookieArr[k])
  526. return TRUE;
  527. // look if the cookie is an ancestor of the current cookie
  528. CUINode* pAncestorNode = m_pCookieArr[k]->GetParent();
  529. while (pAncestorNode != NULL)
  530. {
  531. if (pAncestorNode == pNode)
  532. return TRUE;
  533. pAncestorNode = pAncestorNode->GetParent();
  534. }
  535. }
  536. }
  537. return FALSE;
  538. }
  539. ////////////////////////////////////////////////////////////////////
  540. // CUINodeSheetTable
  541. void CUINodeSheetTable::BringToForeground(CUINode* pNode, CDSComponentData* pCD, BOOL bActivate)
  542. {
  543. ASSERT(pCD != NULL);
  544. ASSERT(pNode != NULL);
  545. //
  546. // look for the cookie itself and for all the cookies that have the
  547. // given cookie as parent or ancestor
  548. //
  549. for (UINT k=0; k<m_nEntries; k++)
  550. {
  551. if (m_pCookieArr[k] != NULL)
  552. {
  553. CUINode* pAncestorNode = m_pCookieArr[k];
  554. while (pAncestorNode != NULL)
  555. {
  556. if (pAncestorNode == pNode)
  557. {
  558. CString szADSIPath;
  559. if (IS_CLASS(*pNode, CDSUINode))
  560. {
  561. CDSCookie* pCookie = GetDSCookieFromUINode(pNode);
  562. if (pCookie != NULL)
  563. {
  564. pCD->GetBasePathsInfo()->ComposeADsIPath(szADSIPath, pCookie->GetPath());
  565. //
  566. // the first one will be also activated
  567. //
  568. TRACE(L"BringSheetToForeground(%s, %d)\n", (LPCWSTR)szADSIPath, bActivate);
  569. VERIFY(BringSheetToForeground((LPWSTR)(LPCWSTR)szADSIPath, bActivate));
  570. if (bActivate)
  571. {
  572. bActivate = FALSE;
  573. }
  574. }
  575. }
  576. }
  577. pAncestorNode = pAncestorNode->GetParent();
  578. }
  579. } // if
  580. } // for
  581. }
  582. /////////////////////////////////////////////////////////////////////////////
  583. // CGenericUINode
  584. CGenericUINode::CGenericUINode(CUINode* pParentNode) : CUINode(pParentNode)
  585. {
  586. m_nImage = 0;
  587. }
  588. CGenericUINode::CGenericUINode(const CGenericUINode& copyNode) : CUINode(copyNode)
  589. {
  590. m_nImage = copyNode.m_nImage;
  591. m_strName = copyNode.m_strName;
  592. m_strDesc = copyNode.m_strDesc;
  593. }
  594. LPCWSTR CGenericUINode::g_szNameXMLTag = L"NAME";
  595. LPCWSTR CGenericUINode::g_szDecriptionXMLTag = L"DESCRIPTION";
  596. HRESULT CGenericUINode::XMLSaveBase(IXMLDOMDocument* pXMLDoc,
  597. IXMLDOMNode* pXMLDOMNode)
  598. {
  599. HRESULT hr = XML_AppendTextDataNode(pXMLDoc, pXMLDOMNode, CGenericUINode::g_szNameXMLTag, GetName());
  600. RETURN_IF_FAILED(hr);
  601. hr = XML_AppendTextDataNode(pXMLDoc, pXMLDOMNode, CGenericUINode::g_szDecriptionXMLTag, GetDesc());
  602. return hr;
  603. }
  604. //////////////////////////////////////////////////////////////////////////////
  605. // CRootNode
  606. BOOL CRootNode::IsRefreshAllowed(CDSComponentData*, BOOL* pbHide)
  607. {
  608. *pbHide = FALSE;
  609. return TRUE;
  610. }
  611. CContextMenuVerbs* CRootNode::GetContextMenuVerbsObject(CDSComponentData* pComponentData)
  612. {
  613. if (m_pMenuVerbs == NULL)
  614. {
  615. m_pMenuVerbs = new CSnapinRootMenuVerbs(pComponentData);
  616. }
  617. return m_pMenuVerbs;
  618. }
  619. HRESULT CRootNode::OnCommand(long lCommandID, CDSComponentData* pComponentData)
  620. {
  621. HRESULT hr = S_OK;
  622. switch (lCommandID)
  623. {
  624. case IDM_GEN_TASK_SELECT_DOMAIN:
  625. case IDM_GEN_TASK_SELECT_FOREST:
  626. if (pComponentData->CanRefreshAll())
  627. {
  628. pComponentData->GetDomain();
  629. }
  630. break;
  631. case IDM_GEN_TASK_SELECT_DC:
  632. if (pComponentData->CanRefreshAll())
  633. {
  634. pComponentData->GetDC();
  635. }
  636. break;
  637. case IDM_VIEW_SERVICES_NODE:
  638. {
  639. if (pComponentData->CanRefreshAll())
  640. {
  641. ASSERT( SNAPINTYPE_SITE == pComponentData->QuerySnapinType() );
  642. pComponentData->GetQueryFilter()->ToggleViewServicesNode();
  643. pComponentData->SetDirty();
  644. if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
  645. {
  646. pComponentData->Refresh(pComponentData->GetRootNode(), FALSE /*bFlushCache*/ );
  647. }
  648. }
  649. }
  650. break;
  651. case IDM_GEN_TASK_EDIT_FSMO:
  652. {
  653. pComponentData->EditFSMO();
  654. }
  655. break;
  656. case IDM_GEN_TASK_RAISE_VERSION:
  657. pComponentData->RaiseVersion();
  658. break;
  659. case IDM_VIEW_ADVANCED:
  660. {
  661. if (pComponentData->CanRefreshAll())
  662. {
  663. ASSERT( SNAPINTYPE_SITE != pComponentData->QuerySnapinType() );
  664. pComponentData->GetQueryFilter()->ToggleAdvancedView();
  665. pComponentData->SetDirty();
  666. if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
  667. {
  668. pComponentData->Refresh(pComponentData->GetRootNode(), TRUE /*bFlushCache*/ );
  669. }
  670. }
  671. }
  672. break;
  673. case IDM_VIEW_COMPUTER_HACK:
  674. if (pComponentData->CanRefreshAll())
  675. {
  676. pComponentData->Lock();
  677. pComponentData->GetQueryFilter()->ToggleExpandComputers();
  678. pComponentData->Unlock();
  679. BOOL fDoRefresh = pComponentData->GetClassCache()->ToggleExpandSpecialClasses(pComponentData->GetQueryFilter()->ExpandComputers());
  680. pComponentData->SetDirty();
  681. if (fDoRefresh)
  682. {
  683. if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
  684. {
  685. pComponentData->Refresh(pComponentData->GetRootNode(), TRUE /*bFlushCache*/ );
  686. }
  687. }
  688. }
  689. break;
  690. default:
  691. ASSERT(FALSE);
  692. break;
  693. }
  694. return hr;
  695. }