mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:52:56 +00:00
[RTL]
- Implement dynamic allocation of handle entry pages in RtlAllocateHandle - Fix a possible NULL pointer dereference svn path=/trunk/; revision=57942
This commit is contained in:
parent
2cdf5f5ce0
commit
be5ff02f5e
1 changed files with 51 additions and 28 deletions
|
@ -60,66 +60,89 @@ RtlAllocateHandle(
|
||||||
PRTL_HANDLE_TABLE HandleTable,
|
PRTL_HANDLE_TABLE HandleTable,
|
||||||
PULONG Index)
|
PULONG Index)
|
||||||
{
|
{
|
||||||
PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph;
|
PRTL_HANDLE_TABLE_ENTRY CurrentEntry, NextEntry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PRTL_HANDLE_TABLE_ENTRY retval;
|
PRTL_HANDLE_TABLE_ENTRY HandleEntry;
|
||||||
PVOID ArrayPointer;
|
PVOID ArrayPointer;
|
||||||
SIZE_T ArraySize;
|
SIZE_T ArraySize;
|
||||||
|
ULONG i, NumberOfEntries;
|
||||||
|
|
||||||
pp_new = &HandleTable->FreeHandles;
|
/* Check if we are out of free handles entries */
|
||||||
|
|
||||||
if (HandleTable->FreeHandles == NULL)
|
if (HandleTable->FreeHandles == NULL)
|
||||||
{
|
{
|
||||||
/* no free handle available */
|
/* Check if we don't have uncomitted handle entries yet */
|
||||||
if (HandleTable->UnCommittedHandles == NULL)
|
if (HandleTable->UnCommittedHandles == NULL)
|
||||||
{
|
{
|
||||||
/* allocate handle array */
|
/* Use the maximum number of handle entries */
|
||||||
ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
|
ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
|
||||||
ArrayPointer = NULL;
|
ArrayPointer = NULL;
|
||||||
|
|
||||||
/* FIXME - only reserve handles here! */
|
/* Reserve memory */
|
||||||
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||||
(PVOID*)&ArrayPointer,
|
&ArrayPointer,
|
||||||
0,
|
0,
|
||||||
&ArraySize,
|
&ArraySize,
|
||||||
MEM_RESERVE | MEM_COMMIT,
|
MEM_RESERVE,
|
||||||
PAGE_READWRITE);
|
PAGE_READWRITE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* update handle array pointers */
|
/* 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;
|
HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
|
||||||
|
HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME - should check if handles need to be committed */
|
/* 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;
|
||||||
|
|
||||||
/* build free list in handle array */
|
/* Update handle array pointers */
|
||||||
ph = HandleTable->FreeHandles;
|
HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
|
||||||
pph = pp_new;
|
HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
|
||||||
while (ph < HandleTable->MaxReservedHandles)
|
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++)
|
||||||
{
|
{
|
||||||
*pph = ph;
|
/* Calculate the address of the next handle entry */
|
||||||
pph = &ph->NextFree;
|
NextEntry = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)CurrentEntry +
|
||||||
ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry);
|
HandleTable->SizeOfHandleTableEntry);
|
||||||
|
|
||||||
|
/* Link the next entry */
|
||||||
|
CurrentEntry->NextFree = NextEntry;
|
||||||
|
|
||||||
|
/* Continue with the next entry */
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
}
|
}
|
||||||
*pph = 0;
|
|
||||||
|
/* CurrentEntry now points to the last entry, terminate the list here */
|
||||||
|
CurrentEntry->NextFree = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove handle from free list */
|
/* remove handle from free list */
|
||||||
retval = *pp_new;
|
HandleEntry = HandleTable->FreeHandles;
|
||||||
*pp_new = retval->NextFree;
|
HandleTable->FreeHandles = HandleEntry->NextFree;
|
||||||
retval->NextFree = NULL;
|
HandleEntry->NextFree = NULL;
|
||||||
|
|
||||||
if (Index)
|
if (Index)
|
||||||
{
|
{
|
||||||
*Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) /
|
*Index = ((ULONG)((ULONG_PTR)HandleEntry - (ULONG_PTR)HandleTable->CommittedHandles) /
|
||||||
HandleTable->SizeOfHandleTableEntry);
|
HandleTable->SizeOfHandleTableEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return HandleEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue