Instrumenting the VGA Driver

In the VGA driver source module ENABLE.C we allocate the data segment into which the counters will be placed, and from which the VGACTRS.DLL will read the counters.

First, add the following #include to ENABLE.C:


__________________________________________________________________
#include "winperf.h" // for Performance API structure definitions __________________________________________________________________

Now add the following global variables to ENABLE.C:


__________________________________________________________________
HMODULE ghmodDrv = (HMODULE) 0; PPERF_COUNTER_BLOCK pCounterBlock; // data structure for counter values __________________________________________________________________

Now add the following .DLL initialization routine to ENABLE.C:


__________________________________________________________________
/*************************************************************************\ * BOOL bInitProc(HMODULE hmod) * * DLL initialization procedure. Save the module handle and exit. * * This routine creates a named mapped memory section that is used * to communicate the driver's performance data to the extensible * counter DLL. This method will only work with "user" mode driver * DLL's.* Kernel or privileged drivers need to provide an IOCTL * interface that will communicate the performance data to the * extensible counter DLL. * \**************************************************************************/ BOOL bInitProc(HMODULE hmod, ULONG Reason, LPVOID Reserved) { HANDLE hMappedObject; TCHAR szMappedObjectName[] = TEXT("VGA_COUNTER_BLOCK"); if (Reason == DLL_PROCESS_ATTACH) { // // create named section for the performance data // hMappedObject = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 4096, szMappedObjectName); if (hMappedObject == NULL) { // Should put out an EventLog error message here DISPDBG((0, "VGA: Could not Create Mapped Object for Counters %x", GetLastError())); pCounterBlock = NULL; } else { // Mapped object created okay // // map the section and assign the counter block pointer // to this section of memory // pCounterBlock = (PPERF_COUNTER_BLOCK) MapViewOfFile(hMappedObject, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (pCounterBlock == NULL) { // Failed to Map View of file DISPDBG((0, "VGA: Failed to Map View of File %x", GetLastError())); } } ghmodDrv = hmod; } return(TRUE); Reserved=Reserved; } __________________________________________________________________

To the BITBLT.C module, add the following #include:


__________________________________________________________________
#include <winperf.h> // include performance API definitions __________________________________________________________________

Add the following external declaration to BITBLT.C:


__________________________________________________________________
// Global counter block for performance data extern PPERF_COUNTER_BLOCK pCounterBlock; __________________________________________________________________

In the DrvBitBlt routine in BITBLT.C, add the following declaration:


__________________________________________________________________
PDWORD pdwCounter; // Pointer to counter to increment __________________________________________________________________

Add the following code as the first thing the DrvBitBlt routine does:


__________________________________________________________________
// Increment BitBlt counter pdwCounter = (PDWORD) pCounterBlock; (*pdwCounter)++; __________________________________________________________________

To the TEXTOUT.C csource module, add the following #include:


__________________________________________________________________
#include "winperf.h" // performance API definitions __________________________________________________________________

Add the external declaration to TEXTOUT.C:


__________________________________________________________________
// definition of counter data area for performance counters extern PPERF_COUNTER_BLOCK pCounterBlock; __________________________________________________________________

Add the following as the last declaration and first code to execute in the DrvTextOut routine in TEXTOUT.C:


__________________________________________________________________
PDWORD pdwCounter; // Pointer to counter to increment // Increment TextOut counter pdwCounter = ( (PDWORD) pCounterBlock ) + 1; (*pdwCounter)++; __________________________________________________________________

That's all there is to it. The VGA driver is now instrumented for its two most important calls. These account for about 80% for display driver activity in the general case. So to heck with the other operations!