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.

1673 lines
52 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CluAdmin.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CClusterAdminApp class.
  10. // Defines the class behaviors for the application.
  11. //
  12. // Author:
  13. // David Potter (davidp) May 1, 1996
  14. //
  15. // Revision History:
  16. //
  17. // Notes:
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "CluAdmin.h"
  22. #include "ConstDef.h"
  23. #include "CASvc.h"
  24. #include "MainFrm.h"
  25. #include "SplitFrm.h"
  26. #include "ClusDoc.h"
  27. #include "TreeView.h"
  28. #include "OpenClus.h"
  29. #include "ClusMru.h"
  30. #include "ExcOper.h"
  31. #include "Notify.h"
  32. #include "TraceTag.h"
  33. #include "TraceDlg.h"
  34. #include "Barf.h"
  35. #include "BarfDlg.h"
  36. #include "About.h"
  37. #include "CmdLine.h"
  38. #include "VerInfo.h"
  39. #ifdef _DEBUG
  40. #define new DEBUG_NEW
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #endif
  44. /////////////////////////////////////////////////////////////////////////////
  45. // Global Variables
  46. /////////////////////////////////////////////////////////////////////////////
  47. static LPCTSTR g_pszProfileName = _T("Cluster Administrator");
  48. #ifdef _DEBUG
  49. CTraceTag g_tagApp( _T("App"), _T("APP"), 0 );
  50. CTraceTag g_tagAppMenu( _T("Menu"), _T("APP"), 0 );
  51. CTraceTag g_tagAppNotify( _T("Notify"), _T("APP NOTIFY"), 0 );
  52. CTraceTag g_tagNotifyThread( _T("Notify"), _T("NOTIFY THREAD"), 0 );
  53. CTraceTag g_tagNotifyThreadReg( _T("Notify"), _T("NOTIFY THREAD (REG)"), 0 );
  54. #endif
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CClusterAdminApp
  57. /////////////////////////////////////////////////////////////////////////////
  58. /////////////////////////////////////////////////////////////////////////////
  59. // The one and only CClusterAdminApp object
  60. CClusterAdminApp theApp;
  61. IMPLEMENT_DYNAMIC( CClusterNotifyContext, CObject );
  62. IMPLEMENT_DYNAMIC( CClusterAdminApp, CWinApp );
  63. /////////////////////////////////////////////////////////////////////////////
  64. // Message Maps
  65. BEGIN_MESSAGE_MAP( CClusterAdminApp, CWinApp )
  66. //{{AFX_MSG_MAP(CClusterAdminApp)
  67. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  68. ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  69. ON_COMMAND(ID_FILE_NEW_CLUSTER, OnFileNewCluster)
  70. ON_COMMAND(ID_WINDOW_CLOSE_ALL, OnWindowCloseAll)
  71. ON_UPDATE_COMMAND_UI(ID_WINDOW_CLOSE_ALL, OnUpdateWindowCloseAll)
  72. //}}AFX_MSG_MAP
  73. // Standard file based document commands
  74. ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  75. #ifdef _DEBUG
  76. ON_COMMAND(ID_DEBUG_TRACE_SETTINGS, OnTraceSettings)
  77. ON_COMMAND(ID_DEBUG_BARF_SETTINGS, OnBarfSettings)
  78. ON_COMMAND(ID_DEBUG_BARF_ALL, OnBarfAllSettings)
  79. #endif // _DEBUG
  80. END_MESSAGE_MAP()
  81. /////////////////////////////////////////////////////////////////////////////
  82. //++
  83. //
  84. // CClusterAdminApp::CClusterAdminApp
  85. //
  86. // Routine Description:
  87. // Default constructor.
  88. //
  89. // Arguments:
  90. // None.
  91. //
  92. // Return Value:
  93. // None.
  94. //
  95. //--
  96. /////////////////////////////////////////////////////////////////////////////
  97. CClusterAdminApp::CClusterAdminApp( void )
  98. {
  99. // TODO: add construction code here,
  100. // Place all significant initialization in InitInstance
  101. m_pDocTemplate = NULL;
  102. m_hchangeNotifyPort = NULL;
  103. m_lcid = MAKELCID( MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), SORT_DEFAULT );
  104. m_hOpenedCluster = NULL;
  105. m_nIdleCount = 0;
  106. m_punkClusCfgClient = NULL;
  107. FillMemory( m_rgiimg, sizeof( m_rgiimg ), 0xFF );
  108. } //*** CClusterAdminApp::CClusterAdminApp()
  109. /////////////////////////////////////////////////////////////////////////////
  110. //++
  111. //
  112. // CClusterAdminApp::InitInstance
  113. //
  114. // Routine Description:
  115. // Initialize this instance of the application.
  116. //
  117. // Arguments:
  118. // None.
  119. //
  120. // Return Value:
  121. // TRUE Application successfully initialized.
  122. // FALSE Failed to initialize the application.
  123. //
  124. //--
  125. /////////////////////////////////////////////////////////////////////////////
  126. BOOL CClusterAdminApp::InitInstance( void )
  127. {
  128. BOOL bSuccess = FALSE;
  129. CMainFrame * pMainFrame = NULL;
  130. CCluAdminCommandLineInfo cmdInfo;
  131. // CG: The following block was added by the Splash Screen component.
  132. {
  133. // CCluAdminCommandLineInfo cmdInfo;
  134. // ParseCommandLine(cmdInfo);
  135. }
  136. // Initialize OLE libraries
  137. if ( ! AfxOleInit() )
  138. {
  139. AfxMessageBox( IDP_OLE_INIT_FAILED );
  140. return FALSE;
  141. }
  142. if ( CoInitializeSecurity(
  143. NULL,
  144. -1,
  145. NULL,
  146. NULL,
  147. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  148. RPC_C_IMP_LEVEL_IMPERSONATE,
  149. NULL,
  150. EOAC_NONE,
  151. 0
  152. ) != S_OK )
  153. {
  154. return FALSE;
  155. } // if:
  156. // Construct the help path.
  157. {
  158. TCHAR szPath[ _MAX_PATH ];
  159. TCHAR szDrive[ _MAX_PATH ];
  160. TCHAR szDir[ _MAX_DIR ];
  161. int cchPath;
  162. VERIFY( ::GetSystemWindowsDirectory( szPath, _MAX_PATH ) );
  163. cchPath = lstrlen( szPath );
  164. if ( szPath[ cchPath - 1 ] != _T('\\') )
  165. {
  166. szPath[ cchPath++ ] = _T('\\');
  167. szPath[ cchPath ] = _T('\0');
  168. } // if: no backslash on the end of the path
  169. lstrcpy( &szPath[ cchPath ], _T("Help\\") );
  170. _tsplitpath( szPath, szDrive, szDir, NULL, NULL );
  171. _tmakepath( szPath, szDrive, szDir, _T("cluadmin"), _T(".hlp") );
  172. free( (void *) m_pszHelpFilePath );
  173. BOOL bEnable;
  174. bEnable = AfxEnableMemoryTracking( FALSE );
  175. m_pszHelpFilePath = _tcsdup( szPath );
  176. AfxEnableMemoryTracking( bEnable );
  177. } // Construct the help path
  178. // Standard initialization
  179. // If you are not using these features and wish to reduce the size
  180. // of your final executable, you should remove from the following
  181. // the specific initialization routines you do not need.
  182. SetRegistryKey( IDS_REGKEY_COMPANY ); // Set the registry key for the program.
  183. //
  184. // Override the profile name because we don't want to localize it.
  185. //
  186. free( (void *) m_pszProfileName );
  187. m_pszProfileName = NULL;
  188. m_pszProfileName = (LPTSTR) malloc( ( lstrlen( g_pszProfileName ) + 1 ) * sizeof( TCHAR ) );
  189. if ( m_pszProfileName == NULL )
  190. {
  191. goto MemoryError;
  192. } // if: error allocating the profile name buffer
  193. lstrcpyn( const_cast< LPTSTR >( m_pszProfileName ), g_pszProfileName, lstrlen( g_pszProfileName ) + 1 );
  194. InitAllTraceTags(); // Initialize all trace tags.
  195. InitBarf(); // Initialize Basic Artificial Resource Failure system.
  196. // Load version information.
  197. #if 0
  198. {
  199. CVersionInfo verinfo;
  200. DWORD dwValue;
  201. // Initialize the version info.
  202. verinfo.Init();
  203. // Get the Locale ID.
  204. if ( verinfo.BQueryValue( _T("\\VarFileInfo\\Translation"), dwValue ) )
  205. {
  206. m_lcid = MAKELCID( dwValue, SORT_DEFAULT );
  207. } // if: locale ID is available
  208. } // Load version information
  209. #else
  210. // Get the locale ID from the system to support MUI.
  211. m_lcid = GetUserDefaultLCID();
  212. #endif
  213. // Initialize global CImageList
  214. InitGlobalImageList();
  215. #ifdef _AFXDLL
  216. Enable3dControls(); // Call this when using MFC in a shared DLL
  217. #else
  218. Enable3dControlsStatic(); // Call this when linking to MFC statically
  219. #endif
  220. LoadStdProfileSettings( 0 ); // Load standard INI file options (including MRU)
  221. // Create cluster MRU.
  222. m_pRecentFileList = new CRecentClusterList( 0, _T("Recent Cluster List"), _T("Cluster%d"), 4 );
  223. if ( m_pRecentFileList == NULL )
  224. {
  225. goto MemoryError;
  226. } // if: error allocating memory
  227. m_pRecentFileList->ReadList();
  228. // Register the application's document templates. Document templates
  229. // serve as the connection between documents, frame windows and views.
  230. m_pDocTemplate = new CMultiDocTemplate(
  231. IDR_CLUADMTYPE,
  232. RUNTIME_CLASS( CClusterDoc ),
  233. RUNTIME_CLASS( CSplitterFrame ), // custom MDI child frame
  234. RUNTIME_CLASS( CClusterTreeView )
  235. );
  236. if ( m_pDocTemplate == NULL )
  237. {
  238. goto MemoryError;
  239. } // if: error allocating memory
  240. AddDocTemplate( m_pDocTemplate );
  241. // create main MDI Frame window
  242. pMainFrame = new CMainFrame;
  243. if ( pMainFrame == NULL )
  244. {
  245. goto MemoryError;
  246. } // if: error allocating memory
  247. ASSERT( pMainFrame != NULL );
  248. if ( ! pMainFrame->LoadFrame( IDR_MAINFRAME ) )
  249. {
  250. goto Cleanup;
  251. } // if: error loading the frame
  252. m_pMainWnd = pMainFrame;
  253. // Parse command line for standard shell commands, DDE, file open
  254. // cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; // Don't want to do a FileNew.
  255. ParseCommandLine( cmdInfo );
  256. // If no commands were specified on the command line, restore the desktop.
  257. if ( cmdInfo.m_nShellCommand == CCommandLineInfo::FileNothing )
  258. {
  259. pMainFrame->PostMessage( WM_CAM_RESTORE_DESKTOP, cmdInfo.m_bReconnect );
  260. } // if: no commands specified on the command line
  261. // Create the cluster notification thread.
  262. if ( ! BInitNotifyThread() )
  263. {
  264. goto Cleanup;
  265. } // if: error creating the cluster notification thread
  266. // The main window has been initialized, so show and update it.
  267. {
  268. WINDOWPLACEMENT wp;
  269. // Set the placement of the window.
  270. if ( ReadWindowPlacement( &wp, REGPARAM_SETTINGS, 0 ) )
  271. {
  272. pMainFrame->SetWindowPlacement( &wp );
  273. m_nCmdShow = wp.showCmd; // set the show command.
  274. } // if: read from profile
  275. // Activate and update the frame window.
  276. pMainFrame->ActivateFrame( m_nCmdShow );
  277. pMainFrame->UpdateWindow();
  278. } // The main window has been initialized, so show and update it
  279. // Dispatch commands specified on the command line
  280. if ( ! ProcessShellCommand( cmdInfo ) )
  281. {
  282. goto Cleanup;
  283. } // if: error processing the command line
  284. TraceMenu( g_tagAppMenu, AfxGetMainWnd()->GetMenu(), _T("InitInstance menu: ") );
  285. bSuccess = TRUE;
  286. Cleanup:
  287. if ( m_pMainWnd != pMainFrame )
  288. {
  289. delete pMainFrame;
  290. } // if: main frame windows allocated but not saved yet
  291. return bSuccess;
  292. MemoryError:
  293. CNTException nte(
  294. ERROR_NOT_ENOUGH_MEMORY,
  295. 0, // idsOperation
  296. NULL, // pszOperArg1
  297. NULL, // pszOperArg2
  298. FALSE // bAutoDelete
  299. );
  300. nte.ReportError();
  301. nte.Delete();
  302. goto Cleanup;
  303. } //*** CClusterAdminApp::InitInstance()
  304. /////////////////////////////////////////////////////////////////////////////
  305. //++
  306. //
  307. // CClusterAdminApp::OnIdle
  308. //
  309. // Routine Description:
  310. // Process the command line or shell command.
  311. //
  312. // Arguments:
  313. // LONG [IN] Number of time we have been called before the next
  314. // message arrives in the queue
  315. //
  316. // Return Value:
  317. // TRUE if more idle processing
  318. //
  319. //--
  320. /////////////////////////////////////////////////////////////////////////////
  321. BOOL CClusterAdminApp::OnIdle(IN LONG lCount)
  322. {
  323. BOOL bMore = CWinApp::OnIdle(lCount);
  324. //
  325. // Since the MFC framework processing many messages lCount was never getting
  326. // higher than 1. Since this work should not be done everytime we are idle
  327. // I added my own counter that determines when the work is done.
  328. //
  329. if ((++m_nIdleCount % 200) == 0)
  330. {
  331. POSITION posDoc; // position in the documents collection
  332. POSITION posDel; // position in the to be deleted list
  333. POSITION posRemove; // position in the to be deleted list to remove
  334. CClusterDoc * pdoc;
  335. CClusterItem * pitem;
  336. CWaitCursor cw;
  337. posDoc = PdocTemplate()->GetFirstDocPosition();
  338. while (posDoc != NULL)
  339. {
  340. pdoc = (CClusterDoc *) PdocTemplate()->GetNextDoc(posDoc);
  341. ASSERT_VALID(pdoc);
  342. try
  343. {
  344. posDel = pdoc->LpciToBeDeleted().GetHeadPosition();
  345. while (posDel != NULL)
  346. {
  347. posRemove = posDel; // save posDel to posRemove since the next call is going to inc posDel
  348. pitem = (CClusterItem *) pdoc->LpciToBeDeleted().GetNext(posDel);
  349. ASSERT_VALID(pitem);
  350. if ((pitem != NULL) && ( pitem->NReferenceCount() == 1))
  351. {
  352. pdoc->LpciToBeDeleted().RemoveAt(posRemove); // the saved position posRemove
  353. } // if: the list's refence is the only one
  354. } // while: more items in the to be deleted list
  355. }
  356. catch (CException * pe)
  357. {
  358. pe->Delete();
  359. } // catch: CException
  360. } // while: more items in the list
  361. m_nIdleCount = 0;
  362. bMore = FALSE; // don't want any more calls until some new messages are received
  363. } // if: every 200th time...
  364. return bMore;
  365. } //*** CClusterAdminApp::OnIdle()
  366. /////////////////////////////////////////////////////////////////////////////
  367. //++
  368. //
  369. // CClusterAdminApp::ProcessShellCommand
  370. //
  371. // Routine Description:
  372. // Process the command line or shell command.
  373. //
  374. // Arguments:
  375. // rCmdInfo [IN OUT] Command line info.
  376. //
  377. // Return Value:
  378. // 0 Error.
  379. // !0 No error.
  380. //
  381. //--
  382. /////////////////////////////////////////////////////////////////////////////
  383. BOOL CClusterAdminApp::ProcessShellCommand(IN OUT CCluAdminCommandLineInfo & rCmdInfo)
  384. {
  385. BOOL bSuccess = TRUE;
  386. if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen)
  387. {
  388. POSITION pos;
  389. try
  390. {
  391. pos = rCmdInfo.LstrClusters().GetHeadPosition();
  392. while (pos != NULL)
  393. {
  394. OpenDocumentFile(rCmdInfo.LstrClusters().GetNext(pos));
  395. } // while: more clusters in the list
  396. } // try
  397. catch (CException * pe)
  398. {
  399. pe->ReportError();
  400. pe->Delete();
  401. bSuccess = FALSE;
  402. } // catch: CException
  403. } // if: we are opening clusters
  404. else
  405. bSuccess = CWinApp::ProcessShellCommand(rCmdInfo);
  406. return bSuccess;
  407. } //*** CClusterAdminApp::ProcessShellCommand()
  408. /////////////////////////////////////////////////////////////////////////////
  409. //++
  410. //
  411. // CClusterAdminApp::ExitInstance
  412. //
  413. // Routine Description:
  414. // Exit this instance of the application.
  415. //
  416. // Arguments:
  417. // None.
  418. //
  419. // Return Value:
  420. // 0 No errors.
  421. //
  422. //--
  423. /////////////////////////////////////////////////////////////////////////////
  424. int CClusterAdminApp::ExitInstance(void)
  425. {
  426. // Close the notification port.
  427. if (HchangeNotifyPort() != NULL)
  428. {
  429. ::CloseClusterNotifyPort(HchangeNotifyPort());
  430. m_hchangeNotifyPort = NULL;
  431. // Allow the notification port threads to clean themselves up.
  432. ::Sleep(100);
  433. } // if: notification port is open
  434. // Delete all the items in the notification key list.
  435. {
  436. POSITION pos;
  437. pos = Cnkl().GetHeadPosition();
  438. while (pos != NULL)
  439. delete Cnkl().GetNext(pos);
  440. Cnkl().RemoveAll();
  441. } // Delete all the items in the notification key list
  442. CleanupAllTraceTags(); // Cleanup trace tags.
  443. CleanupBarf(); // Cleanup Basic Artificial Resource Failure system.
  444. // Release the ClusCfg client object.
  445. if ( m_punkClusCfgClient != NULL )
  446. {
  447. m_punkClusCfgClient->Release();
  448. }
  449. return CWinApp::ExitInstance();
  450. } //*** CClusterAdminApp::ExitInstance()
  451. /////////////////////////////////////////////////////////////////////////////
  452. //++
  453. //
  454. // CClusterAdminApp::InitGlobalImageList
  455. //
  456. // Routine Description:
  457. // Initialize the global image list.
  458. //
  459. // Arguments:
  460. // None.
  461. //
  462. // Return Value:
  463. // None.
  464. //
  465. //--
  466. /////////////////////////////////////////////////////////////////////////////
  467. void CClusterAdminApp::InitGlobalImageList(void)
  468. {
  469. // Create small image list.
  470. VERIFY(PilSmallImages()->Create(
  471. (int) 16, // cx
  472. 16, // cy
  473. TRUE, // bMask
  474. 17, // nInitial
  475. 4 // nGrow
  476. ));
  477. PilSmallImages()->SetBkColor(::GetSysColor(COLOR_WINDOW));
  478. // Load the images into the small image list.
  479. LoadImageIntoList(PilSmallImages(), IDB_FOLDER_16, IMGLI_FOLDER);
  480. LoadImageIntoList(PilSmallImages(), IDB_CLUSTER_16, IMGLI_CLUSTER);
  481. LoadImageIntoList(PilSmallImages(), IDB_CLUSTER_UNKNOWN_16, IMGLI_CLUSTER_UNKNOWN);
  482. LoadImageIntoList(PilSmallImages(), IDB_NODE_16, IMGLI_NODE);
  483. LoadImageIntoList(PilSmallImages(), IDB_NODE_DOWN_16, IMGLI_NODE_DOWN);
  484. LoadImageIntoList(PilSmallImages(), IDB_NODE_PAUSED_16, IMGLI_NODE_PAUSED);
  485. LoadImageIntoList(PilSmallImages(), IDB_NODE_UNKNOWN_16, IMGLI_NODE_UNKNOWN);
  486. LoadImageIntoList(PilSmallImages(), IDB_GROUP_16, IMGLI_GROUP);
  487. LoadImageIntoList(PilSmallImages(), IDB_GROUP_PARTIAL_ONLINE_16, IMGLI_GROUP_PARTIALLY_ONLINE);
  488. LoadImageIntoList(PilSmallImages(), IDB_GROUP_PENDING_16, IMGLI_GROUP_PENDING);
  489. LoadImageIntoList(PilSmallImages(), IDB_GROUP_OFFLINE_16, IMGLI_GROUP_OFFLINE);
  490. LoadImageIntoList(PilSmallImages(), IDB_GROUP_FAILED_16, IMGLI_GROUP_FAILED);
  491. LoadImageIntoList(PilSmallImages(), IDB_GROUP_UNKNOWN_16, IMGLI_GROUP_UNKNOWN);
  492. LoadImageIntoList(PilSmallImages(), IDB_RES_16, IMGLI_RES);
  493. LoadImageIntoList(PilSmallImages(), IDB_RES_OFFLINE_16, IMGLI_RES_OFFLINE);
  494. LoadImageIntoList(PilSmallImages(), IDB_RES_PENDING_16, IMGLI_RES_PENDING);
  495. LoadImageIntoList(PilSmallImages(), IDB_RES_FAILED_16, IMGLI_RES_FAILED);
  496. LoadImageIntoList(PilSmallImages(), IDB_RES_UNKNOWN_16, IMGLI_RES_UNKNOWN);
  497. LoadImageIntoList(PilSmallImages(), IDB_RESTYPE_16, IMGLI_RESTYPE);
  498. LoadImageIntoList(PilSmallImages(), IDB_RESTYPE_UNKNOWN_16, IMGLI_RESTYPE_UNKNOWN);
  499. LoadImageIntoList(PilSmallImages(), IDB_NETWORK_16, IMGLI_NETWORK);
  500. LoadImageIntoList(PilSmallImages(), IDB_NETWORK_PARTITIONED_16, IMGLI_NETWORK_PARTITIONED);
  501. LoadImageIntoList(PilSmallImages(), IDB_NETWORK_DOWN_16, IMGLI_NETWORK_DOWN);
  502. LoadImageIntoList(PilSmallImages(), IDB_NETWORK_UNKNOWN_16, IMGLI_NETWORK_UNKNOWN);
  503. LoadImageIntoList(PilSmallImages(), IDB_NETIFACE_16, IMGLI_NETIFACE);
  504. LoadImageIntoList(PilSmallImages(), IDB_NETIFACE_UNREACHABLE_16, IMGLI_NETIFACE_UNREACHABLE);
  505. LoadImageIntoList(PilSmallImages(), IDB_NETIFACE_FAILED_16, IMGLI_NETIFACE_FAILED);
  506. LoadImageIntoList(PilSmallImages(), IDB_NETIFACE_UNKNOWN_16, IMGLI_NETIFACE_UNKNOWN);
  507. // Create large image list.
  508. VERIFY(PilLargeImages()->Create(
  509. (int) 32, // cx
  510. 32, // cy
  511. TRUE, // bMask
  512. 17, // nInitial
  513. 4 // nGrow
  514. ));
  515. PilLargeImages()->SetBkColor(::GetSysColor(COLOR_WINDOW));
  516. // Load the images into the large image list.
  517. LoadImageIntoList(PilLargeImages(), IDB_FOLDER_32, IMGLI_FOLDER);
  518. LoadImageIntoList(PilLargeImages(), IDB_CLUSTER_32, IMGLI_CLUSTER);
  519. LoadImageIntoList(PilLargeImages(), IDB_CLUSTER_UNKNOWN_32, IMGLI_CLUSTER_UNKNOWN);
  520. LoadImageIntoList(PilLargeImages(), IDB_NODE_32, IMGLI_NODE);
  521. LoadImageIntoList(PilLargeImages(), IDB_NODE_DOWN_32, IMGLI_NODE_DOWN);
  522. LoadImageIntoList(PilLargeImages(), IDB_NODE_PAUSED_32, IMGLI_NODE_PAUSED);
  523. LoadImageIntoList(PilLargeImages(), IDB_NODE_UNKNOWN_32, IMGLI_NODE_UNKNOWN);
  524. LoadImageIntoList(PilLargeImages(), IDB_GROUP_32, IMGLI_GROUP);
  525. LoadImageIntoList(PilLargeImages(), IDB_GROUP_PARTIAL_ONLINE_32, IMGLI_GROUP_PARTIALLY_ONLINE);
  526. LoadImageIntoList(PilLargeImages(), IDB_GROUP_PENDING_32, IMGLI_GROUP_PENDING);
  527. LoadImageIntoList(PilLargeImages(), IDB_GROUP_OFFLINE_32, IMGLI_GROUP_OFFLINE);
  528. LoadImageIntoList(PilLargeImages(), IDB_GROUP_FAILED_32, IMGLI_GROUP_FAILED);
  529. LoadImageIntoList(PilLargeImages(), IDB_GROUP_UNKNOWN_32, IMGLI_GROUP_UNKNOWN);
  530. LoadImageIntoList(PilLargeImages(), IDB_RES_32, IMGLI_RES);
  531. LoadImageIntoList(PilLargeImages(), IDB_RES_OFFLINE_32, IMGLI_RES_OFFLINE);
  532. LoadImageIntoList(PilLargeImages(), IDB_RES_PENDING_32, IMGLI_RES_PENDING);
  533. LoadImageIntoList(PilLargeImages(), IDB_RES_FAILED_32, IMGLI_RES_FAILED);
  534. LoadImageIntoList(PilLargeImages(), IDB_RES_UNKNOWN_32, IMGLI_RES_UNKNOWN);
  535. LoadImageIntoList(PilLargeImages(), IDB_RESTYPE_32, IMGLI_RESTYPE);
  536. LoadImageIntoList(PilLargeImages(), IDB_RESTYPE_UNKNOWN_32, IMGLI_RESTYPE_UNKNOWN);
  537. LoadImageIntoList(PilLargeImages(), IDB_NETWORK_32, IMGLI_NETWORK);
  538. LoadImageIntoList(PilLargeImages(), IDB_NETWORK_PARTITIONED_32, IMGLI_NETWORK_PARTITIONED);
  539. LoadImageIntoList(PilLargeImages(), IDB_NETWORK_DOWN_32, IMGLI_NETWORK_DOWN);
  540. LoadImageIntoList(PilLargeImages(), IDB_NETWORK_UNKNOWN_32, IMGLI_NETWORK_UNKNOWN);
  541. LoadImageIntoList(PilLargeImages(), IDB_NETIFACE_32, IMGLI_NETIFACE);
  542. LoadImageIntoList(PilLargeImages(), IDB_NETIFACE_UNREACHABLE_32, IMGLI_NETIFACE_UNREACHABLE);
  543. LoadImageIntoList(PilLargeImages(), IDB_NETIFACE_FAILED_32, IMGLI_NETIFACE_FAILED);
  544. LoadImageIntoList(PilLargeImages(), IDB_NETIFACE_UNKNOWN_32, IMGLI_NETIFACE_UNKNOWN);
  545. } //*** CClusterAdminApp::InitGlobalImageList()
  546. /////////////////////////////////////////////////////////////////////////////
  547. //++
  548. //
  549. // CClusterAdminApp::LoadImageIntoList
  550. //
  551. // Routine Description:
  552. // Load images into an image list.
  553. //
  554. // Arguments:
  555. // pil [IN OUT] Image list into which to load the image.
  556. // idbImage [IN] Resource ID for the image bitmap.
  557. // imgli [IN] Index into the index array.
  558. //
  559. // Return Value:
  560. // None.
  561. //
  562. //--
  563. /////////////////////////////////////////////////////////////////////////////
  564. void CClusterAdminApp::LoadImageIntoList(
  565. IN OUT CImageList * pil,
  566. IN ID idbImage,
  567. IN UINT imgli
  568. )
  569. {
  570. CBitmap bm;
  571. UINT iimg;
  572. LoadImageIntoList(pil, idbImage, &iimg);
  573. if (m_rgiimg[imgli] == (UINT) -1)
  574. m_rgiimg[imgli] = iimg;
  575. #ifdef DEBUG
  576. else
  577. ASSERT(m_rgiimg[imgli] == iimg);
  578. #endif
  579. } //*** CClusterAdminApp::LoadImageIntoList()
  580. /////////////////////////////////////////////////////////////////////////////
  581. //++
  582. //
  583. // static
  584. // CClusterAdminApp::LoadImageIntoList
  585. //
  586. // Routine Description:
  587. // Load images into an image list.
  588. //
  589. // Arguments:
  590. // pil [IN OUT] Image list into which to load the image.
  591. // idbImage [IN] Resource ID for the image bitmap.
  592. // piimg [OUT] Pointer to image index.
  593. //
  594. // Return Value:
  595. // None.
  596. //
  597. //--
  598. /////////////////////////////////////////////////////////////////////////////
  599. void CClusterAdminApp::LoadImageIntoList(
  600. IN OUT CImageList * pil,
  601. IN ID idbImage,
  602. OUT UINT * piimg
  603. )
  604. {
  605. CBitmap bm;
  606. UINT iimg;
  607. COLORREF crMaskColor = RGB(255,0,255);
  608. ASSERT(pil != NULL);
  609. ASSERT(idbImage != 0);
  610. if (piimg == NULL)
  611. piimg = &iimg;
  612. bm.LoadBitmap(idbImage);
  613. *piimg = pil->Add(&bm, crMaskColor);
  614. } //*** CClusterAdminApp::LoadImageIntoList()
  615. /////////////////////////////////////////////////////////////////////////////
  616. //++
  617. //
  618. // CClusterAdminApp::OnRestoreDesktop
  619. //
  620. // Routine Description:
  621. // Handler for the WM_CAM_RESTORE_DESKTOP message.
  622. // Restores the desktop from the saved parameters.
  623. //
  624. // Arguments:
  625. // wparam TRUE = reconnect, FALSE, don't reconnect.
  626. // lparam Unused.
  627. //
  628. // Return Value:
  629. // 0
  630. //
  631. //--
  632. /////////////////////////////////////////////////////////////////////////////
  633. LRESULT CClusterAdminApp::OnRestoreDesktop(WPARAM wparam, LPARAM lparam)
  634. {
  635. CString strConnections;
  636. WPARAM bReconnect = wparam;
  637. if (bReconnect)
  638. {
  639. // Read the connections the user had last time they exited.
  640. try
  641. {
  642. strConnections = GetProfileString(REGPARAM_CONNECTIONS, REGPARAM_CONNECTIONS);
  643. } // try
  644. catch (CException * pe)
  645. {
  646. pe->ReportError();
  647. pe->Delete();
  648. } // catch: CException
  649. // If there were any connections, restore them.
  650. if (strConnections.GetLength() > 0)
  651. {
  652. LPTSTR pszConnections;
  653. LPTSTR pszConnection;
  654. TCHAR szSep[] = _T(",");
  655. ASSERT(m_pMainWnd != NULL);
  656. try
  657. {
  658. pszConnections = strConnections.GetBuffer(1);
  659. pszConnection = _tcstok(pszConnections, szSep);
  660. while (pszConnection != NULL)
  661. {
  662. // Open a connection to this cluster.
  663. OpenDocumentFile(pszConnection);
  664. // Find the next connection.
  665. pszConnection = _tcstok(NULL, szSep);
  666. } // while: more connections
  667. } // try
  668. catch (CException * pe)
  669. {
  670. pe->ReportError();
  671. pe->Delete();
  672. } // catch: CException
  673. strConnections.ReleaseBuffer();
  674. } // if: connections saved previously
  675. else
  676. bReconnect = FALSE;
  677. } // if: reconnect is desired
  678. if (!bReconnect)
  679. {
  680. CWaitCursor wc;
  681. Sleep(1500);
  682. } // if: not reconnecting
  683. // If there were no previous connections and we are not minimized, do a standard file open.
  684. if (!bReconnect && !AfxGetMainWnd()->IsIconic())
  685. OnFileOpen();
  686. // Otherwise, restore the desktop.
  687. return 0;
  688. } //*** CClusterAdminApp::OnRestoreDesktop()
  689. /////////////////////////////////////////////////////////////////////////////
  690. //++
  691. //
  692. // CClusterAdminApp::SaveConnections
  693. //
  694. // Routine Description:
  695. // Save the current connections so they can be restored later.
  696. //
  697. // Arguments:
  698. // None.
  699. //
  700. // Return Value:
  701. // None.
  702. //
  703. //--
  704. /////////////////////////////////////////////////////////////////////////////
  705. void CClusterAdminApp::SaveConnections(void)
  706. {
  707. POSITION pos;
  708. CClusterDoc * pdoc;
  709. CString strConnections;
  710. TCHAR szSep[] = _T("\0");
  711. pos = PdocTemplate()->GetFirstDocPosition();
  712. while (pos != NULL)
  713. {
  714. pdoc = (CClusterDoc *) PdocTemplate()->GetNextDoc(pos);
  715. ASSERT_VALID(pdoc);
  716. try
  717. {
  718. strConnections += szSep + pdoc->StrNode();
  719. szSep[0] = _T(','); // Subsequent connections are preceded by a separator
  720. }
  721. catch (CException * pe)
  722. {
  723. pe->Delete();
  724. } // catch: CException
  725. // Save connection-specific settings as well.
  726. pdoc->SaveSettings();
  727. } // while: more items in the list
  728. WriteProfileString(REGPARAM_CONNECTIONS, REGPARAM_CONNECTIONS, strConnections);
  729. } //*** CClusterAdminApp::SaveConnections()
  730. /////////////////////////////////////////////////////////////////////////////
  731. //++
  732. //
  733. // CClusterAdminApp::OnFileOpen
  734. //
  735. // Routine Description:
  736. // Prompt the user for the name of a cluster or server and then open it.
  737. //
  738. // Arguments:
  739. // None.
  740. //
  741. // Return Value:
  742. // None.
  743. //
  744. //--
  745. /////////////////////////////////////////////////////////////////////////////
  746. void CClusterAdminApp::OnFileOpen(void)
  747. {
  748. COpenClusterDialog dlg;
  749. ID idDlgStatus;
  750. CDocument * pdoc = NULL;
  751. HCLUSTER hCluster = NULL;
  752. do
  753. {
  754. idDlgStatus = (ID) dlg.DoModal();
  755. if ( idDlgStatus != IDOK )
  756. {
  757. break;
  758. }
  759. switch ( dlg.m_nAction )
  760. {
  761. case OPEN_CLUSTER_DLG_CREATE_NEW_CLUSTER:
  762. OnFileNewCluster();
  763. break;
  764. case OPEN_CLUSTER_DLG_ADD_NODES:
  765. case OPEN_CLUSTER_DLG_OPEN_CONNECTION:
  766. if ( hCluster != NULL )
  767. {
  768. CloseCluster( hCluster );
  769. } // if: previous cluster opened
  770. hCluster = HOpenCluster( dlg.m_strName );
  771. if ( hCluster == NULL )
  772. {
  773. CNTException nte( GetLastError(), IDS_OPEN_CLUSTER_ERROR, dlg.m_strName );
  774. nte.ReportError();
  775. } // if: error opening the cluster
  776. else
  777. {
  778. Trace( g_tagApp, _T("OnFileOpen() - Opening the cluster document on '%s'"), dlg.m_strName );
  779. m_hOpenedCluster = hCluster;
  780. pdoc = OpenDocumentFile( dlg.m_strName );
  781. m_hOpenedCluster = NULL;
  782. hCluster = NULL;
  783. } // else: cluster opened successfully
  784. if ( ( pdoc != NULL ) && ( dlg.m_nAction == OPEN_CLUSTER_DLG_ADD_NODES ) )
  785. {
  786. NewNodeWizard(
  787. dlg.m_strName,
  788. FALSE // fIgnoreErrors
  789. );
  790. } // if: add a node to the cluster
  791. break;
  792. } // switch: dialog action
  793. } while ( ( pdoc == NULL )
  794. && ( dlg.m_nAction != OPEN_CLUSTER_DLG_CREATE_NEW_CLUSTER ) );
  795. if ( hCluster != NULL )
  796. {
  797. CloseCluster( hCluster );
  798. }
  799. } //*** CClusterAdminApp::OnFileOpen()
  800. /////////////////////////////////////////////////////////////////////////////
  801. //++
  802. //
  803. // CClusterAdminApp::OpenDocumentFile
  804. //
  805. // Routine Description:
  806. // Open a cluster.
  807. //
  808. // Arguments:
  809. // lpszFileName The name of the cluster or a server in that cluster.
  810. //
  811. // Return Value:
  812. // NULL Invalid cluster or server name.
  813. // pOpenDocument The document instance for the open cluster.
  814. //
  815. //--
  816. /////////////////////////////////////////////////////////////////////////////
  817. CDocument * CClusterAdminApp::OpenDocumentFile(LPCTSTR lpszFileName)
  818. {
  819. // find the highest confidence
  820. CDocTemplate::Confidence bestMatch = CDocTemplate::noAttempt;
  821. CDocTemplate * pBestTemplate = NULL;
  822. CDocument * pOpenDocument = NULL;
  823. {
  824. ASSERT_KINDOF(CDocTemplate, m_pDocTemplate);
  825. CDocTemplate::Confidence match;
  826. ASSERT(pOpenDocument == NULL);
  827. match = m_pDocTemplate->MatchDocType(lpszFileName, pOpenDocument);
  828. if (match > bestMatch)
  829. {
  830. bestMatch = match;
  831. pBestTemplate = m_pDocTemplate;
  832. }
  833. }
  834. if (pOpenDocument != NULL)
  835. {
  836. POSITION pos = pOpenDocument->GetFirstViewPosition();
  837. if (pos != NULL)
  838. {
  839. CView * pView = pOpenDocument->GetNextView(pos); // get first one
  840. ASSERT_VALID(pView);
  841. CFrameWnd * pFrame = pView->GetParentFrame();
  842. if (pFrame != NULL)
  843. pFrame->ActivateFrame();
  844. else
  845. Trace(g_tagApp, _T("Error: Can not find a frame for document to activate."));
  846. CFrameWnd * pAppFrame;
  847. if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()->m_pMainWnd))
  848. {
  849. ASSERT_KINDOF(CFrameWnd, pAppFrame);
  850. pAppFrame->ActivateFrame();
  851. }
  852. }
  853. else
  854. {
  855. Trace(g_tagApp, _T("Error: Can not find a view for document to activate."));
  856. }
  857. return pOpenDocument;
  858. }
  859. if (pBestTemplate == NULL)
  860. {
  861. TCHAR szMsg[1024];
  862. AfxLoadString(AFX_IDP_FAILED_TO_OPEN_DOC, szMsg, sizeof(szMsg));
  863. AfxMessageBox(szMsg);
  864. return NULL;
  865. }
  866. return pBestTemplate->OpenDocumentFile(lpszFileName);
  867. } //*** CClusterAdminApp::OpenDocumentFile()
  868. /////////////////////////////////////////////////////////////////////////////
  869. //++
  870. //
  871. // CClusterAdminApp::AddToRecentFileList
  872. //
  873. // Routine Description:
  874. // Adds a file to the Most Recently Used file list. Overridden to
  875. // prevent the cluster name from being fully qualified as a file.
  876. //
  877. // Arguments:
  878. // lpszPathName [IN] The path of the file.
  879. //
  880. // Return Value:
  881. // None.
  882. //
  883. //--
  884. /////////////////////////////////////////////////////////////////////////////
  885. void CClusterAdminApp::AddToRecentFileList(LPCTSTR lpszPathName)
  886. {
  887. ASSERT_VALID(this);
  888. ASSERT(lpszPathName != NULL);
  889. ASSERT(AfxIsValidString(lpszPathName));
  890. if (m_pRecentFileList != NULL)
  891. {
  892. // Don't fully qualify the path name.
  893. m_pRecentFileList->Add(lpszPathName);
  894. }
  895. } //*** CClusterAdminApp::AddToRecentFileList()
  896. /////////////////////////////////////////////////////////////////////////////
  897. //++
  898. //
  899. // CClusterAdminApp::LoadClusCfgClient
  900. //
  901. // Routine Description:
  902. // Makes sure that the ClusCfg client has been loaded. This is
  903. // required because it can only be loaded once per process.
  904. //
  905. // Note: DavidP 21-AUG-2000 This is a hack, IMHO!
  906. //
  907. // Arguments:
  908. // None.
  909. //
  910. // Return Value:
  911. // None.
  912. //
  913. //--
  914. /////////////////////////////////////////////////////////////////////////////
  915. void CClusterAdminApp::LoadClusCfgClient( void )
  916. {
  917. HRESULT hr;
  918. if ( m_punkClusCfgClient == NULL )
  919. {
  920. //
  921. // Get the service manager.
  922. //
  923. hr = CoCreateInstance(
  924. CLSID_ServiceManager
  925. , NULL
  926. , CLSCTX_INPROC_SERVER
  927. , IID_IUnknown
  928. , reinterpret_cast< void ** >( &m_punkClusCfgClient )
  929. );
  930. if ( FAILED( hr ) )
  931. {
  932. ThrowStaticException( hr, IDS_CREATE_CLUSCFGWIZ_OBJ_ERROR );
  933. } // if: error loading the ClusCfg client
  934. } // if: not loaded yet
  935. } //*** CClusterAdminApp::LoadClusCfgClient()
  936. /////////////////////////////////////////////////////////////////////////////
  937. //++
  938. //
  939. // CClusterAdminApp::OnFileNewCluster
  940. //
  941. // Routine Description:
  942. // Processes the ID_FILE_NEW_CLUSTER menu command.
  943. //
  944. // Arguments:
  945. // None.
  946. //
  947. // Return Value:
  948. // None.
  949. //
  950. //--
  951. /////////////////////////////////////////////////////////////////////////////
  952. void CClusterAdminApp::OnFileNewCluster( void )
  953. {
  954. HRESULT hr;
  955. IClusCfgWizard * piWiz;
  956. BOOL fCommitted = FALSE;
  957. // Make sure the ClusCfg client has been loaded.
  958. LoadClusCfgClient();
  959. // Get an interface pointer for the wizard.
  960. hr = CoCreateInstance(
  961. CLSID_ClusCfgWizard,
  962. NULL,
  963. CLSCTX_INPROC_SERVER,
  964. IID_IClusCfgWizard,
  965. (LPVOID *) &piWiz
  966. );
  967. if ( FAILED( hr ) )
  968. {
  969. CNTException nte( hr, IDS_CREATE_CLUSCFGWIZ_OBJ_ERROR, NULL, NULL, FALSE /*bAutoDelete*/ );
  970. nte.ReportError();
  971. return;
  972. } // if: error getting the interface pointer
  973. // Display the wizard.
  974. hr = piWiz->CreateCluster(
  975. AfxGetMainWnd()->m_hWnd,
  976. &fCommitted
  977. );
  978. if ( FAILED( hr ) )
  979. {
  980. CNTException nte( hr, IDS_CREATE_CLUSTER_ERROR, NULL, NULL, FALSE /*bAutoDelete*/ );
  981. nte.ReportError();
  982. } // if: error adding cluster nodes
  983. if ( fCommitted )
  984. {
  985. BSTR bstrClusterName;
  986. hr = piWiz->get_ClusterName( &bstrClusterName );
  987. if ( FAILED( hr ) )
  988. {
  989. CNTException nte( hr, IDS_CREATE_CLUSTER_ERROR, NULL, NULL, FALSE /*bAutoDelete*/ );
  990. nte.ReportError();
  991. }
  992. else
  993. {
  994. if ( hr == S_OK )
  995. {
  996. HCLUSTER hCluster;
  997. ASSERT( bstrClusterName != NULL );
  998. // Open the cluster with the cluster name specified by the
  999. // wizard. If it not successful, translate this to a NetBIOS
  1000. // name in case that is more reliable.
  1001. hCluster = OpenCluster( bstrClusterName );
  1002. if ( hCluster == NULL )
  1003. {
  1004. WCHAR szClusterNetBIOSName[ MAX_COMPUTERNAME_LENGTH + 1 ];
  1005. DWORD nSize = sizeof( szClusterNetBIOSName ) / sizeof( szClusterNetBIOSName[ 0 ] );
  1006. DnsHostnameToComputerName( bstrClusterName, szClusterNetBIOSName, &nSize );
  1007. SysFreeString( bstrClusterName );
  1008. bstrClusterName = SysAllocString( szClusterNetBIOSName );
  1009. }
  1010. else
  1011. {
  1012. CloseCluster( hCluster );
  1013. }
  1014. OpenDocumentFile( bstrClusterName );
  1015. } // if: retrieved cluster name successfully
  1016. SysFreeString( bstrClusterName );
  1017. } // else: retrieving cluster name didn't fail
  1018. } // if: user didn't cancel the wizard
  1019. piWiz->Release();
  1020. } //*** CClusterAdminApp::OnFileNewCluster()
  1021. /////////////////////////////////////////////////////////////////////////////
  1022. //++
  1023. //
  1024. // CClusterAdminApp::OnAppAbout
  1025. //
  1026. // Routine Description:
  1027. // Displays the about box.
  1028. //
  1029. // Arguments:
  1030. // None.
  1031. //
  1032. // Return Value:
  1033. // None.
  1034. //
  1035. //--
  1036. /////////////////////////////////////////////////////////////////////////////
  1037. void CClusterAdminApp::OnAppAbout(void)
  1038. {
  1039. CAboutDlg aboutDlg;
  1040. aboutDlg.DoModal();
  1041. } //*** CClusterAdminApp::OnAppAbout()
  1042. /////////////////////////////////////////////////////////////////////////////
  1043. //++
  1044. //
  1045. // CClusterAdminApp::OnUpdateWindowCloseAll
  1046. //
  1047. // Routine Description:
  1048. // Determines whether menu items corresponding to ID_WINDOW_CLOSE_ALL
  1049. // should be enabled or not.
  1050. //
  1051. // Arguments:
  1052. // pCmdUI [IN OUT] Command routing object.
  1053. //
  1054. // Return Value:
  1055. // None.
  1056. //
  1057. //--
  1058. /////////////////////////////////////////////////////////////////////////////
  1059. void CClusterAdminApp::OnUpdateWindowCloseAll(CCmdUI * pCmdUI)
  1060. {
  1061. pCmdUI->Enable(m_pDocTemplate->GetFirstDocPosition() != NULL);
  1062. } //*** CClusterAdminApp::OnUpdateWindowCloseAll()
  1063. /////////////////////////////////////////////////////////////////////////////
  1064. //++
  1065. //
  1066. // CClusterAdminApp::OnWindowCloseAll
  1067. //
  1068. // Routine Description:
  1069. // Processes the ID_WINDOW_CLOSE_ALL menu command.
  1070. //
  1071. // Arguments:
  1072. // None.
  1073. //
  1074. // Return Value:
  1075. // None.
  1076. //
  1077. //--
  1078. /////////////////////////////////////////////////////////////////////////////
  1079. void CClusterAdminApp::OnWindowCloseAll(void)
  1080. {
  1081. CloseAllDocuments(FALSE /*bEndSession*/);
  1082. } //*** CClusterAdminApp::OnWindowCloseAll()
  1083. #ifdef _DEBUG
  1084. /////////////////////////////////////////////////////////////////////////////
  1085. //++
  1086. //
  1087. // CClusterAdminApp::OnTraceSettings
  1088. //
  1089. // Routine Description:
  1090. // Displays the Trace Settings dialog.
  1091. //
  1092. // Arguments:
  1093. // None.
  1094. //
  1095. // Return Value:
  1096. // None.
  1097. //
  1098. //--
  1099. /////////////////////////////////////////////////////////////////////////////
  1100. void CClusterAdminApp::OnTraceSettings(void)
  1101. {
  1102. CTraceDialog dlgTraceSettings;
  1103. dlgTraceSettings.DoModal();
  1104. } //*** CClusterAdminApp::OnTraceSettings()
  1105. /////////////////////////////////////////////////////////////////////////////
  1106. //++
  1107. //
  1108. // CClusterAdminApp::OnBarfSettings
  1109. //
  1110. // Routine Description:
  1111. // Displays the BARF Settings dialog.
  1112. //
  1113. // Arguments:
  1114. // None.
  1115. //
  1116. // Return Value:
  1117. // None.
  1118. //
  1119. //--
  1120. /////////////////////////////////////////////////////////////////////////////
  1121. void CClusterAdminApp::OnBarfSettings(void)
  1122. {
  1123. DoBarfDialog();
  1124. } //*** CClusterAdminApp::OnBarfSettings()
  1125. /////////////////////////////////////////////////////////////////////////////
  1126. //++
  1127. //
  1128. // CClusterAdminApp::OnBarfAllSettings
  1129. //
  1130. // Routine Description:
  1131. // Displays the BARF All Settings dialog.
  1132. //
  1133. // Arguments:
  1134. // None.
  1135. //
  1136. // Return Value:
  1137. // None.
  1138. //
  1139. //--
  1140. /////////////////////////////////////////////////////////////////////////////
  1141. void CClusterAdminApp::OnBarfAllSettings(void)
  1142. {
  1143. BarfAll();
  1144. } //*** CClusterAdminApp::OnBarfAllSettings()
  1145. #endif // _DEBUG
  1146. /////////////////////////////////////////////////////////////////////////////
  1147. //++
  1148. //
  1149. // CClusterAdminApp::OnClusterNotify
  1150. //
  1151. // Routine Description:
  1152. // Handler for the WM_CAM_CLUSTER_NOTIFY message.
  1153. // Processes cluster notifications.
  1154. //
  1155. // Arguments:
  1156. // wparam WPARAM.
  1157. // LPARAM LPARAM = CClusterNotify object describing the notification.
  1158. //
  1159. // Return Value:
  1160. // Value returned from the application method.
  1161. //
  1162. //--
  1163. /////////////////////////////////////////////////////////////////////////////
  1164. LRESULT CClusterAdminApp::OnClusterNotify(WPARAM wparam, LPARAM lparam)
  1165. {
  1166. CClusterNotify * pnotify = (CClusterNotify *) lparam;
  1167. ASSERT(pnotify != NULL);
  1168. ASSERT(pnotify->m_dwNotifyKey != NULL);
  1169. // Send change notifications to the object that registered it.
  1170. if (pnotify->m_pcnk != NULL)
  1171. {
  1172. // Find the notification key in our list of keys. If it is not
  1173. // found, ignore it. Otherwise, ask the object that registered
  1174. // the notification to handle it.
  1175. if (Cnkl().Find(pnotify->m_pcnk) != NULL)
  1176. {
  1177. switch (pnotify->m_pcnk->m_cnkt)
  1178. {
  1179. case cnktDoc:
  1180. ASSERT_VALID(pnotify->m_pcnk->m_pdoc);
  1181. return pnotify->m_pcnk->m_pdoc->OnClusterNotify(pnotify);
  1182. case cnktClusterItem:
  1183. ASSERT_VALID(pnotify->m_pcnk->m_pci);
  1184. ASSERT_VALID(pnotify->m_pcnk->m_pci->Pdoc());
  1185. return pnotify->m_pcnk->m_pci->OnClusterNotify(pnotify);
  1186. } // switch: notification key type
  1187. } // if: notification key found in the list
  1188. } // if: non-NULL object pointer
  1189. // Notification not handled.
  1190. Trace(g_tagError, _T("*** Unhandled notification: key %08.8x, filter %x (%s) - '%s'"), pnotify->m_dwNotifyKey, pnotify->m_dwFilterType, PszNotificationName(pnotify->m_dwFilterType), pnotify->m_strName);
  1191. delete pnotify;
  1192. return 0;
  1193. } //*** CClusterAdminApp::OnClusterNotify()
  1194. /////////////////////////////////////////////////////////////////////////////
  1195. //++
  1196. //
  1197. // CClusterAdminApp::BInitNotifyThread
  1198. //
  1199. // Routine Description:
  1200. // Initialize the cluster notification thread.
  1201. //
  1202. // Arguments:
  1203. // None.
  1204. //
  1205. // Return Value:
  1206. // TRUE Thread initialized successfully.
  1207. // FALSE Thread NOT initialized successfully.
  1208. //
  1209. //--
  1210. /////////////////////////////////////////////////////////////////////////////
  1211. BOOL CClusterAdminApp::BInitNotifyThread(void)
  1212. {
  1213. try
  1214. {
  1215. // Create the notification port.
  1216. m_hchangeNotifyPort = ::CreateClusterNotifyPort(
  1217. (HCHANGE) INVALID_HANDLE_VALUE, // hChange
  1218. (HCLUSTER) INVALID_HANDLE_VALUE, // hCluster
  1219. 0, // dwFilter
  1220. 0 // dwNotifyKey
  1221. );
  1222. if (HchangeNotifyPort() == NULL)
  1223. ThrowStaticException(GetLastError());
  1224. // Construct the context object.
  1225. Pcnctx()->m_hchangeNotifyPort = HchangeNotifyPort();
  1226. Pcnctx()->m_hwndFrame = m_pMainWnd->m_hWnd;
  1227. // Begin the thread.
  1228. m_wtNotifyThread = AfxBeginThread(NotifyThreadProc, Pcnctx());
  1229. if (WtNotifyThread() == NULL)
  1230. ThrowStaticException(GetLastError());
  1231. } // try
  1232. catch (CException * pe)
  1233. {
  1234. // Close the notify port.
  1235. if (HchangeNotifyPort() != NULL)
  1236. {
  1237. ::CloseClusterNotifyPort(HchangeNotifyPort());
  1238. m_hchangeNotifyPort = NULL;
  1239. } // if: notify port is open
  1240. pe->ReportError();
  1241. pe->Delete();
  1242. return FALSE;
  1243. } // catch: CException
  1244. return TRUE;
  1245. } //*** CClusterAdminApp::BInitNotifyThread()
  1246. /////////////////////////////////////////////////////////////////////////////
  1247. //++
  1248. //
  1249. // CClusterAdminApp::NotifyThreadProc (static)
  1250. //
  1251. // Routine Description:
  1252. // Notification thread procedure.
  1253. //
  1254. // Arguments:
  1255. // pParam [IN OUT] Thread procedure parameter -- a notification
  1256. // context object.
  1257. //
  1258. // Return Value:
  1259. // None.
  1260. //
  1261. //--
  1262. /////////////////////////////////////////////////////////////////////////////
  1263. UINT AFX_CDECL CClusterAdminApp::NotifyThreadProc(LPVOID pParam)
  1264. {
  1265. DWORD dwStatus;
  1266. WCHAR* pwszName;
  1267. DWORD cchName;
  1268. DWORD cchBuffer;
  1269. DWORD_PTR dwNotifyKey;
  1270. DWORD dwFilterType;
  1271. CClusterNotify * pnotify = NULL;
  1272. CClusterNotifyContext * pnctx = (CClusterNotifyContext *) pParam;
  1273. #ifdef _DEBUG
  1274. TCHAR * pszTracePrefix;
  1275. CTraceTag * ptag;
  1276. #endif
  1277. ASSERT(pParam != NULL);
  1278. ASSERT_KINDOF(CClusterNotifyContext, pnctx);
  1279. ASSERT(pnctx->m_hchangeNotifyPort != NULL);
  1280. ASSERT(pnctx->m_hwndFrame != NULL);
  1281. pwszName = new WCHAR[1024];
  1282. cchBuffer = 1024;
  1283. ASSERT( pwszName != NULL );
  1284. if ( pwszName == NULL )
  1285. {
  1286. AfxThrowMemoryException();
  1287. } // if: memory exception
  1288. for (;;)
  1289. {
  1290. cchName = cchBuffer;
  1291. dwStatus = GetClusterNotify(
  1292. pnctx->m_hchangeNotifyPort,
  1293. &dwNotifyKey,
  1294. &dwFilterType,
  1295. pwszName,
  1296. &cchName,
  1297. INFINITE
  1298. );
  1299. if (dwStatus == ERROR_INVALID_HANDLE)
  1300. {
  1301. break;
  1302. }
  1303. if ( dwStatus == ERROR_MORE_DATA )
  1304. {
  1305. cchName++; // add one for NULL
  1306. ASSERT( cchName > cchBuffer );
  1307. cchBuffer = cchName;
  1308. // buffer was too small, reallocate
  1309. delete [] pwszName;
  1310. pwszName = new WCHAR[cchBuffer];
  1311. ASSERT( pwszName != NULL );
  1312. if ( pwszName == NULL )
  1313. {
  1314. AfxThrowMemoryException();
  1315. } // if: memory exception
  1316. continue;
  1317. }
  1318. if (dwStatus != ERROR_SUCCESS)
  1319. {
  1320. TraceError(_T("CClusterAdminApp::NotifyThreadProc() %s"), dwStatus);
  1321. continue;
  1322. } // if: error getting notification
  1323. try
  1324. {
  1325. pnotify = new CClusterNotify();
  1326. ASSERT(pnotify != NULL);
  1327. if (pnotify != NULL)
  1328. {
  1329. pnotify->m_dwNotifyKey = dwNotifyKey;
  1330. pnotify->m_dwFilterType = dwFilterType;
  1331. pnotify->m_strName = pwszName;
  1332. #ifdef _DEBUG
  1333. pszTracePrefix = _T("");
  1334. if ( (dwNotifyKey == NULL)
  1335. || (dwNotifyKey == 0xfeeefeee)
  1336. || (dwNotifyKey == 0xbaadf00d))
  1337. {
  1338. ptag = &g_tagError;
  1339. pszTracePrefix = _T("*** NOTIFY THREAD ");
  1340. } // if: bad notification key
  1341. else if (dwFilterType & (CLUSTER_CHANGE_REGISTRY_NAME | CLUSTER_CHANGE_REGISTRY_ATTRIBUTES | CLUSTER_CHANGE_REGISTRY_VALUE))
  1342. ptag = &g_tagNotifyThreadReg;
  1343. else
  1344. ptag = &g_tagNotifyThread;
  1345. Trace(*ptag, _T("%sNotification - key %08.8x, filter %x (%s), %s"), pszTracePrefix, dwNotifyKey, dwFilterType, PszNotificationName(dwFilterType), pnotify->m_strName);
  1346. #endif
  1347. if (!::PostMessage(
  1348. pnctx->m_hwndFrame,
  1349. WM_CAM_CLUSTER_NOTIFY,
  1350. NULL,
  1351. (LPARAM) pnotify
  1352. ))
  1353. delete pnotify;
  1354. } // if: allocated object successfully
  1355. } // try
  1356. catch (...)
  1357. {
  1358. if (pnotify != NULL)
  1359. {
  1360. delete pnotify;
  1361. pnotify = NULL;
  1362. } // if: notification record allocated
  1363. } // catch: any exception
  1364. } // forever
  1365. delete [] pwszName;
  1366. return 0;
  1367. } //*** CClusterAdminApp::NotifyThreadProc()
  1368. //*************************************************************************//
  1369. /////////////////////////////////////////////////////////////////////////////
  1370. // Global Functions
  1371. /////////////////////////////////////////////////////////////////////////////
  1372. /////////////////////////////////////////////////////////////////////////////
  1373. //++
  1374. //
  1375. // BCreateFont
  1376. //
  1377. // Routine Description:
  1378. // Create a font.
  1379. //
  1380. // Arguments:
  1381. // rfont [OUT] Font to create.
  1382. // nPoints [IN] Point size.
  1383. // bBold [IN] Flag specifying whether font is bold or not.
  1384. //
  1385. // Return Value:
  1386. // TRUE Font created successfully.
  1387. // FALSE Error creating font.
  1388. //
  1389. //--
  1390. /////////////////////////////////////////////////////////////////////////////
  1391. BOOL BCreateFont(OUT CFont & rfont, IN int nPoints, IN BOOL bBold)
  1392. {
  1393. return rfont.CreateFont(
  1394. -nPoints, // nHeight
  1395. 0, // nWidth
  1396. 0, // nEscapement
  1397. 0, // nOrientation
  1398. (bBold ? FW_BOLD : FW_DONTCARE), // nWeight
  1399. FALSE, // bItalic
  1400. FALSE, // bUnderline
  1401. FALSE, // cStrikeout
  1402. ANSI_CHARSET, // nCharSet
  1403. OUT_DEFAULT_PRECIS, // nOutPrecision
  1404. CLIP_DEFAULT_PRECIS, // nClipPrecision
  1405. DEFAULT_QUALITY, // nQuality
  1406. DEFAULT_PITCH | FF_DONTCARE, // nPitchAndFamily
  1407. _T("MS Shell Dlg") // lpszFaceName
  1408. );
  1409. } //*** BCreateFont()
  1410. /////////////////////////////////////////////////////////////////////////////
  1411. //++
  1412. //
  1413. // NewNodeWizard
  1414. //
  1415. // Routine Description:
  1416. // Invoke the Add Nodes to Cluster Wizard.
  1417. //
  1418. // Arguments:
  1419. // pcszName -- Name of cluster to add nodes to.
  1420. // fIgnoreErrors -- TRUE = don't display error messages.
  1421. // Defaults to FALSE.
  1422. //
  1423. // Return Value:
  1424. // None.
  1425. //
  1426. //--
  1427. /////////////////////////////////////////////////////////////////////////////
  1428. void NewNodeWizard(
  1429. LPCTSTR pcszName,
  1430. BOOL fIgnoreErrors // = FALSE
  1431. )
  1432. {
  1433. HRESULT hr;
  1434. IClusCfgWizard * pccwWiz;
  1435. BSTR bstrConnectName = NULL;
  1436. BOOL fCommitted = FALSE;
  1437. // Make sure the ClusCfg client has been loaded.
  1438. GetClusterAdminApp()->LoadClusCfgClient();
  1439. // Get an interface pointer for the wizard.
  1440. hr = CoCreateInstance(
  1441. CLSID_ClusCfgWizard,
  1442. NULL,
  1443. CLSCTX_INPROC_SERVER,
  1444. IID_IClusCfgWizard,
  1445. (void **) &pccwWiz
  1446. );
  1447. if ( FAILED( hr ) )
  1448. {
  1449. if ( ! fIgnoreErrors )
  1450. {
  1451. CNTException nte( hr, IDS_CREATE_CLUSCFGWIZ_OBJ_ERROR, NULL, NULL, FALSE /*bAutoDelete*/ );
  1452. nte.ReportError();
  1453. }
  1454. return;
  1455. } // if: error getting the interface pointer
  1456. // TODO: DavidP 24-AUG-2000
  1457. // Get the FQDN of the cluster name.
  1458. // Specify the name of the cluster we are going to add a node to.
  1459. bstrConnectName = SysAllocString( pcszName );
  1460. if ( bstrConnectName == NULL )
  1461. {
  1462. AfxThrowMemoryException();
  1463. }
  1464. hr = pccwWiz->put_ClusterName( bstrConnectName );
  1465. if ( FAILED( hr ) )
  1466. {
  1467. if ( ! fIgnoreErrors )
  1468. {
  1469. CNTException nte( hr, IDS_ADD_NODES_TO_CLUSTER_ERROR, bstrConnectName, NULL, FALSE /*bAutoDelete*/ );
  1470. nte.ReportError();
  1471. }
  1472. } // if: error setting the cluster name
  1473. // Display the wizard.
  1474. hr = pccwWiz->AddClusterNodes(
  1475. AfxGetMainWnd()->m_hWnd,
  1476. &fCommitted
  1477. );
  1478. if ( FAILED( hr ) )
  1479. {
  1480. if ( ! fIgnoreErrors )
  1481. {
  1482. CNTException nte( hr, IDS_ADD_NODES_TO_CLUSTER_ERROR, bstrConnectName, NULL, FALSE /*bAutoDelete*/ );
  1483. nte.ReportError();
  1484. }
  1485. } // if: error adding cluster nodes
  1486. SysFreeString( bstrConnectName );
  1487. pccwWiz->Release();
  1488. } //*** NewNodeWizard()