Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1436 lines
41 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. ipxstats.cpp
  7. IPX Statistics implementation.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "rtrutil.h" // smart MPR handle pointers
  12. #include "format.h" // FormatNumber function
  13. #include "column.h" // containercolumninfo
  14. #include "ipxconn.h" // IPXConnection
  15. #include "ipxutil.h"
  16. #include "rtrlib.h" // DWORD_CMP
  17. #include "ipxrtdef.h"
  18. #include "routprot.h"
  19. #include "stm.h" // for IPX_SERVICE
  20. #include "listctrl.h"
  21. #include "statsdlg.h"
  22. #include "ipxstats.h"
  23. #include "resource.h"
  24. /*---------------------------------------------------------------------------
  25. IPXStatisticsDialog implementation
  26. ---------------------------------------------------------------------------*/
  27. BOOL IPXStatisticsDialog::OnInitDialog()
  28. {
  29. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  30. CString stType;
  31. CString stHost;
  32. GetWindowText(stType);
  33. stHost.Format((LPCTSTR) stType,
  34. m_pIPXConn->GetMachineName());
  35. SetWindowText(stHost);
  36. return StatsDialog::OnInitDialog();
  37. }
  38. /*!--------------------------------------------------------------------------
  39. IPXStatisticsDialog::PostNcDestroy
  40. -
  41. Author: KennT
  42. ---------------------------------------------------------------------------*/
  43. void IPXStatisticsDialog::PostNcDestroy()
  44. {
  45. StatsDialog::PostNcDestroy();
  46. m_dwSortSubitem = 0xFFFFFFFF;
  47. }
  48. /*!--------------------------------------------------------------------------
  49. IPXStatisticsDialog::Sort
  50. -
  51. Author: KennT
  52. ---------------------------------------------------------------------------*/
  53. void IPXStatisticsDialog::Sort(UINT nColumnId)
  54. {
  55. DWORD dwSubitemId;
  56. if (m_pConfig)
  57. dwSubitemId = m_pConfig->MapColumnToSubitem(m_ulId, nColumnId);
  58. else
  59. dwSubitemId = m_viewInfo.MapColumnToSubitem(nColumnId);
  60. if (m_dwSortSubitem != -1)
  61. {
  62. if (dwSubitemId == m_dwSortSubitem)
  63. m_fSortDirection = !m_fSortDirection;
  64. else
  65. m_fSortDirection = 0;
  66. }
  67. if (m_fSortDirection && GetInverseSortFunction())
  68. m_listCtrl.SortItems(GetInverseSortFunction(), dwSubitemId);
  69. else if (GetSortFunction())
  70. m_listCtrl.SortItems(GetSortFunction(), dwSubitemId);
  71. m_dwSortSubitem = dwSubitemId;
  72. }
  73. /*!--------------------------------------------------------------------------
  74. IPXStatisticsDialog::SetConnectionData
  75. -
  76. Author: KennT
  77. ---------------------------------------------------------------------------*/
  78. void IPXStatisticsDialog::SetConnectionData(IPXConnection *pIPXConn)
  79. {
  80. if (m_pIPXConn)
  81. m_pIPXConn->Release();
  82. m_pIPXConn = pIPXConn;
  83. if (pIPXConn)
  84. pIPXConn->AddRef();
  85. }
  86. /*!--------------------------------------------------------------------------
  87. IPXStatisticsDialog::GetSortFunction
  88. -
  89. Author: KennT
  90. ---------------------------------------------------------------------------*/
  91. PFNLVCOMPARE IPXStatisticsDialog::GetSortFunction()
  92. {
  93. return NULL;
  94. }
  95. /*!--------------------------------------------------------------------------
  96. IPXStatisticsDialog::GetInverseSortFunction
  97. -
  98. Author: KennT
  99. ---------------------------------------------------------------------------*/
  100. PFNLVCOMPARE IPXStatisticsDialog::GetInverseSortFunction()
  101. {
  102. return NULL;
  103. }
  104. //
  105. // This list MUST be kept in sync with the enum above.
  106. //
  107. extern const ContainerColumnInfo s_rgIpxStatsColumnInfo[];
  108. const ContainerColumnInfo s_rgIpxStatsColumnInfo[] =
  109. {
  110. { IDS_STATS_IPX_STATE, 0, TRUE, COL_STATUS },
  111. { IDS_STATS_IPX_NETWORK, 0, TRUE, COL_IPXNET },
  112. { IDS_STATS_IPX_NODE, 0, TRUE, COL_STRING },
  113. { IDS_STATS_IPX_INTERFACE_COUNT, 0, TRUE, COL_LARGE_NUM },
  114. { IDS_STATS_IPX_ROUTE_COUNT, 0, TRUE, COL_LARGE_NUM },
  115. { IDS_STATS_IPX_SERVICE_COUNT, 0, TRUE, COL_LARGE_NUM },
  116. { IDS_STATS_IPX_PACKETS_SENT, 0, TRUE, COL_LARGE_NUM },
  117. { IDS_STATS_IPX_PACKETS_RCVD, 0, TRUE, COL_LARGE_NUM },
  118. { IDS_STATS_IPX_PACKETS_FRWD, 0, TRUE, COL_LARGE_NUM },
  119. };
  120. DEBUG_DECLARE_INSTANCE_COUNTER(IpxInfoStatistics);
  121. /*!--------------------------------------------------------------------------
  122. IpxInfoStatistics::IpxInfoStatistics
  123. -
  124. Author: KennT
  125. ---------------------------------------------------------------------------*/
  126. IpxInfoStatistics::IpxInfoStatistics()
  127. : IPXStatisticsDialog(/*STATSDLG_FULLWINDOW | */
  128. STATSDLG_CONTEXTMENU |
  129. STATSDLG_SELECT_COLUMNS |
  130. STATSDLG_VERTICAL)
  131. {
  132. SetColumnInfo(s_rgIpxStatsColumnInfo,
  133. DimensionOf(s_rgIpxStatsColumnInfo));
  134. DEBUG_INCREMENT_INSTANCE_COUNTER(IpxInfoStatistics);
  135. }
  136. /*!--------------------------------------------------------------------------
  137. IpxInfoStatistics::~IpxInfoStatistics
  138. -
  139. Author: KennT
  140. ---------------------------------------------------------------------------*/
  141. IpxInfoStatistics::~IpxInfoStatistics()
  142. {
  143. SetConnectionData(NULL);
  144. DEBUG_DECREMENT_INSTANCE_COUNTER(IpxInfoStatistics);
  145. }
  146. /*!--------------------------------------------------------------------------
  147. IpxInfoStatistics::RefreshData
  148. -
  149. Author: KennT
  150. ---------------------------------------------------------------------------*/
  151. struct SIpxInfoData
  152. {
  153. IPXMIB_BASE m_mibBase;
  154. DWORD m_cForwarded;
  155. DWORD m_cReceived;
  156. DWORD m_cSent;
  157. };
  158. HRESULT IpxInfoStatistics::RefreshData(BOOL fGrabNewData)
  159. {
  160. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  161. int i;
  162. int iPos;
  163. DWORD dwValue;
  164. CString st;
  165. TCHAR szNumber[32];
  166. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  167. PIPXMIB_BASE pIpxMib = NULL;
  168. DWORD cbIpxMib;
  169. DWORD dwErr;
  170. SIpxInfoData ipxInfo;
  171. SPMprMibBuffer spMib;
  172. PIPX_INTERFACE pIpxIf = NULL;
  173. DWORD cbIpxIf;
  174. HRESULT hr = hrOK;
  175. MibGetInputData.TableId = IPX_BASE_ENTRY;
  176. dwErr = ::MprAdminMIBEntryGet(m_pIPXConn->GetMibHandle(),
  177. PID_IPX,
  178. IPX_PROTOCOL_BASE,
  179. &MibGetInputData,
  180. sizeof(MibGetInputData),
  181. (LPVOID *) &pIpxMib,
  182. &cbIpxMib);
  183. hr = HRESULT_FROM_WIN32(dwErr);
  184. if (FHrSucceeded(hr))
  185. {
  186. spMib = (PBYTE) pIpxMib;
  187. ipxInfo.m_mibBase = *pIpxMib;
  188. // Now loop over the interfaces to grab the aggregate data
  189. ipxInfo.m_cForwarded = 0;
  190. ipxInfo.m_cSent = 0;
  191. ipxInfo.m_cReceived = 0;
  192. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  193. dwErr = ::MprAdminMIBEntryGetFirst(m_pIPXConn->GetMibHandle(),
  194. PID_IPX,
  195. IPX_PROTOCOL_BASE,
  196. &MibGetInputData,
  197. sizeof(MibGetInputData),
  198. (LPVOID *) &pIpxIf,
  199. &cbIpxIf);
  200. hr = HRESULT_FROM_WIN32(dwErr);
  201. spMib.Free();
  202. spMib = (PBYTE) pIpxIf;
  203. while (FHrSucceeded(hr))
  204. {
  205. if (pIpxIf->InterfaceIndex == 0)
  206. ipxInfo.m_cForwarded -= pIpxIf->IfStats.InDelivers;
  207. else
  208. {
  209. ipxInfo.m_cReceived += pIpxIf->IfStats.InDelivers;
  210. ipxInfo.m_cForwarded += pIpxIf->IfStats.OutDelivers;
  211. ipxInfo.m_cSent += pIpxIf->IfStats.OutDelivers;
  212. }
  213. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  214. pIpxIf->InterfaceIndex;
  215. spMib.Free();
  216. pIpxIf = NULL;
  217. dwErr = ::MprAdminMIBEntryGetNext(m_pIPXConn->GetMibHandle(),
  218. PID_IPX,
  219. IPX_PROTOCOL_BASE,
  220. &MibGetInputData,
  221. sizeof(MibGetInputData),
  222. (LPVOID *) &pIpxIf,
  223. &cbIpxIf);
  224. spMib = (PBYTE) pIpxIf;
  225. hr = HRESULT_FROM_WIN32(dwErr);
  226. }
  227. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  228. hr = hrOK;
  229. }
  230. for (i=0; i<MVR_IPX_COUNT; i++)
  231. {
  232. if (IsSubitemVisible(i))
  233. {
  234. if (!FHrSucceeded(hr))
  235. st.LoadString(IDS_STATS_NA);
  236. else
  237. {
  238. st.Empty();
  239. dwValue = 0;
  240. switch (i)
  241. {
  242. case MVR_IPX_STATE:
  243. st = IpxOperStateToCString(
  244. ipxInfo.m_mibBase.OperState);
  245. break;
  246. case MVR_IPX_NETWORK:
  247. FormatIpxNetworkNumber(szNumber,
  248. DimensionOf(szNumber),
  249. ipxInfo.m_mibBase.PrimaryNetNumber,
  250. DimensionOf(ipxInfo.m_mibBase.PrimaryNetNumber));
  251. st = szNumber;
  252. break;
  253. case MVR_IPX_NODE:
  254. FormatMACAddress(szNumber,
  255. DimensionOf(szNumber),
  256. ipxInfo.m_mibBase.Node,
  257. DimensionOf(ipxInfo.m_mibBase.Node));
  258. st = szNumber;
  259. break;
  260. case MVR_IPX_INTERFACE_COUNT:
  261. dwValue = ipxInfo.m_mibBase.IfCount;
  262. break;
  263. case MVR_IPX_ROUTE_COUNT:
  264. dwValue = ipxInfo.m_mibBase.DestCount;
  265. break;
  266. case MVR_IPX_SERVICE_COUNT:
  267. dwValue = ipxInfo.m_mibBase.ServCount;
  268. break;
  269. case MVR_IPX_PACKETS_SENT:
  270. dwValue = ipxInfo.m_cSent;
  271. break;
  272. case MVR_IPX_PACKETS_RCVD:
  273. dwValue = ipxInfo.m_cReceived;
  274. break;
  275. case MVR_IPX_PACKETS_FRWD:
  276. dwValue = ipxInfo.m_cForwarded;
  277. break;
  278. default:
  279. Panic1("Unknown IPX statistic id : %d", i);
  280. st.LoadString(IDS_STATS_NA);
  281. break;
  282. }
  283. if (st.IsEmpty())
  284. {
  285. FormatNumber(dwValue, szNumber, DimensionOf(szNumber),
  286. FALSE);
  287. st = szNumber;
  288. }
  289. }
  290. iPos = MapSubitemToColumn(i);
  291. m_listCtrl.SetItemText(iPos, 1, (LPCTSTR) st);
  292. }
  293. }
  294. return hr;
  295. }
  296. /*!--------------------------------------------------------------------------
  297. IpxInfoStatistics::OnInitDialog
  298. -
  299. Author: KennT
  300. ---------------------------------------------------------------------------*/
  301. BOOL IpxInfoStatistics::OnInitDialog()
  302. {
  303. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  304. CString st;
  305. st.LoadString(IDS_STATS_IPX_INFO_TITLE);
  306. SetWindowText((LPCTSTR) st);
  307. return IPXStatisticsDialog::OnInitDialog();
  308. }
  309. /*!--------------------------------------------------------------------------
  310. IpxInfoStatistics::Sort
  311. -
  312. Author: KennT
  313. ---------------------------------------------------------------------------*/
  314. void IpxInfoStatistics::Sort(UINT nColumnId)
  315. {
  316. // Don't do anything, the statistics are displayed in a
  317. // vertical format
  318. }
  319. /*---------------------------------------------------------------------------
  320. IpxRoutingStatistics implementation
  321. ---------------------------------------------------------------------------*/
  322. extern const ContainerColumnInfo s_rgIpxRoutingStatsColumnInfo[];
  323. const ContainerColumnInfo s_rgIpxRoutingStatsColumnInfo[] =
  324. {
  325. { IDS_STATS_IPXROUTING_NETWORK, 0, TRUE, COL_IPXNET },
  326. { IDS_STATS_IPXROUTING_NEXT_HOP_MAC, 0, TRUE, COL_IPXNET },
  327. { IDS_STATS_IPXROUTING_TICK_COUNT, 0, TRUE, COL_LARGE_NUM },
  328. { IDS_STATS_IPXROUTING_HOP_COUNT, 0, TRUE, COL_SMALL_NUM },
  329. { IDS_STATS_IPXROUTING_IF_NAME, 0, TRUE, COL_IF_NAME },
  330. { IDS_STATS_IPXROUTING_PROTOCOL, 0, TRUE, COL_STRING },
  331. { IDS_STATS_IPXROUTING_ROUTE_NOTES, 0, TRUE, COL_STRING },
  332. };
  333. BEGIN_MESSAGE_MAP(IpxRoutingStatistics, IPXStatisticsDialog)
  334. ON_NOTIFY(LVN_GETDISPINFO, IDC_STATSDLG_LIST, OnNotifyGetDispInfo)
  335. END_MESSAGE_MAP()
  336. /*!--------------------------------------------------------------------------
  337. IpxRoutingStatistics::IpxRoutingStatistics
  338. -
  339. Author: KennT
  340. ---------------------------------------------------------------------------*/
  341. IpxRoutingStatistics::IpxRoutingStatistics()
  342. : IPXStatisticsDialog(/* STATSDLG_FULLWINDOW |*/
  343. STATSDLG_CONTEXTMENU |
  344. STATSDLG_SELECT_COLUMNS),
  345. m_dwSortSubitem(0xFFFFFFFF)
  346. {
  347. m_ColWidthMultiple = 1;
  348. m_ColWidthAdder = 15;
  349. SetColumnInfo(s_rgIpxRoutingStatsColumnInfo, DimensionOf(s_rgIpxRoutingStatsColumnInfo));
  350. if (m_pConfig)
  351. {
  352. ULONG cColumns = m_pConfig->GetColumnCount(m_ulId);
  353. ColumnData *pColumnData = (ColumnData *) alloca(sizeof(ColumnData) * cColumns);
  354. m_pConfig->GetColumnData(m_ulId, cColumns, pColumnData);
  355. pColumnData[3].fmt = LVCFMT_RIGHT;
  356. pColumnData[4].fmt = LVCFMT_RIGHT;
  357. m_pConfig->SetColumnData(m_ulId, cColumns, pColumnData);
  358. }
  359. else
  360. {
  361. ULONG cColumns = m_viewInfo.GetColumnCount();
  362. ColumnData *pColumnData = (ColumnData *) alloca(sizeof(ColumnData) * cColumns);
  363. m_viewInfo.GetColumnData(cColumns, pColumnData);
  364. pColumnData[3].fmt = LVCFMT_RIGHT;
  365. pColumnData[4].fmt = LVCFMT_RIGHT;
  366. m_viewInfo.SetColumnData(cColumns, pColumnData);
  367. }
  368. }
  369. /*!--------------------------------------------------------------------------
  370. IpxRoutingStatistics::~IpxRoutingStatistics
  371. -
  372. Author: KennT
  373. ---------------------------------------------------------------------------*/
  374. IpxRoutingStatistics::~IpxRoutingStatistics()
  375. {
  376. SetConnectionData(NULL);
  377. }
  378. /*!--------------------------------------------------------------------------
  379. IpxRoutingStatistics::SetRouterInfo
  380. -
  381. Author: KennT
  382. ---------------------------------------------------------------------------*/
  383. void IpxRoutingStatistics::SetRouterInfo(IRouterInfo *pRouterInfo)
  384. {
  385. m_spRouterInfo.Set(pRouterInfo);
  386. }
  387. /*!--------------------------------------------------------------------------
  388. IpxRoutingStatistics::RefreshData
  389. -
  390. Author: KennT
  391. ---------------------------------------------------------------------------*/
  392. HRESULT IpxRoutingStatistics::RefreshData(BOOL fGrabNewData)
  393. {
  394. HRESULT hr = hrOK;
  395. int i, cItems;
  396. FixColumnAlignment();
  397. CORg( GetIpxRoutingData() );
  398. // Prepare the list control for the large amount of entries
  399. if (m_listCtrl.GetItemCount() < m_Items.GetSize())
  400. m_listCtrl.SetItemCount((int) m_Items.GetSize());
  401. // Iterate through the array adding the data to the list control
  402. cItems = (int) m_Items.GetSize();
  403. for (i=0; i<cItems; i++)
  404. {
  405. // Add the items as callback items
  406. m_listCtrl.InsertItem(LVIF_TEXT | LVIF_PARAM, i, LPSTR_TEXTCALLBACK,
  407. 0, 0, 0, (LPARAM) i);
  408. }
  409. Error:
  410. return hrOK;
  411. }
  412. /*!--------------------------------------------------------------------------
  413. IpxRoutingStatistics::GetIpxRoutingData
  414. Grabs the IPX routing table and fills in the m_Items array with
  415. that data.
  416. Author: KennT
  417. ---------------------------------------------------------------------------*/
  418. HRESULT IpxRoutingStatistics::GetIpxRoutingData()
  419. {
  420. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  421. PIPXMIB_BASE pIpxMib = NULL;
  422. DWORD cbIpxMib;
  423. DWORD dwErr;
  424. HRESULT hr = hrOK;
  425. SPMprMibBuffer spMib;
  426. PIPX_ROUTE pRoute = NULL;
  427. SPMprMibBuffer spMibRoute;
  428. DWORD cbRoute;
  429. int cEntries = 0;
  430. // Load up on the interface titles
  431. CORg( FillInterfaceTable() );
  432. MibGetInputData.TableId = IPX_BASE_ENTRY;
  433. CWRg( ::MprAdminMIBEntryGet(m_pIPXConn->GetMibHandle(),
  434. PID_IPX,
  435. IPX_PROTOCOL_BASE,
  436. &MibGetInputData,
  437. sizeof(MibGetInputData),
  438. (LPVOID *) &pIpxMib,
  439. &cbIpxMib) );
  440. if(pIpxMib == NULL)
  441. {
  442. hr = E_FAIL;
  443. goto Error;
  444. }
  445. spMib = (PBYTE) pIpxMib;
  446. // Prepare the data array for the number of items (+ some buffer)
  447. m_Items.SetSize( pIpxMib->DestCount + 100);
  448. MibGetInputData.TableId = IPX_DEST_TABLE;
  449. dwErr = ::MprAdminMIBEntryGetFirst(m_pIPXConn->GetMibHandle(),
  450. PID_IPX,
  451. IPX_PROTOCOL_BASE,
  452. &MibGetInputData,
  453. sizeof(MibGetInputData),
  454. (LPVOID *) &pRoute,
  455. &cbRoute);
  456. hr = HRESULT_FROM_WIN32(dwErr);
  457. spMibRoute = (PBYTE) pRoute;
  458. cEntries = 0;
  459. while (FHrSucceeded(hr))
  460. {
  461. Assert(pRoute);
  462. // Add this data at position cEntries
  463. m_Items.SetAtGrow(cEntries, *pRoute);
  464. cEntries++;
  465. // Get the next set of data
  466. MibGetInputData.TableId = IPX_DEST_TABLE;
  467. memcpy(MibGetInputData.MibIndex.RoutingTableIndex.Network,
  468. pRoute->Network,
  469. sizeof(MibGetInputData.MibIndex.RoutingTableIndex.Network));
  470. pRoute = NULL;
  471. spMibRoute.Free();
  472. dwErr = ::MprAdminMIBEntryGetNext(m_pIPXConn->GetMibHandle(),
  473. PID_IPX,
  474. IPX_PROTOCOL_BASE,
  475. &MibGetInputData,
  476. sizeof(MibGetInputData),
  477. (LPVOID *) &pRoute,
  478. &cbRoute);
  479. hr = HRESULT_FROM_WIN32(dwErr);
  480. spMibRoute = (PBYTE) pRoute;
  481. }
  482. // Do this to make sure that we don't have bogus entries at the top
  483. // of the array and that we can use the GetSize() to get an accurate
  484. // count of the number of items.
  485. m_Items.SetSize(cEntries);
  486. Error:
  487. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  488. hr = hrOK;
  489. return hr;
  490. }
  491. /*!--------------------------------------------------------------------------
  492. IpxRoutingStatistics::FillInterfaceTable
  493. Fills m_rgIfTitle with the interface titles.
  494. Author: KennT
  495. ---------------------------------------------------------------------------*/
  496. HRESULT IpxRoutingStatistics::FillInterfaceTable()
  497. {
  498. HRESULT hr = hrOK;
  499. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  500. PIPX_INTERFACE pIpxIf = NULL;
  501. DWORD cbIfTable;
  502. SPIInterfaceInfo spIf;
  503. SPIEnumInterfaceInfo spEnumIf;
  504. LPCOLESTR poszIfName;
  505. SPMprMibBuffer spMib;
  506. DWORD dwErr;
  507. USES_CONVERSION;
  508. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  509. CWRg( ::MprAdminMIBEntryGetFirst(m_pIPXConn->GetMibHandle(),
  510. PID_IPX,
  511. IPX_PROTOCOL_BASE,
  512. &MibGetInputData,
  513. sizeof(MibGetInputData),
  514. (LPVOID *) &pIpxIf,
  515. &cbIfTable));
  516. spMib = (PBYTE) pIpxIf;
  517. m_spRouterInfo->EnumInterface(&spEnumIf);
  518. while (FHrSucceeded(hr))
  519. {
  520. poszIfName = A2COLE((LPCSTR)(pIpxIf->InterfaceName));
  521. spIf.Release();
  522. spEnumIf->Reset();
  523. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  524. {
  525. // Look for a match on the interface name
  526. if (StriCmpOle(poszIfName, spIf->GetId()) == 0)
  527. {
  528. m_rgIfTitle.SetAtGrow(pIpxIf->InterfaceIndex,
  529. OLE2CT(spIf->GetTitle()));
  530. break;
  531. }
  532. }
  533. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  534. pIpxIf->InterfaceIndex;
  535. // Get the next name
  536. spMib.Free();
  537. pIpxIf = NULL;
  538. dwErr = ::MprAdminMIBEntryGetNext(m_pIPXConn->GetMibHandle(),
  539. PID_IPX,
  540. IPX_PROTOCOL_BASE,
  541. &MibGetInputData,
  542. sizeof(MibGetInputData),
  543. (LPVOID *) &pIpxIf,
  544. &cbIfTable);
  545. hr = HRESULT_FROM_WIN32(dwErr);
  546. spMib = (PBYTE) pIpxIf;
  547. }
  548. Error:
  549. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  550. hr = hrOK;
  551. return hr;
  552. }
  553. /*!--------------------------------------------------------------------------
  554. IpxRoutingStatistics::FixColumnAlignment
  555. -
  556. Author: Deonb
  557. Fixes the column allignment for the Tick & Hop count columns.
  558. ---------------------------------------------------------------------------*/
  559. void IpxRoutingStatistics::FixColumnAlignment()
  560. {
  561. ULONG cColumns;
  562. ColumnData *pColumnData;
  563. if (m_pConfig)
  564. {
  565. cColumns = m_pConfig->GetColumnCount(m_ulId);
  566. pColumnData = (ColumnData *) alloca(sizeof(ColumnData) * cColumns);
  567. m_pConfig->GetColumnData(m_ulId, cColumns, pColumnData);
  568. for (ULONG i = 0; i < cColumns; i++)
  569. pColumnData[m_pConfig->MapColumnToSubitem(m_ulId, i)].fmt = LVCFMT_LEFT;
  570. pColumnData[m_pConfig->MapColumnToSubitem(m_ulId, 2)].fmt = LVCFMT_RIGHT;
  571. pColumnData[m_pConfig->MapColumnToSubitem(m_ulId, 3)].fmt = LVCFMT_RIGHT;
  572. m_pConfig->SetColumnData(m_ulId, cColumns, pColumnData);
  573. }
  574. else
  575. {
  576. cColumns = m_viewInfo.GetColumnCount();
  577. pColumnData = (ColumnData *) alloca(sizeof(ColumnData) * cColumns);
  578. m_viewInfo.GetColumnData(cColumns, pColumnData);
  579. for (ULONG i = 0; i < cColumns; i++)
  580. pColumnData[m_viewInfo.MapColumnToSubitem(i)].fmt = LVCFMT_LEFT;
  581. pColumnData[m_viewInfo.MapColumnToSubitem(2)].fmt = LVCFMT_RIGHT;
  582. pColumnData[m_viewInfo.MapColumnToSubitem(3)].fmt = LVCFMT_RIGHT;
  583. m_viewInfo.SetColumnData(cColumns, pColumnData);
  584. }
  585. for (ULONG i = 0; i < cColumns; i++)
  586. {
  587. LVCOLUMN lvc;
  588. lvc.mask = LVCF_FMT;
  589. lvc.fmt = pColumnData[i].fmt;
  590. m_listCtrl.SendMessage(LVM_SETCOLUMN, i, (LPARAM)&lvc);
  591. }
  592. }
  593. /*!--------------------------------------------------------------------------
  594. IpxRoutingStatistics::OnInitDialog
  595. -
  596. Author: KennT
  597. ---------------------------------------------------------------------------*/
  598. BOOL IpxRoutingStatistics::OnInitDialog()
  599. {
  600. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  601. CString st;
  602. st.LoadString(IDS_STATS_IPX_ROUTING_TITLE);
  603. SetWindowText((LPCTSTR) st);
  604. FixColumnAlignment();
  605. return IPXStatisticsDialog::OnInitDialog();
  606. }
  607. /*!--------------------------------------------------------------------------
  608. IpxRoutingStatistics::PostNcDestroy
  609. -
  610. Author: KennT
  611. ---------------------------------------------------------------------------*/
  612. void IpxRoutingStatistics::PostNcDestroy()
  613. {
  614. IPXStatisticsDialog::PostNcDestroy();
  615. m_dwSortSubitem = 0xFFFFFFFF;
  616. }
  617. /*!--------------------------------------------------------------------------
  618. IpxRoutingStatisticsCompareProc
  619. -
  620. Author: KennT
  621. ---------------------------------------------------------------------------*/
  622. struct SIpxRoutingSortInfo
  623. {
  624. DWORD m_dwSubitemId;
  625. IpxRoutingStatistics * m_pIpx;
  626. };
  627. int CALLBACK IpxRoutingStatisticsCompareProc(LPARAM lParam1, LPARAM lParam2,
  628. LPARAM lParamSort)
  629. {
  630. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  631. int iReturn = 0;
  632. SIpxRoutingSortInfo * pSort = (SIpxRoutingSortInfo *) lParamSort;
  633. IpxRoutingStatistics * pIpx;
  634. PIPX_ROUTE pRoute1;
  635. PIPX_ROUTE pRoute2;
  636. pIpx = pSort->m_pIpx;
  637. pRoute1 = &(pIpx->m_Items[(int)lParam1]);
  638. pRoute2 = &(pIpx->m_Items[(int)lParam2]);
  639. switch (pSort->m_dwSubitemId)
  640. {
  641. case MVR_IPXROUTING_NETWORK:
  642. iReturn = memcmp(pRoute1->Network,
  643. pRoute2->Network,
  644. sizeof(pRoute1->Network));
  645. break;
  646. case MVR_IPXROUTING_NEXT_HOP_MAC:
  647. iReturn = memcmp(pRoute1->NextHopMacAddress,
  648. pRoute2->NextHopMacAddress,
  649. sizeof(pRoute1->NextHopMacAddress));
  650. break;
  651. case MVR_IPXROUTING_TICK_COUNT:
  652. iReturn = DWORD_CMP(pRoute1->TickCount,
  653. pRoute2->TickCount);
  654. break;
  655. case MVR_IPXROUTING_HOP_COUNT:
  656. iReturn = DWORD_CMP(pRoute1->HopCount,
  657. pRoute2->HopCount);
  658. break;
  659. case MVR_IPXROUTING_IF_NAME:
  660. {
  661. CString st1, st2;
  662. if (pRoute1->InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  663. st1.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  664. else
  665. st1 = pIpx->m_rgIfTitle[pRoute1->InterfaceIndex];
  666. if (pRoute2->InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  667. st2.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  668. else
  669. st2 = pIpx->m_rgIfTitle[pRoute2->InterfaceIndex];
  670. iReturn = StriCmp((LPCTSTR) st1, (LPCTSTR) st2);
  671. }
  672. break;
  673. case MVR_IPXROUTING_PROTOCOL:
  674. {
  675. CString st1, st2;
  676. st1 = IpxProtocolToCString(pRoute1->Protocol);
  677. st2 = IpxProtocolToCString(pRoute2->Protocol);
  678. iReturn = StriCmp((LPCTSTR) st1, (LPCTSTR) st2);
  679. }
  680. break;
  681. case MVR_IPXROUTING_ROUTE_NOTES:
  682. iReturn = DWORD_CMP(pRoute1->Flags,
  683. pRoute2->Flags);
  684. break;
  685. }
  686. return iReturn;
  687. }
  688. /*!--------------------------------------------------------------------------
  689. IpxRoutingStatisticsCompareProcMinus
  690. -
  691. Author: KennT
  692. ---------------------------------------------------------------------------*/
  693. int CALLBACK IpxRoutingStatisticsCompareProcMinus(LPARAM lParam1, LPARAM lParam2,
  694. LPARAM lParamSort)
  695. {
  696. return -IpxRoutingStatisticsCompareProc(lParam1, lParam2, lParamSort);
  697. }
  698. /*!--------------------------------------------------------------------------
  699. IpxRoutingStatistics::Sort
  700. -
  701. Author: KennT
  702. ---------------------------------------------------------------------------*/
  703. void IpxRoutingStatistics::Sort(UINT nColumnId)
  704. {
  705. SIpxRoutingSortInfo ipxSortInfo;
  706. DWORD dwSubitemId;
  707. if (m_pConfig)
  708. dwSubitemId = m_pConfig->MapColumnToSubitem(m_ulId, nColumnId);
  709. else
  710. dwSubitemId = m_viewInfo.MapColumnToSubitem(nColumnId);
  711. if (m_dwSortSubitem != -1)
  712. {
  713. if (dwSubitemId == m_dwSortSubitem)
  714. m_fSortDirection = !m_fSortDirection;
  715. else
  716. m_fSortDirection = 0;
  717. }
  718. ipxSortInfo.m_dwSubitemId = dwSubitemId;
  719. ipxSortInfo.m_pIpx = this;
  720. if (m_fSortDirection)
  721. {
  722. m_listCtrl.SortItems(IpxRoutingStatisticsCompareProcMinus, (LPARAM) &ipxSortInfo);
  723. }
  724. else
  725. {
  726. m_listCtrl.SortItems(IpxRoutingStatisticsCompareProc, (LPARAM) &ipxSortInfo);
  727. }
  728. m_dwSortSubitem = dwSubitemId;
  729. }
  730. /*!--------------------------------------------------------------------------
  731. IpxRoutingStatistics::PreDeleteAllItems
  732. -
  733. Author: KennT
  734. ---------------------------------------------------------------------------*/
  735. void IpxRoutingStatistics::PreDeleteAllItems()
  736. {
  737. m_Items.SetSize(0);
  738. }
  739. /*!--------------------------------------------------------------------------
  740. IpxRoutingStatistics::OnNotifyGetDispInfo
  741. -
  742. Author: KennT
  743. ---------------------------------------------------------------------------*/
  744. void IpxRoutingStatistics::OnNotifyGetDispInfo(NMHDR *pNmHdr, LRESULT *pResult)
  745. {
  746. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  747. LV_DISPINFO * plvDispInfo = reinterpret_cast<LV_DISPINFO *>(pNmHdr);
  748. LV_ITEM * plvItem = &(plvDispInfo->item);
  749. ULONG iIndex = (ULONG)plvItem->lParam;
  750. TCHAR szNumber[32];
  751. CString st;
  752. if ((plvItem->mask & LVIF_PARAM) == 0)
  753. {
  754. // Ok, this lParam is not valid, we will need to request
  755. // the lParam for this item
  756. iIndex = (ULONG)m_listCtrl.GetItemData(plvItem->iItem);
  757. }
  758. // Ok, we can now get the data for this item
  759. switch (MapColumnToSubitem(plvItem->iSubItem))
  760. {
  761. case MVR_IPXROUTING_NETWORK:
  762. FormatIpxNetworkNumber(szNumber, DimensionOf(szNumber),
  763. m_Items[iIndex].Network,
  764. DimensionOf(m_Items[iIndex].Network));
  765. st = szNumber;
  766. break;
  767. case MVR_IPXROUTING_NEXT_HOP_MAC:
  768. FormatMACAddress(szNumber, DimensionOf(szNumber),
  769. m_Items[iIndex].NextHopMacAddress,
  770. DimensionOf(m_Items[iIndex].NextHopMacAddress));
  771. st = szNumber;
  772. break;
  773. case MVR_IPXROUTING_TICK_COUNT:
  774. FormatNumber(m_Items[iIndex].TickCount,
  775. szNumber, DimensionOf(szNumber),
  776. FALSE);
  777. st = szNumber;
  778. break;
  779. case MVR_IPXROUTING_HOP_COUNT:
  780. FormatNumber(m_Items[iIndex].HopCount,
  781. szNumber, DimensionOf(szNumber),
  782. FALSE);
  783. st = szNumber;
  784. break;
  785. case MVR_IPXROUTING_IF_NAME:
  786. if (m_Items[iIndex].InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  787. st.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  788. else
  789. st = m_rgIfTitle[m_Items[iIndex].InterfaceIndex];
  790. break;
  791. case MVR_IPXROUTING_PROTOCOL:
  792. st = IpxProtocolToCString(m_Items[iIndex].Protocol);
  793. break;
  794. case MVR_IPXROUTING_ROUTE_NOTES:
  795. st = IpxRouteNotesToCString(m_Items[iIndex].Flags);
  796. break;
  797. default:
  798. Panic1("Unknown IPX routing id! %d",
  799. MapColumnToSubitem(plvItem->iSubItem));
  800. break;
  801. }
  802. lstrcpyn(plvItem->pszText, (LPCTSTR) st, plvItem->cchTextMax);
  803. }
  804. /*---------------------------------------------------------------------------
  805. IpxServiceStatistics implementation
  806. ---------------------------------------------------------------------------*/
  807. extern const ContainerColumnInfo s_rgIpxServiceStatsColumnInfo[];
  808. const ContainerColumnInfo s_rgIpxServiceStatsColumnInfo[] =
  809. {
  810. { IDS_STATS_IPXSERVICE_SERVICE_NAME, 0, TRUE, COL_STRING },
  811. { IDS_STATS_IPXSERVICE_SERVICE_TYPE, 0, TRUE, COL_STRING },
  812. { IDS_STATS_IPXSERVICE_SERVICE_ADDRESS, 0, TRUE, COL_STRING },
  813. { IDS_STATS_IPXSERVICE_HOP_COUNT, 0, TRUE, COL_SMALL_NUM },
  814. { IDS_STATS_IPXSERVICE_IF_NAME, 0, TRUE, COL_IF_NAME },
  815. { IDS_STATS_IPXSERVICE_PROTOCOL, 0, TRUE, COL_STRING },
  816. };
  817. BEGIN_MESSAGE_MAP(IpxServiceStatistics, IPXStatisticsDialog)
  818. ON_NOTIFY(LVN_GETDISPINFO, IDC_STATSDLG_LIST, OnNotifyGetDispInfo)
  819. END_MESSAGE_MAP()
  820. /*!--------------------------------------------------------------------------
  821. IpxServiceStatistics::IpxServiceStatistics
  822. -
  823. Author: KennT
  824. ---------------------------------------------------------------------------*/
  825. IpxServiceStatistics::IpxServiceStatistics()
  826. : IPXStatisticsDialog(/*STATSDLG_FULLWINDOW |*/
  827. STATSDLG_CONTEXTMENU |
  828. STATSDLG_SELECT_COLUMNS),
  829. m_dwSortSubitem(0xFFFFFFFF)
  830. {
  831. SetColumnInfo(s_rgIpxServiceStatsColumnInfo,
  832. DimensionOf(s_rgIpxServiceStatsColumnInfo));
  833. }
  834. /*!--------------------------------------------------------------------------
  835. IpxServiceStatistics::~IpxServiceStatistics
  836. -
  837. Author: KennT
  838. ---------------------------------------------------------------------------*/
  839. IpxServiceStatistics::~IpxServiceStatistics()
  840. {
  841. m_Items.SetSize(0);
  842. SetConnectionData(NULL);
  843. }
  844. /*!--------------------------------------------------------------------------
  845. IpxServiceStatistics::SetRouterInfo
  846. -
  847. Author: KennT
  848. ---------------------------------------------------------------------------*/
  849. void IpxServiceStatistics::SetRouterInfo(IRouterInfo *pRouterInfo)
  850. {
  851. m_spRouterInfo.Set(pRouterInfo);
  852. }
  853. /*!--------------------------------------------------------------------------
  854. IpxServiceStatistics::RefreshData
  855. -
  856. Author: KennT
  857. ---------------------------------------------------------------------------*/
  858. HRESULT IpxServiceStatistics::RefreshData(BOOL fGrabNewData)
  859. {
  860. HRESULT hr = hrOK;
  861. int i, cItems;
  862. if (fGrabNewData)
  863. {
  864. m_Items.SetSize(0);
  865. CORg( GetIpxServiceData() );
  866. // Prepare the list control for the large amount of entries
  867. if (m_listCtrl.GetItemCount() < m_Items.GetSize())
  868. m_listCtrl.SetItemCount((int) m_Items.GetSize());
  869. }
  870. // Iterate through the array adding the data to the list control
  871. cItems = (int) m_Items.GetSize();
  872. for (i=0; i<cItems; i++)
  873. {
  874. // Add the items as callback items
  875. m_listCtrl.InsertItem(LVIF_TEXT | LVIF_PARAM, i, LPSTR_TEXTCALLBACK,
  876. 0, 0, 0, (DWORD) i);
  877. }
  878. Error:
  879. return hrOK;
  880. }
  881. /*!--------------------------------------------------------------------------
  882. IpxServiceStatistics::GetIpxServiceData
  883. Grabs the IPX service table and fills in the m_Items array with
  884. that data.
  885. Author: KennT
  886. ---------------------------------------------------------------------------*/
  887. HRESULT IpxServiceStatistics::GetIpxServiceData()
  888. {
  889. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  890. PIPXMIB_BASE pIpxMib = NULL;
  891. DWORD cbIpxMib;
  892. DWORD dwErr;
  893. HRESULT hr = hrOK;
  894. SPMprMibBuffer spMib;
  895. PIPX_SERVICE pService = NULL;
  896. SPMprMibBuffer spMibRoute;
  897. DWORD cbService;
  898. int cEntries = 0;
  899. // Load up on the interface titles
  900. CORg( FillInterfaceTable() );
  901. MibGetInputData.TableId = IPX_BASE_ENTRY;
  902. CWRg( ::MprAdminMIBEntryGet(m_pIPXConn->GetMibHandle(),
  903. PID_IPX,
  904. IPX_PROTOCOL_BASE,
  905. &MibGetInputData,
  906. sizeof(MibGetInputData),
  907. (LPVOID *) &pIpxMib,
  908. &cbIpxMib) );
  909. if(pIpxMib == NULL)
  910. {
  911. hr = E_FAIL;
  912. goto Error;
  913. }
  914. spMib = (PBYTE) pIpxMib;
  915. // Prepare the data array for the number of items (+ some buffer)
  916. m_Items.SetSize( pIpxMib->DestCount + 100);
  917. MibGetInputData.TableId = IPX_SERV_TABLE;
  918. dwErr = ::MprAdminMIBEntryGetFirst(m_pIPXConn->GetMibHandle(),
  919. PID_IPX,
  920. IPX_PROTOCOL_BASE,
  921. &MibGetInputData,
  922. sizeof(MibGetInputData),
  923. (LPVOID *) &pService,
  924. &cbService);
  925. hr = HRESULT_FROM_WIN32(dwErr);
  926. spMibRoute = (PBYTE) pService;
  927. cEntries = 0;
  928. while (FHrSucceeded(hr))
  929. {
  930. Assert(pService);
  931. // Add this data at position cEntries
  932. m_Items.SetAtGrow(cEntries, *pService);
  933. cEntries++;
  934. // Get the next set of data
  935. MibGetInputData.TableId = IPX_SERV_TABLE;
  936. MibGetInputData.MibIndex.ServicesTableIndex.ServiceType =
  937. pService->Server.Type;
  938. memcpy(MibGetInputData.MibIndex.ServicesTableIndex.ServiceName,
  939. pService->Server.Name,
  940. sizeof(MibGetInputData.MibIndex.ServicesTableIndex.ServiceName));
  941. pService = NULL;
  942. spMibRoute.Free();
  943. dwErr = ::MprAdminMIBEntryGetNext(m_pIPXConn->GetMibHandle(),
  944. PID_IPX,
  945. IPX_PROTOCOL_BASE,
  946. &MibGetInputData,
  947. sizeof(MibGetInputData),
  948. (LPVOID *) &pService,
  949. &cbService);
  950. hr = HRESULT_FROM_WIN32(dwErr);
  951. spMibRoute = (PBYTE) pService;
  952. }
  953. // Do this to make sure that we don't have bogus entries at the top
  954. // of the array and that we can use the GetSize() to get an accurate
  955. // count of the number of items.
  956. m_Items.SetSize(cEntries);
  957. Error:
  958. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  959. hr = hrOK;
  960. return hr;
  961. }
  962. /*!--------------------------------------------------------------------------
  963. IpxServiceStatistics::FillInterfaceTable
  964. Fills m_rgIfTitle with the interface titles.
  965. Author: KennT
  966. ---------------------------------------------------------------------------*/
  967. HRESULT IpxServiceStatistics::FillInterfaceTable()
  968. {
  969. HRESULT hr = hrOK;
  970. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  971. PIPX_INTERFACE pIpxIf = NULL;
  972. DWORD cbIfTable;
  973. SPIInterfaceInfo spIf;
  974. SPIEnumInterfaceInfo spEnumIf;
  975. LPCOLESTR poszIfName;
  976. SPMprMibBuffer spMib;
  977. DWORD dwErr;
  978. USES_CONVERSION;
  979. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  980. CWRg( ::MprAdminMIBEntryGetFirst(m_pIPXConn->GetMibHandle(),
  981. PID_IPX,
  982. IPX_PROTOCOL_BASE,
  983. &MibGetInputData,
  984. sizeof(MibGetInputData),
  985. (LPVOID *) &pIpxIf,
  986. &cbIfTable));
  987. spMib = (PBYTE) pIpxIf;
  988. m_spRouterInfo->EnumInterface(&spEnumIf);
  989. while (FHrSucceeded(hr))
  990. {
  991. poszIfName = A2COLE((LPCSTR)(pIpxIf->InterfaceName));
  992. spIf.Release();
  993. spEnumIf->Reset();
  994. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  995. {
  996. // Look for a match on the interface name
  997. if (StriCmpOle(poszIfName, spIf->GetId()) == 0)
  998. {
  999. m_rgIfTitle.SetAtGrow(pIpxIf->InterfaceIndex,
  1000. OLE2CT(spIf->GetTitle()));
  1001. break;
  1002. }
  1003. }
  1004. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  1005. pIpxIf->InterfaceIndex;
  1006. // Get the next name
  1007. spMib.Free();
  1008. pIpxIf = NULL;
  1009. dwErr = ::MprAdminMIBEntryGetNext(m_pIPXConn->GetMibHandle(),
  1010. PID_IPX,
  1011. IPX_PROTOCOL_BASE,
  1012. &MibGetInputData,
  1013. sizeof(MibGetInputData),
  1014. (LPVOID *) &pIpxIf,
  1015. &cbIfTable);
  1016. hr = HRESULT_FROM_WIN32(dwErr);
  1017. spMib = (PBYTE) pIpxIf;
  1018. }
  1019. Error:
  1020. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  1021. hr = hrOK;
  1022. return hr;
  1023. }
  1024. /*!--------------------------------------------------------------------------
  1025. IpxServiceStatistics::OnInitDialog
  1026. -
  1027. Author: KennT
  1028. ---------------------------------------------------------------------------*/
  1029. BOOL IpxServiceStatistics::OnInitDialog()
  1030. {
  1031. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1032. CString st;
  1033. st.LoadString(IDS_STATS_IPX_SERVICE_TITLE);
  1034. SetWindowText((LPCTSTR) st);
  1035. return IPXStatisticsDialog::OnInitDialog();
  1036. }
  1037. /*!--------------------------------------------------------------------------
  1038. IpxServiceStatistics::PostNcDestroy
  1039. -
  1040. Author: KennT
  1041. ---------------------------------------------------------------------------*/
  1042. void IpxServiceStatistics::PostNcDestroy()
  1043. {
  1044. IPXStatisticsDialog::PostNcDestroy();
  1045. m_dwSortSubitem = 0xFFFFFFFF;
  1046. }
  1047. /*!--------------------------------------------------------------------------
  1048. IpxServiceStatisticsCompareProc
  1049. -
  1050. Author: KennT
  1051. ---------------------------------------------------------------------------*/
  1052. struct SIpxServiceSortInfo
  1053. {
  1054. DWORD m_dwSubitemId;
  1055. IpxServiceStatistics * m_pIpx;
  1056. };
  1057. int CALLBACK IpxServiceStatisticsCompareProc(LPARAM lParam1, LPARAM lParam2,
  1058. LPARAM lParamSort)
  1059. {
  1060. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1061. int iReturn = 0;
  1062. SIpxServiceSortInfo * pSort = (SIpxServiceSortInfo *) lParamSort;
  1063. IpxServiceStatistics * pIpx;
  1064. PIPX_SERVICE pService1;
  1065. PIPX_SERVICE pService2;
  1066. pIpx = pSort->m_pIpx;
  1067. pService1 = &(pIpx->m_Items[(int)lParam1]);
  1068. pService2 = &(pIpx->m_Items[(int)lParam2]);
  1069. switch (pSort->m_dwSubitemId)
  1070. {
  1071. case MVR_IPXSERVICE_SERVICE_TYPE:
  1072. iReturn = pService1->Server.Type - pService2->Server.Type;
  1073. break;
  1074. case MVR_IPXSERVICE_SERVICE_NAME:
  1075. iReturn = StriCmpA((LPCSTR) pService1->Server.Name,
  1076. (LPCSTR) pService2->Server.Name);
  1077. break;
  1078. case MVR_IPXSERVICE_SERVICE_ADDRESS:
  1079. iReturn = memcmp(pService1->Server.Network,
  1080. pService2->Server.Network,
  1081. sizeof(pService1->Server.Network));
  1082. if (iReturn == 0)
  1083. iReturn = memcmp(pService1->Server.Node,
  1084. pService2->Server.Node,
  1085. sizeof(pService1->Server.Node));
  1086. if (iReturn == 0)
  1087. iReturn = memcmp(pService1->Server.Socket,
  1088. pService2->Server.Socket,
  1089. sizeof(pService1->Server.Socket));
  1090. break;
  1091. case MVR_IPXSERVICE_HOP_COUNT:
  1092. iReturn = DWORD_CMP(pService1->Server.HopCount,
  1093. pService2->Server.HopCount);
  1094. break;
  1095. case MVR_IPXSERVICE_IF_NAME:
  1096. {
  1097. CString st1, st2;
  1098. if (pService1->InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  1099. st1.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  1100. else
  1101. st1 = pIpx->m_rgIfTitle[pService1->InterfaceIndex];
  1102. if (pService2->InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  1103. st2.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  1104. else
  1105. st2 = pIpx->m_rgIfTitle[pService2->InterfaceIndex];
  1106. iReturn = StriCmp((LPCTSTR) st1, (LPCTSTR) st2);
  1107. }
  1108. break;
  1109. case MVR_IPXSERVICE_PROTOCOL:
  1110. {
  1111. CString st1, st2;
  1112. st1 = IpxProtocolToCString(pService1->Protocol);
  1113. st2 = IpxProtocolToCString(pService2->Protocol);
  1114. iReturn = StriCmp((LPCTSTR) st1, (LPCTSTR) st2);
  1115. }
  1116. break;
  1117. }
  1118. return iReturn;
  1119. }
  1120. /*!--------------------------------------------------------------------------
  1121. IpxServiceStatisticsCompareProcMinus
  1122. -
  1123. Author: KennT
  1124. ---------------------------------------------------------------------------*/
  1125. int CALLBACK IpxServiceStatisticsCompareProcMinus(LPARAM lParam1, LPARAM lParam2,
  1126. LPARAM lParamSort)
  1127. {
  1128. return -IpxServiceStatisticsCompareProc(lParam1, lParam2, lParamSort);
  1129. }
  1130. /*!--------------------------------------------------------------------------
  1131. IpxServiceStatistics::Sort
  1132. -
  1133. Author: KennT
  1134. ---------------------------------------------------------------------------*/
  1135. void IpxServiceStatistics::Sort(UINT nColumnId)
  1136. {
  1137. SIpxServiceSortInfo ipxSortInfo;
  1138. DWORD dwSubitemId;
  1139. if (m_pConfig)
  1140. dwSubitemId = m_pConfig->MapColumnToSubitem(m_ulId, nColumnId);
  1141. else
  1142. dwSubitemId = m_viewInfo.MapColumnToSubitem(nColumnId);
  1143. if (m_dwSortSubitem != -1)
  1144. {
  1145. if (dwSubitemId == m_dwSortSubitem)
  1146. m_fSortDirection = !m_fSortDirection;
  1147. else
  1148. m_fSortDirection = 0;
  1149. }
  1150. ipxSortInfo.m_dwSubitemId = dwSubitemId;
  1151. ipxSortInfo.m_pIpx = this;
  1152. if (m_fSortDirection)
  1153. {
  1154. m_listCtrl.SortItems(IpxServiceStatisticsCompareProcMinus, (LPARAM) &ipxSortInfo);
  1155. }
  1156. else
  1157. {
  1158. m_listCtrl.SortItems(IpxServiceStatisticsCompareProc, (LPARAM) &ipxSortInfo);
  1159. }
  1160. m_dwSortSubitem = dwSubitemId;
  1161. }
  1162. /*!--------------------------------------------------------------------------
  1163. IpxServiceStatistics::PreDeleteAllItems
  1164. -
  1165. Author: KennT
  1166. ---------------------------------------------------------------------------*/
  1167. void IpxServiceStatistics::PreDeleteAllItems()
  1168. {
  1169. }
  1170. /*!--------------------------------------------------------------------------
  1171. IpxServiceStatistics::OnNotifyGetDispInfo
  1172. -
  1173. Author: KennT
  1174. ---------------------------------------------------------------------------*/
  1175. void IpxServiceStatistics::OnNotifyGetDispInfo(NMHDR *pNmHdr, LRESULT *pResult)
  1176. {
  1177. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1178. LV_DISPINFO * plvDispInfo = reinterpret_cast<LV_DISPINFO *>(pNmHdr);
  1179. LV_ITEM * plvItem = &(plvDispInfo->item);
  1180. ULONG iIndex = (ULONG)plvItem->lParam;
  1181. TCHAR szNumber[32];
  1182. CString st;
  1183. if ((plvItem->mask & LVIF_PARAM) == 0)
  1184. {
  1185. // Ok, this lParam is not valid, we will need to request
  1186. // the lParam for this item
  1187. iIndex = (ULONG)m_listCtrl.GetItemData(plvItem->iItem);
  1188. }
  1189. // Ok, we can now get the data for this item
  1190. switch (MapColumnToSubitem(plvItem->iSubItem))
  1191. {
  1192. case MVR_IPXSERVICE_SERVICE_NAME:
  1193. st.Format(_T("%.48hs"), m_Items[iIndex].Server.Name);
  1194. break;
  1195. case MVR_IPXSERVICE_SERVICE_TYPE:
  1196. st.Format(_T("%.4x"), m_Items[iIndex].Server.Type);
  1197. break;
  1198. case MVR_IPXSERVICE_SERVICE_ADDRESS:
  1199. FormatIpxNetworkNumber(szNumber, DimensionOf(szNumber),
  1200. m_Items[iIndex].Server.Network,
  1201. DimensionOf(m_Items[iIndex].Server.Network));
  1202. st = szNumber;
  1203. FormatMACAddress(szNumber, DimensionOf(szNumber),
  1204. m_Items[iIndex].Server.Node,
  1205. DimensionOf(m_Items[iIndex].Server.Node));
  1206. st += _T(".");
  1207. st += szNumber;
  1208. wsprintf(szNumber, _T("%.2x%.2x"),
  1209. m_Items[iIndex].Server.Socket[0],
  1210. m_Items[iIndex].Server.Socket[1]);
  1211. st += _T(".");
  1212. st += szNumber;
  1213. break;
  1214. case MVR_IPXSERVICE_HOP_COUNT:
  1215. FormatNumber(m_Items[iIndex].Server.HopCount,
  1216. szNumber, DimensionOf(szNumber),
  1217. FALSE);
  1218. st = szNumber;
  1219. break;
  1220. case MVR_IPXSERVICE_IF_NAME:
  1221. if (m_Items[iIndex].InterfaceIndex == GLOBAL_INTERFACE_INDEX)
  1222. st.LoadString(IDS_IPX_WAN_CLIENT_ROUTE);
  1223. else
  1224. st = m_rgIfTitle[m_Items[iIndex].InterfaceIndex];
  1225. break;
  1226. case MVR_IPXSERVICE_PROTOCOL:
  1227. st = IpxProtocolToCString(m_Items[iIndex].Protocol);
  1228. break;
  1229. default:
  1230. Panic1("Unknown IPX service id! %d",
  1231. MapColumnToSubitem(plvItem->iSubItem));
  1232. break;
  1233. }
  1234. lstrcpyn(plvItem->pszText, (LPCTSTR) st, plvItem->cchTextMax);
  1235. }