merged epsapi into psapi and reformatted some code to make it readable
authorThomas Bluemel <thomas@reactsoft.com>
Wed, 3 Nov 2004 22:43:00 +0000 (22:43 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Wed, 3 Nov 2004 22:43:00 +0000 (22:43 +0000)
svn path=/trunk/; revision=11535

17 files changed:
reactos/Makefile
reactos/include/epsapi.h [deleted file]
reactos/lib/epsapi/enum/drivers.c [deleted file]
reactos/lib/epsapi/enum/modules.c [deleted file]
reactos/lib/epsapi/enum/processes.c [deleted file]
reactos/lib/epsapi/makefile [deleted file]
reactos/lib/psapi/enum/.cvsignore [new file with mode: 0644]
reactos/lib/psapi/enum/drivers.c [new file with mode: 0644]
reactos/lib/psapi/enum/modules.c [new file with mode: 0644]
reactos/lib/psapi/enum/processes.c [new file with mode: 0644]
reactos/lib/psapi/internal.h [new file with mode: 0644]
reactos/lib/psapi/makefile
reactos/lib/psapi/misc/dllmain.c
reactos/lib/psapi/misc/malloc.c
reactos/lib/psapi/misc/stubs.c
reactos/lib/psapi/misc/win32.c
reactos/lib/psapi/precomp.h

index ab9a6c3..3c41f51 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.256 2004/11/03 20:12:59 gvg Exp $
+# $Id: Makefile,v 1.257 2004/11/03 22:42:59 weiden Exp $
 #
 # Global makefile
 #
@@ -38,7 +38,7 @@ BUS = acpi isapnp pci
 LIB_FSLIB = vfatlib
 
 # Static libraries
-LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt pseh adns
+LIB_STATIC = string rosrtl uuid libwine zlib rtl tgetopt pseh adns
 
 # Keyboard layout libraries
 DLLS_KBD = kbddv kbdfr kbdgr kbdse kbduk kbdus
diff --git a/reactos/include/epsapi.h b/reactos/include/epsapi.h
deleted file mode 100644 (file)
index cac0fcd..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/* $Id: epsapi.h,v 1.4 2004/03/21 12:34:02 gvg Exp $
-*/
-/*
- * epsapi.h
- *
- * Process Status Helper API, native interface
- *
- * This file is part of the ReactOS Operating System.
- *
- * Contributors:
- *  Created by KJK::Hyperion <noog@libero.it>
- *
- *  THIS SOFTWARE IS NOT COPYRIGHTED
- *
- *  This source code is offered for use in the public domain. You may
- *  use, modify or distribute it freely.
- *
- *  This code is distributed in the hope that it will be useful but
- *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
- *  DISCLAMED. This includes but is not limited to warranties of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __INTERNAL_PSAPI_H_INCLUDED__
-#define __INTERNAL_PSAPI_H_INCLUDED__
-
-/* INCLUDES */
-#define NTOS_MODE_USER
-#include <ntos.h>
-
-/* OBJECTS */
-
-/* TYPES */
-typedef NTSTATUS (NTAPI *PPROC_ENUM_ROUTINE)
-(
- IN PSYSTEM_PROCESSES CurrentProcess,
- IN OUT PVOID CallbackContext
-);
-
-typedef NTSTATUS (NTAPI *PTHREAD_ENUM_ROUTINE)
-(
- IN PSYSTEM_THREADS CurrentThread,
- IN OUT PVOID CallbackContext
-);
-
-typedef NTSTATUS (NTAPI *PSYSMOD_ENUM_ROUTINE)
-(
- IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule,
- IN OUT PVOID CallbackContext
-);
-
-typedef NTSTATUS (NTAPI *PPROCMOD_ENUM_ROUTINE)
-(
- IN HANDLE ProcessHandle,
- IN PLDR_MODULE CurrentModule,
- IN OUT PVOID CallbackContext
-);
-
-/* CONSTANTS */
-#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
-(
- 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
-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
-);
-
-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
-);
-
-/* System modules */
-/* enumeration */
-NTSTATUS
-NTAPI
-PsaEnumerateSystemModules
-(
- IN PSYSMOD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
-);
-
-/* capturing & walking */
-NTSTATUS
-NTAPI
-PsaCaptureSystemModules
-(
- OUT PSYSTEM_MODULE_INFORMATION * SystemModules
-);
-
-NTSTATUS
-NTAPI
-PsaWalkSystemModules
-(
- IN PSYSTEM_MODULE_INFORMATION SystemModules,
- IN PSYSMOD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
-);
-
-PSYSTEM_MODULE_INFORMATION_ENTRY
-FASTCALL
-PsaWalkFirstSystemModule
-(
- IN PSYSTEM_MODULE_INFORMATION SystemModules
-);
-
-PSYSTEM_MODULE_INFORMATION_ENTRY
-FASTCALL
-PsaWalkNextSystemModule
-(
- IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
-);
-
-/* Process modules */
-NTSTATUS
-NTAPI
-PsaEnumerateProcessModules
-(
- IN HANDLE ProcessHandle,
- IN PPROCMOD_ENUM_ROUTINE Callback,
- 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);
-void *PsaiRealloc(void *ptr, SIZE_T size);
-void PsaiFree(void *ptr);
-
-/* MACROS */
-#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n"
-
-#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */
-
-/* EOF */
diff --git a/reactos/lib/epsapi/enum/drivers.c b/reactos/lib/epsapi/enum/drivers.c
deleted file mode 100644 (file)
index bd54f85..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/* $Id: drivers.c,v 1.2 2003/06/01 14:59:01 chorns 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/epsapi/enum/drivers.c
- * PURPOSE:     Enumerate system modules
- * PROGRAMMER:  KJK::Hyperion <noog@libero.it>
- * UPDATE HISTORY:
- *              02/04/2003: Created
- *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
- *                          isolated in its own library to clear the confusion
- *                          and improve reusability
- */
-
-#include <stddef.h>
-#define NTOS_MODE_USER
-#include <ntos.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#include <epsapi.h>
-
-NTSTATUS
-NTAPI
-PsaEnumerateSystemModules
-(
- IN PSYSMOD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
-)
-{
- register NTSTATUS nErrCode = STATUS_SUCCESS;
- PSYSTEM_MODULE_INFORMATION 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_MODULE_INFORMATION * SystemModules
-)
-{
- SIZE_T nSize = 0;
- register NTSTATUS nErrCode;
- register PSYSTEM_MODULE_INFORMATION psmModules = (PSYSTEM_MODULE_INFORMATION)&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_MODULE_INFORMATION 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->Module[i]), CallbackContext);
-  
-  if(!NT_SUCCESS(nErrCode))
-   /* failure */
-   return nErrCode;
- }
-
- /* success */
- return STATUS_SUCCESS;
-}
-
-PSYSTEM_MODULE_INFORMATION_ENTRY
-FASTCALL
-PsaWalkFirstSystemModule
-(
- IN PSYSTEM_MODULE_INFORMATION SystemModules
-)
-{ 
- return &(SystemModules->Module[0]);
-}
-
-PSYSTEM_MODULE_INFORMATION_ENTRY
-FASTCALL
-PsaWalkNextSystemModule
-(
- IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule
-)
-{
- return (PSYSTEM_MODULE_INFORMATION_ENTRY)
- (
-  (ULONG_PTR)CurrentSystemModule +
-  (
-   offsetof(SYSTEM_MODULE_INFORMATION, Module[1]) -
-   offsetof(SYSTEM_MODULE_INFORMATION, Module[0])
-  )
- );
-}
-
-/* EOF */
diff --git a/reactos/lib/epsapi/enum/modules.c b/reactos/lib/epsapi/enum/modules.c
deleted file mode 100644 (file)
index e595139..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* $Id: modules.c,v 1.2 2003/06/01 14:59:01 chorns 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/epsapi/enum/module.c
- * PURPOSE:     Enumerate process modules
- * 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
- *              02/04/2003: System modules enumeration moved into its own file
- *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
- *                          isolated in its own library to clear the confusion
- *                          and improve reusability
- */
-
-#define NTOS_MODE_USER
-#include <ntos.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#include <epsapi.h>
-
-NTSTATUS
-NTAPI
-PsaEnumerateProcessModules
-(
- IN HANDLE ProcessHandle,
- IN PPROCMOD_ENUM_ROUTINE Callback,
- IN OUT PVOID CallbackContext
-)
-{
- register NTSTATUS nErrCode;
-
- /* current process - use direct memory copy */
- if(ProcessHandle == NtCurrentProcess())
- {
-  register PLIST_ENTRY pleListHead;
-  register PLIST_ENTRY pleCurEntry;
-
-#if 0
-  /* FIXME: activate this when GCC supports SEH */
-  __try
-  {
-#endif
-   pleListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList);
-   pleCurEntry = pleListHead->Flink;
-   while(pleCurEntry != pleListHead)
-   {
-    register PLDR_MODULE plmModule = CONTAINING_RECORD
-    (
-     pleCurEntry,
-     LDR_MODULE,
-     InLoadOrderModuleList
-    );
-   
-    /* return the current module to the callback */
-    nErrCode = Callback(ProcessHandle, plmModule, CallbackContext);
-    
-    if(!NT_SUCCESS(nErrCode))
-     /* failure */
-     goto epm_Failure;
-    
-    pleCurEntry = plmModule->InLoadOrderModuleList.Flink;
-   }
-#if 0
-  /* FIXME: activate this when GCC supports SEH */
-  }
-  __except(EXCEPTION_EXECUTE_HANDLER)
-  {
-   return GetExceptionCode();
-  }
-#endif
- }
- /* another process */
- else
- {
-  PROCESS_BASIC_INFORMATION pbiInfo;
-  PPEB_LDR_DATA ppldLdrData;
-  LDR_MODULE lmModule;
-  PLIST_ENTRY pleListHead;
-  PLIST_ENTRY pleCurEntry;
-  /* query the process basic information (includes the PEB address) */
-  nErrCode = NtQueryInformationProcess
-  (
-   ProcessHandle,
-   ProcessBasicInformation,
-   &pbiInfo,
-   sizeof(pbiInfo),
-   NULL
-  );
-  if(!NT_SUCCESS(nErrCode))
-  {
-   /* failure */
-   DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", nErrCode);
-   goto epm_Failure;
-  }
-  /* get the address of the PE Loader data */
-  nErrCode = NtReadVirtualMemory
-  (
-   ProcessHandle,
-   &(pbiInfo.PebBaseAddress->Ldr),
-   &ppldLdrData,
-   sizeof(ppldLdrData),
-   NULL
-  );
-  if(!NT_SUCCESS(nErrCode))
-  {
-   /* failure */
-   DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode);
-   goto epm_Failure;
-  }
-  /* head of the module list: the last element in the list will point to this */
-  pleListHead = &ppldLdrData->InLoadOrderModuleList;
-  /* get the address of the first element in the list */
-  nErrCode = NtReadVirtualMemory
-  (
-   ProcessHandle,
-   &(ppldLdrData->InLoadOrderModuleList.Flink),
-   &pleCurEntry,
-   sizeof(pleCurEntry),
-   NULL
-  );
-  while(pleCurEntry != pleListHead)
-  {
-   /* read the current module */
-   nErrCode = NtReadVirtualMemory
-   (
-    ProcessHandle,
-    CONTAINING_RECORD(pleCurEntry, LDR_MODULE, InLoadOrderModuleList),
-    &lmModule,
-    sizeof(lmModule),
-    NULL
-   );
-   if(!NT_SUCCESS(nErrCode))
-   {
-    /* failure */
-    DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode);
-    goto epm_Failure;
-   }
-
-   /* return the current module to the callback */
-   nErrCode = Callback(ProcessHandle, &lmModule, CallbackContext);
-   
-   if(!NT_SUCCESS(nErrCode))
-    /* failure */
-    goto epm_Failure;
-    
-   /* address of the next module in the list */
-   pleCurEntry = lmModule.InLoadOrderModuleList.Flink;
-  }
- }
-
- /* success */
- return (STATUS_SUCCESS);
-
-epm_Failure:
- /* failure */
- return (nErrCode);
-}
-
-/* EOF */
diff --git a/reactos/lib/epsapi/enum/processes.c b/reactos/lib/epsapi/enum/processes.c
deleted file mode 100644 (file)
index 2c0e345..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-/* $Id: processes.c,v 1.1 2003/04/13 03:24:27 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/epsapi/enum/processes.c
- * 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
- *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
- *                          isolated in its own library to clear the confusion
- *                          and improve reusability
- */
-
-#include <ddk/ntddk.h>
-#include <debug.h>
-#include <stddef.h>
-
-#include <epsapi.h>
-
-NTSTATUS
-NTAPI
-PsaCaptureProcessesAndThreads
-(
- OUT PSYSTEM_PROCESSES * ProcessesAndThreads
-)
-{
- 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
-    system is already under stress, and a huge buffer could only make things
-    worse. The function should be profiled to see what's the average minimum
-    buffer size, to succeed on the first shot */
- 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 */
-  PsaiFree(pInfoBuffer);
-  pTmp = PsaiMalloc(nSize);
-  
-  if(pTmp == NULL)
-  {
-   /* failure */
-   DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", STATUS_NO_MEMORY);
-   nErrCode = STATUS_NO_MEMORY;
-   break;
-  }
-  
-  pInfoBuffer = pTmp;
-  
-  /* query the information */
-  nErrCode = NtQuerySystemInformation
-  (
-   SystemProcessesAndThreadsInformation,
-   pInfoBuffer,
-   nSize,
-   NULL
-  );
-
-  /* double the buffer size */
-  nSize += nSize;
- }
- /* repeat until the buffer is big enough */
- while(nErrCode == STATUS_INFO_LENGTH_MISMATCH);
- /* failure */
- if(!NT_SUCCESS(nErrCode))
- {
-  DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
-  return nErrCode;  
- }
-
- /* 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
- {
-  /* 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;
-   }
-  }
-
-  /* move to the next process */
-  ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads);
- }
- /* repeat until the end of the string */
- while(ProcessesAndThreads);
-
-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 */
- PsaFreeCapture(pInfoBuffer);
- /* return the last status */
- return (nErrCode);
-}
-
-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;
-
- /* get the offset of the Threads field (dependant on the kernel version) */
- if(!nOffsetOfThreads)
- {
-  /*
-   FIXME: we should probably use the build number, instead, but it isn't
-   available as reliably as the major and minor version numbers
-  */
-  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 */
diff --git a/reactos/lib/epsapi/makefile b/reactos/lib/epsapi/makefile
deleted file mode 100644 (file)
index 460bd66..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# $Id: makefile,v 1.3 2003/09/12 17:51:46 vizzini Exp $
-
-PATH_TO_TOP = ../..
-
-TARGET_TYPE = library
-
-TARGET_NAME = epsapi
-
-# require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -Werror -Wall
-
-TARGET_OBJECTS = \
- enum/drivers.o \
- enum/modules.o \
- enum/processes.o 
-include $(PATH_TO_TOP)/rules.mak
-
-include $(TOOLS_PATH)/helper.mk
-
-# EOF
diff --git a/reactos/lib/psapi/enum/.cvsignore b/reactos/lib/psapi/enum/.cvsignore
new file mode 100644 (file)
index 0000000..b2bf645
--- /dev/null
@@ -0,0 +1,2 @@
+*.o
+.*.d
\ No newline at end of file
diff --git a/reactos/lib/psapi/enum/drivers.c b/reactos/lib/psapi/enum/drivers.c
new file mode 100644 (file)
index 0000000..853a26d
--- /dev/null
@@ -0,0 +1,191 @@
+/* $Id: drivers.c,v 1.3 2004/11/03 22:43:00 weiden 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/epsapi/enum/drivers.c
+ * PURPOSE:     Enumerate system modules
+ * PROGRAMMER:  KJK::Hyperion <noog@libero.it>
+ * UPDATE HISTORY:
+ *              02/04/2003: Created
+ *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
+ *                          isolated in its own library to clear the confusion
+ *                          and improve reusability
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS NTAPI
+PsaEnumerateSystemModules(IN PSYSMOD_ENUM_ROUTINE Callback,
+                          IN OUT PVOID CallbackContext)
+{
+  PSYSTEM_MODULE_INFORMATION psmModules;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+#if 0
+  __try
+  {
+#else
+  do
+  {
+#endif
+  /* capture the system modules */
+  Status = PsaCaptureSystemModules(&psmModules);
+  if(!NT_SUCCESS(Status))
+  {
+    break;
+  }
+
+  /* walk the system modules */
+  Status = PsaWalkSystemModules(psmModules, Callback, CallbackContext);
+#if 0
+  }
+  __finally
+  {
+#else
+  } while(0);
+#endif
+  /* free the capture */
+  PsaFreeCapture(psmModules);
+#if 0
+  }
+#endif
+  return Status;
+}
+
+NTSTATUS NTAPI
+PsaCaptureSystemModules(OUT PSYSTEM_MODULE_INFORMATION *SystemModules)
+{
+  SIZE_T nSize = 0;
+  PSYSTEM_MODULE_INFORMATION psmModules;
+  NTSTATUS Status;
+
+#if 0
+  __try
+  {
+#else
+  do
+  {
+#endif
+  /* initial probe. We just get the count of system modules */
+  Status = NtQuerySystemInformation(SystemModuleInformation,
+                                    &nSize,
+                                    sizeof(nSize),
+                                    NULL);
+
+  if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH))
+  {
+    DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status);
+    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(SYSTEM_MODULE_INFORMATION) +
+          ((psmModules->Count - 1) * sizeof(SYSTEM_MODULE_INFORMATION));
+
+  psmModules = NULL;
+
+  do
+  {
+    PVOID 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)
+    {
+      Status = STATUS_NO_MEMORY;
+      DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", Status);
+      break;
+    }
+
+    psmModules = pTmp;
+
+    /* query the information */
+    Status = NtQuerySystemInformation(SystemModuleInformation,
+                                      psmModules,
+                                      nSize,
+                                      NULL);
+
+    /* double the buffer for the next loop */
+    nSize *= 2;
+  } while(Status == STATUS_INFO_LENGTH_MISMATCH);
+
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status);
+    break;
+  }
+
+  *SystemModules = psmModules;
+
+  Status = STATUS_SUCCESS;
+#if 0
+  }
+  __finally
+  {
+#else
+  } while(0);
+#endif
+  /* in case of failure, free the buffer */
+  if(!NT_SUCCESS(Status))
+  {
+    PsaiFree(psmModules);
+  }
+#if 0
+  }
+#endif
+
+  return Status;
+}
+
+NTSTATUS NTAPI
+PsaWalkSystemModules(IN PSYSTEM_MODULE_INFORMATION SystemModules,
+                     IN PSYSMOD_ENUM_ROUTINE Callback,
+                     IN OUT PVOID CallbackContext)
+{
+  ULONG i;
+  NTSTATUS Status;
+
+  /* repeat until all modules have been returned */
+  for(i = 0; i < SystemModules->Count; i++)
+  {
+    /* return current module to the callback */
+    Status = Callback(&(SystemModules->Module[i]), CallbackContext);
+  
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+
+  return STATUS_SUCCESS;
+}
+
+PSYSTEM_MODULE_INFORMATION_ENTRY FASTCALL
+PsaWalkFirstSystemModule(IN PSYSTEM_MODULE_INFORMATION SystemModules)
+{ 
+  return &(SystemModules->Module[0]);
+}
+
+PSYSTEM_MODULE_INFORMATION_ENTRY FASTCALL
+PsaWalkNextSystemModule(IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule)
+{
+  return (PSYSTEM_MODULE_INFORMATION_ENTRY)((ULONG_PTR)CurrentSystemModule +
+                                            (offsetof(SYSTEM_MODULE_INFORMATION, Module[1]) -
+                                             offsetof(SYSTEM_MODULE_INFORMATION, Module[0])));
+}
+
+/* EOF */
diff --git a/reactos/lib/psapi/enum/modules.c b/reactos/lib/psapi/enum/modules.c
new file mode 100644 (file)
index 0000000..7509dc4
--- /dev/null
@@ -0,0 +1,146 @@
+/* $Id: modules.c,v 1.1 2004/11/03 22:43:00 weiden 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/epsapi/enum/module.c
+ * PURPOSE:     Enumerate process modules
+ * 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
+ *              02/04/2003: System modules enumeration moved into its own file
+ *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
+ *                          isolated in its own library to clear the confusion
+ *                          and improve reusability
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS NTAPI
+PsaEnumerateProcessModules(IN HANDLE ProcessHandle,
+                           IN PPROCMOD_ENUM_ROUTINE Callback,
+                           IN OUT PVOID CallbackContext)
+{
+  NTSTATUS Status;
+
+  /* current process - use direct memory copy */
+  /* FIXME - compare process id instead of a handle */
+  if(ProcessHandle == NtCurrentProcess())
+  {
+    PLIST_ENTRY ListHead, Current;
+
+#if 0
+    __try
+    {
+#endif
+      ListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList);
+      Current = ListHead->Flink;
+      while(Current != ListHead)
+      {
+        PLDR_MODULE LoaderModule = CONTAINING_RECORD(Current, LDR_MODULE, InLoadOrderModuleList);
+   
+        /* return the current module to the callback */
+        Status = Callback(ProcessHandle, LoaderModule, CallbackContext);
+    
+        if(!NT_SUCCESS(Status))
+        {
+          goto Failure;
+        }
+    
+        Current = LoaderModule->InLoadOrderModuleList.Flink;
+      }
+#if 0
+    }
+    __except(EXCEPTION_EXECUTE_HANDLER)
+    {
+      return GetExceptionCode();
+    }
+#endif
+  }
+  else
+  {
+    PROCESS_BASIC_INFORMATION BasicInformation;
+    PPEB_LDR_DATA LoaderData;
+    LDR_MODULE LoaderModule;
+    PLIST_ENTRY ListHead, Current;
+    /* query the process basic information (includes the PEB address) */
+    Status = NtQueryInformationProcess(ProcessHandle,
+                                       ProcessBasicInformation,
+                                       &BasicInformation,
+                                       sizeof(BasicInformation),
+                                       NULL);
+    if(!NT_SUCCESS(Status))
+    {
+      DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", Status);
+      goto Failure;
+    }
+    /* get the address of the PE Loader data */
+    Status = NtReadVirtualMemory(ProcessHandle,
+                                 &(BasicInformation.PebBaseAddress->Ldr),
+                                 &LoaderData,
+                                 sizeof(LoaderData),
+                                 NULL);
+    if(!NT_SUCCESS(Status))
+    {
+      DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", Status);
+      goto Failure;
+    }
+    /* head of the module list: the last element in the list will point to this */
+    ListHead = &LoaderData->InLoadOrderModuleList;
+    /* get the address of the first element in the list */
+    Status = NtReadVirtualMemory(ProcessHandle,
+                                 &(LoaderData->InLoadOrderModuleList.Flink),
+                                 &Current,
+                                 sizeof(Current),
+                                 NULL);
+    while(Current != ListHead)
+    {
+      /* read the current module */
+      Status = NtReadVirtualMemory(ProcessHandle,
+                                   CONTAINING_RECORD(Current, LDR_MODULE, InLoadOrderModuleList),
+                                   &LoaderModule,
+                                   sizeof(LoaderModule),
+                                   NULL);
+      if(!NT_SUCCESS(Status))
+      {
+        DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", Status);
+        goto Failure;
+      }
+
+      /* return the current module to the callback */
+      Status = Callback(ProcessHandle, &LoaderModule, CallbackContext);
+   
+      if(!NT_SUCCESS(Status))
+      {
+        goto Failure;
+      }
+    
+      /* address of the next module in the list */
+      Current = LoaderModule.InLoadOrderModuleList.Flink;
+    }
+  }
+
+  return STATUS_SUCCESS;
+
+Failure:
+  return Status;
+}
+
+/* EOF */
diff --git a/reactos/lib/psapi/enum/processes.c b/reactos/lib/psapi/enum/processes.c
new file mode 100644 (file)
index 0000000..3947422
--- /dev/null
@@ -0,0 +1,301 @@
+/* $Id: processes.c,v 1.1 2004/11/03 22:43:00 weiden 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/epsapi/enum/processes.c
+ * 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
+ *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
+ *                          isolated in its own library to clear the confusion
+ *                          and improve reusability
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS NTAPI
+PsaCaptureProcessesAndThreads(OUT PSYSTEM_PROCESSES *ProcessesAndThreads)
+{
+  PSYSTEM_PROCESSES pInfoBuffer = NULL;
+  SIZE_T nSize = 0x8000;
+  NTSTATUS Status;
+
+  if(ProcessesAndThreads == NULL)
+  {
+    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
+            system is already under stress, and a huge buffer could only make things
+            worse. The function should be profiled to see what's the average minimum
+            buffer size, to succeed on the first shot */
+  do
+  {
+    PVOID 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 */
+    PsaiFree(pInfoBuffer);
+    pTmp = PsaiMalloc(nSize);
+  
+    if(pTmp == NULL)
+    {
+      DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", STATUS_NO_MEMORY);
+      Status = STATUS_NO_MEMORY;
+      break;
+    }
+  
+    pInfoBuffer = pTmp;
+  
+    /* query the information */
+    Status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
+                                      pInfoBuffer,
+                                      nSize,
+                                      NULL);
+
+    /* double the buffer size */
+    nSize *= 2;
+  } while(Status == STATUS_INFO_LENGTH_MISMATCH);
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status);
+    return Status;
+  }
+
+  *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)
+{
+  NTSTATUS Status;
+
+  if(ProcessCallback == NULL && ThreadCallback == NULL)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+  
+  Status = STATUS_SUCCESS;
+
+  ProcessesAndThreads = PsaWalkFirstProcess(ProcessesAndThreads);
+
+  /* scan the process list */
+  do
+  {
+    if(ProcessCallback)
+    {
+      Status = ProcessCallback(ProcessesAndThreads, ProcessCallbackContext);
+      if(!NT_SUCCESS(Status))
+      {
+        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))
+      {
+        Status = ThreadCallback(pCurThread, ThreadCallbackContext);
+        
+        if(!NT_SUCCESS(Status))
+        {
+          goto Bail;
+        }
+      }
+    }
+
+    /* move to the next process */
+    ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads);
+  } while(ProcessesAndThreads);
+
+Bail:
+  return Status;
+}
+
+NTSTATUS NTAPI
+PsaEnumerateProcessesAndThreads(IN PPROC_ENUM_ROUTINE ProcessCallback,
+                                IN OUT PVOID ProcessCallbackContext,
+                                IN PTHREAD_ENUM_ROUTINE ThreadCallback,
+                                IN OUT PVOID ThreadCallbackContext)
+{
+  PSYSTEM_PROCESSES pInfoBuffer;
+  NTSTATUS Status;
+
+  if(ProcessCallback == NULL && ThreadCallback == NULL)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  /* get the processes and threads list */
+  Status = PsaCaptureProcessesAndThreads(&pInfoBuffer);
+
+  if(!NT_SUCCESS(Status))
+  {
+    goto Bail;
+  }
+
+  /* walk the processes and threads list */
+  Status = PsaWalkProcessesAndThreads(pInfoBuffer,
+                                      ProcessCallback,
+                                      ProcessCallbackContext,
+                                      ThreadCallback,
+                                      ThreadCallbackContext);
+
+Bail:
+  PsaFreeCapture(pInfoBuffer);
+  return Status;
+}
+
+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;
+
+  /* get the offset of the Threads field (dependant on the kernel version) */
+  if(!nOffsetOfThreads)
+  {
+    /*
+     FIXME: we should probably use the build number, instead, but it isn't
+     available as reliably as the major and minor version numbers
+    */
+    switch(SharedUserData->NtMajorVersion)
+    {
+      /* NT 3 and 4 */
+      case 3:
+      case 4:
+      {
+        nOffsetOfThreads = offsetof(SYSTEM_PROCESSES_NT4, Threads);
+        break;
+      }
+
+      /* NT 5 and later */
+      case 5:
+      default:
+      {
+        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 */
diff --git a/reactos/lib/psapi/internal.h b/reactos/lib/psapi/internal.h
new file mode 100644 (file)
index 0000000..86eb724
--- /dev/null
@@ -0,0 +1,144 @@
+/* $Id: internal.h,v 1.1 2004/11/03 22:42:59 weiden Exp $
+*/
+/*
+ * epsapi.h
+ *
+ * Process Status Helper API, native interface
+ *
+ * This file is part of the ReactOS Operating System.
+ *
+ * Contributors:
+ *  Created by KJK::Hyperion <noog@libero.it>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __INTERNAL_PSAPI_H_INCLUDED__
+#define __INTERNAL_PSAPI_H_INCLUDED__
+
+#ifndef SetLastErrorByStatus
+#define SetLastErrorByStatus(__S__) \
+ ((void)SetLastError(RtlNtStatusToDosError(__S__)))
+#endif /* SetLastErrorByStatus */
+
+/* OBJECTS */
+
+/* TYPES */
+typedef NTSTATUS (NTAPI *PPROC_ENUM_ROUTINE)(IN PSYSTEM_PROCESSES CurrentProcess,
+                                             IN OUT PVOID CallbackContext);
+
+typedef NTSTATUS (NTAPI *PTHREAD_ENUM_ROUTINE)(IN PSYSTEM_THREADS CurrentThread,
+                                               IN OUT PVOID CallbackContext);
+
+typedef NTSTATUS (NTAPI *PSYSMOD_ENUM_ROUTINE)(IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule,
+                                               IN OUT PVOID CallbackContext);
+
+typedef NTSTATUS (NTAPI *PPROCMOD_ENUM_ROUTINE)(IN HANDLE ProcessHandle,
+                                                IN PLDR_MODULE CurrentModule,
+                                                IN OUT PVOID CallbackContext);
+
+/* CONSTANTS */
+#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(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
+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);
+
+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);
+
+/* System modules */
+/* enumeration */
+NTSTATUS NTAPI
+PsaEnumerateSystemModules(IN PSYSMOD_ENUM_ROUTINE Callback,
+                          IN OUT PVOID CallbackContext);
+
+/* capturing & walking */
+NTSTATUS NTAPI
+PsaCaptureSystemModules(OUT PSYSTEM_MODULE_INFORMATION * SystemModules);
+
+NTSTATUS NTAPI
+PsaWalkSystemModules(IN PSYSTEM_MODULE_INFORMATION SystemModules,
+                     IN PSYSMOD_ENUM_ROUTINE Callback,
+                     IN OUT PVOID CallbackContext);
+
+PSYSTEM_MODULE_INFORMATION_ENTRY FASTCALL
+PsaWalkFirstSystemModule(IN PSYSTEM_MODULE_INFORMATION SystemModules);
+
+PSYSTEM_MODULE_INFORMATION_ENTRY FASTCALL
+PsaWalkNextSystemModule(IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule);
+
+/* Process modules */
+NTSTATUS NTAPI
+PsaEnumerateProcessModules(IN HANDLE ProcessHandle,
+                           IN PPROCMOD_ENUM_ROUTINE Callback,
+                           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);
+void *PsaiRealloc(void *ptr, SIZE_T size);
+void PsaiFree(void *ptr);
+
+/* MACROS */
+#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n"
+
+#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */
+
+/* EOF */
index b4eeadd..519a2a7 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.11 2004/11/02 23:42:49 weiden Exp $
+# $Id: makefile,v 1.12 2004/11/03 22:42:59 weiden Exp $
 
 PATH_TO_TOP = ../..
 
@@ -20,6 +20,9 @@ TARGET_BASE = $(TARGET_BASE_LIB_PSAPI)
 TARGET_PCH = precomp.h
 
 TARGET_OBJECTS = \
+       enum/drivers.o \
+       enum/modules.o \
+       enum/processes.o \
        misc/dllmain.o \
        misc/malloc.o \
        misc/stubs.o \
index d5fa50e..3e3ed92 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dllmain.c,v 1.5 2004/11/02 23:42:49 weiden Exp $
+/* $Id: dllmain.c,v 1.6 2004/11/03 22:43:00 weiden Exp $
 */
 /*
  * COPYRIGHT:   None
@@ -13,6 +13,9 @@
  */
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 BOOLEAN STDCALL DllMain
 (
  PVOID hinstDll,
index 6463776..2b3fe56 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: malloc.c,v 1.5 2004/11/02 23:42:49 weiden Exp $
+/* $Id: malloc.c,v 1.6 2004/11/03 22:43:00 weiden Exp $
  */
 /*
  * COPYRIGHT:   None
@@ -15,6 +15,9 @@
 
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 PVOID
 STDCALL
 MemAlloc(IN HANDLE Heap,
index 38c6cee..94313c6 100644 (file)
@@ -1,6 +1,9 @@
-/* $Id: stubs.c,v 1.6 2004/11/02 23:42:49 weiden Exp $ */
+/* $Id: stubs.c,v 1.7 2004/11/03 22:43:00 weiden Exp $ */
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 #if 0
 /*
  * @unimplemented
index 975278f..f785d0b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: win32.c,v 1.11 2004/11/02 23:42:49 weiden Exp $
+/* $Id: win32.c,v 1.12 2004/11/03 22:43:00 weiden Exp $
  */
 /*
  * COPYRIGHT:   See COPYING in the top level directory
@@ -13,6 +13,9 @@
 
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 /* INTERNAL *******************************************************************/
 
 typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT
index 5f452fc..ff4cd43 100644 (file)
@@ -1,6 +1,8 @@
+#define NTOS_MODE_USER
 #include <windows.h>
 #include <psapi.h>
-#include <epsapi.h>
+#include <ntos.h>
+#include "internal.h"
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
@@ -9,5 +11,3 @@
 #include <ntos/heap.h>
 #include <ntdll/ldr.h>
 
-#define SetLastErrorByStatus(__S__) \
- ((void)SetLastError(RtlNtStatusToDosError(__S__)))