2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Handle table
5 * FILE: lib/rtl/handle.c
6 * PROGRAMMER: Eric Kohl
9 /* INCLUDES *****************************************************************/
16 /* GLOBALS ******************************************************************/
20 RtlInitializeHandleTable(
23 PRTL_HANDLE_TABLE HandleTable
)
25 /* Initialize handle table */
26 memset(HandleTable
, 0, sizeof(RTL_HANDLE_TABLE
));
27 HandleTable
->MaximumNumberOfHandles
= TableSize
;
28 HandleTable
->SizeOfHandleTableEntry
= HandleSize
;
37 RtlDestroyHandleTable(
38 PRTL_HANDLE_TABLE HandleTable
)
43 /* free handle array */
44 if (HandleTable
->CommittedHandles
)
46 ArrayPointer
= (PVOID
)HandleTable
->CommittedHandles
;
47 NtFreeVirtualMemory(NtCurrentProcess(),
58 PRTL_HANDLE_TABLE_ENTRY
61 PRTL_HANDLE_TABLE HandleTable
,
64 PRTL_HANDLE_TABLE_ENTRY CurrentEntry
, NextEntry
;
66 PRTL_HANDLE_TABLE_ENTRY HandleEntry
;
69 ULONG i
, NumberOfEntries
;
71 /* Check if we are out of free handles entries */
72 if (HandleTable
->FreeHandles
== NULL
)
74 /* Check if we don't have uncomitted handle entries yet */
75 if (HandleTable
->UnCommittedHandles
== NULL
)
77 /* Use the maximum number of handle entries */
78 ArraySize
= HandleTable
->SizeOfHandleTableEntry
* HandleTable
->MaximumNumberOfHandles
;
82 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
88 if (!NT_SUCCESS(Status
))
91 /* Update handle array pointers */
92 HandleTable
->UnCommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
93 HandleTable
->MaxReservedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)ArrayPointer
+ ArraySize
);
96 /* Commit one reserved handle entry page */
97 ArraySize
= PAGE_SIZE
;
98 ArrayPointer
= HandleTable
->UnCommittedHandles
;
99 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
105 if (!NT_SUCCESS(Status
))
108 /* Update handle array pointers */
109 HandleTable
->FreeHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
110 HandleTable
->CommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
111 HandleTable
->UnCommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)ArrayPointer
+ ArraySize
);
113 /* Calculate the number of entries we can store in the array */
114 NumberOfEntries
= ArraySize
/ HandleTable
->SizeOfHandleTableEntry
;
116 /* Loop all entries, except the last one */
117 CurrentEntry
= HandleTable
->FreeHandles
;
118 for (i
= 0; i
< NumberOfEntries
- 1; i
++)
120 /* Calculate the address of the next handle entry */
121 NextEntry
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)CurrentEntry
+
122 HandleTable
->SizeOfHandleTableEntry
);
124 /* Link the next entry */
125 CurrentEntry
->NextFree
= NextEntry
;
127 /* Continue with the next entry */
128 CurrentEntry
= NextEntry
;
131 /* CurrentEntry now points to the last entry, terminate the list here */
132 CurrentEntry
->NextFree
= NULL
;
135 /* remove handle from free list */
136 HandleEntry
= HandleTable
->FreeHandles
;
137 HandleTable
->FreeHandles
= HandleEntry
->NextFree
;
138 HandleEntry
->NextFree
= NULL
;
142 *Index
= ((ULONG
)((ULONG_PTR
)HandleEntry
- (ULONG_PTR
)HandleTable
->CommittedHandles
) /
143 HandleTable
->SizeOfHandleTableEntry
);
156 PRTL_HANDLE_TABLE HandleTable
,
157 PRTL_HANDLE_TABLE_ENTRY Handle
)
160 /* check if handle is valid */
161 if (!RtlIsValidHandle(HandleTable
, Handle
))
163 DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
164 HandleTable
, Handle
, Handle
? Handle
->Flags
: 0);
170 memset(Handle
, 0, HandleTable
->SizeOfHandleTableEntry
);
172 /* add handle to free list */
173 Handle
->NextFree
= HandleTable
->FreeHandles
;
174 HandleTable
->FreeHandles
= Handle
;
186 PRTL_HANDLE_TABLE HandleTable
,
187 PRTL_HANDLE_TABLE_ENTRY Handle
)
189 if ((HandleTable
!= NULL
)
190 && (Handle
>= HandleTable
->CommittedHandles
)
191 && (Handle
< HandleTable
->MaxReservedHandles
)
192 && (Handle
->Flags
& RTL_HANDLE_VALID
))
205 RtlIsValidIndexHandle(
206 IN PRTL_HANDLE_TABLE HandleTable
,
208 OUT PRTL_HANDLE_TABLE_ENTRY
*Handle
)
210 PRTL_HANDLE_TABLE_ENTRY InternalHandle
;
212 DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable
, Index
, Handle
);
214 if (HandleTable
== NULL
)
217 DPRINT("Handles %p HandleSize 0x%lx\n",
218 HandleTable
->CommittedHandles
, HandleTable
->SizeOfHandleTableEntry
);
220 InternalHandle
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)HandleTable
->CommittedHandles
+
221 (HandleTable
->SizeOfHandleTableEntry
* Index
));
222 if (!RtlIsValidHandle(HandleTable
, InternalHandle
))
225 DPRINT("InternalHandle %p\n", InternalHandle
);
228 *Handle
= InternalHandle
;