diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 357ad63ff1a..63288fe7116 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -81,10 +81,10 @@ STDCALL RtlCreateHeap( IN ULONG Flags, IN PVOID BaseAddress OPTIONAL, - IN ULONG SizeToReserve OPTIONAL, - IN ULONG SizeToCommit OPTIONAL, + IN SIZE_T SizeToReserve OPTIONAL, + IN SIZE_T SizeToCommit OPTIONAL, IN PVOID Lock OPTIONAL, - IN PRTL_HEAP_DEFINITION Definition OPTIONAL + IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL ); DWORD diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index e1542ceeb9b..bc24f6cce3d 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -109,6 +109,15 @@ typedef VOID PVOID Parameter ); +#ifndef _NTIFS_ +typedef NTSTATUS +(NTAPI * PRTL_HEAP_COMMIT_ROUTINE) ( + IN PVOID Base, + IN OUT PVOID *CommitAddress, + IN OUT PSIZE_T CommitSize +); +#endif + /* TYPES *********************************************************************/ typedef unsigned short RTL_ATOM; @@ -219,12 +228,6 @@ typedef struct _MODULE_INFORMATION ULONG ModuleCount; DEBUG_MODULE_INFORMATION ModuleEntry[1]; } MODULE_INFORMATION, *PMODULE_INFORMATION; - -typedef struct _RTL_HEAP_DEFINITION -{ - ULONG Length; - ULONG Unknown[11]; -} RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION; /* END REVIEW AREA */ #ifdef _INC_EXCPT @@ -399,6 +402,22 @@ typedef struct _RTL_ATOM_TABLE PRTL_ATOM_TABLE_ENTRY Buckets[1]; } RTL_ATOM_TABLE, *PRTL_ATOM_TABLE; +#ifndef _NTIFS_ +typedef struct _RTL_HEAP_PARAMETERS { + ULONG Length; + SIZE_T SegmentReserve; + SIZE_T SegmentCommit; + SIZE_T DeCommitFreeBlockThreshold; + SIZE_T DeCommitTotalFreeThreshold; + SIZE_T MaximumAllocationSize; + SIZE_T VirtualMemoryThreshold; + SIZE_T InitialCommit; + SIZE_T InitialReserve; + PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; + SIZE_T Reserved[2]; +} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS; +#endif + /* Let Kernel Drivers use this */ #ifndef _WINBASE_ typedef struct _SYSTEMTIME diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index 54df02b6a88..428ddee88a4 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -96,7 +96,7 @@ typedef struct tagHEAP RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */ ULONG flags; /* Heap flags */ ULONG magic; /* Magic number */ - UCHAR filler[4]; /* Make multiple of 8 bytes */ + PRTL_HEAP_COMMIT_ROUTINE commitRoutine; } HEAP, *PHEAP; @@ -301,12 +301,19 @@ HEAP_Commit(SUBHEAP *subheap, address = (PVOID)((char *)subheap + subheap->commitSize); commitsize = size - subheap->commitSize; - Status = NtAllocateVirtualMemory(NtCurrentProcess(), - &address, - 0, - &commitsize, - MEM_COMMIT, - PAGE_EXECUTE_READWRITE); + if (subheap->heap->commitRoutine != NULL) + { + Status = subheap->heap->commitRoutine(subheap->heap, &address, &commitsize); + } + else + { + Status = NtAllocateVirtualMemory(NtCurrentProcess(), + &address, + 0, + &commitsize, + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + } if (!NT_SUCCESS(Status)) { DPRINT( "Could not commit %08lx bytes at %p for heap %p\n", @@ -321,6 +328,7 @@ HEAP_Commit(SUBHEAP *subheap, } +#if 0 /*********************************************************************** * HEAP_Decommit * @@ -356,7 +364,7 @@ static inline BOOLEAN HEAP_Decommit( SUBHEAP *subheap, PVOID ptr, ULONG flags ) subheap->commitSize -= decommitsize; return TRUE; } - +#endif /*********************************************************************** * HEAP_CreateFreeBlock @@ -504,27 +512,14 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, ULONG size) * HEAP_InitSubHeap */ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags, - ULONG commitSize, ULONG totalSize ) + ULONG commitSize, ULONG totalSize, + PRTL_HEAP_PARAMETERS Parameters ) { SUBHEAP *subheap = (SUBHEAP *)address; FREE_LIST_ENTRY *pEntry; int i; NTSTATUS Status; - /* Commit memory */ - Status = ZwAllocateVirtualMemory(NtCurrentProcess(), - &address, - 0, - (PULONG)&commitSize, - MEM_COMMIT, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Could not commit %08lx bytes for sub-heap %p\n", - commitSize, address); - return FALSE; - } - /* Fill the sub-heap structure */ subheap = (PSUBHEAP)address; @@ -550,6 +545,10 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags, heap->next = NULL; heap->flags = flags; heap->magic = HEAP_MAGIC; + if (Parameters) + heap->commitRoutine = Parameters->CommitRoutine; + else + heap->commitRoutine = NULL; /* Build the free lists */ @@ -570,6 +569,27 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags, RtlInitializeCriticalSection( &heap->critSection ); } + /* Commit memory */ + if (heap->commitRoutine) + { + Status = heap->commitRoutine(heap, &address, &commitSize); + } + else + { + Status = ZwAllocateVirtualMemory(NtCurrentProcess(), + &address, + 0, + &commitSize, + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("Could not commit %08lx bytes for sub-heap %p\n", + commitSize, address); + return FALSE; + } + /* Create the first free block */ HEAP_CreateFreeBlock( subheap, (PUCHAR)subheap + subheap->headerSize, @@ -586,8 +606,9 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags, */ static PSUBHEAP HEAP_CreateSubHeap(PVOID BaseAddress, - HEAP *heap, ULONG flags, - ULONG commitSize, ULONG totalSize ) + HEAP *heap, ULONG flags, + ULONG commitSize, ULONG totalSize, + PRTL_HEAP_PARAMETERS Parameters ) { PVOID address; NTSTATUS Status; @@ -621,8 +642,9 @@ HEAP_CreateSubHeap(PVOID BaseAddress, /* Initialize subheap */ - if (!HEAP_InitSubHeap( heap? heap : (HEAP *)address, - address, flags, commitSize, totalSize )) + if (!HEAP_InitSubHeap( heap ? heap : (HEAP *)address, + address, flags, commitSize, totalSize, + Parameters )) { if (!BaseAddress) { @@ -690,7 +712,7 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, ULONG size, * might get assigned all remaining free space in HEAP_ShrinkBlock() */ size += sizeof(SUBHEAP) + sizeof(ARENA_FREE) + HEAP_MIN_BLOCK_SIZE; if (!(subheap = HEAP_CreateSubHeap( NULL, heap, heap->flags, size, - max( HEAP_DEF_SIZE, size ) ))) + max( HEAP_DEF_SIZE, size ), NULL ))) return NULL; DPRINT("created new sub-heap %p of %08lx bytes for heap %p\n", @@ -1055,10 +1077,10 @@ static BOOLEAN HEAP_IsRealArena( HANDLE STDCALL RtlCreateHeap(ULONG flags, PVOID BaseAddress, - ULONG maxSize, - ULONG initialSize, - PVOID Unknown, - PRTL_HEAP_DEFINITION Definition) + SIZE_T maxSize, + SIZE_T initialSize, + PVOID Lock, + PRTL_HEAP_PARAMETERS Parameters) { SUBHEAP *subheap; HEAP *heapPtr; @@ -1070,20 +1092,24 @@ RtlCreateHeap(ULONG flags, maxSize = HEAP_DEF_SIZE; flags |= HEAP_GROWABLE; } - if (!(subheap = HEAP_CreateSubHeap( BaseAddress, NULL, flags, initialSize, maxSize ))) + if (!(subheap = HEAP_CreateSubHeap( BaseAddress, NULL, flags, initialSize, + maxSize, Parameters ))) { return 0; } - /* link it into the per-process heap list */ - RtlEnterCriticalSection (&RtlpProcessHeapsListLock); + if (RtlpGetMode() == UserMode) + { + /* link it into the per-process heap list */ + RtlEnterCriticalSection (&RtlpProcessHeapsListLock); - heapPtr = subheap->heap; - heapPtr->next = (HEAP*)NtCurrentPeb()->ProcessHeaps; - NtCurrentPeb()->ProcessHeaps = (HANDLE)heapPtr; - NtCurrentPeb()->NumberOfHeaps++; + heapPtr = subheap->heap; + heapPtr->next = (HEAP*)NtCurrentPeb()->ProcessHeaps; + NtCurrentPeb()->ProcessHeaps = (HANDLE)heapPtr; + NtCurrentPeb()->NumberOfHeaps++; - RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); + RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); + } return (HANDLE)subheap; } @@ -1112,18 +1138,21 @@ RtlDestroyHeap(HANDLE heap) /* [in] Handle of heap */ if (!heapPtr) return heap; - if (heap == NtCurrentPeb()->ProcessHeap) - return heap; /* cannot delete the main process heap */ + if (RtlpGetMode() == UserMode) + { + if (heap == NtCurrentPeb()->ProcessHeap) + return heap; /* cannot delete the main process heap */ - /* remove it from the per-process list */ - RtlEnterCriticalSection (&RtlpProcessHeapsListLock); + /* remove it from the per-process list */ + RtlEnterCriticalSection (&RtlpProcessHeapsListLock); - pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; - while (*pptr && *pptr != heapPtr) pptr = &(*pptr)->next; - if (*pptr) *pptr = (*pptr)->next; - NtCurrentPeb()->NumberOfHeaps--; + pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; + while (*pptr && *pptr != heapPtr) pptr = &(*pptr)->next; + if (*pptr) *pptr = (*pptr)->next; + NtCurrentPeb()->NumberOfHeaps--; - RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); + RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); + } RtlDeleteCriticalSection( &heapPtr->critSection ); subheap = &heapPtr->subheap; diff --git a/reactos/lib/rtl/ppb.c b/reactos/lib/rtl/ppb.c index a4867b1c1ec..ca4497a3cbb 100644 --- a/reactos/lib/rtl/ppb.c +++ b/reactos/lib/rtl/ppb.c @@ -22,11 +22,6 @@ #define DENORMALIZE(x,addr) {if(x) x=(PVOID)((ULONG_PTR)(x)-(ULONG_PTR)(addr));} #define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL))) - -KPROCESSOR_MODE -RtlpGetMode(); - - /* FUNCTIONS ****************************************************************/ diff --git a/reactos/lib/rtl/rtl.h b/reactos/lib/rtl/rtl.h index 4871621eb37..8d62277998a 100644 --- a/reactos/lib/rtl/rtl.h +++ b/reactos/lib/rtl/rtl.h @@ -29,6 +29,7 @@ extern VOID FASTCALL CHECK_PAGED_CODE_RTL(char *file, int line); extern PVOID RtlpAllocateMemory(UINT Bytes, ULONG Tag); extern VOID RtlpFreeMemory(PVOID Mem, ULONG Tag); +extern KPROCESSOR_MODE RtlpGetMode(); #define RtlpAllocateStringMemory RtlpAllocateMemory #define RtlpFreeStringMemory RtlpFreeMemory diff --git a/reactos/w32api/include/ddk/ntifs.h b/reactos/w32api/include/ddk/ntifs.h index 50ce7b86e58..6eb4dc1c78f 100644 --- a/reactos/w32api/include/ddk/ntifs.h +++ b/reactos/w32api/include/ddk/ntifs.h @@ -1486,6 +1486,27 @@ typedef struct _READ_LIST { #endif +typedef NTSTATUS +(NTAPI * PRTL_HEAP_COMMIT_ROUTINE) ( + IN PVOID Base, + IN OUT PVOID *CommitAddress, + IN OUT PSIZE_T CommitSize +); + +typedef struct _RTL_HEAP_PARAMETERS { + ULONG Length; + SIZE_T SegmentReserve; + SIZE_T SegmentCommit; + SIZE_T DeCommitFreeBlockThreshold; + SIZE_T DeCommitTotalFreeThreshold; + SIZE_T MaximumAllocationSize; + SIZE_T VirtualMemoryThreshold; + SIZE_T InitialCommit; + SIZE_T InitialReserve; + PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; + SIZE_T Reserved[2]; +} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS; + NTKERNELAPI BOOLEAN NTAPI @@ -2170,6 +2191,18 @@ FsRtlCopyWrite ( IN PDEVICE_OBJECT DeviceObject ); +NTKERNELAPI +PVOID +NTAPI +RtlCreateHeap ( + IN ULONG Flags, + IN PVOID HeapBase OPTIONAL, + IN SIZE_T ReserveSize OPTIONAL, + IN SIZE_T CommitSize OPTIONAL, + IN PVOID Lock OPTIONAL, + IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL +); + NTKERNELAPI BOOLEAN NTAPI @@ -2199,6 +2232,13 @@ FsRtlDeregisterUncProvider ( IN HANDLE Handle ); +NTKERNELAPI +PVOID +NTAPI +RtlDestroyHeap( + IN PVOID HeapHandle +); + NTKERNELAPI VOID NTAPI