ReactOS  0.4.14-dev-337-gf981a68
heappage.c File Reference
#include <rtl.h>
#include <heap.h>
#include <debug.h>
Include dependency graph for heappage.c:

Go to the source code of this file.

Classes

struct  _DPH_BLOCK_INFORMATION
 
struct  _DPH_HEAP_BLOCK
 
struct  _DPH_HEAP_ROOT
 

Macros

#define NDEBUG
 
#define DPH_RESERVE_SIZE   0x100000
 
#define DPH_POOL_SIZE   0x4000
 
#define DPH_FREE_LIST_MINIMUM   8
 
#define DPH_BREAK_ON_RESERVE_FAIL   0x01
 
#define DPH_BREAK_ON_COMMIT_FAIL   0x02
 
#define DPH_BREAK_ON_RELEASE_FAIL   0x04
 
#define DPH_BREAK_ON_FREE_FAIL   0x08
 
#define DPH_BREAK_ON_PROTECT_FAIL   0x10
 
#define DPH_BREAK_ON_NULL_FREE   0x80
 
#define DPH_DEBUG_INTERNAL_VALIDATE   0x01
 
#define DPH_DEBUG_VERBOSE   0x04
 
#define DPH_EXTRA_LOG_STACK_TRACES   0x02
 
#define DPH_EXTRA_CHECK_UNDERRUN   0x10
 
#define DPH_FILL   0xEEEEEEEE
 
#define DPH_FILL_START_STAMP_1   0xABCDBBBB
 
#define DPH_FILL_START_STAMP_2   0xABCDBBBA
 
#define DPH_FILL_END_STAMP_1   0xDCBABBBB
 
#define DPH_FILL_END_STAMP_2   0xDCBABBBA
 
#define DPH_FILL_SUFFIX   0xD0
 
#define DPH_FILL_INFIX   0xC0
 
#define DPH_VALINFO_BAD_START_STAMP   0x01
 
#define DPH_VALINFO_BAD_END_STAMP   0x02
 
#define DPH_VALINFO_BAD_POINTER   0x04
 
#define DPH_VALINFO_BAD_PREFIX_PATTERN   0x08
 
#define DPH_VALINFO_BAD_SUFFIX_PATTERN   0x10
 
#define DPH_VALINFO_EXCEPTION   0x20
 
#define DPH_VALINFO_1   0x40
 
#define DPH_VALINFO_BAD_INFIX_PATTERN   0x80
 
#define DPH_VALINFO_ALREADY_FREED   0x100
 
#define DPH_VALINFO_CORRUPTED_AFTER_FREE   0x200
 
#define DPH_SIGNATURE   0xFFEEDDCC
 
#define IS_BIASED_POINTER(ptr)   ((ULONG_PTR)(ptr) & 1)
 
#define POINTER_REMOVE_BIAS(ptr)   ((ULONG_PTR)(ptr) & ~(ULONG_PTR)1)
 
#define POINTER_ADD_BIAS(ptr)   ((ULONG_PTR)(ptr) | 1)
 

Typedefs

typedef struct _DPH_BLOCK_INFORMATION DPH_BLOCK_INFORMATION
 
typedef struct _DPH_BLOCK_INFORMATIONPDPH_BLOCK_INFORMATION
 
typedef struct _DPH_HEAP_BLOCK DPH_HEAP_BLOCK
 
typedef struct _DPH_HEAP_BLOCKPDPH_HEAP_BLOCK
 
typedef struct _DPH_HEAP_ROOT DPH_HEAP_ROOT
 
typedef struct _DPH_HEAP_ROOTPDPH_HEAP_ROOT
 

Functions

BOOLEAN NTAPI RtlpDphGrowVirtual (PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
 
BOOLEAN NTAPI RtlpDphIsNormalFreeHeapBlock (PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
 
VOID NTAPI RtlpDphReportCorruptedBlock (PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
 
BOOLEAN NTAPI RtlpDphNormalHeapValidate (PDPH_HEAP_ROOT DphRoot, ULONG Flags, PVOID BaseAddress)
 
VOID NTAPI RtlpDphRaiseException (NTSTATUS Status)
 
PVOID NTAPI RtlpDphPointerFromHandle (PVOID Handle)
 
VOID NTAPI RtlpDphEnterCriticalSection (PDPH_HEAP_ROOT DphRoot, ULONG Flags)
 
VOID NTAPI RtlpDphLeaveCriticalSection (PDPH_HEAP_ROOT DphRoot)
 
VOID NTAPI RtlpDphPreProcessing (PDPH_HEAP_ROOT DphRoot, ULONG Flags)
 
VOID NTAPI RtlpDphPostProcessing (PDPH_HEAP_ROOT DphRoot)
 
NTSTATUS NTAPI RtlpSecMemFreeVirtualMemory (HANDLE Process, PVOID *Base, PSIZE_T Size, ULONG Type)
 
NTSTATUS NTAPI RtlpDphAllocateVm (PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
 
NTSTATUS NTAPI RtlpDphFreeVm (PVOID Base, SIZE_T Size, ULONG Type)
 
NTSTATUS NTAPI RtlpDphProtectVm (PVOID Base, SIZE_T Size, ULONG Protection)
 
BOOLEAN NTAPI RtlpDphWritePageHeapBlockInformation (PDPH_HEAP_ROOT DphRoot, PVOID UserAllocation, SIZE_T Size, SIZE_T UserSize)
 
VOID NTAPI RtlpDphPlaceOnBusyList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
 
VOID NTAPI RtlpDphPlaceOnFreeList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphPlaceOnPoolList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphPlaceOnVirtualList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
PDPH_HEAP_BLOCK NTAPI RtlpDphTakeNodeFromUnusedList (PDPH_HEAP_ROOT DphRoot)
 
VOID NTAPI RtlpDphReturnNodeToUnusedList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphRemoveFromAvailableList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphRemoveFromBusyList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphRemoveFromFreeList (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node, PDPH_HEAP_BLOCK Prev)
 
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
VOID NTAPI RtlpDphCoalesceFreeIntoAvailable (PDPH_HEAP_ROOT DphRoot, ULONG LeaveOnFreeList)
 
VOID NTAPI RtlpDphAddNewPool (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
 
PDPH_HEAP_BLOCK NTAPI RtlpDphSearchAvailableMemoryListForBestFit (PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
 
PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory (PDPH_HEAP_ROOT DphRoot, SIZE_T Size, BOOLEAN Grow)
 
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory (PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
 
NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse (PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
 
NTSTATUS NTAPI RtlpDphSetProtectionAfterUse (PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
 
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode (PDPH_HEAP_ROOT DphRoot)
 
RTL_GENERIC_COMPARE_RESULTS NTAPI RtlpDphCompareNodeForTable (IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
 
PVOID NTAPI RtlpDphAllocateNodeForTable (IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
 
VOID NTAPI RtlpDphFreeNodeForTable (IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
 
NTSTATUS NTAPI RtlpDphInitializeDelayedFreeQueue (VOID)
 
VOID NTAPI RtlpDphFreeDelayedBlocksFromHeap (PDPH_HEAP_ROOT DphRoot, PHEAP NormalHeap)
 
NTSTATUS NTAPI RtlpDphTargetDllsLogicInitialize (VOID)
 
VOID NTAPI RtlpDphInternalValidatePageHeap (PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
 
VOID NTAPI RtlpDphVerifyIntegrity (PDPH_HEAP_ROOT DphRoot)
 
BOOLEAN NTAPI RtlpDphIsPageHeapBlock (PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
 
NTSTATUS NTAPI RtlpDphProcessStartupInitialization (VOID)
 
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap (PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
 
HANDLE NTAPI RtlpPageHeapCreate (ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
 
PVOID NTAPI RtlpPageHeapDestroy (HANDLE HeapPtr)
 
PVOID NTAPI RtlpPageHeapAllocate (IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
 
BOOLEAN NTAPI RtlpPageHeapFree (HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
 
PVOID NTAPI RtlpPageHeapReAllocate (HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
 
BOOLEAN NTAPI RtlpPageHeapGetUserInfo (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
 
BOOLEAN NTAPI RtlpPageHeapSetUserValue (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
 
BOOLEAN NTAPI RtlpPageHeapSetUserFlags (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
 
SIZE_T NTAPI RtlpPageHeapSize (HANDLE HeapHandle, ULONG Flags, PVOID BaseAddress)
 
BOOLEAN NTAPI RtlpDebugPageHeapValidate (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress)
 
BOOLEAN NTAPI RtlpPageHeapLock (HANDLE HeapPtr)
 
BOOLEAN NTAPI RtlpPageHeapUnlock (HANDLE HeapPtr)
 

Variables

BOOLEAN RtlpPageHeapEnabled = FALSE
 
ULONG RtlpDphGlobalFlags
 
ULONG RtlpPageHeapSizeRangeStart
 
ULONG RtlpPageHeapSizeRangeEnd
 
ULONG RtlpPageHeapDllRangeStart
 
ULONG RtlpPageHeapDllRangeEnd
 
WCHAR RtlpDphTargetDlls [512]
 
LIST_ENTRY RtlpDphPageHeapList
 
BOOLEAN RtlpDphPageHeapListInitialized
 
HEAP_LOCK _RtlpDphPageHeapListLock
 
PHEAP_LOCK RtlpDphPageHeapListLock = &_RtlpDphPageHeapListLock
 
ULONG RtlpDphPageHeapListLength
 
UNICODE_STRING RtlpDphTargetDllsUnicode
 
HEAP_LOCK _RtlpDphDelayedFreeQueueLock
 
PHEAP_LOCK RtlpDphDelayedFreeQueueLock = &_RtlpDphDelayedFreeQueueLock
 
LIST_ENTRY RtlpDphDelayedFreeQueue
 
SLIST_HEADER RtlpDphDelayedTemporaryPushList
 
SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks
 
ULONG RtlpDphNumberOfDelayedFreeBlocks
 
LONG RtlpDphCounter
 
LONG RtlpDphAllocFails
 
LONG RtlpDphReleaseFails
 
LONG RtlpDphFreeFails
 
LONG RtlpDphProtectFails
 
ULONG RtlpDphBreakOptions = 0
 
ULONG RtlpDphDebugOptions
 

Macro Definition Documentation

◆ DPH_BREAK_ON_COMMIT_FAIL

#define DPH_BREAK_ON_COMMIT_FAIL   0x02

Definition at line 139 of file heappage.c.

◆ DPH_BREAK_ON_FREE_FAIL

#define DPH_BREAK_ON_FREE_FAIL   0x08

Definition at line 141 of file heappage.c.

◆ DPH_BREAK_ON_NULL_FREE

#define DPH_BREAK_ON_NULL_FREE   0x80

Definition at line 143 of file heappage.c.

◆ DPH_BREAK_ON_PROTECT_FAIL

#define DPH_BREAK_ON_PROTECT_FAIL   0x10

Definition at line 142 of file heappage.c.

◆ DPH_BREAK_ON_RELEASE_FAIL

#define DPH_BREAK_ON_RELEASE_FAIL   0x04

Definition at line 140 of file heappage.c.

◆ DPH_BREAK_ON_RESERVE_FAIL

#define DPH_BREAK_ON_RESERVE_FAIL   0x01

Definition at line 138 of file heappage.c.

◆ DPH_DEBUG_INTERNAL_VALIDATE

#define DPH_DEBUG_INTERNAL_VALIDATE   0x01

Definition at line 146 of file heappage.c.

◆ DPH_DEBUG_VERBOSE

#define DPH_DEBUG_VERBOSE   0x04

Definition at line 147 of file heappage.c.

◆ DPH_EXTRA_CHECK_UNDERRUN

#define DPH_EXTRA_CHECK_UNDERRUN   0x10

Definition at line 151 of file heappage.c.

◆ DPH_EXTRA_LOG_STACK_TRACES

#define DPH_EXTRA_LOG_STACK_TRACES   0x02

Definition at line 150 of file heappage.c.

◆ DPH_FILL

#define DPH_FILL   0xEEEEEEEE

Definition at line 154 of file heappage.c.

◆ DPH_FILL_END_STAMP_1

#define DPH_FILL_END_STAMP_1   0xDCBABBBB

Definition at line 157 of file heappage.c.

◆ DPH_FILL_END_STAMP_2

#define DPH_FILL_END_STAMP_2   0xDCBABBBA

Definition at line 158 of file heappage.c.

◆ DPH_FILL_INFIX

#define DPH_FILL_INFIX   0xC0

Definition at line 160 of file heappage.c.

◆ DPH_FILL_START_STAMP_1

#define DPH_FILL_START_STAMP_1   0xABCDBBBB

Definition at line 155 of file heappage.c.

◆ DPH_FILL_START_STAMP_2

#define DPH_FILL_START_STAMP_2   0xABCDBBBA

Definition at line 156 of file heappage.c.

◆ DPH_FILL_SUFFIX

#define DPH_FILL_SUFFIX   0xD0

Definition at line 159 of file heappage.c.

◆ DPH_FREE_LIST_MINIMUM

#define DPH_FREE_LIST_MINIMUM   8

Definition at line 135 of file heappage.c.

◆ DPH_POOL_SIZE

#define DPH_POOL_SIZE   0x4000

Definition at line 134 of file heappage.c.

◆ DPH_RESERVE_SIZE

#define DPH_RESERVE_SIZE   0x100000

Definition at line 133 of file heappage.c.

◆ DPH_SIGNATURE

#define DPH_SIGNATURE   0xFFEEDDCC

Definition at line 175 of file heappage.c.

◆ DPH_VALINFO_1

#define DPH_VALINFO_1   0x40

Definition at line 169 of file heappage.c.

◆ DPH_VALINFO_ALREADY_FREED

#define DPH_VALINFO_ALREADY_FREED   0x100

Definition at line 171 of file heappage.c.

◆ DPH_VALINFO_BAD_END_STAMP

#define DPH_VALINFO_BAD_END_STAMP   0x02

Definition at line 164 of file heappage.c.

◆ DPH_VALINFO_BAD_INFIX_PATTERN

#define DPH_VALINFO_BAD_INFIX_PATTERN   0x80

Definition at line 170 of file heappage.c.

◆ DPH_VALINFO_BAD_POINTER

#define DPH_VALINFO_BAD_POINTER   0x04

Definition at line 165 of file heappage.c.

◆ DPH_VALINFO_BAD_PREFIX_PATTERN

#define DPH_VALINFO_BAD_PREFIX_PATTERN   0x08

Definition at line 166 of file heappage.c.

◆ DPH_VALINFO_BAD_START_STAMP

#define DPH_VALINFO_BAD_START_STAMP   0x01

Definition at line 163 of file heappage.c.

◆ DPH_VALINFO_BAD_SUFFIX_PATTERN

#define DPH_VALINFO_BAD_SUFFIX_PATTERN   0x10

Definition at line 167 of file heappage.c.

◆ DPH_VALINFO_CORRUPTED_AFTER_FREE

#define DPH_VALINFO_CORRUPTED_AFTER_FREE   0x200

Definition at line 172 of file heappage.c.

◆ DPH_VALINFO_EXCEPTION

#define DPH_VALINFO_EXCEPTION   0x20

Definition at line 168 of file heappage.c.

◆ IS_BIASED_POINTER

#define IS_BIASED_POINTER (   ptr)    ((ULONG_PTR)(ptr) & 1)

Definition at line 178 of file heappage.c.

◆ NDEBUG

#define NDEBUG

Definition at line 19 of file heappage.c.

◆ POINTER_ADD_BIAS

#define POINTER_ADD_BIAS (   ptr)    ((ULONG_PTR)(ptr) | 1)

Definition at line 180 of file heappage.c.

◆ POINTER_REMOVE_BIAS

#define POINTER_REMOVE_BIAS (   ptr)    ((ULONG_PTR)(ptr) & ~(ULONG_PTR)1)

Definition at line 179 of file heappage.c.

Typedef Documentation

◆ DPH_BLOCK_INFORMATION

◆ DPH_HEAP_BLOCK

◆ DPH_HEAP_ROOT

◆ PDPH_BLOCK_INFORMATION

◆ PDPH_HEAP_BLOCK

◆ PDPH_HEAP_ROOT

Function Documentation

◆ RtlpDebugPageHeapValidate()

BOOLEAN NTAPI RtlpDebugPageHeapValidate ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress 
)

Definition at line 2290 of file heappage.c.

2293 {
2294  PDPH_HEAP_ROOT DphRoot;
2296  BOOLEAN Valid = FALSE;
2297 
2298  /* Get a pointer to the heap root */
2299  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2300  if (!DphRoot) return -1;
2301 
2302  /* Add heap flags */
2303  Flags |= DphRoot->HeapFlags;
2304 
2305  /* Acquire the heap lock */
2306  RtlpDphPreProcessing(DphRoot, Flags);
2307 
2308  /* Find busy memory */
2309  if (BaseAddress)
2311 
2312  if (!Node)
2313  {
2314  /* This block was not found in page heap, or the request is to validate all normal heap */
2315  Valid = RtlpDphNormalHeapValidate(DphRoot, Flags, BaseAddress);
2316  }
2317 
2318  /* Leave the heap lock */
2319  RtlpDphPostProcessing(DphRoot);
2320 
2321  /* Return result of a normal heap validation */
2322  if (BaseAddress && !Node)
2323  return Valid;
2324 
2325  /* Otherwise return our own result */
2326  if (!BaseAddress || Node) Valid = TRUE;
2327 
2328  return Valid;
2329 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
BOOLEAN NTAPI RtlpDphNormalHeapValidate(PDPH_HEAP_ROOT DphRoot, ULONG Flags, PVOID BaseAddress)
Definition: heappage.c:2333
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
ULONG HeapFlags
Definition: heappage.c:64
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlValidateHeap().

◆ RtlpDphAddNewPool()

VOID NTAPI RtlpDphAddNewPool ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  NodeBlock,
PVOID  Virtual,
SIZE_T  Size,
BOOLEAN  PlaceOnPool 
)

Definition at line 799 of file heappage.c.

800 {
801  PDPH_HEAP_BLOCK DphNode, DphStartNode;
802  ULONG NodeCount, i;
803 
804  //NodeCount = (Size >> 6) - 1;
805  NodeCount = (ULONG)(Size / sizeof(DPH_HEAP_BLOCK));
806  DphStartNode = Virtual;
807 
808  /* Set pNextAlloc for all blocks */
809  for (DphNode = Virtual, i=NodeCount-1; i > 0; i--)
810  {
811  DphNode->pNextAlloc = DphNode + 1;
812  DphNode = DphNode->pNextAlloc;
813  }
814 
815  /* and the last one */
816  DphNode->pNextAlloc = NULL;
817 
818  /* Add it to the tail of unused node list */
819  if (DphRoot->pUnusedNodeListTail)
820  DphRoot->pUnusedNodeListTail->pNextAlloc = DphStartNode;
821  else
822  DphRoot->pUnusedNodeListHead = DphStartNode;
823 
824  DphRoot->pUnusedNodeListTail = DphNode;
825 
826  /* Increase counters */
827  DphRoot->nUnusedNodes += NodeCount;
828 
829  /* Check if we need to place it on the pool list */
830  if (PlaceOnPool)
831  {
832  /* Get a node from the unused list */
833  DphNode = RtlpDphTakeNodeFromUnusedList(DphRoot);
834  ASSERT(DphNode);
835 
836  /* Set its virtual block values */
837  DphNode->pVirtualBlock = Virtual;
838  DphNode->nVirtualBlockSize = Size;
839 
840  /* Place it on the pool list */
841  RtlpDphPlaceOnPoolList(DphRoot, DphNode);
842  }
843 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
struct _DPH_HEAP_BLOCK * pNextAlloc
Definition: heappage.c:44
VOID NTAPI RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:485
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PUCHAR pVirtualBlock
Definition: heappage.c:49
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PDPH_HEAP_BLOCK pUnusedNodeListHead
Definition: heappage.c:87
PDPH_HEAP_BLOCK NTAPI RtlpDphTakeNodeFromUnusedList(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:521
unsigned int ULONG
Definition: retypes.h:1
ULONG nUnusedNodes
Definition: heappage.c:89
PDPH_HEAP_BLOCK pUnusedNodeListTail
Definition: heappage.c:88

Referenced by RtlpDphAllocateNode(), and RtlpPageHeapCreate().

◆ RtlpDphAllocateNode()

PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode ( PDPH_HEAP_ROOT  DphRoot)

Definition at line 988 of file heappage.c.

989 {
992  SIZE_T Size = DPH_POOL_SIZE, SizeVirtual;
993  PVOID Ptr = NULL;
994 
995  /* Check for the easy case */
996  if (DphRoot->pUnusedNodeListHead)
997  {
998  /* Just take a node from this list */
1000  ASSERT(Node);
1001  return Node;
1002  }
1003 
1004  /* There is a need to make free space */
1006 
1007  if (!DphRoot->pUnusedNodeListHead && !Node)
1008  {
1009  /* Retry with a smaller request */
1010  Size = PAGE_SIZE;
1012  }
1013 
1014  if (!DphRoot->pUnusedNodeListHead)
1015  {
1016  if (Node)
1017  {
1019  Ptr = Node->pVirtualBlock;
1020  SizeVirtual = Node->nVirtualBlockSize;
1021  }
1022  else
1023  {
1024  /* No free space, need to alloc a new VM block */
1025  Size = DPH_POOL_SIZE;
1026  SizeVirtual = DPH_RESERVE_SIZE;
1028 
1029  if (!NT_SUCCESS(Status))
1030  {
1031  /* Retry with a smaller size */
1032  SizeVirtual = 0x10000;
1034  if (!NT_SUCCESS(Status)) return NULL;
1035  }
1036  }
1037 
1038  /* VM is allocated at this point, set protection */
1040  if (!NT_SUCCESS(Status))
1041  {
1042  if (Node)
1043  {
1045  }
1046  else
1047  {
1048  //RtlpDphFreeVm();
1049  ASSERT(FALSE);
1050  }
1051 
1052  return NULL;
1053  }
1054 
1055  /* Zero the memory */
1056  if (Node) RtlZeroMemory(Ptr, Size);
1057 
1058  /* Add a new pool based on this VM */
1059  RtlpDphAddNewPool(DphRoot, Node, Ptr, Size, TRUE);
1060 
1061  if (Node)
1062  {
1063  if (Node->nVirtualBlockSize > Size)
1064  {
1065  Node->pVirtualBlock += Size;
1066  Node->nVirtualBlockSize -= Size;
1067 
1069  }
1070  else
1071  {
1073  }
1074  }
1075  else
1076  {
1077  /* The new VM block was just allocated a few code lines ago,
1078  so initialize it */
1080  Node->pVirtualBlock = Ptr;
1081  Node->nVirtualBlockSize = SizeVirtual;
1082  RtlpDphPlaceOnVirtualList(DphRoot, Node);
1083 
1085  Node->pVirtualBlock = (PUCHAR)Ptr + Size;
1086  Node->nVirtualBlockSize = SizeVirtual - Size;
1087  RtlpDphPlaceOnVirtualList(DphRoot, Node);
1088 
1089  /* Coalesce them into available list */
1091  }
1092  }
1093 
1094  return RtlpDphTakeNodeFromUnusedList(DphRoot);
1095 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:505
VOID NTAPI RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
Definition: heappage.c:799
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
#define DPH_RESERVE_SIZE
Definition: heappage.c:133
#define MEM_COMMIT
Definition: nt_native.h:1313
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:654
union node Node
Definition: types.h:1255
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
#define DPH_POOL_SIZE
Definition: heappage.c:134
VOID NTAPI RtlpDphReturnNodeToUnusedList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:543
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS NTAPI RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
Definition: heappage.c:316
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory(PDPH_HEAP_ROOT DphRoot, SIZE_T Size, BOOLEAN Grow)
Definition: heappage.c:878
PDPH_HEAP_BLOCK pUnusedNodeListHead
Definition: heappage.c:87
PDPH_HEAP_BLOCK NTAPI RtlpDphTakeNodeFromUnusedList(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:521
VOID NTAPI RtlpDphRemoveFromAvailableList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:559
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define PAGE_READWRITE
Definition: nt_native.h:1304
Definition: dlist.c:348

Referenced by RtlpDphGrowVirtual(), RtlpPageHeapAllocate(), and RtlpPageHeapCreate().

◆ RtlpDphAllocateNodeForTable()

PVOID NTAPI RtlpDphAllocateNodeForTable ( IN PRTL_AVL_TABLE  Table,
IN CLONG  ByteSize 
)

Definition at line 1176 of file heappage.c.

1178 {
1179  PDPH_HEAP_BLOCK pBlock;
1180  PDPH_HEAP_ROOT DphRoot;
1181 
1182  /* This mega-assert comes from a text search over Windows 2003 checked binary of ntdll.dll */
1183  ASSERT((ULONG_PTR)(((PRTL_BALANCED_LINKS)0)+1) + sizeof(PUCHAR) == ByteSize);
1184 
1185  /* Get pointer to the containing heap root record */
1186  DphRoot = CONTAINING_RECORD(Table, DPH_HEAP_ROOT, BusyNodesTable);
1187  pBlock = DphRoot->NodeToAllocate;
1188 
1189  DphRoot->NodeToAllocate = NULL;
1190  ASSERT(pBlock);
1191 
1192  return &(pBlock->TableLinks);
1193 }
ASMGENDATA Table[]
Definition: genincdata.c:61
unsigned char * PUCHAR
Definition: retypes.h:3
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
RTL_BALANCED_LINKS TableLinks
Definition: heappage.c:46
PDPH_HEAP_BLOCK NodeToAllocate
Definition: heappage.c:74
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389

Referenced by RtlpPageHeapCreate().

◆ RtlpDphAllocateVm()

NTSTATUS NTAPI RtlpDphAllocateVm ( PVOID Base,
SIZE_T  Size,
ULONG  Type,
ULONG  Protection 
)

Definition at line 316 of file heappage.c.

317 {
319  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
320  Base,
321  0,
322  &Size,
323  Type,
324  Protection);
325  DPRINT("Page heap: AllocVm (%p, %Ix, %lx) status %lx \n", Base, Size, Type, Status);
326  /* Check for failures */
327  if (!NT_SUCCESS(Status))
328  {
329  if (Type == MEM_RESERVE)
330  {
333  {
334  DPRINT1("Page heap: AllocVm (%p, %Ix, %x) failed with %x \n", Base, Size, Type, Status);
335  DbgBreakPoint();
336  return Status;
337  }
338  }
339  else
340  {
343  {
344  DPRINT1("Page heap: AllocVm (%p, %Ix, %x) failed with %x \n", Base, Size, Type, Status);
345  DbgBreakPoint();
346  return Status;
347  }
348  }
349  }
350 
351  return Status;
352 }
Type
Definition: Type.h:6
#define DPH_BREAK_ON_COMMIT_FAIL
Definition: heappage.c:139
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
void DbgBreakPoint()
Definition: mach.c:553
LONG RtlpDphAllocFails
Definition: heappage.c:128
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define MEM_RESERVE
Definition: nt_native.h:1314
#define DPH_BREAK_ON_RESERVE_FAIL
Definition: heappage.c:138
void DPRINT(...)
Definition: polytest.cpp:61
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
LONG RtlpDphCounter
Definition: heappage.c:127
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
ULONG RtlpDphBreakOptions
Definition: heappage.c:183

Referenced by RtlpDphAllocateNode(), RtlpDphGrowVirtual(), and RtlpPageHeapCreate().

◆ RtlpDphCoalesceFreeIntoAvailable()

VOID NTAPI RtlpDphCoalesceFreeIntoAvailable ( PDPH_HEAP_ROOT  DphRoot,
ULONG  LeaveOnFreeList 
)

Definition at line 768 of file heappage.c.

770 {
772  SIZE_T FreeAllocations = DphRoot->nFreeAllocations;
773 
774  /* Make sure requested size is not too big */
775  ASSERT(FreeAllocations >= LeaveOnFreeList);
776 
777  DPRINT("RtlpDphCoalesceFreeIntoAvailable(%p %lu)\n", DphRoot, LeaveOnFreeList);
778 
779  while (Node)
780  {
781  FreeAllocations--;
782  if (FreeAllocations < LeaveOnFreeList) break;
783 
784  /* Get the next pointer, because it may be changed after following two calls */
785  Next = Node->pNextAlloc;
786 
787  /* Remove it from the free list */
789 
790  /* And put into the available */
792 
793  /* Go to the next node */
794  Node = Next;
795  }
796 }
PDPH_HEAP_BLOCK pFreeAllocationListHead
Definition: heappage.c:78
VOID NTAPI RtlpDphRemoveFromFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node, PDPH_HEAP_BLOCK Prev)
Definition: heappage.c:630
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:654
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
ULONG nFreeAllocations
Definition: heappage.c:80
Definition: dlist.c:348

Referenced by RtlpDphFindAvailableMemory().

◆ RtlpDphCoalesceNodeIntoAvailable()

VOID NTAPI RtlpDphCoalesceNodeIntoAvailable ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 654 of file heappage.c.

656 {
657  PDPH_HEAP_BLOCK NodeEntry, PrevNode = NULL, NextNode;
658  PLIST_ENTRY AvailListHead;
659  PLIST_ENTRY CurEntry;
660 
661  DPRINT("RtlpDphCoalesceNodeIntoAvailable(%p %p)\n", DphRoot, Node);
662 
663  /* Update heap counters */
664  DphRoot->nAvailableAllocationBytesCommitted += Node->nVirtualBlockSize;
665  DphRoot->nAvailableAllocations++;
666 
667  /* Find where to put this node according to its virtual address */
668  AvailListHead = &DphRoot->AvailableAllocationHead;
669 
670  /* Find a point where to insert an available node */
671  CurEntry = AvailListHead->Flink;
672 
673  while (CurEntry != AvailListHead)
674  {
675  NodeEntry = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
676  if (NodeEntry->pVirtualBlock >= Node->pVirtualBlock)
677  {
678  PrevNode = NodeEntry;
679  break;
680  }
681  CurEntry = CurEntry->Flink;
682  }
683 
684  if (!PrevNode)
685  {
686  /* That means either this list is empty, or we should add to the head of it */
687  InsertHeadList(AvailListHead, &Node->AvailableEntry);
688  }
689  else
690  {
691  /* Check the previous node and merge if possible */
692  if (PrevNode->pVirtualBlock + PrevNode->nVirtualBlockSize == Node->pVirtualBlock)
693  {
694  /* Check they actually belong to the same virtual memory block */
696  MEMORY_BASIC_INFORMATION MemoryBasicInfo;
697 
700  Node->pVirtualBlock,
702  &MemoryBasicInfo,
703  sizeof(MemoryBasicInfo),
704  NULL);
705 
706  /* There is no way this can fail, we committed this memory! */
708 
709  if ((PUCHAR)MemoryBasicInfo.AllocationBase <= PrevNode->pVirtualBlock)
710  {
711  /* They are adjacent, and from the same VM region. - merge! */
712  PrevNode->nVirtualBlockSize += Node->nVirtualBlockSize;
714  DphRoot->nAvailableAllocations--;
715 
716  Node = PrevNode;
717  }
718  else
719  {
720  /* Insert after PrevNode */
721  InsertTailList(&PrevNode->AvailableEntry, &Node->AvailableEntry);
722  }
723  }
724  else
725  {
726  /* Insert after PrevNode */
727  InsertTailList(&PrevNode->AvailableEntry, &Node->AvailableEntry);
728  }
729 
730  /* Now check the next entry after our one */
731  if (Node->AvailableEntry.Flink != AvailListHead)
732  {
733  NextNode = CONTAINING_RECORD(Node->AvailableEntry.Flink, DPH_HEAP_BLOCK, AvailableEntry);
734  /* Node is not at the tail of the list, check if it's adjacent */
735  if (Node->pVirtualBlock + Node->nVirtualBlockSize == NextNode->pVirtualBlock)
736  {
737  /* Check they actually belong to the same virtual memory block */
739  MEMORY_BASIC_INFORMATION MemoryBasicInfo;
740 
743  NextNode->pVirtualBlock,
745  &MemoryBasicInfo,
746  sizeof(MemoryBasicInfo),
747  NULL);
748 
749  /* There is no way this can fail, we committed this memory! */
751 
752  if ((PUCHAR)MemoryBasicInfo.AllocationBase <= Node->pVirtualBlock)
753  {
754  /* They are adjacent - merge! */
755  Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
756 
757  /* Remove next entry from the list and put it into unused entries list */
758  RemoveEntryList(&NextNode->AvailableEntry);
759  RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
760  DphRoot->nAvailableAllocations--;
761  }
762  }
763  }
764  }
765 }
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:83
#define ZwCurrentProcess()
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define InsertTailList(ListHead, Entry)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSYSAPI NTSTATUS NTAPI ZwQueryVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID Address, _In_ MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass, _Out_ PVOID VirtualMemoryInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
VOID NTAPI RtlpDphReturnNodeToUnusedList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:543
LIST_ENTRY AvailableEntry
Definition: heappage.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PUCHAR pVirtualBlock
Definition: heappage.c:49
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
ULONG nAvailableAllocations
Definition: heappage.c:84
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:85
Definition: dlist.c:348

Referenced by RtlpDphAllocateNode(), RtlpDphCoalesceFreeIntoAvailable(), RtlpDphGrowVirtual(), and RtlpPageHeapCreate().

◆ RtlpDphCompareNodeForTable()

RTL_GENERIC_COMPARE_RESULTS NTAPI RtlpDphCompareNodeForTable ( IN PRTL_AVL_TABLE  Table,
IN PVOID  FirstStruct,
IN PVOID  SecondStruct 
)

Definition at line 1157 of file heappage.c.

1160 {
1161  ULONG_PTR FirstBlock, SecondBlock;
1162 
1163  FirstBlock = *((ULONG_PTR *)FirstStruct);
1164  SecondBlock = *((ULONG_PTR *)SecondStruct);
1165 
1166  if (FirstBlock < SecondBlock)
1167  return GenericLessThan;
1168  else if (FirstBlock > SecondBlock)
1169  return GenericGreaterThan;
1170 
1171  return GenericEqual;
1172 }
uint32_t ULONG_PTR
Definition: typedefs.h:63
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:379
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:379

Referenced by RtlpPageHeapCreate().

◆ RtlpDphEnterCriticalSection()

VOID NTAPI RtlpDphEnterCriticalSection ( PDPH_HEAP_ROOT  DphRoot,
ULONG  Flags 
)

Definition at line 235 of file heappage.c.

236 {
237  if (Flags & HEAP_NO_SERIALIZE)
238  {
239  /* More complex scenario */
240  if (!RtlTryEnterHeapLock(DphRoot->HeapCritSect, TRUE))
241  {
242  if (!DphRoot->nRemoteLockAcquired)
243  {
244  DPRINT1("multithreaded access in HEAP_NO_SERIALIZE heap\n");
245  DbgBreakPoint();
246 
247  /* Clear out the no serialize flag */
248  DphRoot->HeapFlags &= ~HEAP_NO_SERIALIZE;
249  }
250 
251  /* Enter the heap's critical section */
253  }
254  }
255  else
256  {
257  /* Just enter the heap's critical section */
259  }
260 }
#define TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
void DbgBreakPoint()
Definition: mach.c:553
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
ULONG nRemoteLockAcquired
Definition: heappage.c:66
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG HeapFlags
Definition: heappage.c:64
BOOLEAN NTAPI RtlTryEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:117
#define DPRINT1
Definition: precomp.h:8

Referenced by RtlpDphPreProcessing(), and RtlpPageHeapLock().

◆ RtlpDphFindAvailableMemory()

PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory ( PDPH_HEAP_ROOT  DphRoot,
SIZE_T  Size,
BOOLEAN  Grow 
)

Definition at line 878 of file heappage.c.

881 {
883  ULONG NewSize;
884 
885  /* Find an available best fitting node */
887 
888  /* If that didn't work, try to search a smaller one in the loop */
889  while (!Node)
890  {
891  /* Break if the free list becomes too small */
892  if (DphRoot->nFreeAllocations <= DPH_FREE_LIST_MINIMUM) break;
893 
894  /* Calculate a new free list size */
895  NewSize = DphRoot->nFreeAllocations >> 2;
897 
898  /* Coalesce free into available */
900 
901  /* Try to find an available best fitting node again */
903  }
904 
905  /* If Node is NULL, then we could fix the situation only by
906  growing the available VM size */
907  if (!Node && Grow)
908  {
909  /* Grow VM size, if it fails - return failure directly */
910  if (!RtlpDphGrowVirtual(DphRoot, Size)) return NULL;
911 
912  /* Try to find an available best fitting node again */
914 
915  if (!Node)
916  {
917  /* Do the last attempt: coalesce all free into available (if Size fits there) */
919  {
920  /* Coalesce free into available */
922 
923  /* Try to find an available best fitting node again */
925  }
926  }
927  }
928 
929  /* Return node we found */
930  return Node;
931 }
PDPH_HEAP_BLOCK NTAPI RtlpDphSearchAvailableMemoryListForBestFit(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:846
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
SIZE_T nFreeAllocationBytesCommitted
Definition: heappage.c:81
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI RtlpDphCoalesceFreeIntoAvailable(PDPH_HEAP_ROOT DphRoot, ULONG LeaveOnFreeList)
Definition: heappage.c:768
#define DPH_FREE_LIST_MINIMUM
Definition: heappage.c:135
ULONG nFreeAllocations
Definition: heappage.c:80
BOOLEAN NTAPI RtlpDphGrowVirtual(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1098
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:85
Definition: dlist.c:348

Referenced by RtlpDphAllocateNode(), and RtlpPageHeapAllocate().

◆ RtlpDphFindBusyMemory()

PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory ( PDPH_HEAP_ROOT  DphRoot,
PVOID  pUserMem 
)

Definition at line 934 of file heappage.c.

936 {
938  PVOID Ptr;
939 
940  /* Lookup busy block in AVL */
941  Ptr = RtlLookupElementGenericTableAvl(&DphRoot->BusyNodesTable, &pUserMem);
942  if (!Ptr) return NULL;
943 
944  /* Restore pointer to the heap block */
945  Node = CONTAINING_RECORD(Ptr, DPH_HEAP_BLOCK, pUserAllocation);
946  ASSERT(Node->pUserAllocation == pUserMem);
947  return Node;
948 }
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
Definition: dlist.c:348

Referenced by RtlpDebugPageHeapValidate(), RtlpPageHeapFree(), RtlpPageHeapGetUserInfo(), RtlpPageHeapReAllocate(), RtlpPageHeapSetUserFlags(), RtlpPageHeapSetUserValue(), and RtlpPageHeapSize().

◆ RtlpDphFreeDelayedBlocksFromHeap()

VOID NTAPI RtlpDphFreeDelayedBlocksFromHeap ( PDPH_HEAP_ROOT  DphRoot,
PHEAP  NormalHeap 
)

Definition at line 1228 of file heappage.c.

1230 {
1231  PLIST_ENTRY Current, Next;
1232  PDPH_BLOCK_INFORMATION BlockInfo;
1233  ULONG ValidationInfo;
1234 
1235  /* The original routine seems to use a temporary SList to put blocks to be freed,
1236  then it releases the lock and frees the blocks. But let's make it simple for now */
1237 
1238  /* Acquire the delayed free queue lock */
1240 
1241  /* Traverse the list */
1242  Current = RtlpDphDelayedFreeQueue.Flink;
1243  while (Current != &RtlpDphDelayedFreeQueue)
1244  {
1245  /* Get the next entry pointer */
1246  Next = Current->Flink;
1247 
1248  BlockInfo = CONTAINING_RECORD(Current, DPH_BLOCK_INFORMATION, FreeQueue);
1249 
1250  /* Check if it belongs to the same heap */
1251  if (BlockInfo->Heap == DphRoot)
1252  {
1253  /* Remove it from the list */
1254  RemoveEntryList(Current);
1255 
1256  /* Reset its heap to NULL */
1257  BlockInfo->Heap = NULL;
1258 
1259  if (!RtlpDphIsNormalFreeHeapBlock(BlockInfo + 1, &ValidationInfo, TRUE))
1260  {
1261  RtlpDphReportCorruptedBlock(DphRoot, 10, BlockInfo + 1, ValidationInfo);
1262  }
1263 
1264  /* Decrement counters */
1267 
1268  /* Free the normal heap */
1269  RtlFreeHeap(NormalHeap, 0, BlockInfo);
1270  }
1271 
1272  /* Move to the next one */
1273  Current = Next;
1274  }
1275 
1276  /* Release the delayed free queue lock */
1278 }
BOOLEAN NTAPI RtlpDphIsNormalFreeHeapBlock(PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1419
#define TRUE
Definition: types.h:120
SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks
Definition: heappage.c:123
PHEAP_LOCK RtlpDphDelayedFreeQueueLock
Definition: heappage.c:120
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG RtlpDphNumberOfDelayedFreeBlocks
Definition: heappage.c:124
LIST_ENTRY RtlpDphDelayedFreeQueue
Definition: heappage.c:121
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
Definition: typedefs.h:117
unsigned int ULONG
Definition: retypes.h:1

Referenced by RtlpPageHeapDestroy().

◆ RtlpDphFreeNodeForTable()

VOID NTAPI RtlpDphFreeNodeForTable ( IN PRTL_AVL_TABLE  Table,
IN PVOID  Buffer 
)

Definition at line 1197 of file heappage.c.

1199 {
1200  /* Nothing */
1201 }

Referenced by RtlpPageHeapCreate().

◆ RtlpDphFreeVm()

NTSTATUS NTAPI RtlpDphFreeVm ( PVOID  Base,
SIZE_T  Size,
ULONG  Type 
)

Definition at line 355 of file heappage.c.

356 {
358 
359  /* Free the memory */
361  DPRINT("Page heap: FreeVm (%p, %Ix, %x) status %x \n", Base, Size, Type, Status);
362  /* Log/report failures */
363  if (!NT_SUCCESS(Status))
364  {
365  if (Type == MEM_RELEASE)
366  {
369  {
370  DPRINT1("Page heap: FreeVm (%p, %Ix, %x) failed with %x \n", Base, Size, Type, Status);
371  DbgBreakPoint();
372  return Status;
373  }
374  }
375  else
376  {
379  {
380  DPRINT1("Page heap: FreeVm (%p, %Ix, %x) failed with %x \n", Base, Size, Type, Status);
381  DbgBreakPoint();
382  return Status;
383  }
384  }
385  }
386 
387  return Status;
388 }
#define DPH_BREAK_ON_FREE_FAIL
Definition: heappage.c:141
LONG RtlpDphFreeFails
Definition: heappage.c:130
Type
Definition: Type.h:6
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define DPH_BREAK_ON_RELEASE_FAIL
Definition: heappage.c:140
void DbgBreakPoint()
Definition: mach.c:553
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
void DPRINT(...)
Definition: polytest.cpp:61
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI RtlpSecMemFreeVirtualMemory(HANDLE Process, PVOID *Base, PSIZE_T Size, ULONG Type)
Definition: heappage.c:293
ULONG RtlpDphBreakOptions
Definition: heappage.c:183
#define MEM_RELEASE
Definition: nt_native.h:1316
LONG RtlpDphReleaseFails
Definition: heappage.c:129

Referenced by RtlpPageHeapDestroy().

◆ RtlpDphGrowVirtual()

BOOLEAN NTAPI RtlpDphGrowVirtual ( PDPH_HEAP_ROOT  DphRoot,
SIZE_T  Size 
)

Definition at line 1098 of file heappage.c.

1100 {
1101  PDPH_HEAP_BLOCK Node, AvailableNode;
1102  PVOID Base = NULL;
1103  SIZE_T VirtualSize;
1104  NTSTATUS Status;
1105 
1106  /* Start with allocating a couple of nodes */
1107  Node = RtlpDphAllocateNode(DphRoot);
1108  if (!Node) return FALSE;
1109 
1110  AvailableNode = RtlpDphAllocateNode(DphRoot);
1111  if (!AvailableNode)
1112  {
1113  /* Free the allocated node and return failure */
1115  return FALSE;
1116  }
1117 
1118  /* Calculate size of VM to allocate by rounding it up */
1119  Size = ROUND_UP(Size, 0xFFFF);
1120  VirtualSize = Size;
1121  if (Size < DPH_RESERVE_SIZE)
1122  VirtualSize = DPH_RESERVE_SIZE;
1123 
1124  /* Allocate the virtual memory */
1125  // FIXME: Shouldn't it be MEM_RESERVE with later committing?
1127  if (!NT_SUCCESS(Status))
1128  {
1129  /* Retry again with a smaller size */
1130  VirtualSize = Size;
1132  if (!NT_SUCCESS(Status))
1133  {
1134  /* Free the allocated node and return failure */
1136  RtlpDphReturnNodeToUnusedList(DphRoot, AvailableNode);
1137  return FALSE;
1138  }
1139  }
1140 
1141  /* Set up our two nodes describing this VM */
1142  Node->pVirtualBlock = Base;
1143  Node->nVirtualBlockSize = VirtualSize;
1144  AvailableNode->pVirtualBlock = Base;
1145  AvailableNode->nVirtualBlockSize = VirtualSize;
1146 
1147  /* Add them to virtual and available lists respectively */
1148  RtlpDphPlaceOnVirtualList(DphRoot, Node);
1149  RtlpDphCoalesceNodeIntoAvailable(DphRoot, AvailableNode);
1150 
1151  /* Return success */
1152  return TRUE;
1153 }
#define TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
VOID NTAPI RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:505
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define DPH_RESERVE_SIZE
Definition: heappage.c:133
#define MEM_COMMIT
Definition: nt_native.h:1313
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:654
union node Node
Definition: types.h:1255
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
VOID NTAPI RtlpDphReturnNodeToUnusedList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:543
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PUCHAR pVirtualBlock
Definition: heappage.c:49
NTSTATUS NTAPI RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
Definition: heappage.c:316
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
Definition: dlist.c:348

Referenced by RtlpDphFindAvailableMemory().

◆ RtlpDphInitializeDelayedFreeQueue()

NTSTATUS NTAPI RtlpDphInitializeDelayedFreeQueue ( VOID  )

Definition at line 1204 of file heappage.c.

1205 {
1206  NTSTATUS Status;
1207 
1209  if (!NT_SUCCESS(Status))
1210  {
1211  // TODO: Log this error!
1212  DPRINT1("Failure initializing delayed free queue critical section\n");
1213  return Status;
1214  }
1215 
1216  /* Initialize lists */
1219 
1220  /* Reset counters */
1223 
1224  return Status;
1225 }
SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks
Definition: heappage.c:123
SLIST_HEADER RtlpDphDelayedTemporaryPushList
Definition: heappage.c:122
PHEAP_LOCK RtlpDphDelayedFreeQueueLock
Definition: heappage.c:120
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG RtlpDphNumberOfDelayedFreeBlocks
Definition: heappage.c:124
LIST_ENTRY RtlpDphDelayedFreeQueue
Definition: heappage.c:121
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
Definition: libsupp.c:126
Status
Definition: gdiplustypes.h:24
NTSYSAPI VOID NTAPI RtlInitializeSListHead(_Out_ PSLIST_HEADER ListHead)
Definition: slist.c:25
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8

Referenced by RtlpDphProcessStartupInitialization().

◆ RtlpDphInternalValidatePageHeap()

VOID NTAPI RtlpDphInternalValidatePageHeap ( PDPH_HEAP_ROOT  DphRoot,
PVOID  Address,
ULONG  Value 
)

Definition at line 1288 of file heappage.c.

1289 {
1290  UNIMPLEMENTED;
1291 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by RtlpPageHeapAllocate(), RtlpPageHeapCreate(), RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphIsNormalFreeHeapBlock()

BOOLEAN NTAPI RtlpDphIsNormalFreeHeapBlock ( PVOID  Block,
PULONG  ValidationInformation,
BOOLEAN  CheckFillers 
)

Definition at line 1419 of file heappage.c.

1422 {
1423  ASSERT(ValidationInformation != NULL);
1424 
1425  UNIMPLEMENTED;
1426  *ValidationInformation = 0;
1427  return TRUE;
1428 }
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by RtlpDphFreeDelayedBlocksFromHeap().

◆ RtlpDphIsPageHeapBlock()

BOOLEAN NTAPI RtlpDphIsPageHeapBlock ( PDPH_HEAP_ROOT  DphRoot,
PVOID  Block,
PULONG  ValidationInformation,
BOOLEAN  CheckFillers 
)

Definition at line 1356 of file heappage.c.

1360 {
1361  PDPH_BLOCK_INFORMATION BlockInfo;
1362  BOOLEAN SomethingWrong = FALSE;
1363  PUCHAR Byte, Start, End;
1364 
1365  ASSERT(ValidationInformation != NULL);
1366  *ValidationInformation = 0;
1367 
1368  // _SEH2_TRY {
1369  BlockInfo = (PDPH_BLOCK_INFORMATION)Block - 1;
1370 
1371  /* Check stamps */
1372  if (BlockInfo->StartStamp != DPH_FILL_START_STAMP_1)
1373  {
1374  *ValidationInformation |= DPH_VALINFO_BAD_START_STAMP;
1375  SomethingWrong = TRUE;
1376 
1377  /* Check if it has an alloc/free mismatch */
1378  if (BlockInfo->StartStamp == DPH_FILL_START_STAMP_2)
1379  {
1380  /* Notify respectively */
1381  *ValidationInformation = 0x101;
1382  }
1383  }
1384 
1385  if (BlockInfo->EndStamp != DPH_FILL_END_STAMP_1)
1386  {
1387  *ValidationInformation |= DPH_VALINFO_BAD_END_STAMP;
1388  SomethingWrong = TRUE;
1389  }
1390 
1391  /* Check root heap pointer */
1392  if (BlockInfo->Heap != DphRoot)
1393  {
1394  *ValidationInformation |= DPH_VALINFO_BAD_POINTER;
1395  SomethingWrong = TRUE;
1396  }
1397 
1398  /* Check other fillers if requested */
1399  if (CheckFillers)
1400  {
1401  /* Check space after the block */
1402  Start = (PUCHAR)Block + BlockInfo->RequestedSize;
1403  End = (PUCHAR)ROUND_UP(Start, PAGE_SIZE);
1404  for (Byte = Start; Byte < End; Byte++)
1405  {
1406  if (*Byte != DPH_FILL_SUFFIX)
1407  {
1408  *ValidationInformation |= DPH_VALINFO_BAD_SUFFIX_PATTERN;
1409  SomethingWrong = TRUE;
1410  break;
1411  }
1412  }
1413  }
1414 
1415  return (SomethingWrong == FALSE);
1416 }
#define TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
unsigned char Byte
Definition: zconf.h:391
unsigned char * PUCHAR
Definition: retypes.h:3
#define DPH_VALINFO_BAD_END_STAMP
Definition: heappage.c:164
#define DPH_FILL_START_STAMP_1
Definition: heappage.c:155
#define DPH_VALINFO_BAD_SUFFIX_PATTERN
Definition: heappage.c:167
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define DPH_FILL_END_STAMP_1
Definition: heappage.c:157
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
#define DPH_FILL_START_STAMP_2
Definition: heappage.c:156
Definition: partlist.h:33
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define DPH_VALINFO_BAD_POINTER
Definition: heappage.c:165
#define DPH_FILL_SUFFIX
Definition: heappage.c:159
#define DPH_VALINFO_BAD_START_STAMP
Definition: heappage.c:163

Referenced by RtlpPageHeapDestroy(), RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphLeaveCriticalSection()

VOID NTAPI RtlpDphLeaveCriticalSection ( PDPH_HEAP_ROOT  DphRoot)

Definition at line 263 of file heappage.c.

264 {
265  /* Just leave the heap's critical section */
266  RtlLeaveHeapLock(DphRoot->HeapCritSect);
267 }
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133

Referenced by RtlpDphPostProcessing(), and RtlpPageHeapUnlock().

◆ RtlpDphNormalHeapValidate()

BOOLEAN NTAPI RtlpDphNormalHeapValidate ( PDPH_HEAP_ROOT  DphRoot,
ULONG  Flags,
PVOID  BaseAddress 
)

Definition at line 2333 of file heappage.c.

2336 {
2338  if (!BaseAddress)
2339  {
2340  /* Validate all normal heap */
2341  return RtlValidateHeap(DphRoot->NormalHeap, Flags, NULL);
2342  }
2343 
2344  // FIXME: Check is this a normal heap block
2345  /*if (!RtlpDphIsNormalHeapBlock(DphRoot, BaseAddress, &ValidationInfo))
2346  {
2347  }*/
2348 
2349  return RtlValidateHeap(DphRoot->NormalHeap, Flags, BlockInfo);
2350 }
PVOID NormalHeap
Definition: heappage.c:99
NTSYSAPI BOOLEAN WINAPI RtlValidateHeap(HANDLE, ULONG, LPCVOID)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404

Referenced by RtlpDebugPageHeapValidate().

◆ RtlpDphPlaceOnBusyList()

VOID NTAPI RtlpDphPlaceOnBusyList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  DphNode 
)

Definition at line 441 of file heappage.c.

442 {
443  BOOLEAN NewElement;
444  PVOID AddressUserData;
445 
446  DPRINT("RtlpDphPlaceOnBusyList(%p %p)\n", DphRoot, DphNode);
447 
448  /* Add it to the AVL busy nodes table */
449  DphRoot->NodeToAllocate = DphNode;
450  AddressUserData = RtlInsertElementGenericTableAvl(&DphRoot->BusyNodesTable,
451  &DphNode->pUserAllocation,
452  sizeof(ULONG_PTR),
453  &NewElement);
454 
455  ASSERT(AddressUserData == &DphNode->pUserAllocation);
456  ASSERT(NewElement == TRUE);
457 
458  /* Update heap counters */
459  DphRoot->nBusyAllocations++;
462 }
#define TRUE
Definition: types.h:120
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
unsigned char BOOLEAN
SIZE_T nVirtualAccessSize
Definition: heappage.c:51
void DPRINT(...)
Definition: polytest.cpp:61
PUCHAR pUserAllocation
Definition: heappage.c:48
PDPH_HEAP_BLOCK NodeToAllocate
Definition: heappage.c:74
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
SIZE_T nBusyAllocationBytesAccessible
Definition: heappage.c:90
SIZE_T nBusyAllocationBytesCommitted
Definition: heappage.c:76
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
ULONG nBusyAllocations
Definition: heappage.c:75

Referenced by RtlpPageHeapAllocate(), and RtlpPageHeapReAllocate().

◆ RtlpDphPlaceOnFreeList()

VOID NTAPI RtlpDphPlaceOnFreeList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 465 of file heappage.c.

466 {
467  DPRINT("RtlpDphPlaceOnFreeList(%p %p)\n", DphRoot, Node);
468 
469  /* Node is being added to the tail of the list */
470  Node->pNextAlloc = NULL;
471 
472  /* Add it to the tail of the linked list */
473  if (DphRoot->pFreeAllocationListTail)
475  else
476  DphRoot->pFreeAllocationListHead = Node;
477  DphRoot->pFreeAllocationListTail = Node;
478 
479  /* Update byte counts taking in account this new node */
480  DphRoot->nFreeAllocations++;
481  DphRoot->nFreeAllocationBytesCommitted += Node->nVirtualBlockSize;
482 }
PDPH_HEAP_BLOCK pFreeAllocationListHead
Definition: heappage.c:78
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
PDPH_HEAP_BLOCK pFreeAllocationListTail
Definition: heappage.c:79
void DPRINT(...)
Definition: polytest.cpp:61
struct _DPH_HEAP_BLOCK * pNextAlloc
Definition: heappage.c:44
SIZE_T nFreeAllocationBytesCommitted
Definition: heappage.c:81
ULONG nFreeAllocations
Definition: heappage.c:80
Definition: dlist.c:348

Referenced by RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphPlaceOnPoolList()

VOID NTAPI RtlpDphPlaceOnPoolList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 485 of file heappage.c.

486 {
487  DPRINT("RtlpDphPlaceOnPoolList(%p %p)\n", DphRoot, Node);
488 
489  /* Node is being added to the tail of the list */
490  Node->pNextAlloc = NULL;
491 
492  /* Add it to the tail of the linked list */
493  if (DphRoot->pNodePoolListTail)
494  DphRoot->pNodePoolListTail->pNextAlloc = Node;
495  else
496  DphRoot->pNodePoolListHead = Node;
497  DphRoot->pNodePoolListTail = Node;
498 
499  /* Update byte counts taking in account this new node */
500  DphRoot->nNodePools++;
501  DphRoot->nNodePoolBytes += Node->nVirtualBlockSize;
502 }
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _DPH_HEAP_BLOCK * pNextAlloc
Definition: heappage.c:44
ULONG nNodePools
Definition: heappage.c:93
PDPH_HEAP_BLOCK pNodePoolListTail
Definition: heappage.c:92
SIZE_T nNodePoolBytes
Definition: heappage.c:94
Definition: dlist.c:348
PDPH_HEAP_BLOCK pNodePoolListHead
Definition: heappage.c:91

Referenced by RtlpDphAddNewPool(), and RtlpPageHeapCreate().

◆ RtlpDphPlaceOnVirtualList()

VOID NTAPI RtlpDphPlaceOnVirtualList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 505 of file heappage.c.

506 {
507  DPRINT("RtlpDphPlaceOnVirtualList(%p %p)\n", DphRoot, Node);
508 
509  /* Add it to the head of the virtual list */
510  Node->pNextAlloc = DphRoot->pVirtualStorageListHead;
511  if (!DphRoot->pVirtualStorageListHead)
512  DphRoot->pVirtualStorageListTail = Node;
513  DphRoot->pVirtualStorageListHead = Node;
514 
515  /* Update byte counts taking in account this new node */
516  DphRoot->nVirtualStorageRanges++;
517  DphRoot->nVirtualStorageBytes += Node->nVirtualBlockSize;
518 }
PDPH_HEAP_BLOCK pVirtualStorageListTail
Definition: heappage.c:69
PDPH_HEAP_BLOCK pVirtualStorageListHead
Definition: heappage.c:68
union node Node
Definition: types.h:1255
void DPRINT(...)
Definition: polytest.cpp:61
SIZE_T nVirtualStorageBytes
Definition: heappage.c:71
ULONG nVirtualStorageRanges
Definition: heappage.c:70
Definition: dlist.c:348

Referenced by RtlpDphAllocateNode(), RtlpDphGrowVirtual(), and RtlpPageHeapCreate().

◆ RtlpDphPointerFromHandle()

PVOID NTAPI RtlpDphPointerFromHandle ( PVOID  Handle)

Definition at line 218 of file heappage.c.

219 {
220  PHEAP NormalHeap = (PHEAP)Handle;
222 
223  if (NormalHeap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
224  {
225  if (DphHeap->Signature == DPH_SIGNATURE)
226  return DphHeap;
227  }
228 
229  DPRINT1("heap handle with incorrect signature\n");
230  DbgBreakPoint();
231  return NULL;
232 }
struct _DPH_HEAP_ROOT * PDPH_HEAP_ROOT
unsigned char * PUCHAR
Definition: retypes.h:3
void DbgBreakPoint()
Definition: mach.c:553
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
ULONG Signature
Definition: heappage.c:63
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
#define DPH_SIGNATURE
Definition: heappage.c:175
Definition: heap.c:51

Referenced by RtlpDebugPageHeapValidate(), RtlpPageHeapAllocate(), RtlpPageHeapDestroy(), RtlpPageHeapFree(), RtlpPageHeapGetUserInfo(), RtlpPageHeapLock(), RtlpPageHeapReAllocate(), RtlpPageHeapSetUserFlags(), RtlpPageHeapSetUserValue(), RtlpPageHeapSize(), and RtlpPageHeapUnlock().

◆ RtlpDphPostProcessing()

VOID NTAPI RtlpDphPostProcessing ( PDPH_HEAP_ROOT  DphRoot)

Definition at line 279 of file heappage.c.

280 {
281  if (!DphRoot) return;
282 
284  {
285  /* FIXME: Validate integrity, internal lists if necessary */
286  }
287 
288  /* Release the lock */
290 }
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
VOID NTAPI RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:263
ULONG RtlpDphDebugOptions
Definition: heappage.c:184

Referenced by RtlpDebugPageHeapValidate(), RtlpPageHeapAllocate(), RtlpPageHeapFree(), RtlpPageHeapGetUserInfo(), RtlpPageHeapReAllocate(), RtlpPageHeapSetUserFlags(), RtlpPageHeapSetUserValue(), and RtlpPageHeapSize().

◆ RtlpDphPreProcessing()

VOID NTAPI RtlpDphPreProcessing ( PDPH_HEAP_ROOT  DphRoot,
ULONG  Flags 
)

Definition at line 271 of file heappage.c.

272 {
274 
275  /* FIXME: Validate integrity, internal lists if necessary */
276 }
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
VOID NTAPI RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:235

Referenced by RtlpDebugPageHeapValidate(), RtlpPageHeapAllocate(), RtlpPageHeapDestroy(), RtlpPageHeapFree(), RtlpPageHeapGetUserInfo(), RtlpPageHeapReAllocate(), RtlpPageHeapSetUserFlags(), RtlpPageHeapSetUserValue(), and RtlpPageHeapSize().

◆ RtlpDphProcessStartupInitialization()

NTSTATUS NTAPI RtlpDphProcessStartupInitialization ( VOID  )

Definition at line 1431 of file heappage.c.

1432 {
1433  NTSTATUS Status;
1434  PTEB Teb = NtCurrentTeb();
1435 
1436  /* Initialize the DPH heap list and its critical section */
1439  if (!NT_SUCCESS(Status))
1440  {
1441  ASSERT(FALSE);
1442  return Status;
1443  }
1444 
1445  /* Initialize delayed-free queue */
1447  if (!NT_SUCCESS(Status)) return Status;
1448 
1449  /* Initialize the target dlls string */
1452 
1453  /* Per-process DPH init is done */
1455 
1456  DPRINT1("Page heap: pid 0x%p: page heap enabled with flags 0x%X.\n",
1458 
1459  return Status;
1460 }
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
#define TRUE
Definition: types.h:120
WCHAR RtlpDphTargetDlls[512]
Definition: heappage.c:110
LONG NTSTATUS
Definition: precomp.h:26
HANDLE UniqueProcess
Definition: compat.h:482
ULONG RtlpDphGlobalFlags
Definition: heappage.c:107
LIST_ENTRY RtlpDphPageHeapList
Definition: heappage.c:112
CLIENT_ID ClientId
Definition: compat.h:496
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
Definition: libsupp.c:126
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
Definition: compat.h:492
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
UNICODE_STRING RtlpDphTargetDllsUnicode
Definition: heappage.c:117
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8
BOOLEAN RtlpDphPageHeapListInitialized
Definition: heappage.c:113
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI RtlpDphTargetDllsLogicInitialize(VOID)
Definition: heappage.c:1281
NTSTATUS NTAPI RtlpDphInitializeDelayedFreeQueue(VOID)
Definition: heappage.c:1204

Referenced by RtlpPageHeapCreate().

◆ RtlpDphProtectVm()

NTSTATUS NTAPI RtlpDphProtectVm ( PVOID  Base,
SIZE_T  Size,
ULONG  Protection 
)

Definition at line 391 of file heappage.c.

392 {
394  ULONG OldProtection;
395 
396  /* Change protection */
397  Status = ZwProtectVirtualMemory(NtCurrentProcess(), &Base, &Size, Protection, &OldProtection);
398 
399  /* Log/report failures */
400  if (!NT_SUCCESS(Status))
401  {
404  {
405  DPRINT1("Page heap: ProtectVm (%p, %Ix, %x) failed with %x \n", Base, Size, Protection, Status);
406  DbgBreakPoint();
407  return Status;
408  }
409  }
410 
411  return Status;
412 }
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
void DbgBreakPoint()
Definition: mach.c:553
#define DPH_BREAK_ON_PROTECT_FAIL
Definition: heappage.c:142
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
ULONG RtlpDphBreakOptions
Definition: heappage.c:183
unsigned int ULONG
Definition: retypes.h:1
LONG RtlpDphProtectFails
Definition: heappage.c:131
NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID *BaseAddress, _In_ SIZE_T *NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)

Referenced by RtlpDphAllocateNode(), RtlpDphSetProtectionBeforeUse(), RtlpPageHeapCreate(), RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphRaiseException()

VOID NTAPI RtlpDphRaiseException ( NTSTATUS  Status)

Definition at line 202 of file heappage.c.

203 {
204  EXCEPTION_RECORD Exception;
205 
206  /* Initialize exception record */
207  Exception.ExceptionCode = Status;
209  Exception.ExceptionFlags = 0;
210  Exception.ExceptionRecord = NULL;
211  Exception.NumberParameters = 0;
212 
213  /* Raise the exception */
214  RtlRaiseException(&Exception);
215 }
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
PVOID ExceptionAddress
Definition: compat.h:199
DWORD ExceptionCode
Definition: compat.h:196
smooth NULL
Definition: ftsmooth.c:416
Status
Definition: gdiplustypes.h:24
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:202
DWORD ExceptionFlags
Definition: compat.h:197
DWORD NumberParameters
Definition: compat.h:200

Referenced by RtlpPageHeapAllocate(), and RtlpPageHeapReAllocate().

◆ RtlpDphRemoveFromAvailableList()

VOID NTAPI RtlpDphRemoveFromAvailableList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 559 of file heappage.c.

561 {
562  /* Make sure Adjacency list pointers are biased */
563  //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Flink));
564  //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Blink));
565 
566  DPRINT("RtlpDphRemoveFromAvailableList(%p %p)\n", DphRoot, Node);
567 
568  /* Check if it is in the list */
569 #if 0
570  {
571  PLIST_ENTRY CurEntry;
572  PDPH_HEAP_BLOCK NodeEntry;
573  BOOLEAN Found = FALSE;
574 
575  /* Find where to put this node according to its virtual address */
576  CurEntry = DphRoot->AvailableAllocationHead.Flink;
577 
578  while (CurEntry != &DphRoot->AvailableAllocationHead)
579  {
580  NodeEntry = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
581 
582  if (NodeEntry == Node)
583  {
584  Found = TRUE;
585  break;
586  }
587 
588  CurEntry = CurEntry->Flink;
589  }
590 
591  if (!Found)
592  {
593  DPRINT1("Trying to remove non-existing in availlist node!\n");
594  DbgBreakPoint();
595  }
596  }
597 #endif
598 
599  /* Remove it from the list */
600  RemoveEntryList(&Node->AvailableEntry);
601 
602  /* Decrease heap counters */
603  DphRoot->nAvailableAllocations--;
604  DphRoot->nAvailableAllocationBytesCommitted -= Node->nVirtualBlockSize;
605 
606  /* Remove bias from the AdjacencyEntry pointer */
607  Node->AdjacencyEntry.Flink = (PLIST_ENTRY)POINTER_REMOVE_BIAS(Node->AdjacencyEntry.Flink);
608  Node->AdjacencyEntry.Blink = (PLIST_ENTRY)POINTER_REMOVE_BIAS(Node->AdjacencyEntry.Blink);
609 }
struct _LIST_ENTRY * PLIST_ENTRY
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:83
#define TRUE
Definition: types.h:120
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
void DbgBreakPoint()
Definition: mach.c:553
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
return Found
Definition: dirsup.c:1270
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
#define DPRINT1
Definition: precomp.h:8
ULONG nAvailableAllocations
Definition: heappage.c:84
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:85
Definition: dlist.c:348

Referenced by RtlpDphAllocateNode(), and RtlpPageHeapAllocate().

◆ RtlpDphRemoveFromBusyList()

VOID NTAPI RtlpDphRemoveFromBusyList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 612 of file heappage.c.

614 {
615  BOOLEAN ElementPresent;
616 
617  DPRINT("RtlpDphRemoveFromBusyList(%p %p)\n", DphRoot, Node);
618 
619  /* Delete it from busy nodes table */
620  ElementPresent = RtlDeleteElementGenericTableAvl(&DphRoot->BusyNodesTable, &Node->pUserAllocation);
621  ASSERT(ElementPresent == TRUE);
622 
623  /* Update counters */
624  DphRoot->nBusyAllocations--;
625  DphRoot->nBusyAllocationBytesCommitted -= Node->nVirtualBlockSize;
626  DphRoot->nBusyAllocationBytesAccessible -= Node->nVirtualAccessSize;
627 }
#define TRUE
Definition: types.h:120
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
SIZE_T nBusyAllocationBytesAccessible
Definition: heappage.c:90
SIZE_T nBusyAllocationBytesCommitted
Definition: heappage.c:76
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
Definition: dlist.c:348
ULONG nBusyAllocations
Definition: heappage.c:75

Referenced by RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphRemoveFromFreeList()

VOID NTAPI RtlpDphRemoveFromFreeList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node,
PDPH_HEAP_BLOCK  Prev 
)

Definition at line 630 of file heappage.c.

633 {
634  PDPH_HEAP_BLOCK Next;
635 
636  DPRINT("RtlpDphRemoveFromFreeList(%p %p %p)\n", DphRoot, Node, Prev);
637 
638  /* Detach it from the list */
639  Next = Node->pNextAlloc;
640  if (DphRoot->pFreeAllocationListHead == Node)
641  DphRoot->pFreeAllocationListHead = Next;
642  if (DphRoot->pFreeAllocationListTail == Node)
643  DphRoot->pFreeAllocationListTail = Prev;
644  if (Prev) Prev->pNextAlloc = Next;
645 
646  /* Decrease heap counters */
647  DphRoot->nFreeAllocations--;
648  DphRoot->nFreeAllocationBytesCommitted -= Node->nVirtualBlockSize;
649 
650  Node->StackTrace = NULL;
651 }
PDPH_HEAP_BLOCK pFreeAllocationListHead
Definition: heappage.c:78
smooth NULL
Definition: ftsmooth.c:416
PDPH_HEAP_BLOCK pFreeAllocationListTail
Definition: heappage.c:79
void DPRINT(...)
Definition: polytest.cpp:61
struct _DPH_HEAP_BLOCK * pNextAlloc
Definition: heappage.c:44
SIZE_T nFreeAllocationBytesCommitted
Definition: heappage.c:81
ULONG nFreeAllocations
Definition: heappage.c:80
Definition: dlist.c:348

Referenced by RtlpDphCoalesceFreeIntoAvailable().

◆ RtlpDphReportCorruptedBlock()

VOID NTAPI RtlpDphReportCorruptedBlock ( PDPH_HEAP_ROOT  DphRoot,
ULONG  Reserved,
PVOID  Block,
ULONG  ValidationInfo 
)

Definition at line 1300 of file heappage.c.

1304 {
1305  //RtlpDphGetBlockSizeFromCorruptedBlock();
1306 
1307  if (ValidationInfo & DPH_VALINFO_CORRUPTED_AFTER_FREE)
1308  {
1309  DPRINT1("block corrupted after having been freed\n");
1310  }
1311 
1312  if (ValidationInfo & DPH_VALINFO_ALREADY_FREED)
1313  {
1314  DPRINT1("block already freed\n");
1315  }
1316 
1317  if (ValidationInfo & DPH_VALINFO_BAD_INFIX_PATTERN)
1318  {
1319  DPRINT1("corrupted infix pattern for freed block\n");
1320  }
1321 
1322  if (ValidationInfo & DPH_VALINFO_BAD_POINTER)
1323  {
1324  DPRINT1("corrupted heap pointer or using wrong heap\n");
1325  }
1326 
1327  if (ValidationInfo & DPH_VALINFO_BAD_SUFFIX_PATTERN)
1328  {
1329  DPRINT1("corrupted suffix pattern\n");
1330  }
1331 
1332  if (ValidationInfo & DPH_VALINFO_BAD_PREFIX_PATTERN)
1333  {
1334  DPRINT1("corrupted prefix pattern\n");
1335  }
1336 
1337  if (ValidationInfo & DPH_VALINFO_BAD_START_STAMP)
1338  {
1339  DPRINT1("corrupted start stamp\n");
1340  }
1341 
1342  if (ValidationInfo & DPH_VALINFO_BAD_END_STAMP)
1343  {
1344  DPRINT1("corrupted end stamp\n");
1345  }
1346 
1347  if (ValidationInfo & DPH_VALINFO_EXCEPTION)
1348  {
1349  DPRINT1("exception raised while verifying block\n");
1350  }
1351 
1352  DPRINT1("Corrupted heap block %p\n", Block);
1353 }
#define DPH_VALINFO_EXCEPTION
Definition: heappage.c:168
#define DPH_VALINFO_ALREADY_FREED
Definition: heappage.c:171
#define DPH_VALINFO_BAD_PREFIX_PATTERN
Definition: heappage.c:166
#define DPH_VALINFO_BAD_END_STAMP
Definition: heappage.c:164
#define DPH_VALINFO_BAD_SUFFIX_PATTERN
Definition: heappage.c:167
#define DPH_VALINFO_BAD_INFIX_PATTERN
Definition: heappage.c:170
#define DPH_VALINFO_BAD_POINTER
Definition: heappage.c:165
#define DPH_VALINFO_CORRUPTED_AFTER_FREE
Definition: heappage.c:172
#define DPRINT1
Definition: precomp.h:8
#define DPH_VALINFO_BAD_START_STAMP
Definition: heappage.c:163

Referenced by RtlpDphFreeDelayedBlocksFromHeap(), RtlpPageHeapDestroy(), RtlpPageHeapFree(), and RtlpPageHeapReAllocate().

◆ RtlpDphReturnNodeToUnusedList()

VOID NTAPI RtlpDphReturnNodeToUnusedList ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 543 of file heappage.c.

545 {
546  DPRINT("RtlpDphReturnNodeToUnusedList(%p, %p)\n", DphRoot, Node);
547 
548  /* Add it back to the head of the unused list */
549  Node->pNextAlloc = DphRoot->pUnusedNodeListHead;
550  if (!DphRoot->pUnusedNodeListHead)
551  DphRoot->pUnusedNodeListTail = Node;
552  DphRoot->pUnusedNodeListHead = Node;
553 
554  /* Increase amount of unused nodes */
555  DphRoot->nUnusedNodes++;
556 }
union node Node
Definition: types.h:1255
void DPRINT(...)
Definition: polytest.cpp:61
PDPH_HEAP_BLOCK pUnusedNodeListHead
Definition: heappage.c:87
ULONG nUnusedNodes
Definition: heappage.c:89
PDPH_HEAP_BLOCK pUnusedNodeListTail
Definition: heappage.c:88
Definition: dlist.c:348

Referenced by RtlpDphAllocateNode(), RtlpDphCoalesceNodeIntoAvailable(), and RtlpDphGrowVirtual().

◆ RtlpDphSearchAvailableMemoryListForBestFit()

PDPH_HEAP_BLOCK NTAPI RtlpDphSearchAvailableMemoryListForBestFit ( PDPH_HEAP_ROOT  DphRoot,
SIZE_T  Size 
)

Definition at line 846 of file heappage.c.

848 {
849  PLIST_ENTRY CurEntry;
850  PDPH_HEAP_BLOCK Node, NodeFound = NULL;
851 
852  CurEntry = DphRoot->AvailableAllocationHead.Flink;
853 
854  while (CurEntry != &DphRoot->AvailableAllocationHead)
855  {
856  /* Get the current available node */
857  Node = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
858 
859  /* Check its size */
860  if (Node->nVirtualBlockSize >= Size)
861  {
862  NodeFound = Node;
863  break;
864  }
865 
866  /* Move to the next available entry */
867  CurEntry = CurEntry->Flink;
868  }
869 
870  /* Make sure Adjacency list pointers are biased */
871  //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Flink));
872  //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Blink));
873 
874  return NodeFound;
875 }
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:83
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Definition: dlist.c:348

Referenced by RtlpDphFindAvailableMemory().

◆ RtlpDphSetProtectionAfterUse()

NTSTATUS NTAPI RtlpDphSetProtectionAfterUse ( PDPH_HEAP_ROOT  DphRoot,
PDPH_HEAP_BLOCK  Node 
)

Definition at line 972 of file heappage.c.

973 {
974  ASSERT((Node->nVirtualAccessSize + PAGE_SIZE) <= Node->nVirtualBlockSize);
975 
976  // FIXME: Bring stuff here
977  if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
978  {
979  }
980  else
981  {
982  }
983 
984  return STATUS_SUCCESS;
985 }
ULONG ExtraFlags
Definition: heappage.c:97
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
#define PAGE_SIZE
Definition: env_spec_w32.h:49
return STATUS_SUCCESS
Definition: btrfs.c:2938
Definition: dlist.c:348

◆ RtlpDphSetProtectionBeforeUse()

NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse ( PDPH_HEAP_ROOT  DphRoot,
PUCHAR  VirtualBlock,
ULONG  UserSize 
)

Definition at line 951 of file heappage.c.

952 {
953  ULONG Protection;
954  PVOID Base;
955 
956  if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
957  {
958  Base = VirtualBlock + PAGE_SIZE;
959  }
960  else
961  {
962  Base = VirtualBlock;
963  }
964 
965  // FIXME: It should be different, but for now it's fine
966  Protection = PAGE_READWRITE;
967 
968  return RtlpDphProtectVm(Base, UserSize, Protection);
969 }
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
ULONG ExtraFlags
Definition: heappage.c:97
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
#define PAGE_SIZE
Definition: env_spec_w32.h:49
unsigned int ULONG
Definition: retypes.h:1
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by RtlpPageHeapAllocate().

◆ RtlpDphShouldAllocateInPageHeap()

BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap ( PDPH_HEAP_ROOT  DphRoot,
SIZE_T  Size 
)

Definition at line 1463 of file heappage.c.

1465 {
1466  //UNIMPLEMENTED;
1467  /* Always use page heap for now */
1468  return TRUE;
1469 }
#define TRUE
Definition: types.h:120

Referenced by RtlpPageHeapAllocate(), and RtlpPageHeapReAllocate().

◆ RtlpDphTakeNodeFromUnusedList()

PDPH_HEAP_BLOCK NTAPI RtlpDphTakeNodeFromUnusedList ( PDPH_HEAP_ROOT  DphRoot)

Definition at line 521 of file heappage.c.

522 {
524  PDPH_HEAP_BLOCK Next;
525 
526  DPRINT("RtlpDphTakeNodeFromUnusedList(%p), ret %p\n", DphRoot, Node);
527 
528  /* Take the first entry */
529  if (!Node) return NULL;
530 
531  /* Remove that entry (Node) from the list */
532  Next = Node->pNextAlloc;
533  if (DphRoot->pUnusedNodeListHead == Node) DphRoot->pUnusedNodeListHead = Next;
534  if (DphRoot->pUnusedNodeListTail == Node) DphRoot->pUnusedNodeListTail = NULL;
535 
536  /* Decrease amount of unused nodes */
537  DphRoot->nUnusedNodes--;
538 
539  return Node;
540 }
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PDPH_HEAP_BLOCK pUnusedNodeListHead
Definition: heappage.c:87
ULONG nUnusedNodes
Definition: heappage.c:89
PDPH_HEAP_BLOCK pUnusedNodeListTail
Definition: heappage.c:88
Definition: dlist.c:348

Referenced by RtlpDphAddNewPool(), and RtlpDphAllocateNode().

◆ RtlpDphTargetDllsLogicInitialize()

NTSTATUS NTAPI RtlpDphTargetDllsLogicInitialize ( VOID  )

Definition at line 1281 of file heappage.c.

1282 {
1283  UNIMPLEMENTED;
1284  return STATUS_SUCCESS;
1285 }
#define UNIMPLEMENTED
Definition: debug.h:114
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by RtlpDphProcessStartupInitialization().

◆ RtlpDphVerifyIntegrity()

VOID NTAPI RtlpDphVerifyIntegrity ( PDPH_HEAP_ROOT  DphRoot)

Definition at line 1294 of file heappage.c.

1295 {
1296  UNIMPLEMENTED;
1297 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by RtlpPageHeapAllocate().

◆ RtlpDphWritePageHeapBlockInformation()

BOOLEAN NTAPI RtlpDphWritePageHeapBlockInformation ( PDPH_HEAP_ROOT  DphRoot,
PVOID  UserAllocation,
SIZE_T  Size,
SIZE_T  UserSize 
)

Definition at line 415 of file heappage.c.

416 {
417  PDPH_BLOCK_INFORMATION BlockInfo;
418  PUCHAR FillPtr;
419 
420  /* Get pointer to the block info structure */
421  BlockInfo = (PDPH_BLOCK_INFORMATION)UserAllocation - 1;
422 
423  /* Set up basic fields */
424  BlockInfo->Heap = DphRoot;
425  BlockInfo->ActualSize = UserSize;
426  BlockInfo->RequestedSize = Size;
427  BlockInfo->StartStamp = DPH_FILL_START_STAMP_1;
428  BlockInfo->EndStamp = DPH_FILL_END_STAMP_1;
429 
430  /* Fill with a pattern */
431  FillPtr = (PUCHAR)UserAllocation + Size;
432  RtlFillMemory(FillPtr, ROUND_UP(FillPtr, PAGE_SIZE) - (ULONG_PTR)FillPtr, DPH_FILL_SUFFIX);
433 
434  /* FIXME: Check if logging stack traces is turned on */
435  //if (DphRoot->ExtraFlags &
436 
437  return TRUE;
438 }
#define TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
unsigned char * PUCHAR
Definition: retypes.h:3
#define DPH_FILL_START_STAMP_1
Definition: heappage.c:155
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define DPH_FILL_END_STAMP_1
Definition: heappage.c:157
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define DPH_FILL_SUFFIX
Definition: heappage.c:159
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593

Referenced by RtlpPageHeapAllocate().

◆ RtlpPageHeapAllocate()

PVOID NTAPI RtlpPageHeapAllocate ( IN PVOID  HeapPtr,
IN ULONG  Flags,
IN SIZE_T  Size 
)

Definition at line 1697 of file heappage.c.

1700 {
1701  PDPH_HEAP_ROOT DphRoot;
1702  PDPH_HEAP_BLOCK AvailableNode, BusyNode;
1703  BOOLEAN Biased = FALSE;
1704  ULONG AllocateSize, AccessSize;
1705  NTSTATUS Status;
1706  SIZE_T UserActualSize;
1707  PVOID Ptr;
1708 
1709  /* Check requested size */
1710  if (Size > 0x7FF00000)
1711  {
1712  DPRINT1("extreme size request\n");
1713 
1714  /* Generate an exception if needed */
1716 
1717  return NULL;
1718  }
1719 
1720  /* Unbias the pointer if necessary */
1721  if (IS_BIASED_POINTER(HeapPtr))
1722  {
1723  HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
1724  Biased = TRUE;
1725  }
1726 
1727  /* Get a pointer to the heap root */
1728  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1729  if (!DphRoot) return NULL;
1730 
1731  /* Acquire the heap lock */
1732  RtlpDphPreProcessing(DphRoot, Flags);
1733 
1734  /* Perform internal validation if specified by flags */
1736  {
1738  }
1739 
1740  /* Add heap flags */
1741  Flags |= DphRoot->HeapFlags;
1742 
1743  if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
1744  {
1745  /* Perform allocation from a normal heap */
1746  ASSERT(FALSE);
1747  }
1748 
1749  /* Perform heap integrity check if specified by flags */
1751  {
1752  RtlpDphVerifyIntegrity(DphRoot);
1753  }
1754 
1755  /* Calculate sizes */
1756  AccessSize = ROUND_UP(Size + sizeof(DPH_BLOCK_INFORMATION), PAGE_SIZE);
1757  AllocateSize = AccessSize + PAGE_SIZE;
1758 
1759  // FIXME: Move RtlpDphAllocateNode(DphRoot) to this place
1760  AvailableNode = RtlpDphFindAvailableMemory(DphRoot, AllocateSize, TRUE);
1761  if (!AvailableNode)
1762  {
1763  DPRINT1("Page heap: Unable to allocate virtual memory\n");
1764  DbgBreakPoint();
1765 
1766  /* Release the lock */
1767  RtlpDphPostProcessing(DphRoot);
1768 
1769  return NULL;
1770  }
1771  ASSERT(AvailableNode->nVirtualBlockSize >= AllocateSize);
1772 
1773  /* Set protection */
1775  AvailableNode->pVirtualBlock,
1776  AccessSize);
1777  if (!NT_SUCCESS(Status))
1778  {
1779  ASSERT(FALSE);
1780  }
1781 
1782  /* Save available node pointer */
1783  Ptr = AvailableNode->pVirtualBlock;
1784 
1785  /* Check node's size */
1786  if (AvailableNode->nVirtualBlockSize > AllocateSize)
1787  {
1788  /* The block contains too much free space, reduce it */
1789  AvailableNode->pVirtualBlock += AllocateSize;
1790  AvailableNode->nVirtualBlockSize -= AllocateSize;
1791  DphRoot->nAvailableAllocationBytesCommitted -= AllocateSize;
1792 
1793  /* Allocate a new node which will be our busy node */
1794  BusyNode = RtlpDphAllocateNode(DphRoot);
1795  ASSERT(BusyNode != NULL);
1796  BusyNode->pVirtualBlock = Ptr;
1797  BusyNode->nVirtualBlockSize = AllocateSize;
1798  }
1799  else
1800  {
1801  /* The block's size fits exactly */
1802  RtlpDphRemoveFromAvailableList(DphRoot, AvailableNode);
1803  BusyNode = AvailableNode;
1804  }
1805 
1806  /* Calculate actual user size */
1807  if (DphRoot->HeapFlags & HEAP_NO_ALIGNMENT)
1808  UserActualSize = Size;
1809  else
1810  UserActualSize = ROUND_UP(Size, 8);
1811 
1812  /* Set up the block */
1813  BusyNode->nVirtualAccessSize = AccessSize;
1814  BusyNode->nUserActualSize = UserActualSize;
1815  BusyNode->nUserRequestedSize = Size;
1816 
1817  if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
1818  BusyNode->pUserAllocation = BusyNode->pVirtualBlock + PAGE_SIZE;
1819  else
1820  BusyNode->pUserAllocation = BusyNode->pVirtualBlock + BusyNode->nVirtualAccessSize - UserActualSize;
1821 
1822  BusyNode->UserValue = NULL;
1824 
1825  // FIXME: Don't forget about stack traces if such flag was set
1826  BusyNode->StackTrace = NULL;
1827 
1828  /* Place it on busy list */
1829  RtlpDphPlaceOnBusyList(DphRoot, BusyNode);
1830 
1831  /* Zero or patter-fill memory depending on flags */
1832  if (Flags & HEAP_ZERO_MEMORY)
1833  RtlZeroMemory(BusyNode->pUserAllocation, Size);
1834  else
1836 
1837  /* Write DPH info */
1838  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1839  {
1841  BusyNode->pUserAllocation,
1842  Size,
1843  AccessSize);
1844  }
1845 
1846  /* Finally allocation is done, perform validation again if required */
1848  {
1850  }
1851 
1852  /* Release the lock */
1853  RtlpDphPostProcessing(DphRoot);
1854 
1855  DPRINT("Allocated user block pointer: %p\n", BusyNode->pUserAllocation);
1856 
1857  /* Return pointer to user allocation */
1858  return BusyNode->pUserAllocation;
1859 }
#define DPH_FILL_INFIX
Definition: heappage.c:160
PVOID UserValue
Definition: heappage.c:54
#define TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define IS_BIASED_POINTER(ptr)
Definition: heappage.c:178
ULONG UserFlags
Definition: heappage.c:55
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1463
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
Definition: heappage.c:951
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
void DbgBreakPoint()
Definition: mach.c:553
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
SIZE_T nUserActualSize
Definition: heappage.c:53
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
unsigned char BOOLEAN
SIZE_T nVirtualAccessSize
Definition: heappage.c:51
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
void * PVOID
Definition: retypes.h:9
PUCHAR pUserAllocation
Definition: heappage.c:48
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define HEAP_NO_ALIGNMENT
Definition: rtltypes.h:163
PRTL_TRACE_BLOCK StackTrace
Definition: heappage.c:56
PUCHAR pVirtualBlock
Definition: heappage.c:49
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
BOOLEAN NTAPI RtlpDphWritePageHeapBlockInformation(PDPH_HEAP_ROOT DphRoot, PVOID UserAllocation, SIZE_T Size, SIZE_T UserSize)
Definition: heappage.c:415
VOID NTAPI RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
Definition: heappage.c:441
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
#define PAGE_SIZE
Definition: env_spec_w32.h:49
SIZE_T nUserRequestedSize
Definition: heappage.c:52
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory(PDPH_HEAP_ROOT DphRoot, SIZE_T Size, BOOLEAN Grow)
Definition: heappage.c:878
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:202
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI RtlpDphRemoveFromAvailableList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:559
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
VOID NTAPI RtlpDphVerifyIntegrity(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:1294
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:85

Referenced by RtlDebugAllocateHeap(), and RtlpPageHeapReAllocate().

◆ RtlpPageHeapCreate()

HANDLE NTAPI RtlpPageHeapCreate ( ULONG  Flags,
PVOID  Addr,
SIZE_T  TotalSize,
SIZE_T  CommitSize,
PVOID  Lock,
PRTL_HEAP_PARAMETERS  Parameters 
)

Definition at line 1472 of file heappage.c.

1478 {
1479  PVOID Base = NULL;
1480  PHEAP HeapPtr;
1481  PDPH_HEAP_ROOT DphRoot;
1482  PDPH_HEAP_BLOCK DphNode;
1483  ULONG MemSize;
1484  NTSTATUS Status;
1485  LARGE_INTEGER PerfCounter;
1486 
1487  /* Check for a DPH bypass flag */
1488  if ((ULONG_PTR)Parameters == -1) return NULL;
1489 
1490  /* Make sure no user-allocated stuff was provided */
1491  if (Addr || Lock) return NULL;
1492 
1493  /* Allocate minimum amount of virtual memory */
1494  MemSize = DPH_RESERVE_SIZE;
1496  if (!NT_SUCCESS(Status))
1497  {
1498  ASSERT(FALSE);
1499  return NULL;
1500  }
1501 
1502  /* Set protection */
1504  if (!NT_SUCCESS(Status))
1505  {
1506  //RtlpDphFreeVm(Base, 0, 0, 0);
1507  ASSERT(FALSE);
1508  return NULL;
1509  }
1510 
1511  /* Start preparing the 1st page. Fill it with the default filler */
1513 
1514  /* Set flags in the "HEAP" structure */
1515  HeapPtr = (PHEAP)Base;
1516  HeapPtr->Flags = Flags | HEAP_FLAG_PAGE_ALLOCS;
1517  HeapPtr->ForceFlags = Flags | HEAP_FLAG_PAGE_ALLOCS;
1518 
1519  /* Set 1st page to read only now */
1521  if (!NT_SUCCESS(Status))
1522  {
1523  ASSERT(FALSE);
1524  return NULL;
1525  }
1526 
1527  /* 2nd page is the real DPH root block */
1528  DphRoot = (PDPH_HEAP_ROOT)((PCHAR)Base + PAGE_SIZE);
1529 
1530  /* Initialize the DPH root */
1531  DphRoot->Signature = DPH_SIGNATURE;
1532  DphRoot->HeapFlags = Flags;
1533  DphRoot->HeapCritSect = (PHEAP_LOCK)((PCHAR)DphRoot + DPH_POOL_SIZE);
1534  DphRoot->ExtraFlags = RtlpDphGlobalFlags;
1535 
1536  ZwQueryPerformanceCounter(&PerfCounter, NULL);
1537  DphRoot->Seed = PerfCounter.LowPart;
1538 
1541 
1542  /* Create a normal heap for this paged heap */
1543  DphRoot->NormalHeap = RtlCreateHeap(Flags, NULL, TotalSize, CommitSize, NULL, (PRTL_HEAP_PARAMETERS)-1);
1544  if (!DphRoot->NormalHeap)
1545  {
1546  ASSERT(FALSE);
1547  return NULL;
1548  }
1549 
1550  /* 3rd page: a pool for DPH allocations */
1551  RtlpDphAddNewPool(DphRoot, NULL, DphRoot + 1, DPH_POOL_SIZE - sizeof(DPH_HEAP_ROOT), FALSE);
1552 
1553  /* Allocate internal heap blocks. For the root */
1554  DphNode = RtlpDphAllocateNode(DphRoot);
1555  ASSERT(DphNode != NULL);
1556  DphNode->pVirtualBlock = (PUCHAR)DphRoot;
1557  DphNode->nVirtualBlockSize = DPH_POOL_SIZE;
1558  RtlpDphPlaceOnPoolList(DphRoot, DphNode);
1559 
1560  /* For the memory we allocated as a whole */
1561  DphNode = RtlpDphAllocateNode(DphRoot);
1562  ASSERT(DphNode != NULL);
1563  DphNode->pVirtualBlock = Base;
1564  DphNode->nVirtualBlockSize = MemSize;
1565  RtlpDphPlaceOnVirtualList(DphRoot, DphNode);
1566 
1567  /* For the remaining part */
1568  DphNode = RtlpDphAllocateNode(DphRoot);
1569  ASSERT(DphNode != NULL);
1570  DphNode->pVirtualBlock = (PUCHAR)Base + 2*PAGE_SIZE + DPH_POOL_SIZE;
1571  DphNode->nVirtualBlockSize = MemSize - (2*PAGE_SIZE + DPH_POOL_SIZE);
1572  RtlpDphCoalesceNodeIntoAvailable(DphRoot, DphNode);
1573 
1574  //DphRoot->CreateStackTrace = RtlpDphLogStackTrace(1);
1575 
1576  /* Initialize AVL-based busy nodes table */
1581  NULL);
1582 
1583  /* Initialize per-process startup info */
1585 
1586  /* Acquire the heap list lock */
1588 
1589  /* Insert this heap to the tail of the global list */
1591 
1592  /* Note we increased the size of the list */
1594 
1595  /* Release the heap list lock */
1597 
1599  {
1600  DPRINT1("Page heap: process 0x%p created heap @ %p (%p, flags 0x%X)\n",
1602  DphRoot->NormalHeap, DphRoot->ExtraFlags);
1603  }
1604 
1605  /* Perform internal validation if required */
1608 
1609  return (PUCHAR)DphRoot - PAGE_SIZE;
1610 }
#define DPH_DEBUG_VERBOSE
Definition: heappage.c:147
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI NTSTATUS NTAPI ZwQueryPerformanceCounter(_Out_ PLARGE_INTEGER Counter, _Out_opt_ PLARGE_INTEGER Frequency)
NTSTATUS NTAPI RtlpDphProcessStartupInitialization(VOID)
Definition: heappage.c:1431
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:83
struct _DPH_HEAP_ROOT * PDPH_HEAP_ROOT
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
VOID NTAPI RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:505
VOID NTAPI RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
Definition: heappage.c:799
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define DPH_RESERVE_SIZE
Definition: heappage.c:133
PVOID NormalHeap
Definition: heappage.c:99
#define InsertTailList(ListHead, Entry)
HANDLE UniqueProcess
Definition: compat.h:482
#define MEM_COMMIT
Definition: nt_native.h:1313
ULONG RtlpDphGlobalFlags
Definition: heappage.c:107
LIST_ENTRY RtlpDphPageHeapList
Definition: heappage.c:112
struct _HEAP_LOCK * PHEAP_LOCK
uint32_t ULONG_PTR
Definition: typedefs.h:63
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PVOID NTAPI RtlpDphAllocateNodeForTable(IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
Definition: heappage.c:1176
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:654
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
ULONG RtlpDphPageHeapListLength
Definition: heappage.c:116
VOID NTAPI RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:485
VOID NTAPI RtlpDphFreeNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: heappage.c:1197
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define DPH_FILL
Definition: heappage.c:154
#define DPH_POOL_SIZE
Definition: heappage.c:134
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
Definition: libsupp.c:126
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PUCHAR pVirtualBlock
Definition: heappage.c:49
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
NTSTATUS NTAPI RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
Definition: heappage.c:316
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
ULONG LowPart
Definition: typedefs.h:104
VOID NTAPI RtlInitializeGenericTableAvl(IN OUT PRTL_AVL_TABLE Table, IN PRTL_AVL_COMPARE_ROUTINE CompareRoutine, IN PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: avltable.c:26
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
LIST_ENTRY NextHeap
Definition: heappage.c:96
ULONG Seed
Definition: heappage.c:98
Status
Definition: gdiplustypes.h:24
ULONG Signature
Definition: heappage.c:63
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
ULONG Flags
Definition: heap.h:223
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PAGE_READONLY
Definition: compat.h:127
#define DPRINT1
Definition: precomp.h:8
BOOLEAN RtlpDphPageHeapListInitialized
Definition: heappage.c:113
unsigned int ULONG
Definition: retypes.h:1
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
RTL_GENERIC_COMPARE_RESULTS NTAPI RtlpDphCompareNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
Definition: heappage.c:1157
#define DPH_SIGNATURE
Definition: heappage.c:175
Definition: heap.c:51
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by RtlCreateHeap().

◆ RtlpPageHeapDestroy()

PVOID NTAPI RtlpPageHeapDestroy ( HANDLE  HeapPtr)

Definition at line 1613 of file heappage.c.

1614 {
1615  PDPH_HEAP_ROOT DphRoot;
1616  PVOID Ptr;
1617  PDPH_HEAP_BLOCK Node, Next;
1618  PHEAP NormalHeap;
1619  ULONG Value;
1620 
1621  /* Check if it's not a process heap */
1622  if (HeapPtr == RtlGetProcessHeap())
1623  {
1624  DbgBreakPoint();
1625  return NULL;
1626  }
1627 
1628  /* Get pointer to the heap root */
1629  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1630  if (!DphRoot) return NULL;
1631 
1632  RtlpDphPreProcessing(DphRoot, DphRoot->HeapFlags);
1633 
1634  /* Get the pointer to the normal heap */
1635  NormalHeap = DphRoot->NormalHeap;
1636 
1637  /* Free the delayed-free blocks */
1638  RtlpDphFreeDelayedBlocksFromHeap(DphRoot, NormalHeap);
1639 
1640  /* Go through the busy blocks */
1642 
1643  while (Ptr)
1644  {
1645  Node = CONTAINING_RECORD(Ptr, DPH_HEAP_BLOCK, pUserAllocation);
1646  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1647  {
1648  if (!RtlpDphIsPageHeapBlock(DphRoot, Node->pUserAllocation, &Value, TRUE))
1649  {
1650  RtlpDphReportCorruptedBlock(DphRoot, 3, Node->pUserAllocation, Value);
1651  }
1652  }
1653 
1654  /* FIXME: Call AV notification */
1655  //AVrfInternalHeapFreeNotification();
1656 
1657  /* Go to the next node */
1659  }
1660 
1661  /* Acquire the global heap list lock */
1663 
1664  /* Remove the entry and decrement the global counter */
1665  RemoveEntryList(&DphRoot->NextHeap);
1667 
1668  /* Release the global heap list lock */
1670 
1671  /* Leave and delete this heap's critical section */
1672  RtlLeaveHeapLock(DphRoot->HeapCritSect);
1673  RtlDeleteHeapLock(DphRoot->HeapCritSect);
1674 
1675  /* Now go through all virtual list nodes and release the VM */
1676  Node = DphRoot->pVirtualStorageListHead;
1677  while (Node)
1678  {
1679  Next = Node->pNextAlloc;
1680  /* Release the memory without checking result */
1681  RtlpDphFreeVm(Node->pVirtualBlock, 0, MEM_RELEASE);
1682  Node = Next;
1683  }
1684 
1685  /* Destroy the normal heap */
1686  RtlDestroyHeap(NormalHeap);
1687 
1688  /* Report success */
1690  DPRINT1("Page heap: process 0x%p destroyed heap @ %p (%p)\n",
1691  NtCurrentTeb()->ClientId.UniqueProcess, HeapPtr, NormalHeap);
1692 
1693  return NULL;
1694 }
#define DPH_DEBUG_VERBOSE
Definition: heappage.c:147
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
PVOID NormalHeap
Definition: heappage.c:99
HANDLE UniqueProcess
Definition: compat.h:482
void DbgBreakPoint()
Definition: mach.c:553
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
PDPH_HEAP_BLOCK pVirtualStorageListHead
Definition: heappage.c:68
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG RtlpDphPageHeapListLength
Definition: heappage.c:116
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)
VOID NTAPI RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot, PHEAP NormalHeap)
Definition: heappage.c:1228
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
LIST_ENTRY NextHeap
Definition: heappage.c:96
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI RtlpDphFreeVm(PVOID Base, SIZE_T Size, ULONG Type)
Definition: heappage.c:355
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:101
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
Definition: heap.c:51
Definition: dlist.c:348

Referenced by RtlDestroyHeap().

◆ RtlpPageHeapFree()

BOOLEAN NTAPI RtlpPageHeapFree ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr 
)

Definition at line 1862 of file heappage.c.

1865 {
1866  PDPH_HEAP_ROOT DphRoot;
1868  ULONG ValidationInfo;
1870 
1871  /* Check for a NULL pointer freeing */
1872  if (!Ptr)
1873  {
1875  {
1876  DPRINT1("Page heap: freeing a null pointer \n");
1877  DbgBreakPoint();
1878  }
1879  return TRUE;
1880  }
1881 
1882  /* Get a pointer to the heap root */
1883  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1884  if (!DphRoot) return FALSE;
1885 
1886  /* Acquire the heap lock */
1887  RtlpDphPreProcessing(DphRoot, Flags);
1888 
1889  /* Perform internal validation if specified by flags */
1892 
1893  /* Add heap flags */
1894  Flags |= DphRoot->HeapFlags;
1895 
1896  /* Find busy memory */
1897  Node = RtlpDphFindBusyMemory(DphRoot, Ptr);
1898 
1899  if (!Node)
1900  {
1901  /* This block was not found in page heap, try a normal heap instead */
1902  //RtlpDphNormalHeapFree();
1903  ASSERT(FALSE);
1904  }
1905 
1906  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1907  {
1908  /* Check and report corrupted block */
1909  if (!RtlpDphIsPageHeapBlock(DphRoot, Ptr, &ValidationInfo, TRUE))
1910  {
1911  RtlpDphReportCorruptedBlock(DphRoot, 1, Ptr, ValidationInfo);
1912  }
1913 
1914  // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1915  if (Node->nVirtualAccessSize != 0)
1916  {
1917  /* Set stamps */
1918  Info = (PDPH_BLOCK_INFORMATION)Node->pUserAllocation - 1;
1919  Info->StartStamp = DPH_FILL_START_STAMP_2;
1920  Info->EndStamp = DPH_FILL_END_STAMP_2;
1921 
1922  RtlpDphProtectVm(Node->pVirtualBlock, Node->nVirtualAccessSize, PAGE_NOACCESS);
1923  }
1924  }
1925  else
1926  {
1927  // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1928  if (Node->nVirtualAccessSize != 0)
1929  RtlpDphProtectVm(Node->pVirtualBlock + PAGE_SIZE, Node->nVirtualAccessSize, PAGE_NOACCESS);
1930  }
1931 
1932  /* Set new protection */
1933  //RtlpDphSetProtectionAfterUse(DphRoot, Node);
1934 
1935  /* Remove it from the list of busy nodes */
1936  RtlpDphRemoveFromBusyList(DphRoot, Node);
1937 
1938  /* And put it into the list of free nodes */
1939  RtlpDphPlaceOnFreeList(DphRoot, Node);
1940 
1941  //if (DphRoot->ExtraFlags & DPH_EXTRA_LOG_STACK_TRACES)
1942  // Node->StackTrace = RtlpDphLogStackTrace(3);
1943  //else
1944  Node->StackTrace = NULL;
1945 
1946  /* Leave the heap lock */
1947  RtlpDphPostProcessing(DphRoot);
1948 
1949  /* Return success */
1950  return TRUE;
1951 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
void DbgBreakPoint()
Definition: mach.c:553
struct TraceInfo Info
#define DPH_FILL_END_STAMP_2
Definition: heappage.c:158
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
VOID NTAPI RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:612
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
#define DPH_FILL_START_STAMP_2
Definition: heappage.c:156
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
#define DPH_BREAK_ON_NULL_FREE
Definition: heappage.c:143
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
#define DPRINT1
Definition: precomp.h:8
ULONG RtlpDphBreakOptions
Definition: heappage.c:183
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
Definition: dlist.c:348

Referenced by RtlDebugFreeHeap().

◆ RtlpPageHeapGetUserInfo()

BOOLEAN NTAPI RtlpPageHeapGetUserInfo ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID UserValue,
PULONG  UserFlags 
)

Definition at line 2124 of file heappage.c.

2129 {
2130  PDPH_HEAP_ROOT DphRoot;
2132 
2133  /* Get a pointer to the heap root */
2134  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2135  if (!DphRoot) return FALSE;
2136 
2137  /* Add heap flags */
2138  Flags |= DphRoot->HeapFlags;
2139 
2140  /* Acquire the heap lock */
2141  RtlpDphPreProcessing(DphRoot, Flags);
2142 
2143  /* Find busy memory */
2145 
2146  if (!Node)
2147  {
2148  /* This block was not found in page heap, try a normal heap instead */
2149  //RtlpDphNormalHeapGetUserInfo();
2150  ASSERT(FALSE);
2151  return FALSE;
2152  }
2153 
2154  /* Get user values and flags and store them in user provided pointers */
2155  if (UserValue) *UserValue = Node->UserValue;
2156  if (UserFlags) *UserFlags = Node->UserFlags;
2157 
2158  /* Leave the heap lock */
2159  RtlpDphPostProcessing(DphRoot);
2160 
2161  /* Return success */
2162  return TRUE;
2163 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugGetUserInfoHeap().

◆ RtlpPageHeapLock()

BOOLEAN NTAPI RtlpPageHeapLock ( HANDLE  HeapPtr)

Definition at line 2354 of file heappage.c.

2355 {
2356  PDPH_HEAP_ROOT DphRoot;
2357 
2358  /* Get pointer to the heap root */
2359  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2360  if (!DphRoot) return FALSE;
2361 
2362  RtlpDphEnterCriticalSection(DphRoot, DphRoot->HeapFlags);
2363  return TRUE;
2364 }
#define TRUE
Definition: types.h:120
ULONG HeapFlags
Definition: heappage.c:64
VOID NTAPI RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:235
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218

Referenced by RtlLockHeap().

◆ RtlpPageHeapReAllocate()

PVOID NTAPI RtlpPageHeapReAllocate ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr,
SIZE_T  Size 
)

Definition at line 1954 of file heappage.c.

1958 {
1959  PDPH_HEAP_ROOT DphRoot;
1960  PDPH_HEAP_BLOCK Node = NULL, AllocatedNode;
1961  BOOLEAN Biased = FALSE, UseNormalHeap = FALSE, OldBlockPageHeap = TRUE;
1962  ULONG ValidationInfo;
1963  SIZE_T DataSize;
1964  PVOID NewAlloc = NULL;
1965 
1966  /* Check requested size */
1967  if (Size > 0x7FF00000)
1968  {
1969  DPRINT1("extreme size request\n");
1970 
1971  /* Generate an exception if needed */
1973 
1974  return NULL;
1975  }
1976 
1977  /* Unbias the pointer if necessary */
1978  if (IS_BIASED_POINTER(HeapPtr))
1979  {
1980  HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
1981  Biased = TRUE;
1982  }
1983 
1984  /* Get a pointer to the heap root */
1985  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1986  if (!DphRoot) return NULL;
1987 
1988  /* Acquire the heap lock */
1989  RtlpDphPreProcessing(DphRoot, Flags);
1990 
1991  /* Perform internal validation if specified by flags */
1993  {
1995  }
1996 
1997  /* Add heap flags */
1998  Flags |= DphRoot->HeapFlags;
1999 
2000  /* Exit with NULL right away if inplace is specified */
2002  {
2003  /* Release the lock */
2004  RtlpDphPostProcessing(DphRoot);
2005 
2006  /* Generate an exception if needed */
2008 
2009  return NULL;
2010  }
2011 
2012  /* Try to get node of the allocated block */
2013  AllocatedNode = RtlpDphFindBusyMemory(DphRoot, Ptr);
2014 
2015  if (!AllocatedNode)
2016  {
2017  /* This block was not found in page heap, try a normal heap instead */
2018  //RtlpDphNormalHeapFree();
2019  ASSERT(FALSE);
2020  OldBlockPageHeap = FALSE;
2021  }
2022 
2023  /* Check the block */
2024  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
2025  {
2026  if (!RtlpDphIsPageHeapBlock(DphRoot, AllocatedNode->pUserAllocation, &ValidationInfo, TRUE))
2027  {
2028  RtlpDphReportCorruptedBlock(DphRoot, 3, AllocatedNode->pUserAllocation, ValidationInfo);
2029  }
2030  }
2031 
2032  /* Remove old one from the busy list */
2033  RtlpDphRemoveFromBusyList(DphRoot, AllocatedNode);
2034 
2035  if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
2036  {
2037  // FIXME: Use normal heap
2038  ASSERT(FALSE);
2039  UseNormalHeap = TRUE;
2040  }
2041  else
2042  {
2043  /* Now do a trick: bias the pointer and call our allocate routine */
2044  NewAlloc = RtlpPageHeapAllocate((PVOID)POINTER_ADD_BIAS(HeapPtr), Flags, Size);
2045  }
2046 
2047  if (!NewAlloc)
2048  {
2049  /* New allocation failed, put the block back (if it was found in page heap) */
2050  RtlpDphPlaceOnBusyList(DphRoot, AllocatedNode);
2051 
2052  /* Release the lock */
2053  RtlpDphPostProcessing(DphRoot);
2054 
2055  /* Perform validation again if required */
2057  {
2059  }
2060 
2061  /* Generate an exception if needed */
2063 
2064  return NULL;
2065  }
2066 
2067  /* Copy contents of the old block */
2068  if (AllocatedNode->nUserRequestedSize > Size)
2069  DataSize = Size;
2070  else
2071  DataSize = AllocatedNode->nUserRequestedSize;
2072 
2073  if (DataSize != 0) RtlCopyMemory(NewAlloc, Ptr, DataSize);
2074 
2075  /* Copy user flags and values */
2076  if (!UseNormalHeap)
2077  {
2078  /* Get the node of the new block */
2079  Node = RtlpDphFindBusyMemory(DphRoot, NewAlloc);
2080  ASSERT(Node != NULL);
2081 
2082  /* Set its values/flags */
2083  Node->UserValue = AllocatedNode->UserValue;
2085  Node->UserFlags = Flags & HEAP_SETTABLE_USER_FLAGS;
2086  else
2087  Node->UserFlags = AllocatedNode->UserFlags;
2088  }
2089 
2090  if (!OldBlockPageHeap)
2091  {
2092  /* Weird scenario, investigate */
2093  ASSERT(FALSE);
2094  }
2095 
2096  /* Mark the old block as no access */
2097  if (AllocatedNode->nVirtualAccessSize != 0)
2098  {
2099  RtlpDphProtectVm(AllocatedNode->pVirtualBlock, AllocatedNode->nVirtualAccessSize, PAGE_NOACCESS);
2100  }
2101 
2102  /* And place it on the free list */
2103  RtlpDphPlaceOnFreeList(DphRoot, AllocatedNode);
2104 
2105  // FIXME: Capture stack traces if needed
2106  AllocatedNode->StackTrace = NULL;
2107 
2108  /* Finally allocation is done, perform validation again if required */
2110  {
2112  }
2113 
2114  /* Release the lock */
2115  RtlpDphPostProcessing(DphRoot);
2116 
2117  DPRINT("Allocated new user block pointer: %p\n", NewAlloc);
2118 
2119  /* Return pointer to user allocation */
2120  return NewAlloc;
2121 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IS_BIASED_POINTER(ptr)
Definition: heappage.c:178
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1463
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define POINTER_ADD_BIAS(ptr)
Definition: heappage.c:180
VOID NTAPI RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:612
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
VOID NTAPI RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
Definition: heappage.c:441
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1697
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:202
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
Definition: dlist.c:348

Referenced by RtlDebugReAllocateHeap().

◆ RtlpPageHeapSetUserFlags()

BOOLEAN NTAPI RtlpPageHeapSetUserFlags ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
ULONG  UserFlagsReset,
ULONG  UserFlagsSet 
)

Definition at line 2207 of file heappage.c.

2212 {
2213  PDPH_HEAP_ROOT DphRoot;
2215 
2216  /* Get a pointer to the heap root */
2217  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2218  if (!DphRoot) return FALSE;
2219 
2220  /* Add heap flags */
2221  Flags |= DphRoot->HeapFlags;
2222 
2223  /* Acquire the heap lock */
2224  RtlpDphPreProcessing(DphRoot, Flags);
2225 
2226  /* Find busy memory */
2228 
2229  if (!Node)
2230  {
2231  /* This block was not found in page heap, try a normal heap instead */
2232  //RtlpDphNormalHeapSetUserFlags();
2233  ASSERT(FALSE);
2234  return FALSE;
2235  }
2236 
2237  /* Get user values and flags and store them in user provided pointers */
2238  Node->UserFlags &= ~(UserFlagsReset);
2239  Node->UserFlags |= UserFlagsSet;
2240 
2241  /* Leave the heap lock */
2242  RtlpDphPostProcessing(DphRoot);
2243 
2244  /* Return success */
2245  return TRUE;
2246 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSetUserFlagsHeap().

◆ RtlpPageHeapSetUserValue()

BOOLEAN NTAPI RtlpPageHeapSetUserValue ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID  UserValue 
)

Definition at line 2166 of file heappage.c.

2170 {
2171  PDPH_HEAP_ROOT DphRoot;
2173 
2174  /* Get a pointer to the heap root */
2175  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2176  if (!DphRoot) return FALSE;
2177 
2178  /* Add heap flags */
2179  Flags |= DphRoot->HeapFlags;
2180 
2181  /* Acquire the heap lock */
2182  RtlpDphPreProcessing(DphRoot, Flags);
2183 
2184  /* Find busy memory */
2186 
2187  if (!Node)
2188  {
2189  /* This block was not found in page heap, try a normal heap instead */
2190  //RtlpDphNormalHeapSetUserValue();
2191  ASSERT(FALSE);
2192  return FALSE;
2193  }
2194 
2195  /* Get user values and flags and store them in user provided pointers */
2196  Node->UserValue = UserValue;
2197 
2198  /* Leave the heap lock */
2199  RtlpDphPostProcessing(DphRoot);
2200 
2201  /* Return success */
2202  return TRUE;
2203 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSetUserValueHeap().

◆ RtlpPageHeapSize()

SIZE_T NTAPI RtlpPageHeapSize ( HANDLE  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress 
)

Definition at line 2249 of file heappage.c.

2252 {
2253  PDPH_HEAP_ROOT DphRoot;
2255  SIZE_T Size;
2256 
2257  /* Get a pointer to the heap root */
2258  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2259  if (!DphRoot) return -1;
2260 
2261  /* Add heap flags */
2262  Flags |= DphRoot->HeapFlags;
2263 
2264  /* Acquire the heap lock */
2265  RtlpDphPreProcessing(DphRoot, Flags);
2266 
2267  /* Find busy memory */
2269 
2270  if (!Node)
2271  {
2272  /* This block was not found in page heap, try a normal heap instead */
2273  //RtlpDphNormalHeapSize();
2274  ASSERT(FALSE);
2275  return -1;
2276  }
2277 
2278  /* Get heap block size */
2279  Size = Node->nUserRequestedSize;
2280 
2281  /* Leave the heap lock */
2282  RtlpDphPostProcessing(DphRoot);
2283 
2284  /* Return user requested size */
2285  return Size;
2286 }
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSizeHeap().

◆ RtlpPageHeapUnlock()

BOOLEAN NTAPI RtlpPageHeapUnlock ( HANDLE  HeapPtr)

Definition at line 2368 of file heappage.c.

2369 {
2370  PDPH_HEAP_ROOT DphRoot;
2371 
2372  /* Get pointer to the heap root */
2373  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2374  if (!DphRoot) return FALSE;
2375 
2376  RtlpDphLeaveCriticalSection(DphRoot);
2377  return TRUE;
2378 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:263
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218

Referenced by RtlUnlockHeap().

◆ RtlpSecMemFreeVirtualMemory()

NTSTATUS NTAPI RtlpSecMemFreeVirtualMemory ( HANDLE  Process,
PVOID Base,
PSIZE_T  Size,
ULONG  Type 
)

Definition at line 293 of file heappage.c.

294 {
296  //PVOID *SavedBase = Base;
297  //PSIZE_T SavedSize = Size;
298 
299  /* Free the memory */
300  Status = ZwFreeVirtualMemory(Process, Base, Size, Type);
301 
302  /* Flush secure memory cache if needed and retry freeing */
303 #if 0
305  Process == NtCurrentProcess() &&
306  RtlFlushSecureMemoryCache(*SavedBase, *SavedSize))
307  {
308  Status = ZwFreeVirtualMemory(NtCurrentProcess(), SavedBase, SavedSize, Type);
309  }
310 #endif
311 
312  return Status;
313 }
Type
Definition: Type.h:6
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
BOOLEAN NTAPI RtlFlushSecureMemoryCache(IN PVOID MemoryCache, IN OPTIONAL SIZE_T MemoryLength)
Definition: security.c:830

Referenced by RtlpDphFreeVm().

Variable Documentation

◆ _RtlpDphDelayedFreeQueueLock

HEAP_LOCK _RtlpDphDelayedFreeQueueLock

Definition at line 119 of file heappage.c.

◆ _RtlpDphPageHeapListLock

HEAP_LOCK _RtlpDphPageHeapListLock

Definition at line 114 of file heappage.c.

◆ RtlpDphAllocFails

LONG RtlpDphAllocFails

Definition at line 128 of file heappage.c.

Referenced by RtlpDphAllocateVm().

◆ RtlpDphBreakOptions

ULONG RtlpDphBreakOptions = 0

Definition at line 183 of file heappage.c.

Referenced by RtlpDphAllocateVm(), RtlpDphFreeVm(), RtlpDphProtectVm(), and RtlpPageHeapFree().

◆ RtlpDphCounter

LONG RtlpDphCounter

Definition at line 127 of file heappage.c.

Referenced by RtlpDphAllocateVm().

◆ RtlpDphDebugOptions

◆ RtlpDphDelayedFreeQueue

LIST_ENTRY RtlpDphDelayedFreeQueue

◆ RtlpDphDelayedFreeQueueLock

PHEAP_LOCK RtlpDphDelayedFreeQueueLock = &_RtlpDphDelayedFreeQueueLock

◆ RtlpDphDelayedTemporaryPushList

SLIST_HEADER RtlpDphDelayedTemporaryPushList

Definition at line 122 of file heappage.c.

Referenced by RtlpDphInitializeDelayedFreeQueue().

◆ RtlpDphFreeFails

LONG RtlpDphFreeFails

Definition at line 130 of file heappage.c.

Referenced by RtlpDphFreeVm().

◆ RtlpDphGlobalFlags

◆ RtlpDphMemoryUsedByDelayedFreeBlocks

SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks

◆ RtlpDphNumberOfDelayedFreeBlocks

ULONG RtlpDphNumberOfDelayedFreeBlocks

◆ RtlpDphPageHeapList

LIST_ENTRY RtlpDphPageHeapList

Definition at line 112 of file heappage.c.

Referenced by RtlpDphProcessStartupInitialization(), and RtlpPageHeapCreate().

◆ RtlpDphPageHeapListInitialized

BOOLEAN RtlpDphPageHeapListInitialized

Definition at line 113 of file heappage.c.

Referenced by RtlpDphProcessStartupInitialization(), and RtlpPageHeapCreate().

◆ RtlpDphPageHeapListLength

ULONG RtlpDphPageHeapListLength

Definition at line 116 of file heappage.c.

Referenced by RtlpPageHeapCreate(), and RtlpPageHeapDestroy().

◆ RtlpDphPageHeapListLock

PHEAP_LOCK RtlpDphPageHeapListLock = &_RtlpDphPageHeapListLock

◆ RtlpDphProtectFails

LONG RtlpDphProtectFails

Definition at line 131 of file heappage.c.

Referenced by RtlpDphProtectVm().

◆ RtlpDphReleaseFails

LONG RtlpDphReleaseFails

Definition at line 129 of file heappage.c.

Referenced by RtlpDphFreeVm().

◆ RtlpDphTargetDlls

WCHAR RtlpDphTargetDlls[512]

Definition at line 110 of file heappage.c.

Referenced by RtlpDphProcessStartupInitialization().

◆ RtlpDphTargetDllsUnicode

UNICODE_STRING RtlpDphTargetDllsUnicode

Definition at line 117 of file heappage.c.

Referenced by RtlpDphProcessStartupInitialization().

◆ RtlpPageHeapDllRangeEnd

ULONG RtlpPageHeapDllRangeEnd

Definition at line 109 of file heappage.c.

◆ RtlpPageHeapDllRangeStart

ULONG RtlpPageHeapDllRangeStart

Definition at line 109 of file heappage.c.

◆ RtlpPageHeapEnabled

BOOLEAN RtlpPageHeapEnabled = FALSE

◆ RtlpPageHeapSizeRangeEnd

ULONG RtlpPageHeapSizeRangeEnd

Definition at line 108 of file heappage.c.

◆ RtlpPageHeapSizeRangeStart

ULONG RtlpPageHeapSizeRangeStart

Definition at line 108 of file heappage.c.