Listing 2: getstats.c Implementation of object statistics functions
// getstats.c -- wrappers for win32k.sys services #define WIN32_LEAN_AND_MEAN #include <windows.h> #include "getstats.h" #define STATUS_INVALID_PARAMETER (0xC000000DL) static int gUserServiceNumber; static int gGdiServiceNumber; void _NtUserGetStats(DWORD pid, DWORD flags, void *objCount, int maxEntries); void _NtGdiGetStats(DWORD pid, DWORD reserved, DWORD flags, void *objCount, int sizeInBytes); BOOL UserGetStats(DWORD pid, DWORD flags, DWORD objCount[], int maxEntries) { HMODULE hModule; BYTE *address; DWORD ntStatus; int number; // // Find the service number for kernel-mode NtUserGetStats() // by adding 1 to service number for GetProcessWindowStation(). // if (gUserServiceNumber == 0) { gUserServiceNumber = -1; hModule = GetModuleHandle("USER32"); if (IsNT4() && hModule != NULL) { address = (BYTE *) GetProcAddress(hModule, \ "GetProcessWindowStation"); if (address != NULL) { address += 1; /* skip 'mov' opcode */ number = *((DWORD *) address) + 1; if (number >= 0x1000 && number < 0x1500) gUserServiceNumber = number; } } } ntStatus = 0; if (gUserServiceNumber > 0) { memset(objCount, 0, sizeof(DWORD) * maxEntries); _NtUserGetStats(pid, flags, objCount, maxEntries); __asm mov ntStatus, eax } else ntStatus = STATUS_INVALID_PARAMETER; return((ntStatus == 0) ? TRUE : FALSE); } void __declspec(naked) _NtUserGetStats(DWORD pid, DWORD flags, void *objCount, int maxEntries) { __asm mov eax, gUserServiceNumber __asm lea edx, [esp+4] __asm int 0x2e __asm ret } BOOL GdiGetStats(DWORD pid, DWORD flags, DWORD objCount[], int maxEntries) { HMODULE hModule; BYTE *address; DWORD ntStatus; int number; // // Find the service number for kernel-mode NtGdiGetStats() // by adding 1 to service number for GdiGetSpoolMessage(). // if (gGdiServiceNumber == 0) { gGdiServiceNumber = -1; hModule = GetModuleHandle("GDI32"); if (IsNT4() && hModule != NULL) { address = (BYTE *) GetProcAddress(hModule, \ "GdiGetSpoolMessage"); if (address != NULL) { address += 1; /* skip 'mov' opcode */ number = *((DWORD *) address) + 1; if (number >= 0x1000 && number < 0x1500) gGdiServiceNumber = number; } } } ntStatus = 0; if (gGdiServiceNumber > 0) { memset(objCount, 0, sizeof(DWORD) * maxEntries); _NtGdiGetStats(pid, 0L, flags, objCount, \ sizeof(DWORD) * maxEntries); __asm mov ntStatus, eax } else ntStatus = STATUS_INVALID_PARAMETER; return((ntStatus == 0) ? TRUE : FALSE); } void __declspec(naked) _NtGdiGetStats(DWORD pid, DWORD reserved, DWORD flags, void *objCount, int sizeInBytes) { __asm mov eax, gGdiServiceNumber __asm lea edx, [esp+4] __asm int 0x2e __asm ret } BOOL IsNT4(void) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); if (GetVersionEx(&osvi)) { if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) if (osvi.dwMajorVersion == 4) return(TRUE); } return(FALSE); } //End of File