-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash_map.c
136 lines (111 loc) · 2.71 KB
/
hash_map.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "hash_map.h"
#define AVL_HASH_TAG 'hsah'
FAST_MUTEX m_hash_mutex = { 0 };
RTL_AVL_TABLE m_avl_table = { 0 };
RTL_GENERIC_COMPARE_RESULTS CompareHashRoutine(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ PVOID FirstStruct,
_In_ PVOID SecondStruct
)
{
UNREFERENCED_PARAMETER(Table);
HASH_DATA* p1 = (HASH_DATA*)FirstStruct;
HASH_DATA* p2 = (HASH_DATA*)SecondStruct;
if (p1->hash == p2->hash)
{
return GenericEqual;
}
return p1->hash > p2->hash ? GenericGreaterThan : GenericLessThan;
}
PVOID AllocateHashRoutine(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ CLONG ByteSize
)
{
UNREFERENCED_PARAMETER(Table);
return ExAllocatePoolWithTag(PagedPool, ByteSize, AVL_HASH_TAG);
}
VOID FreeHashRoutine(
_In_ struct _RTL_AVL_TABLE* Table,
PVOID Buffer
)
{
UNREFERENCED_PARAMETER(Table);
ExFreePoolWithTag(Buffer, AVL_HASH_TAG);
}
VOID InitHashMap()
{
ExInitializeFastMutex(&m_hash_mutex);
RtlInitializeGenericTableAvl(&m_avl_table,
CompareHashRoutine,
AllocateHashRoutine,
FreeHashRoutine,
NULL);
}
BOOLEAN DeleteElememt(ULONG64 Hash)
{
ExAcquireFastMutex(&m_hash_mutex);
ULONG64 buffer = Hash;
BOOLEAN result = RtlDeleteElementGenericTableAvl(&m_avl_table, &buffer);
ExReleaseFastMutex(&m_hash_mutex);
return result;
}
HASH_DATA* InsertElement(HASH_DATA* Data)
{
ExAcquireFastMutex(&m_hash_mutex);
PVOID result = RtlInsertElementGenericTableAvl(&m_avl_table,
Data,
sizeof(HASH_DATA),
NULL);
ExReleaseFastMutex(&m_hash_mutex);
return result;
}
HASH_DATA* LookupElementWithLock(ULONG64 Hash)
{
ExAcquireFastMutex(&m_hash_mutex);
ULONG64 buffer = Hash;
PVOID result = RtlLookupElementGenericTableAvl(&m_avl_table, &buffer);
ExReleaseFastMutex(&m_hash_mutex);
return result;
}
HASH_DATA* LookupElementWithoutLock(ULONG64 Hash)
{
ULONG64 buffer = Hash;
PVOID result = RtlLookupElementGenericTableAvl(&m_avl_table, &buffer);
return result;
}
ULONG NumberOfElement()
{
ExAcquireFastMutex(&m_hash_mutex);
ULONG result = RtlNumberGenericTableElementsAvl(&m_avl_table);
ExReleaseFastMutex(&m_hash_mutex);
return result;
}
HASH_DATA* GetElementByIndex(ULONG Index)
{
ExAcquireFastMutex(&m_hash_mutex);
PVOID result = RtlGetElementGenericTableAvl(&m_avl_table, Index);
ExReleaseFastMutex(&m_hash_mutex);
return result;
}
VOID EmptyElement()
{
ExAcquireFastMutex(&m_hash_mutex);
PVOID p;
while ((p = RtlGetElementGenericTableAvl(&m_avl_table, 0)) != NULL)
{
RtlDeleteElementGenericTableAvl(&m_avl_table, p);
}
ExReleaseFastMutex(&m_hash_mutex);
}
VOID EnumerateElement()
{
ExAcquireFastMutex(&m_hash_mutex);
for (PVOID p = RtlEnumerateGenericTableAvl(&m_avl_table, TRUE);
p != NULL;
p = RtlEnumerateGenericTableAvl(&m_avl_table, FALSE))
{
// do something
}
ExReleaseFastMutex(&m_hash_mutex);
}