//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1998. // // File: S M U T I L . C P P // // Contents: Utility functions to help out the status monitor // // Notes: // // Author: CWill 2 Dec 1997 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "netcon.h" #include "nsres.h" #include "sminc.h" const UINT c_uiKilo = 1000; const UINT c_cmsSecond = 1; const UINT c_cmsMinute = (c_cmsSecond * 60); const UINT c_cmsHour = (c_cmsMinute * 60); const UINT c_cmsDay = (c_cmsHour * 24); static const WCHAR c_szZero[] = L"0"; extern const WCHAR c_szSpace[]; struct StatusIconMapEntry { NETCON_MEDIATYPE ncm; BOOL fInbound; BOOL fTransmitting; BOOL fReceiving; INT iStatusIcon; }; static const StatusIconMapEntry c_SIMEArray[] = { // Mediatype // | Inbound // | | Transmitting // | | | Receiving // | | | | 32x32 Status Icon // | | | | | // v v v v v // Dial-up NCM_PHONE, FALSE, FALSE, FALSE, IDI_PO_NON_M_16, NCM_PHONE, FALSE, FALSE, TRUE, IDI_PO_RCV_M_16, NCM_PHONE, FALSE, TRUE, FALSE, IDI_PO_TRN_M_16, NCM_PHONE, FALSE, TRUE, TRUE, IDI_PO_CON_M_16, NCM_PHONE, TRUE, FALSE, FALSE, IDI_PI_NON_M_16, NCM_PHONE, TRUE, FALSE, TRUE, IDI_PI_RCV_M_16, NCM_PHONE, TRUE, TRUE, FALSE, IDI_PI_TRN_M_16, NCM_PHONE, TRUE, TRUE, TRUE, IDI_PI_CON_M_16, // LAN NCM_LAN, FALSE, FALSE, FALSE, IDI_LB_NON_M_16, NCM_LAN, FALSE, FALSE, TRUE, IDI_LB_RCV_M_16, NCM_LAN, FALSE, TRUE, FALSE, IDI_LB_TRN_M_16, NCM_LAN, FALSE, TRUE, TRUE, IDI_LB_CON_M_16, // Direct connect NCM_DIRECT, FALSE, FALSE, FALSE, IDI_DO_NON_M_16, NCM_DIRECT, FALSE, FALSE, TRUE, IDI_DO_RCV_M_16, NCM_DIRECT, FALSE, TRUE, FALSE, IDI_DO_TRN_M_16, NCM_DIRECT, FALSE, TRUE, TRUE, IDI_DO_CON_M_16, NCM_DIRECT, TRUE, FALSE, FALSE, IDI_DI_NON_M_16, NCM_DIRECT, TRUE, FALSE, TRUE, IDI_DI_RCV_M_16, NCM_DIRECT, TRUE, TRUE, FALSE, IDI_DI_TRN_M_16, NCM_DIRECT, TRUE, TRUE, TRUE, IDI_DI_CON_M_16, // Tunnel NCM_TUNNEL, FALSE, FALSE, FALSE, IDI_TO_NON_M_16, NCM_TUNNEL, FALSE, FALSE, TRUE, IDI_TO_RCV_M_16, NCM_TUNNEL, FALSE, TRUE, FALSE, IDI_TO_TRN_M_16, NCM_TUNNEL, FALSE, TRUE, TRUE, IDI_TO_CON_M_16, NCM_TUNNEL, TRUE, FALSE, FALSE, IDI_TI_NON_M_16, NCM_TUNNEL, TRUE, FALSE, TRUE, IDI_TI_RCV_M_16, NCM_TUNNEL, TRUE, TRUE, FALSE, IDI_TI_TRN_M_16, NCM_TUNNEL, TRUE, TRUE, TRUE, IDI_TI_CON_M_16, // ISDN NCM_ISDN, FALSE, FALSE, FALSE, IDI_PO_NON_M_16, NCM_ISDN, FALSE, FALSE, TRUE, IDI_PO_RCV_M_16, NCM_ISDN, FALSE, TRUE, FALSE, IDI_PO_TRN_M_16, NCM_ISDN, FALSE, TRUE, TRUE, IDI_PO_CON_M_16, NCM_ISDN, TRUE, FALSE, FALSE, IDI_PI_NON_M_16, NCM_ISDN, TRUE, FALSE, TRUE, IDI_PI_RCV_M_16, NCM_ISDN, TRUE, TRUE, FALSE, IDI_PI_TRN_M_16, NCM_ISDN, TRUE, TRUE, TRUE, IDI_PI_CON_M_16, // PPPoE NCM_PPPOE, FALSE, FALSE, FALSE, IDI_BR_NON_M_16, NCM_PPPOE, FALSE, FALSE, TRUE, IDI_BR_RCV_M_16, NCM_PPPOE, FALSE, TRUE, FALSE, IDI_BR_TRN_M_16, NCM_PPPOE, FALSE, TRUE, TRUE, IDI_BR_CON_M_16, // SHAREDACCESSHOST NCM_SHAREDACCESSHOST_LAN, FALSE, FALSE, FALSE, IDI_LB_NON_M_16, NCM_SHAREDACCESSHOST_LAN, FALSE, FALSE, TRUE, IDI_LB_RCV_M_16, NCM_SHAREDACCESSHOST_LAN, FALSE, TRUE, FALSE, IDI_LB_TRN_M_16, NCM_SHAREDACCESSHOST_LAN, FALSE, TRUE, TRUE, IDI_LB_CON_M_16, NCM_SHAREDACCESSHOST_RAS, FALSE, FALSE, FALSE, IDI_LB_NON_M_16, NCM_SHAREDACCESSHOST_RAS, FALSE, FALSE, TRUE, IDI_LB_RCV_M_16, NCM_SHAREDACCESSHOST_RAS, FALSE, TRUE, FALSE, IDI_LB_TRN_M_16, NCM_SHAREDACCESSHOST_RAS, FALSE, TRUE, TRUE, IDI_LB_CON_M_16, }; const DWORD g_dwStatusIconMapEntryCount = celems(c_SIMEArray); //+--------------------------------------------------------------------------- // // Function: HrGetPcpFromPnse // // Purpose: Gets the connection point off of an INetStatistics Engine // // Arguments: pnseSrc - The interface we want to get the connection // point off of // ppcpStatEng - Where to return the connection point // // Returns: Error code. // HRESULT HrGetPcpFromPnse( INetStatisticsEngine* pnseSrc, IConnectionPoint** ppcpStatEng) { HRESULT hr = S_OK; IConnectionPointContainer* pcpcStatEng = NULL; AssertSz(pnseSrc, "We should have a pnseSrc"); AssertSz(ppcpStatEng, "We should have a ppcpStatEng"); hr = pnseSrc->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast(&pcpcStatEng)); if (SUCCEEDED(hr)) { // Find the interface hr = pcpcStatEng->FindConnectionPoint( IID_INetConnectionStatisticsNotifySink, ppcpStatEng); // Release the connection point ReleaseObj(pcpcStatEng); } TraceError("HrGetPcpFromPnse", hr); return hr; } //+--------------------------------------------------------------------------- // // Member: IGetCurrentConnectionTrayIconId // // Purpose: Get the INetConnection pointer from the persisted data // // Arguments: ncmType - Media type // dwChangeFlags - What states have changed // // Returns: The id of the small icon for the connection or -1 on failure // // Notes: // INT IGetCurrentConnectionTrayIconId(NETCON_MEDIATYPE ncmType, NETCON_STATUS ncsStatus, DWORD dwChangeFlags) { INT iBaseIcon = -1; // Check the trans/recv flags to see what our base icon is. // if (ncsStatus == NCS_INVALID_ADDRESS) { iBaseIcon = IDI_CFT_INVALID_ADDRESS; } else { if (SMDCF_TRANSMITTING & dwChangeFlags) { if (SMDCF_RECEIVING & dwChangeFlags) { // Transmitting and receiving iBaseIcon = IDI_CFT_XMTRECV; } else { // Transmitting only iBaseIcon = IDI_CFT_XMT; } } else { if (SMDCF_RECEIVING & dwChangeFlags) { // Receiving only iBaseIcon = IDI_CFT_RECV; } else { // Neither transmitting nor receiving iBaseIcon = IDI_CFT_BLANK; } } } return iBaseIcon; } //+--------------------------------------------------------------------------- // // Member: GetCurrentConnectionStatusIconId // // Purpose: Get the INetConnection pointer from the persisted data // // Arguments: ncmType - Media type // ncsmType - SubMedia type // dwCharacteristics - Connection characteristics // dwChangeFlags - What states have changed // // Returns: The id of the small icon for the connection or -1 on failure // // Notes: // HICON GetCurrentConnectionStatusIconId( NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType, DWORD dwCharacteristics, DWORD dwChangeFlags) { HICON hMyIcon = NULL; DWORD dwLoop = 0; BOOL fValidIcon = FALSE; BOOL fTransmitting = !!(dwChangeFlags & SMDCF_TRANSMITTING); BOOL fReceiving = !!(dwChangeFlags & SMDCF_RECEIVING); INT iStatusIcon = -1; // Loop through the map and find the appropriate icon // DWORD dwConnectionIcon = 0x4; dwConnectionIcon |= fTransmitting ? 0x2 : 0; dwConnectionIcon |= fReceiving ? 0x1 : 0; HRESULT hr = HrGetIconFromMediaType(GetSystemMetrics(SM_CXICON), ncmType, ncsmType, dwConnectionIcon, (dwCharacteristics & NCCF_INCOMING_ONLY), &hMyIcon); if (FAILED(hr)) { return NULL; } return hMyIcon; } //+--------------------------------------------------------------------------- // // Member: FIsStringInList // // Purpose: To see if a string is in a string list // // Arguments: plstpstrList - The list in which the string is to be found // szString - The string being looked for // // Returns: TRUE if the string is in the list // FALSE otherwise (including the case where the list is empty) // // Notes: It is an case insensitive search // BOOL FIsStringInList(list* plstpstrList, const WCHAR* szString) { BOOL fRet = FALSE; // Only look in non-empty lists // if (!plstpstrList->empty()) { list::iterator iterLstpstr; iterLstpstr = plstpstrList->begin(); while ((!fRet) && (iterLstpstr != plstpstrList->end())) { // See if the string in the list matches the string we are // comparing against // if (!lstrcmpiW((*iterLstpstr)->c_str(), szString)) { fRet = TRUE; } iterLstpstr++; } } return fRet; } //+--------------------------------------------------------------------------- // // Function: FormatBytesPerSecond // // Purpose: To format nicely BPS into a readable string. // // Arguments: // uiBps [] // pchBuffer [] // // Returns: Number of characters put into the buffer. // INT FormatBytesPerSecond ( UINT64 uiBps, WCHAR* pchBuffer) { enum {eZero = 0, eKilo, eMega, eGiga, eTera, eMax}; const WCHAR* pszBPSFormat = NULL; INT iOffset = 0; UINT uiDecimal = 0; // Make sure our resources are still in the correct order // AssertSz(((((IDS_SM_BPS_ZERO + eKilo) == IDS_SM_BPS_KILO) && (IDS_SM_BPS_ZERO + eMega) == IDS_SM_BPS_MEGA) && ((IDS_SM_BPS_ZERO + eGiga) == IDS_SM_BPS_GIGA) && ((IDS_SM_BPS_ZERO + eTera) == IDS_SM_BPS_TERA)), "Someone's been messing with the BPS format strings"); for (iOffset = eZero; iOffset < eMax; iOffset++) { // If we still have data, increment the counter // if (c_uiKilo > uiBps) { break; } // Divide up the string // uiDecimal = (UINT)(uiBps % c_uiKilo); uiBps /= c_uiKilo; } // We only want one digit for the decimal // uiDecimal /= (c_uiKilo/10); // Get the string used to display // pszBPSFormat = SzLoadIds(IDS_SM_BPS_ZERO + iOffset); AssertSz(pszBPSFormat, "We need a format string for BPS"); // Create the string // return wsprintfW(pchBuffer, pszBPSFormat, uiBps, uiDecimal); } INT FormatTransmittingReceivingSpeed( UINT64 nTransmitSpeed, UINT64 nRecieveSpeed, WCHAR* pchBuf) { WCHAR* pch = pchBuf; pch += FormatBytesPerSecond(nTransmitSpeed, pch); if (nTransmitSpeed != nRecieveSpeed) { // Separate with a backslash. // lstrcatW(pch, L"\\"); pch += 1; pch += FormatBytesPerSecond(nRecieveSpeed, pch); } return lstrlenW(pchBuf); } //+--------------------------------------------------------------------------- // // Function: FormatTimeDuration // // Purpose: Takes a millisecond count and formats a string with the // duration represented by the millisecond count. // // Arguments: // uiMilliseconds [] // pstrOut [] // // Returns: nothing // VOID FormatTimeDuration(UINT uiSeconds, tstring* pstrOut) { WCHAR achSep[4]; WCHAR achBuf[64]; UINT uiNumTemp; AssertSz(pstrOut, "We should have a pstrOut"); // Get the seperator for the locale. // SideAssert(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, achSep, celems(achSep))); // // Concatenate the strings together // // Add the days if there are more than zero // uiNumTemp = (uiSeconds / c_cmsDay); if (uiNumTemp > 0) { pstrOut->append(_itow(uiNumTemp, achBuf, 10)); uiSeconds %= c_cmsDay; if (uiNumTemp>1) pstrOut->append(SzLoadIds(IDS_Days)); else pstrOut->append(SzLoadIds(IDS_Day)); pstrOut->append(c_szSpace); } // Append hours // uiNumTemp = (uiSeconds / c_cmsHour); if (10 > uiNumTemp) { pstrOut->append(c_szZero); } pstrOut->append(_itow(uiNumTemp, achBuf, 10)); pstrOut->append(achSep); uiSeconds %= c_cmsHour; // Append minutes // uiNumTemp = (uiSeconds / c_cmsMinute); if (10 > uiNumTemp) { pstrOut->append(c_szZero); } pstrOut->append(_itow(uiNumTemp, achBuf, 10)); pstrOut->append(achSep); uiSeconds %= c_cmsMinute; // Append seconds // uiNumTemp = (uiSeconds / c_cmsSecond); if (10 > uiNumTemp) { pstrOut->append(c_szZero); } pstrOut->append(_itow(uiNumTemp, achBuf, 10)); }