- Nebbet-ized a couple of Zw types [tested]

- PSAPI now 10% better

svn path=/trunk/; revision=4483
This commit is contained in:
KJK::Hyperion 2003-04-03 00:06:24 +00:00
parent 4948893df6
commit 37f24851c5
8 changed files with 356 additions and 190 deletions

View file

@ -301,8 +301,18 @@ struct _SYSTEM_PERFORMANCE_INFORMATION
// SystemModuleInformation (11)
typedef
struct _SYSTEM_MODULE_ENTRY
struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
SIZE_T Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
#if 0
ULONG Unknown1;
ULONG Unknown2;
PVOID BaseAddress;
@ -312,14 +322,15 @@ struct _SYSTEM_MODULE_ENTRY
USHORT NameLength; /* Length of module name not including the path, this field contains valid value only for NTOSKRNL module*/
USHORT PathLength; /* Length of 'directory path' part of modulename*/
CHAR Name [256];
} SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY;
#endif
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
typedef
struct _SYSTEM_MODULE_INFORMATION
struct _SYSTEM_MODULES
{
ULONG Count;
SYSTEM_MODULE_ENTRY Module [1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
SIZE_T Count;
SYSTEM_MODULE_INFORMATION Modules[ANYSIZE_ARRAY];
} SYSTEM_MODULES, *PSYSTEM_MODULES;
// SystemHandleInformation (16)
// (see ontypes.h)

View file

@ -0,0 +1,224 @@
/* $Id: drivers.c,v 1.1 2003/04/03 00:06:23 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* LICENSE: See LGPL.txt in the top level directory
* PROJECT: ReactOS system libraries
* FILE: reactos/lib/psapi/enum/drivers.c
* PURPOSE: Enumerate system modules
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
* UPDATE HISTORY:
* 02/04/2003: Created
*/
#include <ddk/ntddk.h>
#include <debug.h>
#include <stddef.h>
#include "internal/psapi.h"
NTSTATUS
NTAPI
PsaEnumerateSystemModules
(
IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
register NTSTATUS nErrCode = STATUS_SUCCESS;
PSYSTEM_MODULES psmModules = NULL;
#if 0
__try
{
#endif
do
{
/* capture the system modules */
nErrCode = PsaCaptureSystemModules(&psmModules);
if(!NT_SUCCESS(nErrCode))
/* failure */
break;
/* walk the system modules */
nErrCode = PsaWalkSystemModules(psmModules, Callback, CallbackContext);
}
while(0);
#if 0
}
__finally
{
#endif
/* free the capture */
PsaFreeCapture(psmModules);
#if 0
}
#endif
/* return the last status */
return nErrCode;
}
NTSTATUS
NTAPI
PsaCaptureSystemModules
(
OUT PSYSTEM_MODULES * SystemModules
)
{
SIZE_T nSize = 0;
register NTSTATUS nErrCode;
register PSYSTEM_MODULES psmModules = (PSYSTEM_MODULES)&nSize;
#if 0
__try
{
#endif
do
{
/* initial probe. We just get the count of system modules */
nErrCode = NtQuerySystemInformation
(
SystemModuleInformation,
psmModules,
sizeof(nSize),
NULL
);
if(nErrCode != STATUS_INFO_LENGTH_MISMATCH && !NT_SUCCESS(nErrCode))
{
/* failure */
DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
break;
}
/* RATIONALE: the loading of a system module is a rare occurrence. To
minimize memory operations that could be expensive, or fragment the
pool/heap, we try to determine the buffer size in advance, knowing that
the number of elements is unlikely to change */
nSize =
sizeof(*psmModules) +
(psmModules->Count - 1) * sizeof(SYSTEM_MODULE_INFORMATION);
psmModules = NULL;
do
{
register void * pTmp;
/* free the buffer, and reallocate it to the new size. RATIONALE: since we
ignore the buffer's content at this point, there's no point in a realloc,
that could end up copying a large chunk of data we'd discard anyway */
PsaiFree(psmModules);
pTmp = PsaiMalloc(nSize);
if(pTmp == NULL)
{
/* failure */
nErrCode = STATUS_NO_MEMORY;
DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", nErrCode);
break;
}
psmModules = pTmp;
/* query the information */
nErrCode = NtQuerySystemInformation
(
SystemModuleInformation,
psmModules,
nSize,
NULL
);
/* double the buffer for the next loop */
nSize += nSize;
}
/* repeat until the buffer is big enough */
while(nErrCode == STATUS_INFO_LENGTH_MISMATCH);
if(!NT_SUCCESS(nErrCode))
{
/* failure */
DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
break;
}
/* success */
*SystemModules = psmModules;
nErrCode = STATUS_SUCCESS;
}
while(0);
#if 0
}
__finally
{
#endif
/* in case of failure, free the buffer */
if(!NT_SUCCESS(nErrCode))
PsaiFree(psmModules);
#if 0
}
#endif
/* return the last status */
return (nErrCode);
}
NTSTATUS
NTAPI
PsaWalkSystemModules
(
IN PSYSTEM_MODULES SystemModules,
IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
register NTSTATUS nErrCode;
register SIZE_T i;
/* repeat until all modules have been returned */
for(i = 0; i < SystemModules->Count; ++ i)
{
/* return current module to the callback */
nErrCode = Callback(&(SystemModules->Modules[i]), CallbackContext);
if(!NT_SUCCESS(nErrCode))
/* failure */
return nErrCode;
}
/* success */
return STATUS_SUCCESS;
}
PSYSTEM_MODULE_INFORMATION
FASTCALL
PsaWalkFirstSystemModule
(
IN PSYSTEM_MODULES SystemModules
)
{
return &(SystemModules->Modules[0]);
}
PSYSTEM_MODULE_INFORMATION
FASTCALL
PsaWalkNextSystemModule
(
IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
)
{
return (PSYSTEM_MODULE_INFORMATION)
(
(ULONG_PTR)CurrentSystemModule +
(
offsetof(SYSTEM_MODULES, Modules[1]) -
offsetof(SYSTEM_MODULES, Modules[0])
)
);
}
/* EOF */

View file

@ -1,11 +1,11 @@
/* $Id: module.c,v 1.4 2003/04/02 22:09:56 hyperion Exp $
/* $Id: module.c,v 1.5 2003/04/03 00:06:23 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* LICENSE: See LGPL.txt in the top level directory
* PROJECT: ReactOS system libraries
* FILE: reactos/lib/psapi/enum/module.c
* PURPOSE: Enumerate system and process modules
* PURPOSE: Enumerate process modules
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
* UPDATE HISTORY:
* 10/06/2002: Created
@ -13,6 +13,7 @@
* more efficient use of memory operations
* 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
* for better reusability
* 02/04/2003: System modules enumeration moved into its own file
*/
#include <ddk/ntddk.h>
@ -20,112 +21,6 @@
#include <internal/psapi.h>
#include <ntdll/ldr.h>
NTSTATUS
NTAPI
PsaEnumerateSystemModules
(
IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
ULONG nSize;
register NTSTATUS nErrCode = STATUS_SUCCESS;
register PULONG pnModuleCount = &nSize;
register PSYSTEM_MODULE_ENTRY psmeCurModule;
register ULONG nModuleCount;
/* initial probe */
nErrCode = NtQuerySystemInformation
(
SystemModuleInformation,
pnModuleCount,
sizeof(nSize),
NULL
);
if(nErrCode != STATUS_INFO_LENGTH_MISMATCH && !NT_SUCCESS(nErrCode))
{
/* failure */
DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
return nErrCode;
}
/* RATIONALE: the loading of a system module is a rare occurrence. To minimize
memory operations that could be expensive, or fragment the pool/heap, we try
to determine the buffer size in advance, knowing that the number of elements
is unlikely to change */
nSize = sizeof(ULONG) + nSize * sizeof(SYSTEM_MODULE_ENTRY);
pnModuleCount = NULL;
do
{
register void * pTmp;
/* free the buffer, and reallocate it to the new size. RATIONALE: since we
ignore the buffer's content at this point, there's no point in a realloc(),
that could end up copying a large chunk of data we'd discard anyway */
PsaiFree(pnModuleCount);
pTmp = PsaiMalloc(nSize);
if(pTmp == NULL)
{
/* failure */
nErrCode = STATUS_NO_MEMORY;
DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", nErrCode);
goto esm_Finalize;
}
pnModuleCount = pTmp;
/* query the information */
nErrCode = NtQuerySystemInformation
(
SystemModuleInformation,
pnModuleCount,
nSize,
NULL
);
/* double the buffer for the next loop */
nSize += nSize;
}
/* repeat until the buffer is big enough */
while(nErrCode == STATUS_INFO_LENGTH_MISMATCH);
if(!NT_SUCCESS(nErrCode))
{
/* failure */
DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
goto esm_Finalize;
}
/* the array of modules starts right after an ULONG storing their count */
psmeCurModule = (PSYSTEM_MODULE_ENTRY)(pnModuleCount + 1);
nModuleCount = *pnModuleCount;
/* repeat until all modules have been returned */
while(nModuleCount > 0)
{
/* return current module to the callback */
nErrCode = Callback(nModuleCount, psmeCurModule, CallbackContext);
if(!NT_SUCCESS(nErrCode))
/* failure */
goto esm_Finalize;
/* next module */
psmeCurModule ++;
nModuleCount --;
}
esm_Finalize:
/* free the buffer */
PsaiFree(pnModuleCount);
return (nErrCode);
}
NTSTATUS
NTAPI
PsaEnumerateProcessModules

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.4 2003/04/02 22:09:56 hyperion Exp $
/* $Id: process.c,v 1.5 2003/04/03 00:06:23 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
@ -31,7 +31,8 @@
#include <ddk/ntddk.h>
#include <debug.h>
#include <stddef.h>
#include <internal/psapi.h>
#include "internal/psapi.h"
NTSTATUS
NTAPI
@ -324,8 +325,6 @@ PsaWalkFirstThread
{
static SIZE_T nOffsetOfThreads = 0;
#define printoffset(__T__, __F__) fprintf(stderr, "%02X %s->%s\n", offsetof(__T__, __F__), #__T__, #__F__)
/* get the offset of the Threads field (dependant on the kernel version) */
if(!nOffsetOfThreads)
{

View file

@ -1,4 +1,4 @@
/* $Id: psapi.h,v 1.4 2003/04/02 22:09:56 hyperion Exp $
/* $Id: psapi.h,v 1.5 2003/04/03 00:06:24 hyperion Exp $
*/
/*
* internal/psapi.h
@ -46,8 +46,7 @@ typedef NTSTATUS NTAPI (*PTHREAD_ENUM_ROUTINE)
typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE)
(
IN ULONG ModuleCount,
IN PSYSTEM_MODULE_ENTRY CurrentModule,
IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
);
@ -62,6 +61,35 @@ typedef NTSTATUS NTAPI (*PPROCMOD_ENUM_ROUTINE)
#define FAILED_WITH_STATUS DEFINE_DBG_MSG("%s() failed, status 0x%08X")
/* PROTOTYPES */
/* Processes and threads */
/* enumeration */
NTSTATUS
NTAPI
PsaEnumerateProcessesAndThreads
(
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateProcesses
(
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateThreads
(
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
/* capturing & walking */
NTSTATUS
NTAPI
PsaCaptureProcessesAndThreads
@ -82,19 +110,20 @@ PsaWalkProcessesAndThreads
NTSTATUS
NTAPI
PsaEnumerateProcessesAndThreads
PsaWalkProcesses
(
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
VOID
NTSTATUS
NTAPI
PsaFreeCapture
PsaWalkThreads
(
IN PVOID Capture
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
PSYSTEM_PROCESSES
@ -125,40 +154,8 @@ PsaWalkNextThread
IN PSYSTEM_THREADS CurrentThread
);
NTSTATUS
NTAPI
PsaWalkProcesses
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
NTSTATUS
NTAPI
PsaWalkThreads
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateProcesses
(
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateThreads
(
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
/* System modules */
/* enumeration */
NTSTATUS
NTAPI
PsaEnumerateSystemModules
@ -167,6 +164,38 @@ PsaEnumerateSystemModules
IN OUT PVOID CallbackContext
);
/* capturing & walking */
NTSTATUS
NTAPI
PsaCaptureSystemModules
(
OUT PSYSTEM_MODULES * SystemModules
);
NTSTATUS
NTAPI
PsaWalkSystemModules
(
IN PSYSTEM_MODULES SystemModules,
IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
PSYSTEM_MODULE_INFORMATION
FASTCALL
PsaWalkFirstSystemModule
(
IN PSYSTEM_MODULES SystemModules
);
PSYSTEM_MODULE_INFORMATION
FASTCALL
PsaWalkNextSystemModule
(
IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
);
/* Process modules */
NTSTATUS
NTAPI
PsaEnumerateProcessModules
@ -176,6 +205,14 @@ PsaEnumerateProcessModules
IN OUT PVOID CallbackContext
);
/* Miscellaneous */
VOID
NTAPI
PsaFreeCapture
(
IN PVOID Capture
);
/* The user must define these functions. They are called by PSAPI to allocate
memory. This allows PSAPI to be called from any environment */
void *PsaiMalloc(SIZE_T size);
@ -188,4 +225,3 @@ void PsaiFree(void *ptr);
#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */
/* EOF */

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.4 2003/04/02 22:09:57 hyperion Exp $
# $Id: makefile,v 1.5 2003/04/03 00:06:24 hyperion Exp $
PATH_TO_TOP = ../..
@ -20,7 +20,8 @@ TARGET_OBJECTS = \
misc/stubs.o \
misc/win32.o \
enum/module.o \
enum/process.o
enum/process.o \
enum/drivers.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk

View file

@ -1,4 +1,4 @@
/* $Id: win32.c,v 1.6 2003/04/02 22:09:57 hyperion Exp $
/* $Id: win32.c,v 1.7 2003/04/03 00:06:24 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
@ -73,8 +73,7 @@ typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT
/* callback routine */
NTSTATUS STDCALL EnumDeviceDriversCallback
(
IN ULONG ModuleCount,
IN PSYSTEM_MODULE_ENTRY CurrentModule,
IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
)
{
@ -86,7 +85,7 @@ NTSTATUS STDCALL EnumDeviceDriversCallback
return STATUS_INFO_LENGTH_MISMATCH;
/* return current module */
*(peddcContext->lpImageBase) = CurrentModule->BaseAddress;
*(peddcContext->lpImageBase) = CurrentModule->Base;
/* go to next array slot */
(peddcContext->lpImageBase) ++;
@ -309,8 +308,7 @@ typedef struct _GET_DEVICE_DRIVER_NAME_CONTEXT
/* common callback routine */
NTSTATUS STDCALL GetDeviceDriverNameCallback
(
IN ULONG ModuleCount,
IN PSYSTEM_MODULE_ENTRY CurrentModule,
IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
)
{
@ -318,16 +316,16 @@ NTSTATUS STDCALL GetDeviceDriverNameCallback
(PGET_DEVICE_DRIVER_NAME_CONTEXT) CallbackContext;
/* module found */
if(pgddncContext->ImageBase == CurrentModule->BaseAddress)
if(pgddncContext->ImageBase == CurrentModule->Base)
{
register PCHAR pcModuleName;
register ULONG l;
/* get the full name or just the filename part */
if(pgddncContext->bFullName)
pcModuleName = &CurrentModule->Name[0];
pcModuleName = &CurrentModule->ImageName[0];
else
pcModuleName = &CurrentModule->Name[CurrentModule->PathLength];
pcModuleName = &CurrentModule->ImageName[CurrentModule->ModuleNameOffset];
/* get the length of the name */
l = strlen(pcModuleName);

View file

@ -1,4 +1,4 @@
/* $Id: loader.c,v 1.128 2003/03/31 09:30:00 gvg Exp $
/* $Id: loader.c,v 1.129 2003/04/03 00:06:24 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -18,6 +18,7 @@
* JF 26/01/2000 Recoded some parts to retrieve export details correctly
* DW 27/06/2000 Removed redundant header files
* CSH 11/04/2001 Added automatic loading of module symbols if they exist
* KJK 02/04/2003 Nebbet-ized a couple of type names
*/
@ -593,7 +594,7 @@ LdrpQueryModuleInformation(PVOID Buffer,
PLIST_ENTRY current_entry;
PMODULE_OBJECT current;
ULONG ModuleCount = 0;
PSYSTEM_MODULE_INFORMATION Smi;
PSYSTEM_MODULES Smi;
ANSI_STRING AnsiName;
PCHAR p;
KIRQL Irql;
@ -608,8 +609,8 @@ LdrpQueryModuleInformation(PVOID Buffer,
current_entry = current_entry->Flink;
}
*ReqSize = sizeof(SYSTEM_MODULE_INFORMATION)+
(ModuleCount - 1) * sizeof(SYSTEM_MODULE_ENTRY);
*ReqSize = sizeof(SYSTEM_MODULES)+
(ModuleCount - 1) * sizeof(SYSTEM_MODULE_INFORMATION);
if (Size < *ReqSize)
{
@ -620,7 +621,7 @@ LdrpQueryModuleInformation(PVOID Buffer,
/* fill the buffer */
memset(Buffer, '=', Size);
Smi = (PSYSTEM_MODULE_INFORMATION)Buffer;
Smi = (PSYSTEM_MODULES)Buffer;
Smi->Count = ModuleCount;
ModuleCount = 0;
@ -629,15 +630,18 @@ LdrpQueryModuleInformation(PVOID Buffer,
{
current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
Smi->Module[ModuleCount].Unknown2 = 0; /* Always 0 */
Smi->Module[ModuleCount].BaseAddress = current->Base;
Smi->Module[ModuleCount].Size = current->Length;
Smi->Module[ModuleCount].Flags = 0; /* Flags ??? (GN) */
Smi->Module[ModuleCount].EntryIndex = ModuleCount;
Smi->Modules[ModuleCount].Reserved[0] = 0; /* Always 0 */
Smi->Modules[ModuleCount].Reserved[1] = 0; /* Always 0 */
Smi->Modules[ModuleCount].Base = current->Base;
Smi->Modules[ModuleCount].Size = current->Length;
Smi->Modules[ModuleCount].Flags = 0; /* Flags ??? (GN) */
Smi->Modules[ModuleCount].Index = ModuleCount;
Smi->Modules[ModuleCount].Unknown = 0;
Smi->Modules[ModuleCount].LoadCount = 0; /* FIXME */
AnsiName.Length = 0;
AnsiName.MaximumLength = 256;
AnsiName.Buffer = Smi->Module[ModuleCount].Name;
AnsiName.Buffer = Smi->Modules[ModuleCount].ImageName;
RtlUnicodeStringToAnsiString(&AnsiName,
&current->FullName,
FALSE);
@ -645,14 +649,12 @@ LdrpQueryModuleInformation(PVOID Buffer,
p = strrchr(AnsiName.Buffer, '\\');
if (p == NULL)
{
Smi->Module[ModuleCount].PathLength = 0;
Smi->Module[ModuleCount].NameLength = strlen(AnsiName.Buffer);
Smi->Modules[ModuleCount].ModuleNameOffset = 0;
}
else
{
p++;
Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer;
Smi->Module[ModuleCount].NameLength = strlen(p);
Smi->Modules[ModuleCount].ModuleNameOffset = p - AnsiName.Buffer;
}
ModuleCount++;