Why are kernel HANDLEs always a multiple of four?

Raymond Chen

Not very well known is that the bottom two bits of kernel HANDLEsare always zero; in other words, their numeric value isalways a multiple of 4.Note that this applies only to kernel HANDLEs;it does not apply topseudo-handlesor to any other type of handle(USER handles, GDI handles, multimedia handles…)Kernel handles are things you can pass tothe CloseHandle function.

The availability of the bottom two bits is buried in thentdef.h header file:

//
// Low order two bits of a handle are ignored by the system and available
// for use by application code as tag bits.  The remaining bits are opaque
// and used to store a serial number and table index.
//
#define OBJ_HANDLE_TAGBITS  0x00000003L

That at least the bottom bit of kernel HANDLEs is always zero is implied bythe GetQueuedCompletionStatus function,which indicates that you can set the bottom bit of the eventhandle to suppress completion port notification.In order for this to work, the bottom bit must normally be zero.

This information is not useful for most application writers,which should continue to treat HANDLEs as opaque values.The people who would be interested in tag bits are those whoare implementing low-level class libraries or are wrappingkernel objects inside a larger framework.