// Object manager. This file owns reference-counted kernel objects and handle-table lifetime rules. #include #include #include #include // Returns a diagnostic pool tag for the object type. static uint32_t KiObjectPoolTag(OBJECT_TYPE type) { switch (type) { case ObjectTypeProcess: return MM_POOL_TAG('p', 'r', 'o', 'c'); case ObjectTypeThread: return MM_POOL_TAG('t', 'h', 'r', 'd'); case ObjectTypeMutex: return MM_POOL_TAG('m', 't', 'x', ' '); case ObjectTypeSemaphore: return MM_POOL_TAG('s', 'e', 'm', ' '); case ObjectTypeEvent: return MM_POOL_TAG('e', 'v', 'n', 't'); case ObjectTypeQueue: return MM_POOL_TAG('q', 'u', 'e', 'u'); case ObjectTypeFile: return MM_POOL_TAG('f', 'i', 'l', 'e'); case ObjectTypeDir: return MM_POOL_TAG('d', 'i', 'r', ' '); case ObjectTypeAsyncIo: return MM_POOL_TAG('a', 'i', 'o', ' '); case ObjectTypeSocket: return MM_POOL_TAG('s', 'o', 'c', 'k'); case ObjectTypeDevice: return MM_POOL_TAG('d', 'e', 'v', ' '); case ObjectTypeDriver: return MM_POOL_TAG('d', 'r', 'v', 'r'); case ObjectTypeUsbDevice: return MM_POOL_TAG('u', 's', 'b', 'd'); case ObjectTypeUsbPipe: return MM_POOL_TAG('u', 's', 'b', 'p'); case ObjectTypeFileMapping: return MM_POOL_TAG('m', 'a', 'p', 'f'); case ObjectTypeSurface: return MM_POOL_TAG('s', 'u', 'r', 'f'); case ObjectTypeInputQueue: return MM_POOL_TAG('i', 'n', 'p', 'q'); case ObjectTypeImageSection: return MM_POOL_TAG('i', 'm', 's', 'e'); default: return MM_POOL_TAG('o', 'b', 'j', ' '); } } // Creates a zeroed, tagged object with one initial reference. __declspec(dllexport) OBJECT* ObAllocateObject(OBJECT_TYPE type, size_t size) { if (size < sizeof(OBJECT)) size = sizeof(OBJECT); OBJECT* obj = (OBJECT *)MmAllocatePoolTag(size, KiObjectPoolTag(type)); if (!obj) return (OBJECT *)0; memset(obj, 0, size); obj->Type = type; obj->RefCount = 1; obj->Destroy = (void *)0; // caller fills this in return obj; } // Implements the reference Object operation. __declspec(dllexport) void ObReferenceObject(OBJECT* object) { if (!object) return; _InterlockedIncrement(&object->RefCount); } // Implements the dereference Object operation. __declspec(dllexport) void ObDereferenceObject(OBJECT* object) { if (!object) return; long prev = _InterlockedDecrement(&object->RefCount); if (prev == 0) { // Reference count hit zero - run the destructor then free. if (object->Destroy) { object->Destroy(object); } MmFreePool(object); } }