Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * PURPOSE: Handle table * FILE: lib/rtl/handle.c * PROGRAMMER: Eric Kohl */
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG#include <debug.h>
/* GLOBALS ******************************************************************/
VOIDNTAPIRtlInitializeHandleTable( ULONG TableSize, ULONG HandleSize, PRTL_HANDLE_TABLE HandleTable){ /* Initialize handle table */ memset(HandleTable, 0, sizeof(RTL_HANDLE_TABLE)); HandleTable->MaximumNumberOfHandles = TableSize; HandleTable->SizeOfHandleTableEntry = HandleSize;}
/* * @implemented */VOIDNTAPIRtlDestroyHandleTable( PRTL_HANDLE_TABLE HandleTable){ PVOID ArrayPointer; SIZE_T ArraySize = 0;
/* free handle array */ if (HandleTable->CommittedHandles) { ArrayPointer = (PVOID)HandleTable->CommittedHandles; NtFreeVirtualMemory(NtCurrentProcess(), &ArrayPointer, &ArraySize, MEM_RELEASE); }}
/* * @implemented */PRTL_HANDLE_TABLE_ENTRYNTAPIRtlAllocateHandle( PRTL_HANDLE_TABLE HandleTable, PULONG Index){ 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 uncommitted 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->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer; 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->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 */BOOLEANNTAPIRtlFreeHandle( 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; }#endif
/* clear handle */ memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
/* add handle to free list */ Handle->NextFree = HandleTable->FreeHandles; HandleTable->FreeHandles = Handle;
return TRUE;}
/* * @implemented */BOOLEANNTAPIRtlIsValidHandle( 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;}
/* * @implemented */BOOLEANNTAPIRtlIsValidIndexHandle( IN PRTL_HANDLE_TABLE HandleTable, IN ULONG Index, OUT PRTL_HANDLE_TABLE_ENTRY *Handle){ PRTL_HANDLE_TABLE_ENTRY InternalHandle;
DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
if (HandleTable == NULL) return FALSE;
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;
DPRINT("InternalHandle %p\n", InternalHandle);
if (Handle != NULL) *Handle = InternalHandle;
return TRUE;}
/* EOF */