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.

1666 lines
44 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998.
  5. //
  6. // File: S M G E N P S P . C P P
  7. //
  8. // Contents: The rendering of the UI for the network status monitor.
  9. //
  10. // Notes:
  11. //
  12. // Author: CWill 6 Oct 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h"
  18. #include "ncatlui.h"
  19. #include "ncnetcon.h"
  20. #include "ncperms.h"
  21. #include "ncui.h"
  22. #include "ncreg.h"
  23. #include "nsres.h"
  24. #include "sminc.h"
  25. #include "smpsh.h"
  26. #include "windutil.h"
  27. #include "conprops.h"
  28. #include "oncommand.h"
  29. #include "pidlutil.h"
  30. #include "openfold.h"
  31. #include "..\folder\confold.h"
  32. #include "cfpidl.h"
  33. DWORD MapRSSIToWirelessSignalStrength(int iRSSI);
  34. PCWSTR PszGetRSSIString(int iRSSI);
  35. //
  36. // Function Prototypes
  37. //
  38. VOID CompressionToSz(UINT uiCompression, WCHAR* pchbuffer);
  39. //
  40. // Common Strings
  41. //
  42. extern const WCHAR c_szNetShellDll[];
  43. //
  44. // Constants
  45. //
  46. const UINT c_unLocalRefreshTimerID = 817;
  47. //
  48. // ShowLanErrors
  49. //
  50. static const WCHAR c_szRegKeyStatmonRoot[] = L"System\\CurrentControlSet\\Control\\Network\\Connections\\StatMon";
  51. static const WCHAR c_szShowLanErrors[] = L"ShowLanErrors";
  52. // forward declaration
  53. DWORD PropertyThread(CNetStatisticsEngine * pnse);
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Member: CPspStatusMonitorGen::CPspStatusMonitorGen
  57. //
  58. // Purpose: Creator
  59. //
  60. // Arguments: None
  61. //
  62. // Returns: Nil
  63. //
  64. CPspStatusMonitorGen::CPspStatusMonitorGen() :
  65. m_psmEngineData(NULL),
  66. m_pnseStat(NULL),
  67. m_dwConPointCookie(0),
  68. m_fStats(FALSE),
  69. m_ncmType(NCM_LAN),
  70. m_ncsmType(NCSM_LAN),
  71. m_dwCharacter(0),
  72. m_dwLastUpdateStatusDisplayTick(0),
  73. m_fProcessingTimerEvent(FALSE),
  74. m_fIsFirstPage(FALSE),
  75. m_iLastSignalStrength(-100)
  76. {
  77. TraceFileFunc(ttidStatMon);
  78. }
  79. //+---------------------------------------------------------------------------
  80. //
  81. // Member: CPspStatusMonitorGen::FinalRelease
  82. //
  83. // Purpose: Called after last Release.
  84. //
  85. // Arguments: None
  86. //
  87. // Returns: Nil
  88. //
  89. VOID
  90. CPspStatusMonitorGen::FinalRelease(VOID)
  91. {
  92. TraceFileFunc(ttidStatMon);
  93. (VOID) HrCleanupGenPage();
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Member: CPspStatusMonitorGen::HrInitGenPage
  98. //
  99. // Purpose: Before the property page is populated, we have to make sure
  100. // that we have some of the required data. This method
  101. // initializes the page so that it is ready to be shown.
  102. //
  103. // Arguments: pnseNew - The statistics engine associated with this page
  104. // pncNew - The connection the page is being created for
  105. //
  106. // Returns: Error code
  107. //
  108. HRESULT
  109. CPspStatusMonitorGen::HrInitGenPage (
  110. CNetStatisticsEngine* pnseNew,
  111. INetConnection* pncNew,
  112. const DWORD * adwHelpIDs)
  113. {
  114. TraceFileFunc(ttidStatMon);
  115. HRESULT hr = S_OK;
  116. INetStatisticsEngine* pnseInter = pnseNew;
  117. AssertSz(pnseNew, "We don't have a pnseNew");
  118. // Set context help ID
  119. m_adwHelpIDs = adwHelpIDs;
  120. // Initialize the engine data
  121. //
  122. AssertSz(!m_psmEngineData, "We should't have a m_psmEngineData");
  123. DWORD dwBytes = sizeof(STATMON_ENGINEDATA);
  124. PVOID pbBuf;
  125. hr = HrCoTaskMemAlloc(dwBytes, &pbBuf);
  126. if (SUCCEEDED(hr))
  127. {
  128. m_psmEngineData = reinterpret_cast<STATMON_ENGINEDATA *>(pbBuf);
  129. ZeroMemory(m_psmEngineData, sizeof(STATMON_ENGINEDATA));
  130. }
  131. // Advise the interface
  132. //
  133. if (SUCCEEDED(hr))
  134. {
  135. IConnectionPoint* pcpStat = NULL;
  136. hr = ::HrGetPcpFromPnse(pnseInter, &pcpStat);
  137. if (SUCCEEDED(hr))
  138. {
  139. INetConnectionStatisticsNotifySink* pncsThis = this;
  140. hr = pcpStat->Advise(pncsThis, &m_dwConPointCookie);
  141. ::ReleaseObj(pcpStat);
  142. }
  143. }
  144. // Keep track of our owner
  145. //
  146. if (SUCCEEDED(hr))
  147. {
  148. AssertSz(!m_pnseStat, "We should't have a m_pnseStat");
  149. m_pnseStat = pnseNew;
  150. ::AddRefObj(pnseInter);
  151. }
  152. TraceError("CPspStatusMonitorGen::HrInitGenPage", hr);
  153. return hr;
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Member: CPspStatusMonitorGen::OnInitDialog
  158. //
  159. // Purpose: When the page comes up, initialize the fields
  160. //
  161. // Arguments: Standard command parameters
  162. //
  163. // Returns: Standard return
  164. //
  165. LRESULT
  166. CPspStatusMonitorGen::OnInitDialog (
  167. UINT uMsg,
  168. WPARAM wParam,
  169. LPARAM lParam,
  170. BOOL& bHandled)
  171. {
  172. TraceFileFunc(ttidStatMon);
  173. // initialize data member
  174. m_iStatTrans = Stat_Unknown;
  175. // Initialize the icon in the dialog by forcing it to change
  176. //
  177. UpdatePageIcon(SMDCF_TRANSMITTING | SMDCF_RECEIVING);
  178. UpdatePageIcon(SMDCF_NULL);
  179. UpdateSignalStrengthIcon(0);
  180. // Tell the CNetStatisticsEngine about our parent property sheet
  181. // so if someone attempts to bring up a statistics monitor we
  182. // can utilize the existing one
  183. //
  184. Assert(m_pnseStat);
  185. m_pnseStat->SetPropsheetWindow(GetParent());
  186. // Start our local refresh timer with a 1 second period.
  187. //
  188. SetTimer (c_unLocalRefreshTimerID, 1000, NULL);
  189. // leaving creating mode
  190. m_pnseStat->UnSetCreatingDialog();
  191. BOOL fEnableDisconnect = TRUE; // Should we disable the Disconnect button
  192. BOOL fEnableProperties = TRUE; // Should we disable the Properties button
  193. BOOL fShowErrorCount = TRUE;
  194. switch(m_ncmType)
  195. {
  196. case NCM_LAN:
  197. case NCM_BRIDGE:
  198. fEnableDisconnect = FHasPermission(NCPERM_LanConnect);
  199. fEnableProperties = FHasPermission(NCPERM_LanProperties);
  200. if(!FIsShowLanErrorRegKeySet())
  201. {
  202. fShowErrorCount = FALSE;
  203. }
  204. ::ShowWindow(GetDlgItem(IDC_TXT_ERROR), fShowErrorCount);
  205. ::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_TRANS), fShowErrorCount);
  206. ::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_RECV), fShowErrorCount);
  207. ::ShowWindow(GetDlgItem(IDC_FRM_LONG), fShowErrorCount);
  208. ::ShowWindow(GetDlgItem(IDC_FRM_SHORT), !fShowErrorCount); // reversed...
  209. break;
  210. case NCM_SHAREDACCESSHOST_RAS:
  211. ::SetWindowText(GetDlgItem(IDC_PSB_DISCONNECT), ::SzLoadIds(IDS_SM_PSH_DISCONNECT)); // If RAS connection, change the "Disable" button to "Disconnect"
  212. //fallthru
  213. case NCM_SHAREDACCESSHOST_LAN:
  214. {
  215. // TODO fEnableDisconnect
  216. // TODO fEnableProperties
  217. HRESULT hr;
  218. fShowErrorCount = FALSE; // no error stuff in spec
  219. }
  220. break;
  221. case NCM_TUNNEL:
  222. ::ShowWindow(GetDlgItem(IDC_TXT_SM_SPEED_LABEL), FALSE);
  223. ::ShowWindow(GetDlgItem(IDC_TXT_SM_SPEED), FALSE);
  224. //fallthru
  225. case NCM_DIRECT: // REVIEW correct?
  226. case NCM_ISDN:
  227. case NCM_PHONE:
  228. case NCM_PPPOE:
  229. fEnableDisconnect = FHasPermission(NCPERM_RasConnect);
  230. if (
  231. (m_dwCharacter & NCCF_INCOMING_ONLY) ||
  232. ((m_dwCharacter & NCCF_ALL_USERS) && !FHasPermission(NCPERM_RasAllUserProperties)) ||
  233. (!(m_dwCharacter & NCCF_ALL_USERS) && !FHasPermission(NCPERM_RasMyProperties))
  234. )
  235. {
  236. fEnableProperties = FALSE;
  237. }
  238. ::SetWindowText(GetDlgItem(IDC_PSB_DISCONNECT), ::SzLoadIds(IDS_SM_PSH_DISCONNECT)); // If RAS connection, change the "Disable" button to "Disconnect"
  239. ::ShowWindow(GetDlgItem(IDC_TXT_ERROR), fShowErrorCount);
  240. ::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_TRANS), fShowErrorCount);
  241. ::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_RECV), fShowErrorCount);
  242. ::ShowWindow(GetDlgItem(IDC_FRM_LONG), fShowErrorCount);
  243. ::ShowWindow(GetDlgItem(IDC_FRM_SHORT), !fShowErrorCount); // reversed...
  244. break;
  245. default:
  246. AssertSz(FALSE, "Unknown media type");
  247. break;
  248. }
  249. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_PSB_DISCONNECT), fEnableDisconnect);
  250. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_PSB_PROPERTIES), fEnableProperties);
  251. if (m_fIsFirstPage)
  252. {
  253. // get window handle to propertysheet
  254. HWND hwndParent=GetParent();
  255. Assert(hwndParent);
  256. // center the property sheet on desktop
  257. FCenterWindow (hwndParent, NULL);
  258. // hide the "ok" button
  259. //
  260. ::ShowWindow(::GetDlgItem(hwndParent, IDOK), FALSE);
  261. }
  262. return TRUE;
  263. }
  264. //+---------------------------------------------------------------------------
  265. //
  266. // Member: CPspStatusMonitorGen::OnSetActive
  267. //
  268. // Purpose: Enable statistics when the page has focus
  269. //
  270. // Arguments: Standard notification parameters
  271. //
  272. // Returns: Standard return
  273. //
  274. LRESULT
  275. CPspStatusMonitorGen::OnSetActive (
  276. INT idCtrl,
  277. LPNMHDR pnmh,
  278. BOOL& bHandled)
  279. {
  280. TraceFileFunc(ttidStatMon);
  281. HRESULT hr = S_OK;
  282. // Only turn them on if they are not running
  283. //
  284. if (!m_fStats)
  285. {
  286. hr = m_pnseStat->StartStatistics();
  287. m_fStats = TRUE;
  288. }
  289. // User's intent is to view statistics, so give them an immediate
  290. // refreshed view of them.
  291. //
  292. ::PostMessage (m_hWnd, PWM_UPDATE_STATUS_DISPLAY, 0, SMDCF_NULL);
  293. TraceError("CPspStatusMonitorGen::OnSetActive", hr);
  294. return LresFromHr(hr);
  295. }
  296. //+---------------------------------------------------------------------------
  297. //
  298. // Member: CPspStatusMonitorGen::OnKillActive
  299. //
  300. // Purpose: Disable statistics when the page is changed
  301. //
  302. // Arguments: Standard notification parameters
  303. //
  304. // Returns: Standard return
  305. //
  306. LRESULT
  307. CPspStatusMonitorGen::OnKillActive (
  308. INT idCtrl,
  309. LPNMHDR pnmh,
  310. BOOL& bHandled)
  311. {
  312. TraceFileFunc(ttidStatMon);
  313. HRESULT hr = S_OK;
  314. // Only turn them off if they are running
  315. //
  316. if (m_fStats)
  317. {
  318. hr = m_pnseStat->StopStatistics();
  319. m_fStats = FALSE;
  320. }
  321. TraceError("CPspStatusMonitorGen::OnKillActive", hr);
  322. return LresFromHr(hr);
  323. }
  324. //+---------------------------------------------------------------------------
  325. //
  326. // Member: CPspStatusMonitorGen::OnClose
  327. //
  328. // Purpose: Cleans up the items in the page when the dialog is being
  329. // closed
  330. //
  331. // Arguments: Standard command parameters
  332. //
  333. // Returns: Standard return
  334. //
  335. LRESULT
  336. CPspStatusMonitorGen::OnClose (
  337. UINT uMsg,
  338. WPARAM wParam,
  339. LPARAM lParam,
  340. BOOL& bHandled)
  341. {
  342. return DestroyWindow();
  343. }
  344. //+---------------------------------------------------------------------------
  345. //
  346. // Member: CPspStatusMonitorGen::OnDestroy
  347. //
  348. // Purpose: Cleans up the items in the page when the dialog is being
  349. // destroyed
  350. //
  351. // Arguments: Standard command parameters
  352. //
  353. // Returns: Standard return
  354. //
  355. LRESULT
  356. CPspStatusMonitorGen::OnDestroy (
  357. UINT uMsg,
  358. WPARAM wParam,
  359. LPARAM lParam,
  360. BOOL& bHandled)
  361. {
  362. TraceFileFunc(ttidStatMon);
  363. HWND hwndIcon = ::GetDlgItem(m_hWnd, IDI_SM_STATUS_ICON);
  364. HICON hOldIcon = reinterpret_cast<HICON>(::SendMessage(
  365. hwndIcon,
  366. STM_GETICON,
  367. 0,
  368. 0));
  369. if (hOldIcon)
  370. {
  371. DestroyIcon(hOldIcon);
  372. }
  373. HRESULT hr = S_OK;
  374. AssertSz(m_pnseStat, "We should have a m_pnseStat");
  375. // Make sure we don't get released during our destroy
  376. //
  377. ::AddRefObj(this);
  378. // Stop our local refresh timer
  379. //
  380. KillTimer (c_unLocalRefreshTimerID);
  381. // Make sure stats are in a happy state
  382. //
  383. if (m_fStats)
  384. {
  385. (VOID) m_pnseStat->StopStatistics();
  386. m_fStats = FALSE;
  387. }
  388. //
  389. // *** Do this last ***
  390. //
  391. // It is very likely this will result in the this page being destroyed
  392. // if it is the window closing
  393. //
  394. m_pnseStat->SetPropsheetWindow(NULL);
  395. // Clean up all the interfaces
  396. //
  397. hr = HrCleanupGenPage();
  398. ::ReleaseObj(this);
  399. TraceError("CPspStatusMonitorGen::OnDestroy", hr);
  400. return 0;
  401. }
  402. //+---------------------------------------------------------------------------
  403. //
  404. // Member: CPspStatusMonitorGen::HrCleanupGenPage
  405. //
  406. // Purpose: Cleans out all the interfaces that are used by the open page
  407. //
  408. // Arguments: None
  409. //
  410. // Returns: Error code
  411. //
  412. HRESULT
  413. CPspStatusMonitorGen::HrCleanupGenPage (
  414. VOID)
  415. {
  416. TraceFileFunc(ttidStatMon);
  417. HRESULT hr = S_OK;
  418. INetStatisticsEngine* pnseStat = m_pnseStat;
  419. // Only disconnect if we haven't already.
  420. //
  421. if (pnseStat)
  422. {
  423. // Unadvise the interface
  424. //
  425. IConnectionPoint* pcpStat = NULL;
  426. if (m_dwConPointCookie
  427. && (SUCCEEDED(::HrGetPcpFromPnse(pnseStat, &pcpStat))))
  428. {
  429. (VOID) pcpStat->Unadvise(m_dwConPointCookie);
  430. ::ReleaseObj(pcpStat);
  431. // Very important to zero the cookie. This tells
  432. // OnStatisticsChanged that we're no longer interested in updates.
  433. //
  434. m_dwConPointCookie = 0;
  435. }
  436. if (m_psmEngineData)
  437. {
  438. CoTaskMemFree(m_psmEngineData);
  439. m_psmEngineData = NULL;
  440. }
  441. //
  442. // *** Do this last ***
  443. //
  444. // It is very likely this will result in the this page being destroyed
  445. // if it is the window closing
  446. //
  447. m_pnseStat = NULL;
  448. ::ReleaseObj(pnseStat);
  449. }
  450. TraceError("CPspStatusMonitorGen::HrCleanupGenPage", hr);
  451. return hr;
  452. }
  453. //+---------------------------------------------------------------------------
  454. //
  455. // Member: CPspStatusMonitorGen::OnContextMenu
  456. //
  457. // Purpose: When right click a control, bring up help
  458. //
  459. // Arguments: Standard command parameters
  460. //
  461. // Returns: Standard return
  462. //
  463. LRESULT
  464. CPspStatusMonitorGen::OnContextMenu(UINT uMsg,
  465. WPARAM wParam,
  466. LPARAM lParam,
  467. BOOL& fHandled)
  468. {
  469. TraceFileFunc(ttidStatMon);
  470. if (m_adwHelpIDs != NULL)
  471. {
  472. ::WinHelp(m_hWnd,
  473. c_szNetCfgHelpFile,
  474. HELP_CONTEXTMENU,
  475. (ULONG_PTR)m_adwHelpIDs);
  476. }
  477. return 0;
  478. }
  479. //+---------------------------------------------------------------------------
  480. //
  481. // Member: CPspStatusMonitorGen::OnHelp
  482. //
  483. // Purpose: When drag context help icon over a control, bring up help
  484. //
  485. // Arguments: Standard command parameters
  486. //
  487. // Returns: Standard return
  488. //
  489. LRESULT
  490. CPspStatusMonitorGen::OnHelp(UINT uMsg,
  491. WPARAM wParam,
  492. LPARAM lParam,
  493. BOOL& fHandled)
  494. {
  495. TraceFileFunc(ttidStatMon);
  496. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  497. Assert(lphi);
  498. if ((m_adwHelpIDs != NULL) && (HELPINFO_WINDOW == lphi->iContextType))
  499. {
  500. ::WinHelp(static_cast<HWND>(lphi->hItemHandle),
  501. c_szNetCfgHelpFile,
  502. HELP_WM_HELP,
  503. (ULONG_PTR)m_adwHelpIDs);
  504. }
  505. return 0;
  506. }
  507. //+---------------------------------------------------------------------------
  508. //
  509. // Member: CPspStatusMonitorGen::OnDisconnect
  510. //
  511. // Purpose: When the disconnect button is hit, disconnect the connection
  512. // and closes the dialog
  513. //
  514. // Arguments: Standard notification parameters
  515. //
  516. // Returns: Standard return
  517. //
  518. LRESULT CPspStatusMonitorGen::OnDisconnect(WORD wNotifyCode, WORD wID,
  519. HWND hWndCtl, BOOL& fHandled)
  520. {
  521. TraceFileFunc(ttidStatMon);
  522. HRESULT hr = S_OK;
  523. switch (wNotifyCode)
  524. {
  525. case BN_CLICKED:
  526. case BN_DOUBLECLICKED:
  527. {
  528. hr = HrDisconnectConnection();
  529. }
  530. }
  531. TraceError("CPspStatusMonitorGen::OnDisconnect", hr);
  532. return 0;
  533. }
  534. //+---------------------------------------------------------------------------
  535. //
  536. // Member: CPspStatusMonitorGen::OnRaiseproperties
  537. //
  538. // Purpose: Bring up the property of this connection
  539. //
  540. // Arguments: Standard notification parameters
  541. //
  542. // Returns: Standard return
  543. //
  544. LRESULT CPspStatusMonitorGen::OnRaiseProperties(WORD wNotifyCode, WORD wID,
  545. HWND hWndCtl, BOOL& fHandled)
  546. {
  547. TraceFileFunc(ttidStatMon);
  548. HRESULT hr = S_OK;
  549. switch (wNotifyCode)
  550. {
  551. case BN_CLICKED:
  552. case BN_DOUBLECLICKED:
  553. {
  554. // Addref m_pnseStat object
  555. //
  556. AddRefObj(static_cast<INetStatisticsEngine *>(m_pnseStat));
  557. // Make sure the netshell.dll is not unloaded
  558. //
  559. HINSTANCE hInst = LoadLibrary(c_szNetShellDll);
  560. HANDLE hthrd = NULL;
  561. // Create the property sheet on a different thread
  562. //
  563. if (hInst)
  564. {
  565. DWORD dwThreadId;
  566. hthrd = CreateThread(NULL, STACK_SIZE_TINY,
  567. (LPTHREAD_START_ROUTINE)PropertyThread,
  568. (LPVOID)m_pnseStat, 0, &dwThreadId);
  569. }
  570. if (NULL != hthrd)
  571. {
  572. CloseHandle(hthrd);
  573. }
  574. else
  575. {
  576. /// Release m_pnseStat object on failure
  577. //
  578. ReleaseObj(static_cast<INetStatisticsEngine *>(m_pnseStat));
  579. // release the dll
  580. //
  581. if (hInst)
  582. FreeLibrary(hInst);
  583. hr = HrFromLastWin32Error();
  584. }
  585. }
  586. }
  587. TraceError("CPspStatusMonitorGen::OnRaiseproperties", hr);
  588. return 0;
  589. }
  590. DWORD PropertyThread(CNetStatisticsEngine * pnse)
  591. {
  592. TraceFileFunc(ttidStatMon);
  593. HRESULT hr = S_OK;
  594. BOOL fUninitCom = TRUE;
  595. // Initialize COM on this thread
  596. //
  597. hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  598. if (RPC_E_CHANGED_MODE == hr)
  599. {
  600. hr = S_OK;
  601. fUninitCom = FALSE;
  602. }
  603. if (SUCCEEDED(hr))
  604. {
  605. INetConnection* pncMonitor = NULL;
  606. // Get the INetConnection
  607. //
  608. Assert (pnse);
  609. hr = pnse->HrGetConnectionFromBlob(&pncMonitor);
  610. if (SUCCEEDED(hr))
  611. {
  612. hr = HrRaiseConnectionProperties(NULL, pncMonitor);
  613. }
  614. ReleaseObj(pncMonitor);
  615. }
  616. if (fUninitCom)
  617. {
  618. CoUninitialize();
  619. }
  620. // release input interface
  621. ReleaseObj(static_cast<INetStatisticsEngine *>(pnse));
  622. // release the library we loaded
  623. FreeLibraryAndExitThread(GetModuleHandle(c_szNetShellDll), hr);
  624. TraceError("PropertyThread", hr);
  625. return 1;
  626. }
  627. //+---------------------------------------------------------------------------
  628. //
  629. // Member: CPspStatusMonitorGen::HrDisconnectConnection
  630. //
  631. // Purpose: disconnect the connection and closes the dialog if succeeded
  632. //
  633. // Arguments: fConfirmed TRUE if the user has confirmed to disconnect the connection
  634. //
  635. // Returns: Standard return
  636. //
  637. HRESULT CPspStatusMonitorGen::HrDisconnectConnection(BOOL fConfirmed)
  638. {
  639. TraceFileFunc(ttidStatMon);
  640. HRESULT hr;
  641. Assert (m_pnseStat);
  642. // Get the INetConnection
  643. //
  644. INetConnection* pncMonitor;
  645. hr = m_pnseStat->HrGetConnectionFromBlob(&pncMonitor);
  646. if (SUCCEEDED(hr))
  647. {
  648. PCONFOLDPIDL pidlConnection;
  649. hr = HrCreateConFoldPidl(WIZARD_NOT_WIZARD, pncMonitor, pidlConnection);
  650. if (SUCCEEDED(hr))
  651. {
  652. CONFOLDENTRY ccfe;
  653. hr = pidlConnection.ConvertToConFoldEntry(ccfe);
  654. if (SUCCEEDED(hr))
  655. {
  656. // Get the pidl for the Connections Folder
  657. //
  658. PCONFOLDPIDLFOLDER pidlFolder;
  659. hr = HrGetConnectionsFolderPidl(pidlFolder);
  660. if (SUCCEEDED(hr))
  661. {
  662. // Get the Connections Folder object
  663. //
  664. LPSHELLFOLDER psfConnections;
  665. hr = HrGetConnectionsIShellFolder(pidlFolder, &psfConnections);
  666. if (SUCCEEDED(hr))
  667. {
  668. hr = HrOnCommandDisconnectInternal(ccfe,
  669. m_hWnd,
  670. psfConnections);
  671. ReleaseObj(psfConnections);
  672. }
  673. }
  674. }
  675. }
  676. // release INetConnection interface
  677. ReleaseObj(pncMonitor);
  678. }
  679. // If anything above failed.
  680. //
  681. if (SUCCEEDED(hr))
  682. {
  683. if (S_OK == hr)
  684. {
  685. // close the property sheet
  686. HWND hwndPS = ::GetParent(m_hWnd);
  687. // Push the Close ("Cancel") button to close dialog
  688. //
  689. ::PostMessage(hwndPS, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0),
  690. (LPARAM)::GetDlgItem(hwndPS, IDCANCEL));
  691. }
  692. else
  693. {
  694. // Disconnect confirmation canceled. Do nothing (don't close
  695. // statmon, anyway).
  696. //
  697. AssertSz(S_FALSE == hr, "Disconnect != S_OK or S_FALSE, but succeeded? What is it then?");
  698. }
  699. }
  700. else
  701. {
  702. TraceError("pncMonitor->Disconnect", hr);
  703. // Warn the user and don't close if we couldn't disconnect
  704. //
  705. ::NcMsgBox( m_hWnd,
  706. IDS_SM_ERROR_CAPTION,
  707. IDS_SM_ERROR_CANNOT_DISCONNECT,
  708. MB_ICONWARNING);
  709. }
  710. TraceError("CPspStatusMonitorGen::HrDisconnectConnection", hr);
  711. return hr;
  712. }
  713. //+---------------------------------------------------------------------------
  714. //
  715. // Member: CPspStatusMonitorGen::OnSetCursor
  716. //
  717. // Purpose: Ensure the mouse cursor over the Property Sheet is an Arrow.
  718. //
  719. // Arguments: Standard command parameters
  720. //
  721. // Returns: Standard return
  722. //
  723. LRESULT
  724. CPspStatusMonitorGen::OnSetCursor (
  725. UINT uMsg,
  726. WPARAM wParam,
  727. LPARAM lParam,
  728. BOOL& bHandled)
  729. {
  730. TraceFileFunc(ttidStatMon);
  731. if (LOWORD(lParam) == HTCLIENT)
  732. {
  733. SetCursor(LoadCursor(NULL, IDC_ARROW));
  734. }
  735. return FALSE;
  736. }
  737. LRESULT
  738. CPspStatusMonitorGen::OnTimer (
  739. UINT uMsg,
  740. WPARAM wParam,
  741. LPARAM lParam,
  742. BOOL& bHandled)
  743. {
  744. TraceFileFunc(ttidStatMon);
  745. // Prevent same-thread re-entrancy. Any Win32 call made while
  746. // processing this event that return control to the message
  747. // loop may cause this timer to fire again.
  748. //
  749. if (!m_fProcessingTimerEvent)
  750. {
  751. m_fProcessingTimerEvent = TRUE;
  752. // If we're within 200 milliseconds of the last time we updated the
  753. // status display, don't bother doing it again. This covers the case
  754. // where our timer coincides with the timer in smcent which would
  755. // would cause us to update the status display twice in rapid
  756. // succession each time the timers fire.
  757. //
  758. DWORD dwTick = GetTickCount ();
  759. if (dwTick > m_dwLastUpdateStatusDisplayTick + 200)
  760. {
  761. OnUpdateStatusDisplay (uMsg, 0, m_dwChangeFlags, bHandled);
  762. }
  763. m_fProcessingTimerEvent = FALSE;
  764. }
  765. return 0;
  766. }
  767. LRESULT
  768. CPspStatusMonitorGen::OnUpdateStatusDisplay(
  769. UINT uMsg,
  770. WPARAM wParam,
  771. LPARAM lParam,
  772. BOOL& bHandled)
  773. {
  774. TraceFileFunc(ttidStatMon);
  775. HRESULT hr = S_OK;
  776. DWORD dwChangeFlags = lParam;
  777. // We may be in the process of disconnecting the statistics page in
  778. // which case m_dwConPointCookie will be zero.
  779. //
  780. if (m_dwConPointCookie)
  781. {
  782. Assert (m_psmEngineData);
  783. STATMON_ENGINEDATA* psmNewData = NULL;
  784. hr = m_pnseStat->GetStatistics(&psmNewData);
  785. if (SUCCEEDED(hr) && psmNewData)
  786. {
  787. if (m_psmEngineData)
  788. {
  789. //
  790. // Display the new stats
  791. //
  792. UpdatePage(m_psmEngineData, psmNewData);
  793. // Update the icon image
  794. //
  795. UpdatePageIcon(dwChangeFlags);
  796. UpdateSignalStrengthIcon(psmNewData->SMED_802_11_SIGNAL_STRENGTH);
  797. // Note the clock tick of when we last updated
  798. // the status display.
  799. //
  800. m_dwLastUpdateStatusDisplayTick = GetTickCount();
  801. // Replace the old data with the new
  802. //
  803. CoTaskMemFree(m_psmEngineData);
  804. }
  805. m_psmEngineData = psmNewData;
  806. }
  807. }
  808. else
  809. {
  810. TraceTag (ttidStatMon,
  811. "CPspStatusMonitorGen::OnStatisticsChanged called but we've "
  812. "been closed. Ignoring.");
  813. }
  814. TraceError("CPspStatusMonitorGen::OnUpdateStatusDisplay", hr);
  815. return 0;
  816. }
  817. //+---------------------------------------------------------------------------
  818. //
  819. // Member: CPspStatusMonitorGen::OnStatisticsChanged
  820. //
  821. // Purpose: This is the callback that tell the property page that the
  822. // data on the page has changed
  823. //
  824. // Arguments: dwCookie - The cookie of the connection that has changed
  825. // dwChangeFlags - What has changed
  826. //
  827. // Returns: Error code
  828. //
  829. STDMETHODIMP
  830. CPspStatusMonitorGen::OnStatisticsChanged(
  831. DWORD dwChangeFlags)
  832. {
  833. TraceFileFunc(ttidStatMon);
  834. ::PostMessage (m_hWnd, PWM_UPDATE_STATUS_DISPLAY, 0, dwChangeFlags);
  835. return S_OK;
  836. }
  837. //+---------------------------------------------------------------------------
  838. //
  839. // Member: CPspStatusMonitorGen::UpdatePage
  840. //
  841. // Purpose: Fill the fields on the page with new data
  842. //
  843. // Arguments: pseOldData - The old stats being displayed on the page
  844. // pseNewData - The new stats being displayed on the page
  845. //
  846. // Returns: Nothing
  847. //
  848. VOID
  849. CPspStatusMonitorGen::UpdatePage (
  850. STATMON_ENGINEDATA* pseOldData,
  851. const STATMON_ENGINEDATA* pseNewData)
  852. {
  853. TraceFileFunc(ttidStatMon);
  854. AssertSz(pseOldData, "We don't have a puiOld");
  855. AssertSz(pseNewData, "We don't have a puiNew");
  856. //
  857. // Update the dialog fields
  858. //
  859. UpdatePageConnectionStatus(pseOldData, pseNewData);
  860. UpdatePageDuration(pseOldData, pseNewData);
  861. UpdatePageSpeed(pseOldData, pseNewData);
  862. // If the StatMon is not getting any bytes (a common problem with net
  863. // cards), display packets instead
  864. //
  865. if (ShouldShowPackets(pseNewData))
  866. {
  867. // Only change the label if we have to
  868. //
  869. if (Stat_Packets != m_iStatTrans)
  870. {
  871. SetDlgItemText(IDC_TXT_SM_BYTES_LABEL, ::SzLoadIds(IDS_SM_PACKETS));
  872. m_iStatTrans = Stat_Packets;
  873. // Force a refresh
  874. //
  875. pseOldData->SMED_PACKETSTRANSMITTING = 0;
  876. pseOldData->SMED_PACKETSRECEIVING = 0;
  877. }
  878. UpdatePageBytesTransmitting(pseOldData, pseNewData, Stat_Packets);
  879. UpdatePageBytesReceiving(pseOldData, pseNewData, Stat_Packets);
  880. }
  881. else
  882. {
  883. // Only change the label if we have to
  884. //
  885. if (Stat_Bytes != m_iStatTrans)
  886. {
  887. SetDlgItemText(IDC_TXT_SM_BYTES_LABEL, ::SzLoadIds(IDS_SM_BYTES));
  888. m_iStatTrans = Stat_Bytes;
  889. // Force a refresh
  890. //
  891. pseOldData->SMED_BYTESTRANSMITTING = 0;
  892. pseOldData->SMED_BYTESRECEIVING = 0;
  893. }
  894. UpdatePageBytesTransmitting(pseOldData, pseNewData, Stat_Bytes);
  895. UpdatePageBytesReceiving(pseOldData, pseNewData, Stat_Bytes);
  896. }
  897. UpdatePageCompTransmitting(pseOldData, pseNewData);
  898. UpdatePageCompReceiving(pseOldData, pseNewData);
  899. UpdatePageErrorsTransmitting(pseOldData, pseNewData);
  900. UpdatePageErrorsReceiving(pseOldData, pseNewData);
  901. }
  902. //+---------------------------------------------------------------------------
  903. //
  904. // Member: CPspStatusMonitorGen::ShouldShowPackets
  905. //
  906. // Purpose: Decided whether to show bytes or packets
  907. //
  908. // Arguments: pseNewData - The new stats being displayed on the page
  909. //
  910. // Returns: Nothing
  911. //
  912. BOOL CPspStatusMonitorGen::ShouldShowPackets(const STATMON_ENGINEDATA* pseNewData)
  913. {
  914. TraceFileFunc(ttidStatMon);
  915. return (0 == pseNewData->SMED_BYTESTRANSMITTING) && (0 == pseNewData->SMED_BYTESRECEIVING);
  916. }
  917. //+---------------------------------------------------------------------------
  918. //
  919. // Member: CPspStatusMonitorGen::UpdatePageSpeed
  920. //
  921. // Purpose: Updates the speed display on the general page
  922. //
  923. // Arguments: pseOldData - The old stats being displayed on the page
  924. // pseNewData - The new stats being displayed on the page
  925. //
  926. // Returns: Nothing
  927. //
  928. VOID
  929. CPspStatusMonitorGen::UpdatePageSpeed(
  930. const STATMON_ENGINEDATA* pseOldData,
  931. const STATMON_ENGINEDATA* pseNewData)
  932. {
  933. TraceFileFunc(ttidStatMon);
  934. AssertSz(pseOldData, "We don't have a pseOldData");
  935. AssertSz(pseNewData, "We don't have a pseNewData");
  936. // Get the data and see if either is different
  937. //
  938. if ((pseOldData->SMED_SPEEDTRANSMITTING != pseNewData->SMED_SPEEDTRANSMITTING)
  939. || (pseOldData->SMED_SPEEDRECEIVING != pseNewData->SMED_SPEEDRECEIVING))
  940. {
  941. WCHAR achBuffer[MAX_PATH];
  942. FormatTransmittingReceivingSpeed (
  943. pseNewData->SMED_SPEEDTRANSMITTING,
  944. pseNewData->SMED_SPEEDRECEIVING,
  945. achBuffer);
  946. // Set the control text.
  947. //
  948. SetDlgItemText(IDC_TXT_SM_SPEED, achBuffer);
  949. }
  950. }
  951. //+---------------------------------------------------------------------------
  952. //
  953. // Member: CPspStatusMonitorGen::UpdatePageConnectionStatus
  954. //
  955. // Purpose: Update the connections field on the property page
  956. //
  957. // Arguments: puiOldData - The old stats being displayed on the page
  958. // puiNewData - The new stats being displayed on the page
  959. //
  960. // Returns: Nothing
  961. //
  962. VOID
  963. CPspStatusMonitorGen::UpdatePageConnectionStatus(
  964. const STATMON_ENGINEDATA* pseOldData,
  965. const STATMON_ENGINEDATA* pseNewData)
  966. {
  967. TraceFileFunc(ttidStatMon);
  968. AssertSz(pseOldData, "We don't have a pseOldData");
  969. AssertSz(pseNewData, "We don't have a pseNewdata");
  970. // Update the Connection Status
  971. //
  972. if ((pseNewData->SMED_CONNECTIONSTATUS == NCS_DISCONNECTED) ||
  973. (pseOldData->SMED_CONNECTIONSTATUS != pseNewData->SMED_CONNECTIONSTATUS))
  974. {
  975. INT idsConnection = IDS_SM_CS_DISCONNECTED;
  976. // Make sure our strings are still intact
  977. AssertSz((((IDS_SM_CS_DISCONNECTED + 1) == IDS_SM_CS_CONNECTING)
  978. && ((IDS_SM_CS_DISCONNECTED + 2) == IDS_SM_CS_CONNECTED)
  979. && ((IDS_SM_CS_DISCONNECTED + 3) == IDS_SM_CS_DISCONNECTING)
  980. && ((IDS_SM_CS_DISCONNECTED + 4) == IDS_SM_CS_HARDWARE_NOT_PRESENT)
  981. && ((IDS_SM_CS_DISCONNECTED + 5) == IDS_SM_CS_HARDWARE_DISABLED)
  982. && ((IDS_SM_CS_DISCONNECTED + 6) == IDS_SM_CS_HARDWARE_MALFUNCTION)),
  983. "Some one has been messing with connection status strings");
  984. idsConnection = (IDS_SM_CS_DISCONNECTED
  985. + pseNewData->SMED_CONNECTIONSTATUS);
  986. if (idsConnection == IDS_SM_CS_DISCONNECTED)
  987. {
  988. // close the property sheet
  989. HWND hwndPS = ::GetParent(m_hWnd);
  990. TraceTag(ttidStatMon, "Closing Status Monitor page because status was: DISCONNECTED");
  991. // Push the Close ("Cancel") button to close dialog
  992. //
  993. ::PostMessage(hwndPS, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0),
  994. (LPARAM)::GetDlgItem(hwndPS, IDCANCEL));
  995. }
  996. else
  997. {
  998. SetDlgItemText(IDC_TXT_SM_STATUS, ::SzLoadIds(idsConnection));
  999. }
  1000. }
  1001. }
  1002. //+---------------------------------------------------------------------------
  1003. //
  1004. // Member: CPspStatusMonitorGen::UpdatePageIcon
  1005. //
  1006. // Purpose: Update the icon on the property page
  1007. //
  1008. // Arguments: dwChangeFlags - The new changed state
  1009. //
  1010. // Returns: Nothing
  1011. //
  1012. VOID
  1013. CPspStatusMonitorGen::UpdatePageIcon (
  1014. DWORD dwChangeFlags)
  1015. {
  1016. TraceFileFunc(ttidStatMon);
  1017. // If either of these have changed, change the icon
  1018. // so we'll know to update the icon
  1019. //
  1020. if (((SMDCF_TRANSMITTING | SMDCF_RECEIVING) & m_dwChangeFlags)
  1021. != ((SMDCF_TRANSMITTING | SMDCF_RECEIVING) & dwChangeFlags))
  1022. {
  1023. HICON hStatusIcon = 0;
  1024. HWND hwndIcon = NULL;
  1025. // Get the new icon
  1026. //
  1027. hStatusIcon = GetCurrentConnectionStatusIconId(m_ncmType, m_ncsmType, m_dwCharacter, dwChangeFlags);
  1028. if (hStatusIcon)
  1029. {
  1030. hwndIcon = ::GetDlgItem(m_hWnd, IDI_SM_STATUS_ICON);
  1031. // Set the icon to the new one
  1032. //
  1033. HICON hOldIcon = reinterpret_cast<HICON>(::SendMessage(
  1034. hwndIcon,
  1035. STM_SETICON,
  1036. (WPARAM)hStatusIcon,
  1037. 0));
  1038. DestroyIcon(hOldIcon);
  1039. }
  1040. }
  1041. // Keep the flags for the next update
  1042. //
  1043. m_dwChangeFlags = dwChangeFlags;
  1044. }
  1045. //+---------------------------------------------------------------------------
  1046. //
  1047. // Member: CPspStatusMonitorGen::UpdateSignalStrengthIcon
  1048. //
  1049. // Purpose: Update the icon on the property page
  1050. //
  1051. // Arguments: iRSSI - The new signal strenghth
  1052. //
  1053. // Returns: Nothing
  1054. //
  1055. inline
  1056. VOID
  1057. CPspStatusMonitorGen::UpdateSignalStrengthIcon (
  1058. INT iRSSI)
  1059. {
  1060. TraceFileFunc(ttidStatMon);
  1061. if (0 == iRSSI)
  1062. {
  1063. if (0 != m_iLastSignalStrength)
  1064. {
  1065. ::ShowWindow(::GetDlgItem(m_hWnd, IDC_TXT_SM_SIGNAL_STRENGTH), SW_HIDE);
  1066. ::ShowWindow(::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON), SW_HIDE);
  1067. }
  1068. m_iLastSignalStrength = iRSSI;
  1069. return;
  1070. }
  1071. else
  1072. {
  1073. if (0 == m_iLastSignalStrength)
  1074. {
  1075. ::ShowWindow(::GetDlgItem(m_hWnd, IDC_TXT_SM_SIGNAL_STRENGTH), SW_SHOW);
  1076. ::ShowWindow(::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON), SW_SHOW);
  1077. }
  1078. }
  1079. INT idStatusIcon = 0;
  1080. m_iLastSignalStrength = iRSSI;
  1081. // Get the new icon
  1082. //
  1083. idStatusIcon = IDI_802_11_LEVEL0 + MapRSSIToWirelessSignalStrength(iRSSI);
  1084. HWND hwndSignalStrength = ::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON);
  1085. Assert(hwndSignalStrength);
  1086. if (hwndSignalStrength)
  1087. {
  1088. HDC hdcSignalStrength = ::GetDC(hwndSignalStrength);
  1089. Assert(hdcSignalStrength);
  1090. if (hdcSignalStrength)
  1091. {
  1092. HICON hIconSignalStrength = LoadIconTile(_Module.GetResourceInstance(), MAKEINTRESOURCE(idStatusIcon));
  1093. Assert(hIconSignalStrength);
  1094. if (hIconSignalStrength)
  1095. {
  1096. ::DrawIconEx(hdcSignalStrength, 0, 0, hIconSignalStrength, 48, 48, 0, NULL, DI_IMAGE | DI_MASK);
  1097. DestroyIcon(hIconSignalStrength);
  1098. }
  1099. ::ReleaseDC(hwndSignalStrength, hdcSignalStrength);
  1100. }
  1101. }
  1102. }
  1103. //+---------------------------------------------------------------------------
  1104. //
  1105. // Member: CPspStatusMonitorGen::UpdateSignalStrengthIcon
  1106. //
  1107. // Purpose: Update the icon on the property page
  1108. //
  1109. // Arguments: iRSSI - The new signal strenghth
  1110. //
  1111. // Returns: Nothing
  1112. //
  1113. LRESULT CPspStatusMonitorGen::OnPaint (
  1114. UINT uMsg,
  1115. WPARAM wParam,
  1116. LPARAM lParam,
  1117. BOOL& bHandled)
  1118. {
  1119. TraceFileFunc(ttidStatMon);
  1120. PAINTSTRUCT ps;
  1121. BeginPaint(&ps);
  1122. UpdateSignalStrengthIcon(m_iLastSignalStrength);
  1123. EndPaint(&ps);
  1124. bHandled = TRUE;
  1125. return 0;
  1126. }
  1127. //+---------------------------------------------------------------------------
  1128. //
  1129. // Member: CPspStatusMonitorGen::UpdatePageDuration
  1130. //
  1131. // Purpose: Updates the duration display on the general page
  1132. //
  1133. // Arguments: pseOldData - The old stats being displayed on the page
  1134. // pseNewData - The new stats being displayed on the page
  1135. //
  1136. // Returns: Nothing
  1137. //
  1138. VOID
  1139. CPspStatusMonitorGen::UpdatePageDuration(
  1140. const STATMON_ENGINEDATA* pseOldData,
  1141. const STATMON_ENGINEDATA* pseNewData)
  1142. {
  1143. TraceFileFunc(ttidStatMon);
  1144. AssertSz(pseOldData, "We don't have a pseOldData");
  1145. AssertSz(pseNewData, "We don't have a pseNewData");
  1146. // Get the see if either is different
  1147. //
  1148. if (pseOldData->SMED_DURATION != pseNewData->SMED_DURATION)
  1149. {
  1150. tstring strDuration;
  1151. // Format the time duration as a string
  1152. //
  1153. FormatTimeDuration(pseNewData->SMED_DURATION, &strDuration);
  1154. // Set the control
  1155. //
  1156. SetDlgItemText(IDC_TXT_SM_DURATION, strDuration.c_str());
  1157. }
  1158. }
  1159. //+---------------------------------------------------------------------------
  1160. //
  1161. // Member: CPspStatusMonitorGen::UpdatePageBytesTransmitting
  1162. //
  1163. // Purpose: Updates the bytes Transmitting display on the general page
  1164. //
  1165. // Arguments: pseOldData - The old stats being displayed on the page
  1166. // pseNewData - The new stats being displayed on the page
  1167. // iStat - The which stats to display
  1168. //
  1169. // Returns: Nothing
  1170. //
  1171. VOID
  1172. CPspStatusMonitorGen::UpdatePageBytesTransmitting(
  1173. const STATMON_ENGINEDATA* pseOldData,
  1174. const STATMON_ENGINEDATA* pseNewData,
  1175. StatTrans iStat)
  1176. {
  1177. TraceFileFunc(ttidStatMon);
  1178. AssertSz(pseOldData, "We don't have a pseOldData");
  1179. AssertSz(pseNewData, "We don't have a pseNewData");
  1180. AssertSz(((Stat_Packets == iStat) || (Stat_Bytes == iStat)), "We have an invalid iStat");
  1181. UINT64 ui64Old;
  1182. UINT64 ui64New;
  1183. if (Stat_Bytes == iStat)
  1184. {
  1185. ui64Old = pseOldData->SMED_BYTESTRANSMITTING;
  1186. ui64New = pseNewData->SMED_BYTESTRANSMITTING;
  1187. }
  1188. else
  1189. {
  1190. ui64Old = pseOldData->SMED_PACKETSTRANSMITTING;
  1191. ui64New = pseNewData->SMED_PACKETSTRANSMITTING;
  1192. }
  1193. // See if either is different
  1194. //
  1195. if (ui64Old != ui64New)
  1196. {
  1197. SetDlgItemFormatted64bitInteger(
  1198. m_hWnd,
  1199. IDC_TXT_SM_BYTES_TRANS,
  1200. ui64New, FALSE);
  1201. }
  1202. }
  1203. //+---------------------------------------------------------------------------
  1204. //
  1205. // Member: CPspStatusMonitorGen::UpdatePageBytesReceiving
  1206. //
  1207. // Purpose: Updates the bytes receiving display on the general page
  1208. //
  1209. // Arguments: puiOld - The old stats being displayed on the page
  1210. // puiNew - The new stats being displayed on the page
  1211. // iStat - The which stats to display
  1212. //
  1213. // Returns: Nothing
  1214. //
  1215. VOID
  1216. CPspStatusMonitorGen::UpdatePageBytesReceiving(
  1217. const STATMON_ENGINEDATA* pseOldData,
  1218. const STATMON_ENGINEDATA* pseNewData,
  1219. StatTrans iStat)
  1220. {
  1221. TraceFileFunc(ttidStatMon);
  1222. AssertSz(pseOldData, "We don't have a puiOld");
  1223. AssertSz(pseNewData, "We don't have a puiNew");
  1224. AssertSz(((Stat_Packets == iStat) || (Stat_Bytes == iStat)), "We have an invalid iStat");
  1225. UINT64 ui64Old;
  1226. UINT64 ui64New;
  1227. if (Stat_Bytes == iStat)
  1228. {
  1229. ui64Old = pseOldData->SMED_BYTESRECEIVING;
  1230. ui64New = pseNewData->SMED_BYTESRECEIVING;
  1231. }
  1232. else
  1233. {
  1234. ui64Old = pseOldData->SMED_PACKETSRECEIVING;
  1235. ui64New = pseNewData->SMED_PACKETSRECEIVING;
  1236. }
  1237. // See if either is different
  1238. //
  1239. if (ui64Old != ui64New)
  1240. {
  1241. SetDlgItemFormatted64bitInteger(
  1242. m_hWnd,
  1243. IDC_TXT_SM_BYTES_RCVD,
  1244. ui64New, FALSE);
  1245. }
  1246. }
  1247. //+---------------------------------------------------------------------------
  1248. //
  1249. // Member: CPspStatusMonitorGen::UpdatePageCompTransmitting
  1250. //
  1251. // Purpose: Updates the compression transmitting display on the general
  1252. // page
  1253. //
  1254. // Arguments: pseOldData - The old stats being displayed on the page
  1255. // pseNewData - The new stats being displayed on the page
  1256. //
  1257. // Returns: Nothing
  1258. //
  1259. VOID
  1260. CPspStatusMonitorGen::UpdatePageCompTransmitting(
  1261. const STATMON_ENGINEDATA* pseOldData,
  1262. const STATMON_ENGINEDATA* pseNewData)
  1263. {
  1264. TraceFileFunc(ttidStatMon);
  1265. AssertSz(pseOldData, "We don't have a pseOldData");
  1266. AssertSz(pseNewData, "We don't have a pseNewData");
  1267. // See if either is different
  1268. //
  1269. if (pseOldData->SMED_COMPRESSIONTRANSMITTING
  1270. != pseNewData->SMED_COMPRESSIONTRANSMITTING)
  1271. {
  1272. WCHAR achBuf[20];
  1273. CompressionToSz(pseNewData->SMED_COMPRESSIONTRANSMITTING, achBuf);
  1274. SetDlgItemText(IDC_TXT_SM_COMP_TRANS, achBuf);
  1275. }
  1276. }
  1277. //+---------------------------------------------------------------------------
  1278. //
  1279. // Member: CPspStatusMonitorGen::UpdatePageCompReceiving
  1280. //
  1281. // Purpose: Updates the compression receiving display on the general page
  1282. //
  1283. // Arguments: pseOldData - The old stats being displayed on the page
  1284. // pseNewData - The new stats being displayed on the page
  1285. //
  1286. // Returns: Nothing
  1287. //
  1288. VOID
  1289. CPspStatusMonitorGen::UpdatePageCompReceiving(
  1290. const STATMON_ENGINEDATA* pseOldData,
  1291. const STATMON_ENGINEDATA* pseNewData)
  1292. {
  1293. TraceFileFunc(ttidStatMon);
  1294. AssertSz(pseOldData, "We don't have a puiOld");
  1295. AssertSz(pseNewData, "We don't have a puiNew");
  1296. // see if either is different
  1297. //
  1298. if (pseOldData->SMED_COMPRESSIONRECEIVING != pseNewData->SMED_COMPRESSIONRECEIVING)
  1299. {
  1300. WCHAR achBuf[20];
  1301. CompressionToSz(pseNewData->SMED_COMPRESSIONRECEIVING, achBuf);
  1302. SetDlgItemText(IDC_TXT_SM_COMP_RCVD, achBuf);
  1303. }
  1304. }
  1305. //+---------------------------------------------------------------------------
  1306. //
  1307. // Member: CPspStatusMonitorGen::UpdatePageErrorsTransmitting
  1308. //
  1309. // Purpose: Updates the compression transmitting display on the general
  1310. // page
  1311. //
  1312. // Arguments: pseOldData - The old stats being displayed on the page
  1313. // pseNewData - The new stats being displayed on the page
  1314. //
  1315. // Returns: Nothing
  1316. //
  1317. VOID
  1318. CPspStatusMonitorGen::UpdatePageErrorsTransmitting(
  1319. const STATMON_ENGINEDATA* pseOldData,
  1320. const STATMON_ENGINEDATA* pseNewData)
  1321. {
  1322. TraceFileFunc(ttidStatMon);
  1323. AssertSz(pseOldData, "We don't have a pseOldData");
  1324. AssertSz(pseNewData, "We don't have a pseNewData");
  1325. // See if either is different
  1326. //
  1327. if (pseOldData->SMED_ERRORSTRANSMITTING
  1328. != pseNewData->SMED_ERRORSTRANSMITTING)
  1329. {
  1330. SetDlgItemFormatted32bitInteger (
  1331. m_hWnd,
  1332. IDC_TXT_SM_ERROR_TRANS,
  1333. pseNewData->SMED_ERRORSTRANSMITTING,
  1334. FALSE);
  1335. }
  1336. }
  1337. //+---------------------------------------------------------------------------
  1338. //
  1339. // Member: CPspStatusMonitorGen::UpdatePageErrorsReceiving
  1340. //
  1341. // Purpose: Updates the compression receiving display on the general page
  1342. //
  1343. // Arguments: pseOldData - The old stats being displayed on the page
  1344. // pseNewData - The new stats being displayed on the page
  1345. //
  1346. // Returns: Nothing
  1347. //
  1348. VOID
  1349. CPspStatusMonitorGen::UpdatePageErrorsReceiving(
  1350. const STATMON_ENGINEDATA* pseOldData,
  1351. const STATMON_ENGINEDATA* pseNewData)
  1352. {
  1353. TraceFileFunc(ttidStatMon);
  1354. AssertSz(pseOldData, "We don't have a pseOldData");
  1355. AssertSz(pseNewData, "We don't have a pseNewData");
  1356. // see if either is different
  1357. //
  1358. if (pseOldData->SMED_ERRORSRECEIVING != pseNewData->SMED_ERRORSRECEIVING)
  1359. {
  1360. SetDlgItemFormatted32bitInteger (
  1361. m_hWnd,
  1362. IDC_TXT_SM_ERROR_RECV,
  1363. pseNewData->SMED_ERRORSRECEIVING,
  1364. FALSE);
  1365. }
  1366. }
  1367. //+---------------------------------------------------------------------------
  1368. //
  1369. // Function: CompressionToSz
  1370. //
  1371. // Purpose: To format nicely BPS into a readable string
  1372. //
  1373. // Arguments: uiCompression - The amount of compression
  1374. // pchBuffer - The Buffer to receive the string
  1375. //
  1376. // Returns: Nothing
  1377. //
  1378. VOID
  1379. CompressionToSz (
  1380. UINT uiCompression,
  1381. WCHAR* pchBuffer)
  1382. {
  1383. TraceFileFunc(ttidStatMon);
  1384. AssertSz((((INT)uiCompression >= 0) && ((INT)uiCompression <= 100)),
  1385. "Invalid compression");
  1386. wsprintfW(pchBuffer, L"%lu %%", uiCompression);
  1387. }
  1388. //+---------------------------------------------------------------------------
  1389. //
  1390. // Function: FIsShowLanErrorRegKeySet
  1391. //
  1392. // Purpose: Check if the registry key is set:
  1393. // System\CurrentControlSet\Control\Network\Connections\StatMon\ShowLanErrors
  1394. //
  1395. // Arguments:
  1396. //
  1397. // Returns: Nothing
  1398. //
  1399. BOOL CPspStatusMonitorGen::FIsShowLanErrorRegKeySet()
  1400. {
  1401. TraceFileFunc(ttidStatMon);
  1402. BOOL fRet = FALSE;
  1403. HKEY hkeyStatmonRoot = NULL;
  1404. HRESULT hr = S_OK;
  1405. // "System\\CurrentControlSet\\Control\\Network\\Connections\\StatMon\\ShowLanErrors"
  1406. hr = ::HrRegOpenKeyEx(
  1407. HKEY_LOCAL_MACHINE,
  1408. c_szRegKeyStatmonRoot,
  1409. KEY_READ,
  1410. &hkeyStatmonRoot);
  1411. if (SUCCEEDED(hr))
  1412. {
  1413. Assert(hkeyStatmonRoot);
  1414. DWORD dwValue =0;
  1415. hr = HrRegQueryDword(hkeyStatmonRoot, c_szShowLanErrors, &dwValue);
  1416. if SUCCEEDED(hr)
  1417. {
  1418. fRet = !!dwValue;
  1419. }
  1420. RegCloseKey(hkeyStatmonRoot);
  1421. }
  1422. return fRet;
  1423. }