00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #ifndef OW32_PerfData_h
00029 #define OW32_PerfData_h
00030
00031 #include <OW32/OW32libs.h>
00032 #include <OW32/windows.h>
00033 #include <winperf.h>
00034 #include <string>
00035 #include <map>
00036 #include <OW32/tstl.h>
00037 #include <OW32/XHANDLE.h>
00038 #include <OW32/SyncObjects.h>
00039
00040 namespace OW32
00041 {
00042
00043 class OW32_LIB_EXPORT CPerfObject;
00044 class OW32_LIB_EXPORT CPerfCounter;
00045
00049 class OW32_LIB_EXPORT CPerfDataException
00050 {
00051 public:
00059 CPerfDataException(
00060 LPCTSTR prefix,
00061 DWORD error = ERROR_INTERNAL_ERROR
00062 ) :
00063 m_prefix(prefix),
00064 m_error(error)
00065 {
00066 }
00067
00072 DWORD getWin32Error() const { return m_error; }
00073
00077 const std::_tstring &getPrefix() const { return m_prefix; }
00078
00082 std::_tstring getFormattedError() const;
00083
00084 private:
00085 std::_tstring m_prefix;
00086 DWORD m_error;
00087 };
00088
00089 #ifdef _MSC_VER
00090 #pragma warning(disable: 4251)
00091 #endif
00092
00096 class OW32_LIB_EXPORT CPerfData
00097 {
00098 public:
00102 typedef DWORD ObjectId;
00103
00107 typedef DWORD CounterId;
00108
00112 typedef DWORD InstanceId;
00113
00119 enum { PERF_COUNTER_STORAGE = sizeof(__int64) };
00120
00126 CPerfData(LPCWSTR appName);
00127
00131 ~CPerfData();
00132
00140 void addObject(CPerfObject *object);
00141
00148 CPerfObject *getObjectById(ObjectId objectId);
00149
00168 DWORD collect(LPWSTR values, LPVOID *ppData, LPDWORD pBytes, LPDWORD pcObjectTypes);
00169
00186 void activate(bool fApplication);
00187
00204 void deactivate();
00205
00211 void install(LPCTSTR perfCollectorPath);
00212
00216 void uninstall();
00217
00232 InstanceId addInstance(ObjectId objectId, LPCWSTR name,
00233 ObjectId parentObjectId = 0, InstanceId parentInstanceId = 0)
00234 {
00235 return addInstance(objectId, name, PERF_NO_UNIQUE_ID, parentObjectId, parentInstanceId);
00236 }
00237
00253 InstanceId addInstance(ObjectId objectId, LONG uniqueID,
00254 ObjectId parentObjectId = 0, InstanceId parentInstanceId = 0)
00255 {
00256 return addInstance(objectId, NULL, uniqueID, parentObjectId, parentInstanceId);
00257 }
00258
00268 void removeInstance(ObjectId objectId, InstanceId instanceId);
00269
00287 __int64 *getCounter64(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0)
00288 {
00289 return (__int64 *)getCounter(objectId, counterId, instanceId);
00290 }
00291
00309 LONG *getCounter32(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0)
00310 {
00311 return (LONG *)getCounter(objectId, counterId, instanceId);
00312 }
00313
00331 BYTE *getCounter(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0);
00332
00352 bool lock(DWORD timeout = INFINITE);
00353
00361 void unlock();
00362
00363 private:
00364
00382 InstanceId addInstance(ObjectId objectId, LPCWSTR name, LONG uniqueID,
00383 ObjectId parentObjectId, InstanceId parentInstanceId);
00384
00388 void initialiseMMF();
00389
00393 void computeMMFOffsets();
00394
00398 void readCounterIndexes();
00399
00407 void appendCounterTitle(std::wstring &data, LPCWSTR title);
00408
00416 void appendHelpTitle(std::wstring &data, LPCWSTR title);
00417
00421 CPerfObject *m_firstObject;
00422
00426 CPerfObject *m_lastObject;
00427
00431 DWORD m_firstHelp;
00432
00436 DWORD m_lastHelp;
00437
00441 DWORD m_firstCounter;
00442
00446 DWORD m_lastCounter;
00447
00451 LPCWSTR m_appName;
00452
00456 XHANDLE m_hPerfData;
00457
00464 BYTE *m_pPerfData;
00465
00469 typedef std::map<CPerfData::ObjectId, CPerfObject*> object_id_map_t;
00470
00474 object_id_map_t m_objectIdMap;
00475
00482 CEvent m_lockEvent;
00483
00493 CEvent m_applicationEvent;
00494
00501 bool m_fApplication;
00502 };
00503
00504 #ifdef _MSC_VER
00505 #pragma warning(default: 4251)
00506 #endif
00507
00508 #ifdef _MSC_VER
00509 #pragma warning(disable: 4251)
00510 #endif
00511
00515 class OW32_LIB_EXPORT CPerfObject
00516 {
00517 public:
00530 CPerfObject(
00531 CPerfData *perfData,
00532 CPerfData::ObjectId objectId,
00533 LPCWSTR name,
00534 LPCWSTR help,
00535 DWORD detailLevel,
00536 CPerfData::CounterId defaultCounterId,
00537 DWORD maxInstances,
00538 DWORD maxInstanceName
00539 );
00540
00544 DWORD addCounter(CPerfCounter *counter);
00545
00549 void setNext(CPerfObject *next);
00550
00554 void setTitleInfo(DWORD titleIndex, DWORD helpTitleIndex);
00555
00562 void setPerfInstanceInfo(BYTE *firstInstance, DWORD instanceSize);
00563
00569 void setPerfType(PERF_OBJECT_TYPE *type);
00570
00578 bool getFreeInstance(PERF_INSTANCE_DEFINITION **instance, CPerfData::InstanceId *instanceId);
00579
00583 DWORD getPerfInstanceIndex(CPerfData::InstanceId instanceId);
00584
00595 BYTE *getCounter(CPerfData::InstanceId instanceId, CPerfData::CounterId counterId);
00596
00600 void removeInstance(CPerfData::InstanceId instanceId);
00601
00605 CPerfCounter *getCounterById(CPerfData::CounterId counterId);
00606
00610 CPerfObject *getNext() const { return m_next; }
00611
00615 CPerfCounter *getFirstCounter() const { return m_firstCounter; }
00616
00620 CPerfData::ObjectId getId() const { return m_objectId; }
00621
00625 LPCWSTR getName() const { return m_name; }
00626
00630 LPCWSTR getHelp() const { return m_help; }
00631
00635 DWORD getDetailLevel() const { return m_detailLevel; }
00636
00640 CPerfData::CounterId getDefaultCounterId() const { return m_defaultCounterId; }
00641
00647 DWORD getMaxInstances() const { return m_maxInstances; }
00648
00652 bool singleInstance() const { return m_maxInstances == PERF_NO_INSTANCES; }
00653
00658 DWORD getMaxInstanceName() const { return m_maxInstanceName; }
00659
00663 DWORD getTitleIndex() const { return m_titleIndex; }
00664
00668 DWORD getHelpTitleIndex() const { return m_helpTitleIndex; }
00669
00679 DWORD collect(CPerfData *perfData, LPVOID *pBuffer, LPDWORD pBytes);
00680
00684 void setCollect(bool fCollect) { m_fCollect = fCollect; }
00685
00689 bool getCollect() const { return m_fCollect; }
00690
00697 void checkChildDependencies(CPerfData *perfData);
00698
00703 DWORD getCountersWithData() const { return m_countersWithData; }
00704
00705 private:
00709 CPerfData::ObjectId m_objectId;
00710
00714 LPCWSTR m_name;
00715
00719 LPCWSTR m_help;
00720
00724 DWORD m_detailLevel;
00725
00729 CPerfData::CounterId m_defaultCounterId;
00730
00734 DWORD m_maxInstances;
00735
00739 DWORD m_maxInstanceName;
00740
00744 CPerfObject *m_next;
00745
00749 CPerfCounter *m_firstCounter;
00750
00754 CPerfCounter *m_lastCounter;
00755
00759 DWORD m_titleIndex;
00760
00764 DWORD m_helpTitleIndex;
00765
00769 BYTE *m_firstInstance;
00770
00774 DWORD m_instanceSize;
00775
00779 PERF_OBJECT_TYPE *m_perfObjectType;
00780
00784 typedef std::map<CPerfData::CounterId, CPerfCounter*> counter_id_map_t;
00785
00786
00787
00788
00789 counter_id_map_t m_counterIdMap;
00790
00794 bool m_fCollect;
00795
00801 DWORD m_countersWithData;
00802 };
00803
00804 #ifdef _MSC_VER
00805 #pragma warning(default: 4251)
00806 #endif
00807
00811 class OW32_LIB_EXPORT CPerfCounter
00812 {
00813 public:
00827 CPerfCounter(
00828 CPerfObject *object,
00829 CPerfData::CounterId counterId,
00830 LPCWSTR name,
00831 LPCWSTR help,
00832 DWORD detailLevel,
00833 DWORD defaultScale,
00834 DWORD type,
00835 CPerfData::CounterId counterIdParent = 0
00836 );
00837
00843 void setNext(CPerfCounter *next);
00844
00851 void setTitleInfo(DWORD counterTitleIndex, DWORD helpTitleIndex);
00852
00856 DWORD getIndex() const { return m_index; }
00857
00861 CPerfData::CounterId getId() const { return m_counterId; }
00862
00866 CPerfCounter *getNext() const { return m_next; }
00867
00871 LPCWSTR getName() const { return m_name; }
00872
00876 LPCWSTR getHelp() const { return m_help; }
00877
00881 DWORD getDetailLevel() const { return m_detailLevel; }
00882
00886 DWORD getDefaultScale() const { return m_defaultScale; }
00887
00891 DWORD getType() const { return m_type; }
00892
00896 CPerfData::CounterId getParentCounter() const { return m_parentCounterId; }
00897
00901 bool shared() const { return m_parentCounterId != 0; }
00902
00903 private:
00907 CPerfData::CounterId m_counterId;
00908
00912 LPCWSTR m_name;
00913
00917 LPCWSTR m_help;
00918
00922 DWORD m_detailLevel;
00923
00927 DWORD m_defaultScale;
00928
00932 DWORD m_type;
00933
00937 DWORD m_index;
00938
00942 CPerfCounter *m_next;
00943
00947 DWORD m_counterTitleIndex;
00948
00952 DWORD m_helpTitleIndex;
00953
00957 CPerfData::CounterId m_parentCounterId;
00958 };
00959
00969 #define PERF_DECLARE_MAP(appName) \
00970 extern OW32::CPerfData g_perfData_##appName;
00971
00983 #define PERF_DEFINE_OBJECT(sym, val) \
00984 const OW32::CPerfData::ObjectId sym = (OW32::CPerfData::ObjectId)val;
00985
00995 #define PERF_DEFINE_COUNTER(sym, val) \
00996 const OW32::CPerfData::CounterId sym = (OW32::CPerfData::CounterId)val;
00997
01008 #define PERF_MAP_BEGIN(appName) \
01009 OW32::CPerfData g_perfData_##appName(L#appName); \
01010 class CPerfMapConstructor \
01011 { \
01012 public: \
01013 CPerfMapConstructor(OW32::CPerfData *perfData); \
01014 }; \
01015 \
01016 CPerfMapConstructor::CPerfMapConstructor(OW32::CPerfData *perfData) \
01017 {
01018
01033 #define PERF_MAP_BEGIN_OBJECT(objectId, name, help, detailLevel, defaultCounterId, maxInstances, maxInstanceName) \
01034 { \
01035 static OW32::CPerfObject currentObject( \
01036 perfData, objectId, L##name, L##help, detailLevel, defaultCounterId, \
01037 static_cast<DWORD>(maxInstances), maxInstanceName);
01038
01049 #define PERF_MAP_COUNTER(counterId, name, help, detailLevel, defaultScale, type) \
01050 { \
01051 static OW32::CPerfCounter currentCounter( \
01052 ¤tObject, counterId, L##name, L##help, detailLevel, \
01053 static_cast<DWORD>(defaultScale), type); \
01054 }
01055
01073 #define PERF_MAP_COUNTER_SHARED(counterId, counterIdData, name, help, detailLevel, defaultScale, type) \
01074 { \
01075 static OW32::CPerfCounter currentCounter( \
01076 ¤tObject, counterId, L##name, L##help, detailLevel, defaultScale, type, counterIdData); \
01077 }
01078
01083 #define PERF_MAP_END_OBJECT() \
01084 } \
01085
01086
01093 #define PERF_MAP_END(appName) \
01094 } \
01095 static CPerfMapConstructor s_constructPerfData(&g_perfData_##appName);
01096
01114 #define PERF_IMPLEMENT_COLLECTOR(appName) \
01115 extern OW32::CPerfData g_perfData_##appName; \
01116 extern "C" { \
01117 DWORD WINAPI OW32_PerfData_##appName##_Open(LPWSTR ) \
01118 { \
01119 try \
01120 { \
01121 g_perfData_##appName.activate(false); \
01122 return ERROR_SUCCESS; \
01123 } \
01124 catch (const OW32::CPerfDataException &e) \
01125 { \
01126 return e.getWin32Error(); \
01127 } \
01128 } \
01129 \
01130 DWORD WINAPI OW32_PerfData_##appName##_Close() \
01131 { \
01132 g_perfData_##appName.deactivate(); \
01133 return ERROR_SUCCESS; \
01134 } \
01135 \
01136 DWORD WINAPI OW32_PerfData_##appName##_Collect(LPWSTR values, LPVOID *ppData, LPDWORD pBytes, LPDWORD pcObjectTypes) \
01137 { \
01138 try \
01139 { \
01140 return g_perfData_##appName.collect(values, ppData, pBytes, pcObjectTypes); \
01141 } \
01142 catch (const OW32::CPerfDataException &e) \
01143 { \
01144 return e.getWin32Error(); \
01145 } \
01146 } \
01147 }
01148
01165 #define PERF_IMPLEMENT_COLLECTOR_REGISTRATION(appName) \
01166 extern OW32::CPerfData g_perfData_##appName; \
01167 extern "C" { \
01168 HINSTANCE ghInstance; \
01169 \
01170 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID ) \
01171 { \
01172 if (dwReason == DLL_PROCESS_ATTACH) \
01173 { \
01174 ghInstance = hInstance; \
01175 DisableThreadLibraryCalls(hInstance); \
01176 } \
01177 return TRUE; \
01178 } \
01179 \
01180 STDAPI DllRegisterServer() \
01181 { \
01182 TCHAR path[MAX_PATH*2]; \
01183 if (GetModuleFileName((HMODULE)ghInstance, path, sizeof(path)/sizeof(path[0]))==0) \
01184 return HRESULT_FROM_WIN32(::GetLastError()); \
01185 try \
01186 { \
01187 g_perfData_##appName.install(path); \
01188 } \
01189 catch (const OW32::CPerfDataException &e) \
01190 { \
01191 return HRESULT_FROM_WIN32(e.getWin32Error()); \
01192 } \
01193 return S_OK; \
01194 } \
01195 \
01196 STDAPI DllUnregisterServer() \
01197 { \
01198 try \
01199 { \
01200 g_perfData_##appName.uninstall(); \
01201 } \
01202 catch (const OW32::CPerfDataException &e) \
01203 { \
01204 return HRESULT_FROM_WIN32(e.getWin32Error()); \
01205 } \
01206 return S_OK; \
01207 } \
01208 }
01209
01210 };
01211
01212 #endif // OW32_PerfData_h