Removed outdated email addresses.
[reactos.git] / reactos / lib / rtl / handle.c
1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * PURPOSE: Handle table
4 * FILE: lib/rtl/handle.c
5 * PROGRAMER: Eric Kohl
6 */
7
8 /* INCLUDES *****************************************************************/
9
10 #include <rtl.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ******************************************************************/
16
17 VOID NTAPI
18 RtlInitializeHandleTable(ULONG TableSize,
19 ULONG HandleSize,
20 PRTL_HANDLE_TABLE HandleTable)
21 {
22 /* initialize handle table */
23 memset(HandleTable,
24 0,
25 sizeof(RTL_HANDLE_TABLE));
26 HandleTable->MaximumNumberOfHandles = TableSize;
27 HandleTable->SizeOfHandleTableEntry = HandleSize;
28 }
29
30
31 /*
32 * @implemented
33 */
34 VOID NTAPI
35 RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
36 {
37 PVOID ArrayPointer;
38 SIZE_T ArraySize;
39
40 /* free handle array */
41 if (HandleTable->CommittedHandles)
42 {
43 ArrayPointer = (PVOID)HandleTable->CommittedHandles;
44 ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
45 NtFreeVirtualMemory(NtCurrentProcess(),
46 &ArrayPointer,
47 &ArraySize,
48 MEM_RELEASE);
49 }
50 }
51
52
53 /*
54 * @implemented
55 */
56 PRTL_HANDLE_TABLE_ENTRY NTAPI
57 RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
58 PULONG Index)
59 {
60 PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph;
61 NTSTATUS Status;
62 PRTL_HANDLE_TABLE_ENTRY retval;
63 PVOID ArrayPointer;
64 SIZE_T ArraySize;
65
66 pp_new = &HandleTable->FreeHandles;
67
68 if (HandleTable->FreeHandles == NULL)
69 {
70 /* no free handle available */
71 if (HandleTable->UnCommittedHandles == NULL)
72 {
73 /* allocate handle array */
74 ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
75 ArrayPointer = NULL;
76
77 /* FIXME - only reserve handles here! */
78 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
79 (PVOID*)&ArrayPointer,
80 0,
81 &ArraySize,
82 MEM_RESERVE | MEM_COMMIT,
83 PAGE_READWRITE);
84 if (!NT_SUCCESS(Status))
85 return NULL;
86
87 /* update handle array pointers */
88 HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
89 HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
90 HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
91 HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
92 }
93
94 /* FIXME - should check if handles need to be committed */
95
96 /* build free list in handle array */
97 ph = HandleTable->FreeHandles;
98 pph = pp_new;
99 while (ph < HandleTable->MaxReservedHandles)
100 {
101 *pph = ph;
102 pph = &ph->NextFree;
103 ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry);
104 }
105 *pph = 0;
106 }
107
108 /* remove handle from free list */
109 retval = *pp_new;
110 *pp_new = retval->NextFree;
111 retval->NextFree = NULL;
112
113 if (Index)
114 *Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) /
115 HandleTable->SizeOfHandleTableEntry);
116
117 return retval;
118 }
119
120
121 /*
122 * @implemented
123 */
124 BOOLEAN NTAPI
125 RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable,
126 PRTL_HANDLE_TABLE_ENTRY Handle)
127 {
128 #if DBG
129 /* check if handle is valid */
130 if (!RtlIsValidHandle(HandleTable, Handle))
131 {
132 DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
133 HandleTable, Handle, Handle ? Handle->Flags : 0);
134 return FALSE;
135 }
136 #endif
137
138 /* clear handle */
139 memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
140
141 /* add handle to free list */
142 Handle->NextFree = HandleTable->FreeHandles;
143 HandleTable->FreeHandles = Handle;
144
145 return TRUE;
146 }
147
148
149 /*
150 * @implemented
151 */
152 BOOLEAN NTAPI
153 RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
154 PRTL_HANDLE_TABLE_ENTRY Handle)
155 {
156 if ((HandleTable != NULL)
157 && (Handle >= HandleTable->CommittedHandles)
158 && (Handle < HandleTable->MaxReservedHandles)
159 && (Handle->Flags & RTL_HANDLE_VALID))
160 return TRUE;
161 return FALSE;
162 }
163
164
165 /*
166 * @implemented
167 */
168 BOOLEAN NTAPI
169 RtlIsValidIndexHandle(IN PRTL_HANDLE_TABLE HandleTable,
170 IN ULONG Index,
171 OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
172 {
173 PRTL_HANDLE_TABLE_ENTRY InternalHandle;
174
175 DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
176
177 if (HandleTable == NULL)
178 return FALSE;
179
180 DPRINT("Handles %p HandleSize 0x%lx\n",
181 HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
182
183 InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
184 (HandleTable->SizeOfHandleTableEntry * Index));
185 if (!RtlIsValidHandle(HandleTable, InternalHandle))
186 return FALSE;
187
188 DPRINT("InternalHandle %p\n", InternalHandle);
189
190 if (Handle != NULL)
191 *Handle = InternalHandle;
192
193 return TRUE;
194 }
195
196 /* EOF */