#ifndef __PERFAPI_H__ #define __PERFAPI_H__ #include 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__