Geoff Chappell - Software Analyst
Though an OBJECT_HEADER immediately precedes every object, it too has structures ahead of it. The OBJECT_HEADER has what’s needed more or less immediately for almost every operation on almost every object, including to point the way to these other structures that are useful only for some operations and some objects.
Originally, the OBJECT_HEADER is preceded only by an OBJECT_CREATE_INFORMATION, but this structure is relatively large and wastes on two counts. First, not all of it needs to be kept for the whole of any object’s life, at least not in the form given. Second, not all of it is even given for every object. Version 3.50 substantially reduced the overhead by being selective about what’s retained. The OBJECT_CREATE_INFORMATION is in a separate memory allocation, to be freed eventually, and many of its original members are instead in four other structures that can be present as header’s headers. The OBJECT_HEADER then has four single-byte members which are each the negative offset to the corresponding header, else are zero. One byte for each of these is also wasteful. The header’s headers all have known sizes and though not all need be present, whichever are present have a known order. The offsets to each from any one OBJECT_HEADER can therefore be computed just from knowing which headers are present. This requires just one bit per header. Thus was born the InfoMask in the OBJECT_HEADER for Windows 7 and higher:
Mask | Decription | Versions |
---|---|---|
0x01 | object has OBJECT_HEADER_CREATOR_INFO | 6.1 and higher |
0x02 | object has OBJECT_HEADER_NAME_INFO | 6.1 and higher |
0x04 | object has OBJECT_HEADER_HANDLE_INFO | 6.1 and higher |
0x08 | object has OBJECT_HEADER_QUOTA_INFO | 6.1 and higher |
0x10 | object has OBJECT_HEADER_PROCESS_INFO | 6.1 and higher |
0x20 | object has OBJECT_HEADER_AUDIT_INFO | 6.2 and higher |
0x40 | object has OBJECT_HEADER_HANDLE_REVOCATION_INFO | 10.0 and higher |
A set bit signifies that the corresponding header is present. Exactly where the corresponding header is present before the OBJECT_HEADER depends on which lower bits are set. This is because the increasing numerical values of the bits is also the order of the corresponding headers backwards from the OBJECT_HEADER.
Microsoft’s names for the InfoMask bits are not known—not even from the NTOSP.H in early editions of the Windows Driver Kit (WDK) for Windows 10, which otherwise helps with disclosures of macro definitions for the TraceFlags and Flags. Macro definitions surely do exist, but they will not be needed outside a handful of source files that are private to the Object Manager. The details of locating any of the headers from an OBJECT_HEADER would be easily contained in internal routines, and public symbol files for the kernel confirm that the following exist as inlined routines in the applicable versions as long ago as Windows 8:
OBJECT_HEADER_QUOTA_INFO * OBJECT_HEADER_TO_QUOTA_INFO_EXISTS ( OBJECT_HEADER *);
OBJECT_HEADER_PROCESS_INFO * OBJECT_HEADER_TO_PROCESS_INFO_EXISTS ( OBJECT_HEADER *);
OBJECT_HEADER_HANDLE_INFO * OBJECT_HEADER_TO_HANDLE_INFO_EXISTS ( OBJECT_HEADER *);
OBJECT_HEADER_NAME_INFO * OBJECT_HEADER_TO_NAME_INFO_EXISTS ( OBJECT_HEADER *);
OBJECT_HEADER_AUDIT_INFO * OBJECT_HEADER_TO_AUDIT_INFO_EXISTS ( OBJECT_HEADER *);
OBJECT_HEADER_HANDLE_REVOCATION_INFO * OBJECT_HEADER_TO_HANDLE_REVOCATION_INFO_EXISTS ( OBJECT_HEADER *);
Indeed, starting with the 1511 release, these routines, without the EXISTS suffix, are in plain sight, being not inlined.