[NTOSKRNL]

- Return process pool quota on free
- Do not use POOL_QUOTA_FAIL_INSTEAD_OF_RAISE on non-quota allocations
- Welcome back, device installation wizard
CORE-7459 #resolve

svn path=/trunk/; revision=60230
This commit is contained in:
Thomas Faber 2013-09-20 05:46:29 +00:00
parent d5c7aa049b
commit a5d94cf00e
3 changed files with 41 additions and 13 deletions

View file

@ -1708,7 +1708,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// Get the real entry, write down its pool type, and track it
//
Entry--;
Entry->PoolType = PoolType + 1;
Entry->PoolType = OriginalType + 1;
ExpInsertPoolTracker(Tag,
Entry->BlockSize * POOL_BLOCK_SIZE,
OriginalType);
@ -1880,7 +1880,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// We have found an entry for this allocation, so set the pool type
// and release the lock since we're done
//
Entry->PoolType = PoolType + 1;
Entry->PoolType = OriginalType + 1;
ExpCheckPoolBlocks(Entry);
ExUnlockPool(PoolDesc, OldIrql);
@ -1910,7 +1910,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
//
// There were no free entries left, so we have to allocate a new fresh page
//
Entry = MiAllocatePoolPages(PoolType, PAGE_SIZE);
Entry = MiAllocatePoolPages(OriginalType, PAGE_SIZE);
if (!Entry)
{
//
@ -1963,7 +1963,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
//
Entry->Ulong1 = 0;
Entry->BlockSize = i;
Entry->PoolType = PoolType + 1;
Entry->PoolType = OriginalType + 1;
//
// This page will have two entries -- one for the allocation (which we just
@ -2023,7 +2023,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
InterlockedIncrement((PLONG)&PoolDesc->RunningAllocs);
ExpInsertPoolTracker(Tag,
Entry->BlockSize * POOL_BLOCK_SIZE,
PoolType);
OriginalType);
//
// And return the pool allocation
@ -2065,6 +2065,7 @@ ExFreePoolWithTag(IN PVOID P,
PFN_NUMBER PageCount, RealPageCount;
PKPRCB Prcb = KeGetCurrentPrcb();
PGENERAL_LOOKASIDE LookasideList;
PEPROCESS Process;
//
// Check if any of the debug flags are enabled
@ -2255,6 +2256,30 @@ ExFreePoolWithTag(IN PVOID P,
BlockSize * POOL_BLOCK_SIZE,
Entry->PoolType - 1);
//
// Release pool quota, if any
//
if ((Entry->PoolType - 1) & QUOTA_POOL_MASK)
{
Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
ASSERT(Process != NULL);
if (Process)
{
if (Process->Pcb.Header.Type != ProcessObject)
{
DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
KeBugCheckEx(BAD_POOL_CALLER,
0x0D,
(ULONG_PTR)P,
Tag,
(ULONG_PTR)Process);
}
PsReturnPoolQuota(Process, PoolType, BlockSize * POOL_BLOCK_SIZE);
ObDereferenceObject(Process);
}
}
//
// Is this allocation small enough to have come from a lookaside list?
//
@ -2595,7 +2620,7 @@ ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType,
//
// Quota failed, back out the allocation, clear the owner, and fail
//
*(PVOID*)((ULONG_PTR)POOL_NEXT_BLOCK(Entry) - sizeof(PVOID)) = NULL;
((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
ExFreePoolWithTag(Buffer, Tag);
if (Raise) RtlRaiseStatus(Status);
return NULL;
@ -2604,7 +2629,7 @@ ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType,
//
// Quota worked, write the owner and then reference it before returning
//
*(PVOID*)((ULONG_PTR)POOL_NEXT_BLOCK(Entry) - sizeof(PVOID)) = Process;
((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = Process;
ObReferenceObject(Process);
}
else if (!(Buffer) && (Raise))

View file

@ -769,7 +769,10 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
/* Mark it as special pool if needed */
ASSERT(Pfn1->u4.VerifierAllocation == 0);
if (PoolType & 64) Pfn1->u4.VerifierAllocation = 1;
if (PoolType & VERIFIER_POOL_MASK)
{
Pfn1->u4.VerifierAllocation = 1;
}
//
// Check if the allocation is larger than one page
@ -879,7 +882,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
/* Mark it as a verifier allocation if needed */
ASSERT(Pfn1->u4.VerifierAllocation == 0);
if (PoolType & 64) Pfn1->u4.VerifierAllocation = 1;
if (PoolType & VERIFIER_POOL_MASK) Pfn1->u4.VerifierAllocation = 1;
//
// Release the PFN and nonpaged pool lock

View file

@ -526,10 +526,10 @@ NtQueueApcThread(IN HANDLE ThreadHandle,
}
/* Allocate an APC */
Apc = ExAllocatePoolWithTag(NonPagedPool |
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
sizeof(KAPC),
TAG_PS_APC);
Apc = ExAllocatePoolWithQuotaTag(NonPagedPool |
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
sizeof(KAPC),
TAG_PS_APC);
if (!Apc)
{
/* Fail */