From 2ec823a6b0e0a481c0983742dec3ee1ae0718c64 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 6 Nov 2004 11:45:47 +0000 Subject: [PATCH] 1. implemented GetPerformanceInfo() 2. fixed definition of SYSTEM_HANDLE_INFORMATION and SYSTEM_HANDLE_TABLE_ENTRY_INFO svn path=/trunk/; revision=11553 --- reactos/include/ntos/zwtypes.h | 30 ++-- reactos/lib/psapi/misc/stubs.c | 16 +-- reactos/lib/psapi/misc/win32.c | 213 +++++++++++++++++++++++------ reactos/w32api/include/ddk/ntapi.h | 19 ++- 4 files changed, 194 insertions(+), 84 deletions(-) diff --git a/reactos/include/ntos/zwtypes.h b/reactos/include/ntos/zwtypes.h index 17d06d28c82..2bb5d6d04cd 100755 --- a/reactos/include/ntos/zwtypes.h +++ b/reactos/include/ntos/zwtypes.h @@ -407,32 +407,24 @@ typedef struct _SYSTEM_MODULE_INFORMATION { // SystemHandleInformation (16) // (see ontypes.h) typedef -struct _SYSTEM_HANDLE_ENTRY +struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { - ULONG OwnerPid; - BYTE ObjectType; - BYTE HandleFlags; + USHORT UniqueProcessId; + USHORT CreatorBackTraceIndex; + UCHAR ObjectTypeIndex; + UCHAR HandleAttributes; USHORT HandleValue; - PVOID ObjectPointer; - ULONG AccessMask; + PVOID Object; + ULONG GrantedAccess; -} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; typedef -struct _SYSTEM_HANDLE_INFORMATION_NT4 +struct _SYSTEM_HANDLE_INFORMATION { - ULONG Count; - SYSTEM_HANDLE_ENTRY Handle [1]; + ULONG NumberOfHandles; + SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; -} SYSTEM_HANDLE_INFORMATION_NT4, *PSYSTEM_HANDLE_INFORMATION_NT4; - -typedef struct _SYSTEM_HANDLE_INFORMATION { - ULONG ProcessId; - UCHAR ObjectTypeNumber; - UCHAR Flags; - USHORT Handle; - PVOID Object; - ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; // SystemObjectInformation (17) diff --git a/reactos/lib/psapi/misc/stubs.c b/reactos/lib/psapi/misc/stubs.c index 02cf8261a71..c6eed52ecfe 100644 --- a/reactos/lib/psapi/misc/stubs.c +++ b/reactos/lib/psapi/misc/stubs.c @@ -1,24 +1,10 @@ -/* $Id: stubs.c,v 1.10 2004/11/06 01:42:04 weiden Exp $ */ +/* $Id: stubs.c,v 1.11 2004/11/06 11:45:47 weiden Exp $ */ #include "precomp.h" #define NDEBUG #include -/* - * @unimplemented - */ -BOOL -STDCALL -GetPerformanceInfo(PPERFORMANCE_INFORMATION pPerformanceInformation, - DWORD cb) -{ - DPRINT1("PSAPI: GetPerformanceInfo is UNIMPLEMENTED!\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - /* * @unimplemented */ diff --git a/reactos/lib/psapi/misc/win32.c b/reactos/lib/psapi/misc/win32.c index 9b27ad7a0f4..e7a5d26f6e3 100644 --- a/reactos/lib/psapi/misc/win32.c +++ b/reactos/lib/psapi/misc/win32.c @@ -1,4 +1,4 @@ -/* $Id: win32.c,v 1.15 2004/11/06 01:43:59 weiden Exp $ +/* $Id: win32.c,v 1.16 2004/11/06 11:45:47 weiden Exp $ */ /* * COPYRIGHT: See COPYING in the top level directory @@ -7,6 +7,7 @@ * FILE: reactos/lib/psapi/misc/win32.c * PURPOSE: Win32 interfaces for PSAPI * PROGRAMMER: KJK::Hyperion + * Thomas Weidenmueller * UPDATE HISTORY: * 10/06/2002: Created */ @@ -562,6 +563,49 @@ InternalGetModuleInformation(HANDLE hProcess, return 0; } + +typedef struct _INTERNAL_ENUM_PAGE_FILES_CONTEXT +{ + PENUM_PAGE_FILE_CALLBACKA pCallbackRoutine; + LPVOID lpContext; +} INTERNAL_ENUM_PAGE_FILES_CONTEXT, *PINTERNAL_ENUM_PAGE_FILES_CONTEXT; + + +static BOOL +InternalAnsiPageFileCallback(LPVOID pContext, + PENUM_PAGE_FILE_INFORMATION pPageFileInfo, + LPCWSTR lpFilename) +{ + size_t slen; + LPSTR AnsiFileName; + PINTERNAL_ENUM_PAGE_FILES_CONTEXT Context = (PINTERNAL_ENUM_PAGE_FILES_CONTEXT)pContext; + + slen = wcslen(lpFilename); + + AnsiFileName = (LPSTR)LocalAlloc(LMEM_FIXED, (slen + 1) * sizeof(CHAR)); + if(AnsiFileName != NULL) + { + BOOL Ret; + + WideCharToMultiByte(CP_ACP, + 0, + lpFilename, + -1, /* only works if the string is NULL-terminated!!! */ + AnsiFileName, + (slen + 1) * sizeof(CHAR), + NULL, + NULL); + + Ret = Context->pCallbackRoutine(Context->lpContext, pPageFileInfo, AnsiFileName); + + LocalFree((HLOCAL)AnsiFileName); + + return Ret; + } + + return FALSE; +} + /* PUBLIC *********************************************************************/ /* @@ -1030,49 +1074,6 @@ GetProcessImageFileNameA(HANDLE hProcess, } -typedef struct _INTERNAL_ENUM_PAGE_FILES_CONTEXT -{ - PENUM_PAGE_FILE_CALLBACKA pCallbackRoutine; - LPVOID lpContext; -} INTERNAL_ENUM_PAGE_FILES_CONTEXT, *PINTERNAL_ENUM_PAGE_FILES_CONTEXT; - - -static BOOL -InternalAnsiPageFileCallback(LPVOID pContext, - PENUM_PAGE_FILE_INFORMATION pPageFileInfo, - LPCWSTR lpFilename) -{ - size_t slen; - LPSTR AnsiFileName; - PINTERNAL_ENUM_PAGE_FILES_CONTEXT Context = (PINTERNAL_ENUM_PAGE_FILES_CONTEXT)pContext; - - slen = wcslen(lpFilename); - - AnsiFileName = (LPSTR)LocalAlloc(LMEM_FIXED, (slen + 1) * sizeof(CHAR)); - if(AnsiFileName != NULL) - { - BOOL Ret; - - WideCharToMultiByte(CP_ACP, - 0, - lpFilename, - -1, /* only works if the string is NULL-terminated!!! */ - AnsiFileName, - (slen + 1) * sizeof(CHAR), - NULL, - NULL); - - Ret = Context->pCallbackRoutine(Context->lpContext, pPageFileInfo, AnsiFileName); - - LocalFree((HLOCAL)AnsiFileName); - - return Ret; - } - - return FALSE; -} - - /* * @implemented */ @@ -1177,4 +1178,128 @@ EnumPageFilesW(PENUM_PAGE_FILE_CALLBACKW pCallbackRoutine, return Ret; } + +/* + * @implemented + */ +BOOL +STDCALL +GetPerformanceInfo(PPERFORMANCE_INFORMATION pPerformanceInformation, + DWORD cb) +{ + SYSTEM_PERFORMANCE_INFORMATION spi; + SYSTEM_BASIC_INFORMATION sbi; + SYSTEM_HANDLE_INFORMATION shi; + PSYSTEM_PROCESS_INFORMATION ProcessInfo; + ULONG BufferSize, ProcOffset, ProcessCount, ThreadCount; + PVOID Buffer; + NTSTATUS Status; + + Status = NtQuerySystemInformation(SystemPerformanceInformation, + &spi, + sizeof(spi), + NULL); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + Status = NtQuerySystemInformation(SystemBasicInformation, + &sbi, + sizeof(sbi), + NULL); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + /* + * allocate enough memory to get a dump of all processes and threads + */ + BufferSize = 0; + for(;;) + { + BufferSize += 0x10000; + Buffer = (PVOID)LocalAlloc(LMEM_FIXED, BufferSize); + if(Buffer == NULL) + { + return FALSE; + } + + Status = NtQuerySystemInformation(SystemProcessInformation, + Buffer, + BufferSize, + NULL); + if(Status == STATUS_INFO_LENGTH_MISMATCH) + { + LocalFree((HLOCAL)Buffer); + } + else + { + break; + } + } + + if(!NT_SUCCESS(Status)) + { + LocalFree((HLOCAL)Buffer); + SetLastErrorByStatus(Status); + return FALSE; + } + + /* + * determine the process and thread count + */ + ProcessCount = ThreadCount = ProcOffset = 0; + ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)Buffer; + do + { + ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); + ProcessCount++; + ThreadCount += ProcessInfo->NumberOfThreads; + + ProcOffset = ProcessInfo->NextEntryOffset; + } while(ProcOffset != 0); + + LocalFree((HLOCAL)Buffer); + + /* + * it's enough to supply a SYSTEM_HANDLE_INFORMATION structure as buffer. Even + * though it returns STATUS_INFO_LENGTH_MISMATCH, it already sets the NumberOfHandles + * field which is all we're looking for anyway. + */ + Status = NtQuerySystemInformation(SystemHandleInformation, + &shi, + sizeof(shi), + NULL); + if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + /* + * all required information collected, fill the structure + */ + + pPerformanceInformation->cb = sizeof(PERFORMANCE_INFORMATION); + pPerformanceInformation->CommitTotal = spi.TotalCommittedPages; + pPerformanceInformation->CommitLimit = spi.TotalCommitLimit; + pPerformanceInformation->CommitPeak = spi.PeakCommitment; + pPerformanceInformation->PhysicalTotal = sbi.NumberOfPhysicalPages; + pPerformanceInformation->PhysicalAvailable = spi.AvailablePages; + pPerformanceInformation->SystemCache = 0; /* FIXME - where to get this information from? */ + pPerformanceInformation->KernelTotal = spi.PagedPoolUsage + spi.NonPagedPoolUsage; + pPerformanceInformation->KernelPaged = spi.PagedPoolUsage; + pPerformanceInformation->KernelNonpaged = spi.NonPagedPoolUsage; + pPerformanceInformation->PageSize = sbi.PhysicalPageSize; + pPerformanceInformation->HandleCount = shi.NumberOfHandles; + pPerformanceInformation->ProcessCount = ProcessCount; + pPerformanceInformation->ThreadCount = ThreadCount; + + return TRUE; +} + /* EOF */ diff --git a/reactos/w32api/include/ddk/ntapi.h b/reactos/w32api/include/ddk/ntapi.h index a9934672ede..5cd6be1b06f 100644 --- a/reactos/w32api/include/ddk/ntapi.h +++ b/reactos/w32api/include/ddk/ntapi.h @@ -398,13 +398,20 @@ typedef struct _SYSTEM_LOCK_INFORMATION { #define PROTECT_FROM_CLOSE 0x01 #define INHERIT 0x02 -typedef struct _SYSTEM_HANDLE_INFORMATION { - ULONG ProcessId; - UCHAR ObjectTypeNumber; - UCHAR Flags; - USHORT Handle; +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { + USHORT UniqueProcessId; + USHORT CreatorBackTraceIndex; + UCHAR ObjectTypeIndex; + UCHAR HandleAttributes; + USHORT HandleValue; PVOID Object; - ACCESS_MASK GrantedAccess; + ULONG GrantedAccess; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; + +typedef struct _SYSTEM_HANDLE_INFORMATION { + ULONG NumberOfHandles; + SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; + } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; typedef struct _SYSTEM_OBJECT_TYPE_INFORMATION {