Windows XP Object Manager Namespaces and Handles
In Windows XP, the Object Manager acts as the centralized subsystem responsible for creating, tracking, securing, and destroying operating system resources such as files, threads, events, and registry keys. This article explores how the Windows XP Object Manager utilized a unified, hierarchical namespace alongside per-process handle tables to track and maintain system resource handles, manage multi-session environments via Fast User Switching, and guarantee memory and access security across the operating system.
The Hierarchical Object Manager Namespace
The Object Manager maintains resources in an internal directory structure similar to a virtual file system. Rather than exposing internal kernel structures directly to user-mode applications, Windows XP organizes resources under root directories such as:
\Device: Hardware and virtual device objects.\Driver: Loaded device drivers.\KernelObjects: Low-level synchronization primitives.\BaseNamedObjects: Common Win32 synchronization objects (events, mutexes, semaphores).\DosDevices: Drive letters and symbolic links for backward compatibility with MS-DOS and Win32 device naming conventions.
When an application requests a resource by name, the Object Manager traverses this internal namespace tree. If the target resource exists, it verifies security permissions before returning an opaque handle.
Session Separation and Symbolic Links
Windows XP introduced Terminal Services integration into the consumer
desktop through Fast User Switching. To prevent namespace collisions
between distinct user sessions, the Object Manager segmented the
\BaseNamedObjects directory into session-specific
namespaces.
Global system resources reside in \BaseNamedObjects,
while interactive user sessions operate inside dynamic directories, such
as \Sessions\1\BaseNamedObjects. The Object Manager
achieves this transparency through symbolic links and handle
translation:
- Resolution via Symbolic Link: When a process in
Session 1 requests a named object (for example,
MyMutex), the Object Manager resolves the path using a process-specific alias pointing to\Sessions\1\BaseNamedObjects\MyMutex. - Global Namespace Escape: Applications requiring
cross-session access explicitly prefix names with
Global\, routing the request to the shared root\BaseNamedObjects. Session-local objects use theLocal\prefix.
The Structure of System Resource Handles
User-mode processes do not hold direct pointers to kernel objects.
Instead, they receive a HANDLE, which is an indirect index
into a private, per-process handle table maintained by the kernel.
The Process Handle Table
Each process possesses an executive process block
(EPROCESS) containing a pointer to its
HANDLE_TABLE. In Windows XP, this table is implemented as a
multilevel array to conserve memory:
- A single-level table handles up to 512 entries.
- If a process allocates more handles, the table dynamically expands to a two-level or three-level hierarchy.
Each handle table entry (HANDLE_TABLE_ENTRY)
contains:
- A pointer to the object's
OBJECT_HEADERstructure. - An access mask detailing the granted access rights (such as
GENERIC_READorSYNCHRONIZE) determined at creation time. - Flags controlling properties like handle inheritance
(
OBJ_INHERIT) and protection against closing (OBJ_PROTECT_CLOSE).
Because handles are indexes into a private table, a handle value of
0x00000004 in Process A refers to a completely different
resource than 0x00000004 in Process B, isolating processes
from one another.
Reference Counting and Lifetime Management
Every resource managed by the Object Manager is encapsulated within
an OBJECT_HEADER followed by its object-specific body. The
header tracks the object's lifecycle using two distinct counters:
- Handle Count: The number of open handles pointing to the object across all active process handle tables.
- Pointer Count: The total number of references to the object, including open handles and direct pointers held internally by kernel-mode drivers or subsystems.
When a process calls CloseHandle, the Object Manager
locates the entry in the calling process's handle table, invalidates it,
and decrements the object's Handle Count.
When the Handle Count reaches zero, the named object is removed from the Object Manager namespace. However, the underlying memory is retained until the Pointer Count also reaches zero, guaranteeing that the kernel does not release memory that an active driver thread is currently referencing.