Files
nt-lite/code/kernel/ob_object.c
T

67 lines
2.8 KiB
C

// Object manager. This file owns reference-counted kernel objects and handle-table lifetime rules.
#include <string.h>
#include <intrin.h>
#include <kernel/ob_object.h>
#include <kernel/mm_virt.h>
// 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');
case ObjectTypeTimer: return MM_POOL_TAG('t', 'm', 'r', ' ');
case ObjectTypeModule: return MM_POOL_TAG('m', 'o', 'd', 'u');
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);
}
}