windows-nt/Source/XPSP1/NT/net/snmp/subagent/snmpevnt/evntwin/utils.cpp

519 lines
13 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "stdafx.h"
#include "utils.h"
#include "globals.h"
#include "trapreg.h"
//***************************************************************************
//
// MapEventToSeverity
//
// Extract the severity field from the event ID and convert it to a
// string equivallent.
//
// Parameters:
// DWORD dwEvent
// The full event ID
//
// CString& sResult
// The severity code string is returned here.
//
// Returns:
// The severity code string is returned via sResult.
//
// Status:
//
//***************************************************************************
void MapEventToSeverity(DWORD dwEvent, CString& sResult)
{
//
// Values are 32 bit event ID values layed out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
//
//
// Define the facility codes
static UINT auiResource[4] =
{IDS_EVENT_SEV_SUCCESS,
IDS_EVENT_SEV_INFORMATIONAL,
IDS_EVENT_SEV_WARNING,
IDS_EVENT_SEV_ERROR
};
int iSeverity = (dwEvent >> 30) & 3;
sResult.LoadString(auiResource[iSeverity]);
}
//********************************************************************************
// FindSubstring
//
// Find a substring in some text and return an index to the starting
// position of the string if it is found.
//
// Parameters:
// LPCSTR pszTemplate
// Pointer to the string to find.
//
// LPCSTR pszText
// Pointer to the text that will be searched
// for the template string.
//
// Returns:
// An index to the location of the substring within the text if it
// is found, otherwise -1.
//
//********************************************************************************
LONG FindSubstring(LPCTSTR pszTemplate, LPCTSTR pszText)
{
if (*pszTemplate == 0) {
// An empty template string matches anything, so return zero.
// This should never really happen since it doesn't make much
// sense to search for nothing.
return 0;
}
LPCTSTR pszTextStart = pszText;
while (*pszText) {
// Iterate through the character positions in the text
// and return the index to the starting char in the string
// if it is found.
LPCTSTR pch1 = pszTemplate;
LPCTSTR pch2 = pszText;
while (*pch1 && (*pch1 == *pch2))
{
++pch1;
++pch2;
}
if (*pch1 == 0) {
// We reached the end of the template string, so there
// must have been a match.
return (LONG)(pszText - pszTextStart);
}
++pszText;
}
// Failed to find the substring
return -1;
}
//********************************************************************************
// FindWholeWord
//
// Find a whole word in some text and return an index to the starting
// position of the whole word if it is found. Whole word means the
// specified template string followed by a whitespace or end of string.
//
// Parameters:
// LPCSTR pszTemplate
// Pointer to the "whole word" string to find.
//
// LPCSTR pszText
// Pointer to the text that will be searched
// for the template string.
//
// Returns:
// An index to the location of the "whole word" substring within the text if it
// is found, otherwise -1.
//
//********************************************************************************
LONG FindWholeWord(LPCTSTR pszTemplate, LPCTSTR pszText)
{
if (*pszTemplate == 0) {
// An empty search string matches anything, so return the index
// of the first character.
return 0;
}
// Iterate through each character position checking for a whole-word
// match at each position.
LONG nchTemplate = _tcslen(pszTemplate);
LPCTSTR pszTextStart = pszText;
LPCTSTR pchTextLimit = pszText + (_tcslen(pszText) - nchTemplate);
while (pszText <= pchTextLimit) {
// Check to see if the word is contained anywhere within the text
INT iPos = FindSubstring(pszTemplate, pszText);
if (iPos == -1) {
return -1;
}
// Point at the location of the template string within the text
pszText += iPos;
// Get the prefix character
INT ichPrefix;
if (pszText == pszTextStart) {
// Beginning of line counts as white space.
ichPrefix = _T(' ');
}
else {
ichPrefix = *(pszText - 1);
}
// Get the suffix character.
INT ichSuffix = pszText[nchTemplate];
if (ichSuffix == 0) {
// End of line counts as whitespace
ichSuffix = _T(' ');
}
// To match a whole word, the word must be bounded on either side
// by whitespace.
if (isspace(ichPrefix) && isspace(ichSuffix)) {
return (LONG)(pszText - pszTextStart);
}
// Bump the text pointer to the next position so we don't do the
// same thing all over again.
++pszText;
}
return -1;
}
void DecString(CString& sValue, int iValue)
{
// 32 bytes should be enough to hold any value
TCHAR szValue[32];
_itot(iValue, szValue, 10);
sValue = szValue;
}
void DecString(CString& sValue, long lValue)
{
// 32 bytes should be enough to hold any value
TCHAR szValue[32];
_ltot(lValue, szValue, 10);
sValue = szValue;
}
void DecString(CString& sValue, DWORD dwValue)
{
TCHAR szValue[32];
_ultot(dwValue, szValue, 10);
sValue = szValue;
}
CList::CList()
{
m_pndPrev = this;
m_pndNext = this;
}
void CList::Link(CList*& pndHead)
{
if (pndHead == NULL)
pndHead = this;
else
{
m_pndNext = pndHead;
m_pndPrev = pndHead->m_pndPrev;
m_pndPrev->m_pndNext = this;
m_pndNext->m_pndPrev = this;
}
}
void CList::Unlink(CList*& pndHead)
{
if (pndHead == this)
{
if (m_pndNext == this)
pndHead = NULL;
else
pndHead = m_pndNext;
}
m_pndPrev->m_pndNext = m_pndNext;
m_pndNext->m_pndPrev = m_pndPrev;
}
//***************************************************************
// GetFormattedValue
//
// Convert a value to ASCII and insert thousand separator characters
// into resulting value string.
//
// Parameters:
// CString& sValueDst
// The place to return the converted value.
//
// LONG lValue
// The value to convert.
//
//*****************************************************************
void GetFormattedValue(CString& sValueDst, LONG lValue)
{
CString sValueSrc;
DecString(sValueSrc, lValue);
LONG nch = sValueSrc.GetLength();
LPCTSTR pszSrc = sValueSrc;
// Get a buffer as large as the source string plus the largest number of commas
// plus one for the sign, one for the null terminator plus one character for slop.
LPTSTR pszDst = sValueDst.GetBuffer(nch + nch / 3 + 3);
// Copy any leading sign character.
if ((*pszSrc == _T('+')) || (*pszSrc == _T('-'))) {
*pszDst++ = *pszSrc++;
--nch;
}
// Now copy the rest of the number and insert thousand separator characters in
// the appropriate positions.
LONG nchInitial = nch;
while (nch > 0) {
if ((nch % 3) == 0) {
if (nch != nchInitial) {
*pszDst++ = g_chThousandSep;
}
}
*pszDst++ = *pszSrc++;
--nch;
}
*pszDst = _T('\0');
sValueDst.ReleaseBuffer();
}
//**************************************************************
// GenerateRangeMessage
//
// Generate a message indicating that the user should enter a value
// between some numbers nMin and nMax.
//
// Parameters:
// CString& sMessage
// The place to return the message.
//
// LONG nMin
// The minimum valid value in the range.
//
// LONG nMax
// The maximum valid value in the range.
//
//****************************************************************
void GenerateRangeMessage(CString& sMessage, LONG nMin, LONG nMax)
{
CString sText;
sMessage.LoadString(IDS_RANGE_MESSAGE_PREFIX);
sMessage += _T(' ');
GetFormattedValue(sText, nMin);
sMessage += sText;
sMessage += _T(' ');
sText.LoadString(IDS_RANGE_VALUE_SEPARATOR);
sMessage += sText;
sMessage += _T(' ');
GetFormattedValue(sText, nMax);
sMessage += sText;
sText.LoadString(IDS_SENTENCE_TERMINATOR);
sMessage += sText;
}
//***************************************************************************
// GetThousandSeparator
//
// Get the thousand separator character for the current locale.
//
// Parameters:
// TCHAR* pchThousandSep
// Pointer to the place to return the thousand separator character.
//
// Returns:
// SCODE
// S_OK if the thousand separator was returned.
// E_FAIL if the thousand separator was not returned.
//
//**************************************************************************
SCODE GetThousandSeparator(TCHAR* pchThousandSep)
{
// Digit + separator + 3 digits + decimal + two digits + null terminator + 4 slop
#define MAX_CHARS_THOUSAND 12
CString sValue;
LPTSTR pszValue = sValue.GetBuffer(MAX_CHARS_THOUSAND);
GetNumberFormat(NULL, 0, _T("1000"), NULL, pszValue, MAX_CHARS_THOUSAND);
sValue.ReleaseBuffer();
TCHAR ch = sValue[1];
if (isdigit(ch)) {
return E_FAIL;
}
*pchThousandSep = ch;
return S_OK;
}
//***********************************************************************
// IsDecimalInteger
//
// This function tests a string to see whether or not it contains a
// valid integer expression.
//
// Parameters:
// LPCTSTR pszValue
// Pointer to the string to test.
//
// Returns:
// BOOL
// TRUE = The string contained a valid integer expression.
// FALSE = The string did not contain a valid integer expression.
//
//***********************************************************************
BOOL IsDecimalInteger(LPCTSTR pszValue)
{
// Accept leading white space
while (iswspace(*pszValue)) {
++pszValue;
}
// Accept a leading plus or minus sign
if ((*pszValue == _T('+')) || (*pszValue == _T('-'))) {
++pszValue;
}
// Skip a string of consecutive digits with embedded thousand separators
BOOL bSawThousandSep = FALSE;
LONG nDigits = 0;
while (TRUE) {
if (*pszValue == g_chThousandSep) {
if (nDigits > 3) {
return FALSE;
}
bSawThousandSep = TRUE;
nDigits = 0;
}
else if (isdigit(*pszValue)) {
++nDigits;
}
else {
break;
}
++pszValue;
}
if (bSawThousandSep && nDigits != 3) {
// If a thousand separater was encountered, then there must be
// three digits to the right of the last thousand separator.
return FALSE;
}
// Accept trailing whitespace
if (iswspace(*pszValue)) {
++pszValue;
}
if (*pszValue == _T('\0')) {
// We reached the end of the string, so it must have been a decimal integer.
return TRUE;
}
else {
// We did not rech the end of the string, so it couldn't have been a valid
// decimal integer value.
return FALSE;
}
}
//***************************************************************************
// AsciiToLong
//
// This function first validates a string to make sure that it is a properly
// formatted integer expression, and then converts it to a long. Any embedded
// characters, such as the thousand separator, are stripped out before the
// conversion is done.
//
//
// Parameters:
// LPCTSTR pszValue
// Pointer to the string value to convert.
//
// LONG* plResult
// Pointer to the place to store the result.
//
// Returns:
// SCODE
// S_OK = The string contained a valid integer and the converted
// value was returned via plResult.
// E_FAIL = The string did not contain a properly formatted integer
// expression.
//
//
//**************************************************************************
SCODE AsciiToLong(LPCTSTR pszValue, LONG* plResult)
{
if (!IsDecimalInteger(pszValue)) {
return E_FAIL;
}
// Strip out any superfluous characters, such as the thousand separator
// before converting from ascii to long.
CString sStrippedValue;
LPTSTR pszDst = sStrippedValue.GetBuffer(_tcslen(pszValue) + 1);
TCHAR ch;
while (ch = *pszValue++) {
if (isdigit(ch) || ch==_T('+') || ch==_T('-')) {
*pszDst++ = ch;
}
}
*pszDst = 0;
sStrippedValue.ReleaseBuffer();
*plResult = _ttol(sStrippedValue);
return S_OK;
}