[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 // Get the real entry, write down its pool type, and track it
// //
Entry--; Entry--;
Entry->PoolType = PoolType + 1; Entry->PoolType = OriginalType + 1;
ExpInsertPoolTracker(Tag, ExpInsertPoolTracker(Tag,
Entry->BlockSize * POOL_BLOCK_SIZE, Entry->BlockSize * POOL_BLOCK_SIZE,
OriginalType); OriginalType);
@ -1880,7 +1880,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// We have found an entry for this allocation, so set the pool type // We have found an entry for this allocation, so set the pool type
// and release the lock since we're done // and release the lock since we're done
// //
Entry->PoolType = PoolType + 1; Entry->PoolType = OriginalType + 1;
ExpCheckPoolBlocks(Entry); ExpCheckPoolBlocks(Entry);
ExUnlockPool(PoolDesc, OldIrql); 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 // 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) if (!Entry)
{ {
// //
@ -1963,7 +1963,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// //
Entry->Ulong1 = 0; Entry->Ulong1 = 0;
Entry->BlockSize = i; Entry->BlockSize = i;
Entry->PoolType = PoolType + 1; Entry->PoolType = OriginalType + 1;
// //
// This page will have two entries -- one for the allocation (which we just // 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); InterlockedIncrement((PLONG)&PoolDesc->RunningAllocs);
ExpInsertPoolTracker(Tag, ExpInsertPoolTracker(Tag,
Entry->BlockSize * POOL_BLOCK_SIZE, Entry->BlockSize * POOL_BLOCK_SIZE,
PoolType); OriginalType);
// //
// And return the pool allocation // And return the pool allocation
@ -2065,6 +2065,7 @@ ExFreePoolWithTag(IN PVOID P,
PFN_NUMBER PageCount, RealPageCount; PFN_NUMBER PageCount, RealPageCount;
PKPRCB Prcb = KeGetCurrentPrcb(); PKPRCB Prcb = KeGetCurrentPrcb();
PGENERAL_LOOKASIDE LookasideList; PGENERAL_LOOKASIDE LookasideList;
PEPROCESS Process;
// //
// Check if any of the debug flags are enabled // Check if any of the debug flags are enabled
@ -2255,6 +2256,30 @@ ExFreePoolWithTag(IN PVOID P,
BlockSize * POOL_BLOCK_SIZE, BlockSize * POOL_BLOCK_SIZE,
Entry->PoolType - 1); 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? // 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 // 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); ExFreePoolWithTag(Buffer, Tag);
if (Raise) RtlRaiseStatus(Status); if (Raise) RtlRaiseStatus(Status);
return NULL; return NULL;
@ -2604,7 +2629,7 @@ ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType,
// //
// Quota worked, write the owner and then reference it before returning // 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); ObReferenceObject(Process);
} }
else if (!(Buffer) && (Raise)) else if (!(Buffer) && (Raise))

View file

@ -769,7 +769,10 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
/* Mark it as special pool if needed */ /* Mark it as special pool if needed */
ASSERT(Pfn1->u4.VerifierAllocation == 0); 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 // 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 */ /* Mark it as a verifier allocation if needed */
ASSERT(Pfn1->u4.VerifierAllocation == 0); 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 // Release the PFN and nonpaged pool lock

View file

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