Leaked source code of windows server 2003
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.
 
 
 
 
 
 

941 lines
33 KiB

/*****************************************************************************\
Author: Corey Morgan (coreym)
Copyright (c) Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <wtypes.h>
#include <objbase.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <pdhp.h>
#include "resource.h"
#include "varg.c"
DWORD GetLogFormat( LPTSTR str, LPDWORD pdwFormat );
PDH_STATUS GetCountersFromFile( BOOL bExpand, HLOG hLog, HQUERY hQuery );
PDH_STATUS QueryLog( HLOG hLog, HQUERY hQuery, FILE* f );
PDH_STATUS AddCounters( BOOL bExpand, HLOG hLog, HQUERY hQuery );
_inline BOOL IsTextFormat( DWORD dwFormat );
DWORD GetTempName( LPTSTR strFile, size_t cchSize );
void ReportStatus( int Status, double Progress );
#define PDH_LOG_TYPE_RETIRED_BIN_ 3
#define CHECK_STATUS( hr ) if( ERROR_SUCCESS != hr ){ goto cleanup; }
#define RELOG_ERROR_BADFILES 0xF0000001
#define RELOG_ERROR_BADFORMAT 0xF0000002
#define RELOG_ERROR_TIMERANGE 0xF0000003
#define RELOG_ERROR_BADAPPEND 0xF0000004
VARG_DECLARE_COMMANDS
VARG_DEBUG( VARG_FLAG_OPTIONAL|VARG_FLAG_HIDDEN )
VARG_HELP ( VARG_FLAG_OPTIONAL )
VARG_BOOL ( IDS_PARAM_APPEND, VARG_FLAG_OPTIONAL, FALSE )
VARG_MSZ ( IDS_PARAM_COUNTERS, VARG_FLAG_OPTIONAL, _T("") )
VARG_STR ( IDS_PARAM_COUNTERFILE, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_FILENAME, _T("") )
VARG_STR ( IDS_PARAM_FORMAT, VARG_FLAG_OPTIONAL|VARG_FLAG_LITERAL, _T("BIN") )
VARG_MSZ ( IDS_PARAM_INPUT, VARG_FLAG_REQUIRED|VARG_FLAG_NOFLAG|VARG_FLAG_EXPANDFILES|VARG_FLAG_ARG_FILENAME, _T("") )
VARG_INT ( IDS_PARAM_INTERVAL, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DEFAULT, 0 )
VARG_STR ( IDS_PARAM_OUTPUT, VARG_FLAG_OPTIONAL|VARG_FLAG_DEFAULTABLE|VARG_FLAG_RCDEFAULT, IDS_DEFAULT_OUTPUT )
VARG_DATE ( IDS_PARAM_BEGIN, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DATE )
VARG_DATE ( IDS_PARAM_END, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DATE )
VARG_INI ( IDS_PARAM_SETTINGS, VARG_FLAG_OPTIONAL, NULL )
VARG_BOOL ( IDS_PARAM_QUERY, VARG_FLAG_OPTIONAL, FALSE )
VARG_BOOL ( IDS_PARAM_YES, VARG_FLAG_OPTIONAL, FALSE )
VARG_BOOL ( IDS_PARAM_FA, VARG_FLAG_OPTIONAL|VARG_FLAG_HIDDEN, FALSE )
VARG_DECLARE_NAMES
eDebug,
eHelp,
eAppend,
eCounters,
eCounterFile,
eFormat,
eInput,
eInterval,
eOutput,
eBegin,
eEnd,
eSettings,
eQuery,
eYes,
eForceAppend,
VARG_DECLARE_FORMAT
VARG_EXHELP( eFormat, IDS_EXAMPLE_FORMAT )
VARG_EXHELP( eQuery, IDS_EXAMPLE_QUERY )
VARG_EXHELP( eCounterFile, IDS_EXAMPLE_COUNTERFILE )
VARG_EXHELP( eCounters, IDS_EXAMPLE_COUNTERS )
VARG_DECLARE_END
int __cdecl _tmain( int argc, LPTSTR* argv )
{
DWORD dwStatus = ERROR_SUCCESS;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
PDH_RELOG_INFO RelogInfo;
DWORD dwOutputFormat;
DWORD dwInputFormat;
PDH_TIME_INFO InputTimeRange;
LPTSTR strFile = NULL;
TCHAR strTempFile[MAXSTR] = _T("");
ParseCmd( argc, argv );
HLOG hLogIn = NULL;
HQUERY hQuery = NULL;
ZeroMemory( &RelogInfo, sizeof(PDH_RELOG_INFO) );
DWORD dwNumEntries = 1;
DWORD dwBufferSize = sizeof(PDH_TIME_INFO);
int nBinary = 0;
int nFiles = 0;
BOOL bFakeAppend = FALSE;
if( Commands[eInput].strValue == NULL ){
dwStatus = ERROR_OUTOFMEMORY;
goto cleanup;
}
if( Commands[eAppend].bValue && !(Commands[eForceAppend].bValue ) ){
// We are going to do a merge instead
bFakeAppend = TRUE;
dwStatus = varg_cmdStringAddMsz( eInput, Commands[eOutput].strValue );
CHECK_STATUS( dwStatus );
dwStatus = GetTempName( strTempFile, MAXSTR );
CHECK_STATUS( dwStatus );
}
dwStatus = GetLogFormat( Commands[eFormat].strValue, &dwOutputFormat );
CHECK_STATUS(dwStatus);
strFile = Commands[eInput].strValue;
PrintMessage( g_normal, IDS_MESSAGE_INPUT );
PrintMessage( g_normal, IDS_MESSAGE_FILES );
while( strFile != NULL && *strFile != _T('\0') ){
pdhStatus = PdhGetLogFileType( strFile, &dwInputFormat );
nFiles++;
if( pdhStatus != ERROR_SUCCESS ){
dwInputFormat = 0;
}
switch( dwInputFormat ){
case PDH_LOG_TYPE_RETIRED_BIN_:
PrintMessage( g_normal, IDS_MESSAGE_LOG_OLD_BIN, strFile );
break;
case PDH_LOG_TYPE_CSV:
PrintMessage( g_normal, IDS_MESSAGE_LOG_CSV, strFile );
break;
case PDH_LOG_TYPE_TSV:
PrintMessage( g_normal, IDS_MESSAGE_LOG_TSV, strFile );
break;
case PDH_LOG_TYPE_BINARY:
nBinary++;
PrintMessage( g_normal, IDS_MESSAGE_LOG_BINARY, strFile );
break;
case PDH_LOG_TYPE_PERFMON:
PrintMessage( g_normal, IDS_MESSAGE_LOG_PERFMON, strFile );
break;
default:
PrintMessage( g_normal, IDS_MESSAGE_LOG_UNKNOWN, strFile );
}
strFile += _tcslen(strFile)+1;
}
varg_printf( g_normal, _T("\n") );
if( nFiles > 1 && nFiles > nBinary ){
dwStatus = RELOG_ERROR_BADFILES;
goto cleanup;
}
pdhStatus = PdhBindInputDataSource( &hLogIn, Commands[eInput].strValue );
CHECK_STATUS( pdhStatus );
pdhStatus = PdhOpenQueryH( hLogIn, NULL, &hQuery );
CHECK_STATUS( pdhStatus );
pdhStatus = PdhGetDataSourceTimeRangeH (
hLogIn,
&dwNumEntries,
&InputTimeRange,
&dwBufferSize
);
CHECK_STATUS( pdhStatus );
SYSTEMTIME st;
FileTimeToSystemTime( (FILETIME *)&InputTimeRange.StartTime, &st );
PrintMessage( g_normal, IDS_MESSAGE_BEGIN );
PrintDate( &st );
FileTimeToSystemTime( (FILETIME *)&InputTimeRange.EndTime, &st );
PrintMessage( g_normal, IDS_MESSAGE_END );
PrintDate( &st );
PrintMessage( g_normal, IDS_MESSAGE_SAMPLES, InputTimeRange.SampleCount );
if( Commands[eQuery].bDefined ){
FILE* f = NULL;
if( Commands[eOutput].bDefined ){
dwStatus = CheckFile( Commands[eOutput].strValue,
Commands[eYes].bValue ?
VARG_CF_OVERWRITE :
(VARG_CF_PROMPT|VARG_CF_OVERWRITE)
);
CHECK_STATUS( dwStatus );
f = _tfopen( Commands[eOutput].strValue, _T("w") );
if( NULL == f ){
dwStatus = GetLastError();
}
}
pdhStatus = QueryLog( hLogIn, hQuery, f );
if( NULL != f ){
fclose(f);
}
}else if( (!Commands[eCounters].bDefined && !Commands[eCounterFile].bDefined) ){
pdhStatus = QueryLog( hLogIn, hQuery, NULL );
CHECK_STATUS( pdhStatus );
}
if( Commands[eCounters].bDefined ){
pdhStatus = AddCounters( IsTextFormat( dwOutputFormat ), hLogIn, hQuery );
CHECK_STATUS( pdhStatus );
}
if( Commands[eCounterFile].bDefined ){
pdhStatus = GetCountersFromFile(
(IsTextFormat( dwInputFormat ) || IsTextFormat(dwOutputFormat)),
hLogIn,
hQuery
);
CHECK_STATUS( pdhStatus );
}
if( Commands[eBegin].bDefined ){
FILETIME ft;
SystemTimeToFileTime( &Commands[eBegin].stValue, &ft );
RelogInfo.TimeInfo.StartTime = *(LONGLONG *)&ft;
if( RelogInfo.TimeInfo.StartTime >= InputTimeRange.EndTime ){
dwStatus = RELOG_ERROR_TIMERANGE;
}
CHECK_STATUS(dwStatus);
}
if( Commands[eEnd].bDefined ){
FILETIME ft;
SystemTimeToFileTime( &Commands[eEnd].stValue, &ft );
RelogInfo.TimeInfo.EndTime = *(LONGLONG *)&ft;
if( RelogInfo.TimeInfo.EndTime <= InputTimeRange.StartTime ){
dwStatus = RELOG_ERROR_TIMERANGE;
}
CHECK_STATUS(dwStatus);
}
if( Commands[eOutput].bDefined && !Commands[eQuery].bDefined ){
TCHAR strFileBuffer[MAX_PATH];
TCHAR drive[_MAX_DRIVE];
TCHAR path[_MAX_DIR];
TCHAR file[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
RelogInfo.dwFileFormat = dwOutputFormat;
_tsplitpath( Commands[eOutput].strValue, drive, path, file, ext );
if( 0 == _tcslen( ext ) ){
switch( RelogInfo.dwFileFormat ){
case PDH_LOG_TYPE_TSV: StringCchCopy( ext, _MAX_EXT, _T("tsv") ); break;
case PDH_LOG_TYPE_CSV: StringCchCopy( ext, _MAX_EXT, _T("csv") ); break;
case PDH_LOG_TYPE_SQL: break;
case PDH_LOG_TYPE_BINARY:
StringCchCopy( ext, _MAX_EXT, _T("blg") ); break;
}
}
_tmakepath( strFileBuffer, drive, path, file, ext );
if( PDH_LOG_TYPE_SQL != dwOutputFormat ){
if( Commands[eAppend].bDefined ){
dwStatus = CheckFile( strFileBuffer, 0 );
}else{
dwStatus = CheckFile( strFileBuffer, Commands[eYes].bValue ? VARG_CF_OVERWRITE : (VARG_CF_PROMPT|VARG_CF_OVERWRITE) );
}
CHECK_STATUS(dwStatus);
}
RelogInfo.dwFlags = PDH_LOG_WRITE_ACCESS | PDH_LOG_CREATE_ALWAYS;
if( Commands[eAppend].bValue && Commands[eForceAppend].bValue ){
if( IsTextFormat( dwOutputFormat) ){
if( PDH_LOG_TYPE_SQL != dwOutputFormat ){
dwStatus = RELOG_ERROR_BADAPPEND;
goto cleanup;
}
}else{
pdhStatus = PdhGetLogFileType( Commands[eOutput].strValue, &dwOutputFormat );
if( ERROR_SUCCESS == pdhStatus && PDH_LOG_TYPE_BINARY == dwOutputFormat ){
RelogInfo.dwFlags |= PDH_LOG_OPT_APPEND;
}else{
if( ERROR_SUCCESS == pdhStatus ){
pdhStatus = PDH_LOG_FILE_OPEN_ERROR;
}
goto cleanup;
}
}
}
if( bFakeAppend ){
RelogInfo.strLog = strTempFile;
}else{
RelogInfo.strLog = strFileBuffer;
}
RelogInfo.StatusFunction = ReportStatus;
RelogInfo.TimeInfo.SampleCount = Commands[eInterval].nValue;
ReportStatus( 0, 0.0 );
pdhStatus = PdhRelog( hLogIn, &RelogInfo );
CHECK_STATUS( pdhStatus );
ReportStatus( 0, 1.0 );
varg_printf( g_normal, _T("\n\n") );
if( bFakeAppend ){
BOOL bResult;
bResult = CopyFile( strTempFile, Commands[eOutput].strValue, FALSE );
DeleteFile( strTempFile );
if( !bResult ){
dwStatus = GetLastError();
}
CHECK_STATUS( dwStatus );
RelogInfo.strLog = strFileBuffer;
}
PrintMessage( g_normal, IDS_MESSAGE_OUTPUT );
PrintMessage( g_normal, IDS_MESSAGE_FILE, RelogInfo.strLog );
FileTimeToSystemTime( (FILETIME *)&RelogInfo.TimeInfo.StartTime, &st );
PrintMessage( g_normal, IDS_MESSAGE_BEGIN );
PrintDate( &st );
FileTimeToSystemTime( (FILETIME *)&RelogInfo.TimeInfo.EndTime, &st );
PrintMessage( g_normal, IDS_MESSAGE_END );
PrintDate( &st );
PrintMessage( g_normal, IDS_MESSAGE_SAMPLES, RelogInfo.TimeInfo.SampleCount );
}
cleanup:
if( hLogIn != NULL ){
PdhCloseLog( hLogIn, PDH_FLAGS_CLOSE_QUERY );
}
switch( dwStatus ){
case RELOG_ERROR_TIMERANGE:
PrintMessage( g_debug, IDS_MESSAGE_BADRANGE );
break;
case RELOG_ERROR_BADFORMAT:
PrintMessage( g_debug, IDS_MESSAGE_BADFORMAT, Commands[eFormat].strValue );
break;
case RELOG_ERROR_BADAPPEND:
PrintMessage( g_debug, IDS_MESSAGE_BADFORMAT, Commands[eFormat].strValue );
break;
case RELOG_ERROR_BADFILES:
PrintMessage( g_debug, IDS_MESSAGE_BADFILES );
break;
case ERROR_SUCCESS:
if( ERROR_SUCCESS == pdhStatus ){
PrintMessage( g_normal, IDS_MESSAGE_SUCCESS );
}else{
switch( pdhStatus ){
case PDH_SQL_ALLOC_FAILED:
case PDH_SQL_ALLOCCON_FAILED:
case PDH_SQL_EXEC_DIRECT_FAILED:
case PDH_SQL_FETCH_FAILED:
case PDH_SQL_ROWCOUNT_FAILED:
case PDH_SQL_MORE_RESULTS_FAILED:
case PDH_SQL_CONNECT_FAILED:
case PDH_SQL_BIND_FAILED:
PrintMessage( g_debug, IDS_MESSAGE_SQLERROR );
break;
default:
PrintErrorEx( pdhStatus, _T("PDH.DLL") );
}
dwStatus = pdhStatus;
}
break;
default:
PrintError( dwStatus );
}
FreeCmd();
return dwStatus;
}
void ReportStatus( int Status, double Progress )
{
HRESULT hr;
TCHAR buffer[16];
hr = StringCchPrintf( buffer, 16, _T("%1.2f%%"), Progress*100 );
_tprintf( _T("\r") );
varg_printf( g_normal, _T("%1!s!"), buffer );
}
DWORD
GetTempName( LPTSTR strFile, size_t cchSize )
{
DWORD dwStatus;
GUID guid;
const size_t cchGuidSize = 128;
TCHAR strGUID[cchGuidSize];
DWORD nChar = 0;
dwStatus = UuidCreate( &guid );
if( dwStatus == RPC_S_OK || dwStatus == RPC_S_UUID_LOCAL_ONLY ){
nChar = StringFromGUID2( guid, strGUID, cchGuidSize );
dwStatus = ERROR_SUCCESS;
}
if( 0 == nChar ){
StringCchCopy( strGUID, cchGuidSize, _T("{d41c99ea-c303-4d06-b779-f9e8e20acb8f}") );
}
nChar = GetTempPath( cchSize, strFile );
if( 0 == nChar ){
dwStatus = GetLastError();
}
if( ERROR_SUCCESS == dwStatus ){
StringCchCat( strFile, cchSize, strGUID );
}
return dwStatus;
}
_inline BOOL IsTextFormat( DWORD dwFormat )
{
switch( dwFormat ){
case PDH_LOG_TYPE_CSV:
case PDH_LOG_TYPE_TSV:
case PDH_LOG_TYPE_SQL:
return TRUE;
default:
return FALSE;
}
}
DWORD
GetLogFormat( LPTSTR str, LPDWORD pdwFormat )
{
DWORD dwFormat = PDH_LOG_TYPE_UNDEFINED;
if( str != NULL ){
if( !_tcsicmp( str, _T("TSV")) ){
dwFormat = PDH_LOG_TYPE_TSV;
}else if( !_tcsicmp( str, _T("CSV")) ){
dwFormat = PDH_LOG_TYPE_CSV;
}else if( !_tcsicmp( str, _T("SQL")) ){
dwFormat = PDH_LOG_TYPE_SQL;
}else if( !_tcsicmp( str, _T("BIN")) ){
dwFormat = PDH_LOG_TYPE_BINARY;
}else if( !_tcsicmp( str, _T("ETL")) ){
dwFormat = PDH_LOG_TYPE_BINARY;
}else if( !_tcsicmp( str, _T("BLG")) ){
dwFormat = PDH_LOG_TYPE_BINARY;
}
}
if( dwFormat == PDH_LOG_TYPE_UNDEFINED ){
return RELOG_ERROR_BADFORMAT;
}
*pdwFormat = dwFormat;
return ERROR_SUCCESS;
}
PDH_STATUS
RelogGetMachines( HLOG hLog, LPTSTR* mszMachines )
{
PDH_STATUS pdhStatus;
DWORD dwSize = 0;
pdhStatus = PdhEnumMachinesH( hLog, NULL, &dwSize );
if( ERROR_SUCCESS == pdhStatus ||
PDH_MORE_DATA == pdhStatus ||
PDH_INSUFFICIENT_BUFFER == pdhStatus ){
*mszMachines = (LPTSTR)VARG_ALLOC( sizeof(TCHAR)*dwSize );
if( *mszMachines != NULL ){
pdhStatus = PdhEnumMachinesH( hLog, *mszMachines, &dwSize );
}else{
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
return pdhStatus;
}
PDH_STATUS
RelogAddCounter( BOOL bExpand, HLOG hLog, HQUERY hQuery, LPTSTR strCounter, LPTSTR mszMachines )
{
PDH_STATUS pdhStatus;
HCOUNTER pCounter;
LPTSTR szMachineList;
PPDH_COUNTER_PATH_ELEMENTS pPathElements = NULL;
DWORD dwPathElementsBufferSize = 0;
LPTSTR szPathBuffer = NULL;
DWORD dwPathBufferSize = 0;
LPTSTR szExpandedPathBuffer = NULL;
DWORD dwExpandedPathBufferSize = 0;
BOOL bMachineDeclared = FALSE;
if( hQuery == NULL || strCounter == NULL ){
return ERROR_SUCCESS;
}
//
// Parse original path
//
if( _tcslen( strCounter ) > 3 ){
if( strCounter[1] == _T('\\') ){
bMachineDeclared = TRUE;
}
}
do{
pdhStatus = PdhParseCounterPath( strCounter, pPathElements, &dwPathElementsBufferSize, 0 );
if( PDH_MORE_DATA == pdhStatus ){
VARG_FREE( pPathElements );
pPathElements = (PPDH_COUNTER_PATH_ELEMENTS)VARG_ALLOC( ++dwPathElementsBufferSize );
if( NULL == pPathElements ){
break;
}
}
}while( PDH_MORE_DATA == pdhStatus );
if( NULL == pPathElements ){
return ERROR_OUTOFMEMORY;
}
//
// If the original path contains a machine name
// only add that machine. Otherwise counter for
// all machines in the mszMachines list
//
if( bMachineDeclared ){
szMachineList = pPathElements->szMachineName;
}else{
szMachineList = mszMachines;
}
while( NULL != szMachineList ){
pPathElements->szMachineName = szMachineList;
do{
pdhStatus = PdhMakeCounterPath( pPathElements, szPathBuffer, &dwPathBufferSize, 0 );
if( PDH_MORE_DATA == pdhStatus ){
VARG_FREE( szPathBuffer );
szPathBuffer = (LPTSTR)VARG_ALLOC( ++dwPathBufferSize * sizeof(TCHAR) );
if( NULL == szPathBuffer ){
break;
}
}
}while( PDH_MORE_DATA == pdhStatus );
//
// If writing to a text file wild cards must be expanded
//
if( bExpand ){
do{
pdhStatus = PdhExpandWildCardPathH(
hLog,
szPathBuffer,
szExpandedPathBuffer,
&dwExpandedPathBufferSize,
0
);
if( PDH_MORE_DATA == pdhStatus ){
VARG_FREE( szExpandedPathBuffer );
szExpandedPathBuffer = (LPTSTR)VARG_ALLOC( ++dwExpandedPathBufferSize * sizeof(TCHAR) );
if( szExpandedPathBuffer == NULL ){
break;
}
}
}while(PDH_MORE_DATA == pdhStatus);
if( ERROR_SUCCESS == pdhStatus && szExpandedPathBuffer != NULL ){
LPTSTR szCounter = szExpandedPathBuffer;
while( *szCounter != _T('\0') ){
pdhStatus = PdhAddCounter(
hQuery,
szCounter,
0,
&pCounter
);
szCounter += (_tcslen( szCounter) +1 );
}
}
}else{
pdhStatus = PdhAddCounter(
hQuery,
szPathBuffer,
0,
&pCounter
);
}
if( bMachineDeclared ){
szMachineList = NULL;
}else{
szMachineList += (_tcslen( szMachineList ) + 1);
if( _T('\0') == *szMachineList ){
szMachineList = NULL;
}
}
}
VARG_FREE( szPathBuffer );
VARG_FREE( pPathElements );
VARG_FREE( szExpandedPathBuffer );
return ERROR_SUCCESS;
}
PDH_STATUS
AddCounters( BOOL bExpand, HLOG hLog, HQUERY hQuery )
{
PDH_STATUS pdhStatus;
LPTSTR strPath = Commands[eCounters].strValue;
LPTSTR mszMachines = NULL;
RelogGetMachines( hLog, &mszMachines );
if( strPath != NULL ){
while( *strPath != _T('\0') ){
pdhStatus = RelogAddCounter( bExpand, hLog, hQuery, strPath, mszMachines );
strPath += _tcslen( strPath )+1;
}
}
VARG_FREE( mszMachines );
return ERROR_SUCCESS;
}
PDH_STATUS
GetCountersFromFile( BOOL bExpand, HLOG hLog, HQUERY hQuery )
{
TCHAR buffer[MAXSTR];
PDH_STATUS pdhStatus;
LPTSTR strCounter = NULL;
LPTSTR mszMachines = NULL;
FILE* f = _tfopen( Commands[eCounterFile].strValue, _T("r") );
if( !f ){
DWORD dwStatus = GetLastError();
return PDH_FILE_NOT_FOUND;
}
RelogGetMachines( hLog, &mszMachines );
while( NULL != _fgetts( buffer, MAXSTR, f ) ){
if( buffer[0] == _T(';') || // comments
buffer[0] == _T('#') ){
continue;
}
Chomp(buffer);
strCounter = _tcstok( buffer, _T("\"\n") );
if( strCounter != NULL ){
pdhStatus = RelogAddCounter( bExpand, hLog, hQuery, buffer, mszMachines );
}
}
fclose( f );
VARG_FREE( mszMachines );
return ERROR_SUCCESS;
}
_inline BOOL IsSameInstance( LPTSTR strLastInstance, LPTSTR strInstance )
{
if( strLastInstance == NULL || strInstance == NULL ){
return FALSE;
}
return ( _tcscmp( strLastInstance, strInstance ) == 0 );
}
PDH_STATUS
QueryLog( HLOG hLog, HQUERY hQuery, FILE* f )
{
PDH_STATUS pdhStatus;
LPTSTR mszMachines = NULL;
LPTSTR strMachine = NULL;
LPTSTR strFullCounterPath = NULL;
DWORD dwFullCounterPathSize = 0;
DWORD dwMachines = 0;
HCOUNTER pCounter;
pdhStatus = PdhEnumMachinesH( hLog, mszMachines, &dwMachines );
if( ERROR_SUCCESS == pdhStatus ||
PDH_MORE_DATA == pdhStatus ||
PDH_INSUFFICIENT_BUFFER == pdhStatus ){
mszMachines = (LPTSTR)VARG_ALLOC( dwMachines * sizeof(TCHAR) );
if( mszMachines == NULL ){
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
pdhStatus = PdhEnumMachinesH( hLog, mszMachines, &dwMachines );
if( ERROR_SUCCESS == pdhStatus ){
strMachine = mszMachines;
while( NULL != strMachine && strMachine[0] != _T('\0') ){
LPTSTR mszObjects = NULL;
LPTSTR strObject = NULL;
DWORD dwObjects = 0;
pdhStatus = PdhEnumObjectsH(
hLog,
strMachine,
mszObjects,
&dwObjects,
PERF_DETAIL_WIZARD,
FALSE
);
if( ERROR_SUCCESS == pdhStatus ||
PDH_MORE_DATA == pdhStatus ||
PDH_INSUFFICIENT_BUFFER == pdhStatus ){
mszObjects = (LPTSTR)VARG_ALLOC( dwObjects * sizeof(TCHAR));
if( mszObjects == NULL ){
VARG_FREE( mszMachines );
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
pdhStatus = PdhEnumObjectsH(
hLog,
strMachine,
mszObjects,
&dwObjects,
PERF_DETAIL_WIZARD,
FALSE
);
strObject = mszObjects;
while( NULL != strObject && strObject[0] != _T('\0') ){
LPTSTR mszCounters = NULL;
LPTSTR strCounter = NULL;
LPTSTR mszInstances = NULL;
LPTSTR strInstance = NULL;
DWORD dwCounters = 0;
DWORD dwInstances = 0;
pdhStatus = PdhEnumObjectItemsH(
hLog,
strMachine,
strObject,
mszCounters,
&dwCounters,
mszInstances,
&dwInstances,
PERF_DETAIL_WIZARD,
0
);
if( ERROR_SUCCESS == pdhStatus ||
PDH_MORE_DATA == pdhStatus ||
PDH_INSUFFICIENT_BUFFER == pdhStatus ){
if( dwCounters > 0 ){
mszCounters = (LPTSTR)VARG_ALLOC( dwCounters * sizeof(TCHAR) );
}
if( dwInstances > 0 ){
mszInstances = (LPTSTR)VARG_ALLOC( dwInstances * sizeof(TCHAR) );
}
if( (mszCounters == NULL && dwCounters > 0 ) ||
(mszInstances == NULL && dwInstances > 0) ){
VARG_FREE( mszMachines );
VARG_FREE( mszObjects );
VARG_FREE( mszCounters );
VARG_FREE( mszInstances );
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
pdhStatus = PdhEnumObjectItemsH(
hLog,
strMachine,
strObject,
mszCounters,
&dwCounters,
mszInstances,
&dwInstances,
PERF_DETAIL_WIZARD,
0
);
if( ERROR_SUCCESS == pdhStatus ){
strCounter = mszCounters;
while( NULL != strCounter && strCounter[0] != _T('\0') ){
PDH_COUNTER_PATH_ELEMENTS_W pdhElements;
ZeroMemory( &pdhElements, sizeof( PDH_COUNTER_PATH_ELEMENTS ) );
pdhElements.szMachineName = strMachine;
pdhElements.szObjectName = strObject;
pdhElements.szCounterName = strCounter;
strInstance = mszInstances;
if( NULL != strInstance && strInstance[0] != _T('\0') ){
LPTSTR strLastInstance = NULL;
ULONG nInstance = 0;
while( strInstance[0] != _T('\0') ){
DWORD dwSize = dwFullCounterPathSize;
pdhElements.szInstanceName = strInstance;
if( ! IsSameInstance( strLastInstance, strInstance ) ){
pdhElements.dwInstanceIndex = -1;
nInstance = 0;
}else{
pdhElements.dwInstanceIndex = ++nInstance;
}
pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
if( PDH_INSUFFICIENT_BUFFER == pdhStatus || PDH_MORE_DATA == pdhStatus ){
VARG_FREE( strFullCounterPath );
strFullCounterPath = (LPTSTR)VARG_ALLOC( dwSize * sizeof(TCHAR) );
if( NULL != strFullCounterPath ){
dwFullCounterPathSize = dwSize;
pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
}
}
strLastInstance = strInstance;
strInstance += _tcslen( strInstance ) + 1;
if( Commands[eQuery].bValue ){
if( NULL != f ){
_ftprintf( f, _T("%s\n"), strFullCounterPath );
}else{
varg_printf( g_normal, _T("%1!s!\n"), strFullCounterPath );
}
}
if( Commands[eCounters].bDefined == FALSE && Commands[eOutput].bDefined ){
pdhStatus = PdhAddCounter(
hQuery,
strFullCounterPath,
0,
&pCounter
);
}
}
}else{
DWORD dwSize = dwFullCounterPathSize;
pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
if( PDH_INSUFFICIENT_BUFFER == pdhStatus || PDH_MORE_DATA == pdhStatus ){
VARG_FREE( strFullCounterPath );
strFullCounterPath = (LPTSTR)VARG_ALLOC( dwSize * sizeof(TCHAR) );
if( NULL != strFullCounterPath ){
dwFullCounterPathSize = dwSize;
pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
}
}
if( Commands[eQuery].bValue ){
if( NULL != f ){
_ftprintf( f, _T("%s\n"), strFullCounterPath );
}else{
varg_printf( g_normal, _T("%1!s!\n"), strFullCounterPath );
}
}
if( Commands[eCounters].bDefined == FALSE && Commands[eOutput].bDefined ){
pdhStatus = PdhAddCounter(
hQuery,
strFullCounterPath,
0,
&pCounter
);
}
}
strCounter += _tcslen( strCounter ) + 1;
}
}
VARG_FREE( mszCounters );
VARG_FREE( mszInstances );
}
strObject += _tcslen( strObject ) + 1;
}
VARG_FREE( mszObjects );
}
strMachine += _tcslen( strMachine ) + 1;
}
}
VARG_FREE( mszMachines );
}
cleanup:
VARG_FREE( strFullCounterPath );
if( NULL == f ){
if( ERROR_SUCCESS == pdhStatus && Commands[eQuery].bValue){
varg_printf( g_normal, _T("\n") );
}
}
return pdhStatus;
}