Long due update to PSAPI

svn path=/trunk/; revision=4478
This commit is contained in:
KJK::Hyperion 2003-04-02 22:09:57 +00:00
parent 01da24f40c
commit a812f4e0b2
6 changed files with 440 additions and 66 deletions

View file

@ -1,4 +1,4 @@
/* $Id: module.c,v 1.3 2002/08/31 15:36:55 hyperion Exp $
/* $Id: module.c,v 1.4 2003/04/02 22:09:56 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
@ -11,6 +11,8 @@
* 10/06/2002: Created
* 29/08/2002: Generalized the interface to improve reusability,
* more efficient use of memory operations
* 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
* for better reusability
*/
#include <ddk/ntddk.h>
@ -19,7 +21,7 @@
#include <ntdll/ldr.h>
NTSTATUS
STDCALL
NTAPI
PsaEnumerateSystemModules
(
IN PSYSMOD_ENUM_ROUTINE Callback,
@ -62,13 +64,14 @@ PsaEnumerateSystemModules
/* 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 */
free(pnModuleCount);
pTmp = malloc(nSize);
PsaiFree(pnModuleCount);
pTmp = PsaiMalloc(nSize);
if(pTmp == NULL)
{
/* failure */
nErrCode = STATUS_NO_MEMORY;
DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", nErrCode);
goto esm_Finalize;
}
@ -118,13 +121,13 @@ PsaEnumerateSystemModules
esm_Finalize:
/* free the buffer */
free(pnModuleCount);
PsaiFree(pnModuleCount);
return (nErrCode);
}
NTSTATUS
STDCALL
NTAPI
PsaEnumerateProcessModules
(
IN HANDLE ProcessHandle,

View file

@ -1,35 +1,52 @@
/* $Id: process.c,v 1.3 2002/08/31 15:36:55 hyperion Exp $
/* $Id: process.c,v 1.4 2003/04/02 22:09:56 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/process.c
* PURPOSE: Enumerate processes
* PURPOSE: Enumerate processes and threads
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
* UPDATE HISTORY:
* 10/06/2002: Created
* 29/08/2002: Generalized the interface to improve reusability,
* more efficient use of memory operations
* 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
* for better reusability. PsaEnumerateProcesses now
* expanded into:
* - PsaCaptureProcessesAndThreads
* - PsaFreeCapture
* - PsaWalkProcessesAndThreads
* - PsaWalkProcesses
* - PsaWalkThreads
* - PsaWalkFirstProcess
* - PsaWalkNextProcess
* - PsaWalkFirstThread
* - PsaWalkNextThread
* - PsaEnumerateProcessesAndThreads
* - PsaEnumerateProcesses
* - PsaEnumerateThreads
*/
#include <stdlib.h>
#include <ddk/ntddk.h>
#include <debug.h>
#include <stddef.h>
#include <internal/psapi.h>
NTSTATUS
STDCALL
PsaEnumerateProcesses
NTAPI
PsaCaptureProcessesAndThreads
(
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
OUT PSYSTEM_PROCESSES * ProcessesAndThreads
)
{
register NTSTATUS nErrCode = STATUS_SUCCESS;
PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
PSYSTEM_PROCESS_INFORMATION pInfoHead = NULL;
ULONG nSize = 32768;
NTSTATUS nErrCode = STATUS_SUCCESS;
PSYSTEM_PROCESSES pInfoBuffer = NULL;
SIZE_T nSize = 32768;
/* parameter validation */
if(!ProcessesAndThreads)
return STATUS_INVALID_PARAMETER_1;
/* FIXME: if the system has loaded several processes and threads, the buffer
could get really big. But if there's several processes and threads, the
@ -39,19 +56,19 @@ PsaEnumerateProcesses
do
{
void * pTmp;
/* free the buffer, and reallocate it to the new size. RATIONALE: since we
ignore the buffer's contents at this point, there's no point in a realloc()
that could end up copying a large chunk of data we'd discard anyway */
free(pInfoBuffer);
pTmp = malloc(nSize);
PsaiFree(pInfoBuffer);
pTmp = PsaiMalloc(nSize);
if(pTmp == NULL)
{
/* failure */
DPRINT(FAILED_WITH_STATUS, "malloc", STATUS_NO_MEMORY);
DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", STATUS_NO_MEMORY);
nErrCode = STATUS_NO_MEMORY;
goto esp_Finalize;
break;
}
pInfoBuffer = pTmp;
@ -75,36 +92,281 @@ PsaEnumerateProcesses
if(!NT_SUCCESS(nErrCode))
{
DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
goto esp_Finalize;
return nErrCode;
}
/* list head */
pInfoHead = pInfoBuffer;
/* scan the list */
while(1)
/* success */
*ProcessesAndThreads = pInfoBuffer;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
PsaWalkProcessesAndThreads
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
)
{
register NTSTATUS nErrCode = STATUS_SUCCESS;
/* parameter validation */
if(!ProcessCallback && !ThreadCallback)
return STATUS_INVALID_PARAMETER;
ProcessesAndThreads = PsaWalkFirstProcess(ProcessesAndThreads);
/* scan the process list */
do
{
/* notify the callback */
nErrCode = Callback(pInfoHead, CallbackContext);
/* if the caller provided a process callback */
if(ProcessCallback)
{
/* notify the callback */
nErrCode = ProcessCallback(ProcessesAndThreads, ProcessCallbackContext);
/* if the callback returned an error, break out */
if(!NT_SUCCESS(nErrCode))
break;
}
/* if the caller provided a thread callback */
if(ThreadCallback)
{
ULONG i;
PSYSTEM_THREADS pCurThread;
/* scan the current process's thread list */
for
(
i = 0, pCurThread = PsaWalkFirstThread(ProcessesAndThreads);
i < ProcessesAndThreads->ThreadCount;
++ i, pCurThread = PsaWalkNextThread(pCurThread)
)
{
/* notify the callback */
nErrCode = ThreadCallback(pCurThread, ThreadCallbackContext);
/* if the callback returned an error, break out */
if(!NT_SUCCESS(nErrCode)) goto epat_Breakout;
}
}
/* if the callback returned an error or this is the end of the process list,
break out */
if(!NT_SUCCESS(nErrCode) || pInfoHead->RelativeOffset == 0)
break;
/* move to the next process */
pInfoHead =
(SYSTEM_PROCESS_INFORMATION*)
((ULONG)pInfoHead + pInfoHead->RelativeOffset);
ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads);
}
/* repeat until the end of the string */
while(ProcessesAndThreads);
esp_Finalize:
epat_Breakout:
/* return the last status */
return (nErrCode);
}
NTSTATUS
NTAPI
PsaEnumerateProcessesAndThreads
(
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
)
{
register NTSTATUS nErrCode;
PSYSTEM_PROCESSES pInfoBuffer;
/* parameter validation */
if(!ProcessCallback && !ThreadCallback)
return STATUS_INVALID_PARAMETER;
/* get the processes and threads list */
nErrCode = PsaCaptureProcessesAndThreads(&pInfoBuffer);
/* failure */
if(!NT_SUCCESS(nErrCode))
goto epat_Finalize;
/* walk the processes and threads list */
nErrCode = PsaWalkProcessesAndThreads
(
pInfoBuffer,
ProcessCallback,
ProcessCallbackContext,
ThreadCallback,
ThreadCallbackContext
);
epat_Finalize:
/* free the buffer */
free(pInfoBuffer);
PsaFreeCapture(pInfoBuffer);
/* return the last status */
return (nErrCode);
}
/* EOF */
VOID
NTAPI
PsaFreeCapture
(
IN PVOID Capture
)
{
PsaiFree(Capture);
}
NTSTATUS
NTAPI
PsaWalkProcesses
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
return PsaWalkProcessesAndThreads
(
ProcessesAndThreads,
Callback,
CallbackContext,
NULL,
NULL
);
}
NTSTATUS
NTAPI
PsaWalkThreads
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
return PsaWalkProcessesAndThreads
(
ProcessesAndThreads,
NULL,
NULL,
Callback,
CallbackContext
);
}
NTSTATUS
NTAPI
PsaEnumerateProcesses
(
IN PPROC_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
return PsaEnumerateProcessesAndThreads
(
Callback,
CallbackContext,
NULL,
NULL
);
}
NTSTATUS
NTAPI
PsaEnumerateThreads
(
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
)
{
return PsaEnumerateProcessesAndThreads
(
NULL,
NULL,
Callback,
CallbackContext
);
}
PSYSTEM_PROCESSES
FASTCALL
PsaWalkFirstProcess
(
IN PSYSTEM_PROCESSES ProcessesAndThreads
)
{
return ProcessesAndThreads;
}
PSYSTEM_PROCESSES
FASTCALL
PsaWalkNextProcess
(
IN PSYSTEM_PROCESSES CurrentProcess
)
{
if(CurrentProcess->NextEntryDelta == 0)
return NULL;
else
return
(PSYSTEM_PROCESSES)
((ULONG_PTR)CurrentProcess + CurrentProcess->NextEntryDelta);
}
PSYSTEM_THREADS
FASTCALL
PsaWalkFirstThread
(
IN PSYSTEM_PROCESSES CurrentProcess
)
{
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)
{
switch(SharedUserData->NtMajorVersion)
{
/* NT 3 and 4 */
case 3:
case 4:
{
nOffsetOfThreads = offsetof(SYSTEM_PROCESSES_NT4, Threads);
break;
}
/* NT 5 and later */
default:
case 5:
{
nOffsetOfThreads = offsetof(SYSTEM_PROCESSES_NT5, Threads);
break;
}
}
}
return (PSYSTEM_THREADS)((ULONG_PTR)CurrentProcess + nOffsetOfThreads);
}
PSYSTEM_THREADS
FASTCALL
PsaWalkNextThread
(
IN PSYSTEM_THREADS CurrentThread
)
{
return (PSYSTEM_THREADS)
(
(ULONG_PTR)CurrentThread +
(
offsetof(SYSTEM_PROCESSES, Threads[1]) -
offsetof(SYSTEM_PROCESSES, Threads[0])
)
);
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: psapi.h,v 1.3 2002/08/31 15:36:55 hyperion Exp $
/* $Id: psapi.h,v 1.4 2003/04/02 22:09:56 hyperion Exp $
*/
/*
* internal/psapi.h
@ -32,20 +32,26 @@
/* OBJECTS */
/* TYPES */
typedef NTSTATUS STDCALL (*PPROC_ENUM_ROUTINE)
typedef NTSTATUS NTAPI (*PPROC_ENUM_ROUTINE)
(
IN PSYSTEM_PROCESS_INFORMATION CurrentProcess,
IN PSYSTEM_PROCESSES CurrentProcess,
IN OUT PVOID CallbackContext
);
typedef NTSTATUS STDCALL (*PSYSMOD_ENUM_ROUTINE)
typedef NTSTATUS NTAPI (*PTHREAD_ENUM_ROUTINE)
(
IN PSYSTEM_THREADS CurrentThread,
IN OUT PVOID CallbackContext
);
typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE)
(
IN ULONG ModuleCount,
IN PSYSTEM_MODULE_ENTRY CurrentModule,
IN OUT PVOID CallbackContext
);
typedef NTSTATUS STDCALL (*PPROCMOD_ENUM_ROUTINE)
typedef NTSTATUS NTAPI (*PPROCMOD_ENUM_ROUTINE)
(
IN HANDLE ProcessHandle,
IN PLDR_MODULE CurrentModule,
@ -57,7 +63,88 @@ typedef NTSTATUS STDCALL (*PPROCMOD_ENUM_ROUTINE)
/* PROTOTYPES */
NTSTATUS
STDCALL
NTAPI
PsaCaptureProcessesAndThreads
(
OUT PSYSTEM_PROCESSES * ProcessesAndThreads
);
NTSTATUS
NTAPI
PsaWalkProcessesAndThreads
(
IN PSYSTEM_PROCESSES ProcessesAndThreads,
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateProcessesAndThreads
(
IN PPROC_ENUM_ROUTINE ProcessCallback,
IN OUT PVOID ProcessCallbackContext,
IN PTHREAD_ENUM_ROUTINE ThreadCallback,
IN OUT PVOID ThreadCallbackContext
);
VOID
NTAPI
PsaFreeCapture
(
IN PVOID Capture
);
PSYSTEM_PROCESSES
FASTCALL
PsaWalkFirstProcess
(
IN PSYSTEM_PROCESSES ProcessesAndThreads
);
PSYSTEM_PROCESSES
FASTCALL
PsaWalkNextProcess
(
IN PSYSTEM_PROCESSES CurrentProcess
);
PSYSTEM_THREADS
FASTCALL
PsaWalkFirstThread
(
IN PSYSTEM_PROCESSES CurrentProcess
);
PSYSTEM_THREADS
FASTCALL
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,
@ -65,7 +152,15 @@ PsaEnumerateProcesses
);
NTSTATUS
STDCALL
NTAPI
PsaEnumerateThreads
(
IN PTHREAD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
NTSTATUS
NTAPI
PsaEnumerateSystemModules
(
IN PSYSMOD_ENUM_ROUTINE Callback,
@ -73,7 +168,7 @@ PsaEnumerateSystemModules
);
NTSTATUS
STDCALL
NTAPI
PsaEnumerateProcessModules
(
IN HANDLE ProcessHandle,
@ -81,6 +176,12 @@ PsaEnumerateProcessModules
IN OUT PVOID CallbackContext
);
/* 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);
void *PsaiRealloc(void *ptr, SIZE_T size);
void PsaiFree(void *ptr);
/* MACROS */
#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n"

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.3 2002/08/31 15:36:56 hyperion Exp $
# $Id: makefile,v 1.4 2003/04/02 22:09:57 hyperion Exp $
PATH_TO_TOP = ../..
@ -10,6 +10,8 @@ TARGET_SDKLIBS = ntdll.a kernel32.a
TARGET_CFLAGS = -I./include -Wall
TARGET_LFLAGS = -nostartfiles -nostdlib
TARGET_BASE = 0x68F70000
TARGET_OBJECTS = \

View file

@ -1,4 +1,4 @@
/* $Id: malloc.c,v 1.3 2002/08/31 17:11:24 hyperion Exp $
/* $Id: malloc.c,v 1.4 2003/04/02 22:09:57 hyperion Exp $
*/
/*
* COPYRIGHT: None
@ -9,6 +9,8 @@
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
* UPDATE HISTORY:
* 10/06/2002: Created
* 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
* for better reusability
*/
#include <ddk/ntddk.h>
@ -46,17 +48,17 @@ PVOID STDCALL MemAlloc
return pBuf;
}
void *malloc(size_t size)
void *PsaiMalloc(SIZE_T size)
{
return MemAlloc(NULL, NULL, size);
}
void *realloc(void *ptr, size_t size)
void *PsaiRealloc(void *ptr, SIZE_T size)
{
return MemAlloc(NULL, ptr, size);
}
void free(void *ptr)
void PsaiFree(void *ptr)
{
MemAlloc(NULL, ptr, 0);
}

View file

@ -1,4 +1,4 @@
/* $Id: win32.c,v 1.5 2003/02/02 19:26:08 hyperion Exp $
/* $Id: win32.c,v 1.6 2003/04/02 22:09:57 hyperion Exp $
*/
/*
* COPYRIGHT: See COPYING in the top level directory
@ -143,7 +143,7 @@ typedef struct _ENUM_PROCESSES_CONTEXT
/* callback routine */
NTSTATUS STDCALL EnumProcessesCallback
(
IN PSYSTEM_PROCESS_INFORMATION CurrentProcess,
IN PSYSTEM_PROCESSES CurrentProcess,
IN OUT PVOID CallbackContext
)
{
@ -165,7 +165,7 @@ NTSTATUS STDCALL EnumProcessesCallback
}
/* exported interface */
/*
/*!
@brief Enumerate the process identifiers of the currently active processes
@param lpidProcess Array that receives the list of process identifiers
@ -194,7 +194,11 @@ BOOL STDCALL EnumProcesses
}
/* enumerate the process ids */
nErrCode = PsaEnumerateProcesses(&EnumProcessesCallback, &epcContext);
nErrCode = PsaEnumerateProcesses
(
&EnumProcessesCallback,
&epcContext
);
*lpcbNeeded = (cb - epcContext.nCount) * sizeof(DWORD);
@ -492,7 +496,7 @@ DWORD FASTCALL internalGetMappedFileName(
nBufSize = nSize * sizeof(WCHAR);
/* allocate the memory */
pmsnName = malloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer));
pmsnName = PsaiMalloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer));
if(pmsnName == NULL)
{
@ -527,7 +531,7 @@ DWORD FASTCALL internalGetMappedFileName(
#if 0
#else
/* free the buffer */
free(pmsnName);
PsaiFree(pmsnName);
#endif
return 0;
}
@ -546,7 +550,7 @@ DWORD FASTCALL internalGetMappedFileName(
#if 0
#else
/* free the buffer */
free(pmsnName);
PsaiFree(pmsnName);
#endif
if(pmsnName->SectionFileName.Length < nSize)
@ -572,7 +576,7 @@ DWORD FASTCALL internalGetMappedFileName(
#if 0
#else
/* free the buffer */
free(pmsnName);
PsaiFree(pmsnName);
#endif
if(strAnsi.Length < nSize)
@ -589,7 +593,7 @@ DWORD FASTCALL internalGetMappedFileName(
}
__finally
{
free(pmsnName);
PsaiFree(pmsnName);
}
#endif
}
@ -715,7 +719,7 @@ NTSTATUS STDCALL GetModuleInformationCallback
UNICODE_STRING wstrUnicodeBuf;
/* allocate the local buffer */
pwcUnicodeBuf = malloc(pwstrSource->Length);
pwcUnicodeBuf = PsaiMalloc(pwstrSource->Length);
#if 0
__try
@ -767,7 +771,7 @@ NTSTATUS STDCALL GetModuleInformationCallback
__finally
{
/* free the buffer */
free(pwcUnicodeBuf);
PsaiFree(pwcUnicodeBuf);
}
#else
/* success */
@ -775,7 +779,7 @@ NTSTATUS STDCALL GetModuleInformationCallback
exitWithStatus:
/* free the buffer */
free(pwcUnicodeBuf);
PsaiFree(pwcUnicodeBuf);
return nErrCode;
#endif
}