PEPROCESS
PsGetNextProcess (
IN PEPROCESS Process
)
/*++
Routine Description:
This function allows code to enumerate all the active processes in the system.
The first process (if Process is NULL) or subsequent process (if process not NULL) is returned on
each call.
If process is not NULL then this process must have previously been obtained by a call to PsGetNextProcess.
Enumeration may be terminated early by calling PsQuitNextProcess on the last non-NULL process
returned by PsGetNextProcess.
Processes may be referenced and used later safely.
For example, to enumerate all system processes in a loop use this code fragment:
for (Process = PsGetNextProcess (NULL);
Process != NULL;
Process = PsGetNextProcess (Process)) {
...
...
//
// Early terminating conditions are handled like this:
//
if (NeedToBreakOutEarly) {
PsQuitNextProcess (Process);
break;
}
}
Arguments:
Process - Process to get the next process from or NULL for the first process
Return Value:
PEPROCESS - Next process or NULL if no more processes available
--*/
{
PEPROCESS NewProcess = NULL;
PETHREAD CurrentThread;
PLIST_ENTRY ListEntry;
CurrentThread = PsGetCurrentThread ();
PspLockProcessList (CurrentThread);
for (ListEntry = (Process == NULL) ? PsActiveProcessHead.Flink : Process->ActiveProcessLinks.Flink;
ListEntry != &PsActiveProcessHead;
ListEntry = ListEntry->Flink) {
NewProcess = CONTAINING_RECORD (ListEntry, EPROCESS, ActiveProcessLinks);
//
// Processes are removed from this list during process objected deletion (object reference count goes
// to zero). To prevent double deletion of the process we need to do a safe reference here.
//
if (ObReferenceObjectSafe (NewProcess)) {
break;
}
NewProcess = NULL;
}
PspUnlockProcessList (CurrentThread);
if (Process != NULL) {
ObDereferenceObject (Process);
}
return NewProcess;
}