ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
June 2006
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
19 participants
595 discussions
Start a n
N
ew thread
[ion] 22583: - Reformat heap.c to ROS standards - HeapCreate should mask out NT flags and tag allocations with CLASS 1. - Implemented HeapCreateTagsW, HeapExtend, HeapQueryTagW, HeapSummary, HeapUsage. - Stubbed RtlUsageHeap, RtlQueryTagHeap, RtlExtendHeap, RtlCreateTagHeap.
by ion@svn.reactos.org
Author: ion Date: Sat Jun 24 23:49:28 2006 New Revision: 22583 URL:
http://svn.reactos.org/svn/reactos?rev=22583&view=rev
Log: - Reformat heap.c to ROS standards - HeapCreate should mask out NT flags and tag allocations with CLASS 1. - Implemented HeapCreateTagsW, HeapExtend, HeapQueryTagW, HeapSummary, HeapUsage. - Stubbed RtlUsageHeap, RtlQueryTagHeap, RtlExtendHeap, RtlCreateTagHeap. Modified: trunk/reactos/dll/ntdll/def/ntdll.def trunk/reactos/dll/win32/kernel32/mem/heap.c trunk/reactos/include/ndk/rtlfuncs.h trunk/reactos/include/ndk/rtltypes.h trunk/reactos/lib/rtl/heap.c Modified: trunk/reactos/dll/ntdll/def/ntdll.def URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/def/ntdll.def?re…
============================================================================== --- trunk/reactos/dll/ntdll/def/ntdll.def (original) +++ trunk/reactos/dll/ntdll/def/ntdll.def Sat Jun 24 23:49:28 2006 @@ -361,7 +361,7 @@ RtlCreateQueryDebugBuffer@8 RtlCreateRegistryKey@8 RtlCreateSecurityDescriptor@8 -;RtlCreateTagHeap +RtlCreateTagHeap@16 RtlCreateTimer@28 RtlCreateTimerQueue@4 RtlCreateUnicodeString@8 @@ -427,7 +427,7 @@ RtlEraseUnicodeString@4 RtlExitUserThread@4 RtlExpandEnvironmentStrings_U@16 -;RtlExtendHeap +RtlExtendHeap@16 RtlExtendedIntegerMultiply@12 RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide@20 @@ -595,7 +595,7 @@ ;RtlQueryProcessLockInformation RtlQueryRegistryValues@20 RtlQuerySecurityObject@20 -;RtlQueryTagHeap +RtlQueryTagHeap@20 RtlQueryTimeZoneInformation@4 RtlRaiseException@4 RtlRaiseStatus@4 @@ -682,7 +682,7 @@ RtlUpdateTimer@16 RtlUpperChar@4 RtlUpperString@8 -;RtlUsageHeap +RtlUsageHeap@12 @RtlUshortByteSwap@4 RtlValidAcl@4 RtlValidRelativeSecurityDescriptor@12 Modified: trunk/reactos/dll/win32/kernel32/mem/heap.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/mem/hea…
============================================================================== --- trunk/reactos/dll/win32/kernel32/mem/heap.c (original) +++ trunk/reactos/dll/win32/kernel32/mem/heap.c Sat Jun 24 23:49:28 2006 @@ -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). - * - */ - -/* - * Adapted for the ReactOS system libraries by David Welch (welch(a)mcmail.com) - * Put the type definitions of the heap in a seperate header. Boudewijn Dekker - */ +/* + * 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(a)reactos.org) + */ + +/* INCLUDES ******************************************************************/ #include <k32.h> #define NDEBUG -#include "../include/debug.h" - -/********************************************************************* -* HeapCreate -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -HANDLE STDCALL HeapCreate(DWORD flags, 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); - - return hRet; -} - -/********************************************************************* -* HeapDestroy -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -BOOL WINAPI HeapDestroy(HANDLE hheap) -{ - if (hheap == RtlGetProcessHeap()) - { - return FALSE; - } - - if (RtlDestroyHeap( hheap )==NULL) return TRUE; - SetLastError( ERROR_INVALID_HANDLE ); - return FALSE; -} - -/********************************************************************* -* GetProcessHeap -- KERNEL32 * -*********************************************************************/ -/* - * @implemented - */ -HANDLE WINAPI GetProcessHeap(VOID) -{ - DPRINT("GetProcessHeap()\n"); - 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)); -} - +#include "debug.h" + +/* FUNCTIONS ***************************************************************/ + +/* + * @implemented + */ +HANDLE +WINAPI +HeapCreate(DWORD flOptions, + DWORD dwInitialSize, + DWORD dwMaximumSize) +{ + HANDLE hRet; + ULONG Flags; + + /* 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; +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapDestroy(HANDLE hHeap) +{ + /* Return TRUE if the heap was destroyed */ + if (!RtlDestroyHeap(hHeap)) return TRUE; + + /* Otherwise, we got the handle back, so fail */ + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; +} + +/* + * @implemented + */ +HANDLE +WINAPI +GetProcessHeap(VOID) +{ + /* Call the RTL API */ + return RtlGetProcessHeap(); +} + +/* + * @implemented + */ +DWORD +WINAPI +GetProcessHeaps(DWORD NumberOfHeaps, + PHANDLE ProcessHeaps) +{ + /* Call the RTL API */ + return RtlGetProcessHeaps(NumberOfHeaps, ProcessHeaps); +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapLock(HANDLE hHeap) +{ + /* Call the RTL API */ + return RtlLockHeap(hHeap); +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapUnlock(HANDLE hHeap) +{ + /* Call the RTL API */ + return RtlUnlockHeap(hHeap); +} + +/* + * @implemented + */ +SIZE_T +WINAPI +HeapCompact(HANDLE hHeap, DWORD dwFlags) +{ + /* Call the RTL API */ + return RtlCompactHeap(hHeap, dwFlags); +} + +/* + * @implemented + */ +BOOL +WINAPI +HeapValidate(HANDLE hHeap, + DWORD dwFlags, + LPCVOID lpMem) +{ + /* 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 */ -DWORD +BOOL STDCALL -HeapCreateTagsW ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -DWORD -STDCALL -HeapExtend ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) -{ -#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; -} - - -/* - * @unimplemented - */ -DWORD -STDCALL -HeapQueryTagW ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -DWORD -STDCALL -HeapSummary ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -DWORD -STDCALL -HeapUsage ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -BOOL -STDCALL -HeapWalk ( - HANDLE hHeap, - LPPROCESS_HEAP_ENTRY lpEntry - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - +HeapWalk(HANDLE hHeap, + LPPROCESS_HEAP_ENTRY lpEntry) +{ + /* Not implemented */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} /* EOF */ Modified: trunk/reactos/include/ndk/rtlfuncs.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev…
============================================================================== --- trunk/reactos/include/ndk/rtlfuncs.h (original) +++ trunk/reactos/include/ndk/rtlfuncs.h Sat Jun 24 23:49:28 2006 @@ -452,8 +452,8 @@ ULONG NTAPI RtlCompactHeap( - HANDLE heap, - ULONG flags + HANDLE Heap, + ULONG Flags ); NTSYSAPI @@ -471,7 +471,26 @@ 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 @@ -507,6 +526,17 @@ ); 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 RtlReAllocateHeap( @@ -519,12 +549,25 @@ NTSYSAPI BOOLEAN NTAPI -RtlLockHeap(IN HANDLE Heap); - -NTSYSAPI -BOOLEAN -NTAPI -RtlUnlockHeap(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 +); BOOLEAN NTAPI @@ -550,7 +593,7 @@ RtlValidateHeap( HANDLE Heap, ULONG Flags, - PVOID pmem + PVOID P ); #define RtlGetProcessHeap() (NtCurrentPeb()->ProcessHeap) Modified: trunk/reactos/include/ndk/rtltypes.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtltypes.h?rev…
============================================================================== --- trunk/reactos/include/ndk/rtltypes.h (original) +++ trunk/reactos/include/ndk/rtltypes.h Sat Jun 24 23:49:28 2006 @@ -779,6 +779,31 @@ ULONG TimeDateStamp; 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 { Modified: trunk/reactos/lib/rtl/heap.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=22583&r…
============================================================================== --- trunk/reactos/lib/rtl/heap.c (original) +++ trunk/reactos/lib/rtl/heap.c Sat Jun 24 23:49:28 2006 @@ -1897,4 +1897,55 @@ 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 */
18 years, 6 months
1
0
0
0
[ion] 22582: - 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.
by ion@svn.reactos.org
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/glo…
============================================================================== --- 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/loc…
============================================================================== --- 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(a)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/dl…
============================================================================== --- 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=2258…
============================================================================== --- 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);
18 years, 6 months
1
0
0
0
[hpoussin] 22581: Fix prototype of WritePwrScheme. Prototypes shouldn't have LPTSTR in their parameter list!
by hpoussin@svn.reactos.org
Author: hpoussin Date: Sat Jun 24 22:47:50 2006 New Revision: 22581 URL:
http://svn.reactos.org/svn/reactos?rev=22581&view=rev
Log: Fix prototype of WritePwrScheme. Prototypes shouldn't have LPTSTR in their parameter list! Modified: trunk/reactos/include/powrprof.h Modified: trunk/reactos/include/powrprof.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/powrprof.h?rev=225…
============================================================================== --- trunk/reactos/include/powrprof.h (original) +++ trunk/reactos/include/powrprof.h Sat Jun 24 22:47:50 2006 @@ -90,7 +90,7 @@ USER_POWER_POLICY user; MACHINE_POWER_POLICY mach; } POWER_POLICY, *PPOWER_POLICY; -typedef BOOLEAN (CALLBACK* PWRSCHEMESENUMPROC)(UINT, DWORD, LPTSTR, DWORD, LPTSTR, PPOWER_POLICY, LPARAM); +typedef BOOLEAN (CALLBACK* PWRSCHEMESENUMPROC)(UINT, DWORD, LPWSTR, DWORD, LPWSTR, PPOWER_POLICY, LPARAM); typedef BOOLEAN (CALLBACK* PFNNTINITIATEPWRACTION)(POWER_ACTION, SYSTEM_POWER_STATE, ULONG, BOOLEAN); NTSTATUS WINAPI CallNtPowerInformation(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); BOOLEAN WINAPI CanUserWritePwrScheme(VOID); @@ -112,7 +112,7 @@ BOOLEAN WINAPI WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY); BOOLEAN WINAPI WriteProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY); BOOLEAN WINAPI ValidatePowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY); -BOOLEAN WINAPI WritePwrScheme(PUINT, LPTSTR, LPTSTR, PPOWER_POLICY); +BOOLEAN WINAPI WritePwrScheme(PUINT, LPWSTR, LPWSTR, PPOWER_POLICY); #endif /* RC_INVOKED */
18 years, 6 months
1
0
0
0
[hpoussin] 22580: Fix definition of NtGdiAlphaBlend
by hpoussin@svn.reactos.org
Author: hpoussin Date: Sat Jun 24 22:26:28 2006 New Revision: 22580 URL:
http://svn.reactos.org/svn/reactos?rev=22580&view=rev
Log: Fix definition of NtGdiAlphaBlend Modified: trunk/reactos/include/ntgdi.h trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c Modified: trunk/reactos/include/ntgdi.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ntgdi.h?rev=22580&…
============================================================================== --- trunk/reactos/include/ntgdi.h (original) +++ trunk/reactos/include/ntgdi.h Sat Jun 24 22:26:28 2006 @@ -1097,8 +1097,7 @@ IN LONG SrcY, IN LONG SrcCx, IN LONG SrcCy, - IN BLENDFUNCTION BlendFunction, - IN HANDLE hcmXform + IN BLENDFUNCTION BlendFunction ); W32KAPI Modified: trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c (original) +++ trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c Sat Jun 24 22:26:28 2006 @@ -1341,8 +1341,7 @@ LONG YOriginSrc, LONG WidthSrc, LONG HeightSrc, - BLENDFUNCTION BlendFunc, - IN HANDLE hcmXform) + BLENDFUNCTION BlendFunc) { PDC DCDest = NULL; PDC DCSrc = NULL; @@ -1352,7 +1351,7 @@ XLATEOBJ *XlateObj; BLENDOBJ BlendObj; HPALETTE SourcePalette = 0, DestPalette = 0; - BlendObj.BlendFunction = BlendFunc; + BlendObj.BlendFunction = BlendFunc; DCDest = DC_LockDc(hDCDest); if (NULL == DCDest)
18 years, 6 months
1
0
0
0
[ion] 22579: - Rewrote Base Heap implementation nearly from scratch, currently only for Global Heap (Local Heap is as broken as before, since it still calls the Global Heap APIs). For detailed implementation notes, see baseheap.h - Main changes include using the RtlHandle package instead of duplicating an internal implementation, as well as using the RtlHeap* APIs that allow for setting User Flags/Values for associating Base Heap Flags/Handles with the actual RTL-managed block. - Regression-test
by ion@svn.reactos.org
Author: ion Date: Sat Jun 24 22:11:57 2006 New Revision: 22579 URL:
http://svn.reactos.org/svn/reactos?rev=22579&view=rev
Log: - Rewrote Base Heap implementation nearly from scratch, currently only for Global Heap (Local Heap is as broken as before, since it still calls the Global Heap APIs). For detailed implementation notes, see baseheap.h - Main changes include using the RtlHandle package instead of duplicating an internal implementation, as well as using the RtlHeap* APIs that allow for setting User Flags/Values for associating Base Heap Flags/Handles with the actual RTL-managed block. - Regression-tested with WINE tests and basic ROS apps. Added: trunk/reactos/dll/win32/kernel32/include/baseheap.h Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h trunk/reactos/dll/win32/kernel32/mem/global.c trunk/reactos/dll/win32/kernel32/misc/dllmain.c Added: 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 (added) +++ trunk/reactos/dll/win32/kernel32/include/baseheap.h Sat Jun 24 22:11:57 2006 @@ -1,0 +1,121 @@ +/* + * PROJECT: ReactOS Win32 Base API + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/kernel32/include/baseheap.h + * PURPOSE: Base Heap Structures + * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org) + */ + +// +// Some important implementation notes. +// +// Firstly, the Global* APIs in Win32 are largely similar to the Local* APIs, +// but there are a number of small differences (for example, there is no such +// thing as DDE/Shared Local memory, and the re-allocation semantics are also +// simpler, because you cannot force a move). +// +// Note something VERY IMPORTANT: This implementation *depends* on the fact +// that all heap pointers are, at the very least, 8 byte aligned, and that heap +// handles are actually pointers inside our HandleEntry->Object, which happens +// to be at offset 0x4, which means testing with bit 3 tells us if the handle +// is a pointer or a real "handle". On 64-bit, heap pointers should be 16-byte +// aligned, and our offset should be 0x8, so the trick works anyways, but using +// the 4th bit. +// +// Apart from MSDN, a wonderful source of information about how this works is +// available on Raymond's blog, in a 4-parter series starting at: +//
http://blogs.msdn.com/oldnewthing/archive/2004/11/04/252258.aspx
. +// +// Finally, as Raymond points out, be aware that some applications depend on +// the way this implementation was done, since global memory handles are a +// straight-forward overlay on top of the RTL Handle implementation, and rogue +// applications can easily do the conversion manually without calling the right +// API for it (such as GlobalLock). +// + +// +// The Handle Table +// +extern RTL_HANDLE_TABLE BaseGlobalHandleTable; + +// +// Tracing Support +// Define _BASE_HANDLE_TRACE for Traces +// +#ifdef _BASE_HANDLE_TRACE_ +#define BH_PRINT DbgPrint +#else +#define BH_PRINT DPRINT +#endif +#define BASE_TRACE_ALLOC(x, y) \ + BH_PRINT("[BASE_HEAP] %s : Allocating %lx bytes with flags: %lx\n", \ + __FUNCTION__, x, y) +#define BASE_TRACE_ALLOC2(x) \ + BH_PRINT("[BASE_HEAP] %s : Allocated %p\n", \ + __FUNCTION__, x) +#define BASE_TRACE_PTR(x, y) \ + BH_PRINT("[BASE_HEAP] %s : Using handle: %lx for pointer: %p\n", \ + __FUNCTION__, x, y) +#define BASE_TRACE_HANDLE(x, y) \ + BH_PRINT("[BASE_HEAP] %s : Using handle: %lx for block: %p\n", \ + __FUNCTION__, x, y) +#define BASE_TRACE_DEALLOC(x) \ + BH_PRINT("[BASE_HEAP] %s : Freeing %p\n", \ + __FUNCTION__, x) + +// +// 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 +{ + USHORT Flags; + USHORT LockCount; + union + { + PVOID Object; + ULONG OldSize; + }; +} GLOBAL_HEAP_HANDLE_ENTRY, *PGLOBAL_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 + +// +// 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) + +// +// 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 + +// +// Internal Handle Functions +// +#define GlobalAllocEntry() \ + (PGLOBAL_HEAP_HANDLE_ENTRY)RtlAllocateHandle(&BaseGlobalHandleTable, NULL) + +#define GlobalGetEntry(h) \ + (PGLOBAL_HEAP_HANDLE_ENTRY) \ + CONTAINING_RECORD(h, \ + GLOBAL_HEAP_HANDLE_ENTRY, \ + Object); + +#define GlobalValidateEntry(he) \ + RtlIsValidHandle(&BaseGlobalHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he) + +#define GlobalFreeEntry(he) \ + RtlFreeHandle(&BaseGlobalHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he); + 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 (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h Sat Jun 24 22:11:57 2006 @@ -1,5 +1,7 @@ #ifndef _KERNEL32_INCLUDE_KERNEL32_H #define _KERNEL32_INCLUDE_KERNEL32_H + +#include "baseheap.h" #define BINARY_UNKNOWN (0) #define BINARY_PE_EXE32 (1) Modified: trunk/reactos/dll/win32/kernel32/mem/global.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/mem/glo…
============================================================================== --- trunk/reactos/dll/win32/kernel32/mem/global.c (original) +++ trunk/reactos/dll/win32/kernel32/mem/global.c Sat Jun 24 22:11:57 2006 @@ -1,740 +1,931 @@ -/* $Id$ - * - * Win32 Global/Local heap functions (GlobalXXX, LocalXXX). - * These functions included in Win32 for compatibility with 16 bit Windows - * Especially the moveable blocks and handles are oldish. - * But the ability to directly allocate memory with GPTR and LPTR is widely - * used. - * - * Updated to support movable memory with algorithms taken from wine. - */ +/* + * PROJECT: ReactOS Win32 Base API + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/kernel32/mem/global.c + * PURPOSE: Global Memory APIs (sits on top of Heap*) + * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org) + */ + +/* INCLUDES ******************************************************************/ #include <k32.h> #define NDEBUG -#include "../include/debug.h" - -#ifdef _GNUC_ -#define STRUCT_PACK __attribute__((packed)) -#else -#define STRUCT_PACK -#endif - -#define MAGIC_GLOBAL_USED 0x5342BEEF -#define GLOBAL_LOCK_MAX 0xFF - -/*Wine found that some applications complain if memory isn't 8 byte aligned. -* We make use of that experience here. -*/ -#define HANDLE_SIZE 8 /*sizeof(HANDLE) *2 */ - - -typedef struct __GLOBAL_LOCAL_HANDLE -{ - DWORD Magic; - LPVOID Pointer; STRUCT_PACK - BYTE Flags; - BYTE LockCount; -} GLOBAL_HANDLE, LOCAL_HANDLE, *PGLOBAL_HANDLE, *PLOCAL_HANDLE; - -#define HANDLE_TO_INTERN(h) ((PGLOBAL_HANDLE)(((char *)(h))-4)) -#define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer)) -#define POINTER_TO_HANDLE(p) (*(PHANDLE)((ULONG_PTR)p - HANDLE_SIZE)) -#define ISHANDLE(h) ((((ULONG)(h)) & 0x4)!=0) -#define ISPOINTER(h) ((((ULONG)(h)) & 0x4)==0) - - -static void DbgPrintStruct(PGLOBAL_HANDLE h) -{ - DPRINT("Magic: 0x%X\n", h->Magic); - DPRINT("Pointer: 0x%X\n", h->Pointer); - DPRINT("Flags: 0x%X\n", h->Flags); - DPRINT("LockCount: 0x%X\n", h->LockCount); -} - - +#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; /* FUNCTIONS ***************************************************************/ /* * @implemented */ -HGLOBAL STDCALL +HGLOBAL +NTAPI GlobalAlloc(UINT uFlags, DWORD dwBytes) { - - PGLOBAL_HANDLE phandle = 0; - PVOID palloc = 0; - UINT heap_flags = 0; - - if (uFlags & GMEM_ZEROINIT) - { - heap_flags = HEAP_ZERO_MEMORY; - } - - DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", uFlags, dwBytes); - - //Changed hProcessHeap to GetProcessHeap() - if ((uFlags & GMEM_MOVEABLE)==0) /* POINTER */ - { - palloc = RtlAllocateHeap(GetProcessHeap(), heap_flags, dwBytes); - if (! ISPOINTER(palloc)) - { - DPRINT1("GlobalAlloced pointer which is not 8-byte aligned\n"); - RtlFreeHeap(GetProcessHeap(), 0, palloc); + ULONG Flags = 0; + PVOID Ptr = NULL; + HANDLE hMemory; + PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + BASE_TRACE_ALLOC(dwBytes, uFlags); + ASSERT(hProcessHeap); + + /* Make sure the flags are valid */ + if (uFlags & ~GMEM_VALID_FLAGS) + { + /* They aren't, fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Convert ZEROINIT */ + if (uFlags & GMEM_ZEROINIT) Flags |= HEAP_ZERO_MEMORY; + + /* Check if we're not movable, which means pointer-based heap */ + if (!(uFlags & GMEM_MOVEABLE)) + { + /* Check if this is DDESHARE (deprecated) */ + if (uFlags & GMEM_DDESHARE) Flags |= GLOBAL_HEAP_ENTRY_FLAG_DDESHARE; + + /* 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 | + GLOBAL_HEAP_FLAG_MOVABLE; + + /* Allocate the handle */ + HandleEntry = GlobalAllocEntry(); + 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; + GlobalFreeEntry(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 = GLOBAL_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; + } + + /* Check if the handle is moveable */ + if (uFlags & GMEM_MOVEABLE) + { + /* Save it in the handle entry */ + HandleEntry->Flags |= GLOBAL_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; + } + + /* Set the pointer */ + Ptr = hMemory; + } + + /* Return the pointer */ + return Ptr; +} + +/* + * @implemented + */ +SIZE_T +NTAPI +GlobalCompact(DWORD dwMinFree) +{ + /* Call the RTL Heap Manager */ + return RtlCompactHeap(hProcessHeap, 0); +} + +/* + * @implemented + */ +VOID +NTAPI +GlobalFix(HGLOBAL hMem) +{ + /* Lock the memory if it the handle is valid */ + if (INVALID_HANDLE_VALUE != hMem) GlobalLock(hMem); +} + +/* + * @implemented + */ +UINT +NTAPI +GlobalFlags(HGLOBAL hMem) +{ + PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + HANDLE Handle = NULL; + ULONG Flags = 0; + 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 & GLOBAL_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 & GLOBAL_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 & GLOBAL_HEAP_IS_HANDLE_ENTRY) + { + /* Then get the entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure it's a valid handle */ + if (GlobalValidateEntry(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) + { + /* Set the Win32 Flag */ + uFlags |= GMEM_DISCARDED; + } + + /* Check if it's movable */ + if (HandleEntry->Flags & GLOBAL_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) + { + /* Set the Win32 Flag */ + uFlags |= GMEM_DDESHARE; + } + } + } + + /* Check if by now, we still haven't gotten any useful flags */ + if (uFlags == GMEM_INVALID_HANDLE) SetLastError(ERROR_INVALID_HANDLE); + + /* All done! Unlock heap and return Win32 Flags */ + RtlUnlockHeap(hProcessHeap); + return uFlags; +} + +/* + * @implemented + */ +HGLOBAL +NTAPI +GlobalFree(HGLOBAL hMem) +{ + PGLOBAL_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)) + { + /* Free it with the RTL Heap Manager */ + if (RtlFreeHeap(hProcessHeap, 0, hMem)) + { + /* Return NULL since there's no handle */ return NULL; } - return (HGLOBAL) palloc; - } - else /* HANDLE */ - { - HeapLock(hProcessHeap); - - phandle = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(GLOBAL_HANDLE)); - if (phandle) - { - phandle->Magic = MAGIC_GLOBAL_USED; - phandle->Flags = uFlags >> 8; - phandle->LockCount = 0; - phandle->Pointer = 0; - - if (dwBytes) + else + { + /* Otherwise fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + return hMem; + } + } + + /* 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 & GLOBAL_HEAP_IS_HANDLE_ENTRY) + { + /* Get the entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure the handle is valid */ + if (!GlobalValidateEntry(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 */ + GlobalFreeEntry(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; + } + + /* We're done, so unlock the heap and return the handle */ + RtlUnlockHeap(hProcessHeap); + return hMem; +} + +/* + * @implemented + */ +HGLOBAL +NTAPI +GlobalHandle(LPCVOID pMem) +{ + HANDLE Handle = NULL; + 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 & GLOBAL_HEAP_FLAG_MOVABLE)) + { + /* We're actually handle-based, so the pointer is a handle */ + Handle = (HANDLE)pMem; + } + + /* All done, unlock the heap and return the handle */ + RtlUnlockHeap(hProcessHeap); + return Handle; +} + +/* + * @implemented + */ +LPVOID +NTAPI +GlobalLock(HGLOBAL hMem) +{ + PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + LPVOID Ptr; + + /* Check if this was a simple allocated heap entry */ + if (!((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY)) + { + /* Then simply return the pointer */ + return hMem; + } + + /* Otherwise, lock the heap */ + RtlLockHeap(hProcessHeap); + + /* Get the handle entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure it's valid */ + if (!GlobalValidateEntry(HandleEntry)) + { + /* It's not, fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + Ptr = NULL; + } + else + { + /* Otherwise, get the pointer */ + Ptr = HandleEntry->Object; + if (Ptr) + { + /* Increase the lock count, unless we've went too far */ + if (HandleEntry->LockCount++ == GMEM_LOCKCOUNT) { - palloc = RtlAllocateHeap(GetProcessHeap(), heap_flags, dwBytes + HANDLE_SIZE); - if (palloc) + /* In which case we simply unlock once */ + HandleEntry->LockCount--; + } + } + else + { + /* The handle is still there but the memory was already freed */ + SetLastError(ERROR_DISCARDED); + } + } + + /* All done. Unlock the heap and return the pointer */ + RtlUnlockHeap(hProcessHeap); + return Ptr; +} + +HGLOBAL +NTAPI +GlobalReAlloc(HGLOBAL hMem, + DWORD dwBytes, + UINT uFlags) +{ + PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + HANDLE Handle; + LPVOID Ptr; + ULONG Flags = 0; + + /* Convert ZEROINIT */ + if (uFlags & GMEM_ZEROINIT) Flags |= HEAP_ZERO_MEMORY; + + /* If this wasn't a movable heap, then we MUST re-alloc in place */ + 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); + 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)) + { + /* Get the entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure the handle is valid */ + if (!GlobalValidateEntry(HandleEntry)) + { + /* Fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + hMem = NULL; + } + else if (uFlags & GMEM_MODIFY) + { + /* User is changing flags... check if the memory was discardable */ + if (uFlags & GMEM_DISCARDABLE) + { + /* Then set the flag */ + HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSABLE; + } + else + { + /* Otherwise, remove the flag */ + HandleEntry->Flags &= GLOBAL_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) { - *(PHANDLE)palloc = INTERN_TO_HANDLE(phandle); - phandle->Pointer = (PVOID)((ULONG_PTR)palloc + HANDLE_SIZE); + /* Make sure the handle isn't locked */ + if ((uFlags & GMEM_MOVEABLE) & !(HandleEntry->LockCount)) + { + /* Free the current heap */ + RtlFreeHeap(hProcessHeap, Flags, Ptr); + + /* Free the handle */ + HandleEntry->Object = NULL; + HandleEntry->Flags |= GLOBAL_HEAP_ENTRY_FLAG_REUSE; + + /* Get the object pointer */ + hMem = &HandleEntry->Object; + } } - else /*failed to allocate the memory block*/ + else { - RtlFreeHeap(GetProcessHeap(), 0, phandle); - phandle = 0; + /* Otherwise just return the object pointer */ + hMem = &HandleEntry->Object; } } else { - DPRINT("Allocated a 0 size movable block.\n"); - DbgPrintStruct(phandle); - DPRINT("Address of the struct: 0x%X\n", phandle); - DPRINT("Address of pointer: 0x%X\n", &(phandle->Pointer)); - } - } - HeapUnlock(hProcessHeap); - - if (phandle) - { - if (ISPOINTER(INTERN_TO_HANDLE(phandle))) - { - DPRINT1("GlobalAlloced handle which is 8-byte aligned but shouldn't be\n"); - RtlFreeHeap(GetProcessHeap(), 0, palloc); - RtlFreeHeap(GetProcessHeap(), 0, phandle); - return NULL; - } - return INTERN_TO_HANDLE(phandle); - } - else - return (HGLOBAL)0; - } -} - - -/* - * @implemented - */ -SIZE_T STDCALL -GlobalCompact(DWORD dwMinFree) -{ - return RtlCompactHeap(hProcessHeap, 0); -} - - -/* - * @implemented - */ -VOID STDCALL -GlobalFix(HGLOBAL hMem) -{ - if (INVALID_HANDLE_VALUE != hMem) - GlobalLock(hMem); -} - -/* - * @implemented - */ -UINT STDCALL -GlobalFlags(HGLOBAL hMem) -{ - DWORD retval; - PGLOBAL_HANDLE phandle; - - DPRINT("GlobalFlags( 0x%lX )\n", (ULONG)hMem); - - if(!ISHANDLE(hMem)) - { - DPRINT("GlobalFlags: Fixed memory.\n"); - retval = 0; - } - else - { - HeapLock(GetProcessHeap()); - - phandle = HANDLE_TO_INTERN(hMem); - - /*DbgPrintStruct(phandle);*/ - - if (MAGIC_GLOBAL_USED == phandle->Magic) - { - /*DbgPrint("GlobalFlags: Magic number ok\n"); - **DbgPrint("GlobalFlags: pointer is 0x%X\n", phandle->Pointer); - */ - retval = phandle->LockCount + (phandle->Flags << 8); - if (0 == phandle->Pointer) - { - retval = retval | GMEM_DISCARDED; - } - } - else - { - DPRINT1("GlobalSize: invalid handle\n"); - retval = 0; - } - HeapUnlock(GetProcessHeap()); - } - return retval; -} - - -/* - * @implemented - */ -HGLOBAL STDCALL -GlobalFree(HGLOBAL hMem) -{ - PGLOBAL_HANDLE phandle; - HGLOBAL hreturned; - - DPRINT("GlobalFree( 0x%lX )\n", (ULONG)hMem); - - hreturned = 0; - if (ISPOINTER(hMem)) /* POINTER */ - { - if(!RtlFreeHeap(GetProcessHeap(), 0, (PVOID)hMem)) - hMem = 0; - } - else /* HANDLE */ - { - HeapLock(GetProcessHeap()); - - phandle = HANDLE_TO_INTERN(hMem); - - if(MAGIC_GLOBAL_USED == phandle->Magic) - { - /* WIN98 does not make this test. That is you can free a */ - /* block you have not unlocked. Go figure!! */ - if(phandle->LockCount!=0) - { - DPRINT1("Warning! GlobalFree(0x%X) Freeing a handle to a locked object.\n", hMem); - SetLastError(ERROR_INVALID_HANDLE); - } - - if(phandle->Pointer) - if (!RtlFreeHeap(GetProcessHeap(), 0, (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE))) - hreturned = hMem; - - if (!RtlFreeHeap(GetProcessHeap(), 0, phandle)) - hreturned = hMem; - } - HeapUnlock(GetProcessHeap()); - - hMem = 0; - } - return hreturned; -} - - -/* - * @implemented - */ -HGLOBAL STDCALL -GlobalHandle(LPCVOID pMem) -{ - HGLOBAL handle = 0; - PGLOBAL_HANDLE test = 0; - LPCVOID pointer_test = 0; - - DPRINT("GlobalHandle( 0x%lX )\n", (ULONG)pMem); - if (0 == pMem) /*Invalid argument */ - { - SetLastError(ERROR_INVALID_PARAMETER); - DPRINT1("Error: 0 handle.\n"); - return 0; - } - - HeapLock(GetProcessHeap()); - /* Now test to see if this pointer is associated with a handle. - * This is done by calling RtlValidateHeap() and seeing if it fails. - */ - if (RtlValidateHeap(GetProcessHeap(), 0, (char *)pMem)) /*FIXED*/ - { - handle = (HGLOBAL)pMem; - return handle; - } - else /*MOVABLE*/ - { - handle = POINTER_TO_HANDLE(pMem); - } - - - /* Test to see if this memory is valid*/ - test = HANDLE_TO_INTERN(handle); - if (!IsBadReadPtr(test, sizeof(GLOBAL_HANDLE))) - { - if (MAGIC_GLOBAL_USED == test->Magic) - { - pointer_test = test->Pointer; - if (!RtlValidateHeap(GetProcessHeap(), 0, ((char *)pointer_test) - HANDLE_SIZE) || - !RtlValidateHeap(GetProcessHeap(), 0, test)) - { - SetLastError(ERROR_INVALID_HANDLE); - handle = 0; - } - } - } - else - { - DPRINT1("GlobalHandle: Bad read pointer.\n"); - SetLastError(ERROR_INVALID_HANDLE); - handle = 0; - } - - HeapUnlock(GetProcessHeap()); - - return handle; -} - - -/* - * @implemented - */ -LPVOID STDCALL -GlobalLock(HGLOBAL hMem) -{ - PGLOBAL_HANDLE phandle; - LPVOID palloc; - - DPRINT("GlobalLock( 0x%lX )\n", (ULONG)hMem); - - if (ISPOINTER(hMem)) - return (LPVOID) hMem; - - HeapLock(GetProcessHeap()); - - phandle = HANDLE_TO_INTERN(hMem); - - if(MAGIC_GLOBAL_USED == phandle->Magic) - { - if(GLOBAL_LOCK_MAX > phandle->LockCount) - { - phandle->LockCount++; - } - palloc = phandle->Pointer; - } - else - { - DPRINT("GlobalLock: invalid handle\n"); - palloc = (LPVOID) hMem; - } - - HeapUnlock(GetProcessHeap()); - - return palloc; -} - -/* - * @implemented - */ -BOOL -STDCALL -GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) -{ - SYSTEM_BASIC_INFORMATION SysBasicInfo; - SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; - ULONG UserMemory; - NTSTATUS Status; - - DPRINT("GlobalMemoryStatusEx\n"); - - if (lpBuffer->dwLength != sizeof(MEMORYSTATUSEX)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - Status = ZwQuerySystemInformation(SystemBasicInformation, - &SysBasicInfo, - sizeof(SysBasicInfo), - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FALSE; - } - - Status = ZwQuerySystemInformation(SystemPerformanceInformation, - &SysPerfInfo, - sizeof(SysPerfInfo), - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FALSE; - } - - Status = ZwQuerySystemInformation(SystemFullMemoryInformation, - &UserMemory, - sizeof(ULONG), - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FALSE; - } - -/* - * Load percentage 0 thru 100. 0 is good and 100 is bad. - * - * Um = allocated memory / physical memory - * Um = 177 MB / 256 MB = 69.1% - * - * Mult allocated memory by 100 to move decimal point up. - */ - lpBuffer->dwMemoryLoad = (SysBasicInfo.NumberOfPhysicalPages - - SysPerfInfo.AvailablePages) * 100 / - SysBasicInfo.NumberOfPhysicalPages; - - DPRINT1("Memory Load: %d%%\n",lpBuffer->dwMemoryLoad ); - - lpBuffer->ullTotalPhys = SysBasicInfo.NumberOfPhysicalPages * - SysBasicInfo.PageSize; - lpBuffer->ullAvailPhys = SysPerfInfo.AvailablePages * - SysBasicInfo.PageSize; - - DPRINT("%d\n",SysPerfInfo.AvailablePages ); - DPRINT("%d\n",lpBuffer->ullAvailPhys ); - - lpBuffer->ullTotalPageFile = SysPerfInfo.CommitLimit * - SysBasicInfo.PageSize; - - DPRINT("%d\n",lpBuffer->ullTotalPageFile ); - - lpBuffer->ullAvailPageFile = ((SysPerfInfo.CommitLimit - - SysPerfInfo.CommittedPages) * - SysBasicInfo.PageSize); - -/* VM available to the calling processes, User Mem? */ - lpBuffer->ullTotalVirtual = SysBasicInfo.MaximumUserModeAddress - - SysBasicInfo.MinimumUserModeAddress; - - lpBuffer->ullAvailVirtual = (lpBuffer->ullTotalVirtual - - (UserMemory * - SysBasicInfo.PageSize)); - - DPRINT("%d\n",lpBuffer->ullAvailVirtual ); - DPRINT("%d\n",UserMemory); - DPRINT("%d\n",SysBasicInfo.PageSize); - -/* lol! Memory from beyond! */ - lpBuffer->ullAvailExtendedVirtual = 0; - return TRUE; -} - -/* - * @implemented - */ -VOID STDCALL -GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) -{ - MEMORYSTATUSEX lpBufferEx; -#if 0 - if (lpBuffer->dwLength != sizeof(MEMORYSTATUS)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return; - } -#endif - lpBufferEx.dwLength = sizeof(MEMORYSTATUSEX); - - if (GlobalMemoryStatusEx(&lpBufferEx)) - { - - lpBuffer->dwLength = sizeof(MEMORYSTATUS); - - lpBuffer->dwMemoryLoad = lpBufferEx.dwMemoryLoad; - lpBuffer->dwTotalPhys = lpBufferEx.ullTotalPhys; - lpBuffer->dwAvailPhys = lpBufferEx.ullAvailPhys; - lpBuffer->dwTotalPageFile = lpBufferEx.ullTotalPageFile; - lpBuffer->dwAvailPageFile = lpBufferEx.ullAvailPageFile; - lpBuffer->dwTotalVirtual = lpBufferEx.ullTotalVirtual; - lpBuffer->dwAvailVirtual = lpBufferEx.ullAvailVirtual; - } -} - - -HGLOBAL STDCALL -GlobalReAlloc(HGLOBAL hMem, - DWORD dwBytes, - UINT uFlags) -{ - - LPVOID palloc = 0; - HGLOBAL hnew = 0; - PGLOBAL_HANDLE phandle = 0; - ULONG heap_flags = 0; - - DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG)hMem, dwBytes, uFlags); - - if (uFlags & GMEM_ZEROINIT) - { - heap_flags = HEAP_ZERO_MEMORY; - } - - HeapLock(GetProcessHeap()); - - if(uFlags & GMEM_MODIFY) /* modify flags */ - { - if( ISPOINTER(hMem) && (uFlags & GMEM_MOVEABLE)) - { - /* make a fixed block moveable - * actually only NT is able to do this. And it's soo simple - */ - if (0 == hMem) - { - SetLastError( ERROR_NOACCESS ); - hnew = 0; - } - else - { - dwBytes = RtlSizeHeap(GetProcessHeap(), 0, (LPVOID) hMem); - hnew = GlobalAlloc( uFlags, dwBytes); - palloc = GlobalLock(hnew); - memcpy(palloc, (LPVOID) hMem, dwBytes); - GlobalUnlock(hnew); - RtlFreeHeap(GetProcessHeap(),0,hMem); - } - } - else if(ISPOINTER(hMem) && (uFlags & GMEM_DISCARDABLE)) - { - /* change the flags to make our block "discardable" */ - phandle = HANDLE_TO_INTERN(hMem); - phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8); - hnew = hMem; - } - else - { - SetLastError(ERROR_INVALID_PARAMETER); - hnew = 0; - } - } - else - { - if(ISPOINTER(hMem)) - { - if (!(uFlags & GMEM_MOVEABLE)) - { - heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY; - } - - /* reallocate fixed memory */ - hnew = (HANDLE)RtlReAllocateHeap(GetProcessHeap(), heap_flags, (LPVOID) hMem, dwBytes); - } - else - { - /* reallocate a moveable block */ - phandle= HANDLE_TO_INTERN(hMem); - hnew = hMem; - - if (0 != dwBytes) - { - if(phandle->Pointer) - { - - if (phandle->LockCount && !(uFlags & GMEM_MOVEABLE)) - { - /* Locked memory cant normally move but the MEM_MOVEABLE flag - * override this behaviour. But in this case that flag was not passed. - */ - heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY; - } - - palloc = RtlReAllocateHeap(GetProcessHeap(), heap_flags, - (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE), - dwBytes + HANDLE_SIZE); - if (0 == palloc) - { - hnew = 0; - } - else - { - *(PHANDLE)palloc = hMem; - phandle->Pointer = (PVOID)((ULONG_PTR)palloc + HANDLE_SIZE); - } - } - else - { - palloc = RtlAllocateHeap(GetProcessHeap(), heap_flags, dwBytes + HANDLE_SIZE); - if (0 == palloc) - { - hnew = 0; - } - else - { - *(PHANDLE)palloc = hMem; - phandle->Pointer = (PVOID)((ULONG_PTR)palloc + HANDLE_SIZE); - } - } - } - else - { - if(phandle->Pointer) + /* Otherwise, we're allocating, so set the new flags needed */ + Flags |= HEAP_SETTABLE_USER_VALUE | GLOBAL_HEAP_FLAG_MOVABLE; + if (!Ptr) { - RtlFreeHeap(GetProcessHeap(), 0, (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE)); - phandle->Pointer = 0; + /* 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 & GMEM_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 &= ~GLOBAL_HEAP_ENTRY_FLAG_REUSE; + } + else + { + /* Otherwise we failed */ + hMem = NULL; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); } } } } - - HeapUnlock(GetProcessHeap()); - - return hnew; -} - - -DWORD STDCALL -GlobalSize(HGLOBAL hMem) -{ - SIZE_T retval = 0; - PGLOBAL_HANDLE phandle = 0; - - DPRINT("GlobalSize( 0x%lX )\n", (ULONG)hMem); - - if(ISPOINTER(hMem)) /*FIXED*/ - { - retval = RtlSizeHeap(GetProcessHeap(), 0, hMem); - } - else /*MOVEABLE*/ - { - HeapLock(GetProcessHeap()); - - phandle = HANDLE_TO_INTERN(hMem); - - if (MAGIC_GLOBAL_USED == phandle->Magic) - { - if (0 != phandle->Pointer)/*NOT DISCARDED*/ + else if (uFlags & GMEM_MODIFY) + { + /* This is not a handle-based heap and the caller wants it to be one */ + if (uFlags & GMEM_MOVEABLE) + { + /* 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 & GLOBAL_HEAP_FLAG_MOVABLE)) { - retval = RtlSizeHeap(GetProcessHeap(), 0, (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE)); - - if (retval == (SIZE_T)-1) /*RtlSizeHeap failed*/ + /* Allocate a handle for it */ + HandleEntry = GlobalAllocEntry(); + + /* 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; + + /* Now allocate the actual heap for it */ + HandleEntry->Object = RtlAllocateHeap(hProcessHeap, + Flags, + dwBytes); + BASE_TRACE_PTR(HandleEntry->Object, HandleEntry); + if (!HandleEntry->Object) { /* - **TODO: RtlSizeHeap does not set last error. - ** We should choose an error value to set as - ** the last error. Which One? - */ - DPRINT("GlobalSize: RtlSizeHeap failed.\n"); - retval = 0; + * We failed, manually set the allocate flag and + * free the handle + */ + HandleEntry->Flags = RTL_HANDLE_VALID; + GlobalFreeEntry(HandleEntry); + + /* For the cleanup case */ + BASE_TRACE_FAILURE(); + HandleEntry = NULL; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); } - else /*Everything is ok*/ + else { - retval = retval - HANDLE_SIZE; + /* 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 | + GLOBAL_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; + } + + /* Check if it's also DDE Shared */ + if (uFlags & GMEM_DDESHARE) + { + /* Set the internal flag */ + HandleEntry->Flags |= GLOBAL_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, + 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 + */ +DWORD +NTAPI +GlobalSize(HGLOBAL hMem) +{ + PGLOBAL_HEAP_HANDLE_ENTRY HandleEntry; + PVOID Handle = NULL; + ULONG Flags = 0; + SIZE_T dwSize = MAXULONG_PTR; + + /* Lock the heap */ + RtlLockHeap(hProcessHeap); + + /* Check if this is a simple RTL Heap Managed block */ + if (!((ULONG_PTR)hMem & GLOBAL_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 & GLOBAL_HEAP_FLAG_MOVABLE)) + { + /* This implies we're not a handle heap, so use the generic call */ + dwSize = RtlSizeHeap(hProcessHeap, HEAP_NO_SERIALIZE, hMem); + } else { - DPRINT("GlobalSize: invalid handle\n"); - } - HeapUnlock(GetProcessHeap()); - } - return retval; -} - - -/* - * @implemented - */ -VOID STDCALL + /* Otherwise we're a handle heap, so get the internal handle */ + hMem = Handle; + } + } + + /* Make sure that this is an entry in our handle database */ + if ((ULONG_PTR)hMem & GLOBAL_HEAP_IS_HANDLE_ENTRY) + { + /* Get the entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure the handle is valid */ + if (!GlobalValidateEntry(HandleEntry)) + { + /* Fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + } + else if (HandleEntry->Flags & GLOBAL_HEAP_ENTRY_FLAG_REUSE) + { + /* We've reused this block, but we've saved the size for you */ + dwSize = HandleEntry->OldSize; + } + else + { + /* Otherwise, query RTL about it */ + dwSize = RtlSizeHeap(hProcessHeap, + 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; + } + + /* All done! Unlock heap and return the size */ + RtlUnlockHeap(hProcessHeap); + return dwSize; +} + +/* + * @implemented + */ +VOID +NTAPI GlobalUnfix(HGLOBAL hMem) { - if (hMem != INVALID_HANDLE_VALUE) - GlobalUnlock(hMem); -} - - -/* - * @implemented - */ -BOOL STDCALL + /* If the handle is valid, unlock it */ + if (hMem != INVALID_HANDLE_VALUE) GlobalUnlock(hMem); +} + +/* + * @implemented + */ +BOOL +NTAPI GlobalUnlock(HGLOBAL hMem) { - - PGLOBAL_HANDLE phandle; - BOOL locked = FALSE; - - DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG)hMem); - - if(ISPOINTER(hMem)) - { - SetLastError(ERROR_NOT_LOCKED); - return FALSE; - } - - HeapLock(GetProcessHeap()); - - phandle = HANDLE_TO_INTERN(hMem); - if(MAGIC_GLOBAL_USED == phandle->Magic) - { - if (0 >= phandle->LockCount) - { - locked = FALSE; - SetLastError(ERROR_NOT_LOCKED); - } - else if (GLOBAL_LOCK_MAX > phandle->LockCount) - { - phandle->LockCount--; - locked = (0 != phandle->LockCount) ? TRUE : FALSE; - SetLastError(NO_ERROR); - } - } - else - { - DPRINT("GlobalUnlock: invalid handle\n"); - locked = FALSE; - } - HeapUnlock(GetProcessHeap()); - return locked; -} - - -/* - * @implemented - */ -BOOL STDCALL + PGLOBAL_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; + + /* Otherwise, lock the heap */ + RtlLockHeap(hProcessHeap); + + /* Get the handle entry */ + HandleEntry = GlobalGetEntry(hMem); + BASE_TRACE_HANDLE(HandleEntry, hMem); + + /* Make sure it's valid */ + if (!GlobalValidateEntry(HandleEntry)) + { + /* It's not, fail */ + BASE_TRACE_FAILURE(); + SetLastError(ERROR_INVALID_HANDLE); + } + else + { + /* Otherwise, decrement lock count, unless we're already at 0*/ + if (!HandleEntry->LockCount--) + { + /* In which case we simply lock it back and fail */ + HandleEntry->LockCount++; + SetLastError(ERROR_NOT_LOCKED); + RetVal = FALSE; + } + else if (!HandleEntry->LockCount) + { + /* Nothing to unlock */ + SetLastError(NO_ERROR); + RetVal = FALSE; + } + } + + /* All done. Unlock the heap and return the pointer */ + RtlUnlockHeap(hProcessHeap); + return RetVal; +} + +/* + * @implemented + */ +BOOL +NTAPI GlobalUnWire(HGLOBAL hMem) { - return GlobalUnlock(hMem); -} - - -/* - * @implemented - */ -LPVOID STDCALL + /* This is simply an unlock */ + return GlobalUnlock(hMem); +} + +/* + * @implemented + */ +LPVOID +NTAPI GlobalWire(HGLOBAL hMem) { - return GlobalLock(hMem); + /* This is just a lock */ + return GlobalLock(hMem); +} + +/* + * @implemented + */ +BOOL +NTAPI +GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) +{ + SYSTEM_PERFORMANCE_INFORMATION PerformanceInfo; + VM_COUNTERS VmCounters; + QUOTA_LIMITS QuotaLimits; + ULONGLONG PageFile, PhysicalMemory; + + /* Query performance information */ + NtQuerySystemInformation(SystemPerformanceInformation, + &PerformanceInfo, + sizeof(PerformanceInfo), + NULL); + + /* Calculate memory load */ + lpBuffer->dwMemoryLoad = ((DWORD)(BaseCachedSysInfo.NumberOfPhysicalPages - + PerformanceInfo.AvailablePages) * 100) / + BaseCachedSysInfo.NumberOfPhysicalPages; + + /* Save physical memory */ + PhysicalMemory = BaseCachedSysInfo.NumberOfPhysicalPages * + BaseCachedSysInfo.PageSize; + lpBuffer->ullTotalPhys = PhysicalMemory; + + /* Now save available physical memory */ + PhysicalMemory = PerformanceInfo.AvailablePages * + BaseCachedSysInfo.PageSize; + lpBuffer->ullAvailPhys = PhysicalMemory; + + /* Query VM and Quota Limits */ + NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QUOTA_LIMITS), + NULL); + NtQueryInformationProcess(NtCurrentProcess(), + ProcessVmCounters, + &VmCounters, + sizeof(VM_COUNTERS), + NULL); + + /* Save the commit limit */ + lpBuffer->ullTotalPageFile = min(QuotaLimits.PagefileLimit, + PerformanceInfo.CommitLimit); + + /* Calculate how many pages are left */ + PageFile = PerformanceInfo.CommitLimit - PerformanceInfo.CommittedPages; + + /* Save the total */ + lpBuffer->ullAvailPageFile = min(PageFile, + QuotaLimits.PagefileLimit - + VmCounters.PagefileUsage); + lpBuffer->ullAvailPageFile *= BaseCachedSysInfo.PageSize; + + /* Now calculate the total virtual space */ + lpBuffer->ullTotalVirtual = (BaseCachedSysInfo.MaximumUserModeAddress - + BaseCachedSysInfo.MinimumUserModeAddress) + 1; + + /* And finally the avilable virtual space */ + lpBuffer->ullAvailVirtual = lpBuffer->ullTotalVirtual - + VmCounters.VirtualSize; + lpBuffer->ullAvailExtendedVirtual = 0; + return TRUE; +} + +/* + * @implemented + */ +VOID +NTAPI +GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) +{ + MEMORYSTATUSEX lpBufferEx; + + /* Call the extended function */ + lpBufferEx.dwLength = sizeof(MEMORYSTATUSEX); + if (GlobalMemoryStatusEx(&lpBufferEx)) + { + /* Reset the right size and fill out the information */ + lpBuffer->dwLength = sizeof(MEMORYSTATUS); + lpBuffer->dwMemoryLoad = lpBufferEx.dwMemoryLoad; + lpBuffer->dwTotalPhys = lpBufferEx.ullTotalPhys; + lpBuffer->dwAvailPhys = lpBufferEx.ullAvailPhys; + lpBuffer->dwTotalPageFile = lpBufferEx.ullTotalPageFile; + lpBuffer->dwAvailPageFile = lpBufferEx.ullAvailPageFile; + lpBuffer->dwTotalVirtual = lpBufferEx.ullTotalVirtual; + lpBuffer->dwAvailVirtual = lpBufferEx.ullAvailVirtual; + } } /* EOF */ Modified: trunk/reactos/dll/win32/kernel32/misc/dllmain.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/dl…
============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/dllmain.c (original) +++ trunk/reactos/dll/win32/kernel32/misc/dllmain.c Sat Jun 24 22:11:57 2006 @@ -339,6 +339,9 @@ } hProcessHeap = RtlGetProcessHeap(); + RtlInitializeHandleTable(0xFFFF, + sizeof(GLOBAL_HEAP_HANDLE_ENTRY), + &BaseGlobalHandleTable); hCurrentModule = hDll; DPRINT("Heap: %p\n", hProcessHeap);
18 years, 6 months
1
0
0
0
[ion] 22578: - There are more then only the 3 or 4 heap flags WINE's Windows 95 code supports(there are about 18), so it's a bit stupid to mask them all out, especially since that breaks settable/tag flags.
by ion@svn.reactos.org
Author: ion Date: Sat Jun 24 22:01:53 2006 New Revision: 22578 URL:
http://svn.reactos.org/svn/reactos?rev=22578&view=rev
Log: - There are more then only the 3 or 4 heap flags WINE's Windows 95 code supports(there are about 18), so it's a bit stupid to mask them all out, especially since that breaks settable/tag flags. Modified: trunk/reactos/lib/rtl/heap.c Modified: trunk/reactos/lib/rtl/heap.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=22578&r…
============================================================================== --- trunk/reactos/lib/rtl/heap.c (original) +++ trunk/reactos/lib/rtl/heap.c Sat Jun 24 22:01:53 2006 @@ -1217,7 +1217,7 @@ RtlRaiseStatus( STATUS_NO_MEMORY ); return NULL; } - flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY; + //flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY; flags |= heapPtr->flags; if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection ); @@ -1362,8 +1362,8 @@ /* Validate the parameters */ - Flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY | - HEAP_REALLOC_IN_PLACE_ONLY; + //Flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY | + // HEAP_REALLOC_IN_PLACE_ONLY; Flags |= heapPtr->flags; Size = (Size + 7) & ~7; if (Size < HEAP_MIN_BLOCK_SIZE) @@ -1891,6 +1891,7 @@ subheap = HEAP_FindSubHeap( heapPtr, pInUse ); /* Hack */ + DPRINT1("V/F: %lx %p\n", subheap->UserValue, subheap->UserFlags); if (UserValue) *UserValue = subheap->UserValue; if (UserFlags) *UserFlags = subheap->UserFlags; return TRUE;
18 years, 6 months
1
0
0
0
[ion] 22577: - Silence debug message
by ion@svn.reactos.org
Author: ion Date: Sat Jun 24 21:07:15 2006 New Revision: 22577 URL:
http://svn.reactos.org/svn/reactos?rev=22577&view=rev
Log: - Silence debug message Modified: trunk/reactos/lib/rtl/heap.c Modified: trunk/reactos/lib/rtl/heap.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=22577&r…
============================================================================== --- trunk/reactos/lib/rtl/heap.c (original) +++ trunk/reactos/lib/rtl/heap.c Sat Jun 24 21:07:15 2006 @@ -1266,7 +1266,7 @@ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection ); - DPRINT1("(%p,%08lx,%08lx): returning %p\n", + DPRINT("(%p,%08lx,%08lx): returning %p\n", heap, flags, size, (PVOID)(pInUse + 1) ); return (PVOID)(pInUse + 1); }
18 years, 6 months
1
0
0
0
[ion] 22576: - Fix implementation of RtlSetUserValueHeap and RtlGetUserInfoHeap to write their flags to the subheap and not the actual main heap structure (since those flags are valid for each allocation). - Make heap allocations 8-byte aligned again.
by ion@svn.reactos.org
Author: ion Date: Sat Jun 24 21:05:05 2006 New Revision: 22576 URL:
http://svn.reactos.org/svn/reactos?rev=22576&view=rev
Log: - Fix implementation of RtlSetUserValueHeap and RtlGetUserInfoHeap to write their flags to the subheap and not the actual main heap structure (since those flags are valid for each allocation). - Make heap allocations 8-byte aligned again. Modified: trunk/reactos/lib/rtl/heap.c Modified: trunk/reactos/lib/rtl/heap.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=22576&r…
============================================================================== --- trunk/reactos/lib/rtl/heap.c (original) +++ trunk/reactos/lib/rtl/heap.c Sat Jun 24 21:05:05 2006 @@ -87,6 +87,8 @@ struct tagSUBHEAP *next; /* Next sub-heap */ struct tagHEAP *heap; /* Main heap structure */ ULONG magic; /* Magic number */ + ULONG UserFlags; + PVOID UserValue; } SUBHEAP, *PSUBHEAP; @@ -100,7 +102,6 @@ RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */ ULONG flags; /* Heap flags */ ULONG magic; /* Magic number */ - PVOID UserValue; PRTL_HEAP_COMMIT_ROUTINE commitRoutine; } HEAP, *PHEAP; @@ -1250,6 +1251,9 @@ pInUse->threadId = (ULONG)NtCurrentTeb()->Cid.UniqueThread; pInUse->magic = ARENA_INUSE_MAGIC; + /* Save user flags */ + subheap->UserFlags = flags & HEAP_SETTABLE_USER_FLAGS; + /* Shrink the block */ HEAP_ShrinkBlock( subheap, pInUse, size ); @@ -1262,7 +1266,7 @@ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection ); - DPRINT("(%p,%08lx,%08lx): returning %p\n", + DPRINT1("(%p,%08lx,%08lx): returning %p\n", heap, flags, size, (PVOID)(pInUse + 1) ); return (PVOID)(pInUse + 1); } @@ -1855,9 +1859,15 @@ IN PVOID UserValue) { HEAP *heapPtr = HEAP_GetPtr(HeapHandle); + ARENA_INUSE *pInUse; + SUBHEAP *subheap; + + /* Get the subheap */ + pInUse = (ARENA_INUSE *)BaseAddress - 1; + subheap = HEAP_FindSubHeap( heapPtr, pInUse ); /* Hack */ - heapPtr->UserValue = UserValue; + subheap->UserValue = UserValue; return TRUE; } @@ -1873,10 +1883,16 @@ OUT PULONG UserFlags) { HEAP *heapPtr = HEAP_GetPtr(HeapHandle); + ARENA_INUSE *pInUse; + SUBHEAP *subheap; + + /* Get the subheap */ + pInUse = (ARENA_INUSE *)BaseAddress - 1; + subheap = HEAP_FindSubHeap( heapPtr, pInUse ); /* Hack */ - if (UserValue) *UserValue = heapPtr->UserValue; - if (UserFlags) *UserFlags = heapPtr->flags & HEAP_SETTABLE_USER_FLAGS; + if (UserValue) *UserValue = subheap->UserValue; + if (UserFlags) *UserFlags = subheap->UserFlags; return TRUE; }
18 years, 6 months
1
0
0
0
[greatlrd] 22575: fixing so u can edit rsrc.rc again with vs
by greatlrd@svn.reactos.org
Author: greatlrd Date: Sat Jun 24 20:51:12 2006 New Revision: 22575 URL:
http://svn.reactos.org/svn/reactos?rev=22575&view=rev
Log: fixing so u can edit rsrc.rc again with vs Modified: trunk/reactos/base/applications/calc/Hu.rc trunk/reactos/base/applications/calc/Ru.rc Modified: trunk/reactos/base/applications/calc/Hu.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/calc/Hu.…
============================================================================== --- trunk/reactos/base/applications/calc/Hu.rc (original) +++ trunk/reactos/base/applications/calc/Hu.rc Sat Jun 24 20:51:12 2006 @@ -23,7 +23,7 @@ #include "resource.h" #include "winecalc.h" -LANGUAGE LANG_HUNGARIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { Modified: trunk/reactos/base/applications/calc/Ru.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/calc/Ru.…
============================================================================== --- trunk/reactos/base/applications/calc/Ru.rc (original) +++ trunk/reactos/base/applications/calc/Ru.rc Sat Jun 24 20:51:12 2006 @@ -22,7 +22,7 @@ #include "resource.h" #include "winecalc.h" -LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE {
18 years, 6 months
1
0
0
0
[greatlrd] 22574: 1. Fix the russain rc to be open with VS 2. move all langues rc to rsrc.rc so we can open them in VS without genrate project file for VS we already doing it on few other dll/exe
by greatlrd@svn.reactos.org
Author: greatlrd Date: Sat Jun 24 20:44:30 2006 New Revision: 22574 URL:
http://svn.reactos.org/svn/reactos?rev=22574&view=rev
Log: 1. Fix the russain rc to be open with VS 2. move all langues rc to rsrc.rc so we can open them in VS without genrate project file for VS we already doing it on few other dll/exe Added: trunk/reactos/base/applications/cacls/rsrc.rc (with props) Modified: trunk/reactos/base/applications/cacls/Ru.rc trunk/reactos/base/applications/cacls/cacls.rc Modified: trunk/reactos/base/applications/cacls/Ru.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cacls/Ru…
============================================================================== --- trunk/reactos/base/applications/cacls/Ru.rc (original) +++ trunk/reactos/base/applications/cacls/Ru.rc Sat Jun 24 20:44:30 2006 @@ -1,4 +1,4 @@ -LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { Modified: trunk/reactos/base/applications/cacls/cacls.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cacls/ca…
============================================================================== --- trunk/reactos/base/applications/cacls/cacls.rc (original) +++ trunk/reactos/base/applications/cacls/cacls.rc Sat Jun 24 20:44:30 2006 @@ -6,9 +6,5 @@ #define REACTOS_STR_ORIGINAL_FILENAME "cacls.exe\0" #include <reactos/version.rc> -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#include "rsrc.rc" -#include "En.rc" -#include "Nl.rc" -#include "Ru.rc" -#include "De.rc" Added: trunk/reactos/base/applications/cacls/rsrc.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cacls/rs…
============================================================================== --- trunk/reactos/base/applications/cacls/rsrc.rc (added) +++ trunk/reactos/base/applications/cacls/rsrc.rc Sat Jun 24 20:44:30 2006 @@ -1,0 +1,15 @@ + + +#include <windows.h> +#include "resource.h" + +/* define language neutral resources */ + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +/* include localised resources */ +#include "En.rc" +#include "Nl.rc" +#include "Ru.rc" +#include "De.rc" + Propchange: trunk/reactos/base/applications/cacls/rsrc.rc ------------------------------------------------------------------------------ svn:eol-style = native
18 years, 6 months
1
0
0
0
← Newer
1
...
13
14
15
16
17
18
19
...
60
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Results per page:
10
25
50
100
200