* PROJECT: ReactOS system libraries
* PURPOSE: Handle table
* FILE: lib/rtl/handle.c
- * PROGRAMER: Eric Kohl
+ * PROGRAMMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
/* GLOBALS ******************************************************************/
-VOID NTAPI
-RtlInitializeHandleTable(ULONG TableSize,
- ULONG HandleSize,
- PRTL_HANDLE_TABLE HandleTable)
+VOID
+NTAPI
+RtlInitializeHandleTable(
+ ULONG TableSize,
+ ULONG HandleSize,
+ PRTL_HANDLE_TABLE HandleTable)
{
- /* initialize handle table */
- memset(HandleTable,
- 0,
- sizeof(RTL_HANDLE_TABLE));
- HandleTable->MaximumNumberOfHandles = TableSize;
- HandleTable->SizeOfHandleTableEntry = HandleSize;
+ /* Initialize handle table */
+ memset(HandleTable, 0, sizeof(RTL_HANDLE_TABLE));
+ HandleTable->MaximumNumberOfHandles = TableSize;
+ HandleTable->SizeOfHandleTableEntry = HandleSize;
}
/*
* @implemented
*/
-VOID NTAPI
-RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
+VOID
+NTAPI
+RtlDestroyHandleTable(
+ PRTL_HANDLE_TABLE HandleTable)
{
- PVOID ArrayPointer;
- SIZE_T ArraySize;
+ PVOID ArrayPointer;
+ SIZE_T ArraySize = 0;
- /* free handle array */
- if (HandleTable->CommittedHandles)
- {
+ /* free handle array */
+ if (HandleTable->CommittedHandles)
+ {
ArrayPointer = (PVOID)HandleTable->CommittedHandles;
- ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
NtFreeVirtualMemory(NtCurrentProcess(),
- &ArrayPointer,
- &ArraySize,
- MEM_RELEASE);
- }
+ &ArrayPointer,
+ &ArraySize,
+ MEM_RELEASE);
+ }
}
/*
* @implemented
*/
-PRTL_HANDLE_TABLE_ENTRY NTAPI
-RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
- PULONG Index)
+PRTL_HANDLE_TABLE_ENTRY
+NTAPI
+RtlAllocateHandle(
+ PRTL_HANDLE_TABLE HandleTable,
+ PULONG Index)
{
- PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph;
- NTSTATUS Status;
- PRTL_HANDLE_TABLE_ENTRY retval;
- PVOID ArrayPointer;
- SIZE_T ArraySize;
-
- pp_new = &HandleTable->FreeHandles;
-
- if (HandleTable->FreeHandles == NULL)
- {
- /* no free handle available */
- if (HandleTable->UnCommittedHandles == NULL)
- {
- /* allocate handle array */
- ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
- ArrayPointer = NULL;
-
- /* FIXME - only reserve handles here! */
- Status = NtAllocateVirtualMemory(NtCurrentProcess(),
- (PVOID*)&ArrayPointer,
- 0,
- &ArraySize,
- MEM_RESERVE | MEM_COMMIT,
- PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- return NULL;
-
- /* update handle array pointers */
- HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
- HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
- HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
- HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
- }
-
- /* FIXME - should check if handles need to be committed */
-
- /* build free list in handle array */
- ph = HandleTable->FreeHandles;
- pph = pp_new;
- while (ph < HandleTable->MaxReservedHandles)
- {
- *pph = ph;
- pph = &ph->NextFree;
- ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry);
- }
- *pph = 0;
- }
-
- /* remove handle from free list */
- retval = *pp_new;
- *pp_new = retval->NextFree;
- retval->NextFree = NULL;
-
- if (Index)
- *Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) /
- HandleTable->SizeOfHandleTableEntry);
-
- return retval;
+ PRTL_HANDLE_TABLE_ENTRY CurrentEntry, NextEntry;
+ NTSTATUS Status;
+ PRTL_HANDLE_TABLE_ENTRY HandleEntry;
+ PVOID ArrayPointer;
+ SIZE_T ArraySize;
+ ULONG i, NumberOfEntries;
+
+ /* Check if we are out of free handles entries */
+ if (HandleTable->FreeHandles == NULL)
+ {
+ /* Check if we don't have uncomitted handle entries yet */
+ if (HandleTable->UnCommittedHandles == NULL)
+ {
+ /* Use the maximum number of handle entries */
+ ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
+ ArrayPointer = NULL;
+
+ /* Reserve memory */
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &ArrayPointer,
+ 0,
+ &ArraySize,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ /* Update handle array pointers */
+ HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+ HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
+ }
+
+ /* Commit one reserved handle entry page */
+ ArraySize = PAGE_SIZE;
+ ArrayPointer = HandleTable->UnCommittedHandles;
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &ArrayPointer,
+ 0,
+ &ArraySize,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ /* Update handle array pointers */
+ HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+ HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+ HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
+
+ /* Calculate the number of entries we can store in the array */
+ NumberOfEntries = ArraySize / HandleTable->SizeOfHandleTableEntry;
+
+ /* Loop all entries, except the last one */
+ CurrentEntry = HandleTable->FreeHandles;
+ for (i = 0; i < NumberOfEntries - 1; i++)
+ {
+ /* Calculate the address of the next handle entry */
+ NextEntry = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)CurrentEntry +
+ HandleTable->SizeOfHandleTableEntry);
+
+ /* Link the next entry */
+ CurrentEntry->NextFree = NextEntry;
+
+ /* Continue with the next entry */
+ CurrentEntry = NextEntry;
+ }
+
+ /* CurrentEntry now points to the last entry, terminate the list here */
+ CurrentEntry->NextFree = NULL;
+ }
+
+ /* remove handle from free list */
+ HandleEntry = HandleTable->FreeHandles;
+ HandleTable->FreeHandles = HandleEntry->NextFree;
+ HandleEntry->NextFree = NULL;
+
+ if (Index)
+ {
+ *Index = ((ULONG)((ULONG_PTR)HandleEntry - (ULONG_PTR)HandleTable->CommittedHandles) /
+ HandleTable->SizeOfHandleTableEntry);
+ }
+
+ return HandleEntry;
}
/*
* @implemented
*/
-BOOLEAN NTAPI
-RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable,
- PRTL_HANDLE_TABLE_ENTRY Handle)
+BOOLEAN
+NTAPI
+RtlFreeHandle(
+ PRTL_HANDLE_TABLE HandleTable,
+ PRTL_HANDLE_TABLE_ENTRY Handle)
{
#if DBG
- /* check if handle is valid */
- if (!RtlIsValidHandle(HandleTable, Handle))
- {
- DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
- HandleTable, Handle, Handle ? Handle->Flags : 0);
- return FALSE;
- }
+ /* check if handle is valid */
+ if (!RtlIsValidHandle(HandleTable, Handle))
+ {
+ DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
+ HandleTable, Handle, Handle ? Handle->Flags : 0);
+ return FALSE;
+ }
#endif
- /* clear handle */
- memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
+ /* clear handle */
+ memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
- /* add handle to free list */
- Handle->NextFree = HandleTable->FreeHandles;
- HandleTable->FreeHandles = Handle;
+ /* add handle to free list */
+ Handle->NextFree = HandleTable->FreeHandles;
+ HandleTable->FreeHandles = Handle;
- return TRUE;
+ return TRUE;
}
/*
* @implemented
*/
-BOOLEAN NTAPI
-RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
- PRTL_HANDLE_TABLE_ENTRY Handle)
+BOOLEAN
+NTAPI
+RtlIsValidHandle(
+ PRTL_HANDLE_TABLE HandleTable,
+ PRTL_HANDLE_TABLE_ENTRY Handle)
{
- if ((HandleTable != NULL)
- && (Handle >= HandleTable->CommittedHandles)
- && (Handle < HandleTable->MaxReservedHandles)
- && (Handle->Flags & RTL_HANDLE_VALID))
- return TRUE;
- return FALSE;
+ if ((HandleTable != NULL)
+ && (Handle >= HandleTable->CommittedHandles)
+ && (Handle < HandleTable->MaxReservedHandles)
+ && (Handle->Flags & RTL_HANDLE_VALID))
+ {
+ return TRUE;
+ }
+ return FALSE;
}
/*
* @implemented
*/
-BOOLEAN NTAPI
-RtlIsValidIndexHandle(IN PRTL_HANDLE_TABLE HandleTable,
- IN ULONG Index,
- OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
+BOOLEAN
+NTAPI
+RtlIsValidIndexHandle(
+ IN PRTL_HANDLE_TABLE HandleTable,
+ IN ULONG Index,
+ OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
{
- PRTL_HANDLE_TABLE_ENTRY InternalHandle;
+ PRTL_HANDLE_TABLE_ENTRY InternalHandle;
- DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
+ DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
- if (HandleTable == NULL)
- return FALSE;
+ if (HandleTable == NULL)
+ return FALSE;
- DPRINT("Handles %p HandleSize 0x%lx\n",
- HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
+ DPRINT("Handles %p HandleSize 0x%lx\n",
+ HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
- InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
- (HandleTable->SizeOfHandleTableEntry * Index));
- if (!RtlIsValidHandle(HandleTable, InternalHandle))
- return FALSE;
+ InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
+ (HandleTable->SizeOfHandleTableEntry * Index));
+ if (!RtlIsValidHandle(HandleTable, InternalHandle))
+ return FALSE;
- DPRINT("InternalHandle %p\n", InternalHandle);
+ DPRINT("InternalHandle %p\n", InternalHandle);
- if (Handle != NULL)
- *Handle = InternalHandle;
+ if (Handle != NULL)
+ *Handle = InternalHandle;
- return TRUE;
+ return TRUE;
}
/* EOF */