mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 14:45:06 +00:00
[NTOSKRNL]: Implement ExAllocatePoolWithQuotaTag. However PsChargeProcessPoolQuota is still unimplemented so nothing really gets charged (we do write the owner process, though).
svn path=/trunk/; revision=60002
This commit is contained in:
parent
144100a4e2
commit
36f1e2f5d1
|
@ -2511,11 +2511,114 @@ ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType,
|
||||||
IN SIZE_T NumberOfBytes,
|
IN SIZE_T NumberOfBytes,
|
||||||
IN ULONG Tag)
|
IN ULONG Tag)
|
||||||
{
|
{
|
||||||
|
BOOLEAN Raise = TRUE;
|
||||||
|
PVOID Buffer;
|
||||||
|
PPOOL_HEADER Entry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PEPROCESS Process = PsGetCurrentProcess();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate the pool
|
// Check if we should fail intead of raising an exception
|
||||||
//
|
//
|
||||||
UNIMPLEMENTED;
|
if (PoolType & POOL_QUOTA_FAIL_INSTEAD_OF_RAISE)
|
||||||
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
|
{
|
||||||
|
Raise = FALSE;
|
||||||
|
PoolType &= ~POOL_QUOTA_FAIL_INSTEAD_OF_RAISE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inject the pool quota mask
|
||||||
|
//
|
||||||
|
PoolType += QUOTA_POOL_MASK;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if we have enough space to add the quota owner process, as long as
|
||||||
|
// this isn't the system process, which never gets charged quota
|
||||||
|
//
|
||||||
|
ASSERT(NumberOfBytes != 0);
|
||||||
|
if ((NumberOfBytes <= (PAGE_SIZE - sizeof(POOL_BLOCK_SIZE) - sizeof(PVOID))) &&
|
||||||
|
(Process != PsInitialSystemProcess))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Add space for our EPROCESS pointer
|
||||||
|
//
|
||||||
|
NumberOfBytes += sizeof(PEPROCESS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// We won't be able to store the pointer, so don't use quota for this
|
||||||
|
//
|
||||||
|
PoolType -= QUOTA_POOL_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate the pool buffer now
|
||||||
|
//
|
||||||
|
Buffer = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the buffer is page-aligned, this is a large page allocation and we
|
||||||
|
// won't touch it
|
||||||
|
//
|
||||||
|
if (PAGE_ALIGN(Buffer) != Buffer)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Also if special pool is enabled, and this was allocated from there,
|
||||||
|
// we won't touch it either
|
||||||
|
//
|
||||||
|
if ((ExpPoolFlags & POOL_FLAG_SPECIAL_POOL) &&
|
||||||
|
(MmIsSpecialPoolAddress(Buffer)))
|
||||||
|
{
|
||||||
|
return Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If it wasn't actually allocated with quota charges, ignore it too
|
||||||
|
//
|
||||||
|
if (!(PoolType & QUOTA_POOL_MASK)) return Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If this is the system process, we don't charge quota, so ignore
|
||||||
|
//
|
||||||
|
if (Process == PsInitialSystemProcess) return Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actually go and charge quota for the process now
|
||||||
|
//
|
||||||
|
Entry = POOL_ENTRY(Buffer);
|
||||||
|
Status = PsChargeProcessPoolQuota(Process,
|
||||||
|
PoolType & BASE_POOL_TYPE_MASK,
|
||||||
|
Entry->BlockSize * sizeof(POOL_BLOCK_SIZE));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Quota failed, back out the allocation, clear the owner, and fail
|
||||||
|
//
|
||||||
|
*(PVOID*)((ULONG_PTR)POOL_NEXT_BLOCK(Entry) - sizeof(PVOID)) = NULL;
|
||||||
|
ExFreePoolWithTag(Buffer, Tag);
|
||||||
|
if (Raise) RtlRaiseStatus(Status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Quota worked, write the owner and then reference it before returning
|
||||||
|
//
|
||||||
|
*(PVOID*)((ULONG_PTR)POOL_NEXT_BLOCK(Entry) - sizeof(PVOID)) = Process;
|
||||||
|
ObReferenceObject(Process);
|
||||||
|
}
|
||||||
|
else if (!(Buffer) && (Raise))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// The allocation failed, raise an error if we are in raise mode
|
||||||
|
//
|
||||||
|
RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the allocated buffer
|
||||||
|
//
|
||||||
|
return Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DBG && KDBG
|
#if DBG && KDBG
|
||||||
|
|
Loading…
Reference in a new issue