-link heaps together instead of using stupid table past peb

-RtlValidateProcessHeaps/RtlGetProcessHeaps/RtlEnumProcessHeaps  didn't process all heaps
-correct RtlDestroyHeap proto. / return value
All changes based on Wine

svn path=/trunk/; revision=12151
This commit is contained in:
Gunnar Dalsnes 2004-12-16 15:10:01 +00:00
parent 4d8fc530e9
commit 9cbb3d72e1
3 changed files with 62 additions and 41 deletions

View file

@ -1,4 +1,4 @@
/* $Id: rtl.h,v 1.39 2004/11/25 19:22:07 ekohl Exp $ /* $Id: rtl.h,v 1.40 2004/12/16 15:10:00 gdalsnes Exp $
* *
*/ */
#ifndef __DDK_RTL_H #ifndef __DDK_RTL_H
@ -960,7 +960,7 @@ RtlDescribeChunk(IN USHORT CompressionFormat,
NTSTATUS STDCALL NTSTATUS STDCALL
RtlDestroyAtomTable (IN PRTL_ATOM_TABLE AtomTable); RtlDestroyAtomTable (IN PRTL_ATOM_TABLE AtomTable);
BOOLEAN STDCALL HANDLE STDCALL
RtlDestroyHeap (HANDLE hheap); RtlDestroyHeap (HANDLE hheap);
NTSTATUS NTSTATUS

View file

@ -1,4 +1,4 @@
/* $Id: heap.c,v 1.27 2004/06/13 20:04:55 navaraf Exp $ /* $Id: heap.c,v 1.28 2004/12/16 15:10:00 gdalsnes Exp $
* *
* kernel/heap.c * kernel/heap.c
* Copyright (C) 1996, Onno Hovers, All rights reserved * Copyright (C) 1996, Onno Hovers, All rights reserved
@ -53,7 +53,14 @@ HANDLE STDCALL HeapCreate(DWORD flags, DWORD dwInitialSize, DWORD dwMaximumSize)
*/ */
BOOL WINAPI HeapDestroy(HANDLE hheap) BOOL WINAPI HeapDestroy(HANDLE hheap)
{ {
return(RtlDestroyHeap(hheap)); if (hheap == RtlGetProcessHeap())
{
return FALSE;
}
if (RtlDestroyHeap( hheap )==NULL) return TRUE;
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
} }
/********************************************************************* /*********************************************************************

View file

@ -1077,7 +1077,7 @@ RtlCreateHeap(ULONG flags,
PRTL_HEAP_DEFINITION Definition) PRTL_HEAP_DEFINITION Definition)
{ {
SUBHEAP *subheap; SUBHEAP *subheap;
ULONG i; HEAP *heapPtr;
/* Allocate the heap block */ /* Allocate the heap block */
@ -1091,15 +1091,14 @@ RtlCreateHeap(ULONG flags,
return 0; return 0;
} }
/* link it into the per-process heap list */
RtlEnterCriticalSection (&RtlpProcessHeapsListLock); RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
for (i = 0; i < NtCurrentPeb ()->NumberOfHeaps; i++)
{ heapPtr = subheap->heap;
if (NtCurrentPeb ()->ProcessHeaps[i] == NULL) heapPtr->next = (HEAP*)NtCurrentPeb()->ProcessHeaps;
{ NtCurrentPeb()->ProcessHeaps = (HANDLE)heapPtr;
NtCurrentPeb()->ProcessHeaps[i] = (PVOID)subheap; NtCurrentPeb()->NumberOfHeaps++;
break;
}
}
RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
return (HANDLE)subheap; return (HANDLE)subheap;
@ -1112,27 +1111,34 @@ RtlCreateHeap(ULONG flags,
* FALSE: Failure * FALSE: Failure
* *
* @implemented * @implemented
*
* RETURNS
* Success: A NULL HANDLE, if heap is NULL or it was destroyed
* Failure: The Heap handle, if heap is the process heap.
*/ */
BOOLEAN STDCALL HANDLE STDCALL
RtlDestroyHeap(HANDLE heap) /* [in] Handle of heap */ RtlDestroyHeap(HANDLE heap) /* [in] Handle of heap */
{ {
HEAP *heapPtr = HEAP_GetPtr( heap ); HEAP *heapPtr = HEAP_GetPtr( heap );
SUBHEAP *subheap; SUBHEAP *subheap;
ULONG i, flags; ULONG flags;
HEAP **pptr;
DPRINT("%08x\n", heap ); DPRINT("%08x\n", heap );
if (!heapPtr) if (!heapPtr)
return FALSE; return heap;
if (heap == NtCurrentPeb()->ProcessHeap)
return heap; /* cannot delete the main process heap */
/* remove it from the per-process list */
RtlEnterCriticalSection (&RtlpProcessHeapsListLock); RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
for (i = 0; i < NtCurrentPeb ()->NumberOfHeaps; i++)
{ pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps;
if (NtCurrentPeb ()->ProcessHeaps[i] == heap) while (*pptr && *pptr != heapPtr) pptr = &(*pptr)->next;
{ if (*pptr) *pptr = (*pptr)->next;
NtCurrentPeb()->ProcessHeaps[i] = NULL; NtCurrentPeb()->NumberOfHeaps--;
break;
}
}
RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
RtlDeleteCriticalSection( &heapPtr->critSection ); RtlDeleteCriticalSection( &heapPtr->critSection );
@ -1155,7 +1161,7 @@ RtlDestroyHeap(HANDLE heap) /* [in] Handle of heap */
} }
subheap = next; subheap = next;
} }
return TRUE; return (HANDLE)NULL;
} }
@ -1713,8 +1719,8 @@ RtlInitializeHeapManager(VOID)
Peb = NtCurrentPeb(); Peb = NtCurrentPeb();
Peb->NumberOfHeaps = 0; Peb->NumberOfHeaps = 0;
Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(HANDLE); Peb->MaximumNumberOfHeaps = -1; /* no limit */
Peb->ProcessHeaps = (PVOID)Peb + sizeof(PEB); Peb->ProcessHeaps = NULL;
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock); RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
} }
@ -1728,13 +1734,13 @@ RtlEnumProcessHeaps(NTSTATUS STDCALL_FUNC(*func)(PVOID, LONG),
LONG lParam) LONG lParam)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ULONG i; HEAP** pptr;
RtlEnterCriticalSection(&RtlpProcessHeapsListLock); RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
for (i = 0; i < NtCurrentPeb()->NumberOfHeaps; i++) for (pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; *pptr; pptr = &(*pptr)->next)
{ {
Status = func(NtCurrentPeb()->ProcessHeaps[i],lParam); Status = func(*pptr,lParam);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
break; break;
} }
@ -1753,15 +1759,19 @@ RtlGetProcessHeaps(ULONG HeapCount,
HANDLE *HeapArray) HANDLE *HeapArray)
{ {
ULONG Result = 0; ULONG Result = 0;
HEAP ** pptr;
RtlEnterCriticalSection(&RtlpProcessHeapsListLock); RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
Result = NtCurrentPeb()->NumberOfHeaps;
if (NtCurrentPeb()->NumberOfHeaps <= HeapCount) if (NtCurrentPeb()->NumberOfHeaps <= HeapCount)
{ {
Result = NtCurrentPeb()->NumberOfHeaps; int i = 0;
memmove(HeapArray, for (pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; *pptr; pptr = &(*pptr)->next)
NtCurrentPeb()->ProcessHeaps, {
Result * sizeof(HANDLE)); HeapArray[i++] = *pptr;
}
} }
RtlLeaveCriticalSection (&RtlpProcessHeapsListLock); RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
@ -1776,18 +1786,22 @@ RtlGetProcessHeaps(ULONG HeapCount,
BOOLEAN STDCALL BOOLEAN STDCALL
RtlValidateProcessHeaps(VOID) RtlValidateProcessHeaps(VOID)
{ {
HANDLE Heaps[128];
BOOLEAN Result = TRUE; BOOLEAN Result = TRUE;
ULONG HeapCount; HEAP ** pptr;
ULONG i;
HeapCount = RtlGetProcessHeaps(128, Heaps); RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
for (i = 0; i < HeapCount; i++)
for (pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; *pptr; pptr = &(*pptr)->next)
{ {
if (!RtlValidateHeap(Heaps[i], 0, NULL)) if (!RtlValidateHeap(*pptr, 0, NULL))
{
Result = FALSE; Result = FALSE;
break;
}
} }
RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
return Result; return Result;
} }