Author: ion Date: Sat Jun 24 23:00:07 2006 New Revision: 22582
URL: http://svn.reactos.org/svn/reactos?rev=22582&view=rev Log: - Fixup Local* Heap implementation so that calls which have different semantics don't call the Global APIs (ie: LocalAlloc/LocalReAlloc and LocalFlags). The rest can be shared beteween them. Also fix some prototypes. - Rename all the defintions to BASE_HEAP instead of GLOBAL_HEAP, since they apply just as well to the Local Heap.
Modified: trunk/reactos/dll/win32/kernel32/include/baseheap.h trunk/reactos/dll/win32/kernel32/mem/global.c trunk/reactos/dll/win32/kernel32/mem/local.c trunk/reactos/dll/win32/kernel32/misc/dllmain.c trunk/reactos/include/winbase.h
Modified: trunk/reactos/dll/win32/kernel32/include/baseheap.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include/... ============================================================================== --- trunk/reactos/dll/win32/kernel32/include/baseheap.h (original) +++ trunk/reactos/dll/win32/kernel32/include/baseheap.h Sat Jun 24 23:00:07 2006 @@ -36,7 +36,7 @@ // // The Handle Table // -extern RTL_HANDLE_TABLE BaseGlobalHandleTable; +extern RTL_HANDLE_TABLE BaseHeapHandleTable;
// // Tracing Support @@ -62,13 +62,15 @@ #define BASE_TRACE_DEALLOC(x) \ BH_PRINT("[BASE_HEAP] %s : Freeing %p\n", \ __FUNCTION__, x) - +#define BASE_TRACE_FAILURE() \ + BH_PRINT("[BASE_HEAP] %s : Failing %d\n", \ + __FUNCTION__, __LINE__) // // The handle structure for global heap handles. // Notice that it nicely overlays with RTL_HANDLE_ENTRY. // KEEP IT THAT WAY! ;-) // -typedef struct _GLOBAL_HEAP_HANDLE_ENTRY +typedef struct _BASE_HEAP_HANDLE_ENTRY { USHORT Flags; USHORT LockCount; @@ -77,45 +79,45 @@ PVOID Object; ULONG OldSize; }; -} GLOBAL_HEAP_HANDLE_ENTRY, *PGLOBAL_HEAP_HANDLE_ENTRY; +} BASE_HEAP_HANDLE_ENTRY, *PBASE_HEAP_HANDLE_ENTRY;
// // Handle entry flags // Note that 0x0001 is the shared/generic RTL_HANDLE_VALID // -#define GLOBAL_HEAP_ENTRY_FLAG_MOVABLE 0x0002 -#define GLOBAL_HEAP_ENTRY_FLAG_REUSABLE 0x0004 -#define GLOBAL_HEAP_ENTRY_FLAG_REUSE 0x0008 -#define GLOBAL_HEAP_ENTRY_FLAG_DDESHARE 0x0010 +#define BASE_HEAP_ENTRY_FLAG_MOVABLE 0x0002 +#define BASE_HEAP_ENTRY_FLAG_REUSABLE 0x0004 +#define BASE_HEAP_ENTRY_FLAG_REUSE 0x0008 +#define BASE_HEAP_ENTRY_FLAG_DDESHARE 0x0010
// // Easy way to check if the global handle is actually an entry in our table // -#define GLOBAL_HEAP_IS_HANDLE_ENTRY \ - (ULONG_PTR)FIELD_OFFSET(GLOBAL_HEAP_HANDLE_ENTRY, Object) +#define BASE_HEAP_IS_HANDLE_ENTRY \ + (ULONG_PTR)FIELD_OFFSET(BASE_HEAP_HANDLE_ENTRY, Object)
// // Tags for the entire heap allocation for this global memory. // They are set part of the User Flags of the RTL Heap. // -#define GLOBAL_HEAP_FLAG_MOVABLE HEAP_SETTABLE_USER_FLAG1 -#define GLOBAL_HEAP_FLAG_DDESHARE HEAP_SETTABLE_USER_FLAG2 +#define BASE_HEAP_FLAG_MOVABLE HEAP_SETTABLE_USER_FLAG1 +#define BASE_HEAP_FLAG_DDESHARE HEAP_SETTABLE_USER_FLAG2
// // Internal Handle Functions // -#define GlobalAllocEntry() \ - (PGLOBAL_HEAP_HANDLE_ENTRY)RtlAllocateHandle(&BaseGlobalHandleTable, NULL) +#define BaseHeapAllocEntry() \ + (PBASE_HEAP_HANDLE_ENTRY)RtlAllocateHandle(&BaseHeapHandleTable, NULL)
-#define GlobalGetEntry(h) \ - (PGLOBAL_HEAP_HANDLE_ENTRY) \ +#define BaseHeapGetEntry(h) \ + (PBASE_HEAP_HANDLE_ENTRY) \ CONTAINING_RECORD(h, \ - GLOBAL_HEAP_HANDLE_ENTRY, \ + BASE_HEAP_HANDLE_ENTRY, \ Object);
-#define GlobalValidateEntry(he) \ - RtlIsValidHandle(&BaseGlobalHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he) +#define BaseHeapValidateEntry(he) \ + RtlIsValidHandle(&BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he)
-#define GlobalFreeEntry(he) \ - RtlFreeHandle(&BaseGlobalHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he); +#define BaseHeapFreeEntry(he) \ + RtlFreeHandle(&BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he);
Modified: trunk/reactos/dll/win32/kernel32/mem/global.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/mem/glob... ============================================================================== --- trunk/reactos/dll/win32/kernel32/mem/global.c (original) +++ trunk/reactos/dll/win32/kernel32/mem/global.c Sat Jun 24 23:00:07 2006 @@ -13,14 +13,10 @@ #define NDEBUG #include "debug.h"
-#define BASE_TRACE_FAILURE() \ - DbgPrint("[BASE_HEAP] %s : Failing %d\n", \ - __FUNCTION__, __LINE__) - /* TYPES *********************************************************************/
extern SYSTEM_BASIC_INFORMATION BaseCachedSysInfo; -RTL_HANDLE_TABLE BaseGlobalHandleTable; +RTL_HANDLE_TABLE BaseHeapHandleTable;
/* FUNCTIONS ***************************************************************/
@@ -35,7 +31,7 @@ ULONG Flags = 0; PVOID Ptr = NULL; HANDLE hMemory; - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; BASE_TRACE_ALLOC(dwBytes, uFlags); ASSERT(hProcessHeap);
@@ -55,7 +51,7 @@ if (!(uFlags & GMEM_MOVEABLE)) { /* Check if this is DDESHARE (deprecated) */ - if (uFlags & GMEM_DDESHARE) Flags |= GLOBAL_HEAP_ENTRY_FLAG_DDESHARE; + if (uFlags & GMEM_DDESHARE) Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE;
/* Allocate heap for it */ Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); @@ -72,10 +68,10 @@ */ Flags |= HEAP_NO_SERIALIZE | HEAP_SETTABLE_USER_VALUE | - GLOBAL_HEAP_FLAG_MOVABLE; + BASE_HEAP_FLAG_MOVABLE;
/* Allocate the handle */ - HandleEntry = GlobalAllocEntry(); + HandleEntry = BaseHeapAllocEntry(); if (!HandleEntry) { /* Fail */ @@ -96,7 +92,7 @@ { /* We failed, manually set the allocate flag and free the handle */ HandleEntry->Flags = RTL_HANDLE_VALID; - GlobalFreeEntry(HandleEntry); + BaseHeapFreeEntry(HandleEntry);
/* For the cleanup case */ HandleEntry = NULL; @@ -121,28 +117,28 @@ if (!Ptr) { /* We don't have a valid pointer, but so reuse this handle */ - HandleEntry->Flags = GLOBAL_HEAP_ENTRY_FLAG_REUSE; + HandleEntry->Flags = BASE_HEAP_ENTRY_FLAG_REUSE; }
/* Check if the handle is discardable */ if (uFlags & GMEM_DISCARDABLE) { /* Save it in the handle entry */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSABLE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; }
/* Check if the handle is moveable */ if (uFlags & GMEM_MOVEABLE) { /* Save it in the handle entry */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_MOVABLE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_MOVABLE; }
/* Check if the handle is DDE Shared */ if (uFlags & GMEM_DDESHARE) { /* Save it in the handle entry */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_DDESHARE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE; }
/* Set the pointer */ @@ -182,7 +178,7 @@ NTAPI GlobalFlags(HGLOBAL hMem) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; HANDLE Handle = NULL; ULONG Flags = 0; UINT uFlags = GMEM_INVALID_HANDLE; @@ -191,7 +187,7 @@ RtlLockHeap(hProcessHeap);
/* Check if this is a simple RTL Heap Managed block */ - if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Then we'll query RTL Heap */ RtlGetUserInfoHeap(hProcessHeap, Flags, hMem, &Handle, &Flags); @@ -202,7 +198,7 @@ * said that this heap isn't movable, which means something we're * really not a handle-based heap. */ - if (!(Handle) || !(Flags & GLOBAL_HEAP_FLAG_MOVABLE)) + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) { /* Then set the flags to 0 */ uFlags = 0; @@ -215,34 +211,34 @@ }
/* Check if the handle is actually an entry in our table */ - if ((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY) + if ((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY) { /* Then get the entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure it's a valid handle */ - if (GlobalValidateEntry(HandleEntry)) + if (BaseHeapValidateEntry(HandleEntry)) { /* Get the lock count first */ uFlags = HandleEntry->LockCount & GMEM_LOCKCOUNT;
/* Now check if it's discarded */ - if (HandleEntry->Flags & GLOBAL_HEAP_ENTRY_FLAG_REUSABLE) + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE) { /* Set the Win32 Flag */ uFlags |= GMEM_DISCARDED; }
/* Check if it's movable */ - if (HandleEntry->Flags & GLOBAL_HEAP_ENTRY_FLAG_MOVABLE) + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_MOVABLE) { /* Set the Win32 Flag */ uFlags |= GMEM_MOVEABLE; }
/* Check if it's DDE Shared */ - if (HandleEntry->Flags & GLOBAL_HEAP_ENTRY_FLAG_DDESHARE) + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_DDESHARE) { /* Set the Win32 Flag */ uFlags |= GMEM_DDESHARE; @@ -265,12 +261,12 @@ NTAPI GlobalFree(HGLOBAL hMem) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; LPVOID Ptr; BASE_TRACE_DEALLOC(hMem);
/* Check if this was a simple allocated heap entry */ - if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Free it with the RTL Heap Manager */ if (RtlFreeHeap(hProcessHeap, 0, hMem)) @@ -291,14 +287,14 @@ RtlLockHeap(hProcessHeap);
/* Make sure that this is an entry in our handle database */ - if ((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY) + if ((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY) { /* Get the entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure the handle is valid */ - if (!GlobalValidateEntry(HandleEntry)) + if (!BaseHeapValidateEntry(HandleEntry)) { /* It's not, fail */ SetLastError(ERROR_INVALID_HANDLE); @@ -310,7 +306,7 @@ Ptr = HandleEntry->Object;
/* Free this handle */ - GlobalFreeEntry(HandleEntry); + BaseHeapFreeEntry(HandleEntry);
/* If the pointer is 0, then we don't have a handle either */ if (!Ptr) hMem = NULL; @@ -361,7 +357,7 @@ * Check if RTL Heap didn't find a handle for us or said that * this heap isn't movable. */ - if (!(Handle) || !(Flags & GLOBAL_HEAP_FLAG_MOVABLE)) + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) { /* We're actually handle-based, so the pointer is a handle */ Handle = (HANDLE)pMem; @@ -379,11 +375,11 @@ NTAPI GlobalLock(HGLOBAL hMem) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; LPVOID Ptr;
/* Check if this was a simple allocated heap entry */ - if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Then simply return the pointer */ return hMem; @@ -393,11 +389,11 @@ RtlLockHeap(hProcessHeap);
/* Get the handle entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure it's valid */ - if (!GlobalValidateEntry(HandleEntry)) + if (!BaseHeapValidateEntry(HandleEntry)) { /* It's not, fail */ BASE_TRACE_FAILURE(); @@ -435,7 +431,7 @@ DWORD dwBytes, UINT uFlags) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; HANDLE Handle; LPVOID Ptr; ULONG Flags = 0; @@ -449,17 +445,16 @@ /* Lock the heap and disable built-in locking in the RTL Heap funcitons */ RtlLockHeap(hProcessHeap); Flags |= HEAP_NO_SERIALIZE; - DPRINT1("hmem: %p Flags: %lx\n", hMem, uFlags);
/* Check if this is a simple handle-based block */ - if (((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + if (((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Get the entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure the handle is valid */ - if (!GlobalValidateEntry(HandleEntry)) + if (!BaseHeapValidateEntry(HandleEntry)) { /* Fail */ BASE_TRACE_FAILURE(); @@ -472,12 +467,12 @@ if (uFlags & GMEM_DISCARDABLE) { /* Then set the flag */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSABLE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; } else { /* Otherwise, remove the flag */ - HandleEntry->Flags &= GLOBAL_HEAP_ENTRY_FLAG_REUSABLE; + HandleEntry->Flags &= BASE_HEAP_ENTRY_FLAG_REUSABLE; } } else @@ -498,7 +493,7 @@
/* Free the handle */ HandleEntry->Object = NULL; - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
/* Get the object pointer */ hMem = &HandleEntry->Object; @@ -513,7 +508,7 @@ else { /* Otherwise, we're allocating, so set the new flags needed */ - Flags |= HEAP_SETTABLE_USER_VALUE | GLOBAL_HEAP_FLAG_MOVABLE; + Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVABLE; if (!Ptr) { /* We don't have a base, so allocate one */ @@ -554,7 +549,7 @@ { /* Write it in the handle entry and mark it in use */ HandleEntry->Object = Ptr; - HandleEntry->Flags &= ~GLOBAL_HEAP_ENTRY_FLAG_REUSE; + HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSE; } else { @@ -584,16 +579,16 @@ * Check if the handle matches the pointer or if the moveable flag * isn't there, which is what we expect since it currenly isn't. */ - if (Handle == hMem || !(Flags & GLOBAL_HEAP_FLAG_MOVABLE)) + if (Handle == hMem || !(Flags & BASE_HEAP_FLAG_MOVABLE)) { /* Allocate a handle for it */ - HandleEntry = GlobalAllocEntry(); + HandleEntry = BaseHeapAllocEntry();
/* Calculate the size of the current heap */ dwBytes = RtlSizeHeap(hProcessHeap, HEAP_NO_SERIALIZE, hMem);
/* Set the movable flag */ - Flags |= HEAP_SETTABLE_USER_VALUE | GLOBAL_HEAP_FLAG_MOVABLE; + Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVABLE;
/* Now allocate the actual heap for it */ HandleEntry->Object = RtlAllocateHeap(hProcessHeap, @@ -607,7 +602,7 @@ * free the handle */ HandleEntry->Flags = RTL_HANDLE_VALID; - GlobalFreeEntry(HandleEntry); + BaseHeapFreeEntry(HandleEntry);
/* For the cleanup case */ BASE_TRACE_FAILURE(); @@ -626,20 +621,20 @@ /* Initialize the count and default flags */ HandleEntry->LockCount = 0; HandleEntry->Flags = RTL_HANDLE_VALID | - GLOBAL_HEAP_ENTRY_FLAG_MOVABLE; + BASE_HEAP_ENTRY_FLAG_MOVABLE;
/* Check if it's also discardable */ if (uFlags & GMEM_DISCARDABLE) { /* Set the internal flag */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSABLE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; }
/* Check if it's also DDE Shared */ if (uFlags & GMEM_DDESHARE) { /* Set the internal flag */ - HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_DDESHARE; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE; }
/* Allocation succeeded, so save our entry */ @@ -678,7 +673,7 @@ NTAPI GlobalSize(HGLOBAL hMem) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; PVOID Handle = NULL; ULONG Flags = 0; SIZE_T dwSize = MAXULONG_PTR; @@ -687,7 +682,7 @@ RtlLockHeap(hProcessHeap);
/* Check if this is a simple RTL Heap Managed block */ - if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Then we'll query RTL Heap */ RtlGetUserInfoHeap(hProcessHeap, Flags, hMem, &Handle, &Flags); @@ -697,7 +692,7 @@ * Check if RTL Heap didn't give us a handle or said that this heap * isn't movable. */ - if (!(Handle) || !(Flags & GLOBAL_HEAP_FLAG_MOVABLE)) + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) { /* This implies we're not a handle heap, so use the generic call */ dwSize = RtlSizeHeap(hProcessHeap, HEAP_NO_SERIALIZE, hMem); @@ -710,20 +705,20 @@ }
/* Make sure that this is an entry in our handle database */ - if ((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY) + if ((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY) { /* Get the entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure the handle is valid */ - if (!GlobalValidateEntry(HandleEntry)) + if (!BaseHeapValidateEntry(HandleEntry)) { /* Fail */ BASE_TRACE_FAILURE(); SetLastError(ERROR_INVALID_HANDLE); } - else if (HandleEntry->Flags & GLOBAL_HEAP_ENTRY_FLAG_REUSE) + else if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE) { /* We've reused this block, but we've saved the size for you */ dwSize = HandleEntry->OldSize; @@ -769,21 +764,21 @@ NTAPI GlobalUnlock(HGLOBAL hMem) { - PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; BOOL RetVal = TRUE;
/* Check if this was a simple allocated heap entry */ - if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) return RetVal; + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) return RetVal;
/* Otherwise, lock the heap */ RtlLockHeap(hProcessHeap);
/* Get the handle entry */ - HandleEntry = GlobalGetEntry(hMem); + HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem);
/* Make sure it's valid */ - if (!GlobalValidateEntry(HandleEntry)) + if (!BaseHeapValidateEntry(HandleEntry)) { /* It's not, fail */ BASE_TRACE_FAILURE();
Modified: trunk/reactos/dll/win32/kernel32/mem/local.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/mem/loca... ============================================================================== --- trunk/reactos/dll/win32/kernel32/mem/local.c (original) +++ trunk/reactos/dll/win32/kernel32/mem/local.c Sat Jun 24 23:00:07 2006 @@ -1,134 +1,450 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * Copyright (C) 1996, Onno Hovers, All rights reserved - * PROJECT: ReactOS system libraries - * FILE: lib/kernel32/mem/local.c - * PURPOSE: Manages the local heap - * PROGRAMER: Onno Hovers (original wfc version) - * David Welch (adapted for ReactOS) - * UPDATE HISTORY: - * 9/4/98: Adapted from the wfc project - */ - - -/* NOTES - * - * The local heap is the same as the global heap for win32 and both are only - * required for legacy apps - * - */ - -/* INCLUDES ****************************************************************/ +/* + * PROJECT: ReactOS Win32 Base API + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/kernel32/mem/local.c + * PURPOSE: Local Memory APIs (sits on top of Heap*) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/
#include <k32.h>
#define NDEBUG -#include "../include/debug.h" +#include "debug.h" + +/* TYPES *********************************************************************/ + +extern SYSTEM_BASIC_INFORMATION BaseCachedSysInfo;
/* FUNCTIONS ***************************************************************/
- -/* - * @implemented - */ -HLOCAL STDCALL +/* + * @implemented + */ +HLOCAL +NTAPI LocalAlloc(UINT uFlags, - SIZE_T uBytes) -{ - return (HLOCAL)GlobalAlloc(uFlags, uBytes); -} - - -/* - * @implemented - */ -SIZE_T STDCALL -LocalCompact(UINT uMinFree) -{ - return RtlCompactHeap(hProcessHeap, 0); -} - - -/* - * @implemented - */ -UINT STDCALL + SIZE_T dwBytes) +{ + ULONG Flags = 0; + PVOID Ptr = NULL; + HANDLE hMemory; + PBASE_HEAP_HANDLE_ENTRY HandleEntry; + BASE_TRACE_ALLOC(dwBytes, uFlags); + ASSERT(hProcessHeap); + + /* Make sure the flags are valid */ + if (uFlags & ~LMEM_VALID_FLAGS) + { + /* They aren't, fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Convert ZEROINIT */ + if (uFlags & LMEM_ZEROINIT) Flags |= HEAP_ZERO_MEMORY; + + /* Check if we're not movable, which means pointer-based heap */ + if (!(uFlags & LMEM_MOVEABLE)) + { + /* Allocate heap for it */ + Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + BASE_TRACE_ALLOC2(Ptr); + return Ptr; + } + + /* This is heap based, so lock it in first */ + RtlLockHeap(hProcessHeap); + + /* + * Disable locking, enable custom flags, and write the + * movable flag (deprecated) + */ + Flags |= HEAP_NO_SERIALIZE | + HEAP_SETTABLE_USER_VALUE | + BASE_HEAP_FLAG_MOVABLE; + + /* Allocate the handle */ + HandleEntry = BaseHeapAllocEntry(); + if (!HandleEntry) + { + /* Fail */ + hMemory = NULL; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + BASE_TRACE_FAILURE(); + goto Quickie; + } + + /* Get the object and make sure we have size */ + hMemory = &HandleEntry->Object; + if (dwBytes) + { + /* Allocate the actual memory for it */ + Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + BASE_TRACE_PTR(HandleEntry, Ptr); + if (!Ptr) + { + /* We failed, manually set the allocate flag and free the handle */ + HandleEntry->Flags = RTL_HANDLE_VALID; + BaseHeapFreeEntry(HandleEntry); + + /* For the cleanup case */ + HandleEntry = NULL; + } + else + { + /* All worked well, save our heap entry */ + RtlSetUserValueHeap(hProcessHeap, HEAP_NO_SERIALIZE, Ptr, hMemory); + } + } + +Quickie: + /* Cleanup! First unlock the heap */ + RtlUnlockHeap(hProcessHeap); + + /* Check if a handle was allocated */ + if (HandleEntry) + { + /* Set the pointer and allocated flag */ + HandleEntry->Object = Ptr; + HandleEntry->Flags = RTL_HANDLE_VALID; + if (!Ptr) + { + /* We don't have a valid pointer, but so reuse this handle */ + HandleEntry->Flags = BASE_HEAP_ENTRY_FLAG_REUSE; + } + + /* Check if the handle is discardable */ + if (uFlags & GMEM_DISCARDABLE) + { + /* Save it in the handle entry */ + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; + } + + /* Check if the handle is moveable */ + if (uFlags & GMEM_MOVEABLE) + { + /* Save it in the handle entry */ + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_MOVABLE; + } + + /* Set the pointer */ + Ptr = hMemory; + } + + /* Return the pointer */ + return Ptr; +} + +/* + * @implemented + */ +SIZE_T +NTAPI +LocalCompact(UINT dwMinFree) +{ + /* Call the RTL Heap Manager */ + return RtlCompactHeap(hProcessHeap, 0); +} + +/* + * @implemented + */ +UINT +NTAPI LocalFlags(HLOCAL hMem) { - return GlobalFlags((HGLOBAL)hMem); -} - - -/* - * @implemented - */ -HLOCAL STDCALL + PBASE_HEAP_HANDLE_ENTRY HandleEntry; + HANDLE Handle = NULL; + ULONG Flags = 0; + UINT uFlags = LMEM_INVALID_HANDLE; + + /* Start by locking the heap */ + RtlLockHeap(hProcessHeap); + + /* Check if this is a simple RTL Heap Managed block */ + if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) + { + /* Then we'll query RTL Heap */ + RtlGetUserInfoHeap(hProcessHeap, Flags, hMem, &Handle, &Flags); + BASE_TRACE_PTR(Handle, hMem); + + /* + * Check if RTL Heap didn't find a handle associated with us or + * said that this heap isn't movable, which means something we're + * really not a handle-based heap. + */ + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) + { + /* Then set the flags to 0 */ + uFlags = 0; + } + else + { + /* Otherwise we're handle-based, so get the internal handle */ + hMem = Handle; + } + } + + /* Check if the handle is actually an entry in our table */ + if ((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY) + { + /* Then get the entry */ + HandleEntry = BaseHeapGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure it's a valid handle */ + if (BaseHeapValidateEntry(HandleEntry)) + { + /* Get the lock count first */ + uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT; + + /* Now check if it's discarded */ + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE) + { + /* Set the Win32 Flag */ + uFlags |= LMEM_DISCARDED; + } + + /* Check if it's movable */ + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_MOVABLE) + { + /* Set the Win32 Flag */ + uFlags |= LMEM_DISCARDABLE; + } + } + } + + /* Check if by now, we still haven't gotten any useful flags */ + if (uFlags == LMEM_INVALID_HANDLE) SetLastError(ERROR_INVALID_HANDLE); + + /* All done! Unlock heap and return Win32 Flags */ + RtlUnlockHeap(hProcessHeap); + return uFlags; +} + +/* + * @implemented + */ +HLOCAL +NTAPI LocalFree(HLOCAL hMem) { - return (HLOCAL)GlobalFree((HGLOBAL)hMem); -} - - -/* - * @implemented - */ -HLOCAL STDCALL + /* This is identical to a Global Free */ + return GlobalFree(hMem); +} + +/* + * @implemented + */ +HLOCAL +NTAPI LocalHandle(LPCVOID pMem) { - return (HLOCAL)GlobalHandle(pMem); -} - - -/* - * @implemented - */ -LPVOID STDCALL + /* This is identical to a Global Handle */ + return GlobalHandle(pMem); +} + +/* + * @implemented + */ +LPVOID +NTAPI LocalLock(HLOCAL hMem) { - return GlobalLock((HGLOBAL)hMem); -} - - -/* - * @implemented - */ -HLOCAL STDCALL + /* This is the same as a GlobalLock, assuming these never change */ + ASSERT(LMEM_LOCKCOUNT == GMEM_LOCKCOUNT); + return GlobalLock(hMem); +} + +HLOCAL +NTAPI LocalReAlloc(HLOCAL hMem, - SIZE_T uBytes, - UINT uFlags) -{ - return (HLOCAL)GlobalReAlloc((HGLOBAL)hMem, uBytes, uFlags); -} - - -/* - * @implemented - */ -SIZE_T STDCALL -LocalShrink(HLOCAL hMem, UINT cbNewSize) -{ - return RtlCompactHeap(hProcessHeap, 0); -} - - -/* - * @implemented - */ -UINT STDCALL + SIZE_T dwBytes, + UINT uFlags) +{ + PBASE_HEAP_HANDLE_ENTRY HandleEntry; + LPVOID Ptr; + ULONG Flags = 0; + + /* Convert ZEROINIT */ + if (uFlags & LMEM_ZEROINIT) Flags |= HEAP_ZERO_MEMORY; + + /* If this wasn't a movable heap, then we MUST re-alloc in place */ + if (!(uFlags & LMEM_MOVEABLE)) Flags |= HEAP_REALLOC_IN_PLACE_ONLY; + + /* Lock the heap and disable built-in locking in the RTL Heap funcitons */ + RtlLockHeap(hProcessHeap); + Flags |= HEAP_NO_SERIALIZE; + + /* Check if this is a simple handle-based block */ + if (((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) + { + /* Get the entry */ + HandleEntry = BaseHeapGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure the handle is valid */ + if (!BaseHeapValidateEntry(HandleEntry)) + { + /* Fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + hMem = NULL; + } + else if (uFlags & LMEM_MODIFY) + { + /* User is changing flags... check if the memory was discardable */ + if (uFlags & LMEM_DISCARDABLE) + { + /* Then set the flag */ + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; + } + else + { + /* Otherwise, remove the flag */ + HandleEntry->Flags &= BASE_HEAP_ENTRY_FLAG_REUSABLE; + } + } + else + { + /* Otherwise, get the object and check if we have no size */ + Ptr = HandleEntry->Object; + if (!dwBytes) + { + /* Clear the handle and check for a pointer */ + hMem = NULL; + if (Ptr) + { + /* Make sure the handle isn't locked */ + if ((uFlags & LMEM_MOVEABLE) & !(HandleEntry->LockCount)) + { + /* Free the current heap */ + RtlFreeHeap(hProcessHeap, Flags, Ptr); + + /* Free the handle */ + HandleEntry->Object = NULL; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE; + + /* Get the object pointer */ + hMem = &HandleEntry->Object; + } + } + else + { + /* Otherwise just return the object pointer */ + hMem = &HandleEntry->Object; + } + } + else + { + /* Otherwise, we're allocating, so set the new flags needed */ + Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVABLE; + if (!Ptr) + { + /* We don't have a base, so allocate one */ + Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + BASE_TRACE_ALLOC2(Ptr); + if (Ptr) + { + /* Allocation succeeded, so save our entry */ + RtlSetUserValueHeap(hProcessHeap, + HEAP_NO_SERIALIZE, + Ptr, + hMem); + } + } + else + { + /* + * If it's not movable or currently locked, we MUST allocate + * in-place! + */ + if (!(uFlags & LMEM_MOVEABLE) && (HandleEntry->LockCount)) + { + /* Set the flag */ + Flags |= HEAP_REALLOC_IN_PLACE_ONLY; + } + else + { + /* Otherwise clear the flag if we set it previously */ + Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY; + } + + /* And do the re-allocation */ + Ptr = RtlReAllocateHeap(hProcessHeap, Flags, Ptr, dwBytes); + } + + /* Make sure we have a pointer by now */ + if (Ptr) + { + /* Write it in the handle entry and mark it in use */ + HandleEntry->Object = Ptr; + HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSE; + } + else + { + /* Otherwise we failed */ + hMem = NULL; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + } + } + } + else if (!(uFlags & LMEM_MODIFY)) + { + /* Otherwise, this is a simple RTL Managed Heap, so just call it */ + hMem = RtlReAllocateHeap(hProcessHeap, + Flags | HEAP_NO_SERIALIZE, + hMem, + dwBytes); + if (!hMem) + { + /* Fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + } + + /* All done, unlock the heap and return the pointer */ + RtlUnlockHeap(hProcessHeap); + return hMem; +} + +/* + * @implemented + */ +SIZE_T +STDCALL +LocalShrink(HLOCAL hMem, + UINT cbNewSize) +{ + /* Call RTL */ + return RtlCompactHeap(hProcessHeap, 0); +} + +/* + * @implemented + */ +SIZE_T +NTAPI LocalSize(HLOCAL hMem) { - return GlobalSize((HGLOBAL)hMem); -} - - -/* - * @implemented - */ -BOOL STDCALL + /* This is the same as a Global Size */ + return GlobalSize(hMem); +} + +/* + * @implemented + */ +BOOL +NTAPI LocalUnlock(HLOCAL hMem) { - return GlobalUnlock((HGLOBAL)hMem); + /* This is the same as a Global Unlock */ + return GlobalUnlock(hMem); }
/* EOF */
Modified: trunk/reactos/dll/win32/kernel32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/dll... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/dllmain.c (original) +++ trunk/reactos/dll/win32/kernel32/misc/dllmain.c Sat Jun 24 23:00:07 2006 @@ -340,8 +340,8 @@
hProcessHeap = RtlGetProcessHeap(); RtlInitializeHandleTable(0xFFFF, - sizeof(GLOBAL_HEAP_HANDLE_ENTRY), - &BaseGlobalHandleTable); + sizeof(BASE_HEAP_HANDLE_ENTRY), + &BaseHeapHandleTable); hCurrentModule = hDll; DPRINT("Heap: %p\n", hProcessHeap);
Modified: trunk/reactos/include/winbase.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/winbase.h?rev=22582... ============================================================================== --- trunk/reactos/include/winbase.h (original) +++ trunk/reactos/include/winbase.h Sat Jun 24 23:00:07 2006 @@ -327,6 +327,7 @@ #define LMEM_MODIFY 128 #define LMEM_INVALID_HANDLE 32768 #define LMEM_LOCKCOUNT 255 +#define LMEM_VALID_FLAGS 0x0F72 #define LPTR 64 #define LHND 66 #define NONZEROLHND 2 @@ -1698,7 +1699,7 @@ PVOID WINAPI LocalLock(HLOCAL); HLOCAL WINAPI LocalReAlloc(HLOCAL,SIZE_T,UINT); SIZE_T WINAPI LocalShrink(HLOCAL,UINT); /* Obsolete: Has no effect. */ -UINT WINAPI LocalSize(HLOCAL); +SIZE_T WINAPI LocalSize(HLOCAL); BOOL WINAPI LocalUnlock(HLOCAL); BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); BOOL WINAPI LockFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPOVERLAPPED);