-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPdhQuery.cpp
374 lines (329 loc) · 10.3 KB
/
PdhQuery.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#include "PdhQuery.h"
#include <string>
using namespace std;
namespace ProcessFactorySpace {
#ifndef USE_GCC
/* zero the object */
PdhQuery::PdhQuery()
{
count = 0;
names = 0;
counters = 0;
last_error = 0;
}
/* close the object down */
PdhQuery::~PdhQuery()
{
/* free the names */
for(int i=0;i<count;i++)
{
if(names[i]) free(names[i]);
}
if(names)free(names);
/* free the counter array, this is not a pointer to pointer just a straight
array */
if(counters)free(counters);
/* close the query handle */
PdhCloseQuery(query_handle);
}
int PdhQuery::lookUpIndex(char *name)
{
int retval = -1;
for(int i=0;i<count;i++)
{
if(names[i]) /* care */
{
if(!::_stricmp(names[i],name))
{
retval = i;
break;
}
}
}
return retval;
}
bool PdhQuery::upSizeNames(char *name)
{
bool retval = false;
if(names = (char**)realloc(names,((count + 1) * sizeof(char*))))
{
names[count] = NULL;
if(names[count] = ::_strdup(name)) retval = true;
else
{
downSizeNames();
last_error = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
else last_error = PDH_MEMORY_ALLOCATION_FAILURE;
return retval;
}
bool PdhQuery::upSizeCounters()
{
bool retval = false;
if(counters = (PDHCOUNTERSTRUCT*)realloc(counters,
((count + 1) * sizeof(PDHCOUNTERSTRUCT))))
{
retval = true;
}
else last_error = PDH_MEMORY_ALLOCATION_FAILURE;
return retval;
}
bool PdhQuery::downSizeNames()
{
bool retval = true;
if(names[count]) free(names[count]);
names = (char**)realloc(names,(count * sizeof(char*)));
return retval;
}
bool PdhQuery::downSizeCounters()
{
bool retval = true;
counters = (PDHCOUNTERSTRUCT*)realloc(counters,
(count * sizeof(PDHCOUNTERSTRUCT)));
return retval;
}
/* init the object */
bool PdhQuery::init()
{
bool retval = false;
if((last_error = PdhOpenQuery(NULL,1,&query_handle)) == ERROR_SUCCESS)
{
retval = true;
}
return retval;
}
bool PdhQuery::addWildCardCounter(const string &wildCardPath, vector<string> &counterNames)
{
if(mapWildCardToCounters.count(wildCardPath) > 0)
{
cout << "addwildCardCounter() WARNING! wild card path exists : " << wildCardPath << endl;
return false;
}
char *paths = NULL;
unsigned long dwSize = 0;
PDH_STATUS status = PdhExpandWildCardPath(0, wildCardPath.c_str(), paths, &dwSize, 0);
if(status != PDH_MORE_DATA)
{
cout << "addWildCardCounter() ERROR! No expand wild card data on " << wildCardPath << endl;
return false;
}
dwSize = dwSize + 1;
char *pPaths = new char[dwSize];
status = PdhExpandWildCardPath(0, wildCardPath.c_str(), pPaths, &dwSize, 0);
if(status != ERROR_SUCCESS)
{
cout << "addWildCardCounter(): expand path failed on " << wildCardPath << endl;
return false;
}
LPTSTR ptr;
ptr = pPaths;
while(*ptr)
{
//cout << "addWildCardCounter(): adding counter " << ptr << endl;
bool ret = addCounter(ptr);
if(ret == false)
{
cout << "addWildCardCounter(): Couldn't add counter : " << ptr << endl;
}
else
{
counterNames.push_back(string(ptr));
mapWildCardToCounters[wildCardPath].push_back(ptr);
}
ptr += strlen(ptr);
ptr++;
}
delete pPaths;
return true;
}
/* add a counter */
bool PdhQuery::addCounter(char *name)
{
bool retval = false;
if(upSizeCounters())
{
if((last_error = PdhAddCounter(query_handle,
name,
(DWORD)&counters[count],
&counters[count].hCounter)) == ERROR_SUCCESS)
{
if(upSizeNames(name))
{
++count;
retval = true;
}
else
{
PdhRemoveCounter(counters[count].hCounter);
downSizeCounters();
}
}
else downSizeCounters();
}
return retval;
}
bool PdhQuery::updateCounters()
{
bool retval = false;
if((last_error = PdhCollectQueryData(query_handle)) == ERROR_SUCCESS) retval = true;
return retval;
}
bool PdhQuery::getWildCardCounters(const string &wildCardPath, MapCounterToValue32 &mapCounterToValue)
{
if(mapWildCardToCounters.count(wildCardPath) <= 0)
{
//cout << "getwildCardCounter(): WARNING! wild card path does not exist! " << wildCardPath << endl;
return false;
}
const vector<string> &vectorCounterValues = mapWildCardToCounters[wildCardPath];
for(vector<string>::const_iterator it = vectorCounterValues.begin(), it_end = vectorCounterValues.end(); it != it_end; ++it)
{
long val = getCounter((char*)it->c_str());
string key = getWildCardKey(*it);
mapCounterToValue.insert(pair<string, long>(key, val));
}
return true;
}
bool PdhQuery::getWildCardCounters(const string &wildCardPath, MapCounterToValue64 &mapCounterToValue)
{
if(mapWildCardToCounters.count(wildCardPath) <= 0)
{
//cout << "getwildCardCounter(): WARNING! wild card path does not exist! " << wildCardPath << endl;
return false;
}
const vector<string> &vectorCounterValues = mapWildCardToCounters[wildCardPath];
for(vector<string>::const_iterator it = vectorCounterValues.begin(), it_end = vectorCounterValues.end(); it != it_end; ++it)
{
long long val = getCounter64((char*)it->c_str());
string key = getWildCardKey(*it);
mapCounterToValue.insert(pair<string, long long>(key, val));
}
return true;
}
bool PdhQuery::getWildCardCounters(const string &wildCardPath, MapCounterToValueDouble &mapCounterToValue)
{
if(mapWildCardToCounters.count(wildCardPath) <= 0)
{
//cout << "getwildCardCounter(): WARNING! wild card path does not exist! " << wildCardPath << endl;
return false;
}
const vector<string> &vectorCounterValues = mapWildCardToCounters[wildCardPath];
for(vector<string>::const_iterator it = vectorCounterValues.begin(), it_end = vectorCounterValues.end(); it != it_end; ++it)
{
double val = getCounterDouble((char*)it->c_str());
string key = getWildCardKey(*it);
mapCounterToValue.insert(pair<string, double>(key, val));
}
return true;
}
string PdhQuery::getWildCardKey(const string &counter)
{
stringstream value;
bool foundStart = false;
for(string::const_iterator it = counter.begin(), it_end = counter.end(); it != it_end; ++it)
{
if(*it == ')') break;
if(foundStart == true)
{
value << *it;
}
if(*it == '(') foundStart = true;
}
return value.str();
}
long PdhQuery::getCounter(char *name)
{
int i =0;
long retval = -1;
if((i = lookUpIndex(name)) > -1)
{
PDH_FMT_COUNTERVALUE pdhFormattedValue;
if((last_error = PdhGetFormattedCounterValue(counters[i].hCounter,
PDH_FMT_LONG,
NULL,
&pdhFormattedValue)) == ERROR_SUCCESS)
{
retval = pdhFormattedValue.longValue;
}
}
return retval;
}
long long PdhQuery::getCounter64(char *name)
{
int i =0;
long long retval = -1;
if((i = lookUpIndex(name)) > -1)
{
PDH_FMT_COUNTERVALUE pdhFormattedValue;
if((last_error = PdhGetFormattedCounterValue(counters[i].hCounter,
PDH_FMT_LARGE,
NULL,
&pdhFormattedValue)) == ERROR_SUCCESS)
{
retval = pdhFormattedValue.largeValue;
}
}
return retval;
}
double PdhQuery::getCounterDouble(char *name)
{
int i =0;
double retval = -1;
if((i = lookUpIndex(name)) > -1)
{
PDH_FMT_COUNTERVALUE pdhFormattedValue;
if((last_error = PdhGetFormattedCounterValue(counters[i].hCounter,
PDH_FMT_DOUBLE,
NULL,
&pdhFormattedValue)) == ERROR_SUCCESS)
{
retval = pdhFormattedValue.doubleValue;
}
}
return retval;
}
char *PdhQuery::getLastErrorString()
{
switch(last_error)
{
case ERROR_SUCCESS:
strcpy_s(last_error_str,"There is no error");
break;
case PDH_INVALID_ARGUMENT:
strcpy_s(last_error_str,"Invalid argument");
break;
case PDH_MEMORY_ALLOCATION_FAILURE:
strcpy_s(last_error_str,"Memory allocation failure");
break;
case PDH_CSTATUS_BAD_COUNTERNAME:
strcpy_s(last_error_str,"The counter name path string could not be parsed "
"or interpreted");
break;
case PDH_CSTATUS_NO_COUNTER:
strcpy_s(last_error_str,"The specified counter was not found");
break;
case PDH_CSTATUS_NO_COUNTERNAME:
strcpy_s(last_error_str,"An empty counter name path string was passed in");
break;
case PDH_CSTATUS_NO_MACHINE:
strcpy_s(last_error_str,"A machine entry could not be created");
break;
case PDH_CSTATUS_NO_OBJECT:
strcpy_s(last_error_str,"The specified object could not be found");
break;
case PDH_FUNCTION_NOT_FOUND:
strcpy_s(last_error_str,"The calculation function for this counter could "
"not be determined");
break;
case PDH_INVALID_HANDLE:
strcpy_s(last_error_str,"The query handle is not valid");
break;
case PDH_NO_DATA:
strcpy_s(last_error_str,"No data for that counter");
break;
}
return last_error_str;
}
#endif // #ifndef USE_GCC
} // namespace ProcessFactorySpace