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.

3271 lines
103 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusDoc.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CClusterDoc class.
  10. //
  11. // Author:
  12. // David Potter (davidp) May 1, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include <ClAdmWiz.h>
  21. #include "CluAdmin.h"
  22. #include "ConstDef.h"
  23. #include "ClusDoc.h"
  24. #include "Cluster.h"
  25. #include "ExcOper.h"
  26. #include "Notify.h"
  27. #include "TraceTag.h"
  28. #include "ListView.h"
  29. #include "TreeView.h"
  30. #include "GrpWiz.h"
  31. #include "ResWiz.h"
  32. #include "SplitFrm.h"
  33. #include "YesToAll.h"
  34. #include "ActGrp.h"
  35. #ifdef _DEBUG
  36. #define new DEBUG_NEW
  37. #undef THIS_FILE
  38. static char THIS_FILE[] = __FILE__;
  39. #endif
  40. /////////////////////////////////////////////////////////////////////////////
  41. // Global Variables
  42. /////////////////////////////////////////////////////////////////////////////
  43. #ifdef _DEBUG
  44. CTraceTag g_tagDoc(_T("Document"), _T("DOC"), 0);
  45. CTraceTag g_tagDocMenu(_T("Menu"), _T("DOC"), 0);
  46. CTraceTag g_tagDocNotify(_T("Notify"), _T("DOC NOTIFY"), 0);
  47. CTraceTag g_tagDocRegNotify(_T("Notify"), _T("DOC REG NOTIFY"), 0);
  48. CTraceTag g_tagDocRefresh(_T("Document"), _T("REFRESH"), 0);
  49. #endif
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CClusterDoc
  52. /////////////////////////////////////////////////////////////////////////////
  53. IMPLEMENT_DYNCREATE(CClusterDoc, CDocument)
  54. /////////////////////////////////////////////////////////////////////////////
  55. // Message Maps
  56. BEGIN_MESSAGE_MAP(CClusterDoc, CDocument)
  57. //{{AFX_MSG_MAP(CClusterDoc)
  58. ON_COMMAND(ID_FILE_NEW_GROUP, OnCmdNewGroup)
  59. ON_COMMAND(ID_FILE_NEW_RESOURCE, OnCmdNewResource)
  60. ON_COMMAND(ID_FILE_NEW_NODE, OnCmdNewNode)
  61. ON_COMMAND(ID_FILE_CONFIG_APP, OnCmdConfigApp)
  62. ON_COMMAND(ID_VIEW_REFRESH, OnCmdRefresh)
  63. //}}AFX_MSG_MAP
  64. END_MESSAGE_MAP()
  65. /////////////////////////////////////////////////////////////////////////////
  66. //++
  67. //
  68. // CClusterDoc::CClusterDoc
  69. //
  70. // Routine Description:
  71. // Default constructor.
  72. //
  73. // Arguments:
  74. // None.
  75. //
  76. // Return Value:
  77. // None.
  78. //
  79. //--
  80. /////////////////////////////////////////////////////////////////////////////
  81. CClusterDoc::CClusterDoc(void)
  82. {
  83. m_hcluster = NULL;
  84. m_hkeyCluster = NULL;
  85. m_pciCluster = NULL;
  86. m_ptiCluster = NULL;
  87. m_hmenuCluster = NULL;
  88. m_hmenuNode = NULL;
  89. m_hmenuGroup = NULL;
  90. m_hmenuResource = NULL;
  91. m_hmenuResType = NULL;
  92. m_hmenuNetwork = NULL;
  93. m_hmenuNetIFace = NULL;
  94. m_hmenuCurrent = NULL;
  95. m_idmCurrentMenu = 0;
  96. m_bUpdateFrameNumber = TRUE;
  97. m_bInitializing = TRUE;
  98. m_bIgnoreErrors = FALSE;
  99. m_bClusterAvailable = FALSE;
  100. EnableAutomation();
  101. } //*** CClusterDoc::CClusterDoc()
  102. /////////////////////////////////////////////////////////////////////////////
  103. //++
  104. //
  105. // CClusterDoc::~CClusterDoc
  106. //
  107. // Routine Description:
  108. // Destructor.
  109. //
  110. // Arguments:
  111. // None.
  112. //
  113. // Return Value:
  114. // None.
  115. //
  116. //--
  117. /////////////////////////////////////////////////////////////////////////////
  118. CClusterDoc::~CClusterDoc(void)
  119. {
  120. // Destroy any menus we loaded.
  121. if (m_hmenuCluster != NULL)
  122. DestroyMenu(m_hmenuCluster);
  123. if (m_hmenuNode != NULL)
  124. DestroyMenu(m_hmenuNode);
  125. if (m_hmenuGroup != NULL)
  126. DestroyMenu(m_hmenuGroup);
  127. if (m_hmenuResource != NULL)
  128. DestroyMenu(m_hmenuResource);
  129. if (m_hmenuResType != NULL)
  130. DestroyMenu(m_hmenuResType);
  131. if (m_hmenuNetwork != NULL)
  132. DestroyMenu(m_hmenuNetwork);
  133. if (m_hmenuNetIFace != NULL)
  134. DestroyMenu(m_hmenuNetIFace);
  135. delete m_pciCluster;
  136. } //*** CClusterDoc::~CClusterDoc()
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CClusterDoc diagnostics
  139. #ifdef _DEBUG
  140. void CClusterDoc::AssertValid(void) const
  141. {
  142. CDocument::AssertValid();
  143. }
  144. void CClusterDoc::Dump(CDumpContext& dc) const
  145. {
  146. CDocument::Dump(dc);
  147. }
  148. #endif //_DEBUG
  149. /////////////////////////////////////////////////////////////////////////////
  150. //++
  151. //
  152. // CClusterDoc::OnOpenDocument
  153. //
  154. // Routine Description:
  155. // Open a cluster.
  156. //
  157. // Arguments:
  158. // lpszPathName [IN] Name of the cluster to open.
  159. //
  160. // Return Value:
  161. // TRUE Cluster opened successfully.
  162. // FALSE Failed to open the cluster.
  163. //
  164. //--
  165. /////////////////////////////////////////////////////////////////////////////
  166. BOOL CClusterDoc::OnOpenDocument(LPCTSTR lpszPathName)
  167. {
  168. BOOL bSuccess = TRUE;
  169. CWaitCursor wc;
  170. ASSERT(Hcluster() == NULL);
  171. ASSERT(HkeyCluster() == NULL);
  172. // There better be a cluster name.
  173. ASSERT(lpszPathName != NULL);
  174. ASSERT(*lpszPathName != _T('\0'));
  175. // Display a message on the status bar.
  176. {
  177. CString strStatusBarText;
  178. strStatusBarText.FormatMessage(IDS_SB_OPENING_CONNECTION, lpszPathName);
  179. PframeMain()->SetMessageText(strStatusBarText);
  180. PframeMain()->UpdateWindow();
  181. } // Display a message on the status bar
  182. // If the application is minimized, don't display message boxes
  183. // on errors.
  184. m_bIgnoreErrors = AfxGetMainWnd()->IsIconic() == TRUE;
  185. try
  186. {
  187. OnOpenDocumentWorker(lpszPathName);
  188. } // try
  189. catch (CException * pe)
  190. {
  191. if (!m_bIgnoreErrors)
  192. pe->ReportError();
  193. pe->Delete();
  194. if (HkeyCluster() != NULL)
  195. {
  196. ClusterRegCloseKey(HkeyCluster());
  197. m_hkeyCluster = NULL;
  198. } // if: cluster registry key is open
  199. if ((Hcluster() != NULL) && (Hcluster() != GetClusterAdminApp()->HOpenedCluster()))
  200. {
  201. CloseCluster(Hcluster());
  202. m_hcluster = NULL;
  203. } // if: cluster is open
  204. m_bClusterAvailable = FALSE;
  205. bSuccess = FALSE;
  206. } // catch: CException
  207. // Reset the message on the status bar.
  208. PframeMain()->SetMessageText(AFX_IDS_IDLEMESSAGE);
  209. PframeMain()->UpdateWindow();
  210. m_bInitializing = FALSE;
  211. return bSuccess;
  212. } //*** CClusterDoc::OnOpenDocument()
  213. /////////////////////////////////////////////////////////////////////////////
  214. //++
  215. //
  216. // CClusterDoc::OnOpenDocumentWorker
  217. //
  218. // Routine Description:
  219. // Worker function for opening a cluster.
  220. //
  221. // Arguments:
  222. // lpszPathName [IN] Name of the cluster to open.
  223. //
  224. // Return Value:
  225. // None.
  226. //
  227. // Exceptions Thrown:
  228. // Any exceptions thrown by CString::operator=(), CCluster::new(),
  229. // CCluster::Init(), BuildBaseHierarchy(), or CollectClusterItems().
  230. //--
  231. /////////////////////////////////////////////////////////////////////////////
  232. void CClusterDoc::OnOpenDocumentWorker(LPCTSTR lpszPathName)
  233. {
  234. // Set the node name to the path name.
  235. m_strNode = lpszPathName;
  236. // Delete the contents to start out with an empty document.
  237. DeleteContents();
  238. m_bClusterAvailable = TRUE;
  239. // Create a new cluster object.
  240. m_pciCluster = new CCluster;
  241. if ( m_pciCluster == NULL )
  242. {
  243. AfxThrowMemoryException();
  244. } // if: error allocating the cluster object
  245. PciCluster()->AddRef();
  246. PciCluster()->Init(this, lpszPathName, GetClusterAdminApp()->HOpenedCluster());
  247. // Build the base hierarchy.
  248. BuildBaseHierarchy();
  249. // Collect the items in the cluster and build the hierarchy.
  250. CollectClusterItems();
  251. // Collect network priority list.
  252. PciCluster()->CollectNetworkPriority(NULL);
  253. // Open new windows if there were more open when we exited.
  254. {
  255. int iwin;
  256. int cwin;
  257. CString strSection;
  258. strSection = REGPARAM_CONNECTIONS _T("\\") + StrNode();
  259. cwin = AfxGetApp()->GetProfileInt(strSection, REGPARAM_WINDOW_COUNT, 1);
  260. for (iwin = 1 ; iwin < cwin ; iwin++)
  261. AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_WINDOW_NEW, NULL);
  262. } // Open new windows if there were more open when we exited
  263. // Initialize the frame window.
  264. {
  265. POSITION pos;
  266. CView * pview;
  267. CSplitterFrame * pframe;
  268. pos = GetFirstViewPosition();
  269. pview = GetNextView(pos);
  270. ASSERT_VALID(pview);
  271. pframe = (CSplitterFrame *) pview->GetParentFrame();
  272. ASSERT_KINDOF(CSplitterFrame, pframe);
  273. pframe->InitFrame(this);
  274. } // Initialize the frame window
  275. } //*** CClusterDoc::OnOpenDocumentWorker()
  276. /////////////////////////////////////////////////////////////////////////////
  277. //++
  278. //
  279. // CClusterDoc::OnCloseDocument
  280. //
  281. // Routine Description:
  282. // Close a cluster.
  283. //
  284. // Arguments:
  285. // None.
  286. //
  287. // Return Value:
  288. // None.
  289. //
  290. //--
  291. /////////////////////////////////////////////////////////////////////////////
  292. void CClusterDoc::OnCloseDocument(void)
  293. {
  294. TraceMenu(g_tagDocMenu, AfxGetMainWnd()->GetMenu(), _T("OnCloseDocument menu: "));
  295. m_bUpdateFrameNumber = FALSE;
  296. CDocument::OnCloseDocument();
  297. TraceMenu(g_tagDocMenu, AfxGetMainWnd()->GetMenu(), _T("Post-OnCloseDocument menu: "));
  298. } //*** CClusterDoc::OnCloseDocument()
  299. /////////////////////////////////////////////////////////////////////////////
  300. //++
  301. //
  302. // CClusterDoc::SaveSettings
  303. //
  304. // Routine Description:
  305. // Save settings so they can be restored later.
  306. //
  307. // Arguments:
  308. // None.
  309. //
  310. // Return Value:
  311. // None.
  312. //
  313. //--
  314. /////////////////////////////////////////////////////////////////////////////
  315. void CClusterDoc::SaveSettings(void)
  316. {
  317. int cwin = 0;
  318. POSITION pos;
  319. CView * pview;
  320. CString strSection;
  321. try
  322. {
  323. // Save the number of windows open on this document.
  324. strSection = REGPARAM_CONNECTIONS _T("\\") + StrNode();
  325. pos = GetFirstViewPosition();
  326. while (pos != NULL)
  327. {
  328. pview = GetNextView(pos);
  329. ASSERT_VALID(pview);
  330. if (pview->IsKindOf(RUNTIME_CLASS(CClusterTreeView)))
  331. cwin++;
  332. } // while: more views in the list
  333. AfxGetApp()->WriteProfileInt(strSection, REGPARAM_WINDOW_COUNT, cwin);
  334. } // try
  335. catch (CException * pe)
  336. {
  337. pe->Delete();
  338. } // catch: CException
  339. } //*** CClusterDoc::SaveSettings()
  340. /////////////////////////////////////////////////////////////////////////////
  341. //++
  342. //
  343. // CClusterDoc::BuildBaseHierarchy
  344. //
  345. // Routine Description:
  346. // Build the base hierarchy. This hierarchy consists of tree items
  347. // for the hierarchy and list items for what is displayed in the list
  348. // view but does not contain any items for specific objects, other
  349. // than the cluster itself.
  350. //
  351. // Arguments:
  352. // None.
  353. //
  354. // Return Value:
  355. // dwStatus Status of the operation: 0 if successful, !0 otherwise.
  356. //
  357. //--
  358. /////////////////////////////////////////////////////////////////////////////
  359. void CClusterDoc::BuildBaseHierarchy(void)
  360. {
  361. ASSERT_VALID(PciCluster());
  362. ASSERT(PtiCluster() == NULL);
  363. // Create the root cluster item.
  364. {
  365. ASSERT_VALID(PciCluster());
  366. PciCluster()->ReadItem();
  367. m_ptiCluster = new CTreeItem(NULL, PciCluster());
  368. if ( m_ptiCluster == NULL )
  369. {
  370. AfxThrowMemoryException();
  371. } // if: error allocating tree item
  372. m_ptiCluster->AddRef();
  373. ASSERT_VALID(PtiCluster());
  374. PciCluster()->AddTreeItem(PtiCluster());
  375. PtiCluster()->Init();
  376. PtiCluster()->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  377. // PtiCluster()->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  378. PtiCluster()->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  379. PtiCluster()->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  380. } // Create the root cluster item
  381. // Add the Groups container item under the cluster.
  382. {
  383. CTreeItem * ptiGroups;
  384. // Create the Groups container item.
  385. ptiGroups = PtiCluster()->PtiAddChild(IDS_TREEITEM_GROUPS);
  386. ASSERT_VALID(ptiGroups);
  387. ptiGroups->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  388. // ptiGroups->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  389. ptiGroups->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  390. ptiGroups->PcoliAddColumn(IDS_COLTEXT_OWNER, COLI_WIDTH_OWNER);
  391. ptiGroups->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  392. } // Add the Groups container item under the cluster
  393. // Add the Resources container item under the cluster.
  394. {
  395. CTreeItem * ptiResources;
  396. // Create the Resources container item.
  397. ptiResources = PtiCluster()->PtiAddChild(IDS_TREEITEM_RESOURCES);
  398. ASSERT_VALID(ptiResources);
  399. ptiResources->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  400. // ptiResources->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  401. ptiResources->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  402. ptiResources->PcoliAddColumn(IDS_COLTEXT_OWNER, COLI_WIDTH_OWNER);
  403. ptiResources->PcoliAddColumn(IDS_COLTEXT_GROUP, COLI_WIDTH_GROUP);
  404. ptiResources->PcoliAddColumn(IDS_COLTEXT_RESTYPE, COLI_WIDTH_RESTYPE);
  405. ptiResources->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  406. } // Add the Resources container item under the cluster
  407. // Add the Cluster Configuration container item under the cluster.
  408. {
  409. CTreeItem * ptiClusCfg;
  410. // Create the Cluster Configuration container item.
  411. ptiClusCfg = PtiCluster()->PtiAddChild(IDS_TREEITEM_CLUSTER_CONFIG);
  412. ASSERT_VALID(ptiClusCfg);
  413. ptiClusCfg->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  414. // ptiClusCfg->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  415. ptiClusCfg->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  416. // Add the Resources Types container item under the Cluster Configuration container.
  417. {
  418. CTreeItem * ptiResTypes;
  419. // Create the Resources Types container item.
  420. ptiResTypes = ptiClusCfg->PtiAddChild(IDS_TREEITEM_RESTYPES);
  421. ASSERT_VALID(ptiResTypes);
  422. ptiResTypes->PcoliAddColumn(IDS_COLTEXT_DISPLAY_NAME, COLI_WIDTH_DISPLAY_NAME);
  423. // ptiResTypes->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  424. // ptiResTypes->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  425. ptiResTypes->PcoliAddColumn(IDS_COLTEXT_RESDLL, COLI_WIDTH_RESDLL);
  426. ptiResTypes->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  427. } // Add the Resources Types container item under the Cluster Configuration container
  428. // Add the Networks container item under the Cluster Configuration container.
  429. {
  430. CTreeItem * ptiNetworks;
  431. // Create the Networks container item.
  432. ptiNetworks = ptiClusCfg->PtiAddChild(IDS_TREEITEM_NETWORKS);
  433. ASSERT_VALID(ptiNetworks);
  434. ptiNetworks->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  435. // ptiNetworks->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  436. ptiNetworks->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  437. ptiNetworks->PcoliAddColumn(IDS_COLTEXT_ROLE, COLI_WIDTH_NET_ROLE);
  438. // ptiNetworks->PcoliAddColumn(IDS_COLTEXT_ADDRESS, COLI_WIDTH_NET_ADDRESS);
  439. ptiNetworks->PcoliAddColumn(IDS_COLTEXT_MASK, COLI_WIDTH_NET_MASK);
  440. ptiNetworks->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  441. } // Add the Networks container item under the Cluster Configuration container
  442. // Add the Network Interfaces container item under the Cluster Configuration container.
  443. {
  444. CTreeItem * ptiNetworkInterfacess;
  445. // Create the Network Interfaces container item.
  446. ptiNetworkInterfacess = ptiClusCfg->PtiAddChild(IDS_TREEITEM_NETIFACES);
  447. ASSERT_VALID(ptiNetworkInterfacess);
  448. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_NODE, COLI_WIDTH_NODE);
  449. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_NETWORK, COLI_WIDTH_NETWORK);
  450. // ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  451. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  452. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_ADAPTER, COLI_WIDTH_NET_ADAPTER);
  453. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_ADDRESS, COLI_WIDTH_NET_ADDRESS);
  454. ptiNetworkInterfacess->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  455. } // Add the Network Interfaces container item under the Cluster Configuration container
  456. } // Add the Cluster Configuration container item under the cluster
  457. } //*** CClusterDoc::BuildBaseHierarchy()
  458. /////////////////////////////////////////////////////////////////////////////
  459. //++
  460. //
  461. // CClusterDoc::CollectClusterItems
  462. //
  463. // Routine Description:
  464. // Collect items in the cluster.
  465. //
  466. // Arguments:
  467. // None.
  468. //
  469. // Return Value:
  470. // None.
  471. //
  472. // Exceptions Thrown:
  473. // CNTException Status from ClusterOpenEnum or ClusterEnum.
  474. //
  475. //--
  476. /////////////////////////////////////////////////////////////////////////////
  477. void CClusterDoc::CollectClusterItems(void)
  478. {
  479. DWORD dwStatus;
  480. HCLUSENUM hclusenum;
  481. ClusEnumType cet;
  482. int ienum;
  483. LPWSTR pwszName = NULL;
  484. DWORD cchName;
  485. DWORD cchmacName;
  486. // Open the enumeration.
  487. hclusenum = ClusterOpenEnum(
  488. Hcluster(),
  489. ( CLUSTER_ENUM_NODE
  490. | CLUSTER_ENUM_GROUP
  491. | CLUSTER_ENUM_RESOURCE
  492. | CLUSTER_ENUM_RESTYPE
  493. | CLUSTER_ENUM_NETWORK
  494. | CLUSTER_ENUM_NETINTERFACE
  495. )
  496. );
  497. if (hclusenum == NULL)
  498. ThrowStaticException(GetLastError(), IDS_OPEN_CLUSTER_ENUM_ERROR, StrName());
  499. try
  500. {
  501. // Allocate a buffer for object names.
  502. cchmacName = 128;
  503. pwszName = new WCHAR[cchmacName];
  504. if ( pwszName == NULL )
  505. {
  506. AfxThrowMemoryException();
  507. } // if: error allocating the name buffer
  508. // Loop through the enumeration and add each item to the appropriate list.
  509. for (ienum = 0 ; ; ienum++)
  510. {
  511. cchName = cchmacName;
  512. dwStatus = ClusterEnum(hclusenum, ienum, &cet, pwszName, &cchName);
  513. if (dwStatus == ERROR_MORE_DATA)
  514. {
  515. Trace(g_tagDoc, _T("OnOpenDocument() - name buffer too small. Expanding from %d to %d"), cchmacName, cchName);
  516. delete [] pwszName;
  517. pwszName = NULL;
  518. cchmacName = cchName + 1;
  519. pwszName = new WCHAR[cchmacName];
  520. if ( pwszName == NULL )
  521. {
  522. AfxThrowMemoryException();
  523. } // if: error allocating the name buffer
  524. cchName = cchmacName;
  525. dwStatus = ClusterEnum(hclusenum, ienum, &cet, pwszName, &cchName);
  526. } // if: name buffer was too small
  527. if (dwStatus == ERROR_NO_MORE_ITEMS)
  528. break;
  529. else if (dwStatus != ERROR_SUCCESS)
  530. ThrowStaticException(dwStatus, IDS_ENUM_CLUSTER_ERROR, StrName());
  531. switch (cet)
  532. {
  533. case CLUSTER_ENUM_NODE:
  534. PciAddNewNode(pwszName);
  535. break;
  536. case CLUSTER_ENUM_GROUP:
  537. PciAddNewGroup(pwszName);
  538. break;
  539. case CLUSTER_ENUM_RESOURCE:
  540. PciAddNewResource(pwszName);
  541. break;
  542. case CLUSTER_ENUM_RESTYPE:
  543. PciAddNewResourceType(pwszName);
  544. break;
  545. case CLUSTER_ENUM_NETWORK:
  546. PciAddNewNetwork(pwszName);
  547. break;
  548. case CLUSTER_ENUM_NETINTERFACE:
  549. PciAddNewNetInterface(pwszName);
  550. break;
  551. default:
  552. Trace(g_tagDoc, _T("OnOpenDocument() - Unknown cluster enumeration type '%d'"), cet);
  553. ASSERT(0);
  554. break;
  555. } // switch: cet
  556. } // for: each item enumerated
  557. // Initialize all the cluster items.
  558. InitNodes();
  559. InitGroups();
  560. InitResourceTypes();
  561. InitResources();
  562. InitNetworks();
  563. InitNetInterfaces();
  564. // Deallocate our name buffer.
  565. delete [] pwszName;
  566. // Close the enumerator.
  567. ClusterCloseEnum(hclusenum);
  568. } // try
  569. catch (CException *)
  570. {
  571. delete [] pwszName;
  572. ClusterCloseEnum(hclusenum);
  573. throw;
  574. } // catch: any exception
  575. } //*** CClusterDoc::CollectClusterItems()
  576. /////////////////////////////////////////////////////////////////////////////
  577. //++
  578. //
  579. // CClusterDoc::PciAddNewNode
  580. //
  581. // Routine Description:
  582. // Add a new node to the list of nodes.
  583. //
  584. // Arguments:
  585. // pszName [IN] Name of the node.
  586. //
  587. // Return Value:
  588. // pci Cluster item for the new node.
  589. //
  590. //--
  591. /////////////////////////////////////////////////////////////////////////////
  592. CClusterNode * CClusterDoc::PciAddNewNode(IN LPCTSTR pszName)
  593. {
  594. CClusterNode * pciNewNode = NULL;
  595. CClusterNode * pciRetNode = NULL;
  596. CClusterNode * pciOldNode = NULL;
  597. CActiveGroups * pciActiveGroups = NULL;
  598. CTreeItem * ptiActiveGroups = NULL;
  599. ASSERT(pszName != NULL);
  600. ASSERT(*pszName != NULL);
  601. ASSERT_VALID(PtiCluster());
  602. ASSERT(LpciNodes().PciNodeFromName(pszName) == NULL);
  603. // Display a message on the status bar.
  604. {
  605. CString strStatusBarText;
  606. strStatusBarText.FormatMessage(IDS_SB_ADDING_NODE, pszName, StrNode());
  607. PframeMain()->SetMessageText(strStatusBarText);
  608. PframeMain()->UpdateWindow();
  609. } // Display a message on the status bar
  610. try
  611. {
  612. // If there is an item with that name, delete it.
  613. pciOldNode = LpciNodes().PciNodeFromName(pszName);
  614. if (pciOldNode != NULL)
  615. {
  616. pciOldNode->Delete();
  617. pciOldNode = NULL;
  618. } // if: already an item with that name
  619. // Allocate a new node.
  620. pciNewNode = new CClusterNode;
  621. if ( pciNewNode == NULL )
  622. {
  623. AfxThrowMemoryException();
  624. } // if: error allocating the node
  625. // Add a reference while we are working on it to prevent a delete
  626. // notification from taking us out.
  627. pciNewNode->AddRef();
  628. // Initialize the node.
  629. pciNewNode->Init(this, pszName);
  630. } // try
  631. catch (CNTException * pnte)
  632. {
  633. if (pnte->Sc() == RPC_S_CALL_FAILED)
  634. {
  635. if (!m_bIgnoreErrors)
  636. pnte->ReportError();
  637. delete pciNewNode;
  638. throw;
  639. } // if: RPC call failed error
  640. else if (pnte->Sc() != ERROR_FILE_NOT_FOUND)
  641. {
  642. ID id = IdProcessNewObjectError(pnte);
  643. if (id == IDNO)
  644. {
  645. delete pciNewNode;
  646. throw;
  647. } // if: user doesn't want to ignore error
  648. } // else if: error is NOT node not found
  649. else
  650. {
  651. delete pciNewNode;
  652. pnte->Delete();
  653. return NULL;
  654. } // else: object not found
  655. pnte->Delete();
  656. } // catch: CNTException
  657. catch (CException * pe)
  658. {
  659. ID id = IdProcessNewObjectError(pe);
  660. if (id == IDNO)
  661. {
  662. delete pciNewNode;
  663. throw;
  664. } // if: user doesn't want to ignore error
  665. pe->Delete();
  666. if (pciNewNode == NULL)
  667. return NULL;
  668. } // catch: CException
  669. try
  670. {
  671. // Add the node to the list.
  672. {
  673. POSITION posPci;
  674. POSITION posCurPci;
  675. posPci = LpciNodes().GetHeadPosition();
  676. while (posPci != NULL)
  677. {
  678. posCurPci = posPci;
  679. pciOldNode = (CClusterNode *) LpciNodes().GetNext(posPci);
  680. ASSERT_VALID(pciOldNode);
  681. if (pciOldNode->StrName().CompareNoCase(pszName) > 0)
  682. {
  683. LpciNodes().InsertBefore(posCurPci, pciNewNode);
  684. break;
  685. } // if: new node before this node
  686. pciOldNode = NULL;
  687. } // while: more items in the list
  688. if (pciOldNode == NULL)
  689. LpciNodes().AddTail(pciNewNode);
  690. } // Add the node to the list
  691. // Save this node as a return value now that we have added it to the list
  692. pciRetNode = pciNewNode;
  693. pciNewNode = NULL;
  694. // Insert the item in the tree.
  695. {
  696. CTreeItem * ptiNode;
  697. CTreeItem * ptiChild;
  698. ptiNode = PtiCluster()->PtiAddChildBefore(pciOldNode, pciRetNode);
  699. ASSERT_VALID(ptiNode);
  700. ptiNode->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  701. // Add the Active Groups container under the node.
  702. {
  703. CString strName;
  704. // Create the Active Groups container cluster item.
  705. strName.LoadString(IDS_TREEITEM_ACTIVEGROUPS);
  706. pciActiveGroups = new CActiveGroups;
  707. if ( pciActiveGroups == NULL )
  708. {
  709. AfxThrowMemoryException();
  710. } // if: Error allocating the active groups objct
  711. pciActiveGroups->Init(this, strName, pciRetNode);
  712. // Add the tree item for the container.
  713. ptiActiveGroups = ptiNode->PtiAddChild(pciActiveGroups, TRUE /*bTakeOwnership*/);
  714. ASSERT_VALID(ptiActiveGroups);
  715. ptiActiveGroups->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  716. // ptiActiveGroups->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  717. ptiActiveGroups->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  718. ptiActiveGroups->PcoliAddColumn(IDS_COLTEXT_OWNER, COLI_WIDTH_OWNER);
  719. ptiActiveGroups->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  720. } // Add the Active Groups container under the node.
  721. // Add the Active Resources container under the node.
  722. {
  723. ptiChild = ptiNode->PtiAddChild(IDS_TREEITEM_ACTIVERESOURCES);
  724. ASSERT_VALID(ptiChild);
  725. ptiChild->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  726. // ptiChild->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  727. ptiChild->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  728. ptiChild->PcoliAddColumn(IDS_COLTEXT_OWNER, COLI_WIDTH_OWNER);
  729. ptiChild->PcoliAddColumn(IDS_COLTEXT_GROUP, COLI_WIDTH_GROUP);
  730. ptiChild->PcoliAddColumn(IDS_COLTEXT_RESTYPE, COLI_WIDTH_RESTYPE);
  731. ptiChild->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  732. } // Add the Active Resources container under the node.
  733. // Add the Network Interfaces container under the node.
  734. {
  735. ptiChild = ptiNode->PtiAddChild(IDS_TREEITEM_NETIFACES);
  736. ASSERT_VALID(ptiChild);
  737. ptiChild->PcoliAddColumn(IDS_COLTEXT_NODE, COLI_WIDTH_NODE);
  738. ptiChild->PcoliAddColumn(IDS_COLTEXT_NETWORK, COLI_WIDTH_NETWORK);
  739. // ptiChild->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  740. ptiChild->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  741. ptiChild->PcoliAddColumn(IDS_COLTEXT_ADAPTER, COLI_WIDTH_NET_ADAPTER);
  742. ptiChild->PcoliAddColumn(IDS_COLTEXT_ADDRESS, COLI_WIDTH_NET_ADDRESS);
  743. ptiChild->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  744. } // Add the Network Interfaces container under the node
  745. // Add the Physical Devices container under the node.
  746. {
  747. // ptiChild = ptiNode->PtiAddChild(IDS_TREEITEM_PHYSDEVS);
  748. // ASSERT_VALID(ptiChild);
  749. // AddDefaultColumns(ptiChild);
  750. } // Add the Physical Devices container under the node.
  751. } // Insert the item in the tree
  752. } // try
  753. catch (CException * pe)
  754. {
  755. // If the Active Groups container has been created, clean up the
  756. // reference to the node object we are creating. If the tree
  757. // item hasn't been created yet, we still own the cluster item,
  758. // so delete that as well.
  759. if (pciActiveGroups != NULL)
  760. {
  761. pciActiveGroups->Cleanup();
  762. if (ptiActiveGroups == NULL)
  763. delete pciActiveGroups;
  764. } // if: Active Groups container created
  765. delete pciNewNode;
  766. ID id = IdProcessNewObjectError(pe);
  767. if (id == IDNO)
  768. throw;
  769. pe->Delete();
  770. } // catch: CException
  771. if (pciRetNode != NULL)
  772. pciRetNode->Release();
  773. return pciRetNode;
  774. } //*** CClusterDoc::PciAddNewNode()
  775. /////////////////////////////////////////////////////////////////////////////
  776. //++
  777. //
  778. // CClusterDoc::PciAddNewGroup
  779. //
  780. // Routine Description:
  781. // Add a new group to the list of groups.
  782. //
  783. // Arguments:
  784. // pszName [IN] Name of the group.
  785. //
  786. // Return Value:
  787. // pci Cluster item for the new group.
  788. //
  789. //--
  790. /////////////////////////////////////////////////////////////////////////////
  791. CGroup * CClusterDoc::PciAddNewGroup(IN LPCTSTR pszName)
  792. {
  793. CGroup * pciNewGroup = NULL;
  794. CGroup * pciRetGroup = NULL;
  795. CGroup * pciOldGroup = NULL;
  796. ASSERT(pszName != NULL);
  797. ASSERT(*pszName != NULL);
  798. // Display a message on the status bar.
  799. {
  800. CString strStatusBarText;
  801. strStatusBarText.FormatMessage(IDS_SB_ADDING_GROUP, pszName, StrNode());
  802. PframeMain()->SetMessageText(strStatusBarText);
  803. PframeMain()->UpdateWindow();
  804. } // Display a message on the status bar
  805. try
  806. {
  807. // If there is an item with that name, delete it.
  808. pciOldGroup = LpciGroups().PciGroupFromName(pszName);
  809. if (pciOldGroup != NULL)
  810. {
  811. Trace(g_tagGroup, _T("Deleting existing group '%s' (%x) before adding new instance"), pszName, pciOldGroup);
  812. pciOldGroup->Delete();
  813. pciOldGroup = NULL;
  814. } // if: already an item with that name
  815. // Allocate a new group.
  816. pciNewGroup = new CGroup;
  817. if ( pciNewGroup == NULL )
  818. {
  819. AfxThrowMemoryException();
  820. } // if: error allocating the group object
  821. // Add a reference while we are working on it to prevent a delete
  822. // notification from taking us out.
  823. pciNewGroup->AddRef();
  824. // Initialize the group and add it to the list.
  825. pciNewGroup->Init(this, pszName);
  826. } // try
  827. catch (CNTException * pnte)
  828. {
  829. if (pnte->Sc() == RPC_S_CALL_FAILED)
  830. {
  831. if (!m_bIgnoreErrors)
  832. pnte->ReportError();
  833. delete pciNewGroup;
  834. throw;
  835. } // if: RPC call failed error
  836. else if (pnte->Sc() != ERROR_GROUP_NOT_FOUND)
  837. {
  838. ID id = IdProcessNewObjectError(pnte);
  839. if (id == IDNO)
  840. {
  841. delete pciNewGroup;
  842. throw;
  843. } // if: user doesn't want to ignore error
  844. } // else if: error is NOT group not found
  845. else
  846. {
  847. delete pciNewGroup;
  848. pnte->Delete();
  849. return NULL;
  850. } // else: object not found
  851. pnte->Delete();
  852. } // catch: CNTException
  853. catch (CException * pe)
  854. {
  855. ID id = IdProcessNewObjectError(pe);
  856. if (id == IDNO)
  857. {
  858. delete pciNewGroup;
  859. throw;
  860. } // if: user doesn't want to ignore error
  861. pe->Delete();
  862. if (pciNewGroup == NULL)
  863. return NULL;
  864. } // catch: CException
  865. try
  866. {
  867. // Add the group to the list.
  868. {
  869. POSITION posPci;
  870. POSITION posCurPci;
  871. posPci = LpciGroups().GetHeadPosition();
  872. while (posPci != NULL)
  873. {
  874. posCurPci = posPci;
  875. pciOldGroup = (CGroup *) LpciGroups().GetNext(posPci);
  876. ASSERT_VALID(pciOldGroup);
  877. if (pciOldGroup->StrName().CompareNoCase(pszName) > 0)
  878. {
  879. LpciGroups().InsertBefore(posCurPci, pciNewGroup);
  880. break;
  881. } // if: new group before this group
  882. pciOldGroup = NULL;
  883. } // while: more items in the list
  884. if (pciOldGroup == NULL)
  885. LpciGroups().AddTail(pciNewGroup);
  886. } // Add the group to the list
  887. // Save this group as a return value now that we have added it to the list
  888. pciRetGroup = pciNewGroup;
  889. pciNewGroup = NULL;
  890. // Insert the item in the tree.
  891. {
  892. CTreeItem * ptiGroups;
  893. CTreeItem * ptiGroup;
  894. // Find the Groups container tree item.
  895. ptiGroups = PtiCluster()->PtiChildFromName(IDS_TREEITEM_GROUPS);
  896. ASSERT_VALID(ptiGroups);
  897. // Add the item before the found item we inserted it into in the groups list.
  898. ptiGroup = ptiGroups->PtiAddChildBefore(pciOldGroup, pciRetGroup);
  899. ASSERT_VALID(ptiGroup);
  900. ptiGroup->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  901. // ptiGroup->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  902. ptiGroup->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  903. ptiGroup->PcoliAddColumn(IDS_COLTEXT_OWNER, COLI_WIDTH_OWNER);
  904. ptiGroup->PcoliAddColumn(IDS_COLTEXT_RESTYPE, COLI_WIDTH_RESTYPE);
  905. ptiGroup->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  906. } // Insert the item in the tree
  907. } // try
  908. catch (CException * pe)
  909. {
  910. delete pciNewGroup;
  911. ID id = IdProcessNewObjectError(pe);
  912. if (id == IDNO)
  913. throw;
  914. pe->Delete();
  915. } // catch: CException
  916. if (pciRetGroup != NULL)
  917. pciRetGroup->Release();
  918. return pciRetGroup;
  919. } //*** CClusterDoc::PciAddNewGroup()
  920. /////////////////////////////////////////////////////////////////////////////
  921. //++
  922. //
  923. // CClusterDoc::PciAddNewResource
  924. //
  925. // Routine Description:
  926. // Add a new resource to the list of groups.
  927. //
  928. // Arguments:
  929. // pszName [IN] Name of the resource.
  930. //
  931. // Return Value:
  932. // pci Cluster item for the new resource.
  933. //
  934. //--
  935. /////////////////////////////////////////////////////////////////////////////
  936. CResource * CClusterDoc::PciAddNewResource(IN LPCTSTR pszName)
  937. {
  938. CResource * pciNewRes = NULL;
  939. CResource * pciRetRes = NULL;
  940. CResource * pciOldRes;
  941. ASSERT(pszName != NULL);
  942. ASSERT(*pszName != NULL);
  943. // Display a message on the status bar.
  944. {
  945. CString strStatusBarText;
  946. strStatusBarText.FormatMessage(IDS_SB_ADDING_RESOURCE, pszName, StrNode());
  947. PframeMain()->SetMessageText(strStatusBarText);
  948. PframeMain()->UpdateWindow();
  949. } // Display a message on the status bar
  950. try
  951. {
  952. // If there is an item with that name, delete it.
  953. pciOldRes = LpciResources().PciResFromName(pszName);
  954. if (pciOldRes != NULL)
  955. {
  956. if (pciOldRes->BInitializing())
  957. return pciOldRes;
  958. Trace(g_tagResource, _T("Deleting existing resource '%s' (%x) before adding new instance"), pszName, pciOldRes);
  959. pciOldRes->Delete();
  960. pciOldRes = NULL;
  961. } // if: already an item with that name
  962. // Allocate a new resource.
  963. pciNewRes = new CResource;
  964. if ( pciNewRes == NULL )
  965. {
  966. AfxThrowMemoryException();
  967. } // if: error allocating the resource object
  968. // Add a reference while we are working on it to prevent a delete
  969. // notification from taking us out.
  970. pciNewRes->AddRef();
  971. // Initialize the resource and add it to the list.
  972. pciNewRes->Init(this, pszName);
  973. } // try
  974. catch (CNTException * pnte)
  975. {
  976. //DebugBreak();
  977. if (pnte->Sc() == RPC_S_CALL_FAILED)
  978. {
  979. if (!m_bIgnoreErrors)
  980. pnte->ReportError();
  981. delete pciNewRes;
  982. throw;
  983. } // if: RPC call failed error
  984. else if (pnte->Sc() != ERROR_RESOURCE_NOT_FOUND)
  985. {
  986. ID id = IdProcessNewObjectError(pnte);
  987. if (id == IDNO)
  988. {
  989. delete pciNewRes;
  990. throw;
  991. } // if: user doesn't want to ignore error
  992. } // else if: error is NOT resource not found
  993. else
  994. {
  995. delete pciNewRes;
  996. pnte->Delete();
  997. return NULL;
  998. } // else: object not found
  999. pnte->Delete();
  1000. } // catch: CNTException
  1001. catch (CException * pe)
  1002. {
  1003. //DebugBreak();
  1004. ID id = IdProcessNewObjectError(pe);
  1005. if (id == IDNO)
  1006. {
  1007. delete pciNewRes;
  1008. throw;
  1009. } // if: user doesn't want to ignore error
  1010. pe->Delete();
  1011. if (pciNewRes == NULL)
  1012. return NULL;
  1013. } // catch: CException
  1014. try
  1015. {
  1016. // Add the resource to the list.
  1017. {
  1018. POSITION posPci;
  1019. POSITION posCurPci;
  1020. CResource * pciOldRes = NULL;
  1021. posPci = LpciResources().GetHeadPosition();
  1022. while (posPci != NULL)
  1023. {
  1024. posCurPci = posPci;
  1025. pciOldRes = (CResource *) LpciResources().GetNext(posPci);
  1026. ASSERT_VALID(pciOldRes);
  1027. if (pciOldRes->StrName().CompareNoCase(pszName) > 0)
  1028. {
  1029. LpciResources().InsertBefore(posCurPci, pciNewRes);
  1030. break;
  1031. } // if: new resource before this resource
  1032. pciOldRes = NULL;
  1033. } // while: more items in the list
  1034. if (pciOldRes == NULL)
  1035. LpciResources().AddTail(pciNewRes);
  1036. } // Add the resource to the list
  1037. // Save this resource as a return value now that we have added it to the list
  1038. pciRetRes = pciNewRes;
  1039. pciNewRes = NULL;
  1040. // Insert the item in the tree.
  1041. {
  1042. CTreeItem * ptiResources;
  1043. // Find the Resources container tree item.
  1044. ptiResources = PtiCluster()->PtiChildFromName(IDS_TREEITEM_RESOURCES);
  1045. ASSERT_VALID(ptiResources);
  1046. // Add the item to the list of children.
  1047. VERIFY(ptiResources->PliAddChild(pciRetRes) != NULL);
  1048. } // Insert the item in the tree
  1049. } // try
  1050. catch (CException * pe)
  1051. {
  1052. delete pciNewRes;
  1053. ID id = IdProcessNewObjectError(pe);
  1054. if (id == IDNO)
  1055. throw;
  1056. pe->Delete();
  1057. } // catch: CException
  1058. if (pciRetRes != NULL)
  1059. pciRetRes->Release();
  1060. return pciRetRes;
  1061. } //*** CClusterDoc::PciAddNewResource()
  1062. /////////////////////////////////////////////////////////////////////////////
  1063. //++
  1064. //
  1065. // CClusterDoc::PciAddNewResourceType
  1066. //
  1067. // Routine Description:
  1068. // Add a new resource type to the list of groups.
  1069. //
  1070. // Arguments:
  1071. // pszName [IN] Name of the resource type.
  1072. //
  1073. // Return Value:
  1074. // pci Cluster item for the new resource type.
  1075. //
  1076. //--
  1077. /////////////////////////////////////////////////////////////////////////////
  1078. CResourceType * CClusterDoc::PciAddNewResourceType(IN LPCTSTR pszName)
  1079. {
  1080. CResourceType * pciNewResType = NULL;
  1081. CResourceType * pciRetResType = NULL;
  1082. CResourceType * pciOldResType;
  1083. ASSERT(pszName != NULL);
  1084. ASSERT(*pszName != NULL);
  1085. ASSERT(LpciResourceTypes().PciResTypeFromName(pszName) == NULL);
  1086. // Display a message on the status bar.
  1087. {
  1088. CString strStatusBarText;
  1089. strStatusBarText.FormatMessage(IDS_SB_ADDING_RESTYPE, pszName, StrNode());
  1090. PframeMain()->SetMessageText(strStatusBarText);
  1091. PframeMain()->UpdateWindow();
  1092. } // Display a message on the status bar
  1093. try
  1094. {
  1095. // If there is an item with that name, delete it.
  1096. pciOldResType = LpciResourceTypes().PciResTypeFromName(pszName);
  1097. if (pciOldResType != NULL)
  1098. {
  1099. pciOldResType->Delete();
  1100. pciOldResType = NULL;
  1101. } // if: already an item with that name
  1102. // Allocate a new resource type.
  1103. pciNewResType = new CResourceType;
  1104. if ( pciNewResType == NULL )
  1105. {
  1106. AfxThrowMemoryException();
  1107. } // if: error allocating the resource type object
  1108. // Add a reference while we are working on it to prevent a delete
  1109. // notification from taking us out.
  1110. pciNewResType->AddRef();
  1111. // Initialize the resource type and add it to the list.
  1112. pciNewResType->Init(this, pszName);
  1113. } // try
  1114. catch (CNTException * pnte)
  1115. {
  1116. //DebugBreak();
  1117. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1118. {
  1119. if (!m_bIgnoreErrors)
  1120. pnte->ReportError();
  1121. delete pciNewResType;
  1122. throw;
  1123. } // if: RPC call failed error
  1124. else if (pnte->Sc() != ERROR_FILE_NOT_FOUND)
  1125. {
  1126. ID id = IdProcessNewObjectError(pnte);
  1127. if (id == IDNO)
  1128. {
  1129. delete pciNewResType;
  1130. throw;
  1131. } // if: user doesn't want to ignore error
  1132. } // else if: error is NOT resource type not found
  1133. else
  1134. {
  1135. delete pciNewResType;
  1136. pnte->Delete();
  1137. return NULL;
  1138. } // else: object not found
  1139. pnte->Delete();
  1140. } // catch: CNTException
  1141. catch (CException * pe)
  1142. {
  1143. //DebugBreak();
  1144. ID id = IdProcessNewObjectError(pe);
  1145. if (id == IDNO)
  1146. {
  1147. delete pciNewResType;
  1148. throw;
  1149. } // if: user doesn't want to ignore error
  1150. pe->Delete();
  1151. if (pciNewResType == NULL)
  1152. return NULL;
  1153. } // catch: CException
  1154. try
  1155. {
  1156. // Add the resource type to the list.
  1157. {
  1158. POSITION posPci;
  1159. POSITION posCurPci;
  1160. CResourceType * pciOldResType = NULL;
  1161. posPci = LpciResourceTypes().GetHeadPosition();
  1162. while (posPci != NULL)
  1163. {
  1164. posCurPci = posPci;
  1165. pciOldResType = (CResourceType *) LpciResourceTypes().GetNext(posPci);
  1166. ASSERT_VALID(pciOldResType);
  1167. if (pciOldResType->StrName().CompareNoCase(pszName) > 0)
  1168. {
  1169. LpciResourceTypes().InsertBefore(posCurPci, pciNewResType);
  1170. break;
  1171. } // if: new resource type before this resource type
  1172. pciOldResType = NULL;
  1173. } // while: more items in the list
  1174. if (pciOldResType == NULL)
  1175. LpciResourceTypes().AddTail(pciNewResType);
  1176. } // Add the resource type to the list
  1177. // Save this resource type as a return value now that we have added it to the list
  1178. pciRetResType = pciNewResType;
  1179. pciNewResType = NULL;
  1180. // Insert the item in the tree.
  1181. {
  1182. CTreeItem * ptiClusCfg;
  1183. CTreeItem * ptiResTypes;
  1184. // Find the Resource Types container tree item.
  1185. ptiClusCfg = PtiCluster()->PtiChildFromName(IDS_TREEITEM_CLUSTER_CONFIG);
  1186. ASSERT_VALID(ptiClusCfg);
  1187. ptiResTypes = ptiClusCfg->PtiChildFromName(IDS_TREEITEM_RESTYPES);
  1188. ASSERT_VALID(ptiResTypes);
  1189. // Add the item to the list of children.
  1190. VERIFY(ptiResTypes->PliAddChild(pciRetResType) != NULL);
  1191. } // Insert the item in the tree
  1192. } // try
  1193. catch (CException * pe)
  1194. {
  1195. delete pciNewResType;
  1196. ID id = IdProcessNewObjectError(pe);
  1197. if (id == IDNO)
  1198. throw;
  1199. pe->Delete();
  1200. } // catch: CException
  1201. if (pciRetResType != NULL)
  1202. pciRetResType->Release();
  1203. return pciRetResType;
  1204. } //*** CClusterDoc::PciAddNewResourceType()
  1205. /////////////////////////////////////////////////////////////////////////////
  1206. //++
  1207. //
  1208. // CClusterDoc::PciAddNewNetwork
  1209. //
  1210. // Routine Description:
  1211. // Add a new network to the list of networks.
  1212. //
  1213. // Arguments:
  1214. // pszName [IN] Name of the networks.
  1215. //
  1216. // Return Value:
  1217. // pci Cluster item for the new network.
  1218. //
  1219. //--
  1220. /////////////////////////////////////////////////////////////////////////////
  1221. CNetwork * CClusterDoc::PciAddNewNetwork(IN LPCTSTR pszName)
  1222. {
  1223. CNetwork * pciNewNetwork = NULL;
  1224. CNetwork * pciRetNetwork = NULL;
  1225. CNetwork * pciOldNetwork = NULL;
  1226. ASSERT(pszName != NULL);
  1227. ASSERT(*pszName != NULL);
  1228. ASSERT(LpciNetworks().PciNetworkFromName(pszName) == NULL);
  1229. // Display a message on the status bar.
  1230. {
  1231. CString strStatusBarText;
  1232. strStatusBarText.FormatMessage(IDS_SB_ADDING_NETWORK, pszName, StrNode());
  1233. PframeMain()->SetMessageText(strStatusBarText);
  1234. PframeMain()->UpdateWindow();
  1235. } // Display a message on the status bar
  1236. try
  1237. {
  1238. // If there is an item with that name, delete it.
  1239. pciOldNetwork = LpciNetworks().PciNetworkFromName(pszName);
  1240. if (pciOldNetwork != NULL)
  1241. {
  1242. Trace(g_tagNetwork, _T("Deleting existing network '%s' (%x) before adding new instance"), pszName, pciOldNetwork);
  1243. pciOldNetwork->Delete();
  1244. pciOldNetwork = NULL;
  1245. } // if: already an item with that name
  1246. // Allocate a new network.
  1247. pciNewNetwork = new CNetwork;
  1248. if ( pciNewNetwork == NULL )
  1249. {
  1250. AfxThrowMemoryException();
  1251. } // if: error allocating the network object
  1252. // Add a reference while we are working on it to prevent a delete
  1253. // notification from taking us out.
  1254. pciNewNetwork->AddRef();
  1255. // Initialize the network.
  1256. pciNewNetwork->Init(this, pszName);
  1257. } // try
  1258. catch (CNTException * pnte)
  1259. {
  1260. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1261. {
  1262. if (!m_bIgnoreErrors)
  1263. pnte->ReportError();
  1264. delete pciNewNetwork;
  1265. throw;
  1266. } // if: RPC call failed error
  1267. ID id = IdProcessNewObjectError(pnte);
  1268. if (id == IDNO)
  1269. {
  1270. delete pciNewNetwork;
  1271. throw;
  1272. } // if: user doesn't want to ignore error
  1273. pnte->Delete();
  1274. } // catch: CNTException
  1275. catch (CException * pe)
  1276. {
  1277. ID id = IdProcessNewObjectError(pe);
  1278. if (id == IDNO)
  1279. {
  1280. delete pciNewNetwork;
  1281. throw;
  1282. } // if: user doesn't want to ignore error
  1283. pe->Delete();
  1284. if (pciNewNetwork == NULL)
  1285. return NULL;
  1286. } // catch: CException
  1287. try
  1288. {
  1289. // Add the network to the list.
  1290. {
  1291. POSITION posPci;
  1292. POSITION posCurPci;
  1293. posPci = LpciNetworks().GetHeadPosition();
  1294. while (posPci != NULL)
  1295. {
  1296. posCurPci = posPci;
  1297. pciOldNetwork = (CNetwork *) LpciNetworks().GetNext(posPci);
  1298. ASSERT_VALID(pciOldNetwork);
  1299. if (pciOldNetwork->StrName().CompareNoCase(pszName) > 0)
  1300. {
  1301. LpciNetworks().InsertBefore(posCurPci, pciNewNetwork);
  1302. break;
  1303. } // if: new network before this network
  1304. pciOldNetwork = NULL;
  1305. } // while: more items in the list
  1306. if (pciOldNetwork == NULL)
  1307. LpciNetworks().AddTail(pciNewNetwork);
  1308. } // Add the network to the list
  1309. // Save this network as a return value now that we have added it to the list
  1310. pciRetNetwork = pciNewNetwork;
  1311. pciNewNetwork = NULL;
  1312. // Insert the item in the tree.
  1313. {
  1314. CTreeItem * ptiClusCfg;
  1315. CTreeItem * ptiNetworks;
  1316. CTreeItem * ptiNetwork;
  1317. // Find the Networks container tree item.
  1318. ptiClusCfg = PtiCluster()->PtiChildFromName(IDS_TREEITEM_CLUSTER_CONFIG);
  1319. ASSERT_VALID(ptiClusCfg);
  1320. ptiNetworks = ptiClusCfg->PtiChildFromName(IDS_TREEITEM_NETWORKS);
  1321. ASSERT_VALID(ptiNetworks);
  1322. // Add the item before the found item we inserted it into in the networks list.
  1323. ptiNetwork = ptiNetworks->PtiAddChildBefore(pciOldNetwork, pciRetNetwork);
  1324. ASSERT_VALID(ptiNetwork);
  1325. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_NODE, COLI_WIDTH_NODE);
  1326. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_NETWORK, COLI_WIDTH_NETWORK);
  1327. // ptiNetwork->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  1328. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_STATE, COLI_WIDTH_STATE);
  1329. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_ADAPTER, COLI_WIDTH_NET_ADAPTER);
  1330. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_ADDRESS, COLI_WIDTH_NET_ADDRESS);
  1331. ptiNetwork->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  1332. } // Insert the item in the tree
  1333. } // try
  1334. catch (CException * pe)
  1335. {
  1336. delete pciNewNetwork;
  1337. ID id = IdProcessNewObjectError(pe);
  1338. if (id == IDNO)
  1339. throw;
  1340. pe->Delete();
  1341. } // catch: CException
  1342. if (pciRetNetwork != NULL)
  1343. pciRetNetwork->Release();
  1344. return pciRetNetwork;
  1345. } //*** CClusterDoc::PciAddNewNetwork()
  1346. /////////////////////////////////////////////////////////////////////////////
  1347. //++
  1348. //
  1349. // CClusterDoc::PciAddNewNetInterface
  1350. //
  1351. // Routine Description:
  1352. // Add a new network interfaces to the list of network interfaces.
  1353. //
  1354. // Arguments:
  1355. // pszName [IN] Name of the network interface.
  1356. //
  1357. // Return Value:
  1358. // pci Cluster item for the new network interface.
  1359. //
  1360. //--
  1361. /////////////////////////////////////////////////////////////////////////////
  1362. CNetInterface * CClusterDoc::PciAddNewNetInterface(IN LPCTSTR pszName)
  1363. {
  1364. CNetInterface * pciNewNetIFace = NULL;
  1365. CNetInterface * pciRetNetIFace = NULL;
  1366. CNetInterface * pciOldNetIFace;
  1367. ASSERT(pszName != NULL);
  1368. ASSERT(*pszName != NULL);
  1369. ASSERT(LpciNetInterfaces().PciNetInterfaceFromName(pszName) == NULL);
  1370. // Display a message on the status bar.
  1371. {
  1372. CString strStatusBarText;
  1373. strStatusBarText.FormatMessage(IDS_SB_ADDING_NETIFACE, pszName, StrNode());
  1374. PframeMain()->SetMessageText(strStatusBarText);
  1375. PframeMain()->UpdateWindow();
  1376. } // Display a message on the status bar
  1377. try
  1378. {
  1379. // If there is an item with that name, delete it.
  1380. pciOldNetIFace = LpciNetInterfaces().PciNetInterfaceFromName(pszName);
  1381. if (pciOldNetIFace != NULL)
  1382. {
  1383. pciOldNetIFace->Delete();
  1384. pciOldNetIFace = NULL;
  1385. } // if: already an item with that name
  1386. // Allocate a new network interface.
  1387. pciNewNetIFace = new CNetInterface;
  1388. if ( pciNewNetIFace == NULL )
  1389. {
  1390. AfxThrowMemoryException();
  1391. } // if: error allocating the net interface object
  1392. // Add a reference while we are working on it to prevent a delete
  1393. // notification from taking us out.
  1394. pciNewNetIFace->AddRef();
  1395. // Initialize the network interface.
  1396. pciNewNetIFace->Init(this, pszName);
  1397. } // try
  1398. catch (CNTException * pnte)
  1399. {
  1400. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1401. {
  1402. if (!m_bIgnoreErrors)
  1403. pnte->ReportError();
  1404. delete pciNewNetIFace;
  1405. throw;
  1406. } // if: RPC call failed error
  1407. ID id = IdProcessNewObjectError(pnte);
  1408. if (id == IDNO)
  1409. {
  1410. delete pciNewNetIFace;
  1411. throw;
  1412. } // if: user doesn't want to ignore error
  1413. pnte->Delete();
  1414. } // catch: CNTException
  1415. catch (CException * pe)
  1416. {
  1417. ID id = IdProcessNewObjectError(pe);
  1418. if (id == IDNO)
  1419. {
  1420. delete pciNewNetIFace;
  1421. throw;
  1422. } // if: user doesn't want to ignore error
  1423. pe->Delete();
  1424. if (pciNewNetIFace == NULL)
  1425. return NULL;
  1426. } // catch: CException
  1427. try
  1428. {
  1429. // Add the network interface to the list.
  1430. {
  1431. POSITION posPci;
  1432. POSITION posCurPci;
  1433. CNetInterface * pciOldNetIFace = NULL;
  1434. posPci = LpciNetInterfaces().GetHeadPosition();
  1435. while (posPci != NULL)
  1436. {
  1437. posCurPci = posPci;
  1438. pciOldNetIFace = (CNetInterface *) LpciNetInterfaces().GetNext(posPci);
  1439. ASSERT_VALID(pciOldNetIFace);
  1440. if (pciOldNetIFace->StrName().CompareNoCase(pszName) > 0)
  1441. {
  1442. LpciNetInterfaces().InsertBefore(posCurPci, pciNewNetIFace);
  1443. break;
  1444. } // if: new network interfaces before this network interface
  1445. pciOldNetIFace = NULL;
  1446. } // while: more items in the list
  1447. if (pciOldNetIFace == NULL)
  1448. LpciNetInterfaces().AddTail(pciNewNetIFace);
  1449. } // Add the network interface to the list
  1450. // Save this network interface as a return value now that we have added it to the list
  1451. pciRetNetIFace = pciNewNetIFace;
  1452. pciNewNetIFace = NULL;
  1453. // Insert the item in the tree.
  1454. {
  1455. CTreeItem * ptiClusCfg;
  1456. CTreeItem * ptiNetIFaces;
  1457. // Find the Network Interfaces container tree item.
  1458. ptiClusCfg = PtiCluster()->PtiChildFromName(IDS_TREEITEM_CLUSTER_CONFIG);
  1459. ASSERT_VALID(ptiClusCfg);
  1460. ptiNetIFaces = ptiClusCfg->PtiChildFromName(IDS_TREEITEM_NETIFACES);
  1461. ASSERT_VALID(ptiNetIFaces);
  1462. // Add the item to the list of children.
  1463. VERIFY(ptiNetIFaces->PliAddChild(pciRetNetIFace) != NULL);
  1464. } // Insert the item in the tree
  1465. } // try
  1466. catch (CException * pe)
  1467. {
  1468. delete pciNewNetIFace;
  1469. ID id = IdProcessNewObjectError(pe);
  1470. if (id == IDNO)
  1471. throw;
  1472. pe->Delete();
  1473. } // catch: CException
  1474. if (pciRetNetIFace != NULL)
  1475. pciRetNetIFace->Release();
  1476. return pciRetNetIFace;
  1477. } //*** CClusterDoc::PciAddNewNetInterface()
  1478. /////////////////////////////////////////////////////////////////////////////
  1479. //++
  1480. //
  1481. // CClusterDoc::InitNodes
  1482. //
  1483. // Routine Description:
  1484. // Read item data.
  1485. //
  1486. // Arguments:
  1487. // None.
  1488. //
  1489. // Return Value:
  1490. // None.
  1491. //
  1492. //--
  1493. /////////////////////////////////////////////////////////////////////////////
  1494. void CClusterDoc::InitNodes(void)
  1495. {
  1496. POSITION pos;
  1497. CClusterNode * pci;
  1498. CNodeList & rlpci = LpciNodes();
  1499. CString strStatusBarText;
  1500. pos = rlpci.GetHeadPosition();
  1501. while (pos != NULL)
  1502. {
  1503. pci = (CClusterNode *) rlpci.GetNext(pos);
  1504. pci->AddRef();
  1505. try
  1506. {
  1507. // Display a message on the status bar.
  1508. {
  1509. strStatusBarText.FormatMessage(IDS_SB_READING_NODE, pci->StrName(), StrNode());
  1510. PframeMain()->SetMessageText(strStatusBarText);
  1511. PframeMain()->UpdateWindow();
  1512. } // Display a message on the status bar
  1513. pci->ReadItem();
  1514. } // try
  1515. catch (CNTException * pnte)
  1516. {
  1517. strStatusBarText.Empty();
  1518. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1519. {
  1520. if (!m_bIgnoreErrors)
  1521. pnte->ReportError();
  1522. pci->Release();
  1523. throw;
  1524. } // if: RPC call failed
  1525. ID id = IdProcessNewObjectError(pnte);
  1526. if (id == IDNO)
  1527. {
  1528. pci->Release();
  1529. throw;
  1530. } // if: don't ignore the error
  1531. pnte->Delete();
  1532. } // catch: CNTException
  1533. catch (CException * pe)
  1534. {
  1535. strStatusBarText.Empty();
  1536. ID id = IdProcessNewObjectError(pe);
  1537. if (id == IDNO)
  1538. {
  1539. pci->Release();
  1540. throw;
  1541. } // if: don't ignore the error
  1542. pe->Delete();
  1543. } // catch: CException
  1544. pci->Release();
  1545. } // while: more items in the list
  1546. } //*** CClusterDoc::InitNodes()
  1547. /////////////////////////////////////////////////////////////////////////////
  1548. //++
  1549. //
  1550. // CClusterDoc::InitGroups
  1551. //
  1552. // Routine Description:
  1553. // Read item data.
  1554. //
  1555. // Arguments:
  1556. // None.
  1557. //
  1558. // Return Value:
  1559. // None.
  1560. //
  1561. //--
  1562. /////////////////////////////////////////////////////////////////////////////
  1563. void CClusterDoc::InitGroups(void)
  1564. {
  1565. POSITION pos;
  1566. CGroup * pci;
  1567. CGroupList & rlpci = LpciGroups();
  1568. CString strStatusBarText;
  1569. pos = rlpci.GetHeadPosition();
  1570. while (pos != NULL)
  1571. {
  1572. pci = (CGroup *) rlpci.GetNext(pos);
  1573. pci->AddRef();
  1574. try
  1575. {
  1576. // Display a message on the status bar.
  1577. {
  1578. strStatusBarText.FormatMessage(IDS_SB_READING_GROUP, pci->StrName(), StrNode());
  1579. PframeMain()->SetMessageText(strStatusBarText);
  1580. PframeMain()->UpdateWindow();
  1581. } // Display a message on the status bar
  1582. pci->ReadItem();
  1583. } // try
  1584. catch (CNTException * pnte)
  1585. {
  1586. strStatusBarText.Empty();
  1587. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1588. {
  1589. if (!m_bIgnoreErrors)
  1590. pnte->ReportError();
  1591. pci->Release();
  1592. throw;
  1593. } // if: RPC call failed
  1594. ID id = IdProcessNewObjectError(pnte);
  1595. if (id == IDNO)
  1596. {
  1597. pci->Release();
  1598. throw;
  1599. } // if: don't ignore the error
  1600. pnte->Delete();
  1601. } // catch: CNTException
  1602. catch (CException * pe)
  1603. {
  1604. strStatusBarText.Empty();
  1605. ID id = IdProcessNewObjectError(pe);
  1606. if (id == IDNO)
  1607. {
  1608. pci->Release();
  1609. throw;
  1610. } // if: don't ignore the error
  1611. pe->Delete();
  1612. } // catch: CException
  1613. pci->Release();
  1614. } // while: more items in the list
  1615. } //*** CClusterDoc::InitGroups()
  1616. /////////////////////////////////////////////////////////////////////////////
  1617. //++
  1618. //
  1619. // CClusterDoc::InitResources
  1620. //
  1621. // Routine Description:
  1622. // Read item data.
  1623. //
  1624. // Arguments:
  1625. // None.
  1626. //
  1627. // Return Value:
  1628. // None.
  1629. //
  1630. //--
  1631. /////////////////////////////////////////////////////////////////////////////
  1632. void CClusterDoc::InitResources(void)
  1633. {
  1634. POSITION pos;
  1635. CResource * pci;
  1636. CResourceList & rlpci = LpciResources();
  1637. CString strStatusBarText;
  1638. pos = rlpci.GetHeadPosition();
  1639. while (pos != NULL)
  1640. {
  1641. pci = (CResource *) rlpci.GetNext(pos);
  1642. pci->AddRef();
  1643. try
  1644. {
  1645. // Display a message on the status bar.
  1646. {
  1647. CString strStatusBarText;
  1648. strStatusBarText.FormatMessage(IDS_SB_READING_RESOURCE, pci->StrName(), StrNode());
  1649. PframeMain()->SetMessageText(strStatusBarText);
  1650. PframeMain()->UpdateWindow();
  1651. } // Display a message on the status bar
  1652. pci->ReadItem();
  1653. } // try
  1654. catch (CNTException * pnte)
  1655. {
  1656. strStatusBarText.Empty();
  1657. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1658. {
  1659. if (!m_bIgnoreErrors)
  1660. pnte->ReportError();
  1661. pci->Release();
  1662. throw;
  1663. } // if: RPC call failed
  1664. ID id = IdProcessNewObjectError(pnte);
  1665. if (id == IDNO)
  1666. {
  1667. pci->Release();
  1668. throw;
  1669. } // if: don't ignore the error
  1670. pnte->Delete();
  1671. } // catch: CNTException
  1672. catch (CException * pe)
  1673. {
  1674. strStatusBarText.Empty();
  1675. ID id = IdProcessNewObjectError(pe);
  1676. if (id == IDNO)
  1677. {
  1678. pci->Release();
  1679. throw;
  1680. } // if: don't ignore the error
  1681. pe->Delete();
  1682. } // catch: CException
  1683. pci->Release();
  1684. } // while: more items in the list
  1685. } //*** CClusterDoc::InitResources()
  1686. /////////////////////////////////////////////////////////////////////////////
  1687. //++
  1688. //
  1689. // CClusterDoc::InitResourceTypes
  1690. //
  1691. // Routine Description:
  1692. // Read item data.
  1693. //
  1694. // Arguments:
  1695. // None.
  1696. //
  1697. // Return Value:
  1698. // None.
  1699. //
  1700. //--
  1701. /////////////////////////////////////////////////////////////////////////////
  1702. void CClusterDoc::InitResourceTypes(void)
  1703. {
  1704. POSITION pos;
  1705. CResourceType * pci;
  1706. CResourceTypeList & rlpci = LpciResourceTypes();
  1707. CString strStatusBarText;
  1708. pos = rlpci.GetHeadPosition();
  1709. while (pos != NULL)
  1710. {
  1711. pci = (CResourceType *) rlpci.GetNext(pos);
  1712. pci->AddRef();
  1713. try
  1714. {
  1715. // Display a message on the status bar.
  1716. {
  1717. CString strStatusBarText;
  1718. strStatusBarText.FormatMessage(IDS_SB_READING_RESTYPE, pci->StrName(), StrNode());
  1719. PframeMain()->SetMessageText(strStatusBarText);
  1720. PframeMain()->UpdateWindow();
  1721. } // Display a message on the status bar
  1722. pci->ReadItem();
  1723. } // try
  1724. catch (CNTException * pnte)
  1725. {
  1726. strStatusBarText.Empty();
  1727. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1728. {
  1729. if (!m_bIgnoreErrors)
  1730. pnte->ReportError();
  1731. pci->Release();
  1732. throw;
  1733. } // if: RPC call failed
  1734. ID id = IdProcessNewObjectError(pnte);
  1735. if (id == IDNO)
  1736. {
  1737. pci->Release();
  1738. throw;
  1739. } // if: don't ignore the error
  1740. pnte->Delete();
  1741. } // catch: CNTException
  1742. catch (CException * pe)
  1743. {
  1744. strStatusBarText.Empty();
  1745. ID id = IdProcessNewObjectError(pe);
  1746. if (id == IDNO)
  1747. {
  1748. pci->Release();
  1749. throw;
  1750. } // if: don't ignore the error
  1751. pe->Delete();
  1752. } // catch: CException
  1753. pci->Release();
  1754. } // while: more items in the list
  1755. } //*** CClusterDoc::InitResourceTypes()
  1756. /////////////////////////////////////////////////////////////////////////////
  1757. //++
  1758. //
  1759. // CClusterDoc::InitNetworks
  1760. //
  1761. // Routine Description:
  1762. // Read item data.
  1763. //
  1764. // Arguments:
  1765. // None.
  1766. //
  1767. // Return Value:
  1768. // None.
  1769. //
  1770. //--
  1771. /////////////////////////////////////////////////////////////////////////////
  1772. void CClusterDoc::InitNetworks(void)
  1773. {
  1774. POSITION pos;
  1775. CNetwork * pci;
  1776. CNetworkList & rlpci = LpciNetworks();
  1777. CString strStatusBarText;
  1778. pos = rlpci.GetHeadPosition();
  1779. while (pos != NULL)
  1780. {
  1781. pci = (CNetwork *) rlpci.GetNext(pos);
  1782. pci->AddRef();
  1783. try
  1784. {
  1785. // Display a message on the status bar.
  1786. {
  1787. CString strStatusBarText;
  1788. strStatusBarText.FormatMessage(IDS_SB_READING_NETWORK, pci->StrName(), StrNode());
  1789. PframeMain()->SetMessageText(strStatusBarText);
  1790. PframeMain()->UpdateWindow();
  1791. } // Display a message on the status bar
  1792. pci->ReadItem();
  1793. } // try
  1794. catch (CNTException * pnte)
  1795. {
  1796. strStatusBarText.Empty();
  1797. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1798. {
  1799. if (!m_bIgnoreErrors)
  1800. pnte->ReportError();
  1801. pci->Release();
  1802. throw;
  1803. } // if: RPC call failed
  1804. ID id = IdProcessNewObjectError(pnte);
  1805. if (id == IDNO)
  1806. {
  1807. pci->Release();
  1808. throw;
  1809. } // if: don't ignore the error
  1810. pnte->Delete();
  1811. } // catch: CNTException
  1812. catch (CException * pe)
  1813. {
  1814. strStatusBarText.Empty();
  1815. ID id = IdProcessNewObjectError(pe);
  1816. if (id == IDNO)
  1817. {
  1818. pci->Release();
  1819. throw;
  1820. } // if: don't ignore the error
  1821. pe->Delete();
  1822. } // catch: CException
  1823. pci->Release();
  1824. } // while: more items in the list
  1825. } //*** CClusterDoc::InitNetworks()
  1826. /////////////////////////////////////////////////////////////////////////////
  1827. //++
  1828. //
  1829. // CClusterDoc::InitNetInterfaces
  1830. //
  1831. // Routine Description:
  1832. // Read item data.
  1833. //
  1834. // Arguments:
  1835. // None.
  1836. //
  1837. // Return Value:
  1838. // None.
  1839. //
  1840. //--
  1841. /////////////////////////////////////////////////////////////////////////////
  1842. void CClusterDoc::InitNetInterfaces(void)
  1843. {
  1844. POSITION pos;
  1845. CNetInterface * pci;
  1846. CNetInterfaceList & rlpci = LpciNetInterfaces();
  1847. CString strStatusBarText;
  1848. pos = rlpci.GetHeadPosition();
  1849. while (pos != NULL)
  1850. {
  1851. pci = (CNetInterface *) rlpci.GetNext(pos);
  1852. pci->AddRef();
  1853. try
  1854. {
  1855. // Display a message on the status bar.
  1856. {
  1857. CString strStatusBarText;
  1858. strStatusBarText.FormatMessage(IDS_SB_READING_NETIFACE, pci->StrName(), StrNode());
  1859. PframeMain()->SetMessageText(strStatusBarText);
  1860. PframeMain()->UpdateWindow();
  1861. } // Display a message on the status bar
  1862. pci->ReadItem();
  1863. } // try
  1864. catch (CNTException * pnte)
  1865. {
  1866. strStatusBarText.Empty();
  1867. if (pnte->Sc() == RPC_S_CALL_FAILED)
  1868. {
  1869. if (!m_bIgnoreErrors)
  1870. pnte->ReportError();
  1871. pci->Release();
  1872. throw;
  1873. } // if: RPC call failed
  1874. ID id = IdProcessNewObjectError(pnte);
  1875. if (id == IDNO)
  1876. {
  1877. pci->Release();
  1878. throw;
  1879. } // if: don't ignore the error
  1880. pnte->Delete();
  1881. } // catch: CNTException
  1882. catch (CException * pe)
  1883. {
  1884. strStatusBarText.Empty();
  1885. ID id = IdProcessNewObjectError(pe);
  1886. if (id == IDNO)
  1887. {
  1888. pci->Release();
  1889. throw;
  1890. } // if: don't ignore the error
  1891. pe->Delete();
  1892. } // catch: CException
  1893. pci->Release();
  1894. } // while: more items in the list
  1895. } //*** CClusterDoc::InitNetInterfaces()
  1896. /////////////////////////////////////////////////////////////////////////////
  1897. //++
  1898. //
  1899. // CClusterDoc::IdProcessNewObjectError
  1900. //
  1901. // Routine Description:
  1902. // Processes errors that occur when adding a new object. If this
  1903. // occurs during initialization and errors have not already been set
  1904. // to be ignored, display the YesToAll dialog. If not during
  1905. // initialization, add it to the error message queue to be displayed
  1906. // later.
  1907. //
  1908. // Arguments:
  1909. // pe [IN OUT] Exception object to process.
  1910. //
  1911. // Return Value:
  1912. // IDYES Ignore error.
  1913. // IDNO Cancel the object creation.
  1914. // IDC_YTA_YESTOALL Ignore this error and all succeeding ones.
  1915. //
  1916. //--
  1917. /////////////////////////////////////////////////////////////////////////////
  1918. ID CClusterDoc::IdProcessNewObjectError(IN OUT CException * pe)
  1919. {
  1920. ID id = IDYES;
  1921. ASSERT(pe != NULL);
  1922. if (m_bInitializing)
  1923. {
  1924. if (!m_bIgnoreErrors)
  1925. {
  1926. TCHAR szErrorMsg[2048];
  1927. CYesToAllDialog dlg(szErrorMsg);
  1928. pe->GetErrorMessage(szErrorMsg, sizeof(szErrorMsg) / sizeof(TCHAR));
  1929. id = (ID)dlg.DoModal();
  1930. if (id == IDC_YTA_YESTOALL)
  1931. m_bIgnoreErrors = TRUE;
  1932. } // if: not ignoring errors
  1933. } // if: initializing the connection
  1934. else
  1935. {
  1936. if (!m_bIgnoreErrors)
  1937. pe->ReportError();
  1938. } // else: called for a notification
  1939. return id;
  1940. } //*** CClusterDoc::IdProcessNewObjectError()
  1941. /////////////////////////////////////////////////////////////////////////////
  1942. //++
  1943. //
  1944. // CClusterDoc::AddDefaultColumns
  1945. //
  1946. // Routine Description:
  1947. // Add default columns to the item.
  1948. //
  1949. // Arguments:
  1950. // pti [IN OUT] Pointer to the item to add the columns to.
  1951. //
  1952. // Return Value:
  1953. // None.
  1954. //
  1955. //--
  1956. /////////////////////////////////////////////////////////////////////////////
  1957. void CClusterDoc::AddDefaultColumns(IN OUT CTreeItem * pti)
  1958. {
  1959. ASSERT_VALID(pti);
  1960. pti->DeleteAllColumns();
  1961. pti->PcoliAddColumn(IDS_COLTEXT_NAME, COLI_WIDTH_NAME);
  1962. // pti->PcoliAddColumn(IDS_COLTEXT_TYPE, COLI_WIDTH_TYPE);
  1963. pti->PcoliAddColumn(IDS_COLTEXT_DESCRIPTION, COLI_WIDTH_DESCRIPTION);
  1964. } //*** CClusterDoc::AddDefaultColumns()
  1965. /////////////////////////////////////////////////////////////////////////////
  1966. //++
  1967. //
  1968. // CClusterDoc::DeleteContents
  1969. //
  1970. // Routine Description:
  1971. // Delete the contents of the document.
  1972. //
  1973. // Arguments:
  1974. // None.
  1975. //
  1976. // Return Value:
  1977. // None.
  1978. //
  1979. //--
  1980. /////////////////////////////////////////////////////////////////////////////
  1981. void CClusterDoc::DeleteContents(void)
  1982. {
  1983. // Select the root item in all views.
  1984. // This is done so that selection is done right up front when all data
  1985. // is still available.
  1986. if (PtiCluster() != NULL)
  1987. PtiCluster()->SelectInAllViews();
  1988. // Delete the tree hierarchy.
  1989. if (m_ptiCluster != NULL)
  1990. {
  1991. // Delete the tree.
  1992. m_ptiCluster->Delete();
  1993. m_ptiCluster->Release();
  1994. m_ptiCluster = NULL;
  1995. } // if: there is a hierarchy
  1996. // Delete all the lists.
  1997. DeleteAllItemData(LpciResources());
  1998. DeleteAllItemData(LpciGroups());
  1999. DeleteAllItemData(LpciNetInterfaces());
  2000. DeleteAllItemData(LpciNetworks());
  2001. DeleteAllItemData(LpciNodes());
  2002. DeleteAllItemData(LpciResourceTypes());
  2003. LpciResources().RemoveAll();
  2004. LpciGroups().RemoveAll();
  2005. LpciNetInterfaces().RemoveAll();
  2006. LpciNetworks().RemoveAll();
  2007. LpciNodes().RemoveAll();
  2008. LpciResourceTypes().RemoveAll();
  2009. // Delete the top cluster item.
  2010. if (m_pciCluster != NULL)
  2011. {
  2012. m_pciCluster->Delete();
  2013. m_pciCluster->Release();
  2014. m_pciCluster = NULL;
  2015. } // if: there is a cluster item
  2016. // Close the cluster registry key.
  2017. if (HkeyCluster() != NULL)
  2018. {
  2019. ClusterRegCloseKey(HkeyCluster());
  2020. m_hkeyCluster = NULL;
  2021. } // if: cluster registry key is open
  2022. // Close the cluster if it is open.
  2023. if ((Hcluster() != NULL) && (Hcluster() != GetClusterAdminApp()->HOpenedCluster()))
  2024. {
  2025. CloseCluster(Hcluster());
  2026. m_hcluster = NULL;
  2027. } // if: cluster is open
  2028. CDocument::DeleteContents();
  2029. UpdateAllViews(NULL);
  2030. // If there are any items left to be deleted, let's delete them now.
  2031. {
  2032. POSITION pos;
  2033. POSITION posBeingChecked;
  2034. CClusterItem * pci;
  2035. pos = LpciToBeDeleted().GetHeadPosition();
  2036. while (pos != NULL)
  2037. {
  2038. posBeingChecked = pos;
  2039. pci = LpciToBeDeleted().GetNext(pos);
  2040. ASSERT_VALID(pci);
  2041. ASSERT(pci->NReferenceCount() == 1);
  2042. if (pci->NReferenceCount() == 1)
  2043. LpciToBeDeleted().RemoveAt(posBeingChecked);
  2044. } // while: more items in the list
  2045. ASSERT(LpciToBeDeleted().GetCount() == 0);
  2046. } // Delete items in To Be Deleted list
  2047. } //*** CClusterDoc::DeleteContents()
  2048. /////////////////////////////////////////////////////////////////////////////
  2049. //++
  2050. //
  2051. // CClusterDoc::SetPathName
  2052. //
  2053. // Routine Description:
  2054. // Set the name of the document.
  2055. //
  2056. // Arguments:
  2057. // lpszPathName [IN] Name of the cluster.
  2058. // bAddToMRU [IN] TRUE = add to Most Recently Used list.
  2059. //
  2060. // Return Value:
  2061. // None.
  2062. //
  2063. //--
  2064. /////////////////////////////////////////////////////////////////////////////
  2065. void CClusterDoc::SetPathName(IN LPCTSTR lpszPathName, IN BOOL bAddToMRU)
  2066. {
  2067. CString strTitle;
  2068. m_strPathName = lpszPathName;
  2069. ASSERT(!m_strPathName.IsEmpty()); // must be set to something
  2070. m_bEmbedded = FALSE;
  2071. ASSERT_VALID(this);
  2072. // Set the document title to the cluster name.
  2073. strTitle.FormatMessage(IDS_WINDOW_TITLE_FORMAT, m_strName, lpszPathName);
  2074. SetTitle(strTitle);
  2075. // add it to the file MRU list
  2076. if (bAddToMRU)
  2077. AfxGetApp()->AddToRecentFileList(m_strPathName);
  2078. // Set the node name to the path name.
  2079. m_strNode = lpszPathName;
  2080. ASSERT_VALID(this);
  2081. } //*** CClusterDoc::SetPathName()
  2082. /////////////////////////////////////////////////////////////////////////////
  2083. //++
  2084. //
  2085. // CClusterDoc::UpdateTitle
  2086. //
  2087. // Routine Description:
  2088. // Update the title of the document.
  2089. //
  2090. // Arguments:
  2091. // None.
  2092. //
  2093. // Return Value:
  2094. // None.
  2095. //
  2096. //--
  2097. /////////////////////////////////////////////////////////////////////////////
  2098. void CClusterDoc::UpdateTitle(void)
  2099. {
  2100. CString strTitle;
  2101. ASSERT_VALID(PciCluster());
  2102. ASSERT_VALID(this);
  2103. // Set the document title to the cluster name.
  2104. m_strName = PciCluster()->StrName();
  2105. strTitle.FormatMessage(IDS_WINDOW_TITLE_FORMAT, m_strName, m_strPathName);
  2106. SetTitle(strTitle);
  2107. } //*** CClusterDoc::UpdateTitle()
  2108. /////////////////////////////////////////////////////////////////////////////
  2109. //++
  2110. //
  2111. // CClusterDoc::OnChangedViewList
  2112. //
  2113. // Routine Description:
  2114. // Called when the list of view changes by either having a view added
  2115. // or removed.
  2116. //
  2117. // Arguments:
  2118. // None.
  2119. //
  2120. // Return Value:
  2121. // None.
  2122. //
  2123. //--
  2124. /////////////////////////////////////////////////////////////////////////////
  2125. void CClusterDoc::OnChangedViewList(void)
  2126. {
  2127. ASSERT_VALID(this);
  2128. // Notify all frames to re-calculate their frame number.
  2129. if (m_bUpdateFrameNumber)
  2130. {
  2131. POSITION pos;
  2132. CView * pview;
  2133. CSplitterFrame * pframe;
  2134. pos = GetFirstViewPosition();
  2135. while (pos != NULL)
  2136. {
  2137. pview = GetNextView(pos);
  2138. ASSERT_VALID(pview);
  2139. if (pview->IsKindOf(RUNTIME_CLASS(CClusterTreeView)))
  2140. {
  2141. pframe = (CSplitterFrame *) pview->GetParentFrame();
  2142. ASSERT_VALID(pframe);
  2143. pframe->CalculateFrameNumber();
  2144. } // if: tree view
  2145. } // while: more views on the document
  2146. } // if: updating frame numbers
  2147. // Call the base class method.
  2148. CDocument::OnChangedViewList();
  2149. } //*** CClusterDoc::OnChangedViewList()
  2150. /////////////////////////////////////////////////////////////////////////////
  2151. //++
  2152. //
  2153. // CClusterDoc::OnSelChanged
  2154. //
  2155. // Routine Description:
  2156. // Called by one of the cluster views when selection changes.
  2157. // Changes the menu if the object type changed.
  2158. //
  2159. // Arguments:
  2160. // pciSelected [IN] Currently selected item.
  2161. //
  2162. // Return Value:
  2163. // None.
  2164. //
  2165. //--
  2166. /////////////////////////////////////////////////////////////////////////////
  2167. void CClusterDoc::OnSelChanged(IN CClusterItem * pciSelected)
  2168. {
  2169. IDM idmNewMenu;
  2170. HMENU * phmenu;
  2171. IDS idsType;
  2172. // Get the type of object being selected
  2173. if (pciSelected == NULL)
  2174. idsType = 0;
  2175. else
  2176. {
  2177. ASSERT_VALID(pciSelected);
  2178. idsType = pciSelected->IdsType();
  2179. } // else: an item was selected
  2180. // Get the ID of the menu required by the selected item.
  2181. switch (idsType)
  2182. {
  2183. case IDS_ITEMTYPE_CLUSTER:
  2184. idmNewMenu = IDM_CLUSTER;
  2185. phmenu = &m_hmenuCluster;
  2186. break;
  2187. case IDS_ITEMTYPE_NODE:
  2188. idmNewMenu = IDM_NODE;
  2189. phmenu = &m_hmenuNode;
  2190. break;
  2191. case IDS_ITEMTYPE_GROUP:
  2192. idmNewMenu = IDM_GROUP;
  2193. phmenu = &m_hmenuGroup;
  2194. break;
  2195. case IDS_ITEMTYPE_RESOURCE:
  2196. idmNewMenu = IDM_RESOURCE;
  2197. phmenu = &m_hmenuResource;
  2198. break;
  2199. case IDS_ITEMTYPE_RESTYPE:
  2200. idmNewMenu = IDM_RESTYPE;
  2201. phmenu = &m_hmenuResType;
  2202. break;
  2203. case IDS_ITEMTYPE_NETWORK:
  2204. idmNewMenu = IDM_NETWORK;
  2205. phmenu = &m_hmenuNetwork;
  2206. break;
  2207. case IDS_ITEMTYPE_NETIFACE:
  2208. idmNewMenu = IDM_NETIFACE;
  2209. phmenu = &m_hmenuNetIFace;
  2210. break;
  2211. default:
  2212. idmNewMenu = 0;
  2213. phmenu = NULL;
  2214. break;
  2215. } // switch: pciSelected->IdsType()
  2216. // If the menu ID changed, load the new one.
  2217. if (m_idmCurrentMenu != idmNewMenu)
  2218. {
  2219. if (idmNewMenu == 0)
  2220. m_hmenuCurrent = NULL;
  2221. else
  2222. {
  2223. if (*phmenu == NULL)
  2224. *phmenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(idmNewMenu));
  2225. m_hmenuCurrent = *phmenu;
  2226. } // else: special menu required by item
  2227. m_idmCurrentMenu = idmNewMenu;
  2228. } // if: menu ID changed
  2229. // Update the menu bar and redisplay it.
  2230. if (((CMDIFrameWnd *) AfxGetMainWnd())->MDIGetActive() != NULL)
  2231. {
  2232. #ifdef _DEBUG
  2233. if (g_tagDocMenu.BAny())
  2234. {
  2235. TraceMenu(g_tagDocMenu, AfxGetMainWnd()->GetMenu(), _T("OnSelChanged menu: "));
  2236. {
  2237. CMDIFrameWnd * pFrame = (CMDIFrameWnd *) AfxGetMainWnd();
  2238. CMenu menuDefault;
  2239. menuDefault.Attach(pFrame->m_hMenuDefault);
  2240. TraceMenu(g_tagDocMenu, &menuDefault, _T("Frame default menu before OnSelChanged: "));
  2241. menuDefault.Detach();
  2242. } // trace default menu
  2243. } // if: tag is active
  2244. #endif
  2245. ((CFrameWnd *) AfxGetMainWnd())->OnUpdateFrameMenu(NULL);
  2246. AfxGetMainWnd()->DrawMenuBar();
  2247. TraceMenu(g_tagDocMenu, AfxGetMainWnd()->GetMenu(), _T("Post-OnSelChanged menu: "));
  2248. } // if: active window present
  2249. } //*** CClusterDoc::OnSelChanged()
  2250. /////////////////////////////////////////////////////////////////////////////
  2251. //++
  2252. //
  2253. // CClusterDoc::GetDefaultMenu
  2254. //
  2255. // Routine Description:
  2256. // Returns the menu to use. Overridden to allow us to use multiple menus
  2257. // with the same type of document.
  2258. //
  2259. // Arguments:
  2260. // None.
  2261. //
  2262. // Return Value:
  2263. // hmenu The currently selected menu, or NULL for no default.
  2264. //
  2265. //--
  2266. /////////////////////////////////////////////////////////////////////////////
  2267. HMENU CClusterDoc::GetDefaultMenu(void)
  2268. {
  2269. return m_hmenuCurrent;
  2270. } //*** CClusterDoc::GetDefaultMenu()
  2271. /////////////////////////////////////////////////////////////////////////////
  2272. //++
  2273. //
  2274. // CClusterDoc::OnCmdRefresh
  2275. //
  2276. // Routine Description:
  2277. // Processes the ID_VIEW_REFRESH menu command.
  2278. //
  2279. // Arguments:
  2280. // None.
  2281. //
  2282. // Return Value:
  2283. // None.
  2284. //
  2285. //--
  2286. /////////////////////////////////////////////////////////////////////////////
  2287. void CClusterDoc::OnCmdRefresh(void)
  2288. {
  2289. CWaitCursor wc;
  2290. try
  2291. {
  2292. Trace(g_tagDocRefresh, _T("(%s) Deleting old contents"), StrNode());
  2293. {
  2294. POSITION pos;
  2295. CSplitterFrame * pframe;
  2296. CView * pview;
  2297. // Get the active child frame window.
  2298. pframe = (CSplitterFrame *) ((CFrameWnd *) AfxGetMainWnd())->GetActiveFrame();
  2299. if ((pframe->IsKindOf(RUNTIME_CLASS(CSplitterFrame)))
  2300. && (pframe->PviewList()->PtiParent() != NULL))
  2301. {
  2302. // Tell the view to save its column information.
  2303. pframe->PviewList()->SaveColumns();
  2304. } // if: MDI window exists
  2305. pos = GetFirstViewPosition();
  2306. while (pos != NULL)
  2307. {
  2308. pview = GetNextView(pos);
  2309. if (pview->IsKindOf(RUNTIME_CLASS(CClusterTreeView)))
  2310. {
  2311. // Save the current selection
  2312. ((CClusterTreeView *) pview)->SaveCurrentSelection();
  2313. } // if: this is a tree view
  2314. } // while: more views
  2315. } // Save the column information
  2316. DeleteContents();
  2317. Trace(g_tagDocRefresh, _T("(%s) %d items still to be deleted"), StrNode(), LpciToBeDeleted().GetCount());
  2318. Trace(g_tagDocRefresh, _T("(%s) Creating new cluster object"), StrNode());
  2319. m_bClusterAvailable = TRUE;
  2320. m_bInitializing = TRUE;
  2321. // Create a new cluster object.
  2322. m_pciCluster = new CCluster;
  2323. if ( m_pciCluster == NULL )
  2324. {
  2325. AfxThrowMemoryException();
  2326. } // if: error allocating the cluster object
  2327. PciCluster()->AddRef();
  2328. PciCluster()->Init(this, GetPathName());
  2329. Trace(g_tagDocRefresh, _T("(%s) Building base hierarchy"), StrNode());
  2330. // Build the base hierarchy.
  2331. BuildBaseHierarchy();
  2332. Trace(g_tagDocRefresh, _T("(%s) Collecting cluster items"), StrNode());
  2333. // Collect the items in the cluster and build the hierarchy.
  2334. CollectClusterItems();
  2335. PciCluster()->CollectNetworkPriority(NULL);
  2336. Trace(g_tagDocRefresh, _T("(%s) Re-initializing the views"), StrNode());
  2337. // Re-initialize the views.
  2338. {
  2339. POSITION pos;
  2340. CView * pview;
  2341. pos = GetFirstViewPosition();
  2342. while (pos != NULL)
  2343. {
  2344. pview = GetNextView(pos);
  2345. ASSERT_VALID(pview);
  2346. pview->OnInitialUpdate();
  2347. } // while: more items in the list
  2348. } // Re-initialize the views
  2349. } // try
  2350. catch (CException * pe)
  2351. {
  2352. if (!m_bIgnoreErrors)
  2353. pe->ReportError();
  2354. pe->Delete();
  2355. if (HkeyCluster() != NULL)
  2356. {
  2357. ClusterRegCloseKey(HkeyCluster());
  2358. m_hkeyCluster = NULL;
  2359. } // if: cluster registry key is open
  2360. if (Hcluster() != NULL)
  2361. {
  2362. CloseCluster(Hcluster());
  2363. m_hcluster = NULL;
  2364. } // if: cluster is open
  2365. m_bClusterAvailable = FALSE;
  2366. } // catch: CException
  2367. // Reset the message on the status bar.
  2368. PframeMain()->SetMessageText(AFX_IDS_IDLEMESSAGE);
  2369. PframeMain()->UpdateWindow();
  2370. m_bInitializing = FALSE;
  2371. #ifdef GC_DEBUG
  2372. gcCollect();
  2373. #endif
  2374. } //*** CClusterDoc::OnCmdRefresh()
  2375. /////////////////////////////////////////////////////////////////////////////
  2376. //++
  2377. //
  2378. // CClusterDoc::OnCmdNewGroup
  2379. //
  2380. // Routine Description:
  2381. // Processes the ID_FILE_NEW_GROUP menu command.
  2382. //
  2383. // Arguments:
  2384. // None.
  2385. //
  2386. // Return Value:
  2387. // None.
  2388. //
  2389. //--
  2390. /////////////////////////////////////////////////////////////////////////////
  2391. void CClusterDoc::OnCmdNewGroup(void)
  2392. {
  2393. CCreateGroupWizard wiz(this, AfxGetMainWnd());
  2394. if (wiz.BInit())
  2395. {
  2396. if (wiz.DoModal() == ID_WIZFINISH)
  2397. {
  2398. CString strMsg;
  2399. strMsg.FormatMessage(IDS_CREATED_GROUP, wiz.StrName());
  2400. AfxMessageBox(strMsg, MB_ICONINFORMATION);
  2401. } // if: user pressed the FINISH button
  2402. } // if: wizard initialized successfully
  2403. } //*** CClusterDoc::OnCmdNewGroup()
  2404. /////////////////////////////////////////////////////////////////////////////
  2405. //++
  2406. //
  2407. // CClusterDoc::OnCmdNewResource
  2408. //
  2409. // Routine Description:
  2410. // Processes the ID_FILE_NEW_RESOURCE menu command.
  2411. //
  2412. // Arguments:
  2413. // None.
  2414. //
  2415. // Return Value:
  2416. // None.
  2417. //
  2418. //--
  2419. /////////////////////////////////////////////////////////////////////////////
  2420. void CClusterDoc::OnCmdNewResource(void)
  2421. {
  2422. CCreateResourceWizard wiz(this, AfxGetMainWnd());
  2423. if (wiz.BInit())
  2424. {
  2425. if (wiz.DoModal() == ID_WIZFINISH)
  2426. {
  2427. CString strMsg;
  2428. strMsg.FormatMessage(IDS_CREATED_RESOURCE, wiz.StrName());
  2429. AfxMessageBox(strMsg, MB_ICONINFORMATION);
  2430. } // if: user pressed the FINISH button
  2431. } // if: wizard initialized successfully
  2432. } //*** CClusterDoc::OnCmdNewResource()
  2433. /////////////////////////////////////////////////////////////////////////////
  2434. //++
  2435. //
  2436. // CClusterDoc::OnCmdNewNode
  2437. //
  2438. // Routine Description:
  2439. // Processes the ID_FILE_NEW_NODE menu command.
  2440. //
  2441. // Arguments:
  2442. // None.
  2443. //
  2444. // Return Value:
  2445. // None.
  2446. //
  2447. //--
  2448. /////////////////////////////////////////////////////////////////////////////
  2449. void CClusterDoc::OnCmdNewNode( void )
  2450. {
  2451. NewNodeWizard( StrName(), m_bIgnoreErrors );
  2452. #if 0
  2453. HRESULT hr;
  2454. IClusCfgWizard * pccwWiz;
  2455. BSTR bstrConnectName = NULL;
  2456. BOOL fCommitted = FALSE;
  2457. // Make sure the ClusCfg client has been loaded.
  2458. GetClusterAdminApp()->LoadClusCfgClient();
  2459. // Get an interface pointer for the wizard.
  2460. hr = CoCreateInstance(
  2461. CLSID_ClusCfgWizard,
  2462. NULL,
  2463. CLSCTX_INPROC_SERVER,
  2464. IID_IClusCfgWizard,
  2465. (void **) &pccwWiz
  2466. );
  2467. if ( FAILED( hr ) )
  2468. {
  2469. CNTException nte( hr, IDS_CREATE_CLUSCFGWIZ_OBJ_ERROR, NULL, NULL, FALSE /*bAutoDelete*/ );
  2470. if ( ! m_bIgnoreErrors )
  2471. {
  2472. nte.ReportError();
  2473. }
  2474. return;
  2475. } // if: error getting the interface pointer
  2476. // Specify the name of the cluster we are going to add a node to.
  2477. bstrConnectName = SysAllocString( PciCluster()->StrFQDN() );
  2478. if ( bstrConnectName == NULL )
  2479. {
  2480. AfxThrowMemoryException();
  2481. }
  2482. hr = pccwWiz->put_ClusterName( bstrConnectName );
  2483. if ( FAILED( hr ) )
  2484. {
  2485. CNTException nte( hr, IDS_ADD_NODES_TO_CLUSTER_ERROR, bstrConnectName, NULL, FALSE /*bAutoDelete*/ );
  2486. if ( ! m_bIgnoreErrors )
  2487. {
  2488. nte.ReportError();
  2489. }
  2490. } // if: error setting the cluster name
  2491. // Display the wizard.
  2492. hr = pccwWiz->AddClusterNodes(
  2493. AfxGetMainWnd()->m_hWnd,
  2494. &fCommitted
  2495. );
  2496. if ( FAILED( hr ) )
  2497. {
  2498. CNTException nte( hr, IDS_ADD_NODES_TO_CLUSTER_ERROR, bstrConnectName, NULL, FALSE /*bAutoDelete*/ );
  2499. if ( ! m_bIgnoreErrors )
  2500. {
  2501. nte.ReportError();
  2502. }
  2503. } // if: error adding cluster nodes
  2504. SysFreeString( bstrConnectName );
  2505. pccwWiz->Release();
  2506. #endif
  2507. } //*** CClusterDoc::OnCmdNewNode()
  2508. /////////////////////////////////////////////////////////////////////////////
  2509. //++
  2510. //
  2511. // CClusterDoc::OnCmdConfigApp
  2512. //
  2513. // Routine Description:
  2514. // Processes the ID_FILE_CONFIG_APP menu command.
  2515. //
  2516. // Arguments:
  2517. // None.
  2518. //
  2519. // Return Value:
  2520. // None.
  2521. //
  2522. //--
  2523. /////////////////////////////////////////////////////////////////////////////
  2524. void CClusterDoc::OnCmdConfigApp(void)
  2525. {
  2526. HRESULT hr;
  2527. IClusterApplicationWizard * piWiz;
  2528. // Get an interface pointer for the wizard.
  2529. hr = CoCreateInstance(
  2530. __uuidof(ClusAppWiz),
  2531. NULL,
  2532. CLSCTX_INPROC_SERVER,
  2533. __uuidof(IClusterApplicationWizard),
  2534. (LPVOID *) &piWiz
  2535. );
  2536. if (FAILED(hr))
  2537. {
  2538. CNTException nte(hr, (IDS) 0);
  2539. if (!m_bIgnoreErrors)
  2540. nte.ReportError();
  2541. return;
  2542. } // if: error getting the interface pointer
  2543. // Display the wizard.
  2544. hr = piWiz->DoModalWizard(AfxGetMainWnd()->m_hWnd,
  2545. (ULONG_PTR)Hcluster(),
  2546. NULL);
  2547. piWiz->Release();
  2548. // Handle any errors.
  2549. if (FAILED(hr))
  2550. {
  2551. CNTException nte(hr, (IDS) 0);
  2552. if (!m_bIgnoreErrors)
  2553. nte.ReportError();
  2554. } // if: error from the wizard
  2555. } //*** CClusterDoc::OnCmdConfigApp()
  2556. /////////////////////////////////////////////////////////////////////////////
  2557. //++
  2558. //
  2559. // CClusterDoc::OnClusterNotify
  2560. //
  2561. // Routine Description:
  2562. // Handler for the WM_CAM_CLUSTER_NOTIFY message.
  2563. // Processes cluster notifications.
  2564. //
  2565. // Arguments:
  2566. // pnotify [IN OUT] Object describing the notification.
  2567. //
  2568. // Return Value:
  2569. // Value returned from the application method.
  2570. //
  2571. //--
  2572. /////////////////////////////////////////////////////////////////////////////
  2573. LRESULT CClusterDoc::OnClusterNotify( IN OUT CClusterNotify * pnotify )
  2574. {
  2575. ASSERT( pnotify != NULL );
  2576. BOOL bOldIgnoreErrors = m_bIgnoreErrors;
  2577. CClusterItem * pciClusterItemPtr = NULL;
  2578. m_bIgnoreErrors = TRUE;
  2579. try
  2580. {
  2581. switch ( pnotify->m_dwFilterType )
  2582. {
  2583. case CLUSTER_CHANGE_CLUSTER_STATE:
  2584. {
  2585. m_bClusterAvailable = FALSE;
  2586. // Update the state of all objects in the cluster.
  2587. ASSERT_VALID( PtiCluster() );
  2588. PtiCluster()->UpdateAllStatesInTree();
  2589. try
  2590. {
  2591. CString strMsg;
  2592. ASSERT( pnotify->m_strName.GetLength() > 0 );
  2593. strMsg.FormatMessage( IDS_CLUSTER_NOT_AVAILABLE, pnotify->m_strName );
  2594. AfxMessageBox( strMsg, MB_ICONINFORMATION );
  2595. } // try
  2596. catch ( CException * pe )
  2597. {
  2598. pe->Delete();
  2599. } // catch: CException
  2600. break;
  2601. }
  2602. case CLUSTER_CHANGE_CLUSTER_PROPERTY:
  2603. {
  2604. ASSERT_VALID( PciCluster() );
  2605. Trace( g_tagDocNotify, _T("(%s) - Cluster properties changed - new name is '%s'"), StrNode(), pnotify->m_strName );
  2606. PciCluster()->ReadItem();
  2607. PciCluster()->CollectNetworkPriority( NULL );
  2608. break;
  2609. }
  2610. case CLUSTER_CHANGE_NODE_ADDED:
  2611. {
  2612. CClusterNode * pciNode;
  2613. Trace( g_tagNodeNotify, _T("(%s) - Adding node '%s'"), m_strPathName, pnotify->m_strName );
  2614. pciNode = PciAddNewNode( pnotify->m_strName );
  2615. if ( pciNode != NULL )
  2616. {
  2617. ASSERT_VALID( pciNode );
  2618. pciNode->AddRef();
  2619. // For calling Release later. This is done so that
  2620. // release is called even if ReadItem below throws an exception.
  2621. pciClusterItemPtr = pciNode;
  2622. pciNode->ReadItem();
  2623. } // if: node was added
  2624. break;
  2625. }
  2626. case CLUSTER_CHANGE_GROUP_ADDED:
  2627. {
  2628. CGroup * pciGroup;
  2629. Trace( g_tagGroupNotify, _T("(%s) - Adding group '%s'"), m_strPathName, pnotify->m_strName );
  2630. pciGroup = PciAddNewGroup( pnotify->m_strName );
  2631. if ( pciGroup != NULL )
  2632. {
  2633. ASSERT_VALID( pciGroup );
  2634. pciGroup->AddRef();
  2635. // For calling Release later. This is done so that
  2636. // release is called even if ReadItem below throws an exception.
  2637. pciClusterItemPtr = pciGroup;
  2638. pciGroup->ReadItem();
  2639. } // if: group was added
  2640. break;
  2641. }
  2642. case CLUSTER_CHANGE_RESOURCE_ADDED:
  2643. {
  2644. CResource * pciRes;
  2645. Trace( g_tagResNotify, _T("(%s) - Adding resource '%s'"), m_strPathName, pnotify->m_strName );
  2646. pciRes = PciAddNewResource( pnotify->m_strName );
  2647. if (pciRes != NULL)
  2648. {
  2649. ASSERT_VALID( pciRes );
  2650. pciRes->AddRef();
  2651. // For calling Release later. This is done so that
  2652. // release is called even if ReadItem below throws an exception.
  2653. pciClusterItemPtr = pciRes;
  2654. if ( ! pciRes->BInitializing() )
  2655. {
  2656. pciRes->ReadItem();
  2657. } // if: not initializing the resource
  2658. } // if: resource was added
  2659. break;
  2660. }
  2661. case CLUSTER_CHANGE_RESOURCE_TYPE_ADDED:
  2662. {
  2663. CResourceType * pciResType;
  2664. Trace( g_tagResTypeNotify, _T("(%s) - Adding resource Type '%s'"), m_strPathName, pnotify->m_strName );
  2665. pciResType = PciAddNewResourceType( pnotify->m_strName );
  2666. if ( pciResType != NULL )
  2667. {
  2668. ASSERT_VALID( pciResType );
  2669. pciResType->AddRef();
  2670. // For calling Release later. This is done so that
  2671. // release is called even if ReadItem below throws an exception.
  2672. pciClusterItemPtr = pciResType;
  2673. pciResType->ReadItem();
  2674. } // if: resource type was added
  2675. break;
  2676. }
  2677. case CLUSTER_CHANGE_RESOURCE_TYPE_DELETED:
  2678. {
  2679. ASSERT( pnotify->m_strName.GetLength() > 0 );
  2680. CResourceType * pciResType = LpciResourceTypes().PciResTypeFromName( pnotify->m_strName );
  2681. if ( pciResType != NULL )
  2682. {
  2683. ASSERT_VALID( pciResType );
  2684. Trace( g_tagResTypeNotify, _T("(%s) - Resource Type '%s' deleted"), m_strPathName, pnotify->m_strName );
  2685. pciResType->Delete();
  2686. } // if: resource type was found
  2687. else
  2688. {
  2689. Trace( g_tagDocNotify, _T("(%s) - Resource Type '%s' deleted (NOT FOUND)"), m_strPathName, pnotify->m_strName );
  2690. } // else: resource type not found
  2691. break;
  2692. }
  2693. case CLUSTER_CHANGE_RESOURCE_TYPE_PROPERTY:
  2694. {
  2695. ASSERT( pnotify->m_strName.GetLength() > 0 );
  2696. CResourceType * pciResType = LpciResourceTypes().PciResTypeFromName( pnotify->m_strName );
  2697. if ( pciResType != NULL )
  2698. {
  2699. ASSERT_VALID( pciResType );
  2700. Trace( g_tagResTypeNotify, _T("(%s) - Resource Type '%s' property change"), m_strPathName, pnotify->m_strName );
  2701. pciResType->ReadItem();
  2702. } // if: resource type was found
  2703. else
  2704. {
  2705. Trace( g_tagDocNotify, _T("(%s) - Resource Type '%s' deleted (NOT FOUND)"), m_strPathName, pnotify->m_strName );
  2706. } // else: resource type not found
  2707. break;
  2708. }
  2709. case CLUSTER_CHANGE_NETWORK_ADDED:
  2710. {
  2711. CNetwork * pciNetwork;
  2712. Trace( g_tagNetNotify, _T("(%s) - Adding network '%s'"), m_strPathName, pnotify->m_strName );
  2713. pciNetwork = PciAddNewNetwork( pnotify->m_strName );
  2714. if ( pciNetwork != NULL )
  2715. {
  2716. ASSERT_VALID( pciNetwork );
  2717. pciNetwork->AddRef();
  2718. // For calling Release later. This is done so that
  2719. // release is called even if ReadItem below throws an exception.
  2720. pciClusterItemPtr = pciNetwork;
  2721. pciNetwork->ReadItem();
  2722. } // if: network was added
  2723. break;
  2724. }
  2725. case CLUSTER_CHANGE_NETINTERFACE_ADDED:
  2726. {
  2727. CNetInterface * pciNetIFace;
  2728. Trace( g_tagNetIFaceNotify, _T("(%s) - Adding network interface '%s'"), m_strPathName, pnotify->m_strName );
  2729. pciNetIFace = PciAddNewNetInterface( pnotify->m_strName );
  2730. if ( pciNetIFace != NULL )
  2731. {
  2732. ASSERT_VALID( pciNetIFace );
  2733. pciNetIFace->AddRef();
  2734. // For calling Release later. This is done so that
  2735. // release is called even if ReadItem below throws an exception.
  2736. pciClusterItemPtr = pciNetIFace;
  2737. pciNetIFace->ReadItem();
  2738. } // if: network interface was added
  2739. break;
  2740. }
  2741. case CLUSTER_CHANGE_QUORUM_STATE:
  2742. Trace( g_tagDocNotify, _T("(%s) - Quorum state changed (%s)"), m_strPathName, pnotify->m_strName );
  2743. break;
  2744. case CLUSTER_CHANGE_REGISTRY_NAME:
  2745. Trace( g_tagDocRegNotify, _T("(%s) - Registry namespace '%s' changed"), m_strPathName, pnotify->m_strName );
  2746. ProcessRegNotification( pnotify );
  2747. break;
  2748. case CLUSTER_CHANGE_REGISTRY_ATTRIBUTES:
  2749. Trace( g_tagDocRegNotify, _T("(%s) - Registry atributes for '%s' changed"), m_strPathName, pnotify->m_strName );
  2750. ProcessRegNotification( pnotify );
  2751. break;
  2752. case CLUSTER_CHANGE_REGISTRY_VALUE:
  2753. Trace( g_tagDocRegNotify, _T("(%s) - Registry value '%s' changed"), m_strPathName, pnotify->m_strName );
  2754. ProcessRegNotification( pnotify );
  2755. break;
  2756. default:
  2757. Trace( g_tagDocNotify, _T("(%s) - Unknown notification (%x) for '%s'"), m_strPathName, pnotify->m_dwFilterType, pnotify->m_strName );
  2758. } // switch: dwFilterType
  2759. } // try
  2760. catch ( CException * pe )
  2761. {
  2762. // Don't display anything on notification errors.
  2763. // If it's really a problem, the user will see it when
  2764. // refreshing the view.
  2765. if ( ! m_bIgnoreErrors )
  2766. {
  2767. pe->ReportError();
  2768. } // if: not ignoring errors
  2769. pe->Delete();
  2770. } // catch: CException
  2771. if ( pciClusterItemPtr != NULL )
  2772. {
  2773. pciClusterItemPtr->Release();
  2774. } // if: cluster item pointer not released yet
  2775. m_bIgnoreErrors = bOldIgnoreErrors;
  2776. // Reset the message on the status bar.
  2777. {
  2778. CFrameWnd * pframe = PframeMain( );
  2779. if ( pframe != NULL )
  2780. {
  2781. pframe->SetMessageText(AFX_IDS_IDLEMESSAGE);
  2782. pframe->UpdateWindow();
  2783. } // if: main frame window is available
  2784. }
  2785. delete pnotify;
  2786. return 0;
  2787. } //*** CClusterDoc::OnClusterNotify()
  2788. /////////////////////////////////////////////////////////////////////////////
  2789. //++
  2790. //
  2791. // CClusterDoc::ProcessRegNotification
  2792. //
  2793. // Routine Description:
  2794. // Process registry notifications for the document.
  2795. //
  2796. // Arguments:
  2797. // pnotify [IN] Object describing the notification.
  2798. //
  2799. // Return Value:
  2800. // pci Cluster item that cares about the notification.
  2801. // NULL Unknown object.
  2802. //
  2803. //--
  2804. /////////////////////////////////////////////////////////////////////////////
  2805. void CClusterDoc::ProcessRegNotification(IN const CClusterNotify * pnotify)
  2806. {
  2807. CCluster * pci = NULL;
  2808. HKEY hkey = NULL;
  2809. CString strRootKeyName;
  2810. #define RESTYPE_KEY_NAME_PREFIX CLUSREG_KEYNAME_RESOURCE_TYPES _T("\\")
  2811. try
  2812. {
  2813. // If there is no key name, update the cluster item.
  2814. if (pnotify->m_strName.GetLength() == 0)
  2815. pci = PciCluster();
  2816. else
  2817. {
  2818. // Find the root key name.
  2819. strRootKeyName = pnotify->m_strName.SpanExcluding(_T("\\"));
  2820. // If the root key name is the same as the notification name
  2821. // and it is for one of the object type keys, reread the lists
  2822. // of extensions for that one type of object.
  2823. if (strRootKeyName == pnotify->m_strName)
  2824. {
  2825. POSITION pos;
  2826. // Find the object based on its type.
  2827. if (strRootKeyName == CLUSREG_KEYNAME_NODES)
  2828. {
  2829. PciCluster()->ReadNodeExtensions();
  2830. pos = LpciNodes().GetHeadPosition();
  2831. while (pos != NULL)
  2832. ((CClusterNode *) LpciNodes().GetNext(pos))->ReadExtensions();
  2833. } // if: node registry notification
  2834. else if (strRootKeyName == CLUSREG_KEYNAME_GROUPS)
  2835. {
  2836. PciCluster()->ReadGroupExtensions();
  2837. pos = LpciGroups().GetHeadPosition();
  2838. while (pos != NULL)
  2839. ((CGroup *) LpciGroups().GetNext(pos))->ReadExtensions();
  2840. } // else if: group registry notification
  2841. else if (strRootKeyName == CLUSREG_KEYNAME_RESOURCES)
  2842. {
  2843. PciCluster()->ReadResourceExtensions();
  2844. pos = LpciResources().GetHeadPosition();
  2845. while (pos != NULL)
  2846. ((CResource *) LpciResources().GetNext(pos))->ReadExtensions();
  2847. } // else if: resource registry notification
  2848. else if (strRootKeyName == CLUSREG_KEYNAME_RESOURCE_TYPES)
  2849. {
  2850. PciCluster()->ReadResTypeExtensions();
  2851. pos = LpciResourceTypes().GetHeadPosition();
  2852. while (pos != NULL)
  2853. ((CResourceType *) LpciResourceTypes().GetNext(pos))->ReadExtensions();
  2854. pos = LpciResources().GetHeadPosition();
  2855. while (pos != NULL)
  2856. ((CResource *) LpciResources().GetNext(pos))->ReadExtensions();
  2857. } // else if: resource type registry notification
  2858. else if (strRootKeyName == CLUSREG_KEYNAME_NETWORKS)
  2859. {
  2860. PciCluster()->ReadNetworkExtensions();
  2861. pos = LpciNetworks().GetHeadPosition();
  2862. while (pos != NULL)
  2863. ((CNetwork *) LpciNetworks().GetNext(pos))->ReadExtensions();
  2864. } // else if: network registry notification
  2865. else if (strRootKeyName == CLUSREG_KEYNAME_NETINTERFACES)
  2866. {
  2867. PciCluster()->ReadNetInterfaceExtensions();
  2868. pos = LpciNetInterfaces().GetHeadPosition();
  2869. while (pos != NULL)
  2870. ((CNetInterface *) LpciNetInterfaces().GetNext(pos))->ReadExtensions();
  2871. } // else if: network interface registry notification
  2872. } // if: root name and full name are the same
  2873. else if (_tcsnicmp(pnotify->m_strName, RESTYPE_KEY_NAME_PREFIX, lstrlen(RESTYPE_KEY_NAME_PREFIX)) == 0)
  2874. {
  2875. int idxSlash = pnotify->m_strName.Find(_T('\\'));
  2876. CString strResTypeName;
  2877. CResource * pciRes;
  2878. CResourceType * pciResType;
  2879. POSITION pos;
  2880. strResTypeName = pnotify->m_strName.Mid(idxSlash + 1, lstrlen(pnotify->m_strName) - lstrlen(RESTYPE_KEY_NAME_PREFIX));
  2881. // Re-read the resource type extensions.
  2882. pos = LpciResourceTypes().GetHeadPosition();
  2883. while (pos != NULL)
  2884. {
  2885. pciResType = (CResourceType *) LpciResourceTypes().GetNext(pos);
  2886. if (pciResType->StrName().CompareNoCase(strResTypeName) == 0)
  2887. {
  2888. pciResType->ReadExtensions();
  2889. break;
  2890. } // if: found the resource type
  2891. } // while: more resource types
  2892. // Re-read the resource extensions.
  2893. pos = LpciResources().GetHeadPosition();
  2894. while (pos != NULL)
  2895. {
  2896. pciRes = (CResource *) LpciResources().GetNext(pos);
  2897. if (pciRes->StrResourceType() == strResTypeName)
  2898. {
  2899. pciRes->ReadExtensions();
  2900. } // if: found a resource of that type
  2901. } // while: more resources
  2902. } // else if: single resource type changed
  2903. pci = PciCluster();
  2904. } // else: not the cluster object
  2905. // If the cluster object can process it, have it re-read its info
  2906. if (pci != NULL)
  2907. {
  2908. pci->MarkAsChanged();
  2909. pci->ReadClusterExtensions();
  2910. } // if: cluster object changed
  2911. } // try
  2912. catch (...)
  2913. {
  2914. }
  2915. if (hkey != NULL)
  2916. ::ClusterRegCloseKey(hkey);
  2917. } //*** CClusterDoc::ProcessRegNotification()