Object Directories
As already noted in the discussion of the OBJECT_NAME header part, the Windows 2000 object manager keeps individual objects in a tree of OBJECT_DIRECTORY structures, also known as "directory objects." An OBJECT_DIRECTORY is just another fancy type of object, with an ordinary OBJECT_HEADER and everything a real object needs. The Windows 2000 object directory management is quite tricky. As Listing 7 shows, the OBJECT_DIRECTORY is basically a hash table with 37 entries. This unusual size has probably been chosen because it is a prime number. Each table entry can hold a pointer to an OBJECT_DIRECTORY_ENTRY whose Object member refers to an object. When a new object is created, the object manager computes a hash value in the range zero to 36 from the object name and creates an OBJECT_DIRECTORY_ENTRY. If the target slot of the hash table is empty, this slot is set up to point to the new directory entry. If the slot is already in use, the new entry is inserted into a singly linked list of entries originating from the target slot, using the NextEntry members of the involved OBJECT_DIRECTORY_ENTRY structures. To represent hierarchical object relationships, object directories can be nested in a straightforward way by simply adding an OBJECT_DIRECTORY_ENTRY with an Object member that points to a subordinate directory object.
Listing 7 The OBJECT_DIRECTORY and OBJECT_DIRECTORY_ENTRY structures
typedef struct _OBJECT_DIRECTORY_ENTRY { /*000*/ struct _OBJECT_DIRECTORY_ENTRY *NextEntry; /*004*/ POBJECT Object; /*008*/ } OBJECT_DIRECTORY_ENTRY, * POBJECT_DIRECTORY_ENTRY, **PPOBJECT_DIRECTORY_ENTRY; // ----------------------------------------------------------------- #define OBJECT_HASH_TABLE_SIZE 37 typedef struct _OBJECT_DIRECTORY { /*000*/ POBJECT_DIRECTORY_ENTRY HashTable [OBJECT_HASH_TABLE_SIZE]; /*094*/ POBJECT_DIRECTORY_ENTRY CurrentEntry; /*098*/ BOOLEAN CurrentEntryValid; /*099*/ BYTE Reserved1; /*09A*/ WORD Reserved2; /*09C*/ DWORD Reserved3; /*0A0*/ } OBJECT_DIRECTORY, * POBJECT_DIRECTORY, **PPOBJECT_DIRECTORY;
To optimize the access to frequently used objects, the object manager applies a simple MRU (most recently used) algorithm. Whenever an object has successfully been retrieved, it is put in front of the linked list of entries that are assigned to the same hash table slot. Moreover, a pointer to the updated list is kept in the CurrentEntry member of the OBJECT_DIRECTORY. The CurrentEntryValid flag indicates whether the CurrentEntry pointer is valid. Access to the system's global object directory is synchronized by means of an ERESOURCE lock called ObpRootDirectoryMutex. This lock is neither documented nor exported.