/******************************************************************************* * * (C) COPYRIGHT AUTHORS, 2017 - 2025 * * TITLE: OBJECTS.C * * VERSION: 2.10 * * DATE: 22 Nov 2025 * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A * PARTICULAR PURPOSE. * *******************************************************************************/ #include "global.h" WOBJ_TYPE_DESC g_TypeUnknown = { OBTYPE_NAME_UNKNOWN, 0, ObjectTypeUnknown, IDI_ICON_UNKNOWN, IDS_DESC_UNKNOWN }; WOBJ_TYPE_DESC g_TypeActivationObject = { L"ActivationObject", 0xde960015, ObjectTypeActivationObject, IDI_ICON_ACTIVATIONOBJECT, IDS_DESC_ACTIVATIONOBJECT }; WOBJ_TYPE_DESC g_TypeActivityReference = { L"ActivityReference", 0x44db295c, ObjectTypeActivityReference, IDI_ICON_ACTIVITYREFERENCE, IDS_DESC_ACTIVITYREFERENCE }; WOBJ_TYPE_DESC g_TypeAdapter = { L"Adapter", 0x5b4bfe0f, ObjectTypeAdapter, IDI_ICON_ADAPTER, IDS_DESC_ADAPTER }; WOBJ_TYPE_DESC g_TypeALPCPort = { L"ALPC Port", 0xfc99f003, ObjectTypePort, IDI_ICON_PORT, IDS_DESC_PORT }; WOBJ_TYPE_DESC g_TypeCallback = { L"Callback", 0xd619e0a5, ObjectTypeCallback, IDI_ICON_CALLBACK, IDS_DESC_CALLBACK }; WOBJ_TYPE_DESC g_TypeComposition = { L"Composition", 0xf009caea, ObjectTypeComposition, IDI_ICON_DXOBJECT, IDS_DESC_COMPOSITION }; WOBJ_TYPE_DESC g_TypeController = { L"Controller", 0x38a0df3c, ObjectTypeController, IDI_ICON_CONTROLLER, IDS_DESC_CONTROLLER }; WOBJ_TYPE_DESC g_TypeCoreMessaging = { L"CoreMessaging", 0x86bcebe5, ObjectTypeCoreMessaging, IDI_ICON_COREMESSAGING, IDS_DESC_COREMESSAGING }; WOBJ_TYPE_DESC g_TypeCoverageSampler = { L"CoverageSampler", 0xb6a0f960, ObjectTypeCoverageSampler, IDI_ICON_COVERAGESAMPLER, IDS_DESC_COVERAGESAMPLER }; WOBJ_TYPE_DESC g_TypeCpuPartition = { L"CpuPartition", 0xafdf1c82, ObjectTypeCpuPartition, IDI_ICON_CPUPARTITION, IDS_DESC_CPUPARTITION }; WOBJ_TYPE_DESC g_TypeCrossVmEvent = { L"CrossVmEvent", 0x6eb9ebe3, ObjectTypeCrossVmEvent, IDI_ICON_CROSSVMEVENT, IDS_DESC_CROSSVMEVENT }; WOBJ_TYPE_DESC g_TypeCrossVmMutant = { L"CrossVmMutant", 0x4c942872, ObjectTypeCrossVmMutant, IDI_ICON_CROSSVMMUTANT, IDS_DESC_CROSSVMMUTANT }; WOBJ_TYPE_DESC g_TypeDebugObject = { L"DebugObject", 0x8282e52, ObjectTypeDebugObject, IDI_ICON_DEBUGOBJECT, IDS_DESC_DEBUGOBJECT }; WOBJ_TYPE_DESC g_TypeDesktop = { OBTYPE_NAME_DESKTOP, 0xd1ffc79c, ObjectTypeDesktop, IDI_ICON_DESKTOP, IDS_DESC_DESKTOP }; WOBJ_TYPE_DESC g_TypeDevice = { L"Device", OBTYPE_HASH_DEVICE, ObjectTypeDevice, IDI_ICON_DEVICE, IDS_DESC_DEVICE }; WOBJ_TYPE_DESC g_TypeDirectory = { OBTYPE_NAME_DIRECTORY, OBTYPE_HASH_DIRECTORY, ObjectTypeDirectory, IDI_ICON_DIRECTORY, IDS_DESC_DIRECTORY }; WOBJ_TYPE_DESC g_TypeDmaAdapter = { L"DmaAdapter", 0x2201d697, ObjectTypeDmaAdapter, IDI_ICON_HALDMA, IDS_DESC_DMAADAPTER }; WOBJ_TYPE_DESC g_TypeDmaDomain = { L"DmaDomain", 0xfe7e671c, ObjectTypeDmaDomain, IDI_ICON_HALDMA, IDS_DESC_DMADOMAIN }; WOBJ_TYPE_DESC g_TypeDriver = { L"Driver", OBTYPE_HASH_DRIVER, ObjectTypeDriver, IDI_ICON_DRIVER, IDS_DESC_DRIVER }; WOBJ_TYPE_DESC g_TypeDxgkCompositionObject = { L"DxgkCompositionObject", 0xf2bf1f91, ObjectTypeDxgkComposition, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_COMPOSITION_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkCurrentDxgProcessObject = { L"DxgkCurrentDxgProcessObject", 0xc27e9d7c, ObjectTypeDxgkCurrentDxgProcessObject, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_CURRENT_DXG_PROCESS_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkCurrentDxgThreadObject = { L"DxgkCurrentDxgThreadObject", 0xc8d07f5b, ObjectTypeDxgkCurrentDxgThreadObject, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_CURRENT_DXG_THREAD_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkDisplayManagerObject = { L"DxgkDisplayManagerObject", 0x5afc4062, ObjectTypeDxgkDisplayManager, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_DISPLAY_MANAGER_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkDisplayMuxSwitch = { L"DxgkDisplayMuxSwitch", 0x180e2a1a, ObjectTypeDxgkDisplayMuxSwitch, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_DISPLAYMUXSWITCH }; WOBJ_TYPE_DESC g_TypeDxgkSharedBundleObject = { L"DxgkSharedBundleObject", 0xf7e4ab9e, ObjectTypeDxgkSharedBundle, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_SHARED_BUNDLE_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkSharedKeyedMutexObject = { L"DxgkSharedKeyedMutexObject", 0xd6c628fd, ObjectTypeDxgkSharedKeyedMutex, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_SHARED_KEYED_MUTEX_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkSharedProtectedSessionObject = { L"DxgkSharedProtectedSessionObject", 0xa9676f44, ObjectTypeDxgkSharedProtectedSession, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_SHARED_PROTECTED_SESSION_OBJECT }; WOBJ_TYPE_DESC g_TypeDxgkSharedResource = { L"DxgkSharedResource", 0x632e6c2b, ObjectTypeDxgkSharedResource, IDI_ICON_DXOBJECT, IDS_DESC_DXGKSHAREDRES }; WOBJ_TYPE_DESC g_TypeDxgkSharedSwapChainObject = { L"DxgkSharedSwapChainObject", 0xf5053210, ObjectTypeDxgkSharedSwapChain, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_SHARED_SWAPCHAIN }; WOBJ_TYPE_DESC g_TypeDxgkSharedSyncObject = { L"DxgkSharedSyncObject", 0xa29968d7, ObjectTypeDxgkSharedSyncObject, IDI_ICON_DXOBJECT, IDS_DESC_DXGK_SHARED_SYNC }; WOBJ_TYPE_DESC g_TypeEnergyTracker = { L"EnergyTracker", 0x4dcec6d0, ObjectTypeEnergyTracker, IDI_ICON_ENERGYTRACKER, IDS_DESC_ENERGYTRACKER }; WOBJ_TYPE_DESC g_TypeEtwConsumer = { L"EtwConsumer", 0x31a53abe, ObjectTypeETWConsumer, IDI_ICON_ETWCONSUMER, IDS_DESC_ETWCONSUMER }; WOBJ_TYPE_DESC g_TypeEtwRegistration = { L"EtwRegistration", 0x89b06481, ObjectTypeETWRegistration, IDI_ICON_ETWREGISTRATION, IDS_DESC_ETWREGISTRATION }; WOBJ_TYPE_DESC g_TypeEtwSessionDemuxEntry = { L"EtwSessionDemuxEntry", 0x4ce2d111, ObjectTypeEtwSessionDemuxEntry, IDI_ICON_ETWSESSIONDEMUXENTRY, IDS_DESC_ETWSESSIONDEMUXENTRY }; WOBJ_TYPE_DESC g_TypeEvent = { L"Event", 0xf3040cba, ObjectTypeEvent, IDI_ICON_EVENT, IDS_DESC_EVENT }; WOBJ_TYPE_DESC g_TypeEventPair = { L"EventPair", 0x97834894, ObjectTypeEventPair, IDI_ICON_EVENTPAIR, IDS_DESC_EVENTPAIR }; WOBJ_TYPE_DESC g_TypeFile = { OBTYPE_NAME_FILE, 0xecfd8b1c, ObjectTypeFile, IDI_ICON_FILE, IDS_DESC_FILE }; WOBJ_TYPE_DESC g_TypeFilterCommunicationPort = { L"FilterCommunicationPort", 0x7849195f, ObjectTypeFltComnPort, IDI_ICON_FLTCOMMPORT, IDS_DESC_FLT_COMM_PORT }; WOBJ_TYPE_DESC g_TypeFilterConnectionPort = { L"FilterConnectionPort", 0x4598bf7, ObjectTypeFltConnPort, IDI_ICON_FLTCONNPORT, IDS_DESC_FLT_CONN_PORT }; WOBJ_TYPE_DESC g_TypeIoCompletion = { L"IoCompletion", 0xbc81c342, ObjectTypeIoCompletion, IDI_ICON_IOCOMPLETION, IDS_DESC_IOCOMPLETION }; WOBJ_TYPE_DESC g_TypeIoCompletionReserve = { L"IoCompletionReserve", 0xca6e211a, ObjectTypeIoCompletionReserve, IDI_ICON_IOCOMPLETION, IDS_DESC_IOCOMPLETIONRESERVE }; WOBJ_TYPE_DESC g_TypeIoRing = { L"IoRing", 0xe17640f6, ObjectTypeIoRing, IDI_ICON_IORING, IDS_DESC_IORING }; WOBJ_TYPE_DESC g_TypeIRTimer = { L"IRTimer", 0xc161a6dc, ObjectTypeIRTimer, IDI_ICON_IRTIMER, IDS_DESC_IRTIMER }; WOBJ_TYPE_DESC g_TypeJob = { L"Job", 0x24df96fd, ObjectTypeJob, IDI_ICON_JOB, IDS_DESC_JOB }; WOBJ_TYPE_DESC g_TypeKey = { L"Key", 0x2553a41f, ObjectTypeKey, IDI_ICON_KEY, IDS_DESC_KEY }; WOBJ_TYPE_DESC g_TypeKeyedEvent = { L"KeyedEvent", 0x6c3a045c, ObjectTypeKeyedEvent, IDI_ICON_KEYEDEVENT, IDS_DESC_KEYEDEVENT }; WOBJ_TYPE_DESC g_TypeMutant = { L"Mutant", 0xfba93d5b, ObjectTypeMutant, IDI_ICON_MUTANT, IDS_DESC_MUTANT }; WOBJ_TYPE_DESC g_TypeNdisCmState = { L"NdisCmState", 0x28077967, ObjectTypeNdisCmState, IDI_ICON_NDISCMSTATE, IDS_DESC_NDISCMSTATE }; WOBJ_TYPE_DESC g_TypePartition = { L"Partition", 0x5227054a, ObjectTypeMemoryPartition, IDI_ICON_MEMORYPARTITION, IDS_DESC_MEMORY_PARTITION }; WOBJ_TYPE_DESC g_TypePcwObject = { L"PcwObject", 0xe3f801c3, ObjectTypePcwObject, IDI_ICON_PCWOBJECT, IDS_DESC_PCWOBJECT }; WOBJ_TYPE_DESC g_TypePowerRequest = { L"PowerRequest", 0xb5a1b3ea, ObjectTypePowerRequest, IDI_ICON_POWERREQUEST, IDS_DESC_POWERREQUEST }; WOBJ_TYPE_DESC g_TypeProcess = { OBTYPE_NAME_PROCESS, 0x70fcfc4f, ObjectTypeProcess, IDI_ICON_PROCESS, IDS_DESC_PROCESS }; WOBJ_TYPE_DESC g_TypeProcessStateChange = { L"ProcessStateChange", 0x6fd57b92, ObjectTypeProcessStateChange, IDI_ICON_PROCESSSTATECHANGE, IDS_DESC_PROCESSSTATECHANGE }; WOBJ_TYPE_DESC g_TypeProfile = { L"Profile", 0xfe82aac9, ObjectTypeProfile, IDI_ICON_PROFILE, IDS_DESC_PROFILE }; WOBJ_TYPE_DESC g_TypePsSiloContextNonPaged = { L"PsSiloContextNonPaged", 0xe2c391fb, ObjectTypePsSiloContextNonPaged, IDI_ICON_PSSILOCONTEXT, IDS_DESC_PSSILOCONTEXTNP }; WOBJ_TYPE_DESC g_TypePsSiloContextPaged = { L"PsSiloContextPaged", 0x8f91f0a2, ObjectTypePsSiloContextPaged, IDI_ICON_PSSILOCONTEXT, IDS_DESC_PSSILOCONTEXT }; WOBJ_TYPE_DESC g_TypeRawInputManager = { L"RawInputManager", 0xf28870cb, ObjectTypeRawInputManager, IDI_ICON_RAWINPUTMANAGER, IDS_DESC_RAWINPUTMANAGER }; WOBJ_TYPE_DESC g_TypeRegistryTransaction = { L"RegistryTransaction", 0xba530c61, ObjectTypeRegistryTransaction, IDI_ICON_KEY, IDS_DESC_REGISTRY_TRANSACTION }; WOBJ_TYPE_DESC g_TypeSchedulerSharedData = { L"SchedulerSharedData", 0xa4930ca, ObjectTypeSchedulerSharedData, IDI_ICON_SCHEDULERSHAREDDATA, IDS_DESC_SCHEDULERSHAREDDATA }; WOBJ_TYPE_DESC g_TypeSection = { L"Section", OBTYPE_HASH_SECTION, ObjectTypeSection, IDI_ICON_SECTION, IDS_DESC_SECTION }; WOBJ_TYPE_DESC g_TypeSemaphore = { L"Semaphore", 0x33b553e4, ObjectTypeSemaphore, IDI_ICON_SEMAPHORE, IDS_DESC_SEMAPHORE }; WOBJ_TYPE_DESC g_TypeSession = { L"Session", 0xcd4f9c96, ObjectTypeSession, IDI_ICON_SESSION, IDS_DESC_SESSION }; WOBJ_TYPE_DESC g_TypeSymbolicLink = { L"SymbolicLink", OBTYPE_HASH_SYMBOLIC_LINK, ObjectTypeSymbolicLink, IDI_ICON_SYMLINK, IDS_DESC_SYMLINK }; WOBJ_TYPE_DESC g_TypeTerminal = { L"Terminal", 0x17fd8d1c, ObjectTypeTerminal, IDI_ICON_TERMINAL, IDS_DESC_TERMINAL }; WOBJ_TYPE_DESC g_TypeTerminalEventQueue = { L"TerminalEventQueue", 0x87c5d493, ObjectTypeTerminalEventQueue, IDI_ICON_TERMINALEVENTQUEUE, IDS_DESC_TERMINALEVENTQUEUE }; WOBJ_TYPE_DESC g_TypeThread = { OBTYPE_NAME_THREAD, 0xc8bcac4a, ObjectTypeThread, IDI_ICON_THREAD, IDS_DESC_THREAD }; WOBJ_TYPE_DESC g_TypeThreadStateChange = { L"ThreadStateChange", 0x88afedd7, ObjectTypeThreadStateChange, IDI_ICON_THREADSTATECHANGE, IDS_DESC_THREADSTATECHANGE }; WOBJ_TYPE_DESC g_TypeTimer = { L"Timer", 0x94ec7de5, ObjectTypeTimer, IDI_ICON_TIMER, IDS_DESC_TIMER }; WOBJ_TYPE_DESC g_TypeTmEn = { L"TmEn", 0x7a2e2a02, ObjectTypeTmEn, IDI_ICON_TMEN, IDS_DESC_TMEN }; WOBJ_TYPE_DESC g_TypeTmRm = { L"TmRm", 0x7a3b2d34, ObjectTypeTmRm, IDI_ICON_TMRM, IDS_DESC_TMRM }; WOBJ_TYPE_DESC g_TypeTmTm = { L"TmTm", 0x7a3d2db2, ObjectTypeTmTm, IDI_ICON_TMTM, IDS_DESC_TMTM }; WOBJ_TYPE_DESC g_TypeTmTx = { L"TmTx", 0x7a3d2dbd, ObjectTypeTmTx, IDI_ICON_TMTX, IDS_DESC_TMTX }; WOBJ_TYPE_DESC g_TypeToken = { OBTYPE_NAME_TOKEN, 0xab194359, ObjectTypeToken, IDI_ICON_TOKEN, IDS_DESC_TOKEN }; WOBJ_TYPE_DESC g_TypeTpWorkerFactory = { L"TpWorkerFactory", 0x84a8cd0, ObjectTypeTpWorkerFactory, IDI_ICON_TPWORKERFACTORY,IDS_DESC_TPWORKERFACTORY }; WOBJ_TYPE_DESC g_TypeType = { L"Type", OBTYPE_HASH_TYPE, ObjectTypeType, IDI_ICON_TYPE, IDS_DESC_TYPE }; WOBJ_TYPE_DESC g_TypeUserApcReserve = { L"UserApcReserve", 0xa3fa2453, ObjectTypeUserApcReserve, IDI_ICON_USERAPCRESERVE, IDS_DESC_USERAPCRESERVE }; WOBJ_TYPE_DESC g_TypeVirtualKey = { L"VirtualKey", 0x77158ef4, ObjectTypeVirtualKey, IDI_ICON_VIRTUALKEY, IDS_DESC_VIRTUALKEY }; WOBJ_TYPE_DESC g_TypeVRegConfigurationContext = { L"VRegConfigurationContext", 0x783eeab7, ObjectTypeVRegConfigurationContext, IDI_ICON_VREGCFGCTX, IDS_DESC_VREGCFGCTX }; WOBJ_TYPE_DESC g_TypeWaitablePort = { L"WaitablePort", 0x66debaf0, ObjectTypeWaitablePort, IDI_ICON_WAITABLEPORT, IDS_DESC_WAITABLEPORT }; WOBJ_TYPE_DESC g_TypeWaitCompletionPacket = { L"WaitCompletionPacket", 0xdaa80e19, ObjectTypeWaitCompletionPacket, IDI_ICON_WAITCOMPLETIONPACKET, IDS_DESC_WAITCOMPLETIONPACKET }; WOBJ_TYPE_DESC g_TypeWinstation = { L"WindowStation", OBTYPE_HASH_WINSTATION, ObjectTypeWinstation, IDI_ICON_WINSTATION, IDS_DESC_WINSTATION }; WOBJ_TYPE_DESC g_TypeWmiGuid = { L"WmiGuid", 0x36d9823c, ObjectTypeWMIGuid, IDI_ICON_WMIGUID, IDS_DESC_WMIGUID }; // Maximum object type index value for lookup table sizing #define MAX_OBJECT_TYPE_INDEX ObjectTypeUnknown #define OBJECT_TYPE_ENTRIES \ X(g_TypeActivationObject) \ X(g_TypeActivityReference) \ X(g_TypeAdapter) \ X(g_TypeALPCPort) \ X(g_TypeCallback) \ X(g_TypeComposition) \ X(g_TypeController) \ X(g_TypeCoreMessaging) \ X(g_TypeCoverageSampler) \ X(g_TypeCpuPartition) \ X(g_TypeCrossVmEvent) \ X(g_TypeCrossVmMutant) \ X(g_TypeDebugObject) \ X(g_TypeDesktop) \ X(g_TypeDevice) \ X(g_TypeDirectory) \ X(g_TypeDmaAdapter) \ X(g_TypeDmaDomain) \ X(g_TypeDriver) \ X(g_TypeDxgkCompositionObject) \ X(g_TypeDxgkCurrentDxgProcessObject) \ X(g_TypeDxgkCurrentDxgThreadObject) \ X(g_TypeDxgkDisplayManagerObject) \ X(g_TypeDxgkDisplayMuxSwitch) \ X(g_TypeDxgkSharedBundleObject) \ X(g_TypeDxgkSharedKeyedMutexObject) \ X(g_TypeDxgkSharedProtectedSessionObject) \ X(g_TypeDxgkSharedResource) \ X(g_TypeDxgkSharedSwapChainObject) \ X(g_TypeDxgkSharedSyncObject) \ X(g_TypeEnergyTracker) \ X(g_TypeEtwConsumer) \ X(g_TypeEtwRegistration) \ X(g_TypeEtwSessionDemuxEntry) \ X(g_TypeEvent) \ X(g_TypeEventPair) \ X(g_TypeFile) \ X(g_TypeFilterCommunicationPort) \ X(g_TypeFilterConnectionPort) \ X(g_TypeIoCompletion) \ X(g_TypeIoCompletionReserve) \ X(g_TypeIoRing) \ X(g_TypeIRTimer) \ X(g_TypeJob) \ X(g_TypeKey) \ X(g_TypeKeyedEvent) \ X(g_TypeMutant) \ X(g_TypeNdisCmState) \ X(g_TypePartition) \ X(g_TypePcwObject) \ X(g_TypePowerRequest) \ X(g_TypeProcess) \ X(g_TypeProcessStateChange) \ X(g_TypeProfile) \ X(g_TypePsSiloContextNonPaged) \ X(g_TypePsSiloContextPaged) \ X(g_TypeRawInputManager) \ X(g_TypeRegistryTransaction) \ X(g_TypeSchedulerSharedData) \ X(g_TypeSection) \ X(g_TypeSemaphore) \ X(g_TypeSession) \ X(g_TypeSymbolicLink) \ X(g_TypeTerminal) \ X(g_TypeTerminalEventQueue) \ X(g_TypeThread) \ X(g_TypeThreadStateChange) \ X(g_TypeTimer) \ X(g_TypeTmEn) \ X(g_TypeTmRm) \ X(g_TypeTmTm) \ X(g_TypeTmTx) \ X(g_TypeToken) \ X(g_TypeTpWorkerFactory) \ X(g_TypeType) \ X(g_TypeUserApcReserve) \ X(g_TypeVirtualKey) \ X(g_TypeVRegConfigurationContext) \ X(g_TypeWaitablePort) \ X(g_TypeWaitCompletionPacket) \ X(g_TypeWinstation) \ X(g_TypeWmiGuid) // // Array items must be always sorted by object type name. // static WOBJ_TYPE_DESC* gpObjectTypes[] = { #define X(type) &type, OBJECT_TYPE_ENTRIES #undef X }; // // Number of items in gpObjectTypes array // ULONG g_ObjectTypesCount = RTL_NUMBER_OF(gpObjectTypes); // Lookup table for access by type index static WOBJ_TYPE_DESC* g_TypeIndexLookup[MAX_OBJECT_TYPE_INDEX + 1]; // Hash table for type names typedef struct _OBTYPE_HASH_NODE { ULONG NameHash; WOBJ_TYPE_DESC* TypeDesc; struct _OBTYPE_HASH_NODE* Next; } OBTYPE_HASH_NODE, * POBTYPE_HASH_NODE; // Hashtable for types #define HASH_TABLE_SIZE 256 static OBTYPE_HASH_NODE* g_TypeHashTable[HASH_TABLE_SIZE]; static OBTYPE_HASH_NODE g_HashNodePool[ObjectTypeMax]; // One-time init static INIT_ONCE g_LookupTablesInitOnce = INIT_ONCE_STATIC_INIT; /* * ObManagerComparerName * * Purpose: * * Support comparer routine to work with objects array. * */ INT ObManagerComparerName( _In_ PCVOID FirstObject, _In_ PCVOID SecondObject ) { WOBJ_TYPE_DESC* firstObject = (WOBJ_TYPE_DESC*)FirstObject; WOBJ_TYPE_DESC* secondObject = *(WOBJ_TYPE_DESC**)SecondObject; return (_strcmpi(firstObject->Name, secondObject->Name)); } /* * ObManagerInitOnceCallback * * Purpose: * * Initialize lookup tables for faster object type searching. * */ BOOL CALLBACK ObManagerInitOnceCallback( _Inout_ PINIT_ONCE InitOnce, _Inout_opt_ PVOID Parameter, _Out_opt_ PVOID* Context ) { ULONG i, hashIndex; POBTYPE_HASH_NODE node; WOBJ_OBJECT_TYPE typeIndex; #ifdef _DEBUG ULONG k; #endif UNREFERENCED_PARAMETER(InitOnce); UNREFERENCED_PARAMETER(Parameter); RtlSecureZeroMemory(g_TypeIndexLookup, sizeof(g_TypeIndexLookup)); RtlSecureZeroMemory(g_TypeHashTable, sizeof(g_TypeHashTable)); RtlSecureZeroMemory(g_HashNodePool, sizeof(g_HashNodePool)); #if _DEBUG if (g_ObjectTypesCount > 1) { for (k = 1; k < g_ObjectTypesCount; k++) { if (_strcmpi(gpObjectTypes[k - 1]->Name, gpObjectTypes[k]->Name) > 0) { kdDebugPrint("gpObjectTypes ordering error at %lu: %ws > %ws\r\n", k, gpObjectTypes[k - 1]->Name, gpObjectTypes[k]->Name); break; } } } #endif for (i = 0; i < g_ObjectTypesCount; i++) { typeIndex = gpObjectTypes[i]->Index; if (typeIndex >= 0 && (ULONG)typeIndex <= MAX_OBJECT_TYPE_INDEX) { g_TypeIndexLookup[typeIndex] = gpObjectTypes[i]; } #if _DEBUG else { kdDebugPrint("Type index out of bounds for %ws (%lu)\r\n", gpObjectTypes[i]->Name, (ULONG)typeIndex); } #endif if (gpObjectTypes[i]->NameHash != 0) { hashIndex = gpObjectTypes[i]->NameHash & (HASH_TABLE_SIZE - 1); node = &g_HashNodePool[i]; node->NameHash = gpObjectTypes[i]->NameHash; node->TypeDesc = gpObjectTypes[i]; node->Next = g_TypeHashTable[hashIndex]; g_TypeHashTable[hashIndex] = node; } } if (Context) *Context = ULongToPtr(1); return TRUE; } /* * ObManagerEnsureInitialized * * Purpose: * * Ensure lookup tables are initialized exactly once. * */ VOID ObManagerEnsureInitialized( VOID ) { InitOnceExecuteOnce(&g_LookupTablesInitOnce, ObManagerInitOnceCallback, NULL, NULL); } /* * ObManagerInitLookupTables * * Purpose: * * Initialize lookup tables for faster object type searching. * */ VOID ObManagerInitLookupTables(VOID) { ObManagerEnsureInitialized(); } /* * ObManagerGetNameByIndex * * Purpose: * * Returns object name by index of known type. * */ LPWSTR ObManagerGetNameByIndex( _In_ WOBJ_OBJECT_TYPE TypeIndex ) { ObManagerEnsureInitialized(); if (TypeIndex >= 0 && (ULONG)TypeIndex <= MAX_OBJECT_TYPE_INDEX && g_TypeIndexLookup[TypeIndex] != NULL) { return g_TypeIndexLookup[TypeIndex]->Name; } return OBTYPE_NAME_UNKNOWN; } /* * ObManagerGetEntryByTypeIndex * * Purpose: * * Returns object entry by type index. * */ WOBJ_TYPE_DESC* ObManagerGetEntryByTypeIndex( _In_ WOBJ_OBJECT_TYPE TypeIndex ) { ObManagerEnsureInitialized(); if (TypeIndex >= 0 && (ULONG)TypeIndex <= MAX_OBJECT_TYPE_INDEX && g_TypeIndexLookup[TypeIndex] != NULL) { return g_TypeIndexLookup[TypeIndex]; } return &g_TypeUnknown; } /* * ObManagerLookupByHash * * Purpose: * * Fast lookup by hash value. * */ WOBJ_TYPE_DESC* ObManagerLookupByHash( _In_ ULONG NameHash ) { ULONG hashIndex; POBTYPE_HASH_NODE node; if (NameHash == 0) return NULL; hashIndex = NameHash & (HASH_TABLE_SIZE - 1); node = g_TypeHashTable[hashIndex]; while (node != NULL) { if (node->NameHash == NameHash) return node->TypeDesc; node = node->Next; } return NULL; } /* * ObManagerGetEntryByTypeName * * Purpose: * * Returns object description entry by type name or g_TypeUnknown if none found. * */ WOBJ_TYPE_DESC* ObManagerGetEntryByTypeName( _In_opt_ LPCWSTR lpTypeName ) { WOBJ_TYPE_DESC searchItem; WOBJ_TYPE_DESC* result; PVOID lookupItem; ULONG nameHash; if (lpTypeName == NULL) { return &g_TypeUnknown; } ObManagerEnsureInitialized(); // Try fast lookup by hash first nameHash = supHashString(lpTypeName, (ULONG)_strlen(lpTypeName)); result = ObManagerLookupByHash(nameHash); if (result != NULL) { // Verify name matches (in case of hash collision) if (_strcmpi(result->Name, lpTypeName) == 0) return result; } // Fall back to binary search searchItem.Name = (LPWSTR)lpTypeName; lookupItem = supBSearch((PCVOID)&searchItem, (PCVOID)gpObjectTypes, g_ObjectTypesCount, sizeof(PVOID), ObManagerComparerName); if (lookupItem == NULL) { result = &g_TypeUnknown; } else { result = *(WOBJ_TYPE_DESC**)lookupItem; } return result; } /* * ObManagerGetIndexByTypeName * * Purpose: * * Returns object index of known type. * */ WOBJ_OBJECT_TYPE ObManagerGetIndexByTypeName( _In_opt_ LPCWSTR lpTypeName ) { WOBJ_TYPE_DESC* lookupItem = ObManagerGetEntryByTypeName(lpTypeName); return lookupItem->Index; } /* * ObManagerGetImageIndexByTypeName * * Purpose: * * Returns object image index of known type. * */ INT ObManagerGetImageIndexByTypeName( _In_opt_ LPCWSTR lpTypeName ) { WOBJ_TYPE_DESC* lookupItem = ObManagerGetEntryByTypeName(lpTypeName); return lookupItem->ImageIndex; } /* * ObManagerLoadImageForType * * Purpose: * * Load image of the given id. * */ INT ObManagerLoadImageForType( _In_ HIMAGELIST ImageList, _In_ INT ResourceImageId ) { INT ImageIndex = I_IMAGENONE; HICON hIcon; hIcon = (HICON)LoadImage(g_WinObj.hInstance, MAKEINTRESOURCE(ResourceImageId), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); if (hIcon) { ImageIndex = ImageList_ReplaceIcon(ImageList, -1, hIcon); DestroyIcon(hIcon); } return ImageIndex; } /* * ObManagerLoadImageList * * Purpose: * * Create and load image list from icon resource type. * */ HIMAGELIST ObManagerLoadImageList( VOID ) { UINT i; HIMAGELIST ImageList; HICON hIcon; ObManagerEnsureInitialized(); ImageList = ImageList_Create( 16, 16, ILC_COLOR32 | ILC_MASK, g_ObjectTypesCount, 8); if (!ImageList) return NULL; for (i = 0; i < g_ObjectTypesCount; i++) { hIcon = (HICON)LoadImage(g_WinObj.hInstance, MAKEINTRESOURCE(gpObjectTypes[i]->ResourceImageId), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); if (hIcon) { gpObjectTypes[i]->ImageIndex = ImageList_AddIcon(ImageList, hIcon); DestroyIcon(hIcon); } else { gpObjectTypes[i]->ImageIndex = I_IMAGENONE; } } // Load the unknown type icon g_TypeUnknown.ImageIndex = ObManagerLoadImageForType(ImageList, g_TypeUnknown.ResourceImageId); return ImageList; } PVOID ObManagerTable() { return (PVOID)gpObjectTypes; } VOID ObManagerTest() { ULONG hashValue; UINT i; for (i = 0; i < g_ObjectTypesCount; i++) kdDebugPrint("%ws\r\n", gpObjectTypes[i]->Name); for (i = 0; i < g_ObjectTypesCount; i++) { hashValue = supHashString(gpObjectTypes[i]->Name, (ULONG)_strlen(gpObjectTypes[i]->Name)); kdDebugPrint("%ws = 0x%lx\r\n", gpObjectTypes[i]->Name, hashValue); if (hashValue != gpObjectTypes[i]->NameHash) MessageBox(GetDesktopWindow(), L"Wrong type hash", gpObjectTypes[i]->Name, MB_OK); } }