|
|
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: perfvga.c
8:
9: Abstract:
10:
11: This file implements the Extensible Objects for the Vga object type
12:
13: Created:
14:
15: Russ Blake 24 Feb 93
16:
17: Revision History
18:
19:
20: --*/
21:
22: //
23: // Include Files
24: //
25:
26: #include <windows.h>
27: #include <string.h>
28: #include <winperf.h>
29: #include "vgactrs.h" // error message definition
30: #include "perfmsg.h"
31: #include "perfutil.h"
32: #include "datavga.h"
33:
34: //
35: // References to constants which initialize the Object type definitions
36: //
37:
38: extern VGA_DATA_DEFINITION VgaDataDefinition;
39:
40: DWORD dwOpenCount = 0; // count of "Open" threads
41: BOOL bInitOK = FALSE; // true = DLL initialized OK
42:
43: //
44: // Vga data structures
45: //
46:
47: HANDLE hVgaSharedMemory; // Handle of Vga Shared Memory
48: PPERF_COUNTER_BLOCK pCounterBlock;
49:
50: //
51: // Function Prototypes
52: //
53: // these are used to insure that the data collection functions
54: // accessed by Perflib will have the correct calling format.
55: //
56:
57: DWORD APIENTRY OpenVgaPerformanceData(LPWSTR);
58: DWORD APIENTRY CollectVgaPerformanceData(LPWSTR, LPVOID *, LPDWORD, LPDWORD);
59: DWORD APIENTRY CloseVgaPerformanceData(void);
60:
61:
62: DWORD APIENTRY
63: OpenVgaPerformanceData(
64: LPWSTR lpDeviceNames
65: )
66:
67: /*++
68:
69: Routine Description:
70:
71: This routine will open and map the memory used by the VGA driver to
72: pass performance data in. This routine also initializes the data
73: structures used to pass data back to the registry
74:
75: Arguments:
76:
77: Pointer to object ID of each device to be opened (VGA)
78:
79:
80: Return Value:
81:
82: None.
83:
84: --*/
85:
86: {
87: LONG status;
88: TCHAR szMappedObject[] = TEXT("VGA_COUNTER_BLOCK");
89: HKEY hKeyDriverPerf;
90: DWORD size;
91: DWORD type;
92: DWORD dwFirstCounter;
93: DWORD dwFirstHelp;
94:
95: //
96: // Since SCREG is multi-threaded and will call this routine in
97: // order to service remote performance queries, this library
98: // must keep track of how many times it has been opened (i.e.
99: // how many threads have accessed it). the registry routines will
100: // limit access to the initialization routine to only one thread
101: // at a time so synchronization (i.e. reentrancy) should not be
102: // a problem
103: //
104:
105: if (!dwOpenCount) {
106: // open Eventlog interface
107:
108: hEventLog = MonOpenEventLog();
109:
110: // open shared memory used by device driver to pass performance values
111:
112: hVgaSharedMemory = OpenFileMapping(FILE_MAP_READ,
113: FALSE,
114: szMappedObject);
115: pCounterBlock = NULL; // initialize pointer to memory
116:
117: // log error if unsuccessful
118:
119: if (hVgaSharedMemory == NULL) {
120: REPORT_ERROR (VGAPERF_OPEN_FILE_MAPPING_ERROR, LOG_USER);
121: // this is fatal, if we can't get data then there's no
122: // point in continuing.
123: status = GetLastError(); // return error
124: goto OpenExitPoint;
125: } else {
126: // if opened ok, then map pointer to memory
127: pCounterBlock = (PPERF_COUNTER_BLOCK)
128: MapViewOfFile(hVgaSharedMemory,
129: FILE_MAP_READ,
130: 0,
131: 0,
132: 0);
133: if (pCounterBlock == NULL) {
134: REPORT_ERROR (VGAPERF_UNABLE_MAP_VIEW_OF_FILE, LOG_USER);
135: // this is fatal, if we can't get data then there's no
136: // point in continuing.
137: status = GetLastError(); // return error
138: }
139: }
140:
141: // get counter and help index base values from registry
142: // Open key to registry entry
143: // read First Counter and First Help values
144: // update static data strucutures by adding base to
145: // offset value in structure.
146:
147: status = RegOpenKeyEx (
148: HKEY_LOCAL_MACHINE,
149: "SYSTEM\\CurrentControlSet\\Services\\Vga\\Performance",
150: 0L,
151: KEY_ALL_ACCESS,
152: &hKeyDriverPerf);
153:
154: if (status != ERROR_SUCCESS) {
155: REPORT_ERROR_DATA (VGAPERF_UNABLE_OPEN_DRIVER_KEY, LOG_USER,
156: &status, sizeof(status));
157: // this is fatal, if we can't get the base values of the
158: // counter or help names, then the names won't be available
159: // to the requesting application so there's not much
160: // point in continuing.
161: goto OpenExitPoint;
162: }
163:
164: size = sizeof (DWORD);
165: status = RegQueryValueEx(
166: hKeyDriverPerf,
167: "First Counter",
168: 0L,
169: &type,
170: (LPBYTE)&dwFirstCounter,
171: &size);
172:
173: if (status != ERROR_SUCCESS) {
174: REPORT_ERROR_DATA (VGAPERF_UNABLE_READ_FIRST_COUNTER, LOG_USER,
175: &status, sizeof(status));
176: // this is fatal, if we can't get the base values of the
177: // counter or help names, then the names won't be available
178: // to the requesting application so there's not much
179: // point in continuing.
180: goto OpenExitPoint;
181: }
182:
183: size = sizeof (DWORD);
184: status = RegQueryValueEx(
185: hKeyDriverPerf,
186: "First Help",
187: 0L,
188: &type,
189: (LPBYTE)&dwFirstHelp,
190: &size);
191:
192: if (status != ERROR_SUCCESS) {
193: REPORT_ERROR_DATA (VGAPERF_UNABLE_READ_FIRST_HELP, LOG_USER,
194: &status, sizeof(status));
195: // this is fatal, if we can't get the base values of the
196: // counter or help names, then the names won't be available
197: // to the requesting application so there's not much
198: // point in continuing.
199: goto OpenExitPoint;
200: }
201:
202: //
203: // NOTE: the initialization program could also retrieve
204: // LastCounter and LastHelp if they wanted to do
205: // bounds checking on the new number. e.g.
206: //
207: // counter->CounterNameTitleIndex += dwFirstCounter;
208: // if (counter->CounterNameTitleIndex > dwLastCounter) {
209: // LogErrorToEventLog (INDEX_OUT_OF_BOUNDS);
210: // }
211:
212: VgaDataDefinition.VgaObjectType.ObjectNameTitleIndex += dwFirstCounter;
213: VgaDataDefinition.VgaObjectType.ObjectHelpTitleIndex += dwFirstHelp;
214:
215: VgaDataDefinition.NumBitBlts.CounterNameTitleIndex += dwFirstCounter;
216: VgaDataDefinition.NumBitBlts.CounterHelpTitleIndex += dwFirstHelp;
217:
218: VgaDataDefinition.NumTextOuts.CounterNameTitleIndex += dwFirstCounter;
219: VgaDataDefinition.NumTextOuts.CounterHelpTitleIndex += dwFirstHelp;
220:
221: RegCloseKey (hKeyDriverPerf); // close key to registry
222:
223: bInitOK = TRUE; // ok to use this function
224: }
225:
226: dwOpenCount++; // increment OPEN counter
227:
228: status = ERROR_SUCCESS; // for successful exit
229:
230: OpenExitPoint:
231:
232: return status;
233: }
234:
235:
236: DWORD APIENTRY
237: CollectVgaPerformanceData(
238: IN LPWSTR lpValueName,
239: IN OUT LPVOID *lppData,
240: IN OUT LPDWORD lpcbTotalBytes,
241: IN OUT LPDWORD lpNumObjectTypes
242: )
243: /*++
244:
245: Routine Description:
246:
247: This routine will return the data for the VGA counters.
248:
249: Arguments:
250:
251: IN LPWSTR lpValueName
252: pointer to a wide character string passed by registry.
253:
254: IN OUT LPVOID *lppData
255: IN: pointer to the address of the buffer to receive the completed
256: PerfDataBlock and subordinate structures. This routine will
257: append its data to the buffer starting at the point referenced
258: by *lppData.
259: OUT: points to the first byte after the data structure added by this
260: routine. This routine updated the value at lppdata after appending
261: its data.
262:
263: IN OUT LPDWORD lpcbTotalBytes
264: IN: the address of the DWORD that tells the size in bytes of the
265: buffer referenced by the lppData argument
266: OUT: the number of bytes added by this routine is writted to the
267: DWORD pointed to by this argument
268:
269: IN OUT LPDWORD NumObjectTypes
270: IN: the address of the DWORD to receive the number of objects added
271: by this routine
272: OUT: the number of objects added by this routine is writted to the
273: DWORD pointed to by this argument
274:
275: Return Value:
276:
277: ERROR_MORE_DATA if buffer passed is too small to hold data
278: any error conditions encountered are reported to the event log if
279: event logging is enabled.
280:
281: ERROR_SUCCESS if success or any other error. Errors, however are
282: also reported to the event log.
283:
284: --*/
285: {
286: // Variables for reformating the data
287:
288: ULONG SpaceNeeded;
289: PDWORD pdwCounter;
290: PERF_COUNTER_BLOCK *pPerfCounterBlock;
291: VGA_DATA_DEFINITION *pVgaDataDefinition;
292: DWORD dwQueryType;
293:
294: //
295: // before doing anything else, see if Open went OK
296: //
297: if (!bInitOK) {
298: // unable to continue because open failed.
299: *lpcbTotalBytes = (DWORD) 0;
300: *lpNumObjectTypes = (DWORD) 0;
301: return ERROR_SUCCESS; // yes, this is a successful exit
302: }
303:
304: // see if this is a foreign (i.e. non-NT) computer data request
305: //
306: dwQueryType = GetQueryType (lpValueName);
307:
308: if (dwQueryType == QUERY_FOREIGN) {
309: // this routine does not service requests for data from
310: // Non-NT computers
311: *lpcbTotalBytes = (DWORD) 0;
312: *lpNumObjectTypes = (DWORD) 0;
313: return ERROR_SUCCESS;
314: }
315:
316: if (dwQueryType == QUERY_ITEMS){
317: if ( !(IsNumberInUnicodeList (VgaDataDefinition.VgaObjectType.ObjectNameTitleIndex, lpValueName))) {
318:
319: // request received for data object not provided by this routine
320: *lpcbTotalBytes = (DWORD) 0;
321: *lpNumObjectTypes = (DWORD) 0;
322: return ERROR_SUCCESS;
323: }
324: }
325:
326: pVgaDataDefinition = (VGA_DATA_DEFINITION *) *lppData;
327:
328: SpaceNeeded = sizeof(VGA_DATA_DEFINITION) +
329: SIZE_OF_VGA_PERFORMANCE_DATA;
330:
331: if ( *lpcbTotalBytes < SpaceNeeded ) {
332: *lpcbTotalBytes = (DWORD) 0;
333: *lpNumObjectTypes = (DWORD) 0;
334: return ERROR_MORE_DATA;
335: }
336:
337: //
338: // Copy the (constant, initialized) Object Type and counter definitions
339: // to the caller's data buffer
340: //
341:
342: memmove(pVgaDataDefinition,
343: &VgaDataDefinition,
344: sizeof(VGA_DATA_DEFINITION));
345:
346: //
347: // Format and collect VGA data from shared memory
348: //
349:
350: pPerfCounterBlock = (PERF_COUNTER_BLOCK *) &pVgaDataDefinition[1];
351:
352: pPerfCounterBlock->ByteLength = SIZE_OF_VGA_PERFORMANCE_DATA;
353:
354: pdwCounter = (PDWORD) (&pPerfCounterBlock[1]);
355:
356: *pdwCounter = *((PDWORD) pCounterBlock);
357: *++pdwCounter = ((PDWORD) pCounterBlock)[1];
358:
359: *lppData = (PVOID) ++pdwCounter;
360:
361: // update arguments fore return
362:
363: *lpNumObjectTypes = 1;
364:
365: *lpcbTotalBytes = (PBYTE) pdwCounter - (PBYTE) pVgaDataDefinition;
366:
367: return ERROR_SUCCESS;
368: }
369:
370:
371: DWORD APIENTRY
372: CloseVgaPerformanceData(
373: )
374:
375: /*++
376:
377: Routine Description:
378:
379: This routine closes the open handles to VGA device performance counters
380:
381: Arguments:
382:
383: None.
384:
385:
386: Return Value:
387:
388: ERROR_SUCCESS
389:
390: --*/
391:
392: {
393: if (!(--dwOpenCount)) { // when this is the last thread...
394:
395: CloseHandle(hVgaSharedMemory);
396:
397: pCounterBlock = NULL;
398:
399: MonCloseEventLog();
400: }
401:
402: return ERROR_SUCCESS;
403:
404: }
405:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.