// 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;
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)
--- /dev/null
+/* $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 */
-/* $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
* 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>
#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
-/* $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
#include <ddk/ntddk.h>
#include <debug.h>
#include <stddef.h>
-#include <internal/psapi.h>
+
+#include "internal/psapi.h"
NTSTATUS
NTAPI
{
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)
{
-/* $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
typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE)
(
- IN ULONG ModuleCount,
- IN PSYSTEM_MODULE_ENTRY CurrentModule,
+ IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
);
#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
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
IN PSYSTEM_THREADS CurrentThread
);
+/* System modules */
+/* enumeration */
NTSTATUS
NTAPI
-PsaWalkProcesses
+PsaEnumerateSystemModules
(
- IN PSYSTEM_PROCESSES ProcessesAndThreads,
- IN PPROC_ENUM_ROUTINE Callback,
+ IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
+/* capturing & walking */
NTSTATUS
NTAPI
-PsaWalkThreads
+PsaCaptureSystemModules
(
- IN PSYSTEM_PROCESSES ProcessesAndThreads,
- IN PTHREAD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
+ OUT PSYSTEM_MODULES * SystemModules
);
NTSTATUS
NTAPI
-PsaEnumerateProcesses
+PsaWalkSystemModules
(
- IN PPROC_ENUM_ROUTINE Callback,
+ IN PSYSTEM_MODULES SystemModules,
+ IN PSYSMOD_ENUM_ROUTINE Callback,
IN OUT PVOID CallbackContext
);
-NTSTATUS
-NTAPI
-PsaEnumerateThreads
+PSYSTEM_MODULE_INFORMATION
+FASTCALL
+PsaWalkFirstSystemModule
(
- IN PTHREAD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
+ IN PSYSTEM_MODULES SystemModules
);
-NTSTATUS
-NTAPI
-PsaEnumerateSystemModules
+PSYSTEM_MODULE_INFORMATION
+FASTCALL
+PsaWalkNextSystemModule
(
- IN PSYSMOD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
+ IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
);
+/* Process modules */
NTSTATUS
NTAPI
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);
#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */
/* EOF */
-
-# $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 = ../..
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
-/* $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
/* callback routine */
NTSTATUS STDCALL EnumDeviceDriversCallback
(
- IN ULONG ModuleCount,
- IN PSYSTEM_MODULE_ENTRY CurrentModule,
+ IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
)
{
return STATUS_INFO_LENGTH_MISMATCH;
/* return current module */
- *(peddcContext->lpImageBase) = CurrentModule->BaseAddress;
+ *(peddcContext->lpImageBase) = CurrentModule->Base;
/* go to next array slot */
(peddcContext->lpImageBase) ++;
/* common callback routine */
NTSTATUS STDCALL GetDeviceDriverNameCallback
(
- IN ULONG ModuleCount,
- IN PSYSTEM_MODULE_ENTRY CurrentModule,
+ IN PSYSTEM_MODULE_INFORMATION CurrentModule,
IN OUT PVOID CallbackContext
)
{
(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);
-/* $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
* 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
*/
PLIST_ENTRY current_entry;
PMODULE_OBJECT current;
ULONG ModuleCount = 0;
- PSYSTEM_MODULE_INFORMATION Smi;
+ PSYSTEM_MODULES Smi;
ANSI_STRING AnsiName;
PCHAR p;
KIRQL Irql;
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)
{
/* fill the buffer */
memset(Buffer, '=', Size);
- Smi = (PSYSTEM_MODULE_INFORMATION)Buffer;
+ Smi = (PSYSTEM_MODULES)Buffer;
Smi->Count = ModuleCount;
ModuleCount = 0;
{
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,
¤t->FullName,
FALSE);
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++;