#include "stdafx.h" //-------------------------------------------------------------------------------------- PCOMMON_LST_ENTRY LstFindEntry( PCOMMON_LST list, PUNICODE_STRING ObjectName) { PCOMMON_LST_ENTRY ret = NULL; KIRQL OldIrql; KeAcquireSpinLock(&list->ListLock, &OldIrql); __try { PCOMMON_LST_ENTRY e = list->list_head; while (e) { // for empty object name - just return first entry if (ObjectName == NULL || RtlEqualUnicodeString(&e->ObjectName, ObjectName, TRUE)) { ret = e; break; } e = e->next; } } __finally { KeReleaseSpinLock(&list->ListLock, OldIrql); } return ret; } //-------------------------------------------------------------------------------------- PCOMMON_LST_ENTRY LstAddEntry( PCOMMON_LST list, PUNICODE_STRING ObjectName, PVOID Data, ULONG DataSize) { PCOMMON_LST_ENTRY ret = NULL; KIRQL OldIrql; KeAcquireSpinLock(&list->ListLock, &OldIrql); __try { // allocate single list entry PCOMMON_LST_ENTRY e = (PCOMMON_LST_ENTRY)M_ALLOC(sizeof(COMMON_LST_ENTRY)); if (e) { RtlZeroMemory(e, sizeof(COMMON_LST_ENTRY)); if (Data && DataSize > 0) { // allocate memory for custom data if (e->Data = M_ALLOC(DataSize)) { e->DataSize = DataSize; RtlCopyMemory(e->Data, Data, DataSize); } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n"); M_FREE(e); return NULL; } } // allocate and copy string name if (AllocUnicodeString(&e->ObjectName, ObjectName->MaximumLength)) { RtlCopyUnicodeString(&e->ObjectName, ObjectName); } else { if (e->Data) { M_FREE(e->Data); } M_FREE(e); return NULL; } // add it to list if (list->list_end) { list->list_end->next = e; e->prev = list->list_end; list->list_end = e; } else { list->list_end = list->list_head = e; } ret = e; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n"); } } __finally { KeReleaseSpinLock(&list->ListLock, OldIrql); } return ret; } //-------------------------------------------------------------------------------------- void LstFlush(PCOMMON_LST list) { KIRQL OldIrql; KeAcquireSpinLock(&list->ListLock, &OldIrql); __try { // delete all entries from list PCOMMON_LST_ENTRY e = list->list_head; while (e) { PCOMMON_LST_ENTRY e_tmp = e->next; // delete single entry from list if (e->prev) e->prev->next = e->next; if (e->next) e->next->prev = e->prev; if (list->list_head == e) list->list_head = e->next; if (list->list_end == e) list->list_end = e->prev; if (e->Data) { // delete data, if present M_FREE(e->Data); } // free name string RtlFreeUnicodeString(&e->ObjectName); M_FREE(e); e = e_tmp; } list->list_head = NULL; list->list_end = NULL; } __finally { KeReleaseSpinLock(&list->ListLock, OldIrql); } } //-------------------------------------------------------------------------------------- void LstDelEntry(PCOMMON_LST list, PCOMMON_LST_ENTRY e) { KIRQL OldIrql; KeAcquireSpinLock(&list->ListLock, &OldIrql); __try { // delete single entry from list if (e->prev) e->prev->next = e->next; if (e->next) e->next->prev = e->prev; if (list->list_head == e) list->list_head = e->next; if (list->list_end == e) list->list_end = e->prev; if (e->Data) { // delete data, if present M_FREE(e->Data); } // free name string RtlFreeUnicodeString(&e->ObjectName); M_FREE(e); } __finally { KeReleaseSpinLock(&list->ListLock, OldIrql); } } //-------------------------------------------------------------------------------------- PCOMMON_LST LstInit(void) { // allocate new list PCOMMON_LST ret = (PCOMMON_LST)M_ALLOC(sizeof(COMMON_LST)); if (ret) { ret->list_head = ret->list_end = NULL; KeInitializeSpinLock(&ret->ListLock); return ret; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n"); } return NULL; } //-------------------------------------------------------------------------------------- void LstFree(PCOMMON_LST list) { // flust list and free list descriptor LstFlush(list); M_FREE(list); } //-------------------------------------------------------------------------------------- // EoF