sync with trunk (r49230)

svn path=/branches/cmake-bringup/; revision=49246
This commit is contained in:
Sylvain Petreolle 2010-10-23 22:14:59 +00:00
771 changed files with 118975 additions and 68781 deletions

View file

@ -27,6 +27,7 @@ list(APPEND SOURCE
generictable.c
handle.c
heap.c
heapdbg.c
image.c
interlck.c
message.c

View file

@ -541,9 +541,7 @@ Cleanup:
*/
NTSTATUS
NTAPI
RtlCreateSystemVolumeInformationFolder(
IN PUNICODE_STRING VolumeRootPath
)
RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
@ -679,8 +677,8 @@ NTSTATUS
NTAPI
RtlCreateBootStatusDataFile(VOID)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
@ -688,17 +686,15 @@ RtlCreateBootStatusDataFile(VOID)
*/
NTSTATUS
NTAPI
RtlGetSetBootStatusData(
HANDLE Filehandle,
BOOLEAN WriteMode,
DWORD DataClass,
PVOID Buffer,
ULONG BufferSize,
DWORD DataClass2
)
RtlGetSetBootStatusData(HANDLE Filehandle,
BOOLEAN WriteMode,
DWORD DataClass,
PVOID Buffer,
ULONG BufferSize,
DWORD DataClass2)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
@ -706,12 +702,10 @@ RtlGetSetBootStatusData(
*/
NTSTATUS
NTAPI
RtlLockBootStatusData(
HANDLE Filehandle
)
RtlLockBootStatusData(OUT PHANDLE Filehandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
@ -719,12 +713,10 @@ RtlLockBootStatusData(
*/
NTSTATUS
NTAPI
RtlUnlockBootStatusData(
HANDLE Filehandle
)
RtlUnlockBootStatusData(IN HANDLE Filehandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -85,15 +85,14 @@ static const ULONG CrcTable[256] =
* @implemented
*/
ULONG NTAPI
RtlComputeCrc32 (IN USHORT Initial,
IN PUCHAR Data,
IN ULONG Length)
RtlComputeCrc32(IN ULONG Initial,
IN PUCHAR Data,
IN ULONG Length)
{
ULONG CrcValue;
ULONG CrcValue = ~Initial;
DPRINT("(%lu,%p,%lu)\n", Initial, Data, Length);
DPRINT("(%d,%p,%d)\n", Initial, Data, Length);
CrcValue = ~Initial;
while (Length > 0)
{
CrcValue = CrcTable[(CrcValue ^ *Data) & 0xff] ^ (CrcValue >> 8);

View file

@ -150,7 +150,7 @@ typedef struct tagHEAP
{
SUBHEAP subheap; /* First sub-heap */
struct list entry; /* Entry in process heap list */
RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */
HEAP_LOCK lock; /* Critical section for serialization */
DECLSPEC_ALIGN(8) FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */
DWORD flags; /* Heap flags */
DWORD magic; /* Magic number */
@ -717,15 +717,15 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
{
if (!processHeap) /* do it by hand to avoid memory allocations */
{
heap->critSection.DebugInfo = &process_heap_critsect_debug;
heap->critSection.LockCount = -1;
heap->critSection.RecursionCount = 0;
heap->critSection.OwningThread = 0;
heap->critSection.LockSemaphore = 0;
heap->critSection.SpinCount = 0;
process_heap_critsect_debug.CriticalSection = &heap->critSection;
heap->lock.CriticalSection.DebugInfo = &process_heap_critsect_debug;
heap->lock.CriticalSection.LockCount = -1;
heap->lock.CriticalSection.RecursionCount = 0;
heap->lock.CriticalSection.OwningThread = 0;
heap->lock.CriticalSection.LockSemaphore = 0;
heap->lock.CriticalSection.SpinCount = 0;
process_heap_critsect_debug.CriticalSection = &heap->lock.CriticalSection;
}
else RtlInitializeHeapLock( &heap->critSection );
else RtlInitializeHeapLock( &heap->lock );
}
}
@ -1094,7 +1094,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
flags |= heapPtr->flags;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if (!(flags & HEAP_NO_SERIALIZE))
RtlEnterHeapLock( &heapPtr->critSection );
RtlEnterHeapLock( &heapPtr->lock );
if (block)
{
@ -1113,7 +1113,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
ret = HEAP_ValidateInUseArena( subheap, (const ARENA_INUSE *)block - 1, quiet );
if (!(flags & HEAP_NO_SERIALIZE))
RtlLeaveHeapLock( &heapPtr->critSection );
RtlLeaveHeapLock( &heapPtr->lock );
return ret;
}
@ -1143,7 +1143,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
subheap = subheap->next;
}
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
return ret;
}
@ -1181,9 +1181,9 @@ RtlCreateHeap(ULONG flags,
if (processHeap)
{
HEAP *heapPtr = subheap->heap;
RtlEnterHeapLock( &processHeap->critSection );
RtlEnterHeapLock( &processHeap->lock );
list_add_head( &processHeap->entry, &heapPtr->entry );
RtlLeaveHeapLock( &processHeap->critSection );
RtlLeaveHeapLock( &processHeap->lock );
}
else
{
@ -1224,12 +1224,12 @@ RtlDestroyHeap(HANDLE heap) /* [in] Handle of heap */
return heap; /* cannot delete the main process heap */
/* remove it from the per-process list */
RtlEnterHeapLock( &processHeap->critSection );
RtlEnterHeapLock( &processHeap->lock );
list_remove( &heapPtr->entry );
RtlLeaveHeapLock( &processHeap->critSection );
RtlLeaveHeapLock( &processHeap->lock );
}
RtlDeleteHeapLock( &heapPtr->critSection );
RtlDeleteHeapLock( &heapPtr->lock );
subheap = &heapPtr->subheap;
while (subheap)
{
@ -1281,13 +1281,13 @@ RtlAllocateHeap(HANDLE heap, /* [in] Handle of private heap block */
if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
/* Locate a suitable free block */
if (!(pArena = HEAP_FindFreeBlock( heapPtr, rounded_size, &subheap )))
{
TRACE("(%p,%08lx,%08lx): returning NULL\n",
heap, flags, size );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
return NULL;
}
@ -1319,7 +1319,7 @@ RtlAllocateHeap(HANDLE heap, /* [in] Handle of private heap block */
else
mark_block_uninitialized( pInUse + 1, pInUse->size & ARENA_SIZE_MASK );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%08lx): returning %p\n", heap, flags, size, pInUse + 1 );
return (LPVOID)(pInUse + 1);
@ -1357,10 +1357,10 @@ BOOLEAN NTAPI RtlFreeHeap(
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08lx,%p): returning FALSE\n", heap, flags, ptr );
return FALSE;
@ -1376,13 +1376,13 @@ BOOLEAN NTAPI RtlFreeHeap(
HEAP_MakeInUseBlockFree( subheap, pInUse );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p): returning TRUE\n", heap, flags, ptr );
return TRUE;
error:
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p): returning FALSE\n", heap, flags, ptr );
return FALSE;
@ -1427,7 +1427,7 @@ PVOID NTAPI RtlReAllocateHeap(
//Flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY |
// HEAP_REALLOC_IN_PLACE_ONLY;
flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
rounded_size = ROUND_SIZE(size);
if (rounded_size < size) goto oom; /* overflow */
@ -1510,19 +1510,19 @@ PVOID NTAPI RtlReAllocateHeap(
/* Return the new arena */
done:
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p,%08lx): returning %p\n", heap, flags, ptr, size, pArena + 1 );
return (LPVOID)(pArena + 1);
oom:
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_NO_MEMORY );
TRACE("(%p,%08x,%p,%08lx): returning oom\n", heap, flags, ptr, size );
return NULL;
error:
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p,%08lx): returning error\n", heap, flags, ptr, size );
return NULL;
@ -1562,7 +1562,7 @@ RtlLockHeap(IN HANDLE Heap)
HEAP *heapPtr = HEAP_GetPtr( Heap );
if (!heapPtr)
return FALSE;
RtlEnterHeapLock( &heapPtr->critSection );
RtlEnterHeapLock( &heapPtr->lock );
return TRUE;
}
@ -1586,7 +1586,7 @@ RtlUnlockHeap(HANDLE Heap)
HEAP *heapPtr = HEAP_GetPtr( Heap );
if (!heapPtr)
return FALSE;
RtlLeaveHeapLock( &heapPtr->critSection );
RtlLeaveHeapLock( &heapPtr->lock );
return TRUE;
}
@ -1621,7 +1621,7 @@ RtlSizeHeap(
}
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
@ -1632,12 +1632,29 @@ RtlSizeHeap(
const ARENA_INUSE *pArena = (const ARENA_INUSE *)ptr - 1;
ret = (pArena->size & ARENA_SIZE_MASK) - pArena->unused_bytes;
}
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p): returning %08lx\n", heap, flags, ptr, ret );
return ret;
}
BOOLEAN NTAPI
RtlpValidateHeap(HEAP * Heap, BOOLEAN ForceValidation)
{
return HEAP_IsRealArena(Heap, Heap->flags, NULL, TRUE);
}
BOOLEAN NTAPI
RtlpValidateHeapHeaders(HEAP * Heap, BOOLEAN Recalculate)
{
return TRUE;
}
BOOLEAN NTAPI
RtlpValidateHeapEntry(HEAP * Heap, PVOID HeapEntry)
{
return TRUE;
}
/***********************************************************************
* RtlValidateHeap
@ -1694,7 +1711,7 @@ RtlEnumProcessHeaps(PHEAP_ENUMERATION_ROUTINE HeapEnumerationRoutine,
NTSTATUS Status = STATUS_SUCCESS;
struct list *ptr=NULL;
RtlEnterHeapLock(&processHeap->critSection);
RtlEnterHeapLock(&processHeap->lock);
Status=HeapEnumerationRoutine(processHeap,lParam);
LIST_FOR_EACH( ptr, &processHeap->entry )
@ -1703,7 +1720,7 @@ RtlEnumProcessHeaps(PHEAP_ENUMERATION_ROUTINE HeapEnumerationRoutine,
Status = HeapEnumerationRoutine(ptr,lParam);
}
RtlLeaveHeapLock(&processHeap->critSection);
RtlLeaveHeapLock(&processHeap->lock);
return Status;
}
@ -1719,7 +1736,7 @@ RtlGetProcessHeaps(ULONG count,
ULONG total = 1; /* main heap */
struct list *ptr;
ULONG i=0;
RtlEnterHeapLock( &processHeap->critSection );
RtlEnterHeapLock( &processHeap->lock );
LIST_FOR_EACH( ptr, &processHeap->entry ) total++;
//if (total <= count)
{
@ -1732,7 +1749,7 @@ RtlGetProcessHeaps(ULONG count,
*(heaps++) = LIST_ENTRY( ptr, HEAP, entry );
}
}
RtlLeaveHeapLock( &processHeap->critSection );
RtlLeaveHeapLock( &processHeap->lock );
return i;
}
@ -1746,7 +1763,7 @@ RtlValidateProcessHeaps(VOID)
BOOLEAN Result = TRUE;
HEAP ** pptr;
RtlEnterHeapLock( &processHeap->critSection );
RtlEnterHeapLock( &processHeap->lock );
for (pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; *pptr; pptr++)
{
@ -1757,7 +1774,7 @@ RtlValidateProcessHeaps(VOID)
}
}
RtlLeaveHeapLock( &processHeap->critSection );
RtlLeaveHeapLock( &processHeap->lock );
return Result;
}
@ -1812,7 +1829,8 @@ NTAPI
RtlSetUserFlagsHeap(IN PVOID HeapHandle,
IN ULONG Flags,
IN PVOID BaseAddress,
IN ULONG UserFlags)
IN ULONG UserFlagsReset,
IN ULONG UserFlagsSet)
{
HEAP *heapPtr;
PHEAP_USER_DATA udata;
@ -1829,7 +1847,7 @@ RtlSetUserFlagsHeap(IN PVOID HeapHandle,
udata = HEAP_AllocUserData(heapPtr, BaseAddress);
if (!udata) return FALSE;
}
udata->UserFlags = UserFlags & HEAP_SETTABLE_USER_FLAGS;
udata->UserFlags = UserFlagsSet & HEAP_SETTABLE_USER_FLAGS;
return TRUE;
}
@ -1933,7 +1951,7 @@ RtlProtectHeap(IN PVOID HeapHandle,
return NULL;
}
DWORD
NTSTATUS
NTAPI
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
IN HEAP_INFORMATION_CLASS HeapInformationClass,
@ -1944,7 +1962,7 @@ RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
return 0;
}
DWORD
NTSTATUS
NTAPI
RtlQueryHeapInformation(HANDLE HeapHandle,
HEAP_INFORMATION_CLASS HeapInformationClass,
@ -1978,23 +1996,23 @@ RtlQueryHeapInformation(HANDLE HeapHandle,
}
}
DWORD
NTSTATUS
NTAPI
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
IN DWORD Flags,
IN ULONG Flags,
IN SIZE_T Size,
IN DWORD Count,
IN ULONG Count,
OUT PVOID *Array)
{
UNIMPLEMENTED;
return 0;
}
DWORD
NTSTATUS
NTAPI
RtlMultipleFreeHeap(IN PVOID HeapHandle,
IN DWORD Flags,
IN DWORD Count,
IN ULONG Flags,
IN ULONG Count,
OUT PVOID *Array)
{
UNIMPLEMENTED;

396
lib/rtl/heap.h Normal file
View file

@ -0,0 +1,396 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS System Libraries
* FILE: lib/rtl/heap.h
* PURPOSE: Run-Time Libary Heap Manager header
* PROGRAMMER: Aleksey Bragin
*/
/* INCLUDES ******************************************************************/
#ifndef RTL_HEAP_H
#define RTL_HEAP_H
/* Core heap definitions */
#define HEAP_FREELISTS 128
#define HEAP_SEGMENTS 64
#define HEAP_ENTRY_SIZE ((ULONG)sizeof(HEAP_ENTRY))
#ifdef _WIN64
#define HEAP_ENTRY_SHIFT 4
#else
#define HEAP_ENTRY_SHIFT 3
#endif
#define HEAP_MAX_BLOCK_SIZE ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
#define ARENA_INUSE_FILLER 0xBAADF00D
#define ARENA_FREE_FILLER 0xFEEEFEEE
#define HEAP_TAIL_FILL 0xab
// from ntifs.h, should go to another header!
#define HEAP_GLOBAL_TAG 0x0800
#define HEAP_PSEUDO_TAG_FLAG 0x8000
#define HEAP_TAG_MASK (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
#define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \
HEAP_SETTABLE_USER_VALUE | \
(HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT)))
/* Heap entry flags */
#define HEAP_ENTRY_BUSY 0x01
#define HEAP_ENTRY_EXTRA_PRESENT 0x02
#define HEAP_ENTRY_FILL_PATTERN 0x04
#define HEAP_ENTRY_VIRTUAL_ALLOC 0x08
#define HEAP_ENTRY_LAST_ENTRY 0x10
#define HEAP_ENTRY_SETTABLE_FLAG1 0x20
#define HEAP_ENTRY_SETTABLE_FLAG2 0x40
#define HEAP_ENTRY_SETTABLE_FLAG3 0x80
#define HEAP_ENTRY_SETTABLE_FLAGS (HEAP_ENTRY_SETTABLE_FLAG1 | HEAP_ENTRY_SETTABLE_FLAG2 | HEAP_ENTRY_SETTABLE_FLAG3)
/* Signatures */
#define HEAP_SIGNATURE 0xeefeeff
#define HEAP_SEGMENT_SIGNATURE 0xffeeffee
/* Segment flags */
#define HEAP_USER_ALLOCATED 0x1
/* A handy inline to distinguis normal heap, special "debug heap" and special "page heap" */
FORCEINLINE BOOLEAN
RtlpHeapIsSpecial(ULONG Flags)
{
if (Flags & HEAP_SKIP_VALIDATION_CHECKS) return FALSE;
if (Flags & (HEAP_FLAG_PAGE_ALLOCS |
HEAP_VALIDATE_ALL_ENABLED |
HEAP_VALIDATE_PARAMETERS_ENABLED |
HEAP_CAPTURE_STACK_BACKTRACES |
HEAP_CREATE_ENABLE_TRACING))
{
/* This is a special heap */
return TRUE;
}
/* No need for a special treatment */
return FALSE;
}
/* Heap structures */
struct _HEAP_COMMON_ENTRY
{
union
{
struct
{
USHORT Size;
UCHAR Flags;
UCHAR SmallTagIndex;
};
struct
{
PVOID SubSegmentCode;
USHORT PreviousSize;
union
{
UCHAR SegmentOffset;
UCHAR LFHFlags;
};
UCHAR UnusedBytes;
};
struct
{
USHORT FunctionIndex;
USHORT ContextValue;
};
struct
{
ULONG InterceptorValue;
USHORT UnusedBytesLength;
UCHAR EntryOffset;
UCHAR ExtendedBlockSignature;
};
struct
{
ULONG Code1;
USHORT Code2;
UCHAR Code3;
UCHAR Code4;
};
ULONGLONG AgregateCode;
};
};
typedef struct _HEAP_FREE_ENTRY
{
struct _HEAP_COMMON_ENTRY;
LIST_ENTRY FreeList;
} HEAP_FREE_ENTRY, *PHEAP_FREE_ENTRY;
typedef struct _HEAP_ENTRY
{
struct _HEAP_COMMON_ENTRY;
} HEAP_ENTRY, *PHEAP_ENTRY;
#ifdef _WIN64
C_ASSERT(sizeof(HEAP_ENTRY) == 16);
#else
C_ASSERT(sizeof(HEAP_ENTRY) == 8);
#endif
C_ASSERT((1 << HEAP_ENTRY_SHIFT) == sizeof(HEAP_ENTRY));
typedef struct _HEAP_TAG_ENTRY
{
ULONG Allocs;
ULONG Frees;
ULONG Size;
USHORT TagIndex;
USHORT CreatorBackTraceIndex;
WCHAR TagName[24];
} HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY;
typedef struct _HEAP_PSEUDO_TAG_ENTRY
{
ULONG Allocs;
ULONG Frees;
ULONG Size;
} HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
typedef struct _HEAP_COUNTERS
{
ULONG TotalMemoryReserved;
ULONG TotalMemoryCommitted;
ULONG TotalMemoryLargeUCR;
ULONG TotalSizeInVirtualBlocks;
ULONG TotalSegments;
ULONG TotalUCRs;
ULONG CommittOps;
ULONG DeCommitOps;
ULONG LockAcquires;
ULONG LockCollisions;
ULONG CommitRate;
ULONG DecommittRate;
ULONG CommitFailures;
ULONG InBlockCommitFailures;
ULONG CompactHeapCalls;
ULONG CompactedUCRs;
ULONG InBlockDeccommits;
ULONG InBlockDeccomitSize;
} HEAP_COUNTERS, *PHEAP_COUNTERS;
typedef struct _HEAP_TUNING_PARAMETERS
{
ULONG CommittThresholdShift;
ULONG MaxPreCommittThreshold;
} HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS;
typedef struct _HEAP
{
HEAP_ENTRY Entry;
ULONG SegmentSignature;
ULONG SegmentFlags;
LIST_ENTRY SegmentListEntry;
struct _HEAP *Heap;
PVOID BaseAddress;
ULONG NumberOfPages;
PHEAP_ENTRY FirstEntry;
PHEAP_ENTRY LastValidEntry;
ULONG NumberOfUnCommittedPages;
ULONG NumberOfUnCommittedRanges;
USHORT SegmentAllocatorBackTraceIndex;
USHORT Reserved;
LIST_ENTRY UCRSegmentList;
ULONG Flags;
ULONG ForceFlags;
ULONG CompatibilityFlags;
ULONG EncodeFlagMask;
HEAP_ENTRY Encoding;
ULONG PointerKey;
ULONG Interceptor;
ULONG VirtualMemoryThreshold;
ULONG Signature;
ULONG SegmentReserve;
ULONG SegmentCommit;
ULONG DeCommitFreeBlockThreshold;
ULONG DeCommitTotalFreeThreshold;
ULONG TotalFreeSize;
ULONG MaximumAllocationSize;
USHORT ProcessHeapsListIndex;
USHORT HeaderValidateLength;
PVOID HeaderValidateCopy;
USHORT NextAvailableTagIndex;
USHORT MaximumTagIndex;
PHEAP_TAG_ENTRY TagEntries;
LIST_ENTRY UCRList;
LIST_ENTRY UCRSegments; // FIXME: non-Vista
ULONG AlignRound;
ULONG AlignMask;
LIST_ENTRY VirtualAllocdBlocks;
LIST_ENTRY SegmentList;
struct _HEAP_SEGMENT *Segments[HEAP_SEGMENTS]; //FIXME: non-Vista
USHORT AllocatorBackTraceIndex;
ULONG NonDedicatedListLength;
PVOID BlocksIndex;
PVOID UCRIndex;
PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
LIST_ENTRY FreeLists[HEAP_FREELISTS]; //FIXME: non-Vista
union
{
ULONG FreeListsInUseUlong[HEAP_FREELISTS / (sizeof(ULONG) * 8)]; //FIXME: non-Vista
UCHAR FreeListsInUseBytes[HEAP_FREELISTS / (sizeof(UCHAR) * 8)]; //FIXME: non-Vista
} u;
PHEAP_LOCK LockVariable;
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
PVOID FrontEndHeap;
USHORT FrontHeapLockCount;
UCHAR FrontEndHeapType;
HEAP_COUNTERS Counters;
HEAP_TUNING_PARAMETERS TuningParameters;
} HEAP, *PHEAP;
typedef struct _HEAP_SEGMENT
{
HEAP_ENTRY Entry;
ULONG SegmentSignature;
ULONG SegmentFlags;
LIST_ENTRY SegmentListEntry;
PHEAP Heap;
PVOID BaseAddress;
ULONG NumberOfPages;
PHEAP_ENTRY FirstEntry;
PHEAP_ENTRY LastValidEntry;
ULONG NumberOfUnCommittedPages;
ULONG NumberOfUnCommittedRanges;
USHORT SegmentAllocatorBackTraceIndex;
USHORT Reserved;
LIST_ENTRY UCRSegmentList;
PHEAP_ENTRY LastEntryInSegment; //FIXME: non-Vista
} HEAP_SEGMENT, *PHEAP_SEGMENT;
typedef struct _HEAP_UCR_DESCRIPTOR
{
LIST_ENTRY ListEntry;
LIST_ENTRY SegmentEntry;
PVOID Address;
ULONG Size;
} HEAP_UCR_DESCRIPTOR, *PHEAP_UCR_DESCRIPTOR;
typedef struct _HEAP_UCR_SEGMENT
{
LIST_ENTRY ListEntry;
SIZE_T ReservedSize;
SIZE_T CommittedSize;
} HEAP_UCR_SEGMENT, *PHEAP_UCR_SEGMENT;
typedef struct _HEAP_ENTRY_EXTRA
{
union
{
struct
{
USHORT AllocatorBackTraceIndex;
USHORT TagIndex;
ULONG_PTR Settable;
};
UINT64 ZeroInit;
};
} HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA, *PHEAP_FREE_ENTRY_EXTRA;
typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
{
LIST_ENTRY Entry;
HEAP_ENTRY_EXTRA ExtraStuff;
ULONG CommitSize;
ULONG ReserveSize;
HEAP_ENTRY BusyBlock;
} HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
/* Global variables */
extern HEAP_LOCK RtlpProcessHeapsListLock;
extern BOOLEAN RtlpPageHeapEnabled;
/* Functions declarations */
/* heap.c */
PHEAP_FREE_ENTRY NTAPI
RtlpCoalesceFreeBlocks (PHEAP Heap,
PHEAP_FREE_ENTRY FreeEntry,
PSIZE_T FreeSize,
BOOLEAN Remove);
PHEAP_ENTRY_EXTRA NTAPI
RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
BOOLEAN NTAPI
RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation);
BOOLEAN NTAPI
RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry);
BOOLEAN NTAPI
RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate);
/* heapdbg.c */
HANDLE NTAPI
RtlDebugCreateHeap(ULONG Flags,
PVOID Addr,
SIZE_T TotalSize,
SIZE_T CommitSize,
PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters);
BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr);
PVOID NTAPI
RtlDebugAllocateHeap(PVOID HeapPtr,
ULONG Flags,
SIZE_T Size);
PVOID NTAPI
RtlDebugReAllocateHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr,
SIZE_T Size);
BOOLEAN NTAPI
RtlDebugFreeHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr);
BOOLEAN NTAPI
RtlDebugGetUserInfoHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
PVOID *UserValue,
PULONG UserFlags);
BOOLEAN NTAPI
RtlDebugSetUserValueHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
PVOID UserValue);
BOOLEAN
NTAPI
RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
ULONG UserFlagsReset,
ULONG UserFlagsSet);
SIZE_T NTAPI
RtlDebugSizeHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr);
HANDLE NTAPI
RtlpPageHeapCreate(ULONG Flags,
PVOID Addr,
SIZE_T TotalSize,
SIZE_T CommitSize,
PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters);
#endif

4138
lib/rtl/heap_rewrite.c Normal file

File diff suppressed because it is too large Load diff

565
lib/rtl/heapdbg.c Normal file
View file

@ -0,0 +1,565 @@
/*
* PROJECT: ReactOS Runtime Library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/rtl/heapdbg.c
* PURPOSE: Heap manager debug heap
* PROGRAMMERS: Copyright 2010 Aleksey Bragin
*/
/* INCLUDES ******************************************************************/
#include <rtl.h>
#include <heap.h>
#define NDEBUG
#include <debug.h>
BOOLEAN RtlpPageHeapEnabled = FALSE;
ULONG RtlpPageHeapGlobalFlags;
ULONG RtlpPageHeapSizeRangeStart, RtlpPageHeapSizeRangeEnd;
ULONG RtlpPageHeapDllRangeStart, RtlpPageHeapDllRangeEnd;
WCHAR RtlpPageHeapTargetDlls[512];
/* FUNCTIONS ******************************************************************/
HANDLE NTAPI
RtlDebugCreateHeap(ULONG Flags,
PVOID Addr,
SIZE_T ReserveSize,
SIZE_T CommitSize,
PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters)
{
MEMORY_BASIC_INFORMATION MemoryInfo;
NTSTATUS Status;
PHEAP Heap;
/* Validate parameters */
if (ReserveSize <= HEAP_ENTRY_SIZE)
{
DPRINT1("HEAP: Incorrect ReserveSize %x\n", ReserveSize);
return NULL;
}
if (ReserveSize < CommitSize)
{
DPRINT1("HEAP: Incorrect CommitSize %x\n", CommitSize);
return NULL;
}
if (Flags & HEAP_NO_SERIALIZE && Lock)
{
DPRINT1("HEAP: Can't specify Lock routine and have HEAP_NO_SERIALIZE flag set\n");
return NULL;
}
/* If the address is specified, check it's virtual memory */
if (Addr)
{
Status = ZwQueryVirtualMemory(NtCurrentProcess(),
Addr,
MemoryBasicInformation,
&MemoryInfo,
sizeof(MemoryInfo),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("HEAP: Specified heap base address %p is invalid, Status 0x%08X\n", Addr, Status);
return NULL;
}
if (MemoryInfo.BaseAddress != Addr)
{
DPRINT1("HEAP: Specified heap base address %p is not really a base one %p\n", Addr, MemoryInfo.BaseAddress);
return NULL;
}
if (MemoryInfo.State == MEM_FREE)
{
DPRINT1("HEAP: Specified heap base address %p is free\n", Addr);
return NULL;
}
}
/* All validation performed, now call the real routine with skip validation check flag */
Flags |= HEAP_SKIP_VALIDATION_CHECKS |
HEAP_TAIL_CHECKING_ENABLED |
HEAP_FREE_CHECKING_ENABLED;
Heap = RtlCreateHeap(Flags, Addr, ReserveSize, CommitSize, Lock, Parameters);
if (!Heap) return NULL;
// FIXME: Capture stack backtrace
RtlpValidateHeapHeaders(Heap, TRUE);
return Heap;
}
BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr)
{
SIZE_T Size;
PHEAP Heap = (PHEAP)HeapPtr;
if (Heap == RtlGetCurrentPeb()->ProcessHeap)
{
DPRINT1("HEAP: It's forbidden delete process heap!");
return FALSE;
}
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
if (!RtlpValidateHeap(Heap, FALSE)) return FALSE;
/* Make heap invalid by zeroing its signature */
Heap->Signature = 0;
/* Free validate headers copy if it was existing */
if (Heap->HeaderValidateCopy)
{
ZwFreeVirtualMemory(NtCurrentProcess(),
&Heap->HeaderValidateCopy,
&Size,
MEM_RELEASE);
}
return TRUE;
}
PVOID NTAPI
RtlDebugAllocateHeap(PVOID HeapPtr,
ULONG Flags,
SIZE_T Size)
{
PHEAP Heap = (PHEAP)HeapPtr;
SIZE_T AllocSize = 1;
BOOLEAN HeapLocked = FALSE;
PVOID Result;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapAllocateHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return NULL;
}
/* Add settable user value flag */
Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS;
/* Calculate size */
if (Size) AllocSize = Size;
AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
/* Check if size didn't exceed max one */
if (AllocSize < Size ||
AllocSize > Heap->MaximumAllocationSize)
{
DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
return NULL;
}
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Call main routine to do the stuff */
Result = RtlAllocateHeap(HeapPtr, Flags, Size);
/* Validate heap headers */
RtlpValidateHeapHeaders(Heap, TRUE);
if (Result)
{
if (Heap->Flags & HEAP_VALIDATE_ALL_ENABLED)
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
PVOID NTAPI
RtlDebugReAllocateHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr,
SIZE_T Size)
{
PHEAP Heap = (PHEAP)HeapPtr;
SIZE_T AllocSize = 1;
BOOLEAN HeapLocked = FALSE;
PVOID Result = NULL;
PHEAP_ENTRY HeapEntry;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapReAllocateHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return NULL;
}
/* Add settable user value flag */
Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS;
/* Calculate size */
if (Size) AllocSize = Size;
AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
/* Check if size didn't exceed max one */
if (AllocSize < Size ||
AllocSize > Heap->MaximumAllocationSize)
{
DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
return NULL;
}
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* Call main routine to do the stuff */
Result = RtlReAllocateHeap(HeapPtr, Flags, Ptr, Size);
if (Result)
{
/* Validate heap headers and then heap itself */
RtlpValidateHeapHeaders(Heap, TRUE);
RtlpValidateHeap(Heap, FALSE);
}
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
BOOLEAN NTAPI
RtlDebugFreeHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr)
{
PHEAP Heap = (PHEAP)HeapPtr;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapFreeHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlFreeHeap(HeapPtr, Flags, Ptr);
/* Validate heap headers and then heap itself */
RtlpValidateHeapHeaders(Heap, TRUE);
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
BOOLEAN NTAPI
RtlDebugGetUserInfoHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
PVOID *UserValue,
PULONG UserFlags)
{
PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapGetUserInfoHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlGetUserInfoHeap(HeapHandle, Flags, BaseAddress, UserValue, UserFlags);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
BOOLEAN NTAPI
RtlDebugSetUserValueHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
PVOID UserValue)
{
PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapSetUserValueHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSetUserValueHeap(HeapHandle, Flags, BaseAddress, UserValue);
/* Validate the heap */
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
BOOLEAN
NTAPI
RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
ULONG Flags,
PVOID BaseAddress,
ULONG UserFlagsReset,
ULONG UserFlagsSet)
{
PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlPageHeapSetUserFlagsHeap(HeapPtr, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
/* Check if this heap allows flags to be set at all */
if (UserFlagsSet & ~HEAP_SETTABLE_USER_FLAGS ||
UserFlagsReset & ~HEAP_SETTABLE_USER_FLAGS)
{
return FALSE;
}
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSetUserFlagsHeap(HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
/* Validate the heap */
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
SIZE_T NTAPI
RtlDebugSizeHeap(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr)
{
PHEAP Heap = (PHEAP)HeapPtr;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
SIZE_T Result = ~(SIZE_T)0;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlPageHeapSizeHeap(HeapPtr, Flags, Ptr);
/* Check heap signature */
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSizeHeap(HeapPtr, Flags, Ptr);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
}
// Page heap -> move to another file
HANDLE NTAPI
RtlpPageHeapCreate(ULONG Flags,
PVOID Addr,
SIZE_T TotalSize,
SIZE_T CommitSize,
PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters)
{
return NULL;
}
/* EOF */

View file

@ -16,6 +16,9 @@
* RtlInterlockedPopEntrySList(
* IN PSLIST_HEADER ListHead);
*/
.global _ExpInterlockedPopEntrySListResume@0
.global _ExpInterlockedPopEntrySListEnd@0
.global _ExpInterlockedPopEntrySListFault@0
.global _RtlInterlockedPopEntrySList@4
_RtlInterlockedPopEntrySList@4:
@ -25,7 +28,7 @@ _RtlInterlockedPopEntrySList@4:
/* Load ListHead into ebp */
mov ebp, [esp + 12]
_ExpInterlockedPopEntrySListResume@0:
/* Load ListHead->Next into eax */
mov eax, [ebp]
@ -40,14 +43,15 @@ _RtlInterlockedPopEntrySList@4:
/* Copy Depth and Sequence number and adjust Depth */
lea ecx, [edx - 1]
_ExpInterlockedPopEntrySListFault@0:
/* Get next pointer */
mov ebx, [eax]
_ExpInterlockedPopEntrySListEnd@0:
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
lock cmpxchg8b [ebp]
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz 1b
jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
2:
@ -89,7 +93,7 @@ _RtlInterlockedPushEntrySList@8:
lea ecx, [edx + 0x10001]
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
lock cmpxchg8b [ebp]
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz 1b
@ -136,7 +140,7 @@ _RtlInterlockedFlushSList@4:
xor cx, cx
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
lock cmpxchg8b [ebp]
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz 1b

View file

@ -53,9 +53,7 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
PUNICODE_STRING ShellInfo,
PUNICODE_STRING RuntimeData)
{
NTSTATUS Status = STATUS_SUCCESS;
PRTL_USER_PROCESS_PARAMETERS Param = NULL;
SIZE_T RegionSize = 0;
ULONG Length = 0;
PWCHAR Dest;
UNICODE_STRING EmptyString;
@ -121,23 +119,16 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
Length += ALIGN(RuntimeData->MaximumLength, sizeof(ULONG));
/* Calculate the required block size */
RegionSize = ROUND_UP(Length, PAGE_SIZE);
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
(PVOID*)&Param,
0,
&RegionSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
Param = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
if (!Param)
{
RtlReleasePebLock();
return Status;
return STATUS_INSUFFICIENT_RESOURCES;
}
DPRINT ("Process parameters allocated\n");
Param->MaximumLength = RegionSize;
Param->MaximumLength = Length;
Param->Length = Length;
Param->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED;
Param->Environment = Environment;
@ -219,15 +210,12 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
/*
* @implemented
*/
NTSTATUS NTAPI
RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSTATUS
NTAPI
RtlDestroyProcessParameters(IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
{
SIZE_T RegionSize = 0;
return ZwFreeVirtualMemory (NtCurrentProcess (),
(PVOID)ProcessParameters,
&RegionSize,
MEM_RELEASE);
RtlFreeHeap(RtlGetProcessHeap(), 0, ProcessParameters);
return STATUS_SUCCESS;
}
/*

View file

@ -27,10 +27,10 @@ extern VOID FASTCALL CHECK_PAGED_CODE_RTL(char *file, int line);
#endif
#define ROUND_DOWN(n, align) \
(((ULONG)n) & ~((align) - 1l))
(((ULONG)(n)) & ~((align) - 1l))
#define ROUND_UP(n, align) \
ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
ROUND_DOWN(((ULONG)(n)) + (align) - 1, (align))
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
@ -86,19 +86,19 @@ RtlpCaptureStackLimits(
NTSTATUS
NTAPI
RtlDeleteHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
RtlDeleteHeapLock(PHEAP_LOCK Lock);
NTSTATUS
NTAPI
RtlEnterHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
RtlEnterHeapLock(PHEAP_LOCK Lock);
NTSTATUS
NTAPI
RtlInitializeHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
RtlInitializeHeapLock(PHEAP_LOCK Lock);
NTSTATUS
NTAPI
RtlLeaveHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
RtlLeaveHeapLock(PHEAP_LOCK Lock);
BOOLEAN
NTAPI