Commit in reactos on MAIN
Makefile+2-21.257 -> 1.258
lib/psapi/internal.h+1-1101.1 -> 1.2
         /makefile+2-51.13 -> 1.14
         /precomp.h+11.2 -> 1.3
lib/epsapi/enum/.cvsignore+2added 1.1
               /drivers.c+1951.3 -> 1.4
               /modules.c+1491.3 -> 1.4
               /processes.c+3021.2 -> 1.3
lib/epsapi/makefile+201.4 -> 1.5
lib/psapi/enum/.cvsignore-21.1 removed
              /drivers.c-1911.3 removed
              /modules.c-1461.1 removed
              /processes.c-3011.1 removed
+674-757
1 added + 4 removed + 8 modified, total 13 files
separate epsapi as per kjk's request again, sorry for that.

reactos
Makefile 1.257 -> 1.258
diff -u -r1.257 -r1.258
--- Makefile	3 Nov 2004 22:42:59 -0000	1.257
+++ Makefile	8 Nov 2004 00:34:45 -0000	1.258
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.257 2004/11/03 22:42:59 weiden Exp $
+# $Id: Makefile,v 1.258 2004/11/08 00:34:45 weiden Exp $
 #
 # Global makefile
 #
@@ -38,7 +38,7 @@
 LIB_FSLIB = vfatlib
 
 # Static libraries
-LIB_STATIC = string rosrtl uuid libwine zlib rtl tgetopt pseh adns
+LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt pseh adns
 
 # Keyboard layout libraries
 DLLS_KBD = kbddv kbdfr kbdgr kbdse kbduk kbdus

reactos/lib/psapi
internal.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- internal.h	3 Nov 2004 22:42:59 -0000	1.1
+++ internal.h	8 Nov 2004 00:34:45 -0000	1.2
@@ -1,4 +1,4 @@
-/* $Id: internal.h,v 1.1 2004/11/03 22:42:59 weiden Exp $
+/* $Id: internal.h,v 1.2 2004/11/08 00:34:45 weiden Exp $
 */
 /*
  * epsapi.h
@@ -30,115 +30,6 @@
  ((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 */

reactos/lib/psapi
makefile 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- makefile	4 Nov 2004 22:14:41 -0000	1.13
+++ makefile	8 Nov 2004 00:34:45 -0000	1.14
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.13 2004/11/04 22:14:41 weiden Exp $
+# $Id: makefile,v 1.14 2004/11/08 00:34:45 weiden Exp $
 
 PATH_TO_TOP = ../..
 
@@ -6,7 +6,7 @@
 
 TARGET_NAME = psapi
 
-TARGET_SDKLIBS = ntdll.a kernel32.a
+TARGET_SDKLIBS = epsapi.a ntdll.a kernel32.a
 
 TARGET_CFLAGS = -I./include -Wall -Werror
 
@@ -20,9 +20,6 @@
 TARGET_PCH = precomp.h
 
 TARGET_OBJECTS = \
-	enum/drivers.o \
-	enum/modules.o \
-	enum/processes.o \
 	misc/dllmain.o \
 	misc/malloc.o \
 	misc/stubs.o \

reactos/lib/psapi
precomp.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- precomp.h	3 Nov 2004 22:42:59 -0000	1.2
+++ precomp.h	8 Nov 2004 00:34:45 -0000	1.3
@@ -1,6 +1,7 @@
 #define NTOS_MODE_USER
 #include <windows.h>
 #include <psapi.h>
+#include <epsapi.h>
 #include <ntos.h>
 #include "internal.h"
 #include <stddef.h>

reactos/lib/epsapi/enum
.cvsignore added at 1.1
diff -N .cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .cvsignore	8 Nov 2004 00:34:45 -0000	1.1
@@ -0,0 +1,2 @@
+*.o
+.*.d
\ No newline at end of file

reactos/lib/epsapi/enum
drivers.c 1.3 -> 1.4
diff -N drivers.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ drivers.c	8 Nov 2004 00:34:45 -0000	1.4
@@ -0,0 +1,195 @@
+/* $Id: drivers.c,v 1.4 2004/11/08 00:34:45 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 <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)
+{
+  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 */

reactos/lib/epsapi/enum
modules.c 1.3 -> 1.4
diff -N modules.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules.c	8 Nov 2004 00:34:46 -0000	1.4
@@ -0,0 +1,149 @@
+/* $Id: modules.c,v 1.4 2004/11/08 00:34:46 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
+ */
+
+#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)
+{
+  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 */

reactos/lib/epsapi/enum
processes.c 1.2 -> 1.3
diff -N processes.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ processes.c	8 Nov 2004 00:34:46 -0000	1.3
@@ -0,0 +1,302 @@
+/* $Id: processes.c,v 1.3 2004/11/08 00:34:46 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 <ddk/ntddk.h>
+#include <debug.h>
+#include <stddef.h>
+
+#include <epsapi.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 */

reactos/lib/epsapi
makefile 1.4 -> 1.5
diff -N makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ makefile	8 Nov 2004 00:34:46 -0000	1.5
@@ -0,0 +1,20 @@
+# $Id: makefile,v 1.5 2004/11/08 00:34:46 weiden 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
+

reactos/lib/psapi/enum
.cvsignore removed after 1.1
diff -N .cvsignore
--- .cvsignore	3 Nov 2004 22:43:00 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2 +0,0 @@
-*.o
-.*.d
\ No newline at end of file

reactos/lib/psapi/enum
drivers.c removed after 1.3
diff -N drivers.c
--- drivers.c	3 Nov 2004 22:43:00 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,191 +0,0 @@
-/* $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 */

reactos/lib/psapi/enum
modules.c removed after 1.1
diff -N modules.c
--- modules.c	3 Nov 2004 22:43:00 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,146 +0,0 @@
-/* $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 */

reactos/lib/psapi/enum
processes.c removed after 1.1
diff -N processes.c
--- processes.c	3 Nov 2004 22:43:00 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,301 +0,0 @@
-/* $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 */
CVSspam 0.2.8