The Big Picture: Everything Is an Object
Windows has hundreds of different resources: files, processes, threads, locks, timers, registry keys, memory blocks. If every kind had its own naming, counting, security and cleanup code, the OS would be a huge mess. So NT uses one trick: treat them all as objects and let one manager, the Object Manager, handle the common work.
Think of a library. Books, DVDs and magazines are different things, but the library gives each one a catalogue number, tracks who has borrowed it, checks your library card, and takes it off the shelf when no one needs it. The Object Manager is that library system for Windows resources.
6.1 Unified Object Model
What it is: In NT, a kernel object is a block of kernel memory that stands for one resource. Each object has a small header with the same standard fields, plus a body that is different for each type.
┌───────────────────────────────┐
│ OBJECT HEADER (same for all) │
│ - type │
│ - reference count │
│ - name (optional) │
│ - security descriptor (ACL) │
├───────────────────────────────┤
│ OBJECT BODY (type-specific) │
│ e.g. process data, file data │
└───────────────────────────────┘
What the Object Manager does for every object:
| Common job | Meaning |
|---|---|
| Creating and naming | Gives objects a type and (if wanted) a name |
| Reference counting | Counts how many users an object has. When the count falls to zero, the object is deleted. This prevents leaks and "use after delete" |
| Security | Checks the ACL (with the SRM, Section 3.4) before giving access |
| Lifetime | Keeps the object alive while any handle or kernel pointer needs it |
| Lookup | Finds an object by name |
Why this is clever. Because the security check and the counting are written once, they work the same for a file, a process or an event. A program can wait for a process to end or an event to be set using the same function (WaitForSingleObject), since both are objects.
Not every Windows thing is a kernel object. Windows, buttons and menus belong to the user object and GDI object families, managed by win32k. In this section "object" means a kernel object.
6.2 Handles (References to Objects)
What it is: A handle is a small number that a process uses to point at an object. A process never gets a raw pointer to a kernel object (it is in the kernel half, off limits). It gets a handle.
Analogy. A cloakroom ticket. You hand in your coat (the object stays in the cloakroom), and you get ticket number 42. Every time you want the coat, you show ticket 42. Another person's ticket 42 (in their own cloakroom) points to a different coat.
How it works.
Process A Kernel
┌────────────────┐ ┌─────────────────────┐
│ handle table │ │ object: Event "X" │
│ 0x4C → ───────┼────────►│ ref count: 2 │
│ 0x50 → file │ └─────────────────────┘
└────────────────┘ ▲
Process B │
┌────────────────┐ │
│ handle table │ │
│ 0x88 → ───────┼──────────────────┘
└────────────────┘
- Each process has its own handle table. Handle
0x4Cin one process means nothing in another. - A handle records what access was granted (for example read only). The SRM checked this when the handle was opened, so later uses are fast.
- Two processes can hold handles to the same object (as above: both point to Event "X"). This is how they share and signal each other.
CloseHandleremoves the ticket and lowers the object's reference count.
Opening and duplicating. Functions like CreateFile, OpenProcess or CreateEvent return handles. DuplicateHandle copies a handle (even into another process). A child process can inherit handles from its parent if the parent marked them inheritable.
Handle leaks. If a program keeps opening handles and never closes them, its handle count rises and memory is wasted. This is called a handle leak, a typical bug.
Windows tip: Task Manager → Details tab → right-click a header → Select columns → Handles. Process Explorer's lower pane in Handles view lists each handle and the object it points to.
6.3 Object Types
What it is: Each object belongs to a type. The type tells the Object Manager what the body looks like and which operations are allowed.
Common object types:
| Type | What it represents | User-level example |
|---|---|---|
| Process | A running program | OpenProcess |
| Thread | A line of execution | CreateThread |
| File | An open file or device | CreateFile |
| Key | A registry key | RegOpenKeyEx |
| Event | A signal flag that threads wait for | CreateEvent |
| Mutant (mutex) | A lock so only one thread enters | CreateMutex |
| Semaphore | A counted lock | CreateSemaphore |
| Section | A block of memory that can be shared or backed by a file | File mapping |
| Token | An access token (the ID badge) | OpenProcessToken |
| Timer | Fires after a delay | CreateWaitableTimer |
| Job | A group of processes managed together | CreateJobObject |
| SymbolicLink | A name that points to another name | Drive letters (below) |
| Directory | A folder of objects in the object namespace | Section 6.4 |
| Device / Driver | A device and its driver | Section 2.4 |
The odd name "Mutant". The internal name of a mutex object is Mutant. You will see it in tools such as Process Explorer or WinObj. Just remember: mutant = mutex.
What a type defines. Each type has a small set of methods (functions) such as "what to do on close" or "how to delete". The Object Manager calls them at the right times.
Signalled objects. Some types (process, thread, event, mutex, semaphore, timer) are waitable: they have a signalled/not-signalled state. A thread can wait until the object becomes signalled. A process object becomes signalled when the process ends. That is how a parent can wait for a child to finish.
6.4 Object Namespace
What it is: Named objects live in a big tree called the object namespace, like a hidden folder tree inside the kernel (it is not on any disk). The root is \.
Main branches (directories):
| Path | What lives there |
|---|---|
\Device | Device objects, including disk volumes: \Device\HarddiskVolume3 |
\Driver | One object per loaded driver |
\GLOBAL?? (also \??) | Symbolic links, including drive letters such as C: |
\BaseNamedObjects | Named events, mutexes and sections that programs create |
\Sessions | Per-session copies of names (each session has its own set) |
\ObjectTypes | One object for each object type |
\KernelObjects | Kernel-created events and sections |
\Windows | Objects for the Win32 subsystem |
\Registry | The registry as seen from the kernel |
Your drive letters are not magic. C: is a symbolic link in \GLOBAL?? pointing to something like \Device\HarddiskVolume3. When you open C:\file.txt, the Object Manager follows the link and hands the request to the I/O Manager and the file system.
You write: C:\Users\Anna\notes.txt
Win32 turns to: \??\C:\Users\Anna\notes.txt
Object Manager: \GLOBAL??\C: → \Device\HarddiskVolume3
Becomes: \Device\HarddiskVolume3\Users\Anna\notes.txt
Handed to: I/O Manager → NTFS driver
Named objects between programs. Two programs can share an event or mutex if both open the same name in \BaseNamedObjects (or the session's copy). A common trick: an app creates a named mutex at start-up. A second copy tries to create it, sees it exists, and shows "already running". That is how single-instance apps work.
See it yourself. WinObj is a free Microsoft Sysinternals tool that shows the namespace as a tree. It is not part of Windows: download it only from Microsoft's Sysinternals pages (learn.microsoft.com/sysinternals). Open it, expand \GLOBAL??, and find C:. Double-click the entry to see its target.
Summary
| Topic | Remember this |
|---|---|
| Unified object model | Every kernel resource is an object with a standard header: type, count, name, security |
| Object Manager | Creates, names, counts, secures and deletes objects once, for everyone |
| Handle | A per-process ticket number that refers to an object; CloseHandle returns it |
| Object types | Process, Thread, File, Key, Event, Mutant, Section, Token, SymbolicLink and more |
| Namespace | A hidden tree inside the kernel; \Device, \GLOBAL??, \BaseNamedObjects |
| Drive letters | Symbolic links to \Device\HarddiskVolumeN |