|
|
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.