284 lines
9.3 KiB
C++
284 lines
9.3 KiB
C++
#ifndef __PERFAPI_H__
|
|
#define __PERFAPI_H__
|
|
|
|
#include <winperf.h>
|
|
|
|
typedef DWORD INSTANCE_ID;
|
|
typedef DWORD COUNTER_ID;
|
|
|
|
#define MAX_COUNTERS 128
|
|
#define MAX_INSTANCES_PER_OBJECT 32
|
|
#define MAX_PERF_OBJECTS 64
|
|
|
|
#define BITS_IN_DWORD (sizeof(DWORD) << 3)
|
|
|
|
#ifdef __PERF_APP_API
|
|
#define PERF_APP_API __declspec(dllexport)
|
|
#else
|
|
#define PERF_APP_API __declspec(dllimport)
|
|
#endif
|
|
|
|
/* NOTE: The member functions for all classes are in-line */
|
|
|
|
#ifdef __cplusplus
|
|
|
|
// CPerfObject Class
|
|
class PERF_APP_API CPerfObject {
|
|
private:
|
|
HANDLE hObject; // Handle to Performance Object
|
|
BOOL bWithInstances; // True, if object has instances
|
|
BOOL bValid; // True, if the PerfMon object is OK. False, if there had been an exception thrown.
|
|
DWORD cCounters; // # of created counters for the object
|
|
DWORD dwCounterOffsets[MAX_COUNTERS]; // The object's counter offsets
|
|
DWORD bCounterSize[MAX_COUNTERS / BITS_IN_DWORD + 1]; // bitmap of counter sizes. If bit is 0, counter is a DWORD, otherwise (bit is 1), it's a LARGE_INTEGER.
|
|
INSTANCE_ID iidInstances[MAX_INSTANCES_PER_OBJECT]; // The object's instance ids
|
|
BOOL bOriginal[MAX_INSTANCES_PER_OBJECT]; // True, if the instance is original. Then, it needs to be destroyed.
|
|
PBYTE lpInstanceAddr[MAX_INSTANCES_PER_OBJECT]; // The object's instances' start addresses. If the object has no instances, the 0-th address is the object counter data start
|
|
|
|
friend class CPerfCounter;
|
|
|
|
public:
|
|
CPerfObject (void) { bValid = FALSE; };
|
|
BOOL Create (char *pTitle, BOOL bHasInstances = TRUE, char *pHelp = NULL, DWORD nSize = 0);
|
|
BOOL Create (WCHAR *pTitle, BOOL bHasInstances = TRUE, WCHAR *pHelp = NULL, DWORD nSize = 0);
|
|
~CPerfObject (void);
|
|
COUNTER_ID CreateCounter (char *pCounterName, DWORD dwType = PERF_COUNTER_COUNTER, DWORD dwScale = 0, DWORD dwSize = sizeof(DWORD), char *pHelp = NULL);
|
|
COUNTER_ID CreateCounter (WCHAR *pCounterName, DWORD dwType = PERF_COUNTER_COUNTER, DWORD dwScale = 0, DWORD dwSize = sizeof(DWORD), WCHAR *pHelp = NULL);
|
|
INSTANCE_ID CreateInstance (char *pInstanceName);
|
|
INSTANCE_ID CreateInstance (WCHAR *pInstanceName);
|
|
BOOL DestroyInstance (INSTANCE_ID iid);
|
|
|
|
};
|
|
|
|
// CPerfCounter Class
|
|
class PERF_APP_API CPerfCounter {
|
|
private:
|
|
LPDWORD pAddr; // Read address of the counter
|
|
BOOL bDword; // If TRUE, the counter is a DWORD, otherwise, it's a LARGE_INTEGER
|
|
|
|
public:
|
|
CPerfCounter (void) { pAddr = NULL; };
|
|
BOOL Create (CPerfObject &cpoObject, COUNTER_ID idCounter, INSTANCE_ID idInstance = (INSTANCE_ID) -1);
|
|
~CPerfCounter (void) { };
|
|
|
|
CPerfCounter & operator = (DWORD nNewValue)
|
|
{
|
|
if (pAddr)
|
|
*pAddr = nNewValue;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator = (LARGE_INTEGER nNewValue)
|
|
{
|
|
if (pAddr)
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = nNewValue.QuadPart;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator = (const CPerfCounter &PerfCtr)
|
|
{
|
|
if (pAddr && PerfCtr.pAddr) {
|
|
if (bDword != PerfCtr.bDword)
|
|
return *this;
|
|
if (bDword)
|
|
*pAddr = *(PerfCtr.pAddr);
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) PerfCtr.pAddr)->QuadPart;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator += (DWORD nValue)
|
|
{
|
|
if (pAddr)
|
|
*pAddr += nValue;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator += (LARGE_INTEGER nValue)
|
|
{
|
|
if (pAddr)
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart + nValue.QuadPart;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator += (const CPerfCounter &PerfCtr)
|
|
{
|
|
if (pAddr && PerfCtr.pAddr) {
|
|
if (bDword != PerfCtr.bDword)
|
|
return *this;
|
|
if (bDword)
|
|
*pAddr += *(PerfCtr.pAddr);
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart + ((LARGE_INTEGER *) PerfCtr.pAddr)->QuadPart;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator -= (DWORD nValue)
|
|
{
|
|
if (pAddr)
|
|
*pAddr -= nValue;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator -= (LARGE_INTEGER nValue)
|
|
{
|
|
if (pAddr)
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart - nValue.QuadPart;
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator -= (const CPerfCounter &PerfCtr)
|
|
{
|
|
if (pAddr && PerfCtr.pAddr) {
|
|
if (bDword != PerfCtr.bDword)
|
|
return *this;
|
|
if (bDword)
|
|
*pAddr -= *(PerfCtr.pAddr);
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart - ((LARGE_INTEGER *) PerfCtr.pAddr)->QuadPart;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator ++ (void)
|
|
{
|
|
if (pAddr) {
|
|
if (bDword)
|
|
(*pAddr)++;
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart + 1;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator ++ (int dummy)
|
|
{
|
|
if (pAddr) {
|
|
if (bDword)
|
|
(*pAddr)++;
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart + 1;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator -- (void)
|
|
{
|
|
if (pAddr) {
|
|
if (bDword)
|
|
(*pAddr)--;
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart - 1;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
CPerfCounter & operator -- (int dummy)
|
|
{
|
|
if (pAddr) {
|
|
if (bDword)
|
|
(*pAddr)--;
|
|
else
|
|
((LARGE_INTEGER *) pAddr)->QuadPart = ((LARGE_INTEGER *) pAddr)->QuadPart - 1;
|
|
}
|
|
return *this;
|
|
};
|
|
|
|
operator DWORD ()
|
|
{
|
|
if (pAddr == NULL)
|
|
return 0;
|
|
return (*pAddr);
|
|
};
|
|
|
|
operator LARGE_INTEGER ()
|
|
{
|
|
if (pAddr == NULL) {
|
|
LARGE_INTEGER li;
|
|
li.QuadPart = 0;
|
|
return li;
|
|
}
|
|
return (* (LARGE_INTEGER *) pAddr);
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
MakeAPerfObject:: Creates a logical perf object, under which one can create
|
|
counters. This perf object shows up as an object in Perfmon and the counters
|
|
showup under it. A maximum number of instances can be specified. (Currently
|
|
this is hardcoded to 16). And instances can be dynamically created and
|
|
destroyed.
|
|
|
|
An object can be removed with the DestroyObject API. The handle returned by
|
|
the MakeObject is used to denote the object. Note this removes all the
|
|
instances (and all the counters) that were associated with the Object.
|
|
All pointers returned by the MakeCounter become invalidated and the risk is on
|
|
the API user not to reference them anymore.
|
|
|
|
*/
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfObjectW(PWCHAR pTitle, PWCHAR pHelp, DWORD nSize, BOOL bHasInstances, PVOID *lppObjectStart) ;
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfObjectA(char * pTitle, char *pHelp, DWORD nSize, BOOL bHasInstances, PVOID *lppObjectStart) ;
|
|
PERF_APP_API BOOL _stdcall DestroyPerfObject(HANDLE) ;
|
|
|
|
/*
|
|
MakeAPerfCounter:: Returns the Offset of the counter from the start of the
|
|
object.
|
|
*/
|
|
PERF_APP_API DWORD _stdcall MakeAPerfCounterW(DWORD dwType, DWORD dwScale, DWORD dwSize, HANDLE hObject, PWCHAR pDesc, PWCHAR pHelp);
|
|
PERF_APP_API DWORD _stdcall MakeAPerfCounterA(DWORD dwType, DWORD dwScale, DWORD dwSize, HANDLE hObject, char * pDesc, char * pHelp);
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfCounterHandleW(DWORD dwType, DWORD dwScale, DWORD dwSize, HANDLE hObject, PWSTR pCounterName, PWSTR pHelp);
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfCounterHandleA(DWORD dwType, DWORD dwScale, DWORD dwSize, HANDLE hObject,char * pCounterName, char * pHelp);
|
|
PERF_APP_API BOOL _stdcall DestroyPerfCounterHandle(HANDLE pCounterInfo);
|
|
/*
|
|
MakeAPerfInstance - creates a new instance of an already existing Object and
|
|
duplicates all its counters, further any counter created for the object gets
|
|
duplicated too.
|
|
|
|
If the return HANDLE is NULL then the API failed else success.
|
|
The returned HANDLE can be used to Destroy the object instance.
|
|
The final form of this api should be
|
|
MakeAPerfInstanceW(HANDLE, PWCHAR pInstName) ;
|
|
The object name has to be replaced by the object handle returned by MakeObject
|
|
*/
|
|
PERF_APP_API INSTANCE_ID _stdcall MakeAPerfInstanceW(HANDLE hObject, PWCHAR pInstName, PVOID *lppInstanceStart) ;
|
|
PERF_APP_API INSTANCE_ID _stdcall MakeAPerfInstanceA(HANDLE hObject, char *pInstName, PVOID *lppInstanceStart) ;
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfInstanceHandleW(HANDLE hObject, PWCHAR pInstName);
|
|
PERF_APP_API HANDLE _stdcall MakeAPerfInstanceHandleA(HANDLE hObject, char *pInstName);
|
|
PERF_APP_API BOOL _stdcall DestroyPerfInstance(INSTANCE_ID iID);
|
|
PERF_APP_API BOOL _stdcall DestroyPerfInstanceHandle(HANDLE pInstanceInfo);
|
|
PERF_APP_API BOOL _stdcall SetCounterValueByHandle(HANDLE hCounter, HANDLE hParent, PBYTE pbNewValue);
|
|
PERF_APP_API BOOL _stdcall GetCounterValueByHandle(HANDLE hCounter, HANDLE hParent, PBYTE pbCounterValue);
|
|
PERF_APP_API BOOL _stdcall IncrementCounterByHandle(HANDLE hCounter, HANDLE hParent, PBYTE pbIncrement);
|
|
PERF_APP_API BOOL _stdcall DecrementCounterByHandle(HANDLE hCounter, HANDLE hParent, PBYTE pbDecrement);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef UNICODE
|
|
#define MakeAPerfObject MakeAPerfObjectW
|
|
#define MakeAPerfCounter MakeAPerfCounterW
|
|
#define MakeAPerfCounterHandle MakeAPerfCounterHandleW
|
|
#define MakeAPerfInstance MakeAPerfInstanceW
|
|
#define MakeAPerfInstanceHandle MakeAPerfInstanceHandleW
|
|
#else
|
|
#define MakeAPerfObject MakeAPerfObjectA
|
|
#define MakeAPerfCounter MakeAPerfCounterA
|
|
#define MakeAPerfCounterHandle MakeAPerfCounterHandleA
|
|
#define MakeAPerfInstance MakeAPerfInstanceA
|
|
#define MakeAPerfInstanceHandle MakeAPerfInstanceHandleA
|
|
#endif //UNICODE
|
|
|
|
#endif // __PERFAPI_H__
|