In this chapter from Windows Internals, 5th Edition, learn the data structures and algorithms that deal with processes, threads, and jobs in the Windows operating system. The first section focuses on the internal structures that make up a process. The second section outlines the steps involved in creating a process (and its initial thread). The internals of threads and thread scheduling are then described. The chapter concludes with a description of the job object.

Where relevant performance counters or kernel variables exist, they are mentioned.
Although this book isn’t a Windows programming book, the pertinent process, thread, and
job Windows functions are listed so that you can pursue additional information on their
use.

Because processes and threads touch so many components in Windows, a number of terms
and data structures (such as working sets, objects and handles, system memory heaps, and
so on) are referred to in this chapter but are explained in detail elsewhere in the
book. To fully understand this chapter, you need to be familiar with the terms and
concepts explained in Chapter 1 and Chapter 2, such as the difference between a process and a
thread, the Windows virtual address space layout, and the difference between user mode
and kernel mode.

Process Internals

This section describes the key Windows process data structures. Also listed are
key kernel variables, performance counters, and functions and tools that relate to
processes.

Data Structures

Each Windows process is represented by an executive process (EPROCESS) block.
Besides containing many attributes relating to a process, an EPROCESS block
contains and points to a number of other related data structures. For example,
each process has one or more threads represented by executive thread (ETHREAD)
blocks. (Thread data structures are explained in the section Thread Internals later in this chapter.) The EPROCESS block and
its related data structures exist in system address space, with the exception of
the process environment block (PEB), which exists in the process address space
(because it contains information that needs to be accessed by user-mode
code).

In addition to the EPROCESS block and the PEB, the Windows subsystem process
(Csrss) maintains a parallel structure for each process that is executing a
Windows program. Finally, the kernel-mode part of the Windows subsystem
(Win32k.sys) will also maintain a per-process data structure that is created the
first time a thread calls a Windows USER or GDI function that is implemented in
kernel mode.

Figure 5-1 is a simplified
diagram of the process and thread data structures. Each data structure shown in
the figure is described in detail in this chapter.

Figure 5-1. Data structures associated with processes and threads

First let’s focus on the process block. (We’ll get to the thread block in the
section Thread Internals later in the chapter.) Figure 5-2 shows the key fields in
an EPROCESS block.

Figure 5-2. Structure of an executive process block

EXPERIMENT: Displaying the Format of an EPROCESS Block

For a list of the fields that make up an EPROCESS block and their offsets
in hexadecimal, type dt _eprocess in the
kernel debugger. (See Chapter 1 for more
information on the kernel debugger and how to perform kernel debugging on
the local system.) The output (truncated for the sake of space) on a 32-bit
system looks like this:

Note that the first field (Pcb) is actually a substructure, the kernel
process block (KPROCESS), which is where scheduling-related information is
stored. To display the format of the kernel process block, type dt _kprocess:

An alternative way to see the KPROCESS (and other substructures in the
EPROCESS) is to use the recursion (–r) switch
of the dt command. For example, typing dt _eprocess –r1 will recurse and
display all substructures one level deep.

The dt command shows the format of a process block,
not its contents. To show an instance of an actual process, you can specify
the address of an EPROCESS structure as an argument to the
dt command. You can get the address of all the
EPROCESS blocks in the system by using the !process 0 0
command. An annotated example of the output from this command is included
later in this chapter.

Table 5-1 explains some of the fields
in the preceding experiment in more detail and includes references to other
places in the book where you can find more information about them. As we’ve said
before and will no doubt say again, processes and threads are such integral
parts of Windows that it’s impossible to talk about them without referring to
many other parts of the system. To keep the length of this chapter manageable,
however, we’ve covered those related subjects (such as memory management,
security, objects, and handles) elsewhere.

Table 5-1. Contents of the EPROCESS Block

Element

Purpose

Additional Reference

Kernel process (KPROCESS) block

Common dispatcher object header, pointer to the process
page directory, list of kernel thread (KTHREAD) blocks
belonging to the process, default base priority, affinity
mask, and total kernel and user time and CPU clock cycles
for the threads in the process.

Limits on processor usage, nonpaged pool, paged pool, and
page file usage plus current and peak process nonpaged and
paged pool usage. (Note: Several processes can share this
structure: all the system processes in session 0 point to a
single systemwide quota block; all other processes in
interactive sessions share a single quota block.)

Virtual address descriptors (VADs)

Series of data structures that describes the status of the
portions of the address space that exist in the
process.

Interprocess communication channel to which the process
manager sends a message when one of the process’s threads
causes an exception.

Exception dispatching (Chapter 3)

Debugging object

Executive object through which the user-mode debugging
infrastructure sends notifications when one of the process’s
threads causes a debug event.

User-mode debugging (Chapter 3)

Access token (TOKEN)

Executive object describing the security profile of this
process.

Chapter 6

Handle table

Address of per-process handle table.

Object handles and the process handle table (Chapter 3)

Device map

Address of object directory to resolve device name
references in (supports multiple users).

Object names (Chapter 3)

Process environment block (PEB)

Image information (base address, version numbers, module
list), process heap information, and thread-local storage
utilization. (Note: The pointers to the process heaps start
at the first byte after the PEB.)

Chapter 5

Windows subsystem process block (W32PROCESS)

Process details needed by the kernel-mode component of the
Windows subsystem.

The kernel process (KPROCESS) block, which is part of the EPROCESS block, and
the process environment block (PEB), which is pointed to by the EPROCESS block,
contain additional details about the process object. The KPROCESS block (which
is sometimes called the PCB or process control block) is illustrated in Figure 5-3. It contains the basic
information that the Windows kernel needs to schedule the threads inside a
process. (Page directories are covered in Chapter 9,
and kernel thread blocks are described in more detail later in this
chapter.)

The PEB, which lives in the user process address space, contains information
needed by the image loader, the heap manager, and other Windows system DLLs that
need to access it from user mode. (The EPROCESS and KPROCESS blocks are
accessible only from kernel mode.) The basic structure of the PEB is illustrated
in Figure 5-4 and is explained in
more detail later in this chapter.

Figure 5-3. Structure of the executive process block

Figure 5-4. Fields of the process environment block

EXPERIMENT: Examining the PEB

You can dump the PEB structure with the !peb command
in the kernel debugger. To get the address of the PEB, use the
!process command as follows:

Kernel Variables

A few key kernel global variables that relate to processes are listed in Table 5-2. These variables are referred
to later in the chapter, when the steps in creating a process are
described.

Table 5-2. Process-Related Kernel Variables

Element

Purpose

Additional Reference

PsActiveProcessHead

Doubly linked list

List head of process blocks

PsIdleProcess

Pointer to EPROCESS

Idle process block

PsInitialSystemProcess

Pointer to EPROCESS

Pointer to the process block of the initial system process
that contains the system threads

PspCreateProcessNotifyRoutine

Array of executive callback objects

Array of callback objects describing the routines to be
called on process creation and deletion (maximum of
eight)

PspCreateProcessNotifyRoutineCount

32-bit integer

Count of registered process notification routines

PspCreateProcessNotifyRoutineCountEx

32-bit integer

Count of registered extended process notification
routines

PspLoadImageNotifyRoutine

Array of executive callback objects

Array of callback objects describing the routines to be
called on image load (maximum of eight)

PspLoadImageNotifyRoutineCount

32-bit integer

Count of registered image-load notification
routines

PspNotifyEnableMask

32-bit integer

Mask for quickly checking whether any extended or standard
notification routines are enabled

PspCidTable

Pointer to HANDLE_TABLE

Handle table for process and thread client IDs

Performance Counters

Windows maintains a number of counters with which you can track the processes
running on your system; you can retrieve these counters programmatically or view
them with the Performance tool. Table 5-3 lists the performance
counters relevant to processes.

Table 5-3. Process-Related Performance Counters

Object: Counter

Function

Process: % Privileged Time

Describes the percentage of time that the threads in the
process have run in kernel mode during a specified
interval.

Process: % Processor Time

Describes the percentage of CPU time that the threads in
the process have used during a specified interval. This
count is the sum of % Privileged Time and % User
Time.

Process: % User Time

Describes the percentage of time that the threads in the
process have run in user mode during a specified
interval.

Process: Elapsed Time

Describes the total elapsed time in seconds since this
process was created.

Process: ID Process

Returns the process ID. This ID applies only while the
process exists because process IDs are reused.

Process: Creating Process ID

Returns the process ID of the creating process. This value
isn’t updated if the creating process exits.

Process: Thread Count

Returns the number of threads in the process.

Process: Handle Count

Returns the number of handles open in the process.

Relevant Functions

For reference purposes, some of the Windows functions that apply to processes
are described in Table 5-4. For further
information, consult the Windows API documentation in the MSDN
Library.

Table 5-4. Process-Related Functions

Function

Description

CreateProcess

Creates a new process and thread using the caller’s
security identification

CreateProcessAsUser

Creates a new process and thread with the specified
alternate security token

CreateProcessWithLogonW

Creates a new process and thread to run under the
credentials of the specified username and password

CreateProcessWithTokenW

Creates a new process and thread with the specified
alternate security token, with additional options such as
allowing the user profile to be loaded

OpenProcess

Returns a handle to the specified process object

ExitProcess

Ends a process, and notifies all attached DLLs

TerminateProcess

Ends a process without notifying the DLLs

FlushInstructionCache

Empties the specified process’s instruction cache

FlushProcessWriteBuffers

Empties the specified process’s write queue

GetProcessTimes

Obtains a process’s timing information, describing how
much time the threads inside the process spent in user and
kernel mode

QueryProcessCycleTimeCounter

Obtains a process’s CPU timing information, describing how
many clock cycles the threads inside the process have spent
in total

Query/SetProcessAffinityUpdateMode

Defines whether the process’s affinity is automatically
updated if new processors are added to the running
system

Get/SetProcessDEPPolicy

Returns or sets the DEP (Data Execution Protection) policy
for the process

GetExitCodeProcess

Returns the exit code for a process, indicating how and
why the process shut down

GetCommandLine

Returns a pointer to the command-line string passed to the
current process

QueryFullProcessImageName

Returns the full name of the executable image associated
with the process

GetCurrentProcess

Returns a pseudo handle for the current process

GetCurrentProcessId

Returns the ID of the current process

GetProcessVersion

Returns the major and minor versions of the Windows
version on which the specified process expects to run

GetStartupInfo

Returns the contents of the STARTUPINFO structure
specified during CreateProcess

GetEnvironmentStrings

Returns the address of the environment block

Get/SetEnvironmentVariable

Returns or sets a specific environment variable

Get/SetProcessShutdownParameters

Defines the shutdown priority and number of retries for
the current process

SetProcessDPIAware

Specifies whether the process is aware of dots per inch
(DPI) settings

GetGuiResources

Returns a count of User and GDI handles

EXPERIMENT: Using the Kernel Debugger !process
Command

The kernel debugger !process command displays a
subset of the information in an EPROCESS block. This output is arranged in
two parts for each process. First you see the information about the process,
as shown here (when you don’t specify a process address or ID,
!process lists information for the active process
on the current CPU):

After the basic process output comes a list of the threads in the process.
That output is explained in the EXPERIMENT: Using the Kernel Debugger !thread
Command section later in
the chapter. Other commands that display process information include
!handle, which dumps the process handle table
(which is described in more detail in the section Object Handles and the Process Handle Table in Chapter 3). Process and thread security structures
are described in Chapter 6.