#ifndef _PCLIB_H_ #define _PCLIB_H_ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // PCLIB.H // // Public interface to PCLIB to be used by perf counter data // generating and monitoring components. // // Copyright 1986-1998 Microsoft Corporation, All Rights Reserved // // // A signature that uniquely identifies the component whose perf counters are // being implemented. This must be identical to the value of the drivername // key in the [info] section of the perf counter INI file. It is used to // locate the counters' "first counter" information in the registry. // EXTERN_C const WCHAR gc_wszSignature[]; // ************************************************************************ // // INTERFACE for counter data generating processes // // ======================================================================== // // CLASS IPerfCounterBlock // // Created by IPerfObject::NewInstance(). A perf counter block // encapsulates the set of counters for a given instance. The // methods of this interface define the mechanism for changing // the values of the counters in the counter block. // class IPerfCounterBlock { public: // CREATORS // virtual ~IPerfCounterBlock() = 0; // MANIPULATORS // virtual VOID IncrementCounter( UINT iCounter ) = 0; virtual VOID DecrementCounter( UINT iCounter ) = 0; virtual VOID SetCounter( UINT iCounter, LONG lValue ) = 0; }; // ======================================================================== // // CLASS IPerfObject // // Created by PCLIB::NewPerfObject(). A perf object defines a set of // counters. In terms of the NT perf counter structures, a perf object // encapsulates a PERF_OBJECT_TYPE and its PERF_COUNTER_DEFINITIONs. // // IPerfObject::NewInstance() creates a new instance of this perf object // from a PERF_INSTANCE_DEFINITION and a PERF_COUNTER_BLOCK. All values // of both structures must be properly initialized prior to calling // IPerfObject::NewInstance() following standard conventions for these // structures. I.e. the instance name must immediately follow the // PERF_INSTANCE_DEFINITION structure, and the PERF_COUNTER_BLOCK must // be DWORD-aligned following the name. The PERF_COUNTER_BLOCK should // be followed by the counters themselves. Read the documentation for // these structures if you're confused. // class IPerfObject { public: // CREATORS // virtual ~IPerfObject() = 0; // MANIPULATORS // virtual IPerfCounterBlock * NewInstance( const PERF_INSTANCE_DEFINITION& pid, const PERF_COUNTER_BLOCK& pcb ) = 0; }; // ======================================================================== // // NAMESPACE PCLIB // // The top level of the PCLIB interface. PCLIB::FInitialize() should be // called once per process to initialize the library. Similarly, // PCLIB::Deinitialize() should be called once per process to deinitialize // it. NOTE: To simplify your error code cleanup, it is safe to call // PCLIB::Deinitialize() even if you did not call PCLIB::FInitialize(). // // PCLIB::NewPerfObject() creates a new perf object from a // PERF_OBJECT_TYPE and subsequent PERF_COUNTER_DEFINITIONs. All values // of both structures must be properly initialized prior to calling // PCLIB::NewPerfObject() following standard conventions for these // structures, with one exception: PERF_OBJECT_TYPE::NumInstances and // PERF_OBJECT_TYPE::TotalByteLength should both be initialized to 0. // These values are computed in the monitor process because the number // of instances is not generally fixed at the time the object is created. // namespace PCLIB { // // Initialization/Deinitialization // BOOL __fastcall FInitialize( LPCWSTR lpwszSignature ); VOID __fastcall Deinitialize(); // // Instance registration // IPerfObject * __fastcall NewPerfObject( const PERF_OBJECT_TYPE& pot ); }; // ======================================================================== // // CLASS CPclibInit // // PCLIB initializer class. Simplifies PCLIB initialization and // deinitialization. // class CPclibInit { // NOT IMPLEMENTED // CPclibInit& operator=( const CPclibInit& ); CPclibInit( const CPclibInit& ); public: CPclibInit() { } BOOL FInitialize( LPCWSTR lpwszSignature ) { return PCLIB::FInitialize( lpwszSignature ); } ~CPclibInit() { PCLIB::Deinitialize(); } }; // ************************************************************************ // // INTERFACE for counter monitors // // ------------------------------------------------------------------------ // // The interface for monitors *IS* the perfmon interface! // Just define these as EXPORTS for your monitor DLL and you're done. // EXTERN_C BOOL WINAPI FDllEntry( HINSTANCE hinst, DWORD dwReason, LPVOID lpvReserved ); EXTERN_C DWORD APIENTRY OpenPerformanceData( LPCWSTR ); EXTERN_C DWORD APIENTRY CollectPerformanceData( LPCWSTR lpwszCounterIndices, LPVOID * plpvPerfData, LPDWORD lpdwcbPerfData, LPDWORD lpcObjectTypes ); EXTERN_C DWORD APIENTRY ClosePerformanceData(); EXTERN_C STDAPI DllRegisterServer(VOID); EXTERN_C STDAPI DllUnregisterServer(VOID); // ------------------------------------------------------------------------ // // Or, for the do-it-yourself'er.... // // Step 1) Initialize shared memory (see inc\smh.h) // Step 2) Call NewCounterPublisher() or NewCounterMonitor() (depending // on which you are!) passing in the string you used in Step 1. // class ICounterData { protected: // CREATORS // Only create this object through it's descendents! // ICounterData() {}; public: // CREATORS // virtual ~ICounterData() = 0; // MANIPULATORS // virtual IPerfObject * CreatePerfObject( const PERF_OBJECT_TYPE& pot ) = 0; virtual DWORD DwCollectData( LPCWSTR lpwszCounterIndices, DWORD dwFirstCounter, LPVOID * plpvPerfData, LPDWORD lpdwcbPerfData, LPDWORD lpcObjectTypes ) = 0; }; ICounterData * __fastcall NewCounterPublisher( LPCWSTR lpwszSignature ); ICounterData * __fastcall NewCounterMonitor( LPCWSTR lpwszSignature ); #endif // !defined(_PCLIB_H_)