1667 lines
44 KiB
C++
1667 lines
44 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1998.
|
||
|
//
|
||
|
// File: S M G E N P S P . C P P
|
||
|
//
|
||
|
// Contents: The rendering of the UI for the network status monitor.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// Author: CWill 6 Oct 1997
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "foldinc.h"
|
||
|
|
||
|
#include "ncatlui.h"
|
||
|
#include "ncnetcon.h"
|
||
|
#include "ncperms.h"
|
||
|
#include "ncui.h"
|
||
|
#include "ncreg.h"
|
||
|
#include "nsres.h"
|
||
|
#include "sminc.h"
|
||
|
#include "smpsh.h"
|
||
|
#include "windutil.h"
|
||
|
|
||
|
#include "conprops.h"
|
||
|
#include "oncommand.h"
|
||
|
|
||
|
#include "pidlutil.h"
|
||
|
|
||
|
#include "openfold.h"
|
||
|
#include "..\folder\confold.h"
|
||
|
#include "cfpidl.h"
|
||
|
|
||
|
DWORD MapRSSIToWirelessSignalStrength(int iRSSI);
|
||
|
PCWSTR PszGetRSSIString(int iRSSI);
|
||
|
|
||
|
//
|
||
|
// Function Prototypes
|
||
|
//
|
||
|
|
||
|
VOID CompressionToSz(UINT uiCompression, WCHAR* pchbuffer);
|
||
|
|
||
|
//
|
||
|
// Common Strings
|
||
|
//
|
||
|
extern const WCHAR c_szNetShellDll[];
|
||
|
|
||
|
//
|
||
|
// Constants
|
||
|
//
|
||
|
|
||
|
const UINT c_unLocalRefreshTimerID = 817;
|
||
|
|
||
|
//
|
||
|
// ShowLanErrors
|
||
|
//
|
||
|
static const WCHAR c_szRegKeyStatmonRoot[] = L"System\\CurrentControlSet\\Control\\Network\\Connections\\StatMon";
|
||
|
static const WCHAR c_szShowLanErrors[] = L"ShowLanErrors";
|
||
|
|
||
|
// forward declaration
|
||
|
DWORD PropertyThread(CNetStatisticsEngine * pnse);
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::CPspStatusMonitorGen
|
||
|
//
|
||
|
// Purpose: Creator
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Nil
|
||
|
//
|
||
|
CPspStatusMonitorGen::CPspStatusMonitorGen() :
|
||
|
m_psmEngineData(NULL),
|
||
|
m_pnseStat(NULL),
|
||
|
m_dwConPointCookie(0),
|
||
|
m_fStats(FALSE),
|
||
|
m_ncmType(NCM_LAN),
|
||
|
m_ncsmType(NCSM_LAN),
|
||
|
m_dwCharacter(0),
|
||
|
m_dwLastUpdateStatusDisplayTick(0),
|
||
|
m_fProcessingTimerEvent(FALSE),
|
||
|
m_fIsFirstPage(FALSE),
|
||
|
m_iLastSignalStrength(-100)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::FinalRelease
|
||
|
//
|
||
|
// Purpose: Called after last Release.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Nil
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::FinalRelease(VOID)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
(VOID) HrCleanupGenPage();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::HrInitGenPage
|
||
|
//
|
||
|
// Purpose: Before the property page is populated, we have to make sure
|
||
|
// that we have some of the required data. This method
|
||
|
// initializes the page so that it is ready to be shown.
|
||
|
//
|
||
|
// Arguments: pnseNew - The statistics engine associated with this page
|
||
|
// pncNew - The connection the page is being created for
|
||
|
//
|
||
|
// Returns: Error code
|
||
|
//
|
||
|
HRESULT
|
||
|
CPspStatusMonitorGen::HrInitGenPage (
|
||
|
CNetStatisticsEngine* pnseNew,
|
||
|
INetConnection* pncNew,
|
||
|
const DWORD * adwHelpIDs)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
INetStatisticsEngine* pnseInter = pnseNew;
|
||
|
|
||
|
AssertSz(pnseNew, "We don't have a pnseNew");
|
||
|
|
||
|
// Set context help ID
|
||
|
m_adwHelpIDs = adwHelpIDs;
|
||
|
|
||
|
// Initialize the engine data
|
||
|
//
|
||
|
AssertSz(!m_psmEngineData, "We should't have a m_psmEngineData");
|
||
|
|
||
|
DWORD dwBytes = sizeof(STATMON_ENGINEDATA);
|
||
|
PVOID pbBuf;
|
||
|
hr = HrCoTaskMemAlloc(dwBytes, &pbBuf);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
m_psmEngineData = reinterpret_cast<STATMON_ENGINEDATA *>(pbBuf);
|
||
|
ZeroMemory(m_psmEngineData, sizeof(STATMON_ENGINEDATA));
|
||
|
}
|
||
|
|
||
|
// Advise the interface
|
||
|
//
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IConnectionPoint* pcpStat = NULL;
|
||
|
|
||
|
hr = ::HrGetPcpFromPnse(pnseInter, &pcpStat);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
INetConnectionStatisticsNotifySink* pncsThis = this;
|
||
|
|
||
|
hr = pcpStat->Advise(pncsThis, &m_dwConPointCookie);
|
||
|
|
||
|
::ReleaseObj(pcpStat);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Keep track of our owner
|
||
|
//
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
AssertSz(!m_pnseStat, "We should't have a m_pnseStat");
|
||
|
m_pnseStat = pnseNew;
|
||
|
::AddRefObj(pnseInter);
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::HrInitGenPage", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnInitDialog
|
||
|
//
|
||
|
// Purpose: When the page comes up, initialize the fields
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnInitDialog (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
// initialize data member
|
||
|
m_iStatTrans = Stat_Unknown;
|
||
|
|
||
|
// Initialize the icon in the dialog by forcing it to change
|
||
|
//
|
||
|
UpdatePageIcon(SMDCF_TRANSMITTING | SMDCF_RECEIVING);
|
||
|
UpdatePageIcon(SMDCF_NULL);
|
||
|
|
||
|
UpdateSignalStrengthIcon(0);
|
||
|
|
||
|
// Tell the CNetStatisticsEngine about our parent property sheet
|
||
|
// so if someone attempts to bring up a statistics monitor we
|
||
|
// can utilize the existing one
|
||
|
//
|
||
|
Assert(m_pnseStat);
|
||
|
m_pnseStat->SetPropsheetWindow(GetParent());
|
||
|
|
||
|
// Start our local refresh timer with a 1 second period.
|
||
|
//
|
||
|
SetTimer (c_unLocalRefreshTimerID, 1000, NULL);
|
||
|
|
||
|
// leaving creating mode
|
||
|
m_pnseStat->UnSetCreatingDialog();
|
||
|
|
||
|
BOOL fEnableDisconnect = TRUE; // Should we disable the Disconnect button
|
||
|
BOOL fEnableProperties = TRUE; // Should we disable the Properties button
|
||
|
BOOL fShowErrorCount = TRUE;
|
||
|
|
||
|
switch(m_ncmType)
|
||
|
{
|
||
|
case NCM_LAN:
|
||
|
case NCM_BRIDGE:
|
||
|
fEnableDisconnect = FHasPermission(NCPERM_LanConnect);
|
||
|
fEnableProperties = FHasPermission(NCPERM_LanProperties);
|
||
|
if(!FIsShowLanErrorRegKeySet())
|
||
|
{
|
||
|
fShowErrorCount = FALSE;
|
||
|
}
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_ERROR), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_TRANS), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_RECV), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_FRM_LONG), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_FRM_SHORT), !fShowErrorCount); // reversed...
|
||
|
break;
|
||
|
|
||
|
case NCM_SHAREDACCESSHOST_RAS:
|
||
|
::SetWindowText(GetDlgItem(IDC_PSB_DISCONNECT), ::SzLoadIds(IDS_SM_PSH_DISCONNECT)); // If RAS connection, change the "Disable" button to "Disconnect"
|
||
|
//fallthru
|
||
|
case NCM_SHAREDACCESSHOST_LAN:
|
||
|
{
|
||
|
// TODO fEnableDisconnect
|
||
|
// TODO fEnableProperties
|
||
|
HRESULT hr;
|
||
|
|
||
|
fShowErrorCount = FALSE; // no error stuff in spec
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case NCM_TUNNEL:
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_SPEED_LABEL), FALSE);
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_SPEED), FALSE);
|
||
|
//fallthru
|
||
|
|
||
|
case NCM_DIRECT: // REVIEW correct?
|
||
|
case NCM_ISDN:
|
||
|
case NCM_PHONE:
|
||
|
case NCM_PPPOE:
|
||
|
fEnableDisconnect = FHasPermission(NCPERM_RasConnect);
|
||
|
if (
|
||
|
(m_dwCharacter & NCCF_INCOMING_ONLY) ||
|
||
|
((m_dwCharacter & NCCF_ALL_USERS) && !FHasPermission(NCPERM_RasAllUserProperties)) ||
|
||
|
(!(m_dwCharacter & NCCF_ALL_USERS) && !FHasPermission(NCPERM_RasMyProperties))
|
||
|
)
|
||
|
{
|
||
|
fEnableProperties = FALSE;
|
||
|
}
|
||
|
::SetWindowText(GetDlgItem(IDC_PSB_DISCONNECT), ::SzLoadIds(IDS_SM_PSH_DISCONNECT)); // If RAS connection, change the "Disable" button to "Disconnect"
|
||
|
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_ERROR), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_TRANS), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_TXT_SM_ERROR_RECV), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_FRM_LONG), fShowErrorCount);
|
||
|
::ShowWindow(GetDlgItem(IDC_FRM_SHORT), !fShowErrorCount); // reversed...
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
AssertSz(FALSE, "Unknown media type");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
::EnableWindow(::GetDlgItem(m_hWnd, IDC_PSB_DISCONNECT), fEnableDisconnect);
|
||
|
::EnableWindow(::GetDlgItem(m_hWnd, IDC_PSB_PROPERTIES), fEnableProperties);
|
||
|
|
||
|
if (m_fIsFirstPage)
|
||
|
{
|
||
|
// get window handle to propertysheet
|
||
|
HWND hwndParent=GetParent();
|
||
|
Assert(hwndParent);
|
||
|
|
||
|
// center the property sheet on desktop
|
||
|
FCenterWindow (hwndParent, NULL);
|
||
|
|
||
|
// hide the "ok" button
|
||
|
//
|
||
|
::ShowWindow(::GetDlgItem(hwndParent, IDOK), FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnSetActive
|
||
|
//
|
||
|
// Purpose: Enable statistics when the page has focus
|
||
|
//
|
||
|
// Arguments: Standard notification parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnSetActive (
|
||
|
INT idCtrl,
|
||
|
LPNMHDR pnmh,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// Only turn them on if they are not running
|
||
|
//
|
||
|
if (!m_fStats)
|
||
|
{
|
||
|
hr = m_pnseStat->StartStatistics();
|
||
|
m_fStats = TRUE;
|
||
|
}
|
||
|
|
||
|
// User's intent is to view statistics, so give them an immediate
|
||
|
// refreshed view of them.
|
||
|
//
|
||
|
::PostMessage (m_hWnd, PWM_UPDATE_STATUS_DISPLAY, 0, SMDCF_NULL);
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::OnSetActive", hr);
|
||
|
return LresFromHr(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnKillActive
|
||
|
//
|
||
|
// Purpose: Disable statistics when the page is changed
|
||
|
//
|
||
|
// Arguments: Standard notification parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnKillActive (
|
||
|
INT idCtrl,
|
||
|
LPNMHDR pnmh,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// Only turn them off if they are running
|
||
|
//
|
||
|
if (m_fStats)
|
||
|
{
|
||
|
hr = m_pnseStat->StopStatistics();
|
||
|
m_fStats = FALSE;
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::OnKillActive", hr);
|
||
|
return LresFromHr(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnClose
|
||
|
//
|
||
|
// Purpose: Cleans up the items in the page when the dialog is being
|
||
|
// closed
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnClose (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
return DestroyWindow();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnDestroy
|
||
|
//
|
||
|
// Purpose: Cleans up the items in the page when the dialog is being
|
||
|
// destroyed
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnDestroy (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HWND hwndIcon = ::GetDlgItem(m_hWnd, IDI_SM_STATUS_ICON);
|
||
|
HICON hOldIcon = reinterpret_cast<HICON>(::SendMessage(
|
||
|
hwndIcon,
|
||
|
STM_GETICON,
|
||
|
0,
|
||
|
0));
|
||
|
|
||
|
if (hOldIcon)
|
||
|
{
|
||
|
DestroyIcon(hOldIcon);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
AssertSz(m_pnseStat, "We should have a m_pnseStat");
|
||
|
|
||
|
// Make sure we don't get released during our destroy
|
||
|
//
|
||
|
::AddRefObj(this);
|
||
|
|
||
|
// Stop our local refresh timer
|
||
|
//
|
||
|
KillTimer (c_unLocalRefreshTimerID);
|
||
|
|
||
|
// Make sure stats are in a happy state
|
||
|
//
|
||
|
if (m_fStats)
|
||
|
{
|
||
|
(VOID) m_pnseStat->StopStatistics();
|
||
|
m_fStats = FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// *** Do this last ***
|
||
|
//
|
||
|
// It is very likely this will result in the this page being destroyed
|
||
|
// if it is the window closing
|
||
|
//
|
||
|
|
||
|
m_pnseStat->SetPropsheetWindow(NULL);
|
||
|
|
||
|
// Clean up all the interfaces
|
||
|
//
|
||
|
hr = HrCleanupGenPage();
|
||
|
|
||
|
::ReleaseObj(this);
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::OnDestroy", hr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::HrCleanupGenPage
|
||
|
//
|
||
|
// Purpose: Cleans out all the interfaces that are used by the open page
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Error code
|
||
|
//
|
||
|
HRESULT
|
||
|
CPspStatusMonitorGen::HrCleanupGenPage (
|
||
|
VOID)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
INetStatisticsEngine* pnseStat = m_pnseStat;
|
||
|
|
||
|
// Only disconnect if we haven't already.
|
||
|
//
|
||
|
if (pnseStat)
|
||
|
{
|
||
|
// Unadvise the interface
|
||
|
//
|
||
|
IConnectionPoint* pcpStat = NULL;
|
||
|
|
||
|
if (m_dwConPointCookie
|
||
|
&& (SUCCEEDED(::HrGetPcpFromPnse(pnseStat, &pcpStat))))
|
||
|
{
|
||
|
(VOID) pcpStat->Unadvise(m_dwConPointCookie);
|
||
|
|
||
|
::ReleaseObj(pcpStat);
|
||
|
|
||
|
// Very important to zero the cookie. This tells
|
||
|
// OnStatisticsChanged that we're no longer interested in updates.
|
||
|
//
|
||
|
m_dwConPointCookie = 0;
|
||
|
}
|
||
|
|
||
|
if (m_psmEngineData)
|
||
|
{
|
||
|
CoTaskMemFree(m_psmEngineData);
|
||
|
m_psmEngineData = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// *** Do this last ***
|
||
|
//
|
||
|
// It is very likely this will result in the this page being destroyed
|
||
|
// if it is the window closing
|
||
|
//
|
||
|
|
||
|
m_pnseStat = NULL;
|
||
|
::ReleaseObj(pnseStat);
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::HrCleanupGenPage", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnContextMenu
|
||
|
//
|
||
|
// Purpose: When right click a control, bring up help
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnContextMenu(UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& fHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
if (m_adwHelpIDs != NULL)
|
||
|
{
|
||
|
::WinHelp(m_hWnd,
|
||
|
c_szNetCfgHelpFile,
|
||
|
HELP_CONTEXTMENU,
|
||
|
(ULONG_PTR)m_adwHelpIDs);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnHelp
|
||
|
//
|
||
|
// Purpose: When drag context help icon over a control, bring up help
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnHelp(UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& fHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
|
||
|
Assert(lphi);
|
||
|
|
||
|
if ((m_adwHelpIDs != NULL) && (HELPINFO_WINDOW == lphi->iContextType))
|
||
|
{
|
||
|
::WinHelp(static_cast<HWND>(lphi->hItemHandle),
|
||
|
c_szNetCfgHelpFile,
|
||
|
HELP_WM_HELP,
|
||
|
(ULONG_PTR)m_adwHelpIDs);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnDisconnect
|
||
|
//
|
||
|
// Purpose: When the disconnect button is hit, disconnect the connection
|
||
|
// and closes the dialog
|
||
|
//
|
||
|
// Arguments: Standard notification parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT CPspStatusMonitorGen::OnDisconnect(WORD wNotifyCode, WORD wID,
|
||
|
HWND hWndCtl, BOOL& fHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
switch (wNotifyCode)
|
||
|
{
|
||
|
case BN_CLICKED:
|
||
|
case BN_DOUBLECLICKED:
|
||
|
{
|
||
|
hr = HrDisconnectConnection();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::OnDisconnect", hr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnRaiseproperties
|
||
|
//
|
||
|
// Purpose: Bring up the property of this connection
|
||
|
//
|
||
|
// Arguments: Standard notification parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
LRESULT CPspStatusMonitorGen::OnRaiseProperties(WORD wNotifyCode, WORD wID,
|
||
|
HWND hWndCtl, BOOL& fHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
switch (wNotifyCode)
|
||
|
{
|
||
|
case BN_CLICKED:
|
||
|
case BN_DOUBLECLICKED:
|
||
|
{
|
||
|
|
||
|
// Addref m_pnseStat object
|
||
|
//
|
||
|
AddRefObj(static_cast<INetStatisticsEngine *>(m_pnseStat));
|
||
|
|
||
|
// Make sure the netshell.dll is not unloaded
|
||
|
//
|
||
|
HINSTANCE hInst = LoadLibrary(c_szNetShellDll);
|
||
|
HANDLE hthrd = NULL;
|
||
|
|
||
|
// Create the property sheet on a different thread
|
||
|
//
|
||
|
if (hInst)
|
||
|
{
|
||
|
DWORD dwThreadId;
|
||
|
hthrd = CreateThread(NULL, STACK_SIZE_TINY,
|
||
|
(LPTHREAD_START_ROUTINE)PropertyThread,
|
||
|
(LPVOID)m_pnseStat, 0, &dwThreadId);
|
||
|
}
|
||
|
|
||
|
if (NULL != hthrd)
|
||
|
{
|
||
|
CloseHandle(hthrd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/// Release m_pnseStat object on failure
|
||
|
//
|
||
|
ReleaseObj(static_cast<INetStatisticsEngine *>(m_pnseStat));
|
||
|
|
||
|
// release the dll
|
||
|
//
|
||
|
if (hInst)
|
||
|
FreeLibrary(hInst);
|
||
|
|
||
|
hr = HrFromLastWin32Error();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::OnRaiseproperties", hr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
DWORD PropertyThread(CNetStatisticsEngine * pnse)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
BOOL fUninitCom = TRUE;
|
||
|
|
||
|
// Initialize COM on this thread
|
||
|
//
|
||
|
hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
|
||
|
if (RPC_E_CHANGED_MODE == hr)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
fUninitCom = FALSE;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
INetConnection* pncMonitor = NULL;
|
||
|
|
||
|
// Get the INetConnection
|
||
|
//
|
||
|
Assert (pnse);
|
||
|
hr = pnse->HrGetConnectionFromBlob(&pncMonitor);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = HrRaiseConnectionProperties(NULL, pncMonitor);
|
||
|
}
|
||
|
ReleaseObj(pncMonitor);
|
||
|
}
|
||
|
|
||
|
if (fUninitCom)
|
||
|
{
|
||
|
CoUninitialize();
|
||
|
}
|
||
|
|
||
|
// release input interface
|
||
|
ReleaseObj(static_cast<INetStatisticsEngine *>(pnse));
|
||
|
|
||
|
// release the library we loaded
|
||
|
FreeLibraryAndExitThread(GetModuleHandle(c_szNetShellDll), hr);
|
||
|
|
||
|
TraceError("PropertyThread", hr);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::HrDisconnectConnection
|
||
|
//
|
||
|
// Purpose: disconnect the connection and closes the dialog if succeeded
|
||
|
//
|
||
|
// Arguments: fConfirmed TRUE if the user has confirmed to disconnect the connection
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
HRESULT CPspStatusMonitorGen::HrDisconnectConnection(BOOL fConfirmed)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
Assert (m_pnseStat);
|
||
|
|
||
|
// Get the INetConnection
|
||
|
//
|
||
|
INetConnection* pncMonitor;
|
||
|
|
||
|
hr = m_pnseStat->HrGetConnectionFromBlob(&pncMonitor);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
PCONFOLDPIDL pidlConnection;
|
||
|
|
||
|
hr = HrCreateConFoldPidl(WIZARD_NOT_WIZARD, pncMonitor, pidlConnection);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
CONFOLDENTRY ccfe;
|
||
|
|
||
|
hr = pidlConnection.ConvertToConFoldEntry(ccfe);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Get the pidl for the Connections Folder
|
||
|
//
|
||
|
PCONFOLDPIDLFOLDER pidlFolder;
|
||
|
hr = HrGetConnectionsFolderPidl(pidlFolder);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Get the Connections Folder object
|
||
|
//
|
||
|
LPSHELLFOLDER psfConnections;
|
||
|
|
||
|
hr = HrGetConnectionsIShellFolder(pidlFolder, &psfConnections);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = HrOnCommandDisconnectInternal(ccfe,
|
||
|
m_hWnd,
|
||
|
psfConnections);
|
||
|
ReleaseObj(psfConnections);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// release INetConnection interface
|
||
|
ReleaseObj(pncMonitor);
|
||
|
}
|
||
|
|
||
|
// If anything above failed.
|
||
|
//
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
// close the property sheet
|
||
|
HWND hwndPS = ::GetParent(m_hWnd);
|
||
|
|
||
|
// Push the Close ("Cancel") button to close dialog
|
||
|
//
|
||
|
::PostMessage(hwndPS, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0),
|
||
|
(LPARAM)::GetDlgItem(hwndPS, IDCANCEL));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Disconnect confirmation canceled. Do nothing (don't close
|
||
|
// statmon, anyway).
|
||
|
//
|
||
|
AssertSz(S_FALSE == hr, "Disconnect != S_OK or S_FALSE, but succeeded? What is it then?");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TraceError("pncMonitor->Disconnect", hr);
|
||
|
|
||
|
// Warn the user and don't close if we couldn't disconnect
|
||
|
//
|
||
|
::NcMsgBox( m_hWnd,
|
||
|
IDS_SM_ERROR_CAPTION,
|
||
|
IDS_SM_ERROR_CANNOT_DISCONNECT,
|
||
|
MB_ICONWARNING);
|
||
|
}
|
||
|
|
||
|
TraceError("CPspStatusMonitorGen::HrDisconnectConnection", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnSetCursor
|
||
|
//
|
||
|
// Purpose: Ensure the mouse cursor over the Property Sheet is an Arrow.
|
||
|
//
|
||
|
// Arguments: Standard command parameters
|
||
|
//
|
||
|
// Returns: Standard return
|
||
|
//
|
||
|
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnSetCursor (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
if (LOWORD(lParam) == HTCLIENT)
|
||
|
{
|
||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnTimer (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
// Prevent same-thread re-entrancy. Any Win32 call made while
|
||
|
// processing this event that return control to the message
|
||
|
// loop may cause this timer to fire again.
|
||
|
//
|
||
|
if (!m_fProcessingTimerEvent)
|
||
|
{
|
||
|
m_fProcessingTimerEvent = TRUE;
|
||
|
|
||
|
// If we're within 200 milliseconds of the last time we updated the
|
||
|
// status display, don't bother doing it again. This covers the case
|
||
|
// where our timer coincides with the timer in smcent which would
|
||
|
// would cause us to update the status display twice in rapid
|
||
|
// succession each time the timers fire.
|
||
|
//
|
||
|
DWORD dwTick = GetTickCount ();
|
||
|
if (dwTick > m_dwLastUpdateStatusDisplayTick + 200)
|
||
|
{
|
||
|
OnUpdateStatusDisplay (uMsg, 0, m_dwChangeFlags, bHandled);
|
||
|
}
|
||
|
|
||
|
m_fProcessingTimerEvent = FALSE;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LRESULT
|
||
|
CPspStatusMonitorGen::OnUpdateStatusDisplay(
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
DWORD dwChangeFlags = lParam;
|
||
|
|
||
|
// We may be in the process of disconnecting the statistics page in
|
||
|
// which case m_dwConPointCookie will be zero.
|
||
|
//
|
||
|
if (m_dwConPointCookie)
|
||
|
{
|
||
|
Assert (m_psmEngineData);
|
||
|
|
||
|
STATMON_ENGINEDATA* psmNewData = NULL;
|
||
|
hr = m_pnseStat->GetStatistics(&psmNewData);
|
||
|
|
||
|
if (SUCCEEDED(hr) && psmNewData)
|
||
|
{
|
||
|
if (m_psmEngineData)
|
||
|
{
|
||
|
//
|
||
|
// Display the new stats
|
||
|
//
|
||
|
UpdatePage(m_psmEngineData, psmNewData);
|
||
|
|
||
|
// Update the icon image
|
||
|
//
|
||
|
UpdatePageIcon(dwChangeFlags);
|
||
|
|
||
|
UpdateSignalStrengthIcon(psmNewData->SMED_802_11_SIGNAL_STRENGTH);
|
||
|
|
||
|
// Note the clock tick of when we last updated
|
||
|
// the status display.
|
||
|
//
|
||
|
m_dwLastUpdateStatusDisplayTick = GetTickCount();
|
||
|
|
||
|
// Replace the old data with the new
|
||
|
//
|
||
|
CoTaskMemFree(m_psmEngineData);
|
||
|
}
|
||
|
|
||
|
m_psmEngineData = psmNewData;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TraceTag (ttidStatMon,
|
||
|
"CPspStatusMonitorGen::OnStatisticsChanged called but we've "
|
||
|
"been closed. Ignoring.");
|
||
|
}
|
||
|
TraceError("CPspStatusMonitorGen::OnUpdateStatusDisplay", hr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::OnStatisticsChanged
|
||
|
//
|
||
|
// Purpose: This is the callback that tell the property page that the
|
||
|
// data on the page has changed
|
||
|
//
|
||
|
// Arguments: dwCookie - The cookie of the connection that has changed
|
||
|
// dwChangeFlags - What has changed
|
||
|
//
|
||
|
// Returns: Error code
|
||
|
//
|
||
|
STDMETHODIMP
|
||
|
CPspStatusMonitorGen::OnStatisticsChanged(
|
||
|
DWORD dwChangeFlags)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
::PostMessage (m_hWnd, PWM_UPDATE_STATUS_DISPLAY, 0, dwChangeFlags);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePage
|
||
|
//
|
||
|
// Purpose: Fill the fields on the page with new data
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePage (
|
||
|
STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a puiOld");
|
||
|
AssertSz(pseNewData, "We don't have a puiNew");
|
||
|
|
||
|
//
|
||
|
// Update the dialog fields
|
||
|
//
|
||
|
UpdatePageConnectionStatus(pseOldData, pseNewData);
|
||
|
|
||
|
UpdatePageDuration(pseOldData, pseNewData);
|
||
|
|
||
|
UpdatePageSpeed(pseOldData, pseNewData);
|
||
|
|
||
|
// If the StatMon is not getting any bytes (a common problem with net
|
||
|
// cards), display packets instead
|
||
|
//
|
||
|
if (ShouldShowPackets(pseNewData))
|
||
|
{
|
||
|
// Only change the label if we have to
|
||
|
//
|
||
|
if (Stat_Packets != m_iStatTrans)
|
||
|
{
|
||
|
SetDlgItemText(IDC_TXT_SM_BYTES_LABEL, ::SzLoadIds(IDS_SM_PACKETS));
|
||
|
m_iStatTrans = Stat_Packets;
|
||
|
|
||
|
// Force a refresh
|
||
|
//
|
||
|
pseOldData->SMED_PACKETSTRANSMITTING = 0;
|
||
|
pseOldData->SMED_PACKETSRECEIVING = 0;
|
||
|
}
|
||
|
|
||
|
UpdatePageBytesTransmitting(pseOldData, pseNewData, Stat_Packets);
|
||
|
UpdatePageBytesReceiving(pseOldData, pseNewData, Stat_Packets);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Only change the label if we have to
|
||
|
//
|
||
|
if (Stat_Bytes != m_iStatTrans)
|
||
|
{
|
||
|
SetDlgItemText(IDC_TXT_SM_BYTES_LABEL, ::SzLoadIds(IDS_SM_BYTES));
|
||
|
m_iStatTrans = Stat_Bytes;
|
||
|
|
||
|
// Force a refresh
|
||
|
//
|
||
|
pseOldData->SMED_BYTESTRANSMITTING = 0;
|
||
|
pseOldData->SMED_BYTESRECEIVING = 0;
|
||
|
}
|
||
|
|
||
|
UpdatePageBytesTransmitting(pseOldData, pseNewData, Stat_Bytes);
|
||
|
UpdatePageBytesReceiving(pseOldData, pseNewData, Stat_Bytes);
|
||
|
}
|
||
|
|
||
|
UpdatePageCompTransmitting(pseOldData, pseNewData);
|
||
|
UpdatePageCompReceiving(pseOldData, pseNewData);
|
||
|
|
||
|
UpdatePageErrorsTransmitting(pseOldData, pseNewData);
|
||
|
UpdatePageErrorsReceiving(pseOldData, pseNewData);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::ShouldShowPackets
|
||
|
//
|
||
|
// Purpose: Decided whether to show bytes or packets
|
||
|
//
|
||
|
// Arguments: pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
|
||
|
BOOL CPspStatusMonitorGen::ShouldShowPackets(const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
return (0 == pseNewData->SMED_BYTESTRANSMITTING) && (0 == pseNewData->SMED_BYTESRECEIVING);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageSpeed
|
||
|
//
|
||
|
// Purpose: Updates the speed display on the general page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageSpeed(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
// Get the data and see if either is different
|
||
|
//
|
||
|
if ((pseOldData->SMED_SPEEDTRANSMITTING != pseNewData->SMED_SPEEDTRANSMITTING)
|
||
|
|| (pseOldData->SMED_SPEEDRECEIVING != pseNewData->SMED_SPEEDRECEIVING))
|
||
|
{
|
||
|
WCHAR achBuffer[MAX_PATH];
|
||
|
|
||
|
FormatTransmittingReceivingSpeed (
|
||
|
pseNewData->SMED_SPEEDTRANSMITTING,
|
||
|
pseNewData->SMED_SPEEDRECEIVING,
|
||
|
achBuffer);
|
||
|
|
||
|
// Set the control text.
|
||
|
//
|
||
|
SetDlgItemText(IDC_TXT_SM_SPEED, achBuffer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageConnectionStatus
|
||
|
//
|
||
|
// Purpose: Update the connections field on the property page
|
||
|
//
|
||
|
// Arguments: puiOldData - The old stats being displayed on the page
|
||
|
// puiNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageConnectionStatus(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewdata");
|
||
|
|
||
|
// Update the Connection Status
|
||
|
//
|
||
|
if ((pseNewData->SMED_CONNECTIONSTATUS == NCS_DISCONNECTED) ||
|
||
|
(pseOldData->SMED_CONNECTIONSTATUS != pseNewData->SMED_CONNECTIONSTATUS))
|
||
|
{
|
||
|
INT idsConnection = IDS_SM_CS_DISCONNECTED;
|
||
|
|
||
|
// Make sure our strings are still intact
|
||
|
AssertSz((((IDS_SM_CS_DISCONNECTED + 1) == IDS_SM_CS_CONNECTING)
|
||
|
&& ((IDS_SM_CS_DISCONNECTED + 2) == IDS_SM_CS_CONNECTED)
|
||
|
&& ((IDS_SM_CS_DISCONNECTED + 3) == IDS_SM_CS_DISCONNECTING)
|
||
|
&& ((IDS_SM_CS_DISCONNECTED + 4) == IDS_SM_CS_HARDWARE_NOT_PRESENT)
|
||
|
&& ((IDS_SM_CS_DISCONNECTED + 5) == IDS_SM_CS_HARDWARE_DISABLED)
|
||
|
&& ((IDS_SM_CS_DISCONNECTED + 6) == IDS_SM_CS_HARDWARE_MALFUNCTION)),
|
||
|
"Some one has been messing with connection status strings");
|
||
|
|
||
|
idsConnection = (IDS_SM_CS_DISCONNECTED
|
||
|
+ pseNewData->SMED_CONNECTIONSTATUS);
|
||
|
|
||
|
if (idsConnection == IDS_SM_CS_DISCONNECTED)
|
||
|
{
|
||
|
// close the property sheet
|
||
|
HWND hwndPS = ::GetParent(m_hWnd);
|
||
|
|
||
|
TraceTag(ttidStatMon, "Closing Status Monitor page because status was: DISCONNECTED");
|
||
|
// Push the Close ("Cancel") button to close dialog
|
||
|
//
|
||
|
::PostMessage(hwndPS, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0),
|
||
|
(LPARAM)::GetDlgItem(hwndPS, IDCANCEL));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetDlgItemText(IDC_TXT_SM_STATUS, ::SzLoadIds(idsConnection));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageIcon
|
||
|
//
|
||
|
// Purpose: Update the icon on the property page
|
||
|
//
|
||
|
// Arguments: dwChangeFlags - The new changed state
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageIcon (
|
||
|
DWORD dwChangeFlags)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
// If either of these have changed, change the icon
|
||
|
// so we'll know to update the icon
|
||
|
//
|
||
|
if (((SMDCF_TRANSMITTING | SMDCF_RECEIVING) & m_dwChangeFlags)
|
||
|
!= ((SMDCF_TRANSMITTING | SMDCF_RECEIVING) & dwChangeFlags))
|
||
|
{
|
||
|
HICON hStatusIcon = 0;
|
||
|
HWND hwndIcon = NULL;
|
||
|
|
||
|
// Get the new icon
|
||
|
//
|
||
|
hStatusIcon = GetCurrentConnectionStatusIconId(m_ncmType, m_ncsmType, m_dwCharacter, dwChangeFlags);
|
||
|
if (hStatusIcon)
|
||
|
{
|
||
|
hwndIcon = ::GetDlgItem(m_hWnd, IDI_SM_STATUS_ICON);
|
||
|
|
||
|
// Set the icon to the new one
|
||
|
//
|
||
|
HICON hOldIcon = reinterpret_cast<HICON>(::SendMessage(
|
||
|
hwndIcon,
|
||
|
STM_SETICON,
|
||
|
(WPARAM)hStatusIcon,
|
||
|
0));
|
||
|
|
||
|
DestroyIcon(hOldIcon);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Keep the flags for the next update
|
||
|
//
|
||
|
m_dwChangeFlags = dwChangeFlags;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdateSignalStrengthIcon
|
||
|
//
|
||
|
// Purpose: Update the icon on the property page
|
||
|
//
|
||
|
// Arguments: iRSSI - The new signal strenghth
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
inline
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdateSignalStrengthIcon (
|
||
|
INT iRSSI)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
if (0 == iRSSI)
|
||
|
{
|
||
|
if (0 != m_iLastSignalStrength)
|
||
|
{
|
||
|
::ShowWindow(::GetDlgItem(m_hWnd, IDC_TXT_SM_SIGNAL_STRENGTH), SW_HIDE);
|
||
|
::ShowWindow(::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON), SW_HIDE);
|
||
|
}
|
||
|
|
||
|
m_iLastSignalStrength = iRSSI;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (0 == m_iLastSignalStrength)
|
||
|
{
|
||
|
::ShowWindow(::GetDlgItem(m_hWnd, IDC_TXT_SM_SIGNAL_STRENGTH), SW_SHOW);
|
||
|
::ShowWindow(::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON), SW_SHOW);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INT idStatusIcon = 0;
|
||
|
m_iLastSignalStrength = iRSSI;
|
||
|
|
||
|
// Get the new icon
|
||
|
//
|
||
|
idStatusIcon = IDI_802_11_LEVEL0 + MapRSSIToWirelessSignalStrength(iRSSI);
|
||
|
|
||
|
HWND hwndSignalStrength = ::GetDlgItem(m_hWnd, IDI_SM_SIGNAL_STRENGTH_ICON);
|
||
|
Assert(hwndSignalStrength);
|
||
|
if (hwndSignalStrength)
|
||
|
{
|
||
|
HDC hdcSignalStrength = ::GetDC(hwndSignalStrength);
|
||
|
Assert(hdcSignalStrength);
|
||
|
if (hdcSignalStrength)
|
||
|
{
|
||
|
|
||
|
HICON hIconSignalStrength = LoadIconTile(_Module.GetResourceInstance(), MAKEINTRESOURCE(idStatusIcon));
|
||
|
Assert(hIconSignalStrength);
|
||
|
if (hIconSignalStrength)
|
||
|
{
|
||
|
::DrawIconEx(hdcSignalStrength, 0, 0, hIconSignalStrength, 48, 48, 0, NULL, DI_IMAGE | DI_MASK);
|
||
|
DestroyIcon(hIconSignalStrength);
|
||
|
}
|
||
|
|
||
|
::ReleaseDC(hwndSignalStrength, hdcSignalStrength);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdateSignalStrengthIcon
|
||
|
//
|
||
|
// Purpose: Update the icon on the property page
|
||
|
//
|
||
|
// Arguments: iRSSI - The new signal strenghth
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
LRESULT CPspStatusMonitorGen::OnPaint (
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL& bHandled)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
PAINTSTRUCT ps;
|
||
|
BeginPaint(&ps);
|
||
|
|
||
|
UpdateSignalStrengthIcon(m_iLastSignalStrength);
|
||
|
|
||
|
EndPaint(&ps);
|
||
|
|
||
|
bHandled = TRUE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageDuration
|
||
|
//
|
||
|
// Purpose: Updates the duration display on the general page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageDuration(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
// Get the see if either is different
|
||
|
//
|
||
|
if (pseOldData->SMED_DURATION != pseNewData->SMED_DURATION)
|
||
|
{
|
||
|
tstring strDuration;
|
||
|
|
||
|
// Format the time duration as a string
|
||
|
//
|
||
|
FormatTimeDuration(pseNewData->SMED_DURATION, &strDuration);
|
||
|
|
||
|
// Set the control
|
||
|
//
|
||
|
SetDlgItemText(IDC_TXT_SM_DURATION, strDuration.c_str());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageBytesTransmitting
|
||
|
//
|
||
|
// Purpose: Updates the bytes Transmitting display on the general page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
// iStat - The which stats to display
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageBytesTransmitting(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData,
|
||
|
StatTrans iStat)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
AssertSz(((Stat_Packets == iStat) || (Stat_Bytes == iStat)), "We have an invalid iStat");
|
||
|
|
||
|
UINT64 ui64Old;
|
||
|
UINT64 ui64New;
|
||
|
|
||
|
if (Stat_Bytes == iStat)
|
||
|
{
|
||
|
ui64Old = pseOldData->SMED_BYTESTRANSMITTING;
|
||
|
ui64New = pseNewData->SMED_BYTESTRANSMITTING;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ui64Old = pseOldData->SMED_PACKETSTRANSMITTING;
|
||
|
ui64New = pseNewData->SMED_PACKETSTRANSMITTING;
|
||
|
}
|
||
|
|
||
|
// See if either is different
|
||
|
//
|
||
|
if (ui64Old != ui64New)
|
||
|
{
|
||
|
SetDlgItemFormatted64bitInteger(
|
||
|
m_hWnd,
|
||
|
IDC_TXT_SM_BYTES_TRANS,
|
||
|
ui64New, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageBytesReceiving
|
||
|
//
|
||
|
// Purpose: Updates the bytes receiving display on the general page
|
||
|
//
|
||
|
// Arguments: puiOld - The old stats being displayed on the page
|
||
|
// puiNew - The new stats being displayed on the page
|
||
|
// iStat - The which stats to display
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageBytesReceiving(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData,
|
||
|
StatTrans iStat)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a puiOld");
|
||
|
AssertSz(pseNewData, "We don't have a puiNew");
|
||
|
AssertSz(((Stat_Packets == iStat) || (Stat_Bytes == iStat)), "We have an invalid iStat");
|
||
|
|
||
|
UINT64 ui64Old;
|
||
|
UINT64 ui64New;
|
||
|
|
||
|
if (Stat_Bytes == iStat)
|
||
|
{
|
||
|
ui64Old = pseOldData->SMED_BYTESRECEIVING;
|
||
|
ui64New = pseNewData->SMED_BYTESRECEIVING;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ui64Old = pseOldData->SMED_PACKETSRECEIVING;
|
||
|
ui64New = pseNewData->SMED_PACKETSRECEIVING;
|
||
|
}
|
||
|
|
||
|
// See if either is different
|
||
|
//
|
||
|
if (ui64Old != ui64New)
|
||
|
{
|
||
|
SetDlgItemFormatted64bitInteger(
|
||
|
m_hWnd,
|
||
|
IDC_TXT_SM_BYTES_RCVD,
|
||
|
ui64New, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageCompTransmitting
|
||
|
//
|
||
|
// Purpose: Updates the compression transmitting display on the general
|
||
|
// page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageCompTransmitting(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
// See if either is different
|
||
|
//
|
||
|
if (pseOldData->SMED_COMPRESSIONTRANSMITTING
|
||
|
!= pseNewData->SMED_COMPRESSIONTRANSMITTING)
|
||
|
{
|
||
|
WCHAR achBuf[20];
|
||
|
|
||
|
CompressionToSz(pseNewData->SMED_COMPRESSIONTRANSMITTING, achBuf);
|
||
|
|
||
|
SetDlgItemText(IDC_TXT_SM_COMP_TRANS, achBuf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageCompReceiving
|
||
|
//
|
||
|
// Purpose: Updates the compression receiving display on the general page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageCompReceiving(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a puiOld");
|
||
|
AssertSz(pseNewData, "We don't have a puiNew");
|
||
|
|
||
|
// see if either is different
|
||
|
//
|
||
|
if (pseOldData->SMED_COMPRESSIONRECEIVING != pseNewData->SMED_COMPRESSIONRECEIVING)
|
||
|
{
|
||
|
WCHAR achBuf[20];
|
||
|
|
||
|
CompressionToSz(pseNewData->SMED_COMPRESSIONRECEIVING, achBuf);
|
||
|
|
||
|
SetDlgItemText(IDC_TXT_SM_COMP_RCVD, achBuf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageErrorsTransmitting
|
||
|
//
|
||
|
// Purpose: Updates the compression transmitting display on the general
|
||
|
// page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageErrorsTransmitting(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
// See if either is different
|
||
|
//
|
||
|
if (pseOldData->SMED_ERRORSTRANSMITTING
|
||
|
!= pseNewData->SMED_ERRORSTRANSMITTING)
|
||
|
{
|
||
|
SetDlgItemFormatted32bitInteger (
|
||
|
m_hWnd,
|
||
|
IDC_TXT_SM_ERROR_TRANS,
|
||
|
pseNewData->SMED_ERRORSTRANSMITTING,
|
||
|
FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CPspStatusMonitorGen::UpdatePageErrorsReceiving
|
||
|
//
|
||
|
// Purpose: Updates the compression receiving display on the general page
|
||
|
//
|
||
|
// Arguments: pseOldData - The old stats being displayed on the page
|
||
|
// pseNewData - The new stats being displayed on the page
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CPspStatusMonitorGen::UpdatePageErrorsReceiving(
|
||
|
const STATMON_ENGINEDATA* pseOldData,
|
||
|
const STATMON_ENGINEDATA* pseNewData)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz(pseOldData, "We don't have a pseOldData");
|
||
|
AssertSz(pseNewData, "We don't have a pseNewData");
|
||
|
|
||
|
// see if either is different
|
||
|
//
|
||
|
if (pseOldData->SMED_ERRORSRECEIVING != pseNewData->SMED_ERRORSRECEIVING)
|
||
|
{
|
||
|
SetDlgItemFormatted32bitInteger (
|
||
|
m_hWnd,
|
||
|
IDC_TXT_SM_ERROR_RECV,
|
||
|
pseNewData->SMED_ERRORSRECEIVING,
|
||
|
FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CompressionToSz
|
||
|
//
|
||
|
// Purpose: To format nicely BPS into a readable string
|
||
|
//
|
||
|
// Arguments: uiCompression - The amount of compression
|
||
|
// pchBuffer - The Buffer to receive the string
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
VOID
|
||
|
CompressionToSz (
|
||
|
UINT uiCompression,
|
||
|
WCHAR* pchBuffer)
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
AssertSz((((INT)uiCompression >= 0) && ((INT)uiCompression <= 100)),
|
||
|
"Invalid compression");
|
||
|
|
||
|
wsprintfW(pchBuffer, L"%lu %%", uiCompression);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: FIsShowLanErrorRegKeySet
|
||
|
//
|
||
|
// Purpose: Check if the registry key is set:
|
||
|
// System\CurrentControlSet\Control\Network\Connections\StatMon\ShowLanErrors
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
BOOL CPspStatusMonitorGen::FIsShowLanErrorRegKeySet()
|
||
|
{
|
||
|
TraceFileFunc(ttidStatMon);
|
||
|
|
||
|
BOOL fRet = FALSE;
|
||
|
|
||
|
HKEY hkeyStatmonRoot = NULL;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// "System\\CurrentControlSet\\Control\\Network\\Connections\\StatMon\\ShowLanErrors"
|
||
|
hr = ::HrRegOpenKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
c_szRegKeyStatmonRoot,
|
||
|
KEY_READ,
|
||
|
&hkeyStatmonRoot);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
Assert(hkeyStatmonRoot);
|
||
|
|
||
|
DWORD dwValue =0;
|
||
|
hr = HrRegQueryDword(hkeyStatmonRoot, c_szShowLanErrors, &dwValue);
|
||
|
|
||
|
if SUCCEEDED(hr)
|
||
|
{
|
||
|
fRet = !!dwValue;
|
||
|
}
|
||
|
RegCloseKey(hkeyStatmonRoot);
|
||
|
}
|
||
|
|
||
|
return fRet;
|
||
|
}
|