443 lines
13 KiB
C++
443 lines
13 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996-1999
|
|
//
|
|
// File: IdqPerf.hxx
|
|
//
|
|
// Contents: Perfmon counters for ISAPI search engine.
|
|
//
|
|
// History: 15-Mar-1996 KyleP Created (from perfci.hxx)
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <pch.cxx>
|
|
#pragma hdrstop
|
|
|
|
#include <idqperf.hxx>
|
|
#include <smem.hxx>
|
|
|
|
#include "prfutil.hxx"
|
|
|
|
//
|
|
// For Ci - ISAPI HTTP
|
|
//
|
|
|
|
CI_ISAPI_DATA_DEFINITION CIISAPIDataDefinition = {
|
|
{ sizeof(CI_ISAPI_DATA_DEFINITION) +
|
|
CI_ISAPI_SIZE_OF_COUNTER_BLOCK, // Total Bytes ( Size of this header, the counter definitions
|
|
// and the size of the actual counter data )
|
|
sizeof(CI_ISAPI_DATA_DEFINITION),// Definition length ( This header and the counter definitions )
|
|
sizeof(PERF_OBJECT_TYPE), // Header Length ( This header )
|
|
CIISAPIOBJECT, // Object Name Title Index
|
|
0, // Object Name Title
|
|
CIISAPIOBJECT, // Object Help Title Index
|
|
0, // Object Help Title
|
|
PERF_DETAIL_NOVICE, // Detail Level
|
|
CI_ISAPI_TOTAL_NUM_COUNTERS, // Number of Counters
|
|
1, // Default Counters
|
|
PERF_NO_INSTANCES, // Num Instances
|
|
0, // Code Page
|
|
{0,0}, // Perf Time
|
|
{0,0} // Perf Freq
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Number of cache items
|
|
NUM_CACHE_ITEMS,
|
|
0,
|
|
NUM_CACHE_ITEMS,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_CACHE_ITEMS_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Number of cache hits
|
|
NUM_CACHE_HITS,
|
|
0,
|
|
NUM_CACHE_HITS,
|
|
0,
|
|
-1,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_RAW_FRACTION,
|
|
sizeof(DWORD),
|
|
NUM_CACHE_HITS_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Base for number of cache hits
|
|
NUM_CACHE_HITS_AND_MISSES_1,
|
|
0,
|
|
NUM_CACHE_HITS_AND_MISSES_1,
|
|
0,
|
|
-1,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_RAW_BASE,
|
|
sizeof(DWORD),
|
|
NUM_CACHE_HITS_AND_MISSES_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Number of cache misses
|
|
NUM_CACHE_MISSES,
|
|
0,
|
|
NUM_CACHE_MISSES,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_RAW_FRACTION,
|
|
sizeof(DWORD),
|
|
NUM_CACHE_MISSES_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Base for number of cache hits
|
|
NUM_CACHE_HITS_AND_MISSES_2,
|
|
0,
|
|
NUM_CACHE_HITS_AND_MISSES_2,
|
|
0,
|
|
-1,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_RAW_BASE,
|
|
sizeof(DWORD),
|
|
NUM_CACHE_HITS_AND_MISSES_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Number of running queries
|
|
NUM_RUNNING_QUERIES,
|
|
0,
|
|
NUM_RUNNING_QUERIES,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_RUNNING_QUERIES_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Total queries
|
|
NUM_TOTAL_QUERIES,
|
|
0,
|
|
NUM_TOTAL_QUERIES,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_TOTAL_QUERIES_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Number of queries per minute
|
|
NUM_QUERIES_PER_MINUTE,
|
|
0,
|
|
NUM_QUERIES_PER_MINUTE,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_QUERIES_PER_MINUTE_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Current # of queued requests
|
|
NUM_REQUESTS_QUEUED,
|
|
0,
|
|
NUM_REQUESTS_QUEUED,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_REQUESTS_QUEUED_OFF
|
|
},
|
|
{ sizeof(PERF_COUNTER_DEFINITION), // Total # of rejected requests
|
|
NUM_REQUESTS_REJECTED,
|
|
0,
|
|
NUM_REQUESTS_REJECTED,
|
|
0,
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(DWORD),
|
|
NUM_REQUESTS_REJECTED_OFF
|
|
}
|
|
};
|
|
|
|
CNamedSharedMem TheMem;
|
|
|
|
WCHAR const CIISAPIPerformanceKeyName[] =
|
|
TEXT("SYSTEM\\CurrentControlSet\\Services\\ISAPISearch\\Performance");
|
|
WCHAR const FirstCounterKeyName [] = TEXT("First Counter");
|
|
WCHAR const FirstHelpKeyName [] = TEXT("First Help");
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeCIISAPIerformanceData
|
|
//
|
|
// Purpose: Build and initialize the performance data structure.
|
|
//
|
|
// Arguments: [pInstance] -- dummy variable
|
|
//
|
|
// History: 15-Mar-96 KyleP Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD InitializeCIISAPIPerformanceData( LPWSTR pInstance )
|
|
{
|
|
//
|
|
// Some apps open perfmon keys more than once and Done() doesn't
|
|
// free any resources, do don't bother refcounting.
|
|
//
|
|
|
|
static BOOL fInit = FALSE;
|
|
|
|
if ( fInit )
|
|
return NO_ERROR;
|
|
|
|
CTranslateSystemExceptions translate;
|
|
TRY
|
|
{
|
|
if ( !TheMem.Ok() )
|
|
TheMem.OpenForRead( CI_ISAPI_PERF_SHARED_MEM );
|
|
|
|
//
|
|
// If no IDQ queries have been issued, there will be no memory, but
|
|
// don't fail the initialize; just return 0 data in Collect().
|
|
// This (apparently) is the intended design of perfmon.
|
|
//
|
|
|
|
if ( 0 == TheMem.GetPointer() )
|
|
return NO_ERROR; //the collect function will just return no data
|
|
}
|
|
CATCH( CException, e )
|
|
{
|
|
return NO_ERROR; // the collect function will just return no data
|
|
}
|
|
END_CATCH;
|
|
|
|
//
|
|
// Open the registry which contain the last key's index
|
|
//
|
|
|
|
HKEY hKeyPerf = 0;
|
|
LONG status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
CIISAPIPerformanceKeyName,
|
|
0L,
|
|
KEY_READ,
|
|
&hKeyPerf );
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey( hKeyPerf );
|
|
//ciGibDebugOut(( DEB_ERROR, "Error in RegOpenKeyEx\n"));
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Get the index of the first counter
|
|
//
|
|
DWORD type;
|
|
DWORD dwFirstCounter;
|
|
DWORD size = sizeof dwFirstCounter;
|
|
status = RegQueryValueEx( hKeyPerf, FirstCounterKeyName, 0L, &type,
|
|
(LPBYTE)&dwFirstCounter, &size);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
//ciGibDebugOut(( DEB_ERROR, "Error in Query First Counter\n"));
|
|
RegCloseKey( hKeyPerf );
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Get the index of the first help
|
|
//
|
|
DWORD dwFirstHelp;
|
|
size = sizeof dwFirstHelp;
|
|
status = RegQueryValueEx( hKeyPerf, FirstHelpKeyName,
|
|
0L, &type, (LPBYTE)&dwFirstHelp, &size );
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
//ciGibDebugOut(( DEB_ERROR, "Error in Query First Help Key\n"));
|
|
RegCloseKey( hKeyPerf );
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Update the index of both title and help of each counter
|
|
//
|
|
|
|
CIISAPIDataDefinition.CIISAPIObjectType.ObjectNameTitleIndex += dwFirstCounter;
|
|
CIISAPIDataDefinition.CIISAPIObjectType.ObjectHelpTitleIndex += dwFirstHelp;
|
|
|
|
PERF_COUNTER_DEFINITION * pTmp = (PERF_COUNTER_DEFINITION *) ((BYTE *)&CIISAPIDataDefinition
|
|
+ sizeof(PERF_OBJECT_TYPE) );
|
|
|
|
for ( unsigned i = 0;
|
|
i < CIISAPIDataDefinition.CIISAPIObjectType.NumCounters;
|
|
i++ )
|
|
{
|
|
pTmp->CounterNameTitleIndex += dwFirstCounter;
|
|
pTmp->CounterHelpTitleIndex += dwFirstHelp;
|
|
pTmp++;
|
|
}
|
|
|
|
//
|
|
// Close the registry key
|
|
//
|
|
|
|
RegCloseKey( hKeyPerf );
|
|
|
|
//
|
|
// set the flag to TRUE
|
|
//
|
|
|
|
//ciGibDebugOut((DEB_ITRACE, "InitializeFilterPerformanceData : Done\n" ));
|
|
fInit = TRUE;
|
|
|
|
return ERROR_SUCCESS;
|
|
} //InitializeCIISAPIPerformanceData
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function : CollectCIISAPIPerformanceData
|
|
//
|
|
// Purpose : Collect Performance Data of Content Index to PerfMon
|
|
//
|
|
// Arguments:
|
|
// [lpValueName] -- pointer to a wide character string passed by registry
|
|
//
|
|
// [lppData] -- IN: pointer to the address of the buffer to receive the
|
|
// completed PerfDataBlock and subordinate structures. This
|
|
// routine will append its data to the buffer starting at
|
|
// the point referenced by *lppData.
|
|
//
|
|
// OUT: points to the first byte after the data structure
|
|
// added by this routine. This routine updated the value at
|
|
// lppdata after appending its data.
|
|
//
|
|
// [lpcbTotalBytes] -- IN: the address of the DWORD that tells the size in bytes
|
|
// of the buffer referenced by the lppData argument
|
|
//
|
|
// OUT: the number of bytes added by this routine is written
|
|
// to the DWORD pointed to by this argument
|
|
//
|
|
// [lpNumObjectTypes] -- IN: the address of the DWORD to receive the number of
|
|
// objects added by this routine
|
|
//
|
|
// OUT: the number of objects added by this routine is written
|
|
// to the DWORD pointed to by this argument
|
|
//
|
|
// History : 23-March-94 t-joshh Created
|
|
//
|
|
// Return : ERROR_MORE_DATA if the size of the input buffer is too small
|
|
// ERROR_SUCCESS if success
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD CollectCIISAPIPerformanceData( LPWSTR lpValueName,
|
|
LPVOID *lppData,
|
|
LPDWORD lpcbTotalBytes,
|
|
LPDWORD lpNumObjectTypes )
|
|
{
|
|
//
|
|
// see if this is a foreign (i.e. non-NT) computer data request
|
|
//
|
|
|
|
DWORD dwQueryType = GetQueryType (lpValueName);
|
|
|
|
if ( ( QUERY_FOREIGN == dwQueryType ) ||
|
|
( !TheMem.Ok() ) )
|
|
{
|
|
//
|
|
// This routine does not service requests for data from
|
|
// Non-NT computers. Or if Init() failed.
|
|
//
|
|
*lpcbTotalBytes = (DWORD) 0;
|
|
*lpNumObjectTypes = (DWORD) 0;
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
//
|
|
// If the caller only wanted some counter, check if we have them
|
|
//
|
|
|
|
if ( dwQueryType == QUERY_ITEMS )
|
|
{
|
|
WCHAR wcsNum[50];
|
|
_ultow( CIISAPIDataDefinition.CIISAPIObjectType.ObjectNameTitleIndex,
|
|
wcsNum,
|
|
10 );
|
|
|
|
if ( 0 == wcsstr( lpValueName, wcsNum ) )
|
|
{
|
|
//
|
|
// request received for data object not provided by this routine
|
|
//
|
|
|
|
*lpcbTotalBytes = (DWORD) 0;
|
|
*lpNumObjectTypes = (DWORD) 0;
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check whether there is enough space allocated in the lppData
|
|
//
|
|
|
|
ULONG ulSpaceNeeded = CIISAPIDataDefinition.CIISAPIObjectType.TotalByteLength;
|
|
|
|
if ( *lpcbTotalBytes < (DWORD) ulSpaceNeeded )
|
|
{
|
|
*lpcbTotalBytes = (DWORD) 0;
|
|
*lpNumObjectTypes = (DWORD) 0;
|
|
return( ERROR_MORE_DATA );
|
|
}
|
|
|
|
|
|
//
|
|
// Copy the Data Definition to the buffer first
|
|
//
|
|
|
|
CI_ISAPI_DATA_DEFINITION * pCIISAPIDataDefinition =
|
|
(CI_ISAPI_DATA_DEFINITION *) *lppData;
|
|
|
|
RtlCopyMemory( pCIISAPIDataDefinition,
|
|
&CIISAPIDataDefinition,
|
|
sizeof(CI_ISAPI_DATA_DEFINITION) );
|
|
|
|
DWORD * pdwCounter = (DWORD *)( pCIISAPIDataDefinition + 1 );
|
|
|
|
//
|
|
// Number of Object are always 1
|
|
//
|
|
|
|
*lpNumObjectTypes = 1;
|
|
|
|
//
|
|
// Fill in counter block.
|
|
//
|
|
|
|
*pdwCounter = CI_ISAPI_SIZE_OF_COUNTER_BLOCK;
|
|
pdwCounter++;
|
|
|
|
RtlCopyMemory( pdwCounter, TheMem.GetPointer(), CI_ISAPI_SIZE_OF_COUNTER_BLOCK - sizeof(DWORD) );
|
|
|
|
//
|
|
// Fill in the number of bytes copied including object and counter
|
|
// definition and counter data
|
|
//
|
|
|
|
*lpcbTotalBytes = ulSpaceNeeded;
|
|
*lppData = (void *) (((BYTE *) *lppData) + ulSpaceNeeded);
|
|
|
|
return ERROR_SUCCESS;
|
|
} //CollectCIISAPIPerformanceData
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function : DoneCIISAPIPerformanceData
|
|
//
|
|
// Purpose : dummy function
|
|
//
|
|
// Argument : none
|
|
//
|
|
// History : 23-March-94 t-joshh Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD DoneCIISAPIPerformanceData ( void )
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|