|
|
1.1 root 1: /*++ BUILD Version: 0001 // Increment this if a change has global effects
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: perfutil.c
8:
9: Abstract:
10:
11: This file implements the utility routines used to construct the
12: common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and
13: perform event logging functions.
14:
15: Created:
16:
17: Russ Blake 07/30/92
18:
19: Revision History:
20:
21: --*/
22: //
23: // include files
24: //
25: #include <windows.h>
26: #include <string.h>
27: #include <winperf.h>
28: #include "vgactrs.h" // error message definition
29: #include "perfmsg.h"
30: #include "perfutil.h"
31:
32: #define INITIAL_SIZE 1024L
33: #define EXTEND_SIZE 1024L
34:
35: //
36: // Global data definitions.
37: //
38:
39: ULONG ulInfoBufferSize = 0;
40:
41: HANDLE hEventLog = NULL; // event log handle for reporting events
42: // initialized in Open... routines
43: DWORD dwLogUsers = 0; // count of functions using event log
44:
45: DWORD MESSAGE_LEVEL = 0;
46:
47: WCHAR GLOBAL_STRING[] = L"Global";
48: WCHAR FOREIGN_STRING[] = L"Foreign";
49: WCHAR COSTLY_STRING[] = L"Costly";
50:
51: WCHAR NULL_STRING[] = L"\0"; // pointer to null string
52:
53: // test for delimiter, end of line and non-digit characters
54: // used by IsNumberInUnicodeList routine
55: //
56: #define DIGIT 1
57: #define DELIMITER 2
58: #define INVALID 3
59:
60: #define EvalThisChar(c,d) ( \
61: (c == d) ? DELIMITER : \
62: (c == 0) ? DELIMITER : \
63: (c < (WCHAR)'0') ? INVALID : \
64: (c > (WCHAR)'9') ? INVALID : \
65: DIGIT)
66:
67:
68: HANDLE
69: MonOpenEventLog (
70: )
71: /*++
72:
73: Routine Description:
74:
75: Reads the level of event logging from the registry and opens the
76: channel to the event logger for subsequent event log entries.
77:
78: Arguments:
79:
80: None
81:
82: Return Value:
83:
84: Handle to the event log for reporting events.
85: NULL if open not successful.
86:
87: --*/
88: {
89: HKEY hAppKey;
90: TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
91: TCHAR LogLevelValueName[] = "EventLogLevel";
92:
93: LONG lStatus;
94:
95: DWORD dwLogLevel;
96: DWORD dwValueType;
97: DWORD dwValueSize;
98:
99: // if global value of the logging level not initialized or is disabled,
100: // check the registry to see if it should be updated.
101:
102: if (!MESSAGE_LEVEL) {
103:
104: lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
105: LogLevelKeyName,
106: 0,
107: KEY_READ,
108: &hAppKey);
109:
110: dwValueSize = sizeof (dwLogLevel);
111:
112: if (lStatus == ERROR_SUCCESS) {
113: lStatus = RegQueryValueEx (hAppKey,
114: LogLevelValueName,
115: (LPDWORD)NULL,
116: &dwValueType,
117: (LPBYTE)&dwLogLevel,
118: &dwValueSize);
119:
120: if (lStatus == ERROR_SUCCESS) {
121: MESSAGE_LEVEL = dwLogLevel;
122: } else {
123: MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
124: }
125: RegCloseKey (hAppKey);
126: } else {
127: MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
128: }
129: }
130:
131: if (hEventLog == NULL){
132: hEventLog = RegisterEventSource (
133: (LPTSTR)NULL, // Use Local Machine
134: APP_NAME); // event log app name to find in registry
135:
136: if (hEventLog != NULL) {
137: REPORT_INFORMATION (UTIL_LOG_OPEN, LOG_DEBUG);
138: }
139: }
140:
141: if (hEventLog != NULL) {
142: dwLogUsers++; // increment count of perfctr log users
143: }
144: return (hEventLog);
145: }
146:
147:
148: VOID
149: MonCloseEventLog (
150: )
151: /*++
152:
153: Routine Description:
154:
155: Closes the handle to the event logger if this is the last caller
156:
157: Arguments:
158:
159: None
160:
161: Return Value:
162:
163: None
164:
165: --*/
166: {
167: if (hEventLog != NULL) {
168: dwLogUsers--; // decrement usage
169: if (dwLogUsers <= 0) { // and if we're the last, then close up log
170: REPORT_INFORMATION (UTIL_CLOSING_LOG, LOG_DEBUG);
171: DeregisterEventSource (hEventLog);
172: }
173: }
174: }
175:
176: DWORD
177: GetQueryType (
178: IN LPWSTR lpValue
179: )
180: /*++
181:
182: GetQueryType
183:
184: returns the type of query described in the lpValue string so that
185: the appropriate processing method may be used
186:
187: Arguments
188:
189: IN lpValue
190: string passed to PerfRegQuery Value for processing
191:
192: Return Value
193:
194: QUERY_GLOBAL
195: if lpValue == 0 (null pointer)
196: lpValue == pointer to Null string
197: lpValue == pointer to "Global" string
198:
199: QUERY_FOREIGN
200: if lpValue == pointer to "Foriegn" string
201:
202: QUERY_COSTLY
203: if lpValue == pointer to "Costly" string
204:
205: otherwise:
206:
207: QUERY_ITEMS
208:
209: --*/
210: {
211: WCHAR *pwcArgChar, *pwcTypeChar;
212: BOOL bFound;
213:
214: if (lpValue == 0) {
215: return QUERY_GLOBAL;
216: } else if (*lpValue == 0) {
217: return QUERY_GLOBAL;
218: }
219:
220: // check for "Global" request
221:
222: pwcArgChar = lpValue;
223: pwcTypeChar = GLOBAL_STRING;
224: bFound = TRUE; // assume found until contradicted
225:
226: // check to the length of the shortest string
227:
228: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
229: if (*pwcArgChar++ != *pwcTypeChar++) {
230: bFound = FALSE; // no match
231: break; // bail out now
232: }
233: }
234:
235: if (bFound) return QUERY_GLOBAL;
236:
237: // check for "Foreign" request
238:
239: pwcArgChar = lpValue;
240: pwcTypeChar = FOREIGN_STRING;
241: bFound = TRUE; // assume found until contradicted
242:
243: // check to the length of the shortest string
244:
245: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
246: if (*pwcArgChar++ != *pwcTypeChar++) {
247: bFound = FALSE; // no match
248: break; // bail out now
249: }
250: }
251:
252: if (bFound) return QUERY_FOREIGN;
253:
254: // check for "Costly" request
255:
256: pwcArgChar = lpValue;
257: pwcTypeChar = COSTLY_STRING;
258: bFound = TRUE; // assume found until contradicted
259:
260: // check to the length of the shortest string
261:
262: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
263: if (*pwcArgChar++ != *pwcTypeChar++) {
264: bFound = FALSE; // no match
265: break; // bail out now
266: }
267: }
268:
269: if (bFound) return QUERY_COSTLY;
270:
271: // if not Global and not Foreign and not Costly,
272: // then it must be an item list
273:
274: return QUERY_ITEMS;
275:
276: }
277:
278: BOOL
279: IsNumberInUnicodeList (
280: IN DWORD dwNumber,
281: IN LPWSTR lpwszUnicodeList
282: )
283: /*++
284:
285: IsNumberInUnicodeList
286:
287: Arguments:
288:
289: IN dwNumber
290: DWORD number to find in list
291:
292: IN lpwszUnicodeList
293: Null terminated, Space delimited list of decimal numbers
294:
295: Return Value:
296:
297: TRUE:
298: dwNumber was found in the list of unicode number strings
299:
300: FALSE:
301: dwNumber was not found in the list.
302:
303: --*/
304: {
305: DWORD dwThisNumber;
306: WCHAR *pwcThisChar;
307: BOOL bValidNumber;
308: BOOL bNewItem;
309: BOOL bReturnValue;
310: WCHAR wcDelimiter; // could be an argument to be more flexible
311:
312: if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
313:
314: pwcThisChar = lpwszUnicodeList;
315: dwThisNumber = 0;
316: wcDelimiter = (WCHAR)' ';
317: bValidNumber = FALSE;
318: bNewItem = TRUE;
319:
320: while (TRUE) {
321: switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
322: case DIGIT:
323: // if this is the first digit after a delimiter, then
324: // set flags to start computing the new number
325: if (bNewItem) {
326: bNewItem = FALSE;
327: bValidNumber = TRUE;
328: }
329: if (bValidNumber) {
330: dwThisNumber *= 10;
331: dwThisNumber += (*pwcThisChar - (WCHAR)'0');
332: }
333: break;
334:
335: case DELIMITER:
336: // a delimter is either the delimiter character or the
337: // end of the string ('\0') if when the delimiter has been
338: // reached a valid number was found, then compare it to the
339: // number from the argument list. if this is the end of the
340: // string and no match was found, then return.
341: //
342: if (bValidNumber) {
343: if (dwThisNumber == dwNumber) return TRUE;
344: bValidNumber = FALSE;
345: }
346: if (*pwcThisChar == 0) {
347: return FALSE;
348: } else {
349: bNewItem = TRUE;
350: dwThisNumber = 0;
351: }
352: break;
353:
354: case INVALID:
355: // if an invalid character was encountered, ignore all
356: // characters up to the next delimiter and then start fresh.
357: // the invalid number is not compared.
358: bValidNumber = FALSE;
359: break;
360:
361: default:
362: break;
363:
364: }
365: pwcThisChar++;
366: }
367:
368: } // IsNumberInUnicodeList
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.