move the rest of the alread defined tags to the private tag.h
[reactos.git] / reactos / ntoskrnl / rtl / handle.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/rtl/handle.c
6 * PURPOSE: Handle table
7 *
8 * PROGRAMMERS: Eric Kohl <ekohl@rz-online.de>
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 static BOOLEAN
18 RtlpIsValidHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE Handle);
19 static BOOLEAN
20 RtlpIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE *Handle, ULONG Index);
21
22
23 /* FUNCTIONS *****************************************************************/
24
25 VOID
26 RtlpInitializeHandleTable(ULONG TableSize,
27 PRTL_HANDLE_TABLE HandleTable)
28 {
29 /* initialize handle table */
30 memset(HandleTable,
31 0,
32 sizeof(RTL_HANDLE_TABLE));
33 HandleTable->TableSize = TableSize;
34 }
35
36
37 VOID
38 RtlpDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
39 {
40 ExFreePool((PVOID)HandleTable->Handles);
41 }
42
43
44 BOOLEAN
45 RtlpAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
46 PVOID Object,
47 PULONG Index)
48 {
49 RTL_HANDLE **pp_new,**pph,*ph;
50 PRTL_HANDLE retval;
51 PVOID ArrayPointer;
52 ULONG ArraySize;
53
54 if (Index == NULL)
55 return FALSE;
56
57 pp_new = &HandleTable->FirstFree;
58
59 if (HandleTable->FirstFree == NULL)
60 {
61 /* no free handle available */
62 if (HandleTable->LastUsed == NULL)
63 {
64 /* allocate handle array */
65 ArraySize = sizeof(RTL_HANDLE) * HandleTable->TableSize;
66 ArrayPointer = ExAllocatePoolWithTag(NonPagedPool,
67 ArraySize,
68 TAG_HDTB);
69 if (ArrayPointer == NULL)
70 return FALSE;
71
72 /* update handle array pointers */
73 HandleTable->Handles = (PRTL_HANDLE)ArrayPointer;
74 HandleTable->Limit = (PRTL_HANDLE)((char*)ArrayPointer + ArraySize);
75 HandleTable->LastUsed = (PRTL_HANDLE)ArrayPointer;
76 }
77
78 /* build free list in handle array */
79 ph = HandleTable->LastUsed;
80 pph = pp_new;
81 while (ph < HandleTable->Limit)
82 {
83 *pph = ph;
84 pph = &ph->Next;
85 ph = (PRTL_HANDLE)((ULONG)ph + sizeof(RTL_HANDLE));
86 }
87 *pph = 0;
88 }
89
90 /* remove handle from free list */
91 retval = *pp_new;
92 *pp_new = retval->Next;
93 retval->Next = NULL;
94 retval->Object = Object;
95
96 *Index = ((ULONG)retval - (ULONG)HandleTable->Handles) / sizeof(RTL_HANDLE);
97
98 return TRUE;
99 }
100
101
102 BOOLEAN
103 RtlpFreeHandle(PRTL_HANDLE_TABLE HandleTable,
104 ULONG Index)
105 {
106 PRTL_HANDLE Handle;
107
108 /* check if handle is valid */
109 if (! RtlpIsValidIndexHandle(HandleTable,
110 &Handle,
111 Index))
112 return FALSE;
113
114 /* clear handle */
115 memset(Handle, 0, sizeof(RTL_HANDLE));
116
117 /* add handle to free list */
118 Handle->Next = HandleTable->FirstFree;
119 HandleTable->FirstFree = Handle;
120
121 return TRUE;
122 }
123
124
125 static BOOLEAN
126 RtlpIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
127 PRTL_HANDLE Handle)
128 {
129 if ((HandleTable != NULL)
130 && (Handle != NULL)
131 && (Handle >= HandleTable->Handles)
132 && (Handle < HandleTable->Limit))
133 return TRUE;
134 return FALSE;
135 }
136
137
138 static BOOLEAN
139 RtlpIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable,
140 PRTL_HANDLE *Handle,
141 ULONG Index)
142 {
143 PRTL_HANDLE InternalHandle;
144
145 DPRINT("RtlpIsValidIndexHandle(HandleTable %p Handle %p Index %x)\n", HandleTable, Handle, Index);
146
147 if (HandleTable == NULL)
148 return FALSE;
149
150 DPRINT("Handles %p\n", HandleTable->Handles);
151
152 InternalHandle = (PRTL_HANDLE)((ULONG)HandleTable->Handles + sizeof(RTL_HANDLE) * Index);
153 if (RtlpIsValidHandle(HandleTable, InternalHandle) == FALSE)
154 return FALSE;
155
156 DPRINT("InternalHandle %p\n", InternalHandle);
157
158 if (Handle != NULL)
159 *Handle = InternalHandle;
160
161 return TRUE;
162 }
163
164 PVOID
165 RtlpMapHandleToPointer(PRTL_HANDLE_TABLE HandleTable,
166 ULONG Index)
167 {
168 PRTL_HANDLE Handle;
169
170 if (!RtlpIsValidIndexHandle(HandleTable,
171 &Handle,
172 Index))
173 {
174 return NULL;
175 }
176
177 return Handle->Object;
178 }
179
180 /* EOF */