4 * COPYRIGHT: See COPYING in the top level directory
5 * LICENSE: See LGPL.txt in the top level directory
6 * PROJECT: ReactOS system libraries
7 * FILE: reactos/lib/psapi/enum/process.c
8 * PURPOSE: Enumerate processes
9 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
12 * 29/08/2002: Generalized the interface to improve reusability,
13 * more efficient use of memory operations
17 #include <ddk/ntddk.h>
19 #include <internal/psapi.h>
25 IN PPROC_ENUM_ROUTINE Callback,
26 IN OUT PVOID CallbackContext
29 register NTSTATUS nErrCode = STATUS_SUCCESS;
30 PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL;
31 PSYSTEM_PROCESS_INFORMATION pInfoHead = NULL;
34 /* FIXME: if the system has loaded several processes and threads, the buffer
35 could get really big. But if there's several processes and threads, the
36 system is already under stress, and a huge buffer could only make things
37 worse. The function should be profiled to see what's the average minimum
38 buffer size, to succeed on the first shot */
43 /* free the buffer, and reallocate it to the new size. RATIONALE: since we
44 ignore the buffer's contents at this point, there's no point in a realloc()
45 that could end up copying a large chunk of data we'd discard anyway */
52 DPRINT(FAILED_WITH_STATUS, "malloc", STATUS_NO_MEMORY);
53 nErrCode = STATUS_NO_MEMORY;
59 /* query the information */
60 nErrCode = NtQuerySystemInformation
62 SystemProcessesAndThreadsInformation,
68 /* double the buffer size */
71 /* repeat until the buffer is big enough */
72 while(nErrCode == STATUS_INFO_LENGTH_MISMATCH);
75 if(!NT_SUCCESS(nErrCode))
77 DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode);
82 pInfoHead = pInfoBuffer;
87 /* notify the callback */
88 nErrCode = Callback(pInfoHead, CallbackContext);
90 /* if the callback returned an error or this is the end of the process list,
92 if(!NT_SUCCESS(nErrCode) || pInfoHead->RelativeOffset == 0)
95 /* move to the next process */
97 (SYSTEM_PROCESS_INFORMATION*)
98 ((ULONG)pInfoHead + pInfoHead->RelativeOffset);
102 /* free the buffer */
105 /* return the last status */