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.

750 lines
21 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. ServStat.cpp
  7. The server statistics dialog
  8. FILE HISTORY:
  9. */
  10. #include <afx.h>
  11. #include "dbgutil.h"
  12. #include "stdafx.h"
  13. #include "winssnap.h"
  14. #include "server.h"
  15. #include "resource.h"
  16. #include "svrstats.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. #define INTLTIMESTR(time) (((CIntlTime)(time)).CIntlTime::operator const CString())
  23. #define TMST1(x) INTLTIMESTR((m_wrResults).WinsStat.TimeStamps.x)
  24. #define INTLNUMSTR(num) (((CIntlNumber)(num)).CIntlNumber::operator const CString())
  25. #define TCTR(x) INTLNUMSTR((m_wrResults).WinsStat.Counters.x)
  26. #define STATMUTEXNAME _T("WINSADMNGETSTATISTICS")
  27. #define WM_UPDATE_STATS WM_USER + 1099
  28. enum
  29. {
  30. SERVER_STAT_START_TIME = 0,
  31. SERVER_STAT_DB_INIT_TIME,
  32. SERVER_STAT_STAT_CLEAR_TIME,
  33. SERVER_STAT_BLANK0,
  34. SERVER_STAT_LAST_PERIODIC_REP,
  35. SERVER_STAT_LAST_ADMIN_REP,
  36. SERVER_STAT_LAST_NET_UPDATE_REP,
  37. SERVER_STAT_LAST_ADDRESS_CHANGE_REP,
  38. SERVER_STAT_BLANK1,
  39. SERVER_STAT_TOTAL_QUERIES,
  40. SERVER_STAT_SUCCESSFUL_QUERRIES,
  41. SERVER_STAT_FAILED_QUERRIES,
  42. SERVER_STAT_BLANK2,
  43. SERVER_STAT_TOTAL_RELEASES,
  44. SERVER_STAT_SUCCESSFUL_RELEASES,
  45. SERVER_STAT_FAILED_RELEASES,
  46. SERVER_STAT_BLANK3,
  47. SERVER_STAT_UNIQUE_REGISTRATIONS,
  48. SERVER_STAT_UNIQUE_CONFLICTS,
  49. SERVER_STAT_UNIQUE_RENEWALS,
  50. SERVER_STAT_BLANK4,
  51. SERVER_STAT_GROUP_REGISTRATIONS,
  52. SERVER_STAT_GROUP_CONFLICTS,
  53. SERVER_STAT_GROUP_RENEWALS,
  54. SERVER_STAT_BLANK5,
  55. SERVER_STAT_TOTAL_REG,
  56. SERVER_STAT_BLANK6,
  57. SERVER_STAT_LAST_PERIODIC_SCAV,
  58. SERVER_STAT_LAST_ADMIN_SCAV,
  59. SERVER_STAT_LAST_EXTINCTION_SCAV,
  60. SERVER_STAT_LAST_VERIFICATION_SCAV,
  61. SERVER_STAT_BLANK7,
  62. SERVER_STAT_PARTNERS_HEADER,
  63. SERVER_STAT_MAX
  64. };
  65. /*---------------------------------------------------------------------------
  66. CServerStatsFrame implementation
  67. ---------------------------------------------------------------------------*/
  68. const ContainerColumnInfo s_rgServerStatsColumnInfo[] =
  69. {
  70. { IDS_SERVER_STATS_START_TIME, 0, TRUE },
  71. { IDS_SERVER_STATS_DB_INIT_TIME, 0, TRUE },
  72. { IDS_SERVER_STATS_LAST_CLEAR_TIME, 0, TRUE },
  73. { IDS_BLANK, 0, TRUE },
  74. { IDS_SERVER_STATS_LAST_PREP, 0, TRUE },
  75. { IDS_SERVER_STATS_LAST_AREP, 0, TRUE },
  76. { IDS_SERVER_STATS_LAST_NREP, 0, TRUE },
  77. { IDS_SERVER_STATS_LAST_ACREP, 0, TRUE },
  78. { IDS_BLANK, 0, TRUE },
  79. { IDS_SERVER_STATS_TOTAL_QUERRIES, 0, TRUE },
  80. { IDS_SERVER_STATS_SUCCESSFUL, 0, TRUE },
  81. { IDS_SERVER_STATS_FAILED, 0, TRUE },
  82. { IDS_BLANK, 0, TRUE },
  83. { IDS_SERVER_STATS_TOTAL_RELEASES, 0, TRUE },
  84. { IDS_SERVER_STATS_SUCCESSFUL, 0, TRUE },
  85. { IDS_SERVER_STATS_FAILED, 0, TRUE },
  86. { IDS_BLANK, 0, TRUE },
  87. { IDS_SERVER_STATS_UNIQUE_REGISTRATIONS, 0, TRUE },
  88. { IDS_SERVER_STATS_CONFLICTS, 0, TRUE },
  89. { IDS_SERVER_STATS_RENEWALS, 0, TRUE },
  90. { IDS_BLANK, 0, TRUE },
  91. { IDS_SERVER_STATS_GROUP_REGISTRATIONS, 0, TRUE },
  92. { IDS_SERVER_STATS_CONFLICTS, 0, TRUE },
  93. { IDS_SERVER_STATS_RENEWALS, 0, TRUE },
  94. { IDS_BLANK, 0, TRUE },
  95. { IDS_SERVER_STATS_TOTAL_REGISTRATIONS, 0, TRUE },
  96. { IDS_BLANK, 0, TRUE },
  97. { IDS_SERVER_STATS_LAST_PSCAV, 0, TRUE },
  98. { IDS_SERVER_STATS_LAST_ASCAV, 0, TRUE },
  99. { IDS_SERVER_STATS_LAST_ESCAV, 0, TRUE },
  100. { IDS_SERVER_STATS_LAST_VSCAV, 0, TRUE },
  101. { IDS_BLANK, 0, TRUE },
  102. { IDS_SERVER_STATS_PARTNERS_HEADER, 0, TRUE },
  103. };
  104. UINT _cdecl
  105. RefreshStatsThread(LPVOID pParam)
  106. {
  107. DWORD dw;
  108. ThreadInfo * pInfo = (ThreadInfo *)(pParam);
  109. HANDLE hmutStatistics = NULL;
  110. HRESULT hr = hrOK;
  111. COM_PROTECT_TRY
  112. {
  113. // Open the existing mutex
  114. while (hmutStatistics == NULL)
  115. {
  116. if ((hmutStatistics = ::OpenMutex(SYNCHRONIZE, FALSE, STATMUTEXNAME)) == NULL)
  117. {
  118. ::Sleep(2000L);
  119. }
  120. }
  121. // This is where the work gets done
  122. for (;;)
  123. {
  124. pInfo->dwInterval = pInfo->pDlg->GetRefreshInterval();
  125. //::Sleep((pInfo->dwInterval)*1000);
  126. if (::WaitForSingleObject(pInfo->pDlg->m_hAbortEvent, (pInfo->dwInterval) * 1000) == WAIT_OBJECT_0)
  127. {
  128. // we're going away, lets get outta here
  129. break;
  130. }
  131. // Wait until we get the go ahead
  132. dw = ::WaitForSingleObject(hmutStatistics, INFINITE);
  133. if (dw == WAIT_OBJECT_0)
  134. {
  135. dw = pInfo->pDlg->GetStats();
  136. if (dw == ERROR_SUCCESS)
  137. {
  138. PostMessage(pInfo->pDlg->GetSafeHwnd(), WM_UPDATE_STATS, 0, 0);
  139. }
  140. ::ReleaseMutex(hmutStatistics);
  141. }
  142. }
  143. delete pInfo;
  144. }
  145. COM_PROTECT_CATCH
  146. return 0;
  147. }
  148. /*---------------------------------------------------------------------------
  149. CServerStatsFrame::CServerStatsFrame()
  150. Constructor
  151. ---------------------------------------------------------------------------*/
  152. CServerStatsFrame::CServerStatsFrame()
  153. : StatsDialog(STATSDLG_VERTICAL|STATSDLG_CLEAR)
  154. {
  155. SetColumnInfo(s_rgServerStatsColumnInfo,
  156. DimensionOf(s_rgServerStatsColumnInfo));
  157. m_hmutStatistics = NULL;
  158. m_hAbortEvent = NULL;
  159. m_pRefreshThread = NULL;
  160. ZeroMemory(&m_wrResults, sizeof(m_wrResults));
  161. }
  162. /*---------------------------------------------------------------------------
  163. CServerStatsFrame::CServerStatsFrame()
  164. Destructor
  165. ---------------------------------------------------------------------------*/
  166. CServerStatsFrame::~CServerStatsFrame()
  167. {
  168. }
  169. BEGIN_MESSAGE_MAP(CServerStatsFrame, StatsDialog)
  170. //{{AFX_MSG_MAP(CServerStatistics)
  171. //}}AFX_MSG_MAP
  172. ON_MESSAGE(WM_NEW_STATS_AVAILABLE, OnNewStatsAvailable)
  173. ON_MESSAGE(WM_UPDATE_STATS, OnUpdateStats)
  174. ON_BN_CLICKED(IDC_STATSDLG_BTN_CLEAR, OnClear)
  175. ON_WM_DESTROY()
  176. END_MESSAGE_MAP()
  177. /*---------------------------------------------------------------------------
  178. CServerStatsFrame::CServerStatsFrame()
  179. Gets the statistics from the server handler and updates the
  180. internal variable m_wrResults
  181. ---------------------------------------------------------------------------*/
  182. HRESULT CServerStatsFrame::RefreshData(BOOL fGrabNewData)
  183. {
  184. if (fGrabNewData)
  185. {
  186. DWORD dwError = 0;
  187. BEGIN_WAIT_CURSOR;
  188. dwError = GetStats();
  189. END_WAIT_CURSOR;
  190. if (dwError != ERROR_SUCCESS)
  191. {
  192. WinsMessageBox(dwError);
  193. }
  194. else
  195. {
  196. UpdateWindow(&m_wrResults);
  197. }
  198. }
  199. return hrOK;
  200. }
  201. DWORD CServerStatsFrame::GetStats()
  202. {
  203. DWORD dwError = 0;
  204. SPITFSNode spNode;
  205. PWINSINTF_RESULTS_T pResults = NULL;
  206. CWinsServerHandler * pServer;
  207. pServer = GETHANDLER(CWinsServerHandler, m_spNode);
  208. dwError = pServer->GetStatistics(m_spNode, &pResults);
  209. if (dwError == ERROR_SUCCESS)
  210. {
  211. m_wrResults = *(pResults);
  212. }
  213. return dwError;
  214. }
  215. BOOL CServerStatsFrame::OnInitDialog()
  216. {
  217. CString st;
  218. BOOL bRet;
  219. AfxFormatString1(st, IDS_SERVER_STATS_TITLE, m_strServerAddress);
  220. SetWindowText((LPCTSTR) st);
  221. bRet = StatsDialog::OnInitDialog();
  222. // add the blank column because the replication partner stats need them
  223. m_listCtrl.InsertColumn(2, _T(" "), LVCFMT_LEFT, 100);
  224. // Set the default column widths to the width of the widest column
  225. SetColumnWidths(2 /* Number of Columns */);
  226. UpdateWindow(&m_wrResults);
  227. // set the default window size
  228. RECT rect;
  229. GetWindowRect(&rect);
  230. int nWidth = 0;
  231. for (int i = 0; i < 3; i++)
  232. {
  233. nWidth += m_listCtrl.GetColumnWidth(i);
  234. }
  235. SetWindowPos(NULL, rect.left, rect.top, nWidth + 20, SERVER_STATS_DEFAULT_HEIGHT, SWP_SHOWWINDOW);
  236. if ((m_hmutStatistics = ::CreateMutex(NULL, FALSE, STATMUTEXNAME)) == NULL)
  237. {
  238. Trace1("CServerStatsFrame::OnInitDialog() - CreateMutex failed! %lx\n", GetLastError());
  239. return FALSE;
  240. }
  241. if ((m_hAbortEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
  242. {
  243. Trace1("CServerStatsFrame::OnInitDialog() - CreateEvent failed! %lx\n", GetLastError());
  244. return FALSE;
  245. }
  246. StartRefresherThread();
  247. return bRet;
  248. }
  249. void CServerStatsFrame::Sort(UINT nColumnId)
  250. {
  251. // we don't sort any of our stats
  252. }
  253. /*---------------------------------------------------------------------------
  254. CServerStatsFrame::OnNewStatsAvailable(UINT wParam, LONG lParam)
  255. called in response to the message ON_NEW_STATS_AVAILABLE
  256. Author: EricDav
  257. ---------------------------------------------------------------------------*/
  258. afx_msg long
  259. CServerStatsFrame::OnNewStatsAvailable(UINT wParam, LONG lParam)
  260. {
  261. DWORD dwErr = GetStats();
  262. if (dwErr == ERROR_SUCCESS)
  263. {
  264. UpdateWindow(&m_wrResults);
  265. }
  266. else
  267. {
  268. WinsMessageBox(dwErr);
  269. }
  270. return 0;
  271. }
  272. /*---------------------------------------------------------------------------
  273. CServerStatsFrame::OnNewStatsAvailable(UINT wParam, LONG lParam)
  274. called in response to the message WM_UPDATE_STATS
  275. The background thread updates the stats, now we need to update
  276. the UI on the correct thread.
  277. Author: EricDav
  278. ---------------------------------------------------------------------------*/
  279. afx_msg long
  280. CServerStatsFrame::OnUpdateStats(UINT wParam, LONG lParam)
  281. {
  282. UpdateWindow(&m_wrResults);
  283. return 0;
  284. }
  285. /*---------------------------------------------------------------------------
  286. CServerStatsFrame::UpdateWindow(PWINSINTF_RESULTS_T pwrResults)
  287. Updates the contents of the dialog
  288. ---------------------------------------------------------------------------*/
  289. void
  290. CServerStatsFrame::UpdateWindow(PWINSINTF_RESULTS_T pwrResults)
  291. {
  292. SPITFSNode spNode;
  293. CWinsServerHandler * pServer;
  294. CString str;
  295. UINT i;
  296. int nTotalAddresses = 0, nTotalInUse = 0, nTotalAvailable = 0;
  297. // now fill in the data
  298. for (i = 0; i < SERVER_STAT_MAX; i++)
  299. {
  300. if (!pwrResults)
  301. str = _T("---");
  302. else
  303. {
  304. switch (i)
  305. {
  306. // server stsrt time
  307. case SERVER_STAT_START_TIME:
  308. {
  309. CTime timeStart(m_wrResults.WinsStat.TimeStamps.WinsStartTime);
  310. if(timeStart != 0)
  311. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.WinsStartTime);
  312. else
  313. str.LoadString(IDS_INVALID_TIME);
  314. }
  315. break;
  316. // database initialized time
  317. case SERVER_STAT_DB_INIT_TIME:
  318. {
  319. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastInitDbTime);
  320. if(timeStart != 0)
  321. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastInitDbTime);
  322. else
  323. str.LoadString(IDS_INVALID_TIME);
  324. }
  325. break;
  326. // statistics last cleared time
  327. case SERVER_STAT_STAT_CLEAR_TIME:
  328. {
  329. CTime timeStart(m_wrResults.WinsStat.TimeStamps.CounterResetTime);
  330. if(timeStart != 0)
  331. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.CounterResetTime);
  332. else
  333. str.LoadString(IDS_INVALID_TIME);
  334. }
  335. break;
  336. // some blank lines in between
  337. case SERVER_STAT_BLANK0:
  338. case SERVER_STAT_BLANK1:
  339. case SERVER_STAT_BLANK2:
  340. case SERVER_STAT_BLANK3:
  341. case SERVER_STAT_BLANK4:
  342. case SERVER_STAT_BLANK5:
  343. case SERVER_STAT_BLANK6:
  344. case SERVER_STAT_BLANK7:
  345. str = _T("");
  346. break;
  347. case SERVER_STAT_LAST_PERIODIC_REP:
  348. {
  349. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastPRplTime);
  350. if(timeStart != 0)
  351. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastPRplTime);
  352. else
  353. str.LoadString(IDS_INVALID_TIME);
  354. }
  355. break;
  356. case SERVER_STAT_LAST_ADMIN_REP:
  357. {
  358. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastATRplTime);
  359. if(timeStart != 0)
  360. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastATRplTime);
  361. else
  362. str.LoadString(IDS_INVALID_TIME);
  363. }
  364. break;
  365. case SERVER_STAT_LAST_NET_UPDATE_REP:
  366. {
  367. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastNTRplTime);
  368. if(timeStart != 0)
  369. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastNTRplTime);
  370. else
  371. str.LoadString(IDS_INVALID_TIME);
  372. }
  373. break;
  374. // last address changed time
  375. case SERVER_STAT_LAST_ADDRESS_CHANGE_REP:
  376. {
  377. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastACTRplTime);
  378. if(timeStart != 0)
  379. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastACTRplTime);
  380. else
  381. str.LoadString(IDS_INVALID_TIME);
  382. }
  383. break;
  384. // total queries received
  385. case SERVER_STAT_TOTAL_QUERIES:
  386. str = TCTR(NoOfQueries);
  387. break;
  388. // successful queries
  389. case SERVER_STAT_SUCCESSFUL_QUERRIES:
  390. str = TCTR(NoOfSuccQueries);
  391. break;
  392. // Queries that failed
  393. case SERVER_STAT_FAILED_QUERRIES:
  394. str = TCTR(NoOfFailQueries);
  395. break;
  396. case SERVER_STAT_TOTAL_RELEASES:
  397. str = TCTR(NoOfRel);
  398. break;
  399. case SERVER_STAT_SUCCESSFUL_RELEASES:
  400. str = TCTR(NoOfSuccRel);
  401. break;
  402. case SERVER_STAT_FAILED_RELEASES:
  403. str = TCTR(NoOfFailRel);
  404. break;
  405. // unique registrations
  406. case SERVER_STAT_UNIQUE_REGISTRATIONS:
  407. str = TCTR(NoOfUniqueReg);
  408. break;
  409. case SERVER_STAT_UNIQUE_CONFLICTS:
  410. str = TCTR(NoOfUniqueCnf);
  411. break;
  412. case SERVER_STAT_UNIQUE_RENEWALS:
  413. str = TCTR(NoOfUniqueRef);
  414. break;
  415. // group registrations
  416. case SERVER_STAT_GROUP_REGISTRATIONS:
  417. str = TCTR(NoOfGroupReg);
  418. break;
  419. case SERVER_STAT_GROUP_CONFLICTS:
  420. str = TCTR(NoOfGroupCnf);
  421. break;
  422. case SERVER_STAT_GROUP_RENEWALS:
  423. str = TCTR(NoOfGroupRef);
  424. break;
  425. // total registrations
  426. case SERVER_STAT_TOTAL_REG:
  427. str = INTLNUMSTR(m_wrResults.WinsStat.Counters.NoOfGroupReg +
  428. m_wrResults.WinsStat.Counters.NoOfUniqueReg);
  429. break;
  430. case SERVER_STAT_LAST_PERIODIC_SCAV:
  431. {
  432. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastPScvTime);
  433. if(timeStart != 0)
  434. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastPScvTime);
  435. else
  436. str.LoadString(IDS_INVALID_TIME);
  437. }
  438. break;
  439. case SERVER_STAT_LAST_ADMIN_SCAV:
  440. {
  441. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastATScvTime);
  442. if(timeStart != 0)
  443. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastATScvTime);
  444. else
  445. str.LoadString(IDS_INVALID_TIME);
  446. }
  447. break;
  448. case SERVER_STAT_LAST_EXTINCTION_SCAV:
  449. {
  450. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastTombScvTime);
  451. if(timeStart != 0)
  452. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastTombScvTime);
  453. else
  454. str.LoadString(IDS_INVALID_TIME);
  455. }
  456. break;
  457. case SERVER_STAT_LAST_VERIFICATION_SCAV:
  458. {
  459. CTime timeStart(m_wrResults.WinsStat.TimeStamps.LastVerifyScvTime);
  460. if(timeStart != 0)
  461. FormatDateTime(str, &m_wrResults.WinsStat.TimeStamps.LastVerifyScvTime);
  462. else
  463. str.LoadString(IDS_INVALID_TIME);
  464. }
  465. break;
  466. case SERVER_STAT_PARTNERS_HEADER:
  467. {
  468. str.LoadString(IDS_SERVER_STATS_NO_OF_FAILED);
  469. m_listCtrl.SetItemText(i, 2, (LPCTSTR) str);
  470. str.LoadString(IDS_SERVER_STATS_NO_OF_REPLS);
  471. }
  472. break;
  473. default:
  474. Assert("Invalid server statistic type!");
  475. break;
  476. }
  477. }
  478. // now the string is set, display in the dlg
  479. m_listCtrl.SetItemText(i, 1, (LPCTSTR) str);
  480. }
  481. UpdatePartnerStats();
  482. }
  483. /*---------------------------------------------------------------------------
  484. CServerStatsFrame::StartRefresherThread()
  485. Starts the refresher thread, called as soon as the dilog is
  486. brought up
  487. ---------------------------------------------------------------------------*/
  488. void
  489. CServerStatsFrame::StartRefresherThread()
  490. {
  491. ThreadInfo *info = new ThreadInfo;
  492. CWinsServerHandler * pServer;
  493. pServer = GETHANDLER(CWinsServerHandler, m_spNode);
  494. info->dwInterval = pServer->m_dwRefreshInterval;
  495. info->pDlg = this;
  496. m_pRefreshThread = ::AfxBeginThread(RefreshStatsThread, info);
  497. if (m_pRefreshThread == NULL)
  498. {
  499. Trace0("Failed to create thread\n");
  500. m_pRefreshThread = NULL;
  501. return;
  502. }
  503. Trace0("Auto refresh thread succesfully started\n");
  504. }
  505. /*---------------------------------------------------------------------------
  506. CServerStatsFrame::ReInitRefresherThread()
  507. If the refresher thread was running, re-start it. It is needed
  508. in order to pick on the fly the new refresh intervals
  509. ---------------------------------------------------------------------------*/
  510. void
  511. CServerStatsFrame::ReInitRefresherThread()
  512. {
  513. // if there is a refresher thread, just restart it
  514. if (m_pRefreshThread != NULL)
  515. {
  516. KillRefresherThread();
  517. StartRefresherThread();
  518. }
  519. }
  520. /*---------------------------------------------------------------------------
  521. CServerStatsFrame::KillRefresherThread()
  522. Kills the refresh data thread, caled when the dlg is destroyed
  523. ---------------------------------------------------------------------------*/
  524. void
  525. CServerStatsFrame::KillRefresherThread()
  526. {
  527. //
  528. // Kill refresher thread if necessary.
  529. //
  530. if (m_pRefreshThread == NULL)
  531. {
  532. //
  533. // No thread running
  534. //
  535. return;
  536. }
  537. //::TerminateThread(m_pRefreshThread->m_hThread, 0);
  538. //::CloseHandle(m_pRefreshThread->m_hThread);
  539. ::SetEvent(m_hAbortEvent);
  540. ::WaitForSingleObject(m_pRefreshThread->m_hThread, 5000);
  541. m_pRefreshThread = NULL;
  542. }
  543. /*---------------------------------------------------------------------------
  544. CServerStatsFrame::OnDestroy( )
  545. Message Handler
  546. ---------------------------------------------------------------------------*/
  547. void
  548. CServerStatsFrame::OnDestroy( )
  549. {
  550. KillRefresherThread();
  551. if (m_hmutStatistics)
  552. {
  553. ::CloseHandle(m_hmutStatistics);
  554. m_hmutStatistics = NULL;
  555. }
  556. if (m_hAbortEvent)
  557. {
  558. ::CloseHandle(m_hAbortEvent);
  559. m_hAbortEvent = NULL;
  560. }
  561. }
  562. /*---------------------------------------------------------------------------
  563. CServerStatsFrame::GetRefreshInterval()
  564. Returns the refresh interval, stored in the server handler
  565. ---------------------------------------------------------------------------*/
  566. DWORD
  567. CServerStatsFrame::GetRefreshInterval()
  568. {
  569. CWinsServerHandler * pServer;
  570. pServer = GETHANDLER(CWinsServerHandler, m_spNode);
  571. return pServer->m_dwRefreshInterval;
  572. }
  573. /*---------------------------------------------------------------------------
  574. CServerStatsFrame::OnClear()
  575. Calls the wins api to reset counters and updates data, in response to
  576. click of the clear button
  577. ---------------------------------------------------------------------------*/
  578. void
  579. CServerStatsFrame::OnClear()
  580. {
  581. DWORD dwErr = ERROR_SUCCESS;
  582. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, m_spNode);
  583. // clear the ststistics
  584. BEGIN_WAIT_CURSOR
  585. dwErr = pServer->ClearStatistics(m_spNode);
  586. END_WAIT_CURSOR
  587. if (dwErr == ERROR_SUCCESS)
  588. {
  589. // refresh the data now
  590. RefreshData(TRUE);
  591. UpdateWindow(&m_wrResults);
  592. }
  593. else
  594. {
  595. WinsMessageBox(dwErr);
  596. }
  597. }
  598. /*---------------------------------------------------------------------------
  599. CServerStatsFrame::UpdatePartnerStats()
  600. ---------------------------------------------------------------------------*/
  601. void
  602. CServerStatsFrame::UpdatePartnerStats()
  603. {
  604. UINT i, uCount;
  605. CString strText;
  606. // first remove all old partner info
  607. uCount = m_listCtrl.GetItemCount();
  608. for (i = 0; i < (uCount - SERVER_STAT_MAX); i++)
  609. {
  610. m_listCtrl.DeleteItem(SERVER_STAT_MAX);
  611. }
  612. int nPartner = 0;
  613. // now add all of the partner information in
  614. for (i = SERVER_STAT_MAX; i < SERVER_STAT_MAX + m_wrResults.WinsStat.NoOfPnrs; i++)
  615. {
  616. m_listCtrl.InsertItem(i, _T(""));
  617. // ip address
  618. ::MakeIPAddress(m_wrResults.WinsStat.pRplPnrs[nPartner].Add.IPAdd, strText);
  619. m_listCtrl.SetItemText(i, 0, strText);
  620. // replication count
  621. strText.Format(_T("%d"), m_wrResults.WinsStat.pRplPnrs[nPartner].NoOfRpls);
  622. m_listCtrl.SetItemText(i, 1, strText);
  623. // failed count
  624. strText.Format(_T("%d"), m_wrResults.WinsStat.pRplPnrs[nPartner].NoOfCommFails);
  625. m_listCtrl.SetItemText(i, 2, strText);
  626. nPartner++;
  627. }
  628. }