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.
1384 lines
40 KiB
1384 lines
40 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 <strsafe.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 ),
|
|
m_bCounterListInLocale (FALSE),
|
|
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;
|
|
LPWSTR 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) {
|
|
ASSERT ( 0 == dwBufferSize % sizeof(WCHAR) );
|
|
szNewCounterList = new WCHAR[dwBufferSize / sizeof(WCHAR)];
|
|
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(WCHAR);
|
|
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(WCHAR);
|
|
} 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(WCHAR);
|
|
} 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(WCHAR);
|
|
} 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(WCHAR);
|
|
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(WCHAR);
|
|
} 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;
|
|
}
|
|
|
|
DWORD
|
|
CSmAlertQuery::TranslateCounterListToLocale()
|
|
{
|
|
DWORD dwBufferSize = 0;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
LPWSTR szNewCounterList = NULL;
|
|
|
|
if (m_bCounterListInLocale) {
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
CWaitCursor WaitCursor;
|
|
//
|
|
// Translate the counter list into Locale
|
|
//
|
|
dwBufferSize = 0;
|
|
dwStatus = TranslateMSZAlertCounterList(
|
|
mr_szCounterList,
|
|
NULL,
|
|
&dwBufferSize,
|
|
TRUE);
|
|
|
|
if (dwStatus == ERROR_NOT_ENOUGH_MEMORY) {
|
|
|
|
ASSERT ( 0 == dwBufferSize % sizeof(WCHAR) );
|
|
szNewCounterList = new WCHAR [dwBufferSize / sizeof(WCHAR)];
|
|
|
|
if (szNewCounterList != NULL) {
|
|
//
|
|
// Translate the counter list into Locale
|
|
//
|
|
dwStatus = TranslateMSZAlertCounterList(
|
|
mr_szCounterList,
|
|
szNewCounterList,
|
|
&dwBufferSize,
|
|
TRUE);
|
|
|
|
if (dwStatus == ERROR_SUCCESS) {
|
|
m_dwCounterListLength = dwBufferSize / sizeof(WCHAR);
|
|
//
|
|
// Remove the old
|
|
//
|
|
delete [] mr_szCounterList;
|
|
m_szNextCounter = NULL;
|
|
mr_szCounterList = szNewCounterList;
|
|
m_bCounterListInLocale = TRUE;
|
|
}
|
|
}
|
|
}
|
|
WaitCursor.Restore();
|
|
|
|
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;
|
|
LPWSTR pszTemp = NULL;
|
|
LPWSTR szIndTemp = NULL;
|
|
UINT uiBufferLen = 0;
|
|
|
|
ASSERT (m_hKeyQuery != NULL);
|
|
|
|
m_bCounterListInLocale = FALSE;
|
|
|
|
//
|
|
// Load the counter string 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(WCHAR);
|
|
}
|
|
|
|
// 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(WCHAR) ) {
|
|
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(WCHAR) ) {
|
|
ASSERT ( NULL != pszTemp );
|
|
ASSERT ( 0 != *pszTemp );
|
|
mr_strNetName = pszTemp;
|
|
}
|
|
delete [] pszTemp ;
|
|
pszTemp = NULL;
|
|
dwBufferSize = 0;
|
|
|
|
// User text field can be indirect
|
|
|
|
if ( ERROR_SUCCESS == dwStatus ) {
|
|
dwStatus = SmNoLocReadRegIndStrVal (
|
|
m_hKeyQuery,
|
|
IDS_REG_USER_TEXT,
|
|
ALRT_DEFAULT_USER_TEXT,
|
|
&szIndTemp,
|
|
&uiBufferLen );
|
|
}
|
|
mr_strCmdUserText.Empty();
|
|
|
|
if ( NULL != szIndTemp ) {
|
|
if ( L'\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(WCHAR) ) {
|
|
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
|
|
ftLocalTime.dwLowDateTime = ftLocalTime.dwHighDateTime = 0;
|
|
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(WCHAR);
|
|
}
|
|
|
|
if ( !mr_strCmdFileName.IsEmpty() ) {
|
|
dwSizeRequired += ( mr_strCmdFileName.GetLength() + 1 ) * sizeof(WCHAR);
|
|
}
|
|
if ( !mr_strCmdUserText.IsEmpty() ) {
|
|
dwSizeRequired += ( mr_strCmdUserText.GetLength() + 1 ) * sizeof(WCHAR);
|
|
}
|
|
if ( !mr_strPerfLogName.IsEmpty() ) {
|
|
dwSizeRequired += ( mr_strPerfLogName.GetLength() + 1 ) * sizeof(WCHAR);
|
|
}
|
|
|
|
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;
|
|
StringCchCopy ( szNextString, dwSizeRequired, mr_strNetName );
|
|
szNextString += lstrlen(szNextString) + 1;
|
|
}
|
|
if ( !mr_strCmdFileName.IsEmpty() ) {
|
|
pInfo->szCmdFilePath = szNextString;
|
|
StringCchCopy ( szNextString, dwSizeRequired, mr_strCmdFileName );
|
|
szNextString += lstrlen(szNextString) + 1;
|
|
}
|
|
if ( !mr_strCmdUserText.IsEmpty() ) {
|
|
pInfo->szUserText = szNextString;
|
|
StringCchCopy ( szNextString, dwSizeRequired, mr_strCmdUserText );
|
|
szNextString += lstrlen(szNextString) + 1;
|
|
}
|
|
if ( !mr_strPerfLogName.IsEmpty() ) {
|
|
pInfo->szLogName = szNextString;
|
|
StringCchCopy ( szNextString, dwSizeRequired, 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)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwNewLen;
|
|
LPWSTR szNewString;
|
|
LPWSTR szNextString;
|
|
|
|
ASSERT (szCounterPath != NULL);
|
|
|
|
if (szCounterPath == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
dwNewLen = lstrlen(szCounterPath) + 1;
|
|
|
|
if (m_dwCounterListLength <= 2) {
|
|
dwNewLen += 1; // add room for the MSZ null
|
|
// then this is the first string to go in the list
|
|
try {
|
|
szNewString = new WCHAR [dwNewLen];
|
|
} catch ( ... ) {
|
|
return FALSE; // leave now
|
|
}
|
|
szNextString = szNewString;
|
|
} else {
|
|
//
|
|
// Double the list size on each allocation.
|
|
//
|
|
dwNewLen += m_dwCounterListLength;
|
|
// this is the nth string to go in the list
|
|
try {
|
|
szNewString = new WCHAR [dwNewLen];
|
|
} catch ( ... ) {
|
|
return FALSE; // leave now
|
|
}
|
|
// Use memcpy because MSZ string.
|
|
memcpy (szNewString, mr_szCounterList,
|
|
(m_dwCounterListLength * sizeof(WCHAR)));
|
|
szNextString = szNewString;
|
|
szNextString += m_dwCounterListLength - 1;
|
|
}
|
|
hr = StringCchCopy ( szNextString, dwNewLen, szCounterPath );
|
|
|
|
if ( SUCCEEDED ( hr) ) {
|
|
szNextString = szNewString;
|
|
szNextString += dwNewLen - 1;
|
|
*szNextString = L'\0'; // MSZ Null
|
|
|
|
if (mr_szCounterList != NULL) {
|
|
delete [] mr_szCounterList;
|
|
}
|
|
mr_szCounterList = szNewString;
|
|
m_szNextCounter = szNewString;
|
|
m_dwCounterListLength = dwNewLen;
|
|
} else {
|
|
delete [] szNewString;
|
|
return FALSE;
|
|
}
|
|
|
|
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 WCHAR [cchListSize];
|
|
memcpy (mr_szCounterList, mszCounterList, (cchListSize * sizeof(WCHAR)));
|
|
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 = ERROR_SUCCESS;
|
|
DWORD dwCount;
|
|
DWORD dwIndex;
|
|
CString strParamName;
|
|
CString strNonLocParamName;
|
|
LPWSTR szLocaleBuf = NULL;
|
|
DWORD dwLocaleBufLen = 0;
|
|
LPWSTR pszPath;
|
|
PALERT_INFO_BLOCK paibInfo = NULL;
|
|
LPWSTR szString = NULL;
|
|
LPWSTR szCounterPath = NULL;
|
|
|
|
m_bCounterListInLocale = FALSE;
|
|
|
|
hr = DwordFromPropertyBag (
|
|
pPropBag,
|
|
pIErrorLog,
|
|
IDS_HTML_SYSMON_COUNTERCOUNT,
|
|
0,
|
|
dwCount);
|
|
|
|
for ( dwIndex = 1; dwIndex <= dwCount; dwIndex++ ) {
|
|
|
|
pdhStatus = ERROR_SUCCESS;
|
|
hr = S_OK;
|
|
pszPath = NULL;
|
|
|
|
MFC_TRY
|
|
DWORD dwBufLen = 0;
|
|
DWORD dwCharCount = 0;
|
|
DWORD dwByteCount = 0;
|
|
DWORD dwOverUnder;
|
|
DOUBLE dThreshold;
|
|
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_SYSMON_COUNTERPATH ), dwIndex );
|
|
strParamName.Format ( IDS_HTML_SYSMON_COUNTERPATH, dwIndex );
|
|
|
|
hr = StringFromPropertyBag (
|
|
pPropBag,
|
|
pIErrorLog,
|
|
strParamName,
|
|
strNonLocParamName,
|
|
L"",
|
|
&szCounterPath,
|
|
&dwBufLen );
|
|
|
|
pszPath = szCounterPath;
|
|
|
|
//
|
|
// 1 for NULL character
|
|
//
|
|
if (dwBufLen > 1) {
|
|
|
|
//
|
|
// Initialize the locale path buffer
|
|
//
|
|
if (dwLocaleBufLen == 0) {
|
|
dwLocaleBufLen = PDH_MAX_COUNTER_PATH + 1;
|
|
szLocaleBuf = new WCHAR [dwLocaleBufLen];
|
|
if (szLocaleBuf == NULL) {
|
|
dwLocaleBufLen = 0;
|
|
}
|
|
}
|
|
|
|
if (szLocaleBuf != NULL) {
|
|
//
|
|
// Translate counter name from English to Locale
|
|
//
|
|
dwBufLen = dwLocaleBufLen;
|
|
|
|
pdhStatus = PdhTranslateLocaleCounter(
|
|
szCounterPath,
|
|
szLocaleBuf,
|
|
&dwBufLen);
|
|
|
|
if (pdhStatus == ERROR_SUCCESS) {
|
|
m_bCounterListInLocale = TRUE;
|
|
pszPath = szLocaleBuf;
|
|
} else if ( PDH_MORE_DATA == pdhStatus ) {
|
|
//
|
|
// Todo: Build error message.
|
|
//
|
|
} // else build error message.
|
|
}
|
|
}
|
|
|
|
if ( NULL != pszPath ) {
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_ALERT_OVER_UNDER ), dwIndex );
|
|
strParamName.Format ( IDS_HTML_ALERT_OVER_UNDER, dwIndex );
|
|
hr = DwordFromPropertyBag (
|
|
pPropBag,
|
|
pIErrorLog,
|
|
strParamName,
|
|
strNonLocParamName,
|
|
AIBF_UNDER,
|
|
dwOverUnder);
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_ALERT_THRESHOLD ), dwIndex );
|
|
strParamName.Format ( IDS_HTML_ALERT_THRESHOLD, dwIndex );
|
|
hr = DoubleFromPropertyBag (
|
|
pPropBag,
|
|
pIErrorLog,
|
|
strParamName,
|
|
strNonLocParamName,
|
|
((DOUBLE)0.0),
|
|
dThreshold);
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
|
|
// 1 = size of "<"
|
|
// SLQ_MAX_VALUE_LEN = size of threshold value
|
|
// 1 = size of null terminator
|
|
dwCharCount = lstrlen(pszPath) + 1 + SLQ_MAX_VALUE_LEN + 1;
|
|
dwByteCount = sizeof (ALERT_INFO_BLOCK) + ( dwCharCount * sizeof(WCHAR) ) + MAX_ALIGN_BYTES;
|
|
paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwByteCount];
|
|
ZeroMemory ( paibInfo, dwByteCount );
|
|
szString = new WCHAR[dwCharCount];
|
|
|
|
paibInfo->dwSize = dwByteCount;
|
|
paibInfo->szCounterPath = pszPath;
|
|
pszPath = NULL;
|
|
paibInfo->dwFlags = dwOverUnder;
|
|
paibInfo->dLimit = dThreshold;
|
|
|
|
if ( MakeStringFromInfo( paibInfo, szString, &dwCharCount ) ) {
|
|
AddCounter ( szString );
|
|
}
|
|
}
|
|
}
|
|
MFC_CATCH_MINIMUM
|
|
|
|
if ( NULL != szString ) {
|
|
delete [] szString;
|
|
szString = NULL;
|
|
}
|
|
if ( NULL != szCounterPath ) {
|
|
delete [] szCounterPath;
|
|
szCounterPath = NULL;
|
|
}
|
|
if ( NULL != paibInfo ) {
|
|
delete [] paibInfo;
|
|
paibInfo = NULL;
|
|
}
|
|
}
|
|
|
|
if ( NULL != szLocaleBuf ) {
|
|
delete [] szLocaleBuf;
|
|
}
|
|
|
|
//
|
|
// Todo: Display error message listing unloaded counters.
|
|
//
|
|
// Return good status regardless.
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT
|
|
CSmAlertQuery::LoadFromPropertyBag (
|
|
IPropertyBag* pPropBag,
|
|
IErrorLog* pIErrorLog )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
SLQ_TIME_INFO stiDefault;
|
|
LPWSTR 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(WCHAR) < 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(WCHAR) < 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(WCHAR) < 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(WCHAR) < 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 = S_OK;
|
|
PDH_STATUS pdhStatus = ERROR_SUCCESS;
|
|
LPCWSTR szString;
|
|
CString strNonLocParamName;
|
|
DWORD dwIndex = 0;
|
|
LPWSTR szEnglishBuf = NULL;
|
|
DWORD dwEnglishBufLen = 0;
|
|
LPWSTR pszPath = NULL;
|
|
PALERT_INFO_BLOCK paibInfo = NULL;
|
|
LPWSTR pNewBuf = NULL;
|
|
DWORD dwByteCount;
|
|
DWORD dwBufLen;
|
|
|
|
szString = GetFirstCounter();
|
|
|
|
//
|
|
// Todo: Error message for counters that fail.
|
|
//
|
|
while ( NULL != szString ) {
|
|
pdhStatus = ERROR_SUCCESS;
|
|
hr = S_OK;
|
|
pszPath = NULL;
|
|
|
|
MFC_TRY
|
|
if ( NULL == paibInfo ) {
|
|
//
|
|
// Include space for possibly alignment padding
|
|
//
|
|
dwByteCount =
|
|
sizeof (ALERT_INFO_BLOCK)
|
|
+ ( PDH_MAX_COUNTER_PATH + 1 ) * sizeof(WCHAR)
|
|
+ MAX_ALIGN_BYTES;
|
|
paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwByteCount];
|
|
}
|
|
|
|
if ( MakeInfoFromString( szString, paibInfo, &dwByteCount ) ) {
|
|
|
|
pszPath = paibInfo->szCounterPath;
|
|
|
|
if (m_bCounterListInLocale) {
|
|
//
|
|
// Translate counter name from Locale into English
|
|
//
|
|
|
|
if ( 0 == dwEnglishBufLen ) {
|
|
dwEnglishBufLen = PDH_MAX_COUNTER_PATH + 1;
|
|
szEnglishBuf = new WCHAR [dwEnglishBufLen];
|
|
if ( NULL == szEnglishBuf ) {
|
|
dwEnglishBufLen = 0;
|
|
}
|
|
}
|
|
|
|
dwBufLen = dwEnglishBufLen;
|
|
|
|
pdhStatus = PdhTranslate009Counter(
|
|
paibInfo->szCounterPath,
|
|
szEnglishBuf,
|
|
&dwBufLen);
|
|
|
|
if (pdhStatus == ERROR_SUCCESS) {
|
|
pszPath = szEnglishBuf;
|
|
} else if ( PDH_MORE_DATA == pdhStatus ) {
|
|
//
|
|
// Todo: Build error message.
|
|
//
|
|
} // else build error message.
|
|
}
|
|
|
|
if ( NULL != pszPath ) {
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_SYSMON_COUNTERPATH ), ++dwIndex );
|
|
hr = StringToPropertyBag ( pPropBag, strNonLocParamName, pszPath);
|
|
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_ALERT_OVER_UNDER ), dwIndex );
|
|
hr = DwordToPropertyBag ( pPropBag, strNonLocParamName, paibInfo->dwFlags );
|
|
|
|
strNonLocParamName.Format ( GetNonLocHtmlPropName ( IDS_HTML_ALERT_THRESHOLD ), dwIndex );
|
|
hr = DoubleToPropertyBag ( pPropBag, strNonLocParamName, paibInfo->dLimit );
|
|
} else {
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
}
|
|
MFC_CATCH_HR
|
|
|
|
szString = GetNextCounter();
|
|
}
|
|
hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SYSMON_COUNTERCOUNT, dwIndex );
|
|
|
|
if ( NULL != paibInfo ) {
|
|
delete [] (char*)paibInfo;
|
|
paibInfo = NULL;
|
|
}
|
|
|
|
if (szEnglishBuf != NULL) {
|
|
delete [] szEnglishBuf;
|
|
}
|
|
|
|
//
|
|
// Todo: Display error message
|
|
// Todo: Caller handle error. Return count of saved counters.
|
|
//
|
|
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;
|
|
}
|
|
|
|
DWORD
|
|
CSmAlertQuery::TranslateMSZAlertCounterList(
|
|
LPWSTR pszCounterList,
|
|
LPWSTR pBuffer,
|
|
LPDWORD pdwBufferSize,
|
|
BOOL bFlag
|
|
)
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pTmpBuf = NULL;
|
|
DWORD dwLen = 0;
|
|
LPWSTR pOriginPath = NULL;
|
|
LPWSTR pszCounterPathToAdd = NULL;
|
|
LPWSTR pNextStringPosition = NULL;
|
|
BOOL bEnoughBuffer = TRUE;
|
|
DWORD dwNewCounterListLen = 0;
|
|
DWORD dwCounterPathLen = 0;
|
|
LPWSTR pData = NULL;
|
|
LPWSTR pszBackupPath = NULL;
|
|
size_t cchBackupLen = PDH_MAX_COUNTER_PATH + 1;
|
|
|
|
if (pszCounterList == NULL || pdwBufferSize == NULL) {
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
return dwStatus;
|
|
}
|
|
|
|
if ( pBuffer == NULL || *pdwBufferSize == 0 ) {
|
|
bEnoughBuffer = FALSE;
|
|
} else {
|
|
pBuffer[0] = L'\0';
|
|
}
|
|
|
|
pOriginPath = pszCounterList;
|
|
|
|
while ( *pOriginPath ) {
|
|
|
|
pszCounterPathToAdd = NULL;
|
|
dwStatus = ERROR_SUCCESS;
|
|
|
|
MFC_TRY
|
|
|
|
//
|
|
// Locate the position where the data description begins
|
|
//
|
|
pData = pOriginPath;
|
|
while (*pData != L'\0' && *pData != L'<' && *pData != L'>') {
|
|
pData++;
|
|
}
|
|
|
|
//
|
|
// Backup the counter path
|
|
//
|
|
//
|
|
if (pszBackupPath == NULL) {
|
|
//
|
|
// Memory allocation error throws exception
|
|
//
|
|
pszBackupPath = new WCHAR [cchBackupLen] ;
|
|
pszBackupPath [0] = L'\0';
|
|
}
|
|
|
|
//
|
|
// StringCchCopyN adds null termination
|
|
//
|
|
hr = StringCchCopyN ( pszBackupPath, cchBackupLen, pOriginPath, (INT_PTR)(pData - pOriginPath) );
|
|
|
|
if ( SUCCEEDED ( hr ) && L'\0' != pszBackupPath [0] ) {
|
|
|
|
pszCounterPathToAdd = pszBackupPath;
|
|
//
|
|
// Initialize the buffer used for translating counter path.
|
|
// This is called only once.
|
|
//
|
|
dwLen = PDH_MAX_COUNTER_PATH + 1;
|
|
if (pTmpBuf == NULL) {
|
|
pTmpBuf = new WCHAR [ dwLen ] ;
|
|
}
|
|
|
|
if (bFlag) {
|
|
dwStatus = PdhTranslateLocaleCounter(
|
|
pszBackupPath,
|
|
pTmpBuf,
|
|
&dwLen);
|
|
} else {
|
|
dwStatus = PdhTranslate009Counter(
|
|
pszBackupPath,
|
|
pTmpBuf,
|
|
&dwLen);
|
|
}
|
|
|
|
if (dwStatus == ERROR_SUCCESS) {
|
|
pszCounterPathToAdd = pTmpBuf;
|
|
}
|
|
|
|
if ( NULL != pszCounterPathToAdd ) {
|
|
//
|
|
// Add the translated counter path to the new counter
|
|
// path list. The translated path is the original
|
|
// counter path if translation failed.
|
|
//
|
|
dwStatus = ERROR_SUCCESS;
|
|
dwCounterPathLen = lstrlen(pszCounterPathToAdd) + 1;
|
|
|
|
dwNewCounterListLen += dwCounterPathLen;
|
|
|
|
if ( bEnoughBuffer ) {
|
|
if ( (dwNewCounterListLen + lstrlen(pData) + 1) * sizeof(WCHAR) <= *pdwBufferSize) {
|
|
//
|
|
// Set up the copy position
|
|
//
|
|
pNextStringPosition = pBuffer + dwNewCounterListLen - dwCounterPathLen;
|
|
|
|
StringCchCopy ( pNextStringPosition, (dwCounterPathLen + lstrlen(pData) + 1), pszCounterPathToAdd );
|
|
StringCchCat (pNextStringPosition, (dwCounterPathLen + lstrlen(pData) + 1), pData);
|
|
}
|
|
else {
|
|
bEnoughBuffer = FALSE;
|
|
}
|
|
}
|
|
dwNewCounterListLen += lstrlen(pData);
|
|
|
|
pszCounterPathToAdd = NULL;
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// Todo: On failure, add path to error list and continue with next counter.
|
|
//
|
|
}
|
|
MFC_CATCH_DWSTATUS
|
|
//
|
|
// Continue processing next counter path
|
|
//
|
|
pOriginPath += lstrlen(pOriginPath) + 1;
|
|
}
|
|
|
|
dwNewCounterListLen ++;
|
|
|
|
if ( bEnoughBuffer ) {
|
|
if ( ERROR_SUCCESS == dwStatus ) {
|
|
//
|
|
// Append the terminating 0
|
|
//
|
|
pBuffer[dwNewCounterListLen - 1] = L'\0';
|
|
}
|
|
//
|
|
// Todo: Display error for unadded counters.
|
|
//
|
|
} else {
|
|
|
|
if ( NULL != pBuffer ) {
|
|
pBuffer[0] = L'\0';
|
|
}
|
|
|
|
if ( ERROR_SUCCESS == dwStatus ) {
|
|
dwStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
*pdwBufferSize = dwNewCounterListLen * sizeof(WCHAR);
|
|
|
|
if (pszBackupPath != NULL) {
|
|
delete [] pszBackupPath;
|
|
}
|
|
if (pTmpBuf != NULL) {
|
|
delete [] pTmpBuf;
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|