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.
 
 
 
 
 
 

1336 lines
37 KiB

/*++
Copyright (C) 1998-1999 Microsoft Corporation
Module Name:
smalrtq.cpp
Abstract:
Implementation of the alert query class
--*/
#include "Stdafx.h"
#include <pdhp.h> // for MIN_TIME_VALUE, MAX_TIME_VALUE
#include <pdhmsg.h>
#include "smlogs.h"
#include "common.h"
#include "smalrtq.h"
USE_HANDLE_MACROS("SMLOGCFG(smalrtq.cpp)");
#define ALRT_DEFAULT_COMMAND_FILE L""
#define ALRT_DEFAULT_NETWORK_NAME L""
#define ALRT_DEFAULT_USER_TEXT L""
#define ALRT_DEFAULT_PERF_LOG_NAME L""
//
// Constructor
CSmAlertQuery::CSmAlertQuery( CSmLogService* pLogService )
: CSmLogQuery( pLogService ),
m_dwCounterListLength ( 0 ),
m_szNextCounter ( NULL ),
mr_szCounterList ( NULL ),
mr_dwActionFlags ( ALRT_DEFAULT_ACTION )
{
memset (&mr_stiSampleInterval, 0, sizeof(mr_stiSampleInterval));
return;
}
//
// Destructor
CSmAlertQuery::~CSmAlertQuery()
{
return;
}
//
// Open function. either opens an existing log query entry
// or creates a new one
//
DWORD
CSmAlertQuery::Open ( const CString& rstrName, HKEY hKeyQuery, BOOL bReadOnly)
{
DWORD dwStatus = ERROR_SUCCESS;
ASSERT ( SLQ_ALERT == GetLogType() );
dwStatus = CSmLogQuery::Open ( rstrName, hKeyQuery, bReadOnly );
return dwStatus;
}
//
// Close Function
// closes registry handles and frees allocated memory
//
DWORD
CSmAlertQuery::Close ()
{
DWORD dwStatus;
LOCALTRACE (L"Closing Query\n");
if (mr_szCounterList != NULL) {
delete (mr_szCounterList);
mr_szCounterList = NULL;
}
mr_strNetName.Empty();
mr_strCmdFileName.Empty();
mr_strCmdUserText.Empty();
mr_strCmdUserTextIndirect.Empty();
mr_strPerfLogName.Empty();
dwStatus = CSmLogQuery::Close();
return dwStatus;
}
//
// UpdateRegistry function.
// copies the current settings to the registry where they
// are read by the log service
//
DWORD
CSmAlertQuery::UpdateRegistry()
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwBufferSize = 0;
LPTSTR szNewCounterList = NULL;
if ( IsModifiable() ) {
dwBufferSize = 0;
//
// Translate the counter list into English
//
dwStatus = TranslateMSZAlertCounterList(mr_szCounterList,
NULL,
&dwBufferSize,
FALSE);
if (dwStatus == ERROR_NOT_ENOUGH_MEMORY) {
szNewCounterList = (LPTSTR) new char [dwBufferSize];
if (szNewCounterList != NULL) {
dwStatus = TranslateMSZAlertCounterList(mr_szCounterList,
szNewCounterList,
&dwBufferSize,
FALSE);
}
}
if (dwStatus == ERROR_SUCCESS && szNewCounterList != NULL) {
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_COUNTER_LIST,
REG_MULTI_SZ,
szNewCounterList,
&dwBufferSize);
}
else {
dwBufferSize = m_dwCounterListLength * sizeof(TCHAR);
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_COUNTER_LIST,
REG_MULTI_SZ,
mr_szCounterList,
&dwBufferSize);
}
// Schedule
if ( ERROR_SUCCESS == dwStatus ) {
dwStatus = WriteRegistrySlqTime (
m_hKeyQuery,
IDS_REG_SAMPLE_INTERVAL,
&mr_stiSampleInterval);
}
if ( ERROR_SUCCESS == dwStatus ) {
if ( !mr_strCmdFileName.IsEmpty() ) {
dwBufferSize = mr_strCmdFileName.GetLength() + 1;
dwBufferSize *= sizeof(TCHAR);
} else {
dwBufferSize = 0;
}
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_COMMAND_FILE,
REG_SZ,
mr_strCmdFileName,
&dwBufferSize);
}
if ( ERROR_SUCCESS == dwStatus ) {
if ( !mr_strNetName.IsEmpty() ) {
dwBufferSize = mr_strNetName.GetLength() + 1;
dwBufferSize *= sizeof(TCHAR);
} else {
dwBufferSize = 0;
}
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_NETWORK_NAME,
REG_SZ,
mr_strNetName,
&dwBufferSize);
}
if ( ERROR_SUCCESS == dwStatus ) {
if ( !mr_strCmdUserText.IsEmpty() ) {
dwBufferSize = mr_strCmdUserText.GetLength() + 1;
dwBufferSize *= sizeof(TCHAR);
} else {
dwBufferSize = 0;
}
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_USER_TEXT,
REG_SZ,
mr_strCmdUserText,
&dwBufferSize);
}
if ( ERROR_SUCCESS == dwStatus && !mr_strCmdUserTextIndirect.IsEmpty() ) {
dwBufferSize = mr_strCmdUserTextIndirect.GetLength() + 1;
dwBufferSize *= sizeof(TCHAR);
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_USER_TEXT,
REG_SZ,
mr_strCmdUserTextIndirect,
&dwBufferSize);
}
if ( ERROR_SUCCESS == dwStatus ) {
if ( !mr_strPerfLogName.IsEmpty() ) {
dwBufferSize = mr_strPerfLogName.GetLength() + 1;
dwBufferSize *= sizeof(TCHAR);
} else {
dwBufferSize = 0;
}
dwStatus = WriteRegistryStringValue (
m_hKeyQuery,
IDS_REG_PERF_LOG_NAME,
REG_SZ,
mr_strPerfLogName,
&dwBufferSize);
}
if ( ERROR_SUCCESS == dwStatus ) {
dwStatus = WriteRegistryDwordValue(
m_hKeyQuery,
IDS_REG_ACTION_FLAGS,
&mr_dwActionFlags,
REG_DWORD);
}
if ( ERROR_SUCCESS == dwStatus ) {
dwStatus = CSmLogQuery::UpdateRegistry ();
}
} else {
dwStatus = ERROR_ACCESS_DENIED;
}
return dwStatus;
}
//
// SyncWithRegistry()
// reads the current values for this query from the registry
// and reloads the internal values to match
//
DWORD
CSmAlertQuery::SyncWithRegistry()
{
DWORD dwBufferSize = 0;
DWORD dwStatus = ERROR_SUCCESS;
SLQ_TIME_INFO stiDefault;
LPTSTR pszTemp = NULL;
LPWSTR szIndTemp = NULL;
UINT uiBufferLen = 0;
CString strValueName;
LPTSTR szNewCounterList = NULL;
ASSERT (m_hKeyQuery != NULL);
// load counter string list
// Get Counter List
dwStatus = ReadRegistryStringValue (
m_hKeyQuery,
IDS_REG_COUNTER_LIST,
NULL,
&mr_szCounterList,
&dwBufferSize);
if (dwStatus != ERROR_SUCCESS) {
m_szNextCounter = NULL; //re-initialize
m_dwCounterListLength = 0;
} else {
// convert buffersize to chars from bytes
m_dwCounterListLength = dwBufferSize / sizeof(TCHAR);
//
// Translate the counter list into Locale
//
dwBufferSize = 0;
dwStatus = TranslateMSZAlertCounterList(
mr_szCounterList,
NULL,
&dwBufferSize,
TRUE);
if (dwStatus == ERROR_NOT_ENOUGH_MEMORY) {
szNewCounterList = (LPTSTR) new char [dwBufferSize];
if (szNewCounterList != NULL) {
//
// Translate the counter list into Locale
//
dwStatus = TranslateMSZAlertCounterList(
mr_szCounterList,
szNewCounterList,
&dwBufferSize,
TRUE);
if (dwStatus == ERROR_SUCCESS) {
m_dwCounterListLength = dwBufferSize / sizeof(TCHAR);
//
// Remove the old
//
delete (mr_szCounterList);
m_szNextCounter = NULL;
mr_szCounterList = szNewCounterList;
}
}
}
}
// Schedule
stiDefault.wDataType = SLQ_TT_DTYPE_UNITS;
stiDefault.wTimeType = SLQ_TT_TTYPE_SAMPLE;
stiDefault.dwAutoMode = SLQ_AUTO_MODE_AFTER;
stiDefault.dwValue = 5; // default interval;
stiDefault.dwUnitType = SLQ_TT_UTYPE_SECONDS;
dwStatus = ReadRegistrySlqTime (
m_hKeyQuery,
IDS_REG_SAMPLE_INTERVAL,
&stiDefault,
&mr_stiSampleInterval);
ASSERT (dwStatus == ERROR_SUCCESS);
dwBufferSize = 0;
dwStatus = ReadRegistryStringValue (
m_hKeyQuery,
IDS_REG_COMMAND_FILE,
ALRT_DEFAULT_COMMAND_FILE,
&pszTemp,
&dwBufferSize);
ASSERT (dwStatus == ERROR_SUCCESS);
mr_strCmdFileName.Empty();
if ( dwBufferSize > sizeof(TCHAR) ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != *pszTemp );
mr_strCmdFileName = pszTemp;
}
delete ( pszTemp );
pszTemp = NULL;
dwBufferSize = 0;
dwStatus = ReadRegistryStringValue (
m_hKeyQuery,
IDS_REG_NETWORK_NAME,
ALRT_DEFAULT_NETWORK_NAME,
&pszTemp,
&dwBufferSize);
ASSERT (dwStatus == ERROR_SUCCESS);
mr_strNetName.Empty();
if ( dwBufferSize > sizeof(TCHAR) ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != *pszTemp );
mr_strNetName = pszTemp;
}
delete ( pszTemp );
pszTemp = NULL;
dwBufferSize = 0;
// User text field can be indirect
MFC_TRY
strValueName.LoadString ( IDS_REG_USER_TEXT );
MFC_CATCH_DWSTATUS;
if ( ERROR_SUCCESS == dwStatus ) {
dwStatus = SmReadRegistryIndirectStringValue (
m_hKeyQuery,
strValueName,
ALRT_DEFAULT_USER_TEXT,
&szIndTemp,
&uiBufferLen );
}
mr_strCmdUserText.Empty();
if ( NULL != szIndTemp ) {
if ( _T('\0') != *szIndTemp ) {
mr_strCmdUserText = szIndTemp;
}
}
if ( NULL != szIndTemp ) {
G_FREE ( szIndTemp );
szIndTemp = NULL;
}
uiBufferLen = 0;
dwStatus = ReadRegistryStringValue (
m_hKeyQuery,
IDS_REG_PERF_LOG_NAME,
ALRT_DEFAULT_PERF_LOG_NAME,
&pszTemp,
&dwBufferSize);
ASSERT (dwStatus == ERROR_SUCCESS);
mr_strPerfLogName.Empty();
if ( dwBufferSize > sizeof(TCHAR) ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != *pszTemp );
mr_strPerfLogName = pszTemp;
}
delete ( pszTemp );
pszTemp = NULL;
dwBufferSize = 0;
dwStatus = ReadRegistryDwordValue (
m_hKeyQuery,
IDS_REG_ACTION_FLAGS,
ALRT_DEFAULT_ACTION,
&mr_dwActionFlags);
ASSERT ( ERROR_SUCCESS == dwStatus );
// Call parent class last to update shared values.
dwStatus = CSmLogQuery::SyncWithRegistry();
ASSERT (dwStatus == ERROR_SUCCESS);
return dwStatus;
}
BOOL
CSmAlertQuery::GetLogTime ( PSLQ_TIME_INFO pTimeInfo, DWORD dwFlags )
{
BOOL bStatus;
ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
|| ( SLQ_TT_TTYPE_STOP == dwFlags )
|| ( SLQ_TT_TTYPE_RESTART == dwFlags )
|| ( SLQ_TT_TTYPE_SAMPLE == dwFlags ) );
bStatus = CSmLogQuery::GetLogTime( pTimeInfo, dwFlags );
return bStatus;
}
BOOL
CSmAlertQuery::SetLogTime ( PSLQ_TIME_INFO pTimeInfo, const DWORD dwFlags )
{
BOOL bStatus;
ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
|| ( SLQ_TT_TTYPE_STOP == dwFlags )
|| ( SLQ_TT_TTYPE_RESTART == dwFlags )
|| ( SLQ_TT_TTYPE_SAMPLE == dwFlags ) );
bStatus = CSmLogQuery::SetLogTime( pTimeInfo, dwFlags );
return bStatus;
}
BOOL
CSmAlertQuery::GetDefaultLogTime(SLQ_TIME_INFO& rTimeInfo, DWORD dwFlags )
{
ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
|| ( SLQ_TT_TTYPE_STOP == dwFlags ) );
rTimeInfo.wTimeType = (WORD)dwFlags;
rTimeInfo.wDataType = SLQ_TT_DTYPE_DATETIME;
if ( SLQ_TT_TTYPE_START == dwFlags ) {
SYSTEMTIME stLocalTime;
FILETIME ftLocalTime;
// Milliseconds set to 0 for Schedule times
GetLocalTime (&stLocalTime);
stLocalTime.wMilliseconds = 0;
SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_AT;
rTimeInfo.llDateTime = *(LONGLONG *)&ftLocalTime;
} else {
// Default stop values
rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_NONE;
rTimeInfo.llDateTime = MAX_TIME_VALUE;
}
return TRUE;
}
BOOL
CSmAlertQuery::GetActionInfo( PALERT_ACTION_INFO pInfo, LPDWORD pdwInfoBufSize)
{
DWORD dwSizeRequired = sizeof (ALERT_ACTION_INFO);
BOOL bReturn = FALSE;
LPWSTR szNextString;
// compute required size
if (pdwInfoBufSize == NULL) {
return FALSE;
}
if ( !mr_strNetName.IsEmpty() ) {
dwSizeRequired += ( mr_strNetName.GetLength() + 1 ) * sizeof(TCHAR);
}
if ( !mr_strCmdFileName.IsEmpty() ) {
dwSizeRequired += ( mr_strCmdFileName.GetLength() + 1 ) * sizeof(TCHAR);
}
if ( !mr_strCmdUserText.IsEmpty() ) {
dwSizeRequired += ( mr_strCmdUserText.GetLength() + 1 ) * sizeof(TCHAR);
}
if ( !mr_strPerfLogName.IsEmpty() ) {
dwSizeRequired += ( mr_strPerfLogName.GetLength() + 1 ) * sizeof(TCHAR);
}
if (dwSizeRequired <= *pdwInfoBufSize) {
// clear the caller's buffer before we start filling it
if (pInfo != NULL) {
memset (pInfo, 0, *pdwInfoBufSize);
pInfo->dwSize = dwSizeRequired;
pInfo->dwActionFlags = mr_dwActionFlags;
szNextString = (LPWSTR)&pInfo[1];
if ( !mr_strNetName.IsEmpty() ) {
pInfo->szNetName = szNextString;
lstrcpyW(szNextString, mr_strNetName);
szNextString += lstrlen(szNextString) + 1;
}
if ( !mr_strCmdFileName.IsEmpty() ) {
pInfo->szCmdFilePath = szNextString;
lstrcpyW(szNextString, mr_strCmdFileName);
szNextString += lstrlen(szNextString) + 1;
}
if ( !mr_strCmdUserText.IsEmpty() ) {
pInfo->szUserText = szNextString;
lstrcpyW(szNextString, mr_strCmdUserText);
szNextString += lstrlen(szNextString) + 1;
}
if ( !mr_strPerfLogName.IsEmpty() ) {
pInfo->szLogName = szNextString;
lstrcpyW(szNextString, mr_strPerfLogName);
szNextString += lstrlen(szNextString) + 1;
}
bReturn = TRUE;
}
}
*pdwInfoBufSize = dwSizeRequired;
return bReturn;
}
DWORD
CSmAlertQuery::SetActionInfo( PALERT_ACTION_INFO pInfo )
{
DWORD dwStatus = ERROR_SUCCESS;
if (pInfo != NULL) {
// Update action values with those from the structure
MFC_TRY
mr_dwActionFlags = pInfo->dwActionFlags;
mr_strNetName.Empty();
if ( NULL != pInfo->szNetName ) {
mr_strNetName = pInfo->szNetName;
}
mr_strCmdFileName.Empty();
if ( NULL != pInfo->szCmdFilePath ) {
mr_strCmdFileName = pInfo->szCmdFilePath;
}
mr_strCmdUserText.Empty();
if ( NULL != pInfo->szUserText ) {
mr_strCmdUserText = pInfo->szUserText;
}
mr_strPerfLogName.Empty();
if ( NULL != pInfo->szLogName ) {
mr_strPerfLogName = pInfo->szLogName;
}
MFC_CATCH_DWSTATUS
} else {
dwStatus = ERROR_INVALID_PARAMETER;
}
// Todo: Handle return status
return dwStatus;
}
//
// Get first counter in counter list
//
LPCWSTR
CSmAlertQuery::GetFirstCounter()
{
LPWSTR szReturn;
szReturn = mr_szCounterList;
if (szReturn != NULL) {
if (*szReturn == 0) {
// then it's an empty string
szReturn = NULL;
m_szNextCounter = NULL;
} else {
m_szNextCounter = szReturn + lstrlen(szReturn) + 1;
if (*m_szNextCounter == 0) {
// end of list reached so set pointer to NULL
m_szNextCounter = NULL;
}
}
} else {
// no buffer allocated yet
m_szNextCounter = NULL;
}
return (LPCWSTR)szReturn;
}
//
// Get next counter in counter list
// NULL pointer means no more counters in list
//
LPCWSTR
CSmAlertQuery::GetNextCounter()
{
LPWSTR szReturn;
szReturn = m_szNextCounter;
if (m_szNextCounter != NULL) {
m_szNextCounter += lstrlen(szReturn) + 1;
if (*m_szNextCounter == 0) {
// end of list reached so set pointer to NULL
m_szNextCounter = NULL;
}
} else {
// already at the end of the list so nothing to do
}
return (LPCWSTR)szReturn;
}
//
// clear out the counter list
//
VOID
CSmAlertQuery::ResetCounterList()
{
if (mr_szCounterList != NULL) {
delete (mr_szCounterList);
m_szNextCounter = NULL;
mr_szCounterList = NULL;
}
m_dwCounterListLength = sizeof(WCHAR); // sizeof MSZ Null
try {
mr_szCounterList = new WCHAR [m_dwCounterListLength];
mr_szCounterList[0] = 0;
} catch ( ... ) {
m_dwCounterListLength = 0;
}
}
//
// Add this counter string to the internal list
//
BOOL
CSmAlertQuery::AddCounter(LPCWSTR szCounterPath)
{
DWORD dwNewSize;
LPWSTR szNewString;
LPWSTR szNextString;
ASSERT (szCounterPath != NULL);
if (szCounterPath == NULL) return FALSE;
dwNewSize = lstrlen(szCounterPath) + 1;
if (m_dwCounterListLength <= 2) {
dwNewSize += 1; // add room for the MSZ null
// then this is the first string to go in the list
try {
szNewString = new TCHAR [dwNewSize];
} catch ( ... ) {
return FALSE; // leave now
}
szNextString = szNewString;
} else {
dwNewSize += m_dwCounterListLength;
// this is the nth string to go in the list
try {
szNewString = new TCHAR [dwNewSize];
} catch ( ... ) {
return FALSE; // leave now
}
memcpy (szNewString, mr_szCounterList,
(m_dwCounterListLength * sizeof(TCHAR)));
szNextString = szNewString;
szNextString += m_dwCounterListLength - 1;
}
lstrcpyW (szNextString, szCounterPath);
szNextString = szNewString;
szNextString += dwNewSize - 1;
*szNextString = 0; // MSZ Null
if (mr_szCounterList != NULL) delete (mr_szCounterList);
mr_szCounterList = szNewString;
m_szNextCounter = szNewString;
m_dwCounterListLength = dwNewSize;
return TRUE;
}
DWORD
CSmAlertQuery::GetLogType()
{
return ( SLQ_ALERT );
}
BOOL
CSmAlertQuery::SetLogFileType ( const DWORD /* dwType */)
{
// No alert log file type
return FALSE;
}
//
// Get log file type and return as a string
//
//
const CString&
CSmAlertQuery::GetLogFileType ( )
{
return cstrEmpty;
}
void
CSmAlertQuery::GetLogFileType ( DWORD& rdwFileType )
{
// Log file type should default in property bags.
ASSERT ( FALSE );
rdwFileType = ((DWORD)0xFFFFFFFF);
return;
}
LPCWSTR
CSmAlertQuery::GetCounterList( LPDWORD pcchListSize)
{
if (pcchListSize != NULL) *pcchListSize = m_dwCounterListLength;
return mr_szCounterList;
}
BOOL CSmAlertQuery::SetCounterList( LPCWSTR mszCounterList, DWORD cchListSize)
{
BOOL bReturn = TRUE;
if (mr_szCounterList != NULL) {
delete (mr_szCounterList);
mr_szCounterList = NULL;
m_dwCounterListLength = 0;
}
try {
mr_szCounterList = new TCHAR [cchListSize];
memcpy (mr_szCounterList, mszCounterList, (cchListSize * sizeof(TCHAR)));
m_dwCounterListLength = cchListSize;
} catch ( ... ) {
bReturn = FALSE;
}
return bReturn;
}
const CString&
CSmAlertQuery::GetLogFileName( BOOL )
{
// 2000.1 return empty string so that empty string is written to HTML file for alerts.
return cstrEmpty;
}
HRESULT
CSmAlertQuery::LoadCountersFromPropertyBag (
IPropertyBag* pPropBag,
IErrorLog* pIErrorLog )
{
HRESULT hr = S_OK;
PDH_STATUS pdhStatus;
DWORD dwCount;
DWORD dwIndex;
CString strParamName;
LPTSTR szLocaleBuf = NULL;
DWORD dwLocaleBufSize = 0;
LPTSTR pszPath;
PALERT_INFO_BLOCK paibInfo = NULL;
hr = DwordFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_SYSMON_COUNTERCOUNT,
0,
dwCount);
for ( dwIndex = 1; dwIndex <= dwCount; dwIndex++ ) {
LPTSTR szCounterPath = NULL;
DWORD dwBufSize = 0;
DWORD dwByteCount = 0;
DWORD dwOverUnder;
DOUBLE dThreshold;
LPTSTR pNewBuf;
strParamName.Format ( IDS_HTML_SYSMON_COUNTERPATH, dwIndex );
hr = StringFromPropertyBag (
pPropBag,
pIErrorLog,
strParamName,
L"",
&szCounterPath,
&dwBufSize );
pszPath = szCounterPath;
if (dwBufSize > sizeof(TCHAR)) {
//
// Initialize the locale path buffer
//
if (dwLocaleBufSize == 0) {
dwLocaleBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
szLocaleBuf = (LPTSTR) G_ALLOC(dwLocaleBufSize);
if (szLocaleBuf == NULL) {
dwLocaleBufSize = 0;
}
}
if (szLocaleBuf != NULL) {
//
// Translate counter name from English to Localization
//
dwBufSize = dwLocaleBufSize;
pdhStatus = PdhTranslateLocaleCounter(
szCounterPath,
szLocaleBuf,
&dwBufSize);
if (pdhStatus == PDH_MORE_DATA) {
pNewBuf = (LPTSTR) G_REALLOC(szLocaleBuf, dwBufSize);
if (pNewBuf != NULL) {
szLocaleBuf = pNewBuf;
dwLocaleBufSize = dwBufSize;
pdhStatus = PdhTranslateLocaleCounter(
szCounterPath,
szLocaleBuf,
&dwBufSize);
}
}
if (pdhStatus == ERROR_SUCCESS) {
pszPath = szLocaleBuf;
}
}
}
strParamName.Format ( IDS_HTML_ALERT_OVER_UNDER, dwIndex );
hr = DwordFromPropertyBag (
pPropBag,
pIErrorLog,
strParamName,
AIBF_UNDER,
dwOverUnder);
strParamName.Format ( IDS_HTML_ALERT_THRESHOLD, dwIndex );
hr = DoubleFromPropertyBag (
pPropBag,
pIErrorLog,
strParamName,
((DOUBLE)0.0),
dThreshold);
dwByteCount = sizeof (ALERT_INFO_BLOCK) + ((lstrlen(pszPath) + 3 + 20 + 1) * sizeof(TCHAR));
MFC_TRY
LPTSTR szString = NULL;
paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwByteCount];
ZeroMemory ( paibInfo, dwByteCount );
// 1 = size of "<"
// 20 = size of threshold value
// 1 = size of null terminator
szString = new TCHAR[lstrlen(pszPath) + 3 + 20 + 1];
paibInfo->dwSize = dwByteCount;
paibInfo->szCounterPath = pszPath;
paibInfo->dwFlags = dwOverUnder;
paibInfo->dLimit = dThreshold;
if ( MakeStringFromInfo( paibInfo, szString, &dwByteCount ) ) {
AddCounter ( szString );
}
delete szString;
MFC_CATCH_HR
delete szCounterPath;
delete paibInfo;
}
if (szLocaleBuf != NULL) {
G_FREE(szLocaleBuf);
}
// Return good status regardless.
return S_OK;
}
HRESULT
CSmAlertQuery::LoadFromPropertyBag (
IPropertyBag* pPropBag,
IErrorLog* pIErrorLog )
{
HRESULT hr = S_OK;
SLQ_TIME_INFO stiDefault;
LPTSTR pszTemp = NULL;
DWORD dwBufSize;
// Continue even if error, using defaults for missing values.
hr = LoadCountersFromPropertyBag ( pPropBag, pIErrorLog );
stiDefault.wTimeType = SLQ_TT_TTYPE_SAMPLE;
stiDefault.dwAutoMode = SLQ_AUTO_MODE_AFTER;
stiDefault.wDataType = SLQ_TT_DTYPE_UNITS;
stiDefault.dwUnitType = SLQ_TT_UTYPE_SECONDS;
stiDefault.dwValue = 5;
hr = SlqTimeFromPropertyBag (
pPropBag,
pIErrorLog,
SLQ_TT_TTYPE_SAMPLE,
&stiDefault,
&mr_stiSampleInterval );
mr_strCmdFileName.Empty();
dwBufSize = 0;
hr = StringFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_COMMAND_FILE,
ALRT_DEFAULT_COMMAND_FILE,
&pszTemp,
&dwBufSize );
if ( sizeof(TCHAR) < dwBufSize ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != * pszTemp );
mr_strCmdFileName = pszTemp;
}
delete (pszTemp);
pszTemp = NULL;
mr_strNetName.Empty();
dwBufSize = 0;
hr = StringFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_NETWORK_NAME,
ALRT_DEFAULT_NETWORK_NAME,
&pszTemp,
&dwBufSize );
if ( sizeof(TCHAR) < dwBufSize ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != * pszTemp );
mr_strNetName = pszTemp;
}
delete (pszTemp);
pszTemp = NULL;
mr_strCmdUserText.Empty();
dwBufSize = 0;
hr = StringFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_USER_TEXT,
ALRT_DEFAULT_USER_TEXT,
&pszTemp,
&dwBufSize );
if ( sizeof(TCHAR) < dwBufSize ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != * pszTemp );
mr_strCmdUserText = pszTemp;
}
delete (pszTemp);
pszTemp = NULL;
mr_strPerfLogName.Empty();
dwBufSize = 0;
hr = StringFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_PERF_LOG_NAME,
ALRT_DEFAULT_PERF_LOG_NAME,
&pszTemp,
&dwBufSize );
if ( sizeof(TCHAR) < dwBufSize ) {
ASSERT ( NULL != pszTemp );
ASSERT ( 0 != * pszTemp );
mr_strPerfLogName = pszTemp;
}
delete (pszTemp);
pszTemp = NULL;
hr = DwordFromPropertyBag (
pPropBag,
pIErrorLog,
IDS_HTML_ACTION_FLAGS,
ALRT_DEFAULT_ACTION,
mr_dwActionFlags);
hr = CSmLogQuery::LoadFromPropertyBag( pPropBag, pIErrorLog );
return hr;
}
HRESULT
CSmAlertQuery::SaveCountersToPropertyBag (
IPropertyBag* pPropBag )
{
HRESULT hr = NOERROR;
LPCTSTR szString;
CString strParamName;
DWORD dwIndex = 0;
LPTSTR szEnglishBuf = NULL;
DWORD dwEnglishBufSize = 0;
LPTSTR pszPath = NULL;
PDH_STATUS pdhStatus;
PALERT_INFO_BLOCK paibInfo = NULL;
szString = GetFirstCounter();
// Todo: Stop processing on failure?
while ( NULL != szString ) {
LPTSTR pNewBuf;
DWORD dwBufSize;
dwBufSize = sizeof (ALERT_INFO_BLOCK) + (lstrlen(szString) + 1) * sizeof(TCHAR);
MFC_TRY
paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwBufSize];
if ( MakeInfoFromString( szString, paibInfo, &dwBufSize ) ) {
dwIndex++;
strParamName.Format ( IDS_HTML_SYSMON_COUNTERPATH, dwIndex );
pszPath = paibInfo->szCounterPath;
//
// Initialize the locale path buffer
//
if (dwEnglishBufSize == 0) {
dwEnglishBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
szEnglishBuf = (LPTSTR) G_ALLOC(dwEnglishBufSize);
if (szEnglishBuf == NULL) {
dwEnglishBufSize = 0;
}
}
if (szEnglishBuf != NULL) {
//
// Translate counter name from Localization into English
//
dwBufSize = dwEnglishBufSize;
pdhStatus = PdhTranslate009Counter(
paibInfo->szCounterPath,
szEnglishBuf,
&dwBufSize);
if (pdhStatus == PDH_MORE_DATA) {
pNewBuf = (LPTSTR)G_REALLOC(szEnglishBuf, dwBufSize);
if (pNewBuf != NULL) {
szEnglishBuf = pNewBuf;
dwEnglishBufSize = dwBufSize;
pdhStatus = PdhTranslate009Counter(
paibInfo->szCounterPath,
szEnglishBuf,
&dwBufSize);
}
}
if (pdhStatus == ERROR_SUCCESS) {
pszPath = szEnglishBuf;
}
}
//
// Passing sz. ( TCHAR[n] ) causes memory alloc, which might throw an exception
//
hr = StringToPropertyBag ( pPropBag, strParamName, pszPath);
strParamName.Format ( IDS_HTML_ALERT_OVER_UNDER, dwIndex );
hr = DwordToPropertyBag ( pPropBag, strParamName, paibInfo->dwFlags );
strParamName.Format ( IDS_HTML_ALERT_THRESHOLD, dwIndex );
hr = DoubleToPropertyBag ( pPropBag, strParamName, paibInfo->dLimit );
}
MFC_CATCH_HR
if ( NULL != paibInfo ) {
delete paibInfo;
paibInfo = NULL;
}
szString = GetNextCounter();
}
hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SYSMON_COUNTERCOUNT, dwIndex );
if (szEnglishBuf != NULL) {
G_FREE(szEnglishBuf);
}
// Todo: Caller handle error
return hr;
}
HRESULT
CSmAlertQuery::SaveToPropertyBag (
IPropertyBag* pPropBag,
BOOL fSaveAllProps )
{
HRESULT hr = NOERROR;
hr = SaveCountersToPropertyBag ( pPropBag );
hr = SlqTimeToPropertyBag ( pPropBag, SLQ_TT_TTYPE_SAMPLE, &mr_stiSampleInterval );
hr = StringToPropertyBag ( pPropBag, IDS_HTML_COMMAND_FILE, mr_strCmdFileName );
hr = StringToPropertyBag ( pPropBag, IDS_HTML_NETWORK_NAME, mr_strNetName );
hr = StringToPropertyBag ( pPropBag, IDS_HTML_USER_TEXT, mr_strCmdUserText );
hr = StringToPropertyBag ( pPropBag, IDS_HTML_PERF_LOG_NAME, mr_strPerfLogName );
hr = DwordToPropertyBag ( pPropBag, IDS_HTML_ACTION_FLAGS, mr_dwActionFlags );
hr = CSmLogQuery::SaveToPropertyBag( pPropBag, fSaveAllProps );
return hr;
}
HRESULT
CSmAlertQuery::TranslateMSZAlertCounterList(
LPTSTR pszCounterList,
LPTSTR pBuffer,
LPDWORD pdwBufferSize,
BOOL bFlag
)
{
LPTSTR pTmpBuf = NULL;
DWORD dwTmpBufSize = 0;
DWORD dwSize = 0;
LPTSTR pNewBuf = NULL;
LPTSTR pOriginPath = NULL;
LPTSTR pszCounterPathToAdd = NULL;
LPTSTR pNextStringPosition = NULL;
BOOL bNotEnoughBuffer = FALSE;
DWORD dwNewCounterListLen = 0;
DWORD dwCounterPathLen = 0;
PDH_STATUS Status = ERROR_SUCCESS;
LPTSTR pData = NULL;
LPTSTR pszBackupPath = NULL;
int nBackupLen = 0;
if (pszCounterList == NULL || pdwBufferSize == NULL) {
Status = ERROR_INVALID_PARAMETER;
goto ErrorOut;
}
if (pBuffer == NULL || *pdwBufferSize == 0) {
bNotEnoughBuffer = TRUE;
}
//
// Probe parameters
//
__try {
if (* pdwBufferSize != 0 && pBuffer != NULL) {
*pBuffer = 0;
* (LPTSTR) ( ((LPBYTE) pBuffer)
+ ((* pdwBufferSize) - sizeof(*pBuffer)) ) = 0;
}
pOriginPath = pszCounterList;
while (*pOriginPath) {
//
// Locate the position where the data description begins
//
pData = pOriginPath;
while (*pData != _T('\0') && *pData != _T('<') && *pData != _T('>')) {
pData++;
}
//
// Backup the counter path
//
//
if (pszBackupPath == NULL) {
nBackupLen = MAX_PATH + 1;
pszBackupPath = (LPTSTR) G_ALLOC(nBackupLen * sizeof(TCHAR));
if (pszBackupPath == NULL) {
Status = ERROR_OUTOFMEMORY;
goto ErrorOut;
}
}
if (lstrlen(pOriginPath) + 1 > nBackupLen) {
nBackupLen = lstrlen(pOriginPath) + 1;
pNewBuf = (LPTSTR) G_REALLOC(pszBackupPath, nBackupLen * sizeof(TCHAR) );
if (pNewBuf == NULL) {
Status = ERROR_OUTOFMEMORY;
goto ErrorOut;
}
pszBackupPath = pNewBuf;
}
lstrcpyn(pszBackupPath, pOriginPath, (int)(pData - pOriginPath + 1));
pszCounterPathToAdd = pszBackupPath;
//
// Initialize the buffer used for translating counter path
// called only once
//
if (pTmpBuf == NULL) {
dwTmpBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
pTmpBuf = (LPTSTR) G_ALLOC(dwTmpBufSize);
if (pTmpBuf == NULL) {
dwTmpBufSize = 0;
}
}
if (pTmpBuf != NULL) {
dwSize = dwTmpBufSize;
if (bFlag) {
Status = PdhTranslateLocaleCounter(
pszBackupPath,
pTmpBuf,
&dwSize);
}
else {
Status = PdhTranslate009Counter(
pszBackupPath,
pTmpBuf,
&dwSize);
}
if (Status == PDH_MORE_DATA) {
pNewBuf = (LPTSTR) G_REALLOC(pTmpBuf, dwSize);
if (pNewBuf == NULL) {
Status = ERROR_OUTOFMEMORY;
goto ErrorOut;
}
pTmpBuf = pNewBuf;
dwTmpBufSize = dwSize;
//
// Try second time
//
if (bFlag) {
Status = PdhTranslateLocaleCounter(
pszBackupPath,
pTmpBuf,
&dwSize);
}
else {
Status = PdhTranslate009Counter(
pszBackupPath,
pTmpBuf,
&dwSize);
}
}
if (Status == ERROR_SUCCESS) {
pszCounterPathToAdd = pTmpBuf;
}
}
//
// Add the translated counter path(it is the original
// counter path if translation failed) to the new counter
// path list
//
dwCounterPathLen = lstrlen(pszCounterPathToAdd) + 1;
dwNewCounterListLen += dwCounterPathLen;
if (! bNotEnoughBuffer) {
if ( (dwNewCounterListLen + lstrlen(pData) + 1) * sizeof(TCHAR) <= *pdwBufferSize) {
//
// Set up the copy position
//
pNextStringPosition = pBuffer + dwNewCounterListLen - dwCounterPathLen;
lstrcpy(pNextStringPosition, pszCounterPathToAdd);
lstrcat(pNextStringPosition, pData);
}
else {
bNotEnoughBuffer = TRUE;
}
}
dwNewCounterListLen += lstrlen(pData);
//
// Continue processing next counter path
//
pOriginPath += lstrlen(pOriginPath) + 1;
}
dwNewCounterListLen ++;
if (! bNotEnoughBuffer) {
//
// Append the terminating 0
//
pBuffer[dwNewCounterListLen - 1] = _T('\0');
}
else {
Status = ERROR_NOT_ENOUGH_MEMORY;
}
*pdwBufferSize = dwNewCounterListLen * sizeof(TCHAR);
} __except (EXCEPTION_EXECUTE_HANDLER) {
Status = ERROR_INVALID_PARAMETER;
}
ErrorOut:
if (pszBackupPath != NULL) {
G_FREE(pszBackupPath);
}
if (pTmpBuf != NULL) {
G_FREE(pTmpBuf);
}
return Status;
}