Author: ion Date: Thu Aug 4 22:18:01 2011 New Revision: 53068
URL: http://svn.reactos.org/svn/reactos?rev=53068&view=rev Log: [KERNEL32]: Cleanup and fix the Global* APIs for heap allocation. Mostly parameter check fixing, checking for errors and failure cases, as well as adding SEH (no real functionality improvement, other than fixing a security issue in GlobalLock). [KERNEL32]: Rename hProcessHeap to BaseHeap, and only allow the heapmem.c access to this (change find.c to use RtlGetProcessHeap() like everyone else).
Modified: trunk/reactos/dll/win32/kernel32/client/dllmain.c trunk/reactos/dll/win32/kernel32/client/file/find.c trunk/reactos/dll/win32/kernel32/client/heapmem.c trunk/reactos/dll/win32/kernel32/include/baseheap.h trunk/reactos/dll/win32/kernel32/include/kernel32.h
Modified: trunk/reactos/dll/win32/kernel32/client/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/d... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] Thu Aug 4 22:18:01 2011 @@ -29,7 +29,6 @@ WCHAR BaseDefaultPathBuffer[6140];
HANDLE BaseNamedObjectDirectory; -HANDLE hProcessHeap = NULL; HMODULE hCurrentModule = NULL; HMODULE kernel32_handle = NULL; HANDLE hBaseDir = NULL; @@ -57,13 +56,6 @@ extern BOOL FASTCALL NlsInit(VOID); extern VOID FASTCALL NlsUninit(VOID); BOOLEAN InWindows = FALSE; - -HANDLE -WINAPI -DuplicateConsoleHandle(HANDLE hConsole, - DWORD dwDesiredAccess, - BOOL bInheritHandle, - DWORD dwOptions);
#define WIN_OBJ_DIR L"\Windows" #define SESSION_DIR L"\Sessions" @@ -323,11 +315,7 @@ }
/* Initialize heap handle table */ - hProcessHeap = RtlGetProcessHeap(); - RtlInitializeHandleTable(0xFFFF, - sizeof(BASE_HEAP_HANDLE_ENTRY), - &BaseHeapHandleTable); - DPRINT("Heap: %p\n", hProcessHeap); + BaseDllInitializeMemoryManager();
/* Set HMODULE for our DLL */ kernel32_handle = hCurrentModule = hDll;
Modified: trunk/reactos/dll/win32/kernel32/client/file/find.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/f... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/file/find.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/file/find.c [iso-8859-1] Thu Aug 4 22:18:01 2011 @@ -364,7 +364,7 @@
if (!NT_SUCCESS(Status)) { - RtlFreeHeap (hProcessHeap, + RtlFreeHeap (RtlGetProcessHeap(), 0, NtPathBuffer);
@@ -387,20 +387,20 @@ { /* No file part?! */ NtClose(hDirectory); - RtlFreeHeap (hProcessHeap, + RtlFreeHeap (RtlGetProcessHeap(), 0, NtPathBuffer); SetLastError(ERROR_FILE_NOT_FOUND); return INVALID_HANDLE_VALUE; }
- IHeader = RtlAllocateHeap (hProcessHeap, + IHeader = RtlAllocateHeap (RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KERNEL32_FIND_DATA_HEADER) + sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE); if (NULL == IHeader) { - RtlFreeHeap (hProcessHeap, + RtlFreeHeap (RtlGetProcessHeap(), 0, NtPathBuffer); NtClose(hDirectory); @@ -431,7 +431,7 @@ &PathFileName, lpFindFileData);
- RtlFreeHeap (hProcessHeap, + RtlFreeHeap (RtlGetProcessHeap(), 0, NtPathBuffer);
@@ -596,7 +596,7 @@ PKERNEL32_FIND_STREAM_DATA IData = (PKERNEL32_FIND_STREAM_DATA)(IHeader + 1); if (IData->pFileStreamInfo != NULL) { - RtlFreeHeap (hProcessHeap, 0, IData->pFileStreamInfo); + RtlFreeHeap (RtlGetProcessHeap(), 0, IData->pFileStreamInfo); } break; } @@ -606,7 +606,7 @@ return FALSE; }
- RtlFreeHeap (hProcessHeap, 0, IHeader); + RtlFreeHeap (RtlGetProcessHeap(), 0, IHeader);
return TRUE; } @@ -835,7 +835,7 @@ }
/* create the search context */ - IHeader = RtlAllocateHeap(hProcessHeap, + IHeader = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(KERNEL32_FIND_DATA_HEADER) + sizeof(KERNEL32_FIND_STREAM_DATA)); @@ -859,7 +859,7 @@
if (IData->pFileStreamInfo == NULL) { - IData->pFileStreamInfo = RtlAllocateHeap(hProcessHeap, + IData->pFileStreamInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); if (IData->pFileStreamInfo == NULL) @@ -872,7 +872,7 @@ { PFILE_STREAM_INFORMATION pfsi;
- pfsi = RtlReAllocateHeap(hProcessHeap, + pfsi = RtlReAllocateHeap(RtlGetProcessHeap(), 0, IData->pFileStreamInfo, BufferSize); @@ -923,12 +923,12 @@ { if (IData->pFileStreamInfo != NULL) { - RtlFreeHeap(hProcessHeap, + RtlFreeHeap(RtlGetProcessHeap(), 0, IData->pFileStreamInfo); }
- RtlFreeHeap(hProcessHeap, + RtlFreeHeap(RtlGetProcessHeap(), 0, IHeader); }
Modified: trunk/reactos/dll/win32/kernel32/client/heapmem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/h... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/heapmem.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/heapmem.c [iso-8859-1] Thu Aug 4 22:18:01 2011 @@ -6,18 +6,36 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */
-/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG #include <debug.h>
-/* TYPES *********************************************************************/ +/* GLOBALS ********************************************************************/
RTL_HANDLE_TABLE BaseHeapHandleTable; - -/* FUNCTIONS ***************************************************************/ +HANDLE BaseHeap; +ULONG_PTR SystemRangeStart; + +/* PRIVATE FUNCTIONS **********************************************************/ + +VOID +NTAPI +BaseDllInitializeMemoryManager(VOID) +{ + BaseHeap = RtlGetProcessHeap(); + RtlInitializeHandleTable(0xFFFF, + sizeof(BASE_HEAP_HANDLE_ENTRY), + &BaseHeapHandleTable); + NtQuerySystemInformation(SystemRangeStartInformation, + &SystemRangeStart, + sizeof(SystemRangeStart), + NULL); +} + +/* PUBLIC FUNCTIONS ***********************************************************/
/* * @implemented @@ -275,6 +293,8 @@ { NTSTATUS Status;
+ DPRINT1("Warning, HeapWalk is calling RtlWalkHeap with Win32 parameters\n"); + Status = RtlWalkHeap(hHeap, lpEntry);
if (!NT_SUCCESS(Status)) @@ -353,7 +373,7 @@ HANDLE hMemory; PBASE_HEAP_HANDLE_ENTRY HandleEntry; BASE_TRACE_ALLOC(dwBytes, uFlags); - ASSERT(hProcessHeap); + ASSERT(BaseHeap);
/* Make sure the flags are valid */ if (uFlags & ~GMEM_VALID_FLAGS) @@ -374,13 +394,14 @@ if (uFlags & GMEM_DDESHARE) Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE;
/* Allocate heap for it */ - Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes ? dwBytes : 1); + if (!Ptr) SetLastError(ERROR_NOT_ENOUGH_MEMORY); BASE_TRACE_ALLOC2(Ptr); return Ptr; }
/* This is heap based, so lock it in first */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap);
/* * Disable locking, enable custom flags, and write the @@ -398,35 +419,35 @@ 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: + } + else + { + /* Get the object and make sure we have size */ + hMemory = &HandleEntry->Object; + if (dwBytes) + { + /* Allocate the actual memory for it */ + Ptr = RtlAllocateHeap(BaseHeap, 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(BaseHeap, HEAP_NO_SERIALIZE, Ptr, hMemory); + } + } + } + /* Cleanup! First unlock the heap */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap);
/* Check if a handle was allocated */ if (HandleEntry) @@ -477,7 +498,7 @@ GlobalCompact(DWORD dwMinFree) { /* Call the RTL Heap Manager */ - return RtlCompactHeap(hProcessHeap, 0); + return RtlCompactHeap(BaseHeap, 0); }
/* @@ -504,71 +525,81 @@ UINT uFlags = GMEM_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 & GMEM_LOCKCOUNT; - - /* Now check if it's discardable */ - if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE) - { - /* Set the Win32 Flag */ - uFlags |= GMEM_DISCARDABLE; - } - - /* Check if it's DDE Shared */ - if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_DDESHARE) - { - /* Set the Win32 Flag */ - uFlags |= GMEM_DDESHARE; - } - - /* Now check if it's discarded */ - if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE) - /* Set the Win32 Flag */ - uFlags |= GMEM_DISCARDED; - } - } - - /* Check if by now, we still haven't gotten any useful flags */ - if (uFlags == GMEM_INVALID_HANDLE) SetLastError(ERROR_INVALID_HANDLE); + RtlLockHeap(BaseHeap); + _SEH2_TRY + { + /* 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(BaseHeap, 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 & GMEM_LOCKCOUNT; + + /* Now check if it's discardable */ + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE) + { + /* Set the Win32 Flag */ + uFlags |= GMEM_DISCARDABLE; + } + + /* Check if it's DDE Shared */ + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_DDESHARE) + { + /* Set the Win32 Flag */ + uFlags |= GMEM_DDESHARE; + } + + /* Now check if it's discarded */ + if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE) + { + /* Set the Win32 Flag */ + uFlags |= GMEM_DISCARDED; + } + } + } + + /* Check if by now, we still haven't gotten any useful flags */ + if (uFlags == GMEM_INVALID_HANDLE) SetLastError(ERROR_INVALID_HANDLE); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Set the exception code */ + BaseSetLastNTError(_SEH2_GetExceptionCode()); + } + _SEH2_END;
/* All done! Unlock heap and return Win32 Flags */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return uFlags; }
@@ -587,7 +618,7 @@ if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { /* Free it with the RTL Heap Manager */ - if (RtlFreeHeap(hProcessHeap, 0, hMem)) + if (RtlFreeHeap(BaseHeap, 0, hMem)) { /* Return NULL since there's no handle */ return NULL; @@ -602,51 +633,67 @@ }
/* It's a handle probably, so lock the heap */ - RtlLockHeap(hProcessHeap); - - /* Make sure that this is an entry in our handle database */ - 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)) - { - /* It's not, fail */ - SetLastError(ERROR_INVALID_HANDLE); - Ptr = NULL; + RtlLockHeap(BaseHeap); + _SEH2_TRY + { + /* Make sure that this is an entry in our handle database */ + 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)) + { + /* It's not, fail */ + SetLastError(ERROR_INVALID_HANDLE); + Ptr = NULL; + } + else + { + /* It's valid, so get the pointer */ + Ptr = HandleEntry->Object; + + /* Free this handle */ + BaseHeapFreeEntry(HandleEntry); + + /* If the pointer is 0, then we don't have a handle either */ + if (!Ptr) hMem = NULL; + } } else { - /* It's valid, so get the pointer */ - Ptr = HandleEntry->Object; - - /* Free this handle */ - BaseHeapFreeEntry(HandleEntry); - - /* If the pointer is 0, then we don't have a handle either */ - if (!Ptr) hMem = NULL; - } - } - else - { - /* Otherwise, reuse the handle as a pointer */ - BASE_TRACE_FAILURE(); - Ptr = hMem; - } - - /* Check if we got here with a valid heap pointer */ - if (Ptr) - { - /* Free it */ - RtlFreeHeap(hProcessHeap, HEAP_NO_SERIALIZE, Ptr); - hMem = NULL; - } + /* Otherwise, reuse the handle as a pointer */ + BASE_TRACE_FAILURE(); + Ptr = hMem; + } + + /* Check if we got here with a valid heap pointer */ + if (Ptr) + { + /* Free it with the RTL Heap Manager */ + if (RtlFreeHeap(BaseHeap, HEAP_NO_SERIALIZE, Ptr)) + { + /* Everything worked */ + hMem = NULL; + } + else + { + /* This wasn't a real heap handle */ + SetLastError(ERROR_INVALID_HANDLE); + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Set the exception code */ + BaseSetLastNTError(_SEH2_GetExceptionCode()); + } + _SEH2_END;
/* We're done, so unlock the heap and return the handle */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return hMem; }
@@ -661,28 +708,42 @@ ULONG Flags;
/* Lock the heap */ - RtlLockHeap(hProcessHeap); - - /* Query RTL Heap */ - RtlGetUserInfoHeap(hProcessHeap, - HEAP_NO_SERIALIZE, - (PVOID)pMem, - &Handle, - &Flags); - BASE_TRACE_PTR(Handle, pMem); - - /* - * Check if RTL Heap didn't find a handle for us or said that - * this heap isn't movable. - */ - if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) - { - /* We're actually handle-based, so the pointer is a handle */ - Handle = (HANDLE)pMem; - } + RtlLockHeap(BaseHeap); + _SEH2_TRY + { + /* Query RTL Heap */ + if (!RtlGetUserInfoHeap(BaseHeap, + HEAP_NO_SERIALIZE, + (PVOID)pMem, + &Handle, + &Flags)) + { + /* RTL Heap Manager does not know about this heap */ + SetLastError(ERROR_INVALID_HANDLE); + } + else + { + /* + * Check if RTL Heap didn't find a handle for us or said that + * this heap isn't movable. + */ + BASE_TRACE_PTR(Handle, pMem); + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) + { + /* We're actually handle-based, so the pointer is a handle */ + Handle = (HANDLE)pMem; + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Set the exception code */ + BaseSetLastNTError(_SEH2_GetExceptionCode()); + } + _SEH2_END;
/* All done, unlock the heap and return the handle */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return Handle; }
@@ -699,13 +760,20 @@ /* Check if this was a simple allocated heap entry */ if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) { - /* Verify and return the pointer */ - return IsBadReadPtr(hMem, 1) ? NULL : hMem; + /* Make sure it's not a kernel or invalid address */ + if ((hMem >= (HGLOBAL)SystemRangeStart) || (IsBadReadPtr(hMem, 1))) + { + /* Signal an error */ + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + + /* It's all good */ + return hMem; }
/* Otherwise, lock the heap */ - RtlLockHeap(hProcessHeap); - + RtlLockHeap(BaseHeap); _SEH2_TRY { /* Get the handle entry */ @@ -745,10 +813,10 @@ SetLastError(ERROR_INVALID_HANDLE); Ptr = NULL; } - _SEH2_END + _SEH2_END;
/* All done. Unlock the heap and return the pointer */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return Ptr; }
@@ -763,6 +831,20 @@ LPVOID Ptr; ULONG Flags = 0;
+ /* Throw out invalid flags */ + if (uFlags & ~(GMEM_VALID_FLAGS | GMEM_MODIFY)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Throw out invalid combo */ + if ((uFlags & GMEM_DISCARDABLE) && !(uFlags & GMEM_MODIFY)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + /* Convert ZEROINIT */ if (uFlags & GMEM_ZEROINIT) Flags |= HEAP_ZERO_MEMORY;
@@ -770,7 +852,7 @@ if (!(uFlags & GMEM_MOVEABLE)) Flags |= HEAP_REALLOC_IN_PLACE_ONLY;
/* Lock the heap and disable built-in locking in the RTL Heap funcitons */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap); Flags |= HEAP_NO_SERIALIZE;
/* Check if this is a simple handle-based block */ @@ -816,14 +898,15 @@ if ((uFlags & GMEM_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; + if (RtlFreeHeap(BaseHeap, Flags, Ptr)) + { + /* Free the handle */ + HandleEntry->Object = NULL; + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE; + + /* Get the object pointer */ + hMem = &HandleEntry->Object; + } } } else @@ -839,12 +922,12 @@ if (!Ptr) { /* We don't have a base, so allocate one */ - Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes); BASE_TRACE_ALLOC2(Ptr); if (Ptr) { /* Allocation succeeded, so save our entry */ - RtlSetUserValueHeap(hProcessHeap, + RtlSetUserValueHeap(BaseHeap, HEAP_NO_SERIALIZE, Ptr, hMem); @@ -867,18 +950,8 @@ Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY; }
- /* And do the re-allocation */ - Ptr = RtlReAllocateHeap(hProcessHeap, Flags, Ptr, dwBytes); - - if (Ptr) - { - /* Allocation succeeded, so save our entry */ - RtlSetUserValueHeap(hProcessHeap, - HEAP_NO_SERIALIZE, - Ptr, - hMem); - } - + /* Do the re-allocation. No need to save the entry again */ + Ptr = RtlReAllocateHeap(BaseHeap, Flags, Ptr, dwBytes); }
/* Make sure we have a pointer by now */ @@ -904,89 +977,95 @@ { /* Get information on its current state */ Handle = hMem; - DPRINT1("h h %lx %lx\n", Handle, hMem); - RtlGetUserInfoHeap(hProcessHeap, - HEAP_NO_SERIALIZE, - hMem, - &Handle, - &Flags); - DPRINT1("h h %lx %lx\n", Handle, hMem); - - /* - * 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 & BASE_HEAP_FLAG_MOVABLE)) - { - /* Allocate a handle for it */ - 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 | BASE_HEAP_FLAG_MOVABLE; - - /* Now allocate the actual heap for it */ - HandleEntry->Object = RtlAllocateHeap(hProcessHeap, - Flags, - dwBytes); - BASE_TRACE_PTR(HandleEntry->Object, HandleEntry); - if (!HandleEntry->Object) + if (RtlGetUserInfoHeap(BaseHeap, + HEAP_NO_SERIALIZE, + hMem, + &Handle, + NULL)) + { + /* + * Check if the handle matches the pointer or the moveable flag + * isn't there, which is what we expect since it currenly isn't. + */ + if ((Handle == hMem) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) { - /* - * We failed, manually set the allocate flag and - * free the handle - */ - HandleEntry->Flags = RTL_HANDLE_VALID; - BaseHeapFreeEntry(HandleEntry); - - /* For the cleanup case */ - BASE_TRACE_FAILURE(); - HandleEntry = NULL; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + /* Allocate a handle for it */ + HandleEntry = BaseHeapAllocEntry(); + if (!HandleEntry) + { + /* No entry could be allocated */ + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + RtlUnlockHeap(BaseHeap); + return NULL; + } + + /* Calculate the size of the current heap */ + dwBytes = RtlSizeHeap(BaseHeap, HEAP_NO_SERIALIZE, hMem); + + /* Set the movable flag */ + Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVABLE; + + /* Now allocate the actual heap for it */ + HandleEntry->Object = RtlAllocateHeap(BaseHeap, + Flags, + dwBytes); + BASE_TRACE_PTR(HandleEntry->Object, HandleEntry); + if (!HandleEntry->Object) + { + /* + * We failed, manually set the allocate flag and + * free the handle + */ + HandleEntry->Flags = RTL_HANDLE_VALID; + BaseHeapFreeEntry(HandleEntry); + + /* For the cleanup case */ + BASE_TRACE_FAILURE(); + HandleEntry = NULL; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + else + { + /* Otherwise, copy the new heap and free the old one */ + RtlMoveMemory(HandleEntry->Object, hMem, dwBytes); + RtlFreeHeap(BaseHeap, HEAP_NO_SERIALIZE, hMem); + + /* Select the heap pointer */ + hMem = (HANDLE)&HandleEntry->Object; + + /* Initialize the count and default flags */ + HandleEntry->LockCount = 0; + HandleEntry->Flags = RTL_HANDLE_VALID | + BASE_HEAP_ENTRY_FLAG_MOVABLE; + + /* Check if it's also discardable */ + if (uFlags & GMEM_DISCARDABLE) + { + /* Set the internal flag */ + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; + } + + /* Check if it's also DDE Shared */ + if (uFlags & GMEM_DDESHARE) + { + /* Set the internal flag */ + HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE; + } + + /* Allocation succeeded, so save our entry */ + RtlSetUserValueHeap(BaseHeap, + HEAP_NO_SERIALIZE, + HandleEntry->Object, + hMem); + } } - else - { - /* Otherwise, copy the current heap and free the old one */ - RtlMoveMemory(HandleEntry->Object, hMem, dwBytes); - RtlFreeHeap(hProcessHeap, HEAP_NO_SERIALIZE, hMem); - - /* Select the heap pointer */ - hMem = (HANDLE)&HandleEntry->Object; - - /* Initialize the count and default flags */ - HandleEntry->LockCount = 0; - HandleEntry->Flags = RTL_HANDLE_VALID | - BASE_HEAP_ENTRY_FLAG_MOVABLE; - - /* Check if it's also discardable */ - if (uFlags & GMEM_DISCARDABLE) - { - /* Set the internal flag */ - HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE; - } - - /* Check if it's also DDE Shared */ - if (uFlags & GMEM_DDESHARE) - { - /* Set the internal flag */ - HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE; - } - - /* Allocation succeeded, so save our entry */ - RtlSetUserValueHeap(hProcessHeap, - HEAP_NO_SERIALIZE, - HandleEntry->Object, - hMem); - } } } } else { /* Otherwise, this is a simple RTL Managed Heap, so just call it */ - hMem = RtlReAllocateHeap(hProcessHeap, + hMem = RtlReAllocateHeap(BaseHeap, Flags | HEAP_NO_SERIALIZE, hMem, dwBytes); @@ -999,7 +1078,7 @@ }
/* All done, unlock the heap and return the pointer */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return hMem; }
@@ -1016,30 +1095,30 @@ SIZE_T dwSize = MAXULONG_PTR;
/* Lock the heap */ - RtlLockHeap(hProcessHeap); - + RtlLockHeap(BaseHeap); _SEH2_TRY { /* 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 give us a handle or said that this heap - * isn't 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); - } - else - { - /* Otherwise we're a handle heap, so get the internal handle */ - hMem = Handle; + if (RtlGetUserInfoHeap(BaseHeap, Flags, hMem, &Handle, &Flags)) + { + BASE_TRACE_PTR(Handle, hMem); + /* + * Check if RTL Heap didn't give us a handle or said that this + * heap isn't movable. + */ + if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE)) + { + /* We're not a handle heap, so use the generic call */ + dwSize = RtlSizeHeap(BaseHeap, HEAP_NO_SERIALIZE, hMem); + } + else + { + /* We're a handle heap so get the internal handle */ + hMem = Handle; + } } }
@@ -1065,30 +1144,30 @@ else { /* Otherwise, query RTL about it */ - dwSize = RtlSizeHeap(hProcessHeap, + dwSize = RtlSizeHeap(BaseHeap, HEAP_NO_SERIALIZE, HandleEntry->Object); } } - - /* Check if by now, we still haven't gotten any useful size */ - if (dwSize == MAXULONG_PTR) - { - /* Fail */ - BASE_TRACE_FAILURE(); - SetLastError(ERROR_INVALID_HANDLE); - dwSize = 0; - } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Set failure for later */ + dwSize = MAXULONG_PTR; + } + _SEH2_END; + + /* Check if by now, we still haven't gotten any useful size */ + if (dwSize == MAXULONG_PTR) + { + /* Fail */ + BASE_TRACE_FAILURE(); SetLastError(ERROR_INVALID_HANDLE); dwSize = 0; } - _SEH2_END
/* All done! Unlock heap and return the size */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return dwSize; }
@@ -1117,7 +1196,7 @@ if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) return RetVal;
/* Otherwise, lock the heap */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap);
/* Get the handle entry */ HandleEntry = BaseHeapGetEntry(hMem); @@ -1156,10 +1235,10 @@ SetLastError(ERROR_INVALID_PARAMETER); RetVal = FALSE; } - _SEH2_END + _SEH2_END;
/* All done. Unlock the heap and return the pointer */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return RetVal; }
@@ -1292,7 +1371,7 @@ HANDLE hMemory; PBASE_HEAP_HANDLE_ENTRY HandleEntry; BASE_TRACE_ALLOC(dwBytes, uFlags); - ASSERT(hProcessHeap); + ASSERT(BaseHeap);
/* Make sure the flags are valid */ if (uFlags & ~LMEM_VALID_FLAGS) @@ -1310,13 +1389,13 @@ if (!(uFlags & LMEM_MOVEABLE)) { /* Allocate heap for it */ - Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes); BASE_TRACE_ALLOC2(Ptr); return Ptr; }
/* This is heap based, so lock it in first */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap);
/* * Disable locking, enable custom flags, and write the @@ -1342,7 +1421,7 @@ if (dwBytes) { /* Allocate the actual memory for it */ - Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes); BASE_TRACE_PTR(HandleEntry, Ptr); if (!Ptr) { @@ -1356,13 +1435,13 @@ else { /* All worked well, save our heap entry */ - RtlSetUserValueHeap(hProcessHeap, HEAP_NO_SERIALIZE, Ptr, hMemory); + RtlSetUserValueHeap(BaseHeap, HEAP_NO_SERIALIZE, Ptr, hMemory); } }
Quickie: /* Cleanup! First unlock the heap */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap);
/* Check if a handle was allocated */ if (HandleEntry) @@ -1406,7 +1485,7 @@ LocalCompact(UINT dwMinFree) { /* Call the RTL Heap Manager */ - return RtlCompactHeap(hProcessHeap, 0); + return RtlCompactHeap(BaseHeap, 0); }
/* @@ -1422,13 +1501,13 @@ UINT uFlags = LMEM_INVALID_HANDLE;
/* Start by locking the heap */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap);
/* 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); + RtlGetUserInfoHeap(BaseHeap, Flags, hMem, &Handle, &Flags); BASE_TRACE_PTR(Handle, hMem);
/* @@ -1479,7 +1558,7 @@ if (uFlags == LMEM_INVALID_HANDLE) SetLastError(ERROR_INVALID_HANDLE);
/* All done! Unlock heap and return Win32 Flags */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return uFlags; }
@@ -1534,7 +1613,7 @@ 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); + RtlLockHeap(BaseHeap); Flags |= HEAP_NO_SERIALIZE;
/* Check if this is a simple handle-based block */ @@ -1580,7 +1659,7 @@ if ((uFlags & LMEM_MOVEABLE) && !(HandleEntry->LockCount)) { /* Free the current heap */ - RtlFreeHeap(hProcessHeap, Flags, Ptr); + RtlFreeHeap(BaseHeap, Flags, Ptr);
/* Free the handle */ HandleEntry->Object = NULL; @@ -1603,12 +1682,12 @@ if (!Ptr) { /* We don't have a base, so allocate one */ - Ptr = RtlAllocateHeap(hProcessHeap, Flags, dwBytes); + Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes); BASE_TRACE_ALLOC2(Ptr); if (Ptr) { /* Allocation succeeded, so save our entry */ - RtlSetUserValueHeap(hProcessHeap, + RtlSetUserValueHeap(BaseHeap, HEAP_NO_SERIALIZE, Ptr, hMem); @@ -1632,7 +1711,7 @@ }
/* And do the re-allocation */ - Ptr = RtlReAllocateHeap(hProcessHeap, Flags, Ptr, dwBytes); + Ptr = RtlReAllocateHeap(BaseHeap, Flags, Ptr, dwBytes); }
/* Make sure we have a pointer by now */ @@ -1654,7 +1733,7 @@ else if (!(uFlags & LMEM_MODIFY)) { /* Otherwise, this is a simple RTL Managed Heap, so just call it */ - hMem = RtlReAllocateHeap(hProcessHeap, + hMem = RtlReAllocateHeap(BaseHeap, Flags | HEAP_NO_SERIALIZE, hMem, dwBytes); @@ -1667,7 +1746,7 @@ }
/* All done, unlock the heap and return the pointer */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return hMem; }
@@ -1680,7 +1759,7 @@ UINT cbNewSize) { /* Call RTL */ - return RtlCompactHeap(hProcessHeap, 0); + return RtlCompactHeap(BaseHeap, 0); }
/* @@ -1713,12 +1792,11 @@ }
/* Otherwise, lock the heap */ - RtlLockHeap(hProcessHeap); + RtlLockHeap(BaseHeap);
/* Get the handle entry */ HandleEntry = BaseHeapGetEntry(hMem); BASE_TRACE_HANDLE(HandleEntry, hMem); - _SEH2_TRY { /* Make sure it's valid */ @@ -1752,10 +1830,10 @@ SetLastError(ERROR_INVALID_PARAMETER); RetVal = FALSE; } - _SEH2_END + _SEH2_END;
/* All done. Unlock the heap and return the pointer */ - RtlUnlockHeap(hProcessHeap); + RtlUnlockHeap(BaseHeap); return RetVal; }
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 [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/baseheap.h [iso-8859-1] Thu Aug 4 22:18:01 2011 @@ -33,12 +33,6 @@ // API for it (such as GlobalLock). //
-// -// The Handle Table -// -extern RTL_HANDLE_TABLE BaseHeapHandleTable; - -// // Tracing Support // Define _BASE_HANDLE_TRACE for Traces //
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include/... ============================================================================== --- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Thu Aug 4 22:18:01 2011 @@ -91,7 +91,6 @@ /* GLOBAL VARIABLES **********************************************************/
extern BOOL bIsFileApiAnsi; -extern HANDLE hProcessHeap; extern HANDLE hBaseDir; extern HMODULE hCurrentModule;
@@ -109,6 +108,10 @@ extern BOOLEAN BaseRunningInServerProcess;
/* FUNCTION PROTOTYPES *******************************************************/ + +VOID +NTAPI +BaseDllInitializeMemoryManager(VOID);
BOOL WINAPI VerifyConsoleIoHandle(HANDLE Handle);
@@ -249,3 +252,11 @@
/* FIXME */ WCHAR WINAPI RtlAnsiCharToUnicodeChar(LPSTR *); + +HANDLE +WINAPI +DuplicateConsoleHandle(HANDLE hConsole, + DWORD dwDesiredAccess, + BOOL bInheritHandle, + DWORD dwOptions); +