ReactOS  0.4.14-dev-384-g5b37caa
processes.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * LICENSE: See LGPL.txt in the top level directory
4  * PROJECT: ReactOS system libraries
5  * FILE: reactos/lib/epsapi/enum/processes.c
6  * PURPOSE: Enumerate processes and threads
7  * PROGRAMMER: KJK::Hyperion <noog@libero.it>
8  * UPDATE HISTORY:
9  * 10/06/2002: Created
10  * 29/08/2002: Generalized the interface to improve reusability,
11  * more efficient use of memory operations
12  * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree,
13  * for better reusability. PsaEnumerateProcesses now
14  * expanded into:
15  * - PsaCaptureProcessesAndThreads
16  * - PsaFreeCapture
17  * - PsaWalkProcessesAndThreads
18  * - PsaWalkProcesses
19  * - PsaWalkThreads
20  * - PsaWalkFirstProcess
21  * - PsaWalkNextProcess
22  * - PsaWalkFirstThread
23  * - PsaWalkNextThread
24  * - PsaEnumerateProcessesAndThreads
25  * - PsaEnumerateProcesses
26  * - PsaEnumerateThreads
27  * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and
28  * isolated in its own library to clear the confusion
29  * and improve reusability
30  */
31 
32 #include "precomp.h"
33 
34 #define NDEBUG
35 #include <debug.h>
36 
39 {
40  PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
41  SIZE_T nSize = 0x8000;
43 
44  if(ProcessesAndThreads == NULL)
45  {
47  }
48 
49  /* FIXME: if the system has loaded several processes and threads, the buffer
50  could get really big. But if there's several processes and threads, the
51  system is already under stress, and a huge buffer could only make things
52  worse. The function should be profiled to see what's the average minimum
53  buffer size, to succeed on the first shot */
54  do
55  {
56  PVOID pTmp;
57 
58  /* free the buffer, and reallocate it to the new size. RATIONALE: since we
59  ignore the buffer's contents at this point, there's no point in a realloc()
60  that could end up copying a large chunk of data we'd discard anyway */
61  PsaiFree(pInfoBuffer);
62  pTmp = PsaiMalloc(nSize);
63 
64  if(pTmp == NULL)
65  {
68  break;
69  }
70 
71  pInfoBuffer = pTmp;
72 
73  /* query the information */
75  pInfoBuffer,
76  nSize,
77  NULL);
78 
79  /* double the buffer size */
80  nSize *= 2;
82 
83  if(!NT_SUCCESS(Status))
84  {
85  DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", Status);
86  return Status;
87  }
88 
89  *ProcessesAndThreads = pInfoBuffer;
90  return STATUS_SUCCESS;
91 }
92 
95  IN PPROC_ENUM_ROUTINE ProcessCallback,
96  IN OUT PVOID ProcessCallbackContext,
98  IN OUT PVOID ThreadCallbackContext)
99 {
101 
102  if(ProcessCallback == NULL && ThreadCallback == NULL)
103  {
105  }
106 
108 
109  ProcessesAndThreads = PsaWalkFirstProcess(ProcessesAndThreads);
110 
111  /* scan the process list */
112  do
113  {
114  if(ProcessCallback)
115  {
116  Status = ProcessCallback(ProcessesAndThreads, ProcessCallbackContext);
117 
118  if(!NT_SUCCESS(Status))
119  {
120  break;
121  }
122  }
123 
124  /* if the caller provided a thread callback */
125  if(ThreadCallback)
126  {
127  ULONG i;
128  PSYSTEM_THREAD_INFORMATION pCurThread;
129 
130  /* scan the current process's thread list */
131  for(i = 0, pCurThread = PsaWalkFirstThread(ProcessesAndThreads);
132  i < ProcessesAndThreads->NumberOfThreads;
133  i++, pCurThread = PsaWalkNextThread(pCurThread))
134  {
135  Status = ThreadCallback(pCurThread, ThreadCallbackContext);
136 
137  if(!NT_SUCCESS(Status))
138  {
139  goto Bail;
140  }
141  }
142  }
143 
144  /* move to the next process */
145  ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads);
146  } while(ProcessesAndThreads);
147 
148 Bail:
149  return Status;
150 }
151 
154  IN OUT PVOID ProcessCallbackContext,
156  IN OUT PVOID ThreadCallbackContext)
157 {
158  PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
160 
161  if(ProcessCallback == NULL && ThreadCallback == NULL)
162  {
164  }
165 
166  /* get the processes and threads list */
167  Status = PsaCaptureProcessesAndThreads(&pInfoBuffer);
168 
169  if(!NT_SUCCESS(Status))
170  {
171  goto Bail;
172  }
173 
174  /* walk the processes and threads list */
175  Status = PsaWalkProcessesAndThreads(pInfoBuffer,
176  ProcessCallback,
177  ProcessCallbackContext,
179  ThreadCallbackContext);
180 
181 Bail:
182  PsaFreeCapture(pInfoBuffer);
183 
184  return Status;
185 }
186 
187 VOID NTAPI
189 {
190  PsaiFree(Capture);
191 }
192 
197 {
198  return PsaWalkProcessesAndThreads(ProcessesAndThreads,
199  Callback,
201  NULL,
202  NULL);
203 }
204 
209 {
210  return PsaWalkProcessesAndThreads(ProcessesAndThreads,
211  NULL,
212  NULL,
213  Callback,
215 }
216 
220 {
223  NULL,
224  NULL);
225 }
226 
230 {
232  NULL,
233  Callback,
235 }
236 
239 {
240  return ProcessesAndThreads;
241 }
242 
245 {
246  if(CurrentProcess->NextEntryOffset == 0)
247  {
248  return NULL;
249  }
250  else
251  {
253  }
254 }
255 
258 {
259  static SIZE_T nOffsetOfThreads = 0;
260 
261  /* get the offset of the Threads field */
262  nOffsetOfThreads = sizeof(SYSTEM_PROCESS_INFORMATION);
263 
264  return (PSYSTEM_THREAD_INFORMATION)((ULONG_PTR)CurrentProcess + nOffsetOfThreads);
265 }
266 
269 {
270  return (PSYSTEM_THREAD_INFORMATION)((ULONG_PTR)CurrentThread +
272  sizeof(SYSTEM_PROCESS_INFORMATION)));
273 }
274 
275 /* EOF */
VOID NTAPI PsaFreeCapture(IN PVOID Capture)
Definition: processes.c:188
#define IN
Definition: typedefs.h:38
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI PsaEnumerateThreads(IN PTHREAD_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext)
Definition: processes.c:228
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2031
LONG NTSTATUS
Definition: precomp.h:26
void * PsaiMalloc(SIZE_T size)
Definition: ctm.c:101
#define FASTCALL
Definition: nt_native.h:50
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PSYSTEM_THREAD_INFORMATION FASTCALL PsaWalkFirstThread(IN PSYSTEM_PROCESS_INFORMATION CurrentProcess)
Definition: processes.c:257
PSYSTEM_THREAD_INFORMATION FASTCALL PsaWalkNextThread(IN PSYSTEM_THREAD_INFORMATION CurrentThread)
Definition: processes.c:268
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
ULONG CurrentProcess
Definition: shell.c:125
NTSTATUS NTAPI PsaWalkProcessesAndThreads(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads, IN PPROC_ENUM_ROUTINE ProcessCallback, IN OUT PVOID ProcessCallbackContext, IN PTHREAD_ENUM_ROUTINE ThreadCallback, IN OUT PVOID ThreadCallbackContext)
Definition: processes.c:94
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION
NTSTATUS NTAPI PsaEnumerateProcessesAndThreads(IN PPROC_ENUM_ROUTINE ProcessCallback, IN OUT PVOID ProcessCallbackContext, IN PTHREAD_ENUM_ROUTINE ThreadCallback, IN OUT PVOID ThreadCallbackContext)
Definition: processes.c:153
void PsaiFree(void *ptr)
Definition: ctm.c:103
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI PsaEnumerateProcesses(IN PPROC_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext)
Definition: processes.c:218
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSTATUS NTAPI PsaWalkProcesses(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads, IN PPROC_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext)
Definition: processes.c:194
NTSTATUS NTAPI PsaCaptureProcessesAndThreads(OUT PSYSTEM_PROCESS_INFORMATION *ProcessesAndThreads)
Definition: processes.c:38
NTSTATUS NTAPI(* PTHREAD_ENUM_ROUTINE)(IN PSYSTEM_THREADS CurrentThread, IN OUT PVOID CallbackContext)
Definition: test.h:76
NTSTATUS NTAPI(* PPROC_ENUM_ROUTINE)(IN PSYSTEM_PROCESSES CurrentProcess, IN OUT PVOID CallbackContext)
Definition: test.h:70
#define FAILED_WITH_STATUS
Definition: test.h:95
PSYSTEM_PROCESS_INFORMATION FASTCALL PsaWalkNextProcess(IN PSYSTEM_PROCESS_INFORMATION CurrentProcess)
Definition: processes.c:244
PSYSTEM_PROCESS_INFORMATION FASTCALL PsaWalkFirstProcess(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads)
Definition: processes.c:238
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI PsaWalkThreads(IN PSYSTEM_PROCESS_INFORMATION ProcessesAndThreads, IN PTHREAD_ENUM_ROUTINE Callback, IN OUT PVOID CallbackContext)
Definition: processes.c:206
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
return STATUS_SUCCESS
Definition: btrfs.c:2938
LPFNPSPCALLBACK Callback
Definition: desk.c:111