24 static char THIS_FILE[] = __FILE__;
28 #include"../DumpWinMsg.hpp"
30 #pragma comment(lib, "loadperf.lib")
32 using namespace libjmmcg;
41 template <> HeapID NTPerformanceObjects::sm_char_heap_type::GetHeapID(
void) {
42 return HeapID(initial_shared_memory_size, string_shared_memory_name, string_shared_mutex_name, &NTPerformanceObjects::allow_all);
45 template <> HeapID NTPerformanceObjects::nt_po_heap_type::GetHeapID(
void) {
46 return HeapID(initial_shared_memory_size, ptr_shared_memory_name, ptr_shared_mutex_name, &NTPerformanceObjects::allow_all);
49 template <> HeapID NTPerformanceObjects::sm_string_heap_type::GetHeapID(
void) {
50 return HeapID(initial_shared_memory_size, list_shared_memory_name, list_shared_mutex_name, &NTPerformanceObjects::allow_all);
53 template <> HeapID NTPerformanceObjects::cpp_po_heap_type::GetHeapID(
void) {
54 return HeapID(initial_shared_memory_size, map_shared_memory_name, map_shared_mutex_name, &NTPerformanceObjects::allow_all);
64 DWORD CALLBACK OpenPerformanceData(LPWSTR lpDeviceNames) {
65 NTUtils::CSectionLock lock(NTPerformanceObjects::perf_ctr_map_sect);
66 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_information, NTUtils::EventLog::cat_custom1,
"OpenPerformanceData(...) : Connecting ...");
69 NTPerformanceObjects::cpp_po_heap_type cpp_po_heap(HeapID(initial_shared_memory_size, map_shared_memory_names, &NTPerformanceObjects::allow_all));
70 NTPerformanceObjects::cpp_performance_objects_type *
const cpp_performance_objects=(NTPerformanceObjects::cpp_performance_objects_type *)cpp_po_heap;
71 if (cpp_performance_objects->find(
reinterpret_cast<
char *>(lpDeviceNames))==cpp_performance_objects->end()) {
72 str=
"OpenPerformanceData(...) : The device name does not exist:'";
73 str+=
reinterpret_cast<
char *>(lpDeviceNames);
75 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_information, NTUtils::EventLog::cat_custom1, str);
76 return ERROR_DEV_NOT_EXIST;
78 return NTPerformanceObjects::Open((*cpp_performance_objects)[
reinterpret_cast<
char *>(lpDeviceNames)]);
79 }
catch (std::exception err) {
80 str=
"OpenPerformanceData(...) : Connection failure.\nSTL exception caught.\nDetails:\n";
82 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom1, str);
84 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom1,
"OpenPerformanceData(...) : Connection failure.\nUnknown exception caught.");
86 return ERROR_INVALID_FUNCTION;
90 DWORD WINAPI CollectPerformanceData(LPWSTR lpwszValue, LPVOID *lppData, LPDWORD lpcbBytes, LPDWORD lpcObjectTypes) {
91 NTUtils::CSectionLock lock(NTPerformanceObjects::perf_ctr_map_sect);
92 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_information, NTUtils::EventLog::cat_custom2,
"CollectPerformanceData(...) : Collecting...");
95 NTPerformanceObjects::cpp_po_heap_type cpp_po_heap(HeapID(initial_shared_memory_size, map_shared_memory_names, &NTPerformanceObjects::allow_all));
96 NTPerformanceObjects::cpp_performance_objects_type *
const cpp_performance_objects=(NTPerformanceObjects::cpp_performance_objects_type *)cpp_po_heap;
97 std::auto_ptr<
char> n_value(
new char[wcslen(lpwszValue)]);
98 CharToOemW(lpwszValue, n_value.get());
99 str=
"CollectPerformanceData(...) : Collection parameters:\nCollection load type:'";
102 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_information, NTUtils::EventLog::cat_custom2, str);
103 if (cpp_performance_objects->find(n_value.get())==cpp_performance_objects->end()) {
104 str=
"CollectPerformanceData(...) : The device name does not exist:'";
107 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom2, str);
108 return ERROR_DEV_NOT_EXIST;
110 return NTPerformanceObjects::Collect((*cpp_performance_objects)[n_value.get()], lpwszValue, lppData, lpcbBytes, lpcObjectTypes);
111 }
catch (std::exception err) {
112 str=
"CollectPerformanceData(...) : Connection failure.\nSTL exception caught.\nDetails:";
114 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom2, str);
116 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom2,
"CollectPerformanceData(...) : Connection failure.\nUnknown exception caught.");
120 return ERROR_INVALID_FUNCTION;
124 DWORD WINAPI ClosePerformanceData(
void) {
125 NTUtils::CSectionLock lock(NTPerformanceObjects::perf_ctr_map_sect);
126 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_information, NTUtils::EventLog::cat_custom3,
"ClosePerformanceData() : Disconnecting.");
129 return NTPerformanceObjects::Close();
130 }
catch (std::exception err) {
131 str=
"CollectPerformanceData(...) : Connection failure.\nSTL exception caught.\nDetails:";
133 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom3, str);
135 NTPerformanceObjects::nt_event_log.Log(NTUtils::EventLog::err_error, NTUtils::EventLog::cat_custom3,
"CollectPerformanceData(...) : Connection failure.\nUnknown exception caught.");
137 return ERROR_INVALID_FUNCTION;
147 NTUtils::EventLog NTPerformanceObjects::nt_event_log(
"NTPerformanceObjects");
154 driver_name( TempPerfINIFile::make_driver_name(perf_obj_details
.object.name) ),
164 std::cerr <<
"NTPerformanceObjects::NTPerformanceObjects(...) : Performance object: '" << driver_name <<
"' must have at least one counter." << std::endl;
179 conststd::stringctr_name(
"SYSTEM\\CurrentControlSet\\Services\\"+driver_name);
181 if (perf_key.Open(HKEY_LOCAL_MACHINE, ctr_name)==ERROR_SUCCESS) {
182 std::cerr <<
"NTPerformanceObjects::NTPerformanceObjects(...) : Performance counter '" << ctr_name <<
"' already created. Cannot have duplicate named counters." << std::endl;
183 }
else if (perf_key.Create(HKEY_LOCAL_MACHINE, ctr_name)==ERROR_SUCCESS
184 && perf_perf_key.Create(perf_key.hkey(),
"Performance")==ERROR_SUCCESS
185 && perf_link_key.Create(perf_key.hkey(),
"Linkage")==ERROR_SUCCESS) {
186 size_t total_ctr_size=0;
187 std::set< PerfObjectDetails::PerfCtrDetails >::const_iterator iter( perf_obj_details.counters.begin() );
188 while ( iter!=perf_obj_details.counters.end() ) {
189 total_ctr_size+=
sizeof(PERF_COUNTER_BLOCK)+iter->size;
192 perf_ctrs_details=
reinterpret_cast<perf_ctrs_details_type *>(
new char[total_ctr_size]);
193 perf_objects_details=
reinterpret_cast<perf_objects_details_type *>(
new char[
sizeof(PERF_OBJECT_TYPE)+
sizeof(PERF_COUNTER_DEFINITION)*perf_obj_details.counters.size()]);
194 perf_objects_details->object_type.HeaderLength=
sizeof(PERF_OBJECT_TYPE);
195 perf_objects_details->object_type.DefinitionLength=perf_objects_details->object_type.HeaderLength+
sizeof(PERF_COUNTER_DEFINITION)*perf_obj_details.counters.size();
196 perf_objects_details->object_type.TotalByteLength=perf_objects_details->object_type.DefinitionLength+perf_ctrs_details->ctr_block.ByteLength;
197 perf_objects_details->object_type.ObjectNameTitleIndex=0;
198 perf_objects_details->object_type.ObjectNameTitle=0;
199 perf_objects_details->object_type.ObjectHelpTitleIndex=0;
200 perf_objects_details->object_type.ObjectHelpTitle=0;
201 perf_objects_details->object_type.DetailLevel=PERF_DETAIL_ADVANCED;
202 perf_objects_details->object_type.NumCounters=(perf_objects_details->object_type.DefinitionLength-
sizeof(PERF_OBJECT_TYPE))/
sizeof(PERF_COUNTER_DEFINITION);
203 perf_objects_details->object_type.DefaultCounter=0;
204 perf_objects_details->object_type.NumInstances=PERF_NO_INSTANCES;
205 perf_objects_details->object_type.CodePage=0;
206 iter=perf_obj_details.counters.begin();
207 std::set< PerfObjectDetails::PerfCtrDetails >::size_type i=0;
208 while ( iter!=perf_obj_details.counters.end() ) {
209 reinterpret_cast<perf_ctrs_details_type *>(perf_ctrs_details+i*(
sizeof(PERF_COUNTER_BLOCK)+iter->size))->ctr_block.ByteLength=
sizeof(PERF_COUNTER_BLOCK)+iter->size;
210 perf_objects_details->ctr_defs[i].ByteLength=
sizeof(PERF_COUNTER_DEFINITION);
211 perf_objects_details->ctr_defs[i].CounterNameTitleIndex=(i<<1);
212 perf_objects_details->ctr_defs[i].CounterNameTitle=0;
213 perf_objects_details->ctr_defs[i].CounterHelpTitleIndex=(i<<1);
214 perf_objects_details->ctr_defs[i].CounterHelpTitle=0;
215 perf_objects_details->ctr_defs[i].DefaultScale=0;
216 perf_objects_details->ctr_defs[i].DetailLevel=PERF_DETAIL_ADVANCED;
217 perf_objects_details->ctr_defs[i].CounterType=iter->flags;
218 perf_objects_details->ctr_defs[i].CounterSize=
sizeof(perf_ctrs_details->values[i]);
219 perf_objects_details->ctr_defs[i].CounterOffset=(DWORD)&(((perf_ctrs_details_type *)NULL)->values[i]);
223 char mod_name[MAX_PATH];
225 if (GetModuleFileName(GetModuleHandle(
"cmduilib"), mod_name, MAX_PATH)) {
226 perf_link_key.SetValue(driver_name,
"Export", REG_BINARY);
227 perf_perf_key.SetValue(mod_name,
"Library");
229 perf_perf_key.SetValue(
"_OpenPerformanceData@4",
"Open");
231 perf_perf_key.SetValue(
"_CollectPerformanceData@16",
"Collect");
233 perf_perf_key.SetValue(
"_ClosePerformanceData@0",
"Close");
234 TempPerfINIFile ini_file(obj_prefix, lang_details, perf_obj_details);
237 if ((err=LoadPerfCounterTextStrings(
const_cast<
char *
const>((
"x " + ini_file.name()).c_str()), quiet))!=ERROR_SUCCESS) {
238 std::cerr <<
"NTPerformanceObject::NTPerformanceObject(...) : '" << NTUtils::DumpWinMessage(err) <<
"'" << std::endl;
241 std::cerr <<
"NTPerformanceObjects::NTPerformanceObjects(...) : Failed to get module name. Windows error: '" << NTUtils::DumpWinMessage(::GetLastError()) <<
"'" << std::endl;
248 NTUtils::CSectionLock lock(perf_ctr_map_sect);
254 if ((err=UnloadPerfCounterTextStrings(
const_cast<
char *
const>((
"x " + driver_name).c_str()), quiet))!=ERROR_SUCCESS) {
255 std::cerr <<
"NTPerformanceObjects::~NTPerformanceObjects() : '" << NTUtils::DumpWinMessage(err) <<
"'" << std::endl;
257 if (perf_ctrs_details) {
258 delete[]
reinterpret_cast<
char *>(perf_ctrs_details);
260 if (perf_objects_details) {
261 delete[]
reinterpret_cast<
char *>(perf_objects_details);
268 NTUtils::RegistryKey perf_key;
270 if ((ret=perf_key.Open(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\" + driver_name +
"\\Performance"))==ERROR_SUCCESS) {
271 DWORD size=
sizeof(DWORD);
273 DWORD dwFirstCounter;
275 if ((ret=::RegQueryValueEx(perf_key.hkey(),
"First Counter", 0L, &type, (LPBYTE)&dwFirstCounter, &size))!=ERROR_SUCCESS) {
276 std::cerr <<
"NTPerformanceObjects::Open() : Unable to query key 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\" << driver_name <<
"\\Performance\\First Counter'." << std::endl;
277 std::cerr <<
"Error is '" << NTUtils::DumpWinMessage(ret) <<
"'" << std::endl;
281 if ((ret=::RegQueryValueEx(perf_key.hkey(),
"First Help", 0L, &type, (LPBYTE)&dwFirstHelp, &size))!=ERROR_SUCCESS) {
282 std::cerr <<
"NTPerformanceObjects::Open() : Unable to query key 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\" << driver_name <<
"\\Performance\\First Help'." << std::endl;
283 std::cerr <<
"Error is '" << NTUtils::DumpWinMessage(ret) <<
"'" << std::endl;
286 perf_objects_details->object_type.ObjectNameTitleIndex+=dwFirstCounter;
287 perf_objects_details->object_type.ObjectHelpTitleIndex+=dwFirstHelp;
288 perf_objects_details->object_type.DefaultCounter=0;
289 std::set< PerfObjectDetails::PerfCtrDetails >::size_type i=0;
290 while ( i<num_ctrs ) {
291 perf_objects_details->ctr_defs[i].CounterNameTitleIndex+=dwFirstCounter;
292 perf_objects_details->ctr_defs[i].CounterHelpTitleIndex+=dwFirstHelp;
302 return ERROR_SUCCESS;
306 NTPerformanceObjects::TempPerfINIFile::TempPerfINIFile(
const std::string &obj_prefix,
const std::pair<
std::string,
std::string > &lang_details,
const PerfObjectDetails &perf_obj_details) : symbol(obj_prefix, perf_obj_details.counters.size()+1) {
307 ini.file() <<
"[info]" << std::endl;
308 const std::string driver_name(make_driver_name(perf_obj_details
.object.name));
309 ini.file() <<
"drivername=" << driver_name << std::endl;
310 ini.file() <<
"symbolfile=" << symbol.name() << std::endl;
311 ini.file() <<
"[languages]" << std::endl;
312 ini.file() << lang_details.first <<
"=" << lang_details.second << std::endl;
313 ini.file() <<
"[text]" << std::endl;
314 ini.file() << symbol.names()[0] <<
"_" << lang_details.first <<
"_NAME=" << driver_name << std::endl;
315 ini.file() << symbol.names()[0] <<
"_" << lang_details.first <<
"_HELP=" << perf_obj_details.object.help << std::endl;
316 std::vector< std::string >::size_type i=1;
317 std::set< PerfObjectDetails::PerfCtrDetails >::const_iterator iter( perf_obj_details.counters.begin() );
318 while (i<symbol.names().size()) {
319 ini.file() << symbol.names()[i] <<
"_" << lang_details.first <<
"_NAME=" << iter->details.name << std::endl;
320 ini.file() << symbol.names()[i] <<
"_" << lang_details.first <<
"_HELP=" << iter->details.help << std::endl;
324 ini.file() << std::endl;
339 char bname[MAX_PATH];
340 ::GetModuleFileName(NULL,bname,MAX_PATH);
341 std::string name(bname);
342 const std::string::size_type begin=name.find_last_of(
'\\')+1;
343 name=name.substr(begin, name.find_last_of(
'.')-begin);
344 return name +
" " + str;
347 inline NTPerformanceObjects::TempPerfINIFile::TempSymbolFile::TempSymbolFile(
const std::string &obj_prefix,
const std::vector< std::string >::size_type size) {
348 std::vector< std::string >::size_type i=0;
350 std::stringstream ss;
351 ss << obj_prefix <<
"_" << i;
352 object_names.push_back(ss.str());
353 symbol.file() <<
"#define " << object_names[i] <<
" " << (i<<1) << std::endl;
356 symbol.file().close();
364 return symbol.name();
367 inline const std::vector< std::string > &
NTPerformanceObjects::TempPerfINIFile::TempSymbolFile::names(
void)
const {