ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

processes.c
Go to the documentation of this file.
00001 /* $Id: processes.c 52985 2011-07-28 16:21:48Z akhaldi $
00002 */
00003 /*
00004  * COPYRIGHT:   See COPYING in the top level directory
00005  * LICENSE:     See LGPL.txt in the top level directory
00006  * PROJECT:     ReactOS system libraries
00007  * FILE:        reactos/lib/epsapi/enum/processes.c
00008  * PURPOSE:     Enumerate processes and threads
00009  * PROGRAMMER:  KJK::Hyperion <noog@libero.it>
00010  * UPDATE HISTORY:
00011  *              10/06/2002: Created
00012  *              29/08/2002: Generalized the interface to improve reusability,
00013  *                          more efficient use of memory operations
00014  *              12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
00015  *                          for better reusability. PsaEnumerateProcesses now
00016  *                          expanded into:
00017  *                           - PsaCaptureProcessesAndThreads
00018  *                           - PsaFreeCapture
00019  *                           - PsaWalkProcessesAndThreads
00020  *                           - PsaWalkProcesses
00021  *                           - PsaWalkThreads
00022  *                           - PsaWalkFirstProcess
00023  *                           - PsaWalkNextProcess
00024  *                           - PsaWalkFirstThread
00025  *                           - PsaWalkNextThread
00026  *                           - PsaEnumerateProcessesAndThreads
00027  *                           - PsaEnumerateProcesses
00028  *                           - PsaEnumerateThreads
00029  *              12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
00030  *                          isolated in its own library to clear the confusion
00031  *                          and improve reusability
00032  */
00033 
00034 #include "precomp.h"
00035 
00036 #define NDEBUG
00037 #include <debug.h>
00038 
00039 NTSTATUS NTAPI
00040 PsaCaptureProcessesAndThreads(OUT PSYSTEM_PROCESS_INFORMATION *ProcessesAndThreads)
00041 {
00042   PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
00043   SIZE_T nSize = 0x8000;
00044   NTSTATUS Status;
00045 
00046   if(ProcessesAndThreads == NULL)
00047   {
00048     return STATUS_INVALID_PARAMETER_1;
00049   }
00050 
00051   /* FIXME: if the system has loaded several processes and threads, the buffer
00052             could get really big. But if there's several processes and threads, the
00053             system is already under stress, and a huge buffer could only make things
00054             worse. The function should be profiled to see what's the average minimum
00055             buffer size, to succeed on the first shot */
00056   do
00057   {
00058     PVOID pTmp;
00059 
00060     /* free the buffer, and reallocate it to the new size. RATIONALE: since we
00061        ignore the buffer's contents at this point, there's no point in a realloc()
00062        that could end up copying a large chunk of data we'd discard anyway */
00063     PsaiFree(pInfoBuffer);
00064     pTmp = PsaiMalloc(nSize);
00065 
00066     if(pTmp == NULL)
00067     {
00068       DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", STATUS_NO_MEMORY);
00069       Status = STATUS_NO_MEMORY;
00070       break;
00071     }
00072 
00073     pInfoBuffer = pTmp;
00074 
00075     /* query the information */
00076     Status = NtQuerySystemInformation(SystemProcessInformation,
00077                                       pInfoBuffer,
00078                                       nSize,
00079                                       NULL);
00080 
00081     /* double the buffer size */
00082     nSize *= 2;
00083   } while(Status == STATUS_INFO_LENGTH_MISMATCH);
00084 
00085   if(!NT_SUCCESS(Status))
00086   {
00087     DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status);
00088     return Status;
00089   }
00090 
00091   *ProcessesAndThreads = pInfoBuffer;
00092   return STATUS_SUCCESS;
00093 }
00094 
00095 NTSTATUS NTAPI
00096 PsaWalkProcessesAndThreads(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads,
00097                            IN PPROC_ENUM_ROUTINE ProcessCallback,
00098                            IN OUT PVOID ProcessCallbackContext,
00099                            IN PTHREAD_ENUM_ROUTINE ThreadCallback,
00100                            IN OUT PVOID ThreadCallbackContext)
00101 {
00102   NTSTATUS Status;
00103 
00104   if(ProcessCallback == NULL && ThreadCallback == NULL)
00105   {
00106     return STATUS_INVALID_PARAMETER;
00107   }
00108 
00109   Status = STATUS_SUCCESS;
00110 
00111   ProcessesAndThreads = PsaWalkFirstProcess(ProcessesAndThreads);
00112 
00113   /* scan the process list */
00114   do
00115   {
00116     if(ProcessCallback)
00117     {
00118       Status = ProcessCallback(ProcessesAndThreads, ProcessCallbackContext);
00119 
00120       if(!NT_SUCCESS(Status))
00121       {
00122         break;
00123       }
00124     }
00125 
00126     /* if the caller provided a thread callback */
00127     if(ThreadCallback)
00128     {
00129       ULONG i;
00130       PSYSTEM_THREAD_INFORMATION pCurThread;
00131 
00132       /* scan the current process's thread list */
00133       for(i = 0, pCurThread = PsaWalkFirstThread(ProcessesAndThreads);
00134           i < ProcessesAndThreads->NumberOfThreads;
00135           i++, pCurThread = PsaWalkNextThread(pCurThread))
00136       {
00137         Status = ThreadCallback(pCurThread, ThreadCallbackContext);
00138 
00139         if(!NT_SUCCESS(Status))
00140         {
00141           goto Bail;
00142         }
00143       }
00144     }
00145 
00146     /* move to the next process */
00147     ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads);
00148   } while(ProcessesAndThreads);
00149 
00150 Bail:
00151   return Status;
00152 }
00153 
00154 NTSTATUS NTAPI
00155 PsaEnumerateProcessesAndThreads(IN PPROC_ENUM_ROUTINE ProcessCallback,
00156                                 IN OUT PVOID ProcessCallbackContext,
00157                                 IN PTHREAD_ENUM_ROUTINE ThreadCallback,
00158                                 IN OUT PVOID ThreadCallbackContext)
00159 {
00160   PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
00161   NTSTATUS Status;
00162 
00163   if(ProcessCallback == NULL && ThreadCallback == NULL)
00164   {
00165     return STATUS_INVALID_PARAMETER;
00166   }
00167 
00168   /* get the processes and threads list */
00169   Status = PsaCaptureProcessesAndThreads(&pInfoBuffer);
00170 
00171   if(!NT_SUCCESS(Status))
00172   {
00173     goto Bail;
00174   }
00175 
00176   /* walk the processes and threads list */
00177   Status = PsaWalkProcessesAndThreads(pInfoBuffer,
00178                                       ProcessCallback,
00179                                       ProcessCallbackContext,
00180                                       ThreadCallback,
00181                                       ThreadCallbackContext);
00182 
00183 Bail:
00184   PsaFreeCapture(pInfoBuffer);
00185 
00186   return Status;
00187 }
00188 
00189 VOID NTAPI
00190 PsaFreeCapture(IN PVOID Capture)
00191 {
00192   PsaiFree(Capture);
00193 }
00194 
00195 NTSTATUS NTAPI
00196 PsaWalkProcesses(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads,
00197                  IN PPROC_ENUM_ROUTINE Callback,
00198                  IN OUT PVOID CallbackContext)
00199 {
00200   return PsaWalkProcessesAndThreads(ProcessesAndThreads,
00201                                     Callback,
00202                                     CallbackContext,
00203                                     NULL,
00204                                     NULL);
00205 }
00206 
00207 NTSTATUS NTAPI
00208 PsaWalkThreads(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads,
00209                IN PTHREAD_ENUM_ROUTINE Callback,
00210                IN OUT PVOID CallbackContext)
00211 {
00212   return PsaWalkProcessesAndThreads(ProcessesAndThreads,
00213                                     NULL,
00214                                     NULL,
00215                                    Callback,
00216                                    CallbackContext);
00217 }
00218 
00219 NTSTATUS NTAPI
00220 PsaEnumerateProcesses(IN PPROC_ENUM_ROUTINE Callback,
00221                       IN OUT PVOID CallbackContext)
00222 {
00223   return PsaEnumerateProcessesAndThreads(Callback,
00224                                          CallbackContext,
00225                                          NULL,
00226                                          NULL);
00227 }
00228 
00229 NTSTATUS NTAPI
00230 PsaEnumerateThreads(IN PTHREAD_ENUM_ROUTINE Callback,
00231                     IN OUT PVOID CallbackContext)
00232 {
00233   return PsaEnumerateProcessesAndThreads(NULL,
00234                                          NULL,
00235                                          Callback,
00236                                          CallbackContext);
00237 }
00238 
00239 PSYSTEM_PROCESS_INFORMATION FASTCALL
00240 PsaWalkFirstProcess(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads)
00241 {
00242   return ProcessesAndThreads;
00243 }
00244 
00245 PSYSTEM_PROCESS_INFORMATION FASTCALL
00246 PsaWalkNextProcess(IN PSYSTEM_PROCESS_INFORMATION CurrentProcess)
00247 {
00248   if(CurrentProcess->NextEntryOffset == 0)
00249   {
00250     return NULL;
00251   }
00252   else
00253   {
00254     return (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)CurrentProcess + CurrentProcess->NextEntryOffset);
00255   }
00256 }
00257 
00258 PSYSTEM_THREAD_INFORMATION FASTCALL
00259 PsaWalkFirstThread(IN PSYSTEM_PROCESS_INFORMATION CurrentProcess)
00260 {
00261   static SIZE_T nOffsetOfThreads = 0;
00262 
00263   /* get the offset of the Threads field */
00264   nOffsetOfThreads = sizeof(SYSTEM_PROCESS_INFORMATION);
00265 
00266   return (PSYSTEM_THREAD_INFORMATION)((ULONG_PTR)CurrentProcess + nOffsetOfThreads);
00267 }
00268 
00269 PSYSTEM_THREAD_INFORMATION FASTCALL
00270 PsaWalkNextThread(IN PSYSTEM_THREAD_INFORMATION CurrentThread)
00271 {
00272   return (PSYSTEM_THREAD_INFORMATION)((ULONG_PTR)CurrentThread +
00273                            ((sizeof(SYSTEM_PROCESS_INFORMATION) + sizeof(SYSTEM_THREAD_INFORMATION)) -
00274                             sizeof(SYSTEM_PROCESS_INFORMATION)));
00275 }
00276 
00277 /* EOF */

Generated on Sat May 19 2012 04:34:07 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.