- Merge the remaining portion of the wlan-bringup branch
[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 = 0;
39
40 /* free handle array */
41 if (HandleTable->CommittedHandles)
42 {
43 ArrayPointer = (PVOID)HandleTable->CommittedHandles;
44 NtFreeVirtualMemory(NtCurrentProcess(),
45 &ArrayPointer,
46 &ArraySize,
47 MEM_RELEASE);
48 }
49 }
50
51
52 /*
53 * @implemented
54 */
55 PRTL_HANDLE_TABLE_ENTRY NTAPI
56 RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
57 PULONG Index)
58 {
59 PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph;
60 NTSTATUS Status;
61 PRTL_HANDLE_TABLE_ENTRY retval;
62 PVOID ArrayPointer;
63 SIZE_T ArraySize;
64
65 pp_new = &HandleTable->FreeHandles;
66
67 if (HandleTable->FreeHandles == NULL)
68 {
69 /* no free handle available */
70 if (HandleTable->UnCommittedHandles == NULL)
71 {
72 /* allocate handle array */
73 ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
74 ArrayPointer = NULL;
75
76 /* FIXME - only reserve handles here! */
77 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
78 (PVOID*)&ArrayPointer,
79 0,
80 &ArraySize,
81 MEM_RESERVE | MEM_COMMIT,
82 PAGE_READWRITE);
83 if (!NT_SUCCESS(Status))
84 return NULL;
85
86 /* update handle array pointers */
87 HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
88 HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
89 HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
90 HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
91 }
92
93 /* FIXME - should check if handles need to be committed */
94
95 /* build free list in handle array */
96 ph = HandleTable->FreeHandles;
97 pph = pp_new;
98 while (ph < HandleTable->MaxReservedHandles)
99 {
100 *pph = ph;
101 pph = &ph->NextFree;
102 ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry);
103 }
104 *pph = 0;
105 }
106
107 /* remove handle from free list */
108 retval = *pp_new;
109 *pp_new = retval->NextFree;
110 retval->NextFree = NULL;
111
112 if (Index)
113 *Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) /
114 HandleTable->SizeOfHandleTableEntry);
115
116 return retval;
117 }
118
119
120 /*
121 * @implemented
122 */
123 BOOLEAN NTAPI
124 RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable,
125 PRTL_HANDLE_TABLE_ENTRY Handle)
126 {
127 #if DBG
128 /* check if handle is valid */
129 if (!RtlIsValidHandle(HandleTable, Handle))
130 {
131 DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
132 HandleTable, Handle, Handle ? Handle->Flags : 0);
133 return FALSE;
134 }
135 #endif
136
137 /* clear handle */
138 memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
139
140 /* add handle to free list */
141 Handle->NextFree = HandleTable->FreeHandles;
142 HandleTable->FreeHandles = Handle;
143
144 return TRUE;
145 }
146
147
148 /*
149 * @implemented
150 */
151 BOOLEAN NTAPI
152 RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
153 PRTL_HANDLE_TABLE_ENTRY Handle)
154 {
155 if ((HandleTable != NULL)
156 && (Handle >= HandleTable->CommittedHandles)
157 && (Handle < HandleTable->MaxReservedHandles)
158 && (Handle->Flags & RTL_HANDLE_VALID))
159 return TRUE;
160 return FALSE;
161 }
162
163
164 /*
165 * @implemented
166 */
167 BOOLEAN NTAPI
168 RtlIsValidIndexHandle(IN PRTL_HANDLE_TABLE HandleTable,
169 IN ULONG Index,
170 OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
171 {
172 PRTL_HANDLE_TABLE_ENTRY InternalHandle;
173
174 DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
175
176 if (HandleTable == NULL)
177 return FALSE;
178
179 DPRINT("Handles %p HandleSize 0x%lx\n",
180 HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
181
182 InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
183 (HandleTable->SizeOfHandleTableEntry * Index));
184 if (!RtlIsValidHandle(HandleTable, InternalHandle))
185 return FALSE;
186
187 DPRINT("InternalHandle %p\n", InternalHandle);
188
189 if (Handle != NULL)
190 *Handle = InternalHandle;
191
192 return TRUE;
193 }
194
195 /* EOF */