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 * PROGRAMMER: Eric Kohl
8 /* INCLUDES *****************************************************************/
15 /* GLOBALS ******************************************************************/
19 RtlInitializeHandleTable(
22 PRTL_HANDLE_TABLE HandleTable
)
24 /* Initialize handle table */
25 memset(HandleTable
, 0, sizeof(RTL_HANDLE_TABLE
));
26 HandleTable
->MaximumNumberOfHandles
= TableSize
;
27 HandleTable
->SizeOfHandleTableEntry
= HandleSize
;
36 RtlDestroyHandleTable(
37 PRTL_HANDLE_TABLE HandleTable
)
42 /* free handle array */
43 if (HandleTable
->CommittedHandles
)
45 ArrayPointer
= (PVOID
)HandleTable
->CommittedHandles
;
46 NtFreeVirtualMemory(NtCurrentProcess(),
57 PRTL_HANDLE_TABLE_ENTRY
60 PRTL_HANDLE_TABLE HandleTable
,
63 PRTL_HANDLE_TABLE_ENTRY CurrentEntry
, NextEntry
;
65 PRTL_HANDLE_TABLE_ENTRY HandleEntry
;
68 ULONG i
, NumberOfEntries
;
70 /* Check if we are out of free handles entries */
71 if (HandleTable
->FreeHandles
== NULL
)
73 /* Check if we don't have uncomitted handle entries yet */
74 if (HandleTable
->UnCommittedHandles
== NULL
)
76 /* Use the maximum number of handle entries */
77 ArraySize
= HandleTable
->SizeOfHandleTableEntry
* HandleTable
->MaximumNumberOfHandles
;
81 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
87 if (!NT_SUCCESS(Status
))
90 /* Update handle array pointers */
91 HandleTable
->UnCommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
92 HandleTable
->MaxReservedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)ArrayPointer
+ ArraySize
);
95 /* Commit one reserved handle entry page */
96 ArraySize
= PAGE_SIZE
;
97 ArrayPointer
= HandleTable
->UnCommittedHandles
;
98 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
104 if (!NT_SUCCESS(Status
))
107 /* Update handle array pointers */
108 HandleTable
->FreeHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
109 HandleTable
->CommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)ArrayPointer
;
110 HandleTable
->UnCommittedHandles
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)ArrayPointer
+ ArraySize
);
112 /* Calculate the number of entries we can store in the array */
113 NumberOfEntries
= ArraySize
/ HandleTable
->SizeOfHandleTableEntry
;
115 /* Loop all entries, except the last one */
116 CurrentEntry
= HandleTable
->FreeHandles
;
117 for (i
= 0; i
< NumberOfEntries
- 1; i
++)
119 /* Calculate the address of the next handle entry */
120 NextEntry
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)CurrentEntry
+
121 HandleTable
->SizeOfHandleTableEntry
);
123 /* Link the next entry */
124 CurrentEntry
->NextFree
= NextEntry
;
126 /* Continue with the next entry */
127 CurrentEntry
= NextEntry
;
130 /* CurrentEntry now points to the last entry, terminate the list here */
131 CurrentEntry
->NextFree
= NULL
;
134 /* remove handle from free list */
135 HandleEntry
= HandleTable
->FreeHandles
;
136 HandleTable
->FreeHandles
= HandleEntry
->NextFree
;
137 HandleEntry
->NextFree
= NULL
;
141 *Index
= ((ULONG
)((ULONG_PTR
)HandleEntry
- (ULONG_PTR
)HandleTable
->CommittedHandles
) /
142 HandleTable
->SizeOfHandleTableEntry
);
155 PRTL_HANDLE_TABLE HandleTable
,
156 PRTL_HANDLE_TABLE_ENTRY Handle
)
159 /* check if handle is valid */
160 if (!RtlIsValidHandle(HandleTable
, Handle
))
162 DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
163 HandleTable
, Handle
, Handle
? Handle
->Flags
: 0);
169 memset(Handle
, 0, HandleTable
->SizeOfHandleTableEntry
);
171 /* add handle to free list */
172 Handle
->NextFree
= HandleTable
->FreeHandles
;
173 HandleTable
->FreeHandles
= Handle
;
185 PRTL_HANDLE_TABLE HandleTable
,
186 PRTL_HANDLE_TABLE_ENTRY Handle
)
188 if ((HandleTable
!= NULL
)
189 && (Handle
>= HandleTable
->CommittedHandles
)
190 && (Handle
< HandleTable
->MaxReservedHandles
)
191 && (Handle
->Flags
& RTL_HANDLE_VALID
))
204 RtlIsValidIndexHandle(
205 IN PRTL_HANDLE_TABLE HandleTable
,
207 OUT PRTL_HANDLE_TABLE_ENTRY
*Handle
)
209 PRTL_HANDLE_TABLE_ENTRY InternalHandle
;
211 DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable
, Index
, Handle
);
213 if (HandleTable
== NULL
)
216 DPRINT("Handles %p HandleSize 0x%lx\n",
217 HandleTable
->CommittedHandles
, HandleTable
->SizeOfHandleTableEntry
);
219 InternalHandle
= (PRTL_HANDLE_TABLE_ENTRY
)((ULONG_PTR
)HandleTable
->CommittedHandles
+
220 (HandleTable
->SizeOfHandleTableEntry
* Index
));
221 if (!RtlIsValidHandle(HandleTable
, InternalHandle
))
224 DPRINT("InternalHandle %p\n", InternalHandle
);
227 *Handle
= InternalHandle
;