windows-nt/Source/XPSP1/NT/base/win32/client/lmem.c
2020-09-26 16:20:57 +08:00

1027 lines
25 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
lmem.c
Abstract:
This module contains the Win32 Local Memory Management APIs
Author:
Steve Wood (stevewo) 24-Sep-1990
Revision History:
--*/
#include "basedll.h"
void
BaseDllInitializeMemoryManager( VOID )
{
BaseHeap = RtlProcessHeap();
RtlInitializeHandleTable( 0xFFFF,
sizeof( BASE_HANDLE_TABLE_ENTRY ),
&BaseHeapHandleTable
);
NtQuerySystemInformation(SystemRangeStartInformation,
&SystemRangeStart,
sizeof(SystemRangeStart),
NULL);
}
#if i386
#pragma optimize("y",off)
#endif
HLOCAL
WINAPI
LocalAlloc(
UINT uFlags,
SIZE_T uBytes
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
HANDLE hMem;
ULONG Flags;
LPSTR p;
if (uFlags & ~LMEM_VALID_FLAGS) {
SetLastError( ERROR_INVALID_PARAMETER );
return( NULL );
}
Flags = 0;
if (uFlags & LMEM_ZEROINIT) {
Flags |= HEAP_ZERO_MEMORY;
}
if (!(uFlags & LMEM_MOVEABLE)) {
p = RtlAllocateHeap( BaseHeap,
MAKE_TAG( LMEM_TAG ) | Flags,
uBytes
);
if (p == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
return( p );
}
RtlLockHeap( BaseHeap );
Flags |= HEAP_NO_SERIALIZE | HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVEABLE;
try {
p = NULL;
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)RtlAllocateHandle( &BaseHeapHandleTable, NULL );
if (HandleEntry == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
goto Fail;
}
hMem = (HANDLE)&HandleEntry->Object;
if (uBytes != 0) {
p = (LPSTR)RtlAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, uBytes );
if (p == NULL) {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
HandleEntry = NULL;
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
else {
RtlSetUserValueHeap( BaseHeap, HEAP_NO_SERIALIZE, p, hMem );
}
}
else {
p = NULL;
}
Fail: ;
}
except (EXCEPTION_EXECUTE_HANDLER) {
p = NULL;
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
if (HandleEntry != NULL) {
if (HandleEntry->Object = p) {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
}
else {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED | BASE_HANDLE_DISCARDED;
}
if (uFlags & LMEM_DISCARDABLE) {
HandleEntry->Flags |= BASE_HANDLE_DISCARDABLE;
}
if (uFlags & LMEM_MOVEABLE) {
HandleEntry->Flags |= BASE_HANDLE_MOVEABLE;
}
p = (LPSTR)hMem;
}
return( (HANDLE)p );
}
HLOCAL
WINAPI
LocalReAlloc(
HLOCAL hMem,
SIZE_T uBytes,
UINT uFlags
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
LPSTR p;
ULONG Flags;
if ((uFlags & ~(LMEM_VALID_FLAGS | LMEM_MODIFY)) ||
((uFlags & LMEM_DISCARDABLE) && !(uFlags & LMEM_MODIFY))
) {
#if DBG
DbgPrint( "*** LocalReAlloc( %lx ) - invalid flags\n", uFlags );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_PARAMETER );
return( NULL );
}
Flags = 0;
if (uFlags & LMEM_ZEROINIT) {
Flags |= HEAP_ZERO_MEMORY;
}
if (!(uFlags & LMEM_MOVEABLE)) {
Flags |= HEAP_REALLOC_IN_PLACE_ONLY;
}
RtlLockHeap( BaseHeap );
Flags |= HEAP_NO_SERIALIZE;
try {
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
#if DBG
DbgPrint( "*** LocalReAlloc( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
hMem = NULL;
}
else
if (uFlags & LMEM_MODIFY) {
if (uFlags & LMEM_DISCARDABLE) {
HandleEntry->Flags |= BASE_HANDLE_DISCARDABLE;
}
else {
HandleEntry->Flags &= ~BASE_HANDLE_DISCARDABLE;
}
}
else {
p = HandleEntry->Object;
if (uBytes == 0) {
hMem = NULL;
if (p != NULL) {
if ((uFlags & LMEM_MOVEABLE) && HandleEntry->LockCount == 0) {
if (RtlFreeHeap( BaseHeap, Flags | HEAP_NO_SERIALIZE, p )) {
HandleEntry->Object = NULL;
HandleEntry->Flags |= BASE_HANDLE_DISCARDED;
hMem = (HANDLE)&HandleEntry->Object;
}
}
else {
#if DBG
DbgPrint( "*** LocalReAlloc( %lx ) - failing with locked handle\n", &HandleEntry->Object );
BaseHeapBreakPoint();
#endif
}
}
else {
hMem = (HANDLE)&HandleEntry->Object;
}
}
else {
Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVEABLE;
if (p == NULL) {
p = RtlAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, uBytes );
if (p != NULL) {
RtlSetUserValueHeap( BaseHeap, HEAP_NO_SERIALIZE, p, hMem );
}
}
else {
if (!(uFlags & LMEM_MOVEABLE) &&
HandleEntry->LockCount != 0
) {
Flags |= HEAP_REALLOC_IN_PLACE_ONLY;
}
else {
Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY;
}
p = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, p, uBytes );
}
if (p != NULL) {
HandleEntry->Object = p;
HandleEntry->Flags &= ~BASE_HANDLE_DISCARDED;
}
else {
hMem = NULL;
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
}
}
}
else
if (!(uFlags & LMEM_MODIFY)) {
hMem = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, (PVOID)hMem, uBytes );
if (hMem == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
hMem = NULL;
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
return( (LPSTR)hMem );
}
PVOID
WINAPI
LocalLock(
HLOCAL hMem
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
LPSTR p;
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
RtlLockHeap( BaseHeap );
try {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
#if DBG
DbgPrint( "*** LocalLock( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
p = NULL;
}
else {
p = HandleEntry->Object;
if (p != NULL) {
if (HandleEntry->LockCount++ == LMEM_LOCKCOUNT) {
HandleEntry->LockCount--;
}
}
else {
SetLastError( ERROR_DISCARDED );
}
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
p = NULL;
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
return( p );
}
else {
if ( (ULONG_PTR)hMem >= SystemRangeStart ) {
return NULL;
}
return( (LPSTR)hMem );
}
}
HLOCAL
WINAPI
LocalHandle(
LPCVOID pMem
)
{
HANDLE Handle;
ULONG Flags;
RtlLockHeap( BaseHeap );
try {
Handle = NULL;
if (!RtlGetUserInfoHeap( BaseHeap, HEAP_NO_SERIALIZE, (LPVOID)pMem, &Handle, &Flags )) {
SetLastError( ERROR_INVALID_HANDLE );
}
else
if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
Handle = (HANDLE)pMem;
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
return( Handle );
}
BOOL
WINAPI
LocalUnlock(
HLOCAL hMem
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
BOOL Result;
Result = FALSE;
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
RtlLockHeap( BaseHeap );
try {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
#if DBG
DbgPrint( "*** LocalUnlock( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
}
else
if (HandleEntry->LockCount-- == 0) {
HandleEntry->LockCount++;
SetLastError( ERROR_NOT_LOCKED );
}
else
if (HandleEntry->LockCount != 0) {
Result = TRUE;
}
else {
SetLastError( NO_ERROR );
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
}
else {
SetLastError( ERROR_NOT_LOCKED );
}
return( Result );
}
SIZE_T
WINAPI
LocalSize(
HLOCAL hMem
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
PVOID Handle;
ULONG Flags;
SIZE_T uSize;
uSize = MAXULONG_PTR;
Flags = 0;
RtlLockHeap( BaseHeap );
try {
if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
Handle = NULL;
if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
}
else
if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, (PVOID)hMem );
}
else {
hMem = Handle;
}
}
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
#if DBG
DbgPrint( "*** LocalSize( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
}
else
if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
uSize = HandleEntry->Size;
}
else {
uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, HandleEntry->Object );
}
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
if (uSize == MAXULONG_PTR) {
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
else {
return uSize;
}
}
UINT
WINAPI
LocalFlags(
HLOCAL hMem
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
HANDLE Handle;
ULONG Flags;
UINT uFlags;
uFlags = LMEM_INVALID_HANDLE;
RtlLockHeap( BaseHeap );
try {
if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
Handle = NULL;
Flags = 0;
if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
}
else
if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
uFlags = 0;
}
else {
hMem = Handle;
}
}
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT;
if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
uFlags |= LMEM_DISCARDED;
}
if (HandleEntry->Flags & BASE_HANDLE_DISCARDABLE) {
uFlags |= LMEM_DISCARDABLE;
}
}
}
if (uFlags == LMEM_INVALID_HANDLE) {
#if DBG
DbgPrint( "*** LocalFlags( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
return( uFlags );
}
HLOCAL
WINAPI
LocalFree(
HLOCAL hMem
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
LPSTR p;
try {
if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
if (RtlFreeHeap( BaseHeap,
0,
(PVOID)hMem
)
) {
return NULL;
}
else {
SetLastError( ERROR_INVALID_HANDLE );
return hMem;
}
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
return hMem;
}
RtlLockHeap( BaseHeap );
try {
if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
#if DBG
DbgPrint( "*** LocalFree( %lx ) - invalid handle\n", hMem );
BaseHeapBreakPoint();
#endif
SetLastError( ERROR_INVALID_HANDLE );
p = NULL;
}
else {
#if DBG
if (HandleEntry->LockCount != 0) {
DbgPrint( "BASE: LocalFree called with a locked object.\n" );
BaseHeapBreakPoint();
}
#endif
p = HandleEntry->Object;
RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
if (p == NULL) {
hMem = NULL;
}
}
}
else {
p = (LPSTR)hMem;
}
if (p != NULL) {
if (RtlFreeHeap( BaseHeap, HEAP_NO_SERIALIZE, p )) {
hMem = NULL;
}
else {
SetLastError( ERROR_INVALID_HANDLE );
}
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}
RtlUnlockHeap( BaseHeap );
return( hMem );
}
SIZE_T
WINAPI
LocalCompact(
UINT uMinFree
)
{
return RtlCompactHeap( BaseHeap, 0 );
}
SIZE_T
WINAPI
LocalShrink(
HLOCAL hMem,
UINT cbNewSize
)
{
return RtlCompactHeap( BaseHeap, 0 );
}
HANDLE
WINAPI
HeapCreate(
DWORD flOptions,
SIZE_T dwInitialSize,
SIZE_T dwMaximumSize
)
{
HANDLE hHeap;
ULONG GrowthThreshold;
ULONG Flags;
Flags = (flOptions & (HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE)) | HEAP_CLASS_1;
GrowthThreshold = 0;
if (dwMaximumSize < BASE_SYSINFO.PageSize) {
if (dwMaximumSize == 0) {
GrowthThreshold = BASE_SYSINFO.PageSize * 16;
Flags |= HEAP_GROWABLE;
}
else {
dwMaximumSize = BASE_SYSINFO.PageSize;
}
}
if (GrowthThreshold == 0 && dwInitialSize > dwMaximumSize) {
dwMaximumSize = dwInitialSize;
}
hHeap = (HANDLE)RtlCreateHeap( Flags,
NULL,
dwMaximumSize,
dwInitialSize,
0,
NULL
);
if (hHeap == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
return( hHeap );
}
BOOL
WINAPI
HeapDestroy(
HANDLE hHeap
)
{
if (RtlDestroyHeap( (PVOID)hHeap ) == NULL ) {
return( TRUE );
}
else {
SetLastError( ERROR_INVALID_HANDLE );
return( FALSE );
}
}
BOOL
WINAPI
HeapExtend(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpBase,
DWORD dwBytes
)
{
NTSTATUS Status;
Status = RtlExtendHeap( hHeap, dwFlags, lpBase, dwBytes );
if (NT_SUCCESS( Status )) {
return TRUE;
}
else {
BaseSetLastNTError( Status );
}
return FALSE;
}
WINBASEAPI
DWORD
WINAPI
HeapCreateTagsW(
HANDLE hHeap,
DWORD dwFlags,
LPCWSTR lpTagPrefix,
LPCWSTR lpTagNames
)
{
return RtlCreateTagHeap( hHeap, dwFlags, (PWSTR)lpTagPrefix, (PWSTR)lpTagNames );
}
WINBASEAPI
LPCWSTR
WINAPI
HeapQueryTagW(
HANDLE hHeap,
DWORD dwFlags,
WORD wTagIndex,
BOOL bResetCounters,
LPHEAP_TAG_INFO TagInfo
)
{
ASSERT( sizeof(RTL_HEAP_TAG_INFO) == sizeof(HEAP_TAG_INFO) );
return RtlQueryTagHeap( hHeap,
dwFlags,
wTagIndex,
(BOOLEAN)bResetCounters,
(PRTL_HEAP_TAG_INFO)TagInfo
);
}
BOOL
WINAPI
HeapSummary(
HANDLE hHeap,
DWORD dwFlags,
LPHEAP_SUMMARY lpSummary
)
{
NTSTATUS Status;
RTL_HEAP_USAGE HeapInfo;
if (lpSummary->cb != sizeof( *lpSummary )) {
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
HeapInfo.Length = sizeof( HeapInfo );
Status = RtlUsageHeap( hHeap,
dwFlags & ~(HEAP_USAGE_ALLOCATED_BLOCKS |
HEAP_USAGE_FREE_BUFFER
),
&HeapInfo
);
if (NT_SUCCESS( Status )) {
lpSummary->cbAllocated = HeapInfo.BytesAllocated;
lpSummary->cbCommitted = HeapInfo.BytesCommitted;
return TRUE;
}
else {
BaseSetLastNTError( Status );
return FALSE;
}
}
BOOL
WINAPI
HeapUsage(
HANDLE hHeap,
DWORD dwFlags,
BOOL bFirstCall,
BOOL bLastCall,
PHEAP_USAGE lpUsage
)
{
NTSTATUS Status;
if (lpUsage->cb != sizeof( *lpUsage ) || (bFirstCall & bLastCall)) {
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
dwFlags &= ~(HEAP_USAGE_ALLOCATED_BLOCKS |
HEAP_USAGE_FREE_BUFFER
);
if (bLastCall) {
dwFlags |= HEAP_USAGE_FREE_BUFFER;
}
else {
dwFlags |= HEAP_USAGE_ALLOCATED_BLOCKS;
if (bFirstCall) {
RtlZeroMemory( (&lpUsage->cb)+1, sizeof( *lpUsage ) - sizeof( lpUsage->cb ) );
}
}
ASSERT( sizeof(RTL_HEAP_USAGE) == sizeof(HEAP_USAGE) );
Status = RtlUsageHeap( hHeap, dwFlags, (PRTL_HEAP_USAGE)lpUsage );
if (NT_SUCCESS( Status )) {
if (Status == STATUS_MORE_ENTRIES) {
return TRUE;
}
else {
SetLastError( NO_ERROR );
return FALSE;
}
}
else {
BaseSetLastNTError( Status );
return FALSE;
}
}
BOOL
WINAPI
HeapValidate(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem
)
{
return RtlValidateHeap( hHeap, dwFlags, lpMem );
}
HANDLE
WINAPI
GetProcessHeap( VOID )
{
return RtlProcessHeap();
}
WINBASEAPI
DWORD
WINAPI
GetProcessHeaps(
DWORD NumberOfHeaps,
PHANDLE ProcessHeaps
)
{
return RtlGetProcessHeaps( NumberOfHeaps, ProcessHeaps );
}
WINBASEAPI
SIZE_T
WINAPI
HeapCompact(
HANDLE hHeap,
DWORD dwFlags
)
{
return RtlCompactHeap( hHeap, dwFlags );
}
WINBASEAPI
BOOL
WINAPI
HeapLock(
HANDLE hHeap
)
{
return RtlLockHeap( hHeap );
}
WINBASEAPI
BOOL
WINAPI
HeapUnlock(
HANDLE hHeap
)
{
return RtlUnlockHeap( hHeap );
}
WINBASEAPI
BOOL
WINAPI
HeapWalk(
HANDLE hHeap,
LPPROCESS_HEAP_ENTRY lpEntry
)
{
RTL_HEAP_WALK_ENTRY Entry;
NTSTATUS Status;
if (lpEntry->lpData == NULL) {
Entry.DataAddress = NULL;
Status = RtlWalkHeap( hHeap, &Entry );
}
else {
Entry.DataAddress = lpEntry->lpData;
Entry.SegmentIndex = lpEntry->iRegionIndex;
if (lpEntry->wFlags & PROCESS_HEAP_REGION) {
Entry.Flags = RTL_HEAP_SEGMENT;
}
else
if (lpEntry->wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) {
Entry.Flags = RTL_HEAP_UNCOMMITTED_RANGE;
Entry.DataSize = lpEntry->cbData;
}
else
if (lpEntry->wFlags & PROCESS_HEAP_ENTRY_BUSY) {
Entry.Flags = RTL_HEAP_BUSY;
}
else {
Entry.Flags = 0;
}
Status = RtlWalkHeap( hHeap, &Entry );
}
if (NT_SUCCESS( Status )) {
lpEntry->lpData = Entry.DataAddress;
lpEntry->cbData = (DWORD)Entry.DataSize;
lpEntry->cbOverhead = Entry.OverheadBytes;
lpEntry->iRegionIndex = Entry.SegmentIndex;
if (Entry.Flags & RTL_HEAP_BUSY) {
lpEntry->wFlags = PROCESS_HEAP_ENTRY_BUSY;
if (Entry.Flags & BASE_HEAP_FLAG_DDESHARE) {
lpEntry->wFlags |= PROCESS_HEAP_ENTRY_DDESHARE;
}
if (Entry.Flags & BASE_HEAP_FLAG_MOVEABLE) {
lpEntry->wFlags |= PROCESS_HEAP_ENTRY_MOVEABLE;
lpEntry->Block.hMem = (HLOCAL)Entry.Block.Settable;
}
memset( lpEntry->Block.dwReserved, 0, sizeof( lpEntry->Block.dwReserved ) );
}
else
if (Entry.Flags & RTL_HEAP_SEGMENT) {
lpEntry->wFlags = PROCESS_HEAP_REGION;
lpEntry->Region.dwCommittedSize = Entry.Segment.CommittedSize;
lpEntry->Region.dwUnCommittedSize = Entry.Segment.UnCommittedSize;
lpEntry->Region.lpFirstBlock = Entry.Segment.FirstEntry;
lpEntry->Region.lpLastBlock = Entry.Segment.LastEntry;
}
else
if (Entry.Flags & RTL_HEAP_UNCOMMITTED_RANGE) {
lpEntry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
memset( &lpEntry->Region, 0, sizeof( lpEntry->Region ) );
}
else {
lpEntry->wFlags = 0;
}
return TRUE;
}
else {
BaseSetLastNTError( Status );
return FALSE;
}
}
WINBASEAPI
BOOL
WINAPI
HeapSetInformation (
IN PVOID HeapHandle,
IN HEAP_INFORMATION_CLASS HeapInformationClass,
IN PVOID HeapInformation OPTIONAL,
IN SIZE_T HeapInformationLength OPTIONAL
)
{
NTSTATUS Status;
Status = RtlSetHeapInformation( HeapHandle,
HeapInformationClass,
HeapInformation,
HeapInformationLength );
if (NT_SUCCESS( Status )) {
return TRUE;
}
else {
BaseSetLastNTError( Status );
}
return FALSE;
}
WINBASEAPI
BOOL
WINAPI
HeapQueryInformation (
IN PVOID HeapHandle,
IN HEAP_INFORMATION_CLASS HeapInformationClass,
OUT PVOID HeapInformation OPTIONAL,
IN SIZE_T HeapInformationLength OPTIONAL,
OUT PSIZE_T ReturnLength OPTIONAL
)
{
NTSTATUS Status;
Status = RtlQueryHeapInformation( HeapHandle,
HeapInformationClass,
HeapInformation,
HeapInformationLength,
ReturnLength );
if (NT_SUCCESS( Status )) {
return TRUE;
}
else {
BaseSetLastNTError( Status );
}
return FALSE;
}
#if DBG
VOID
BaseHeapBreakPoint( VOID )
{
if (NtCurrentPeb()->BeingDebugged)
{
#if i386
_asm { int 3 }
#else
DbgBreakPoint();
#endif
}
}
#endif