diff --git a/reactos/dll/ntdll/def/ntdll.def b/reactos/dll/ntdll/def/ntdll.def index 73f04a905f2..8c9f10ee254 100644 --- a/reactos/dll/ntdll/def/ntdll.def +++ b/reactos/dll/ntdll/def/ntdll.def @@ -361,7 +361,7 @@ RtlCreateProcessParameters@40 RtlCreateQueryDebugBuffer@8 RtlCreateRegistryKey@8 RtlCreateSecurityDescriptor@8 -;RtlCreateTagHeap +RtlCreateTagHeap@16 RtlCreateTimer@28 RtlCreateTimerQueue@4 RtlCreateUnicodeString@8 @@ -427,7 +427,7 @@ RtlEqualUnicodeString@12 RtlEraseUnicodeString@4 RtlExitUserThread@4 RtlExpandEnvironmentStrings_U@16 -;RtlExtendHeap +RtlExtendHeap@16 RtlExtendedIntegerMultiply@12 RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide@20 @@ -595,7 +595,7 @@ RtlQueryProcessDebugInformation@12 ;RtlQueryProcessLockInformation RtlQueryRegistryValues@20 RtlQuerySecurityObject@20 -;RtlQueryTagHeap +RtlQueryTagHeap@20 RtlQueryTimeZoneInformation@4 RtlRaiseException@4 RtlRaiseStatus@4 @@ -682,7 +682,7 @@ RtlUpcaseUnicodeToOemN@20 RtlUpdateTimer@16 RtlUpperChar@4 RtlUpperString@8 -;RtlUsageHeap +RtlUsageHeap@12 @RtlUshortByteSwap@4 RtlValidAcl@4 RtlValidRelativeSecurityDescriptor@12 diff --git a/reactos/dll/win32/kernel32/mem/heap.c b/reactos/dll/win32/kernel32/mem/heap.c index da748de624b..726e4545cf4 100644 --- a/reactos/dll/win32/kernel32/mem/heap.c +++ b/reactos/dll/win32/kernel32/mem/heap.c @@ -1,256 +1,266 @@ -/* $Id$ - * - * kernel/heap.c - * Copyright (C) 1996, Onno Hovers, All rights reserved - * - * This software is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this software; see the file COPYING.LIB. If - * not, write to the Free Software Foundation, Inc., 675 Mass Ave, - * Cambridge, MA 02139, USA. - * - * Win32 heap functions (HeapXXX). - * +/* + * PROJECT: ReactOS Win32 Base API + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/kernel32/mem/heap.c + * PURPOSE: Heap Memory APIs (wrappers for RtlHeap*) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* - * Adapted for the ReactOS system libraries by David Welch (welch@mcmail.com) - * Put the type definitions of the heap in a seperate header. Boudewijn Dekker - */ +/* INCLUDES ******************************************************************/ #include #define NDEBUG -#include "../include/debug.h" +#include "debug.h" + +/* FUNCTIONS ***************************************************************/ -/********************************************************************* -* HeapCreate -- KERNEL32 * -*********************************************************************/ /* * @implemented */ -HANDLE STDCALL HeapCreate(DWORD flags, DWORD dwInitialSize, DWORD dwMaximumSize) +HANDLE +WINAPI +HeapCreate(DWORD flOptions, + DWORD dwInitialSize, + DWORD dwMaximumSize) { - HANDLE hRet; - DPRINT("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, dwInitialSize, dwMaximumSize); - - hRet = RtlCreateHeap(flags, NULL, dwMaximumSize, dwInitialSize, NULL, NULL); - - if (!hRet) - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + HANDLE hRet; + ULONG Flags; - return hRet; + /* Remove non-Win32 flags and tag this allocation */ + Flags = (flOptions & (HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE)) | + HEAP_CLASS_1; + + /* Call RTL Heap */ + hRet = RtlCreateHeap(Flags, + NULL, + dwMaximumSize, + dwInitialSize, + NULL, + NULL); + + /* Set the last error if we failed, and return the pointer */ + if (!hRet) SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return hRet; } -/********************************************************************* -* HeapDestroy -- KERNEL32 * -*********************************************************************/ /* * @implemented */ -BOOL WINAPI HeapDestroy(HANDLE hheap) +BOOL +WINAPI +HeapDestroy(HANDLE hHeap) { - if (hheap == RtlGetProcessHeap()) - { - return FALSE; - } + /* Return TRUE if the heap was destroyed */ + if (!RtlDestroyHeap(hHeap)) return TRUE; - if (RtlDestroyHeap( hheap )==NULL) return TRUE; - SetLastError( ERROR_INVALID_HANDLE ); - return FALSE; + /* Otherwise, we got the handle back, so fail */ + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; } -/********************************************************************* -* GetProcessHeap -- KERNEL32 * -*********************************************************************/ /* * @implemented */ -HANDLE WINAPI GetProcessHeap(VOID) +HANDLE +WINAPI +GetProcessHeap(VOID) { - DPRINT("GetProcessHeap()\n"); - return(RtlGetProcessHeap()); + /* Call the RTL API */ + return RtlGetProcessHeap(); } -/******************************************************************** -* GetProcessHeaps -- KERNEL32 * -********************************************************************/ /* * @implemented */ -DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles) -{ - return(RtlGetProcessHeaps(maxheaps, phandles)); -} - -/********************************************************************* -* HeapLock -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -BOOL WINAPI HeapLock(HANDLE hheap) -{ - return(RtlLockHeap(hheap)); -} - -/********************************************************************* -* HeapUnlock -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -BOOL WINAPI HeapUnlock(HANDLE hheap) -{ - return(RtlUnlockHeap(hheap)); -} - -/********************************************************************* -* HeapCompact -- KERNEL32 * -* * -* NT uses this function to compact moveable blocks and other things * -* Here it does not compact, but it finds the largest free region * -*********************************************************************/ -/* - * @implemented - */ -SIZE_T WINAPI HeapCompact(HANDLE hheap, DWORD flags) -{ - return RtlCompactHeap(hheap, flags); -} - -/********************************************************************* -* HeapValidate -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -BOOL WINAPI HeapValidate(HANDLE hheap, DWORD flags, LPCVOID pmem) -{ - return(RtlValidateHeap(hheap, flags, (PVOID)pmem)); -} - - -/* - * @unimplemented - */ DWORD -STDCALL -HeapCreateTagsW ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) +WINAPI +GetProcessHeaps(DWORD NumberOfHeaps, + PHANDLE ProcessHeaps) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + /* Call the RTL API */ + return RtlGetProcessHeaps(NumberOfHeaps, ProcessHeaps); } - /* - * @unimplemented + * @implemented */ -DWORD -STDCALL -HeapExtend ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) +BOOL +WINAPI +HeapLock(HANDLE hHeap) { -#if 0 - NTSTATUS Status; - - Status = RtlExtendHeap(Unknown1, Unknown2, Unknown3, Unknown4); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FALSE; - } - return TRUE; -#endif - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + /* Call the RTL API */ + return RtlLockHeap(hHeap); } - /* - * @unimplemented + * @implemented */ -DWORD -STDCALL -HeapQueryTagW ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) +BOOL +WINAPI +HeapUnlock(HANDLE hHeap) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + /* Call the RTL API */ + return RtlUnlockHeap(hHeap); } - /* - * @unimplemented + * @implemented */ -DWORD -STDCALL -HeapSummary ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) +SIZE_T +WINAPI +HeapCompact(HANDLE hHeap, DWORD dwFlags) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + /* Call the RTL API */ + return RtlCompactHeap(hHeap, dwFlags); } - /* - * @unimplemented + * @implemented */ -DWORD -STDCALL -HeapUsage ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) +BOOL +WINAPI +HeapValidate(HANDLE hHeap, + DWORD dwFlags, + LPCVOID lpMem) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + /* Call the RTL API */ + return RtlValidateHeap(hHeap, dwFlags, (PVOID)lpMem); } +/* + * @implemented + */ +DWORD +WINAPI +HeapCreateTagsW(HANDLE hHeap, + DWORD dwFlags, + PWSTR lpTagName, + PWSTR lpTagSubName) +{ + /* Call the RTL API */ + return RtlCreateTagHeap(hHeap, + dwFlags, + lpTagName, + lpTagSubName); +} + +/* + * @implemented + */ +DWORD +WINAPI +HeapExtend(HANDLE hHeap, + DWORD dwFlags, + PVOID BaseAddress, + DWORD dwBytes) +{ + NTSTATUS Status; + + /* Call the RTL API */ + Status = RtlExtendHeap(hHeap, dwFlags, BaseAddress, dwBytes); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + SetLastErrorByStatus(Status); + return FALSE; + } + + /* Return success */ + return TRUE; +} + +/* + * @implemented + */ +PWSTR +WINAPI +HeapQueryTagW(HANDLE hHeap, + DWORD dwFlags, + WORD wTagIndex, + BOOL bResetCounters, + PVOID lpTagInfo) +{ + /* Call the RTL API */ + return RtlQueryTagHeap(hHeap, + dwFlags, + wTagIndex, + bResetCounters, + lpTagInfo); +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapSummary(HANDLE hHeap, + DWORD dwFlags, + PVOID Summary) +{ + NTSTATUS Status; + RTL_HEAP_USAGE Usage; + + /* Fill in the length information */ + Usage.Length = sizeof(Usage); + + /* Call RTL */ + Status = RtlUsageHeap(hHeap, dwFlags, &Usage); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + SetLastErrorByStatus(Status); + return FALSE; + } + + /* FIXME: Summary == Usage?! */ + RtlCopyMemory(Summary, &Usage, sizeof(Usage)); + return TRUE; +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapUsage(HANDLE hHeap, + DWORD dwFlags, + DWORD Unknown, + DWORD Unknown2, + IN PVOID Usage) +{ + NTSTATUS Status; + + /* Call RTL */ + Status = RtlUsageHeap(hHeap, dwFlags, Usage); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + SetLastErrorByStatus(Status); + return FALSE; + } + else if (Status == STATUS_MORE_ENTRIES) + { + /* There are still more entries to parse */ + return TRUE; + } + + /* Otherwise, we're completely done, so we return FALSE, but NO_ERROR */ + SetLastError(NO_ERROR); + return FALSE; +} /* * @unimplemented */ BOOL STDCALL -HeapWalk ( - HANDLE hHeap, - LPPROCESS_HEAP_ENTRY lpEntry - ) +HeapWalk(HANDLE hHeap, + LPPROCESS_HEAP_ENTRY lpEntry) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + /* Not implemented */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } - /* EOF */ diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 2d5bf3886cb..ff03b6dad42 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -452,8 +452,8 @@ RtlCreateTagHeap( ULONG NTAPI RtlCompactHeap( - HANDLE heap, - ULONG flags + HANDLE Heap, + ULONG Flags ); NTSYSAPI @@ -471,7 +471,26 @@ RtlDebugCreateHeap( NTSYSAPI HANDLE NTAPI -RtlDestroyHeap(HANDLE hheap); +RtlDestroyHeap( + IN HANDLE Heap +); + +NTSYSAPI +HANDLE +NTAPI +RtlDestroyHeap( + IN HANDLE Heap +); + +NTSYSAPI +ULONG +NTAPI +RtlExtendHeap( + IN HANDLE Heap, + IN ULONG Flags, + IN PVOID P, + IN ULONG Size +); NTSYSAPI BOOLEAN @@ -506,6 +525,17 @@ RtlGetUserInfoHeap( OUT PULONG UserFlags ); +NTSYSAPI +PWSTR +NTAPI +RtlQueryTagHeap( + IN PVOID HeapHandle, + IN ULONG Flags, + IN USHORT TagIndex, + IN BOOLEAN ResetCounters, + OUT PRTL_HEAP_TAG_INFO HeapTagInfo +); + NTSYSAPI PVOID NTAPI @@ -519,12 +549,25 @@ RtlReAllocateHeap( NTSYSAPI BOOLEAN NTAPI -RtlLockHeap(IN HANDLE Heap); +RtlLockHeap( + IN HANDLE Heap +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUsageHeap( + IN HANDLE Heap, + IN ULONG Flags, + OUT PRTL_HEAP_USAGE Usage +); NTSYSAPI BOOLEAN NTAPI -RtlUnlockHeap(IN HANDLE Heap); +RtlUnlockHeap( + IN HANDLE Heap +); BOOLEAN NTAPI @@ -550,7 +593,7 @@ NTAPI RtlValidateHeap( HANDLE Heap, ULONG Flags, - PVOID pmem + PVOID P ); #define RtlGetProcessHeap() (NtCurrentPeb()->ProcessHeap) diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index 00884f53173..40c54e9528a 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -780,6 +780,31 @@ typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX PVOID DefaultBase; } RTL_PROCESS_MODULE_INFORMATION_EX, *PRTL_PROCESS_MODULE_INFORMATION_EX; +typedef struct _RTL_HEAP_TAG_INFO +{ + ULONG NumberOfAllocations; + ULONG NumberOfFrees; + ULONG BytesAllocated; +} RTL_HEAP_TAG_INFO, *PRTL_HEAP_TAG_INFO; + +typedef struct _RTL_HEAP_USAGE_ENTRY +{ + struct _RTL_HEAP_USAGE_ENTRY *Next; +} RTL_HEAP_USAGE_ENTRY, *PRTL_HEAP_USAGE_ENTRY; + +typedef struct _RTL_HEAP_USAGE +{ + ULONG Length; + ULONG BytesAllocated; + ULONG BytesCommitted; + ULONG BytesReserved; + ULONG BytesReservedMaximum; + PRTL_HEAP_USAGE_ENTRY Entries; + PRTL_HEAP_USAGE_ENTRY AddedEntries; + PRTL_HEAP_USAGE_ENTRY RemovedEntries; + UCHAR Reserved[32]; +} RTL_HEAP_USAGE, *PRTL_HEAP_USAGE; + typedef struct _RTL_HEAP_INFORMATION { PVOID BaseAddress; diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index 6f94e2a1d95..d420a85a7f7 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -1897,4 +1897,55 @@ RtlGetUserInfoHeap(IN PVOID HeapHandle, return TRUE; } +/* + * @unimplemented + */ +NTSTATUS +NTAPI +RtlUsageHeap(IN HANDLE Heap, + IN ULONG Flags, + OUT PRTL_HEAP_USAGE Usage) +{ + /* TODO */ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +PWSTR +NTAPI +RtlQueryTagHeap(IN PVOID HeapHandle, + IN ULONG Flags, + IN USHORT TagIndex, + IN BOOLEAN ResetCounters, + OUT PRTL_HEAP_TAG_INFO HeapTagInfo) +{ + /* TODO */ + UNIMPLEMENTED; + return NULL; +} + +ULONG +NTAPI +RtlExtendHeap(IN HANDLE Heap, + IN ULONG Flags, + IN PVOID P, + IN ULONG Size) +{ + /* TODO */ + UNIMPLEMENTED; + return 0; +} + +ULONG +NTAPI +RtlCreateTagHeap(IN HANDLE HeapHandle, + IN ULONG Flags, + IN PWSTR TagName, + IN PWSTR TagSubName) +{ + /* TODO */ + UNIMPLEMENTED; + return 0; +} + /* EOF */