Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

poolhack.c File Reference

#include "exp.h"
#include "..\mm\mi.h"

Go to the source code of this file.

Classes

struct  _POOL_LIST_HEAD
struct  _POOL_DESCRIPTOR
struct  _POOL_HEADER

Defines

#define POOL_PAGE_SIZE   0x1000
#define POOL_LOG_PAGE   12
#define POOL_LIST_HEADS   8
#define POOL_LOG_MIN   (POOL_LOG_PAGE - POOL_LIST_HEADS + 1)
#define POOL_MIN_ROUND   ( (1<<POOL_LOG_MIN) - 1 )
#define PAGE_ALIGNED(p)   (!(((ULONG)p) & (POOL_PAGE_SIZE - 1)))
#define POOL_OVERHEAD   sizeof(POOL_HEADER)
#define POOL_BUDDY_MAX   (POOL_PAGE_SIZE - POOL_OVERHEAD)
#define LOCK_POOL(Lock, PoolType, LockHandle)
#define UNLOCK_POOL(Lock, PoolType, LockHandle, Wait)

Typedefs

typedef _POOL_LIST_HEAD POOL_LIST_HEAD
typedef POOL_LIST_HEADPPOOL_LIST_HEAD
typedef _POOL_DESCRIPTOR POOL_DESCRIPTOR
typedef POOL_DESCRIPTORPPOOL_DESCRIPTOR
typedef _POOL_HEADER POOL_HEADER
typedef POOL_HEADERPPOOL_HEADER

Functions

PPOOL_HEADER AllocatePoolInternal (IN PPOOL_DESCRIPTOR PoolDesc, IN LONG Index)
VOID DeallocatePoolInternal (IN PPOOL_DESCRIPTOR PoolDesc, IN PPOOL_HEADER Entry)
PLIST_ENTRY ExpInterlockedTryAllocatePool (IN PLIST_ENTRY List, IN KSPIN_LOCK Lock, IN ULONG Size, IN LONG SizeOffset)
KIRQL ExLockPool (IN POOL_TYPE PoolType)
VOID ExUnlockPool (IN POOL_TYPE PoolType, IN KIRQL LockHandle, IN BOOLEAN Wait)
VOID InitializePool (IN POOL_TYPE PoolType, IN ULONG Threshold)
PVOID ExAllocatePool (IN POOL_TYPE PoolType, IN ULONG NumberOfBytes)
ULONG ExpAllocatePoolWithQuotaHandler (IN NTSTATUS ExceptionCode, IN PVOID PoolAddress)
PVOID ExAllocatePoolWithQuota (IN POOL_TYPE PoolType, IN ULONG NumberOfBytes)
VOID ExFreePool (IN PVOID P)
VOID DumpPool (IN PSZ s, IN POOL_TYPE pt)
VOID CheckPool ()
VOID DumpAllocatedPool (IN ULONG DumpOrFlush)
VOID ExQueryPoolUsage (OUT PULONG PagedPoolPages, OUT PULONG NonPagedPoolPages)

Variables

CHAR PoolIndexTable [128]
POOL_DESCRIPTOR NonPagedPoolDescriptor
POOL_DESCRIPTOR PagedPoolDescriptor
POOL_DESCRIPTOR NonPagedPoolDescriptorMS
POOL_DESCRIPTOR PagedPoolDescriptorMS
KSPIN_LOCK NonPagedPoolLock
KMUTEX PagedPoolLock
PPOOL_DESCRIPTOR PoolVector [MaxPoolType]
POOL_TYPE BasePoolTypeTable [MaxPoolType]
BOOLEAN MustSucceedPoolTable [MaxPoolType]


Define Documentation

#define LOCK_POOL Lock,
PoolType,
LockHandle   ) 
 

Value:

{ \ if ( (PoolType) == (NonPagedPool) || (PoolType) == NonPagedPoolMustSucceed ) { \ KeAcquireSpinLock((PKSPIN_LOCK)Lock,&LockHandle); \ } else { \ KeRaiseIrql(APC_LEVEL,&LockHandle); \ KeWaitForSingleObject( \ Lock, \ PoolAllocation, \ KernelMode, \ FALSE, \ NULL \ ); \ } \ }

Definition at line 173 of file poolhack.c.

#define PAGE_ALIGNED  )     (!(((ULONG)p) & (POOL_PAGE_SIZE - 1)))
 

Definition at line 71 of file poolhack.c.

Referenced by ExAllocatePoolWithQuota(), ExAllocatePoolWithQuotaTag(), ExFreePool(), ExFreePoolSanityChecks(), ExFreePoolWithTag(), ExQueryPoolBlockSize(), and VerifierFreeTrackedPool().

#define POOL_BUDDY_MAX   (POOL_PAGE_SIZE - POOL_OVERHEAD)
 

Definition at line 117 of file poolhack.c.

Referenced by ExAllocatePool(), ExAllocatePoolWithTag(), ExAllocatePoolWithTagPriority(), MmCreateMdl(), and ViPostPoolAllocation().

#define POOL_LIST_HEADS   8
 

Definition at line 68 of file poolhack.c.

Referenced by AllocatePoolInternal(), CheckPool(), DumpPool(), ExAllocatePoolWithTag(), ExpInitializePoolDescriptor(), and InitializePool().

#define POOL_LOG_MIN   (POOL_LOG_PAGE - POOL_LIST_HEADS + 1)
 

Definition at line 69 of file poolhack.c.

Referenced by AllocatePoolInternal(), CheckPool(), DeallocatePoolInternal(), DumpPool(), and ExAllocatePool().

#define POOL_LOG_PAGE   12
 

Definition at line 67 of file poolhack.c.

#define POOL_MIN_ROUND   ( (1<<POOL_LOG_MIN) - 1 )
 

Definition at line 70 of file poolhack.c.

Referenced by ExAllocatePool().

#define POOL_OVERHEAD   sizeof(POOL_HEADER)
 

Definition at line 116 of file poolhack.c.

Referenced by AllocatePoolInternal(), CheckPool(), DeallocatePoolInternal(), DumpPool(), ExAllocatePool(), ExAllocatePoolWithQuota(), ExAllocatePoolWithQuotaTag(), ExAllocatePoolWithTag(), ExFreePool(), ExFreePoolSanityChecks(), ExFreePoolWithTag(), ExQueryPoolBlockSize(), ExReturnPoolQuota(), InitializePool(), MiAllocateSpecialPool(), MmFreeSpecialPool(), MmQuerySpecialPoolBlockSize(), VerifierFreeTrackedPool(), and ViPostPoolAllocation().

#define POOL_PAGE_SIZE   0x1000
 

Definition at line 66 of file poolhack.c.

Referenced by CheckPool(), DeallocatePoolInternal(), DumpPool(), and InitializePool().

#define UNLOCK_POOL Lock,
PoolType,
LockHandle,
Wait   ) 
 

Value:

{ \ if ( PoolType == NonPagedPool || (PoolType) == NonPagedPoolMustSucceed ) { \ KeReleaseSpinLock( \ Lock, \ (KIRQL)LockHandle \ ); \ } else { \ KeReleaseMutex((PKMUTEX)Lock,Wait); \ KeLowerIrql(LockHandle); \ } \ }

Definition at line 248 of file poolhack.c.


Typedef Documentation

typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR
 

typedef struct _POOL_HEADER POOL_HEADER
 

Referenced by InitializePool().

typedef struct _POOL_LIST_HEAD POOL_LIST_HEAD
 

typedef POOL_DESCRIPTOR* PPOOL_DESCRIPTOR
 

Definition at line 102 of file poolhack.c.

Referenced by CheckPool(), DumpAllocatedPool(), DumpPool(), ExAllocatePool(), ExFreePool(), ExQueryPoolUsage(), and MiInitializeSessionPool().

typedef POOL_HEADER* PPOOL_HEADER
 

Definition at line 114 of file poolhack.c.

Referenced by AllocatePoolInternal(), CheckPool(), DeallocatePoolInternal(), DumpPool(), ExAllocatePool(), ExAllocatePoolWithQuota(), ExAllocatePoolWithTag(), ExFreePool(), and MmQuerySpecialPoolBlockSize().

typedef POOL_LIST_HEAD* PPOOL_LIST_HEAD
 

Definition at line 93 of file poolhack.c.

Referenced by AllocatePoolInternal(), CheckPool(), DumpAllocatedPool(), and DumpPool().


Function Documentation

PPOOL_HEADER AllocatePoolInternal IN PPOOL_DESCRIPTOR  PoolDesc,
IN LONG  Index
 

Definition at line 786 of file poolhack.c.

References ASSERT, BasePoolTypeTable, Index, _POOL_LIST_HEAD::ListHead, _POOL_HEADER::LogAllocationSize, MiAllocatePoolPages(), MustSucceedPoolTable, NULL, PAGE_SIZE, POOL_LIST_HEADS, POOL_LOG_MIN, POOL_OVERHEAD, _POOL_HEADER::PoolType, PPOOL_HEADER, PPOOL_LIST_HEAD, _POOL_HEADER::ProcessBilled, and USHORT.

Referenced by ExAllocatePool().

00793 : 00794 00795 This function implements the guts of the binary buddy pool 00796 allocator. It is a recursive function. It assumes that the caller 00797 (ExAllocatePool) chose the correct pool descriptor, and that the 00798 allocation should be satisfied from the binary buddy allocator. 00799 00800 The binary buddy allocator calculates the smallest block size that 00801 is a power of two and that can be used to satisfy the request. If 00802 there are no blocks available of this size, then a block of the next 00803 larger block size is allocated and split in half. One piece is 00804 placed back into the pool, and the other piece is used to satisfy 00805 the request. If the allocator reaches the paged sized block list, 00806 and nothing is there, the page aligned pool allocator is called. 00807 The page is added to the binary buddy pool... 00808 00809 Arguments: 00810 00811 PoolDesc - Supplies the address of the pool descriptor to use to 00812 satisfy the request. 00813 00814 Index - Supplies the index into the pool descriptor list head array 00815 that should satisfy an allocation. 00816 00817 Return Value: 00818 00819 Non-Null - Returns a pointer to the allocated pool header. Before 00820 this can be returned to the caller of ExAllocatePool or 00821 ExAllocatePoolWithQuota, the value must be adjusted 00822 (incremented) to account for the 64bit binary buddy pool 00823 overhead. 00824 00825 --*/ 00826 00827 { 00828 LONG Log2N,ShiftedN; 00829 PPOOL_HEADER Entry,Buddy; 00830 PPOOL_LIST_HEAD PoolListHead; 00831 00832 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00833 PULONG BadFood; 00834 #endif // TRACE_ALLOC 00835 00836 Log2N = POOL_LOG_MIN + Index; 00837 ShiftedN = 1 << Log2N; 00838 00839 PoolListHead = &PoolDesc->ListHeads[Index]; 00840 00841 // 00842 // this is the correct list head. See if anything is on the 00843 // list if so, delink and mark as allocated. Otherwise, 00844 // recurse and split. 00845 // 00846 00847 if ( !IsListEmpty(&PoolListHead->ListHead) ) { 00848 00849 // 00850 // list has an entry, so grab it 00851 // 00852 00853 Entry = (PPOOL_HEADER)RemoveHeadList( 00854 &PoolListHead->ListHead); 00855 00856 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00857 BadFood = (PULONG)Entry; 00858 *BadFood = 0xBAADF00D; 00859 *(BadFood+1) = 0xBAADF00D; 00860 #endif // TRACE_ALLOC 00861 00862 Entry = (PPOOL_HEADER) ((PCH)Entry - POOL_OVERHEAD); 00863 00864 // 00865 // allocated entries have a size field set and pool type set 00866 // 00867 00868 Entry->LogAllocationSize = (USHORT)Log2N; 00869 Entry->PoolType = PoolDesc->PoolType; 00870 Entry->ProcessBilled = (PEPROCESS)NULL; 00871 00872 return (PVOID)Entry; 00873 00874 } else { 00875 00876 if ( Index != (POOL_LIST_HEADS - 1) ) { 00877 00878 // 00879 // This is the right list head, but since it is empty 00880 // must recurse. Allocate from the next highest entry. 00881 // The resulting entry is then split in half. One half 00882 // is marked as free and added to the list. The other 00883 // half is returned 00884 // 00885 00886 Entry = (PPOOL_HEADER)AllocatePoolInternal(PoolDesc,Index+1); 00887 00888 if ( !Entry ) { 00889 return NULL; 00890 } 00891 00892 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00893 BadFood = (PULONG)((PCH)Entry + POOL_OVERHEAD); 00894 *BadFood = 0xBAADF00D; 00895 *(BadFood+1) = 0xBAADF00D; 00896 #endif // TRACE_ALLOC 00897 00898 Buddy = (PPOOL_HEADER)((PCH)Entry + ShiftedN); 00899 00900 // 00901 // mark buddy as free and entry as allocated 00902 // 00903 00904 Entry->LogAllocationSize = (USHORT) Log2N; 00905 Entry->PoolType = PoolDesc->PoolType; 00906 Entry->ProcessBilled = (PEPROCESS)NULL; 00907 00908 Buddy->LogAllocationSize = 0; 00909 Buddy->PoolType = Index; 00910 Buddy->ProcessBilled = (PEPROCESS)NULL; 00911 00912 InsertTailList( 00913 &PoolListHead->ListHead, 00914 (PLIST_ENTRY)(((PCH)Buddy + POOL_OVERHEAD)) 00915 ); 00916 00917 return (PVOID)Entry; 00918 00919 } else { 00920 00921 // 00922 // Need to call page allocator for a page to add to the pool 00923 // 00924 00925 Entry = (PPOOL_HEADER)MiAllocatePoolPages ( 00926 BasePoolTypeTable[PoolDesc->PoolType], 00927 PAGE_SIZE 00928 ); 00929 00930 if ( !Entry ) { 00931 if ( MustSucceedPoolTable[PoolDesc->PoolType] ) { 00932 Entry = (PPOOL_HEADER)MiAllocatePoolPages ( 00933 PoolDesc->PoolType, 00934 PAGE_SIZE 00935 ); 00936 ASSERT(Entry); 00937 } else { 00938 return NULL; 00939 } 00940 } 00941 00942 Entry->LogAllocationSize = (USHORT) Log2N; 00943 Entry->PoolType = PoolDesc->PoolType; 00944 Entry->ProcessBilled = (PEPROCESS)NULL; 00945 00946 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00947 { 00948 PULONG NewPool; 00949 ULONG LongCount; 00950 00951 NewPool = (PULONG) ((PCH)Entry + POOL_OVERHEAD); 00952 LongCount = (1 << Entry->LogAllocationSize) >> 2; 00953 LongCount -= (POOL_OVERHEAD>>2); 00954 00955 while(LongCount--) { 00956 *NewPool++ = 0xBAADF00D; 00957 } 00958 } 00959 #endif //TRACE_ALLOC 00960 00961 PoolDesc->TotalPages++; 00962 00963 return (PVOID)Entry; 00964 00965 } 00966 } 00967 }

VOID CheckPool  ) 
 

Definition at line 1400 of file poolhack.c.

References DbgPrint, FALSE, KeBugCheck(), _POOL_LIST_HEAD::ListHead, _POOL_HEADER::LogAllocationSize, MmDeterminePoolType(), NonPagedPool, pd, POOL_LIST_HEADS, POOL_LOG_MIN, POOL_OVERHEAD, POOL_PAGE_SIZE, _POOL_HEADER::PoolType, PoolVector, PPOOL_DESCRIPTOR, PPOOL_HEADER, PPOOL_LIST_HEAD, and TRUE.

01401 { 01402 PPOOL_DESCRIPTOR pd; 01403 PPOOL_HEADER ph,bph; 01404 PPOOL_LIST_HEAD plh; 01405 PLIST_ENTRY lh,next,lh2,next2; 01406 BOOLEAN buddyinlist; 01407 LONG i,j; 01408 ULONG size; 01409 01410 pd = PoolVector[NonPagedPool]; 01411 01412 if ( pd->PoolType != NonPagedPool ) { 01413 DbgPrint("pd = %8lx\n", pd); 01414 KeBugCheck(0x70000001); 01415 } 01416 01417 if ( (LONG) pd->TotalPages < 0 ) { 01418 DbgPrint("pd = %8lx\n", pd); 01419 KeBugCheck(0x70000002); 01420 } 01421 01422 for (i=0; i<POOL_LIST_HEADS; i++ ) { 01423 plh = &pd->ListHeads[i]; 01424 size = (1 << (i + POOL_LOG_MIN)); 01425 01426 if ( !IsListEmpty(&plh->ListHead) ) { 01427 01428 lh = &plh->ListHead; 01429 next = lh->Flink; 01430 while ( next != lh ) { 01431 ph = (PPOOL_HEADER)((PCH)next - POOL_OVERHEAD); 01432 01433 if ( MmDeterminePoolType(ph) != NonPagedPool ) { 01434 DbgPrint("ph = %8lx\n", ph); 01435 KeBugCheck(0x70000004); 01436 } 01437 if ( size != POOL_PAGE_SIZE ) { 01438 bph = (PPOOL_HEADER)((ULONG)ph ^ size); 01439 if ( bph->LogAllocationSize == 0 && 01440 bph->PoolType == i ) { 01441 lh2 = &plh->ListHead; 01442 next2 = lh2->Flink; 01443 buddyinlist = FALSE; 01444 while ( next2 != lh2 ) { 01445 ph = (PPOOL_HEADER)((PCH)next - POOL_OVERHEAD); 01446 if ( bph == ph ) { 01447 buddyinlist = TRUE; 01448 } 01449 next2 = next2->Flink; 01450 } 01451 if ( !buddyinlist ) { 01452 KeBugCheck(0x70000005); 01453 } 01454 } 01455 } 01456 if ( next == next->Flink ) { 01457 DbgPrint("next = %8lx\n", next); 01458 KeBugCheck(0x70000006); 01459 } 01460 next = next->Flink; 01461 } 01462 } 01463 01464 } 01465 }

VOID DeallocatePoolInternal IN PPOOL_DESCRIPTOR  PoolDesc,
IN PPOOL_HEADER  Entry
 

Definition at line 1177 of file poolhack.c.

References L, _POOL_HEADER::LogAllocationSize, MiFreePoolPages(), POOL_LOG_MIN, POOL_OVERHEAD, POOL_PAGE_SIZE, _POOL_HEADER::PoolType, and PPOOL_HEADER.

Referenced by ExFreePool().

01184 : 01185 01186 This function implements the guts of the binary buddy pool 01187 deallocator. It is a recursive function. It assumes that the 01188 caller (ExFreePool) chose the correct pool descriptor, and that 01189 the deallocation should be done using the binary buddy deallocator. 01190 01191 The binary buddy deallocator automatically collapses adjacent free 01192 blocks of the same size into a single free block of the next larger 01193 size. This is a recursive operation. This does not occur on a 01194 deallocation of a page sized block. If a page sized block is being 01195 deallocated, then the pool descriptor's threshold is examined. If 01196 the deallocation would cause the threshold to be exceeded, the page 01197 sized block is returned to the page aligned pool allocator. 01198 01199 Arguments: 01200 01201 PoolDesc - Supplies the address of the pool descriptor to use to 01202 satisfy the request. 01203 01204 Entry - Supplies the address of the pool header of the block of pool 01205 being deallocated. 01206 01207 Return Value: 01208 01209 None. 01210 01211 --*/ 01212 01213 { 01214 PPOOL_HEADER Buddy,Base; 01215 LONG index; 01216 ULONG EntrySize; 01217 01218 // 01219 // Locate buddy of Entry being deallocated. Page size entries have no 01220 // buddy 01221 // 01222 01223 01224 index = Entry->LogAllocationSize - POOL_LOG_MIN; 01225 01226 EntrySize = (1L << Entry->LogAllocationSize); 01227 01228 if ( EntrySize < POOL_PAGE_SIZE ) { 01229 01230 // 01231 // buddy of Entry is LogAllocationSize bytes from Entry rounded 01232 // down on a 2*LogAllocationSize boundry 01233 // 01234 01235 Buddy = (PPOOL_HEADER)((ULONG)Entry ^ EntrySize); 01236 01237 // 01238 // see if buddy is free. If so, then join buddy and Entry and 01239 // deallocate the joined Entry 01240 // 01241 01242 if ( Buddy->LogAllocationSize == 0 && 01243 Buddy->PoolType == index ) { 01244 01245 // 01246 // buddy is free. Figure out which Entry is the base. 01247 // Convert the size of the base to next larger size and 01248 // deallocate the new Entry 01249 // 01250 01251 Base = ((ULONG)Entry & EntrySize) ? Buddy : Entry; 01252 01253 RemoveEntryList((PLIST_ENTRY)((PCH)Buddy + POOL_OVERHEAD)); 01254 01255 // 01256 // Update statistics for buddy's list head. 01257 // 01258 01259 PoolDesc->ListHeads[index].CurrentFreeLength--; 01260 01261 // 01262 // mark base as allocated as next size Entry and then deallocate it 01263 // 01264 01265 Base->LogAllocationSize = Entry->LogAllocationSize + 1; 01266 01267 DeallocatePoolInternal(PoolDesc,Base); 01268 01269 } else { 01270 01271 // 01272 // Buddy is not free, so just mark Entry as free and return to 01273 // appropriate list head 01274 // 01275 01276 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 01277 { 01278 PULONG OldPool; 01279 ULONG LongCount; 01280 01281 OldPool = (PULONG)((PCH)Entry + POOL_OVERHEAD); 01282 LongCount = EntrySize >> 2; 01283 LongCount -= (POOL_OVERHEAD>>2); 01284 01285 while(LongCount--) { 01286 *OldPool++ = 0xBAADF00D; 01287 } 01288 } 01289 #endif //TRACE_ALLOC 01290 01291 InsertTailList( 01292 &PoolDesc->ListHeads[index].ListHead, 01293 (PLIST_ENTRY)((PCH)Entry + POOL_OVERHEAD) 01294 ); 01295 01296 PoolDesc->ListHeads[index].CurrentFreeLength++; 01297 01298 Entry->LogAllocationSize = 0; 01299 Entry->PoolType = index; 01300 } 01301 01302 } else { 01303 01304 // 01305 // Page Sized Entry. Check threshold. If deallocating Entry 01306 // would cross threshold then give back the page. Otherwise put 01307 // it on the free list 01308 // 01309 01310 if ( PoolDesc->ListHeads[index].CurrentFreeLength == PoolDesc->Threshold ) { 01311 01312 MiFreePoolPages (Entry); 01313 01314 } else { 01315 01316 // 01317 // so just mark Entry as free and return to appropriate list head 01318 // 01319 01320 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 01321 { 01322 PULONG OldPool; 01323 ULONG LongCount; 01324 01325 OldPool = (PULONG)((PCH)Entry + POOL_OVERHEAD); 01326 LongCount = EntrySize >> 2; 01327 LongCount -= (POOL_OVERHEAD>>2); 01328 01329 while(LongCount--) { 01330 *OldPool++ = 0xBAADF00D; 01331 } 01332 } 01333 #endif //TRACE_ALLOC 01334 01335 InsertTailList( 01336 &PoolDesc->ListHeads[index].ListHead, 01337 (PLIST_ENTRY)((PCH)Entry + POOL_OVERHEAD) 01338 ); 01339 01340 PoolDesc->ListHeads[index].CurrentFreeLength++; 01341 01342 Entry->LogAllocationSize = 0; 01343 Entry->PoolType = index; 01344 01345 } 01346 } 01347 }

VOID DumpAllocatedPool IN ULONG  DumpOrFlush  ) 
 

Definition at line 1467 of file poolhack.c.

References DbgPrint, MaxPoolType, pd, POOL_TYPE, PPOOL_DESCRIPTOR, PPOOL_LIST_HEAD, and VOID().

01470 { 01471 VOID MiFlushUnusedSections( VOID ); 01472 POOL_TYPE pt; 01473 ULONG PoolUsage[MaxPoolType]; 01474 ULONG PoolFree[MaxPoolType]; 01475 01476 PPOOL_DESCRIPTOR pd; 01477 PPOOL_LIST_HEAD plh; 01478 PLIST_ENTRY lh,next; 01479 LONG i,j,k; 01480 ULONG size; 01481 01482 if ( DumpOrFlush ) { 01483 MiFlushUnusedSections(); 01484 return; 01485 } 01486 01487 DbgPrint ("PoolHack does not work with POOL command\n"); 01488 01489 return; 01490 }

VOID DumpPool IN PSZ  s,
IN POOL_TYPE  pt
 

Definition at line 1351 of file poolhack.c.

References _POOL_LIST_HEAD::CurrentFreeLength, DbgPrint, _POOL_LIST_HEAD::ListHead, _POOL_HEADER::LogAllocationSize, pd, POOL_LIST_HEADS, POOL_LOG_MIN, POOL_OVERHEAD, POOL_PAGE_SIZE, _POOL_HEADER::PoolType, PoolVector, PPOOL_DESCRIPTOR, PPOOL_HEADER, PPOOL_LIST_HEAD, and _POOL_HEADER::ProcessBilled.

01355 { 01356 PPOOL_DESCRIPTOR pd; 01357 PPOOL_HEADER ph,bph; 01358 PPOOL_LIST_HEAD plh; 01359 PLIST_ENTRY lh,next; 01360 LONG i; 01361 ULONG size; 01362 01363 pd = PoolVector[pt]; 01364 01365 DbgPrint("\n\n%s\n",s); 01366 01367 DbgPrint("PoolType: 0x%lx\n",(ULONG)pd->PoolType); 01368 DbgPrint("TotalPages: 0x%lx\n",pd->TotalPages); 01369 DbgPrint("Threshold: 0x%lx\n",pd->Threshold); 01370 for (i=0; i<POOL_LIST_HEADS; i++ ) { 01371 plh = &pd->ListHeads[i]; 01372 size = (1 << (i + POOL_LOG_MIN)); 01373 DbgPrint("\npd_list_head[0x%lx] size 0x%lx\n",i,size); 01374 DbgPrint("\tCurrentFreeLength 0x%lx\n",plh->CurrentFreeLength); 01375 DbgPrint("\t&ListHead 0x%lx\n",&plh->ListHead); 01376 lh = &plh->ListHead; 01377 DbgPrint("\t\tpFlink 0x%lx\n",lh->Flink); 01378 DbgPrint("\t\tpBlink 0x%lx\n",lh->Blink); 01379 next = lh->Flink; 01380 while ( next != lh ) { 01381 ph = (PPOOL_HEADER)((PCH)next - POOL_OVERHEAD); 01382 DbgPrint("\t\t\tpool header at 0x%lx list 0x%lx\n",ph,next); 01383 DbgPrint("\t\t\tLogAllocationSize 0x%lx 0x%lx\n",(ULONG)ph->LogAllocationSize,(ULONG)(1<<ph->LogAllocationSize)); 01384 DbgPrint("\t\t\tPoolType 0x%lx\n",(ULONG)ph->PoolType); 01385 DbgPrint("\t\t\tProcessBilled 0x%lx\n",ph->ProcessBilled); 01386 if ( size != POOL_PAGE_SIZE ) { 01387 bph = (PPOOL_HEADER)((ULONG)ph ^ size); 01388 DbgPrint("\t\t\t\tBuddy pool header at 0x%lx\n",bph); 01389 DbgPrint("\t\t\t\tBuddy LogAllocationSize 0x%lx 0x%lx\n",(ULONG)bph->LogAllocationSize,(ULONG)(1<<bph->LogAllocationSize)); 01390 DbgPrint("\t\t\t\tBuddy PoolType 0x%lx\n",(ULONG)bph->PoolType); 01391 DbgPrint("\t\t\t\tBuddy ProcessBilled 0x%lx\n",bph->ProcessBilled); 01392 } 01393 next = next->Flink; 01394 } 01395 } 01396 }

PVOID ExAllocatePool IN POOL_TYPE  PoolType,
IN ULONG  NumberOfBytes
 

Definition at line 413 of file poolhack.c.

References AllocatePoolInternal(), APC_LEVEL, ASSERT, BasePoolTypeTable, DbgPrint, FALSE, Index, KeBugCheck(), KeLowerIrql(), KeRaiseIrql(), KeReleaseSemaphore(), KeReleaseSpinLock(), KernelMode, KeWaitForSingleObject(), L, _POOL_DESCRIPTOR::ListHeads, Lock, LOCK_POOL, _POOL_DESCRIPTOR::LockAddress, LockQueuePfnLock, _POOL_HEADER::LogAllocationSize, MiAllocatePoolPages(), MiGetVirtualAddressMappedByPte, MiInitializePfn(), MiRemoveAnyPage(), MiReserveSystemPtes(), MmAvailablePages, MmPfnLock, MustSucceedPoolTable, NULL, PAGE_SIZE, POOL_BUDDY_MAX, POOL_LOG_MIN, POOL_MIN_ROUND, POOL_OVERHEAD, PoolAllocation, PoolIndexTable, _POOL_HEADER::PoolType, PoolVector, PPOOL_DESCRIPTOR, PPOOL_HEADER, _POOL_HEADER::ProcessBilled, PsGetCurrentThread, SystemPteSpace, TRUE, _MMPTE::u, UNLOCK_POOL, USHORT, ValidKernelPte, and VOID().

00420 : 00421 00422 This function allocates a block of pool of the specified type and 00423 returns a pointer to the allocated block. This function is used to 00424 access both the page-aligned pools, and the binary buddy (less than 00425 a page) pools. 00426 00427 If the number of bytes specifies a size that is too large to be 00428 satisfied by the appropriate binary buddy pool, then the page-aligned 00429 pool allocator is used. The allocated block will be page-aligned 00430 and a page-sized multiple. 00431 00432 Otherwise, the appropriate binary buddy pool is used. The allocated 00433 block will be 64-bit aligned, but will not be page aligned. The 00434 binary buddy allocator calculates the smallest block size that is a 00435 power of two and that can be used to satisfy the request. If there 00436 are no blocks available of this size, then a block of the next 00437 larger block size is allocated and split in half. One piece is 00438 placed back into the pool, and the other piece is used to satisfy 00439 the request. If the allocator reaches the paged-sized block list, 00440 and nothing is there, the page-aligned pool allocator is called. 00441 The page is added to the binary buddy pool... 00442 00443 Arguments: 00444 00445 PoolType - Supplies the type of pool to allocate. If the pool type 00446 is one of the "MustSucceed" pool types, then this call will 00447 always succeed and return a pointer to allocated pool. 00448 Otherwise, if the system can not allocate the requested amount 00449 of memory a NULL is returned. 00450 00451 NumberOfBytes - Supplies the number of bytes to allocate. 00452 00453 Return Value: 00454 00455 NULL - The PoolType is not one of the "MustSucceed" pool types, and 00456 not enough pool exists to satisfy the request. 00457 00458 NON-NULL - Returns a pointer to the allocated pool. 00459 00460 --*/ 00461 00462 { 00463 PPOOL_HEADER Entry; 00464 PEPROCESS CurrentProcess; 00465 KIRQL LockHandle; 00466 PPOOL_DESCRIPTOR PoolDesc; 00467 PVOID Lock; 00468 LONG Index; 00469 PVOID Block; 00470 00471 KIRQL OldIrql; 00472 PMMPTE PointerPte; 00473 ULONG PageFrameIndex; 00474 MMPTE TempPte; 00475 BOOLEAN ReleaseSpinLock = TRUE; 00476 00477 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00478 00479 PULONG BadFood; 00480 #endif //TRACE_ALLOC 00481 00482 #ifdef TRACE_ALLOC 00483 PULONG xFp, xPrevFp, xR1, xPrevR1, xPrevPrevR1; 00484 00485 xFp = RtlpGetFramePointer(); 00486 xR1 = (PULONG)*(xFp+1); 00487 xPrevFp = (PULONG)*xFp; 00488 xPrevR1 = (PULONG)*(xPrevFp+1); 00489 xPrevFp = (PULONG)*xPrevFp; 00490 xPrevPrevR1 = (PULONG)*(xPrevFp+1); 00491 00492 #endif // TRACE_ALLOC 00493 00494 00495 00496 PoolDesc = PoolVector[PoolType]; 00497 Lock = PoolDesc->LockAddress; 00498 00499 if (NumberOfBytes > POOL_BUDDY_MAX) { 00500 00501 LOCK_POOL(Lock,PoolType,LockHandle); 00502 00503 Entry = (PPOOL_HEADER)MiAllocatePoolPages ( 00504 BasePoolTypeTable[PoolType], 00505 NumberOfBytes 00506 ); 00507 if ( !Entry && MustSucceedPoolTable[PoolType] ) { 00508 Entry = (PPOOL_HEADER)MiAllocatePoolPages ( 00509 PoolType, 00510 NumberOfBytes 00511 ); 00512 } 00513 UNLOCK_POOL(Lock,PoolType,LockHandle,FALSE); 00514 00515 return Entry; 00516 } 00517 00518 if (KeGetCurrentIrql() >= 2) { 00519 DbgPrint("allocating pool at irql >= 2\n"); 00520 ReleaseSpinLock = FALSE; 00521 00522 } else { 00523 KeAcquireQueuedSpinLock(LockQueuePfnLock); 00524 } 00525 00526 PointerPte = MiReserveSystemPtes (2, SystemPteSpace, 0, 0, TRUE); 00527 00528 ASSERT (MmAvailablePages > 0); 00529 PageFrameIndex = MiRemoveAnyPage (); 00530 TempPte = ValidKernelPte; 00531 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00532 *PointerPte = TempPte; 00533 MiInitializePfn (PageFrameIndex, PointerPte, 1L, 1); 00534 00535 if (ReleaseSpinLock) { 00536 KeReleaseSpinLock ( &MmPfnLock, OldIrql ); 00537 } 00538 00539 Entry = (PVOID)MiGetVirtualAddressMappedByPte (PointerPte); 00540 00541 Entry = (PVOID)(((ULONG)Entry + (PAGE_SIZE - (NumberOfBytes))) & 00542 0xfffffff8L); 00543 00544 return Entry; 00545 00546 00547 Index = ( (NumberOfBytes+POOL_OVERHEAD+POOL_MIN_ROUND) >> POOL_LOG_MIN) - 1; 00548 00549 Index = PoolIndexTable[Index]; 00550 00551 LOCK_POOL(Lock,PoolType,LockHandle); 00552 00553 if ( !IsListEmpty(&PoolDesc->ListHeads[Index].ListHead) ) { 00554 00555 Block = RemoveHeadList(&PoolDesc->ListHeads[Index].ListHead); 00556 Entry = (PPOOL_HEADER) ((PCH)Block - POOL_OVERHEAD); 00557 Entry->ProcessBilled = (PEPROCESS)NULL; 00558 Entry->LogAllocationSize = (USHORT)POOL_LOG_MIN + Index; 00559 Entry->PoolType = (USHORT)PoolType; 00560 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00561 BadFood = (PULONG)Block; 00562 *BadFood = 0xBAADF00D; 00563 *(BadFood+1) = 0xBAADF00D; 00564 #endif // TRACE_ALLOC 00565 00566 } else { 00567 00568 Entry = AllocatePoolInternal(PoolDesc,Index); 00569 00570 if ( !Entry ) { 00571 #if DBG 00572 DbgPrint("EX: ExAllocatePool returning NULL\n"); 00573 DbgBreakPoint(); 00574 #endif // DBG 00575 UNLOCK_POOL(Lock,PoolType,LockHandle,FALSE); 00576 return NULL; 00577 } 00578 } 00579 00580 UNLOCK_POOL(Lock,PoolType,LockHandle,FALSE); 00581 00582 #ifdef TRACE_ALLOC 00583 { 00584 KIRQL xIrql; 00585 00586 KeRaiseIrql(APC_LEVEL, &xIrql); 00587 00588 KeWaitForSingleObject( 00589 &TracePoolLock, 00590 PoolAllocation, 00591 KernelMode, 00592 FALSE, 00593 NULL 00594 ); 00595 00596 InsertTailList(&TracePoolListHead[PoolType],&Entry->TraceLinks); 00597 00598 Entry->xR1 = xR1; 00599 Entry->xPrevR1 = xPrevR1; 00600 Entry->ProcessBilled = (PEPROCESS)xPrevPrevR1; 00601 00602 //Entry->ProcessBilled = (PEPROCESS)NextAllocTrace; 00603 00604 AllocTrace[NextAllocTrace].BufferAddress = (PCH)Entry + POOL_OVERHEAD; 00605 AllocTrace[NextAllocTrace].Thread = PsGetCurrentThread(); 00606 AllocTrace[NextAllocTrace].xR1 = xR1; 00607 AllocTrace[NextAllocTrace++].xPrevR1 = xPrevR1; 00608 if ( NextAllocTrace >= MAXTRACE ) { 00609 NextAllocTrace = 0; 00610 } 00611 00612 00613 (VOID) KeReleaseSemaphore( 00614 &TracePoolLock, 00615 0L, 00616 1L, 00617 FALSE 00618 ); 00619 KeLowerIrql(xIrql); 00620 00621 } 00622 #endif // TRACE_ALLOC 00623 00624 #if defined(TRACE_ALLOC) || defined (DEADBEEF) 00625 { 00626 PULONG NewPool; 00627 ULONG LongCount; 00628 00629 Block = (PULONG)((PCH)Entry + POOL_OVERHEAD); 00630 NewPool = (PULONG) ((PCH)Entry + POOL_OVERHEAD); 00631 LongCount = (1 << Entry->LogAllocationSize) >> 2; 00632 LongCount -= (POOL_OVERHEAD>>2); 00633 00634 while(LongCount--) { 00635 if ( *NewPool != 0xBAADF00D ) { 00636 DbgPrint("ExAllocatePool: No BAADF00D Block %lx at %lx\n", 00637 Block, 00638 NewPool 00639 ); 00640 KeBugCheck(0xBADF00D2); 00641 } 00642 *NewPool++ = 0xDEADBEEF; 00643 } 00644 } 00645 #endif //TRACE_ALLOC 00646 00647 return ((PCH)Entry + POOL_OVERHEAD); 00648 }

PVOID ExAllocatePoolWithQuota IN POOL_TYPE  PoolType,
IN ULONG  NumberOfBytes
 

Definition at line 694 of file poolhack.c.

References BasePoolTypeTable, ExAllocatePool, ExpAllocatePoolWithQuotaHandler(), ExRaiseStatus(), KeBugCheck(), _POOL_HEADER::LogAllocationSize, ObReferenceObject, PAGE_ALIGNED, POOL_OVERHEAD, PPOOL_HEADER, _POOL_HEADER::ProcessBilled, PsChargePoolQuota(), and PsGetCurrentProcess.

00701 : 00702 00703 This function allocates a block of pool of the specified type, 00704 returns a pointer to the allocated block, and if the binary buddy 00705 allocator was used to satisfy the request, charges pool quota to the 00706 current process. This function is used to access both the 00707 page-aligned pools, and the binary buddy. 00708 00709 If the number of bytes specifies a size that is too large to be 00710 satisfied by the appropriate binary buddy pool, then the 00711 page-aligned pool allocator is used. The allocated block will be 00712 page-aligned and a page-sized multiple. No quota is charged to the 00713 current process if this is the case. 00714 00715 Otherwise, the appropriate binary buddy pool is used. The allocated 00716 block will be 64-bit aligned, but will not be page aligned. After 00717 the allocation completes, an attempt will be made to charge pool 00718 quota (of the appropriate type) to the current process object. If 00719 the quota charge succeeds, then the pool block's header is adjusted 00720 to point to the current process. The process object is not 00721 dereferenced until the pool is deallocated and the appropriate 00722 amount of quota is returned to the process. Otherwise, the pool is 00723 deallocated, a "quota exceeded" condition is raised. 00724 00725 Arguments: 00726 00727 PoolType - Supplies the type of pool to allocate. If the pool type 00728 is one of the "MustSucceed" pool types and sufficient quota 00729 exists, then this call will always succeed and return a pointer 00730 to allocated pool. Otherwise, if the system can not allocate 00731 the requested amount of memory a STATUS_INSUFFICIENT_RESOURCES 00732 status is raised. 00733 00734 NumberOfBytes - Supplies the number of bytes to allocate. 00735 00736 Return Value: 00737 00738 NON-NULL - Returns a pointer to the allocated pool. 00739 00740 Unspecified - If insuffient quota exists to complete the pool 00741 allocation, the return value is unspecified. 00742 00743 --*/ 00744 00745 { 00746 PVOID p; 00747 PEPROCESS Process; 00748 PPOOL_HEADER Entry; 00749 ULONG AllocationSize; 00750 00751 p = ExAllocatePool(PoolType,NumberOfBytes); 00752 00753 00754 #ifndef TRACE_ALLOC 00755 if ( p && !PAGE_ALIGNED(p) ) { 00756 00757 Entry = (PPOOL_HEADER)((PCH)p - POOL_OVERHEAD); 00758 00759 Process = PsGetCurrentProcess(); 00760 00761 // 00762 // Catch exception and back out allocation if necessary 00763 // 00764 00765 try { 00766 00767 PsChargePoolQuota(Process,BasePoolTypeTable[PoolType],(1 << Entry->LogAllocationSize)); 00768 ObReferenceObject(Process); 00769 Entry->ProcessBilled = Process; 00770 00771 } except ( ExpAllocatePoolWithQuotaHandler(GetExceptionCode(),p)) { 00772 KeBugCheck(GetExceptionCode()); 00773 } 00774 00775 } else { 00776 if ( !p ) { 00777 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00778 } 00779 } 00780 #endif // TRACE_ALLOC 00781 00782 return p; 00783 }

VOID ExFreePool IN PVOID  P  ) 
 

Definition at line 970 of file poolhack.c.

References APC_LEVEL, BasePoolTypeTable, DbgPrint, DeallocatePoolInternal(), FALSE, HBLOCK_SIZE, KeAcquireSpinLock, KeBugCheck(), KeLowerIrql(), KeRaiseIrql(), KeReleaseSemaphore(), KeReleaseSpinLock(), KernelMode, KeSweepDcache(), KeWaitForSingleObject(), KiFlushSingleTb(), L, Lock, LOCK_POOL, _POOL_DESCRIPTOR::LockAddress, _POOL_HEADER::LogAllocationSize, MaxPoolType, MI_PFN_ELEMENT, MiDecrementShareCountOnly, MiFreePoolPages(), MiGetPteAddress, MiReleaseSystemPtes(), MM_EMPTY_LIST, MmDeterminePoolType(), MmPfnLock, NtFreeVirtualMemory(), NULL, ObDereferenceObject, PAGE_ALIGNED, POOL_OVERHEAD, POOL_TYPE, PoolAllocation, _POOL_HEADER::PoolType, PoolVector, PPOOL_DESCRIPTOR, PPOOL_HEADER, _POOL_HEADER::ProcessBilled, PsGetCurrentThread, PsReturnPoolQuota(), _MMPFN::PteAddress, SystemPteSpace, TRUE, _MMPTE::u, UNLOCK_POOL, VOID(), and ZeroPte.

Referenced by ArbAddOrdering(), ArbBuildAssignmentOrdering(), ArbDeleteArbiterInstance(), ArbFreeOrderingList(), ArbInitializeArbiterInstance(), ArbpBuildAllocationStack(), ArbpGetRegistryValue(), ArbPruneOrdering(), ArbQueryConflict(), BuildQueryDirectoryIrp(), CcDeallocateBcb(), CcDeleteMbcb(), CcDeleteSharedCacheMap(), CcDrainVacbLevelZone(), CcExtendVacbArray(), CcInitializeCacheMap(), CcPostDeferredWrites(), CcUninitializeCacheMap(), CcUnpinData(), CcUnpinDataForThread(), CcWriteBehind(), CcZeroData(), CmDeleteKeyRecursive(), CmInitSystem1(), CmpAddToHiveFileList(), CmpAllocatePostBlock(), CmpAppendStringToMultiSz(), CmpCleanUpKcbValueCache(), CmpCloneControlSet(), CmpCloneHwProfile(), CmpCloseInfFile(), CmpCopySyncTree(), CmpCopySyncTree2(), CmpCreateRegistryRoot(), CmpDelayedDerefKeys(), CmpDestroyTemporaryHive(), CmpDiskFullWarningWorker(), CmpFindACPITable(), CmpFindRSDTTable(), CmpFlushNotify(), CmpFree(), CmpFreeLineList(), CmpFreePostBlock(), CmpFreeSectionList(), CmpFreeValueList(), CmpGetAcpiProfileInformation(), CmpGetRegistryValue(), CmpGetSymbolicLink(), CmpGetValueDataFromCache(), CmpHiveRootSecurityDescriptor(), CmpInitializeHardwareConfiguration(), CmpInitializeHive(), CmpInitializeHiveList(), CmpInitializeMachineDependentConfiguration(), CmpInitializeRegistryNode(), CmpInitializeSystemHive(), CmpLoadHiveVolatile(), CmpMergeKeyValues(), CmpNameFromAttributes(), CmpNotifyChangeKey(), CmpOpenHiveFiles(), CmpOpenRegKey(), CmpParseInfBuffer(), CmpPostNotify(), CmpProcessBitRegLine(), CmpQuotaWarningWorker(), CmpRemoveFromHiveFileList(), CmpSaveBootControlSet(), CmpSaveKeyByFileCopy(), CmpSetSecurityDescriptorInfo(), CmpSetValueKeyExisting(), CmpSetVersionData(), CmpValidateAlternate(), CmpWorker(), CmReplaceKey(), CmSetAcpiHwProfile(), CmUnloadKey(), ComPortDBAdd(), DbgkCreateThread(), DbgkpSectionHandleToFileHandle(), DoPoolTest(), DriverEntry(), EisaBuildEisaDeviceNode(), EisaGetEisaDevicesResources(), ExCreateDebugLogTag(), ExDeleteResourceLite(), ExLockUserBuffer(), ExpAllocateHandleTable(), ExpAllocateHandleTableEntry(), ExpAllocatePoolWithQuotaHandler(), ExpFindCurrentThread(), ExpFreeHandleTable(), ExpGetPoolTagInfo(), ExpProfileDelete(), ExpQueryLegacyDriverInformation(), ExpSystemErrorHandler(), ExRegisterCallback(), ExUnlockUserBuffer(), ExUnregisterCallback(), FatRecFsControl(), FindPathForDevice(), FsgWriteToFrameBuffer(), FsRecUnload(), FsRtlAddLargeEntry(), FsRtlAllocateOplock(), FsRtlCancelNotify(), FsRtlDeregisterUncProvider(), FsRtlFreeTunnelNode(), FsRtlGetCompatibilityModeValue(), FsRtlGetTunnelParameterValue(), FsRtlIsDbcsInExpression(), FsRtlIsNameInExpressionPrivate(), FsRtlNotifyCleanup(), FsRtlNotifyCompleteIrp(), FsRtlNotifyFullChangeDirectory(), FsRtlNotifyFullReportChange(), FsRtlNotifyUninitializeSync(), FsRtlpRegisterProviderWithMUP(), FsRtlRegisterUncProvider(), FsRtlRemoveAndCompleteWaitIrp(), FsRtlStackOverflowRead(), FsRtlTruncateLargeMcb(), FsRtlUninitializeLargeMcb(), FsRtlUninitializeOplock(), FsVgaServiceParameters(), FsVgaWriteToFrameBuffer(), GetNextReparseVolumePath(), HalpGetFullGeometry(), HalpNextMountLetter(), HalpSetMountLetter(), HvpDiscardBins(), HvpDoWriteHive(), HvpReadFileImageAndBuildMap(), HvpRecoverData(), HvpWriteLog(), InitCreateUserCrit(), IoAllocateDriverObjectExtension(), IoBuildDeviceIoControlRequest(), IoConnectInterrupt(), IoCreateDevice(), IoCreateFile(), IoDeleteDevice(), IoDisconnectInterrupt(), IoepFreeErrStack(), IoepGetErrCaseDB(), IoepInitErrLog(), IoepLogErr(), IoErrFreeSavedData(), IoErrGetErrData(), IoErrPropagateErrLog(), IoErrTerminateErrLog(), IoFreeDumpStack(), IoFreeMdl(), IoFreePoDeviceNotifyList(), IoFreeWorkItem(), IoGetBootDiskInformation(), IoGetDeviceInterfaceAlias(), IoGetDeviceProperty(), IoGetLegacyVetoList(), IoInitSystem(), IoIsValidNameGraftingBuffer(), IoOpenDeviceRegistryKey(), IopAllocateResources(), IopApcHardError(), IopAppendLegacyVeto(), IopAppendStringToValueKey(), IopApplyFunctionToServiceInstances(), IopApplyFunctionToSubKeys(), IopApplySystemPartitionProt(), IopArbitrateDeviceResources(), IopBuildCmResourceList(), IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopChangeDeviceObjectFromRegistryProperties(), IopCheckDependencies(), IopChildToRootTranslation(), IopCompleteRequest(), IopCompleteUnloadOrDelete(), IopCompressRelationList(), IopCopyBootLogRegistryToFile(), IopCreateArcNames(), IopCreateCmResourceList(), IopCreateMadeupNode(), IopDeallocateApc(), IopDelayedRemoveWorker(), IopDeleteDevice(), IopDeleteDriver(), IopDeleteFile(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeleteSessionSymLinks(), IopDereferenceNotify(), IopDereferenceVpbAndFree(), IopDestroyDeviceNode(), IopDeviceActionWorker(), IopDeviceObjectFromDeviceInstance(), IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopDoDeferredSetInterfaceState(), IopDoNameTransmogrify(), IopDriverLoadingFailed(), IopDropIrp(), IopDuplicateDetection(), IopEnumerateDevice(), IopErrorLogDpc(), IopErrorLogThread(), IopExceptionCleanup(), IopExecuteHardwareProfileChange(), IopFilterResourceRequirementsList(), IopFreeAllocatedUnicodeString(), IopFreeBuffer(), IopFreeDCB(), IopFreeGroupTree(), IopFreeIrp(), IopFreeMiniPacket(), IopFreePoDeviceNotifyListHead(), IopFreeRelationList(), IopFreeReqAlternative(), IopFreeReqList(), IopFreeResourceRequirementsForAssignTable(), IopFreeUnicodeStringList(), IopGetBusTypeGuidIndex(), IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceInterfaces(), IopGetDeviceResourcesFromRegistry(), IopGetDriverDeviceList(), IopGetDriverNameFromKeyNode(), IopGetDriverTagPriority(), IopGetDumpStack(), IopGetGroupOrderIndex(), IopGetLegacyVetoListDrivers(), IopGetRegistryDwordWithFallback(), IopGetRegistryKeyInformation(), IopGetRegistrySecurityWithFallback(), IopGetRegistryValue(), IopGetRelatedTargetDevice(), IopGetResourceRequirementsForAssignTable(), IopGetRootDevices(), IopGetServiceInstanceCsConfigFlags(), IopGetServiceType(), IopHardErrorThread(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileMarkDock(), IopInitializeBootDrivers(), IopInitializeDCB(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInitializeResourceMap(), IopInitializeSystemDrivers(), IopInvalidateDeviceStateWorker(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopIsFirmwareMapperDevicePresent(), IopIsReportedAlready(), IopLegacyResourceAllocation(), IopLoadBootFilterDriver(), IopLoadDriver(), IopLoadDumpDriver(), IopLoadUnloadDriver(), IopMakeGloballyUniqueId(), IoPnPDeliverServicePowerNotification(), IopOpenDeviceParametersSubkey(), IopParseDevice(), IopPrepareDriverLoading(), IopProcessAssignResources(), IopProcessCompletedEject(), IopProcessCriticalDeviceRoutine(), IopProcessDeferredRegistrations(), IopProcessNewDeviceNode(), IopProcessNewProfileWorker(), IopProcessRelation(), IopProcessSetInterfaceState(), IopQueryConflictListInternal(), IopQueryDeviceResources(), IopQueryDockRemovalInterface(), IopQueryLegacyBusInformation(), IopQueryName(), IopQueryPnpBusInformation(), IopQueryRebalance(), IopQueryResourceHandlerInterface(), IopRaiseHardError(), IopRaiseInformationalHardError(), IopReadDeviceConfiguration(), IopReadDumpRegistry(), IopRealloc(), IopReallocateResources(), IopRebalance(), IopReleaseFilteredBootResources(), IopReleaseResources(), IopRemoveDeviceInterfaces(), IopRemoveIndirectRelationsFromList(), IopRemoveRelationFromList(), IopRemoveStringFromValueKey(), IopReportTargetDeviceChangeAsyncWorker(), IopRequestDeviceEjectWorker(), IopReserveBootResources(), IopReserveBootResourcesInternal(), IopReserveLegacyBootResources(), IopResizeBuffer(), IopRestartDeviceNode(), IopRestoreResourcesInternal(), IopSafebootDriverLoad(), IopServiceInstanceToDeviceInstance(), IopSetDefaultGateway(), IopSetDeviceSecurityDescriptors(), IopSetEaOrQuotaInformationFile(), IopSetSecurityObjectFromRegistry(), IopStartAndEnumerateDevice(), IopStartApcHardError(), IopStartDriverDevices(), IopStartNetworkForRemoteBoot(), IopSynchronousApiServiceTail(), IopTCPSetInformationEx(), IopTrackLink(), IopTranslateAndAdjustReqDesc(), IopUncacheInterfaceInformation(), IopUnloadAttachedDriver(), IopUnregisterDeviceInterface(), IopUpdateHardwareProfile(), IoQueryDeviceDescription(), IoRaiseInformationalHardError(), IoRegisterPlugPlayNotification(), IoReleaseRemoveLockAndWaitEx(), IoReleaseRemoveLockEx(), IoReportDetectedDevice(), IoReportResourceUsageInternal(), IoShutdownSystem(), IoUnregisterFsRegistrationChange(), IoUnregisterPlugPlayNotification(), IoUnregisterShutdownNotification(), IovpInternalCompleteAfterWait(), IovpInternalDeferredCompletion(), IovpProtectedIrpMakeUntouchable(), IovpSessionDataDereference(), IovpThrowChaffAtStartedPdoStack(), IovpTrackingDataFree(), IoWriteErrorLogEntry(), IsUdfsVolume(), Ke386CallBios(), KeRestoreFloatingPointState(), KeSetAutoAlignmentThread(), KeStartAllProcessors(), KeStartProfile(), KeStopProfile(), KiAddRange(), KiCompleteEffectiveRangeChange(), KiInitializeMTRR(), LfsDeallocateLbcb(), LfsDeallocateLcb(), LfsDeallocateLfcb(), LfsDeleteLogHandle(), LfsWriteLfsRestart(), LpcpDestroyPortQueue(), LpcpExtendPortZone(), LpcpInitializePortZone(), MapperAdjustResourceList(), MapperCallback(), MapperConstructRootEnumTree(), MapperFreeList(), MapperMarkKey(), MapperPeripheralCallback(), MapperPhantomizeDetectedComPorts(), MapperSeedKey(), MiAllocateContiguousMemory(), MiBuildImportsForBootDrivers(), MiCleanPhysicalProcessPages(), MiClearImports(), MiCloneProcessAddressSpace(), MiCreateDataFileMap(), MiCreateImageFileMap(), MiCreatePagingFileMap(), MiCreatePebOrTeb(), MiDecrementCloneBlockReference(), MiDereferenceImports(), MiDereferenceSegmentThread(), MiDoPoolCopy(), MiFindContiguousMemory(), MiFlushEventCounter(), MiFlushInPageSupportBlock(), MiFreeMdlTracker(), MiFreeSessionPoolBitMaps(), MiFreeSessionSpaceMap(), MiGetInPageSupportBlock(), MiGetWorkingSetInfo(), MiInitializeLoadedModuleList(), MiInsertInSystemSpace(), MiLoadSystemImage(), MiMapLockedPagesInUserSpace(), MiMapViewOfDataSection(), MiMapViewOfImageSection(), MiMapViewOfPhysicalSection(), MiPhysicalViewRemover(), MiReleaseDeadPteTrackers(), MiRemoveMappedView(), MiRemoveVad(), MiResolveImageReferences(), MiSectionInitialization(), MiSegmentDelete(), MiSessionRemoveImage(), MiSessionWideDereferenceImage(), MiSessionWideInsertImageAddress(), MiSnapThunk(), MiUnmapLockedPagesInUserSpace(), MiVerifierCheckThunks(), MiVerifyingDriverUnloading(), MmAddPhysicalMemory(), MmAddVerifierThunks(), MmAllocatePagesForMdl(), MmCallDllInitialize(), MmCleanProcessAddressSpace(), MmCreateSection(), MmDeleteTeb(), MmExtendSection(), MmFreeContiguousMemory(), MmFreeContiguousMemorySpecifyCache(), MmGetFileNameForSection(), MmInitializeProcessAddressSpace(), MmMapLockedPagesSpecifyCache(), MmMapVideoDisplay(), MmRemovePhysicalMemory(), MmSecureVirtualMemory(), MmUnloadSystemImage(), MmUnmapVideoDisplay(), MmUnmapViewOfSection(), MmUnsecureVirtualMemory(), NtAddAtom(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtCloseObjectAuditAlarm(), NtCreatePagingFile(), NtDeleteObjectAuditAlarm(), NtFindAtom(), NtFlushBuffersFile(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtfsRecFsControl(), NtLoadDriver(), NtLoadKey2(), NtMapUserPhysicalPages(), NtMapUserPhysicalPagesScatter(), NtOpenObjectAuditAlarm(), NtOpenThreadToken(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), NtQueryDirectoryObject(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQuerySystemEnvironmentValue(), NtQueryVolumeInformationFile(), NtQueueApcThread(), NtRaiseHardError(), NtReadFileScatter(), NtReplaceKey(), NtSecureConnectPort(), NtSetEaFile(), NtSetInformationFile(), NtSetInformationJobObject(), NtSetInformationProcess(), NtSetLdtEntries(), NtSetSystemEnvironmentValue(), NtSetSystemInformation(), NtSetValueKey(), NtSetVolumeInformationFile(), NtStartProfile(), NtStopProfile(), NtUnloadDriver(), NtUnlockFile(), NtWaitForMultipleObjects(), NtWriteFileGather(), ObCreateObjectType(), ObDereferenceDeviceMap(), ObGetObjectSecurity(), ObpCaptureObjectName(), ObpDeleteDirectoryEntry(), ObpDeleteNameCheck(), ObpDeleteSymbolicLink(), ObpDestroySecurityDescriptorHeader(), ObpFreeDosDevicesProtection(), ObpFreeObject(), ObpFreeObjectNameBuffer(), ObpInitSecurityDescriptorCache(), ObpInsertHandleCount(), ObpLogSecurityDescriptor(), ObpLookupObjectName(), ObpParseSymbolicLink(), ObpProcessDosDeviceSymbolicLink(), ObpRemoveObjectRoutine(), ObReleaseObjectSecurity(), ObSetSecurityDescriptorInfo(), OpenDeviceReparseIndex(), pIoQueryBusDescription(), pIoQueryDeviceDescription(), PnPBiosCopyDeviceParamKey(), PnPBiosCopyIoDecode(), PnPBiosEliminateDupes(), PnPBiosFreeDevNodeInfo(), PnPBiosGetBiosInfo(), PnPBiosMapper(), PnPBiosTranslateInfo(), PnPBiosWriteInfo(), PnPCheckFixedIoOverrideDecodes(), PsExitSpecialApc(), Psp386CreateVdmIoListHead(), Psp386InstallIoHandler(), PspApplyJobLimitsToProcessSet(), PspCaptureTokenFilter(), PspDeleteLdt(), PspDeleteThreadSecurity(), PspDeleteVdmObjects(), PspDereferenceQuota(), PspExitNormalApc(), PspExitThread(), PspJobDelete(), PspNullSpecialApc(), PspProcessDelete(), PspQueueApcSpecialApc(), PspSetLdtInformation(), PspSetLdtSize(), PspSetQuotaLimits(), PspTerminateThreadByPointer(), PspUserThreadStartup(), PsReturnSharedPoolQuota(), QueryDeviceNameForPath(), QuerySymbolicLink(), RtlpAllocDeallocQueryBuffer(), RtlpComputeMergedAcl(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpFreeAtom(), RtlpInheritAcl(), RtlpNewSecurityObject(), RtlpSetSecurityObject(), RtlReleaseRemoveLock(), RtlReleaseRemoveLockAndWait(), RtlVolumeDeviceToDosName(), SeAccessCheckByType(), SeAppendPrivileges(), SeCaptureAcl(), SeCaptureLuidAndAttributesArray(), SeCaptureObjectTypeList(), SeCaptureSecurityDescriptor(), SeCaptureSecurityQos(), SeCaptureSid(), SeCaptureSidAndAttributesArray(), SeCreateObjectAuditAlarm(), SeDeassignSecurity(), SeDeleteAccessState(), SeFreeCapturedObjectTypeList(), SeFreeCapturedSecurityQos(), SeFreePrivileges(), SeMakeAnonymousLogonToken(), SeMakeSystemToken(), SeOpenObjectAuditAlarm(), SeOpenObjectForDeleteAuditAlarm(), SepAccessCheckAndAuditAlarm(), SepAdtInitializeBounds(), SepAdtLogAuditRecord(), SepAdtObjectReferenceAuditAlarm(), SepAdtOpenObjectAuditAlarm(), SepCopyProxyData(), SepCreateLogonSessionTrack(), SepDeleteLogonSessionTrack(), SepDequeueWorkItem(), SepDeReferenceLogonSession(), SepDuplicateToken(), SepFilterToken(), SepFreeCapturedString(), SepFreeProxyData(), SepInformLsaOfDeletedLogon(), SepInitializationPhase1(), SepNotifyFileSystems(), SepProbeAndCaptureQosData(), SepProbeAndCaptureString_U(), SepQueryNameString(), SepRmCallLsa(), SepTokenDeleteMethod(), SeReleaseAcl(), SeReleaseLuidAndAttributesArray(), SeReleaseSecurityDescriptor(), SeReleaseSid(), SeReleaseSidAndAttributesArray(), SeRmInitPhase1(), SeUnregisterLogonSessionTerminatedRoutine(), SmbTraceCompleteRdr(), SmbTraceCompleteSrv(), SmbTraceDeferredDereferenceHeap(), SmbTraceEmptyQueue(), SmbTraceInitialize(), SmbTraceTerminate(), SmbTraceThreadEntry(), TestCaptureSecurityDescriptor(), TestDefaultObjectMethod(), TestMakeSystemToken(), TestTokenCopy(), TestTokenSize(), UdfDeallocateTable(), UdfDeletePcb(), UdfFreePool(), UdfNormalizeFileNames(), UdfRemovePrefix(), UdfUpdateVcbPhase0(), VdmpDelayInterrupt(), VdmpInitialize(), VdmQueryDirectoryFile(), VerifierFreePool(), ViReservePoolAllocation(), Win32KDriverUnload(), Win32kNtUserCleanup(), xHalExamineMBR(), xHalGetPartialGeometry(), xHalIoAssignDriveLetters(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), and xHalIoWritePartitionTable().

00976 : 00977 00978 This function deallocates a block of pool. This function is used to 00979 deallocate to both the page aligned pools, and the binary buddy 00980 (less than a page) pools. 00981 00982 If the address of the block being deallocated is page-aligned, then 00983 the page-aliged pool deallocator is used. 00984 00985 Otherwise, the binary buddy pool deallocator is used. Deallocation 00986 looks at the allocated block's pool header to determine the pool 00987 type and block size being deallocated. If the pool was allocated 00988 using ExAllocatePoolWithQuota, then after the deallocation is 00989 complete, the appropriate process's pool quota is adjusted to reflect 00990 the deallocation, and the process object is dereferenced. 00991 00992 Arguments: 00993 00994 P - Supplies the address of the block of pool being deallocated. 00995 00996 Return Value: 00997 00998 None. 00999 01000 --*/ 01001 01002 { 01003 PPOOL_HEADER Entry; 01004 POOL_TYPE PoolType; 01005 KIRQL LockHandle; 01006 PVOID Lock; 01007 PPOOL_DESCRIPTOR PoolDesc; 01008 01009 KIRQL OldIrql; 01010 BOOLEAN ReleaseSpinLock = TRUE; 01011 PMMPTE PointerPte; 01012 PMMPFN Pfn1; 01013 01014 #ifdef TRACE_ALLOC 01015 01016 PULONG xFp, xPrevFp, xR1, xPrevR1; 01017 01018 xFp = RtlpGetFramePointer(); 01019 xR1 = (PULONG)*(xFp+1); 01020 xPrevFp = (PULONG)*xFp; 01021 xPrevR1 = (PULONG)*(xPrevFp+1); 01022 01023 #endif // TRACE_ALLOC 01024 01025 // 01026 // If Entry is page aligned, then call page aligned pool 01027 // 01028 01029 if ( PAGE_ALIGNED(P) ) { 01030 01031 PoolType = MmDeterminePoolType(P); 01032 01033 Lock = PoolVector[PoolType]->LockAddress; 01034 01035 LOCK_POOL(Lock,PoolType,LockHandle); 01036 MiFreePoolPages (P); 01037 UNLOCK_POOL(Lock,PoolType,LockHandle,FALSE); 01038 return; 01039 } 01040 01041 PointerPte = MiGetPteAddress (P); 01042 01043 if (PointerPte->u.Hard.Valid == 0) { 01044 DbgPrint("bad pool deallocation\n"); 01045 KeBugCheck (12345); 01046 } 01047 01048 if (KeGetCurrentIrql() >= 2) { 01049 DbgPrint("deallocating pool at irql >= 2\n"); 01050 ReleaseSpinLock = FALSE; 01051 } else { 01052 KeAcquireSpinLock ( &MmPfnLock, &OldIrql); 01053 } 01054 01055 KeSweepDcache(TRUE); 01056 01057 Pfn1 = MI_PFN_ELEMENT (PointerPte->u.Hard.PageFrameNumber); 01058 Pfn1->PteAddress = (PMMPTE)MM_EMPTY_LIST; 01059 MiDecrementShareCountOnly (PointerPte->u.Hard.PageFrameNumber); 01060 *PointerPte = ZeroPte; 01061 MiReleaseSystemPtes (PointerPte, 2, SystemPteSpace); 01062 // 01063 // BUGBUG Fix for MP. 01064 // 01065 KiFlushSingleTb (P,TRUE); 01066 if (ReleaseSpinLock) { 01067 KeReleaseSpinLock ( &MmPfnLock, OldIrql ); 01068 } 01069 return; 01070 01071 Entry = (PPOOL_HEADER)((PCH)P - POOL_OVERHEAD); 01072 01073 PoolType = Entry->PoolType; 01074 01075 PoolDesc = PoolVector[PoolType]; 01076 Lock = PoolDesc->LockAddress; 01077 01078 // 01079 // Sanity Check pool header 01080 // 01081 01082 if ( (Entry->LogAllocationSize == 0) || (Entry->PoolType >= MaxPoolType) ) { 01083 DbgPrint("Invalid pool header 0x%lx 0x%lx\n",P,*(PULONG)P); 01084 KeBugCheck(BAD_POOL_HEADER); 01085 return; 01086 } 01087 01088 if ( (ULONG)P & 0x0000000f != 8 ) { 01089 DbgPrint("Misaligned Deallocation 0x%lx\n",P); 01090 KeBugCheck(BAD_POOL_HEADER); 01091 return; 01092 } 01093 01094 #ifdef TRACE_ALLOC 01095 { 01096 KIRQL xIrql; 01097 PLIST_ENTRY Next, Target; 01098 BOOLEAN Found; 01099 01100 KeRaiseIrql(APC_LEVEL, &xIrql); 01101 01102 KeWaitForSingleObject( 01103 &TracePoolLock, 01104 PoolAllocation, 01105 KernelMode, 01106 FALSE, 01107 NULL 01108 ); 01109 01110 Found = FALSE; 01111 Target = &Entry->TraceLinks; 01112 Next = TracePoolListHead[PoolType].Flink; 01113 while( Next != &TracePoolListHead[PoolType] ){ 01114 if ( Next == Target ) { 01115 01116 RemoveEntryList(&Entry->TraceLinks); 01117 Found = TRUE; 01118 break; 01119 } 01120 Next = Next->Flink; 01121 } 01122 01123 if ( !Found ) { 01124 DbgPrint("Block Not in Allocated Pool List 0x%lx\n",P); 01125 KeBugCheck(BAD_POOL_HEADER); 01126 return; 01127 } 01128 01129 DeallocTrace[NextDeallocTrace].BufferAddress = P; 01130 DeallocTrace[NextDeallocTrace].Thread = PsGetCurrentThread(); 01131 DeallocTrace[NextDeallocTrace].xR1 = xR1; 01132 DeallocTrace[NextDeallocTrace++].xPrevR1 = xPrevR1; 01133 if ( NextDeallocTrace >= MAXTRACE ) { 01134 NextDeallocTrace = 0; 01135 } 01136 01137 (VOID) KeReleaseSemaphore( 01138 &TracePoolLock, 01139 0L, 01140 1L, 01141 FALSE 01142 ); 01143 KeLowerIrql(xIrql); 01144 01145 } 01146 #endif // TRACE_ALLOC 01147 01148 #ifndef TRACE_ALLOC 01149 01150 // 01151 // Check ProcessBilled flag to see if quota was charged on 01152 // this allocation 01153 // 01154 01155 if ( Entry->ProcessBilled ) { 01156 01157 PsReturnPoolQuota( 01158 Entry->ProcessBilled, 01159 BasePoolTypeTable[PoolType], 01160 (1 << Entry->LogAllocationSize) 01161 ); 01162 01163 ObDereferenceObject(Entry->ProcessBilled); 01164 01165 } 01166 #endif // TRACE_ALLOC 01167 01168 LOCK_POOL(Lock,PoolType,LockHandle); 01169 01170 DeallocatePoolInternal(PoolDesc,Entry); 01171 01172 UNLOCK_POOL(Lock,PoolType,LockHandle,FALSE); 01173 01174 }

KIRQL ExLockPool IN POOL_TYPE  PoolType  ) 
 

Definition at line 190 of file poolhack.c.

References APC_LEVEL, BASE_POOL_TYPE_MASK, FALSE, KeAcquireSpinLock, KeRaiseIrql(), KernelMode, KeWaitForSingleObject(), _POOL_DESCRIPTOR::LockAddress, NonPagedPool, NonPagedPoolDescriptor, NonPagedPoolMustSucceed, NULL, PagedPool, PoolAllocation, and PoolVector.

Referenced by MiFindContiguousMemory().

00196 : 00197 00198 This function locks the pool specified by pool type. 00199 00200 Arguments: 00201 00202 PoolType - Specifies the pool that should be locked. 00203 00204 Return Value: 00205 00206 Opaque - Returns a lock handle that must be returned in a subsequent 00207 call to ExUnlockPool. 00208 00209 --*/ 00210 00211 { 00212 00213 KIRQL Irql; 00214 00215 if ( PoolType == NonPagedPool || PoolType == NonPagedPoolMustSucceed ) { 00216 00217 // 00218 // Spin Lock locking 00219 // 00220 00221 KeAcquireSpinLock((PKSPIN_LOCK)PoolVector[PoolType]->LockAddress, &Irql); 00222 return Irql; 00223 } else { 00224 00225 // 00226 // Mutex Locking 00227 // 00228 00229 KeRaiseIrql(APC_LEVEL, &Irql); 00230 00231 KeWaitForSingleObject( 00232 PoolVector[PoolType]->LockAddress, 00233 PoolAllocation, 00234 KernelMode, 00235 FALSE, 00236 NULL 00237 ); 00238 00239 return Irql; 00240 } 00241 00242 }

ULONG ExpAllocatePoolWithQuotaHandler IN NTSTATUS  ExceptionCode,
IN PVOID  PoolAddress
 

Definition at line 651 of file poolhack.c.

References ASSERT, EXCEPTION_CONTINUE_SEARCH, and ExFreePool().

Referenced by ExAllocatePoolWithQuota(), and ExAllocatePoolWithQuotaTag().

00658 : 00659 00660 This function is called when an exception occurs in ExFreePool 00661 while quota is being charged to a process. 00662 00663 Its function is to deallocate the pool block and continue the search 00664 for an exception handler. 00665 00666 Arguments: 00667 00668 ExceptionCode - Supplies the exception code that caused this 00669 function to be entered. 00670 00671 PoolAddress - Supplies the address of a pool block that needs to be 00672 deallocated. 00673 00674 Return Value: 00675 00676 EXCEPTION_CONTINUE_SEARCH - The exception should be propagated to the 00677 caller of ExAllocatePoolWithQuota. 00678 00679 --*/ 00680 00681 { 00682 if ( PoolAddress ) { 00683 ASSERT(ExceptionCode == STATUS_QUOTA_EXCEEDED); 00684 ExFreePool(PoolAddress); 00685 } else { 00686 ASSERT(ExceptionCode == STATUS_INSUFFICIENT_RESOURCES); 00687 } 00688 return EXCEPTION_CONTINUE_SEARCH; 00689 }

PLIST_ENTRY ExpInterlockedTryAllocatePool IN PLIST_ENTRY  List,
IN KSPIN_LOCK  Lock,
IN ULONG  Size,
IN LONG  SizeOffset
 

VOID ExQueryPoolUsage OUT PULONG  PagedPoolPages,
OUT PULONG  NonPagedPoolPages
 

Definition at line 1493 of file poolhack.c.

References NonPagedPool, NonPagedPoolMustSucceed, PagedPool, pd, PoolVector, and PPOOL_DESCRIPTOR.

01497 { 01498 PPOOL_DESCRIPTOR pd; 01499 01500 pd = PoolVector[PagedPool]; 01501 *PagedPoolPages = pd->TotalPages; 01502 pd = PoolVector[PagedPoolMustSucceed]; 01503 *PagedPoolPages += pd->TotalPages; 01504 01505 pd = PoolVector[NonPagedPool]; 01506 *NonPagedPoolPages = pd->TotalPages; 01507 pd = PoolVector[NonPagedPoolMustSucceed]; 01508 *NonPagedPoolPages += pd->TotalPages; 01509 01510 }

VOID ExUnlockPool IN POOL_TYPE  PoolType,
IN KIRQL  LockHandle,
IN BOOLEAN  Wait
 

Definition at line 262 of file poolhack.c.

References KeLowerIrql(), KeReleaseMutex(), KeReleaseSpinLock(), NonPagedPool, NonPagedPoolMustSucceed, and PoolVector.

00270 : 00271 00272 This function unlocks the pool specified by pool type. If the value 00273 of the Wait parameter is true, then the pool's lock is released 00274 using "wait == true". 00275 00276 00277 Arguments: 00278 00279 PoolType - Specifies the pool that should be unlocked. 00280 00281 LockHandle - Specifies the lock handle from a previous call to 00282 ExLockPool. 00283 00284 Wait - Supplies a boolean value that signifies whether the call to 00285 ExUnlockPool will be immediately followed by a call to one of 00286 the kernel Wait functions. 00287 00288 Return Value: 00289 00290 None. 00291 00292 --*/ 00293 00294 { 00295 00296 if ( PoolType == NonPagedPool || (PoolType) == NonPagedPoolMustSucceed ) { 00297 00298 // 00299 // Spin Lock locking 00300 // 00301 00302 KeReleaseSpinLock( 00303 (PKSPIN_LOCK)PoolVector[PoolType]->LockAddress, 00304 LockHandle 00305 ); 00306 00307 } else { 00308 00309 // 00310 // Mutex Locking 00311 // 00312 00313 KeReleaseMutex((PKMUTEX)PoolVector[PoolType]->LockAddress,Wait); 00314 00315 // 00316 // This could be a problem if wait == true is specified ! 00317 // 00318 00319 KeLowerIrql(LockHandle); 00320 } 00321 00322 }

VOID InitializePool IN POOL_TYPE  PoolType,
IN ULONG  Threshold
 

DBG

DBG

Definition at line 325 of file poolhack.c.

References ASSERT, _POOL_LIST_HEAD::CurrentFreeLength, ExAllocatePoolWithTag, ExInitializeFastMutex, ExpInitializePoolDescriptor(), ExpInsertPoolTracker(), ExpNumberOfPagedPools, ExpPagedPoolDescriptor, ExpTaggedPoolLock, FALSE, Index, KeBugCheck(), KeBugCheckEx(), KeInitializeMutex(), KeInitializeSemaphore(), KeInitializeSpinLock(), L, _POOL_DESCRIPTOR::ListHeads, _POOL_DESCRIPTOR::LockAddress, MAX_BIGPAGE_TABLE, MiAllocatePoolPages(), MUST_SUCCEED_POOL_TYPE_MASK, MustSucceedPoolTable, NonPagedPool, NonPagedPoolDescriptor, NonPagedPoolDescriptorMS, NonPagedPoolLock, NonPagedPoolMustSucceed, NtGlobalFlag, NULL, PagedPool, PagedPoolDescriptor, PagedPoolDescriptorMS, PagedPoolLock, POOL_HEADER, POOL_LIST_HEADS, POOL_OVERHEAD, POOL_PAGE_SIZE, POOL_SMALLEST_BLOCK, POOL_TRACKER_BIG_PAGES, POOL_TRACKER_TABLE, POOL_TYPE, PoolBigPageTable, PoolBigPageTableHash, PoolBigPageTableSize, PoolTrackTable, PoolTrackTableMask, PoolTrackTableSize, _POOL_DESCRIPTOR::PoolType, PoolVector, PsGetCurrentProcess, ROUND_TO_PAGES, Size, _POOL_DESCRIPTOR::Threshold, and _POOL_DESCRIPTOR::TotalPages.

Referenced by MiBuildPagedPool(), and MiInitMachineDependent().

00332 : 00333 00334 This procedure initializes a pool descriptor for a binary buddy pool 00335 type. Once initialized, the pool may be used for allocation and 00336 deallocation. 00337 00338 This function should be called once for each base pool type during 00339 system initialization. 00340 00341 Each pool descriptor contains an array of list heads for free 00342 blocks. Each list head holds blocks of a particular size. One list 00343 head contains page-sized blocks. The other list heads contain 1/2- 00344 page-sized blocks, 1/4-page-sized blocks.... A threshold is 00345 associated with the page-sized list head. The number of free blocks 00346 on this list will not grow past the specified threshold. When a 00347 deallocation occurs that would cause the threshold to be exceeded, 00348 the page is returned to the page-aliged pool allocator. 00349 00350 Arguments: 00351 00352 PoolType - Supplies the type of pool being initialized (e.g. 00353 nonpaged pool, paged pool...). 00354 00355 Threshold - Supplies the threshold value for the specified pool. 00356 00357 Return Value: 00358 00359 None. 00360 00361 --*/ 00362 00363 { 00364 int i; 00365 POOL_TYPE BasePoolType, MustSucceedPoolType; 00366 00367 if ( MustSucceedPoolTable[PoolType] ) { 00368 KeBugCheck(PHASE0_INITIALIZATION_FAILED); 00369 } 00370 00371 if (PoolType == NonPagedPool) { 00372 00373 BasePoolType = NonPagedPool; 00374 MustSucceedPoolType = NonPagedPoolMustSucceed; 00375 00376 KeInitializeSpinLock(&PsGetCurrentProcess()->StatisticsLock); 00377 KeInitializeSpinLock(&NonPagedPoolLock); 00378 NonPagedPoolDescriptor.LockAddress = (PVOID)&NonPagedPoolLock; 00379 NonPagedPoolDescriptorMS.LockAddress = (PVOID)&NonPagedPoolLock; 00380 00381 KeInitializeMutex(&PagedPoolLock,MUTEX_LEVEL_EX_PAGED_POOL); 00382 PagedPoolDescriptor.LockAddress = (PVOID)&PagedPoolLock; 00383 PagedPoolDescriptorMS.LockAddress = (PVOID)&PagedPoolLock; 00384 00385 #ifdef TRACE_ALLOC 00386 00387 KeInitializeSemaphore(&TracePoolLock,1L,1L); 00388 InitializeListHead(&TracePoolListHead[NonPagedPool]); 00389 InitializeListHead(&TracePoolListHead[PagedPool]); 00390 00391 #endif // TRACE_ALLOC 00392 } else { 00393 BasePoolType = PagedPool; 00394 MustSucceedPoolType = PagedPoolMustSucceed; 00395 } 00396 00397 PoolVector[BasePoolType]->TotalPages = 0; 00398 PoolVector[BasePoolType]->Threshold = Threshold; 00399 PoolVector[BasePoolType]->PoolType = BasePoolType; 00400 PoolVector[MustSucceedPoolType]->TotalPages = 0; 00401 PoolVector[MustSucceedPoolType]->Threshold = 0; 00402 PoolVector[MustSucceedPoolType]->PoolType = MustSucceedPoolType; 00403 for (i=0; i<POOL_LIST_HEADS ;i++ ) { 00404 InitializeListHead(&PoolVector[BasePoolType]->ListHeads[i].ListHead); 00405 PoolVector[BasePoolType]->ListHeads[i].CurrentFreeLength = 0; 00406 InitializeListHead(&PoolVector[MustSucceedPoolType]->ListHeads[i].ListHead); 00407 PoolVector[MustSucceedPoolType]->ListHeads[i].CurrentFreeLength = 0; 00408 } 00409 return; 00410 }


Variable Documentation

POOL_TYPE BasePoolTypeTable[MaxPoolType]
 

Initial value:

Definition at line 133 of file poolhack.c.

Referenced by AllocatePoolInternal(), ExAllocatePool(), ExAllocatePoolWithQuota(), and ExFreePool().

BOOLEAN MustSucceedPoolTable[MaxPoolType]
 

Initial value:

{ FALSE, FALSE, TRUE, TRUE }

Definition at line 140 of file poolhack.c.

Referenced by AllocatePoolInternal(), ExAllocatePool(), and InitializePool().

POOL_DESCRIPTOR NonPagedPoolDescriptor
 

Definition at line 119 of file poolhack.c.

POOL_DESCRIPTOR NonPagedPoolDescriptorMS
 

Definition at line 120 of file poolhack.c.

KSPIN_LOCK NonPagedPoolLock
 

Definition at line 122 of file poolhack.c.

Referenced by ExAllocatePoolWithTag(), ExUnlockPool(), and InitializePool().

POOL_DESCRIPTOR PagedPoolDescriptor
 

Definition at line 119 of file poolhack.c.

Referenced by InitializePool().

POOL_DESCRIPTOR PagedPoolDescriptorMS
 

Definition at line 120 of file poolhack.c.

Referenced by InitializePool().

KMUTEX PagedPoolLock
 

Definition at line 123 of file poolhack.c.

Referenced by InitializePool().

CHAR PoolIndexTable[128]
 

Initial value:

{ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }

Definition at line 73 of file poolhack.c.

Referenced by ExAllocatePool().

PPOOL_DESCRIPTOR PoolVector[MaxPoolType]
 

Initial value:

Definition at line 126 of file poolhack.c.


Generated on Sat May 15 19:45:17 2004 for test by doxygen 1.3.7