using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
/// Specifies the class of heap information to be set or retrieved.
// typedef enum _HEAP_INFORMATION_CLASS { HeapCompatibilityInformation = 0, HeapEnableTerminationOnCorruption = 1} HEAP_INFORMATION_CLASS; https://msdn.microsoft.com/en-us/library/windows/desktop/dn280633(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "dn280633")]
public enum HEAP_INFORMATION_CLASS
{
///
///
/// The heap features that are enabled. The available features vary based on operating system. Depending on the HeapInformation parameter in the
/// HeapQueryInformation or HeapSetInformation functions, specifying this enumeration value can indicate one of the following features:
///
/// For more information about look-aside lists, see the Remarks section.
///
HeapCompatibilityInformation = 0,
///
///
/// The terminate-on-corruption feature. If the heap manager detects an error in any heap used by the process, it calls the Windows Error Reporting
/// service and terminates the process.
///
/// After a process enables this feature, it cannot be disabled.
///
HeapEnableTerminationOnCorruption = 1,
///
/// If HeapSetInformation is called with HeapHandle set to NULL, then all heaps in the process with a low-fragmentation heap (LFH) will have their
/// caches optimized, and the memory will be decommitted if possible.
/// If a heap pointer is supplied in HeapHandle, then only that heap will be optimized.
/// Note that the HEAP_OPTIMIZE_RESOURCES_INFORMATION structure passed in HeapInformation must be properly initialized.
/// Note This value was added in Windows 8.1.
///
HeapOptimizeResources = 3
}
/// Flags for Head functions
[PInvokeData("HeapApi.h")]
[Flags]
public enum HeapFlags
{
///
/// Serialized access will not be used for this allocation. For more information, see Remarks.
///
/// To ensure that serialized access is disabled for all calls to this function, specify HEAP_NO_SERIALIZE in the call to HeapCreate. In this case,
/// it is not necessary to additionally specify HEAP_NO_SERIALIZE in this function call.
///
///
/// This value should not be specified when accessing the process's default heap. The system may create additional threads within the application's
/// process, such as a CTRL+C handler, that simultaneously access the process's default heap.
///
///
HEAP_NO_SERIALIZE = 0x00000001,
HEAP_GROWABLE = 0x00000002,
///
/// The system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
///
/// To ensure that exceptions are generated for all calls to this function, specify HEAP_GENERATE_EXCEPTIONS in the call to HeapCreate. In this case,
/// it is not necessary to additionally specify HEAP_GENERATE_EXCEPTIONS in this function call.
///
///
HEAP_GENERATE_EXCEPTIONS = 0x00000004,
/// The allocated memory will be initialized to zero. Otherwise, the memory is not initialized to zero.
HEAP_ZERO_MEMORY = 0x00000008,
///
/// There can be no movement when reallocating a memory block. If this value is not specified, the function may move the block to a new location. If
/// this value is specified and the block cannot be resized without moving, the function fails, leaving the original memory block unchanged.
///
HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010,
HEAP_TAIL_CHECKING_ENABLED = 0x00000020,
HEAP_FREE_CHECKING_ENABLED = 0x00000040,
HEAP_DISABLE_COALESCE_ON_FREE = 0x00000080,
HEAP_CREATE_ALIGN_16 = 0x00010000,
HEAP_CREATE_ENABLE_TRACING = 0x00020000,
///
/// All memory blocks that are allocated from this heap allow code execution, if the hardware enforces data execution prevention. Use this flag heap
/// in applications that run code from the heap. If HEAP_CREATE_ENABLE_EXECUTE is not specified and an application attempts to run code from a
/// protected page, the application receives an exception with the status code STATUS_ACCESS_VIOLATION.
///
HEAP_CREATE_ENABLE_EXECUTE = 0x00040000,
HEAP_MAXIMUM_TAG = 0x0FFF,
HEAP_PSEUDO_TAG_FLAG = 0x8000,
HEAP_TAG_SHIFT = 18,
HEAP_CREATE_SEGMENT_HEAP = 0x00000100,
HEAP_CREATE_HARDENED = 0x00000200,
}
/// The properties of the heap element.
[Flags]
public enum PROCESS_HEAP : ushort
{
///
/// The heap element is located at the beginning of a region of contiguous virtual memory in use by the heap.The lpData member of the structure
/// points to the first virtual address used by the region; the cbData member specifies the total size, in bytes, of the address space that is
/// reserved for this region; and the cbOverhead member specifies the size, in bytes, of the heap control structures that describe the region.The
/// Region structure becomes valid. The dwCommittedSize, dwUnCommittedSize, lpFirstBlock, and lpLastBlock members of the structure contain additional
/// information about the region.
///
PROCESS_HEAP_REGION = 1,
///
/// The heap element is located in a range of uncommitted memory within the heap region.The lpData member points to the beginning of the range of
/// uncommitted memory; the cbData member specifies the size, in bytes, of the range of uncommitted memory; and the cbOverhead member specifies the
/// size, in bytes, of the control structures that describe this uncommitted range.
///
PROCESS_HEAP_UNCOMMITTED_RANGE = 2,
///
/// The heap element is an allocated block.If PROCESS_HEAP_ENTRY_MOVEABLE is also specified, the Block structure becomes valid. The hMem member of
/// the Block structure contains a handle to the allocated, moveable memory block.
///
PROCESS_HEAP_ENTRY_BUSY = 4,
///
/// This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.The block was allocated with
/// LMEM_MOVEABLE or GMEM_MOVEABLE, and the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated,
/// moveable memory block.
///
PROCESS_HEAP_ENTRY_MOVEABLE = 16,
/// This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.
PROCESS_HEAP_ENTRY_DDESHARE = 32,
}
/// Retrieves a handle to the default heap of the calling process. This handle can then be used in subsequent calls to the heap functions.
///
/// If the function succeeds, the return value is a handle to the calling process's heap. If the function fails, the return value is NULL. To get
/// extended error information, call GetLastError.
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366569")]
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcessHeap();
/// Returns the number of active heaps and retrieves handles to all of the active heaps for the calling process.
/// The maximum number of heap handles that can be stored into the buffer pointed to by ProcessHeaps.
/// A pointer to a buffer that receives an array of heap handles.
///
/// The return value is the number of handles to heaps that are active for the calling process.
///
/// If the return value is less than or equal to NumberOfHeaps, the function has stored that number of heap handles in the buffer pointed to by ProcessHeaps.
///
///
/// If the return value is greater than NumberOfHeaps, the buffer pointed to by ProcessHeaps is too small to hold all the heap handles for the calling
/// process, and the function stores NumberOfHeaps handles in the buffer. Use the return value to allocate a buffer that is large enough to receive all
/// of the handles, and call the function again.
///
///
/// If the return value is zero, the function has failed because every process has at least one active heap, the default heap for the process. To get
/// extended error information, call GetLastError.
///
///
// DWORD WINAPI GetProcessHeaps( _In_ DWORD NumberOfHeaps, _Out_ PHANDLE ProcessHeaps);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366571(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366571")]
public static extern uint GetProcessHeaps(uint NumberOfHeaps, out IntPtr ProcessHeaps);
/// Allocates a block of memory from a heap. The allocated memory is not movable.
/// A handle to the heap from which the memory will be allocated. This handle is returned by the HeapCreate or GetProcessHeap function.
///
/// The heap allocation options. Specifying any of these values will override the corresponding value specified when the heap was created with
/// HeapCreate. This parameter can be one or more of the following values: HEAP_GENERATE_EXCEPTIONS, HEAP_NO_SERIALIZE and HEAP_ZERO_MEMORY.
///
///
/// The number of bytes to be allocated. If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You
/// create a non-growable heap by calling the HeapCreate function with a nonzero value.
///
///
/// If the function succeeds, the return value is a pointer to the allocated memory block.
/// If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.
///
/// If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate either of the exceptions listed in the following
/// table. The particular exception depends upon the nature of the heap corruption. For more information, see GetExceptionCode.
///
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366597")]
[DllImport(Lib.Kernel32, ExactSpelling = true)]
public static extern IntPtr HeapAlloc(IntPtr hHeap, HeapFlags dwFlags, [MarshalAs(UnmanagedType.SysInt)] IntPtr dwBytes);
///
/// Returns the size of the largest committed free block in the specified heap. If the Disable heap coalesce on free global flag is set, this function
/// also coalesces adjacent free blocks of memory in the heap.
///
/// A handle to the heap. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
/// The heap access options. This parameter can be the following value.
///
///
///
/// Value
/// Meaning
///
/// -
/// HEAP_NO_SERIALIZE0x00000001
///
/// Serialized access will not be used. For more information, see Remarks.To ensure that serialized access is disabled for all calls to this function,
/// specify HEAP_NO_SERIALIZE in the call to HeapCreate. In this case, it is not necessary to additionally specify HEAP_NO_SERIALIZE in this function
/// call.Do not specify this value when accessing the process heap. The system may create additional threads within the application's process,
/// such as a CTRL+C handler, that simultaneously access the process heap.
///
///
///
///
///
///
/// If the function succeeds, the return value is the size of the largest committed free block in the heap, in bytes.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
/// In the unlikely case that there is absolutely no space available in the heap, the function return value is zero, and GetLastError returns the
/// value NO_ERROR.
///
///
// SIZE_T WINAPI HeapCompact( _In_ HANDLE hHeap, _In_ DWORD dwFlags);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366598(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366598")]
public static extern SizeT HeapCompact([In] IntPtr hHeap, HeapFlags dwFlags);
///
/// Creates a private heap object that can be used by the calling process. The function reserves space in the virtual address space of the process and
/// allocates physical storage for a specified initial portion of this block.
///
///
/// The heap allocation options. These options affect subsequent access to the new heap through calls to the heap functions. This parameter can be 0 or
/// one or more of the following values: HEAP_CREATE_ENABLE_EXECUTE, HEAP_GENERATE_EXCEPTIONS, HEAP_NO_SERIALIZE.
///
///
/// The initial size of the heap, in bytes. This value determines the initial amount of memory that is committed for the heap. The value is rounded up to
/// a multiple of the system page size. The value must be smaller than dwMaximumSize.
/// If this parameter is 0, the function commits one page. To determine the size of a page on the host computer, use the GetSystemInfo function.
///
///
/// The maximum size of the heap, in bytes. The HeapCreate function rounds dwMaximumSize up to a multiple of the system page size and then reserves a
/// block of that size in the process's virtual address space for the heap. If allocation requests made by the HeapAlloc or HeapReAlloc functions exceed
/// the size specified by dwInitialSize, the system commits additional pages of memory for the heap, up to the heap's maximum size.
///
/// If dwMaximumSize is not zero, the heap size is fixed and cannot grow beyond the maximum size. Also, the largest memory block that can be allocated
/// from the heap is slightly less than 512 KB for a 32-bit process and slightly less than 1,024 KB for a 64-bit process. Requests to allocate larger
/// blocks fail, even if the maximum size of the heap is large enough to contain the block.
///
///
/// If dwMaximumSize is 0, the heap can grow in size. The heap's size is limited only by the available memory. Requests to allocate memory blocks larger
/// than the limit for a fixed-size heap do not automatically fail; instead, the system calls the VirtualAlloc function to obtain the memory that is
/// needed for large blocks. Applications that need to allocate large memory blocks should set dwMaximumSize to 0.
///
///
///
/// If the function succeeds, the return value is a handle to the newly created heap. If the function fails, the return value is NULL. To get extended
/// error information, call GetLastError.
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366599")]
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
public static extern SafePrivateHeapHandle HeapCreate(HeapFlags flOptions, [MarshalAs(UnmanagedType.SysInt)] IntPtr dwInitialSize, [MarshalAs(UnmanagedType.SysInt)] IntPtr dwMaximumSize);
///
/// Destroys the specified heap object. It decommits and releases all the pages of a private heap object, and it invalidates the handle to the heap.
///
///
/// A handle to the heap to be destroyed. This handle is returned by the HeapCreate function. Do not use the handle to the process heap returned by the
/// GetProcessHeap function.
///
///
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366700")]
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapDestroy(IntPtr hHeap);
/// Frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.
///
/// A handle to the heap whose memory block is to be freed. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
///
/// The heap free options. Specifying the following value overrides the corresponding value specified in the flOptions parameter when the heap was
/// created by using the HeapCreate function: HEAP_NO_SERIALIZE
///
///
/// A pointer to the memory block to be freed. This pointer is returned by the HeapAlloc or HeapReAlloc function. If this pointer is NULL, the behavior
/// is undefined.
///
///
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.An application can call GetLastError for
/// extended error information.
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366701")]
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapFree(IntPtr hHeap, HeapFlags dwFlags, IntPtr lpMem);
/// Attempts to acquire the critical section object, or lock, that is associated with a specified heap.
/// A handle to the heap to be locked. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI HeapLock( _In_ HANDLE hHeap);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366702(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366702")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapLock([In] IntPtr hHeap);
/// Retrieves information about the specified heap.
///
/// A handle to the heap whose information is to be retrieved. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
///
/// The class of information to be retrieved. This parameter can be the following value from the HEAP_INFORMATION_CLASS enumeration type.
///
///
///
/// Value
/// Meaning
///
/// -
/// HeapCompatibilityInformation0
///
/// Indicates the heap features that are enabled. The HeapInformation parameter is a pointer to a ULONG variable.If HeapInformation is 0, the heap is a
/// standard heap that does not support look-aside lists.If HeapInformation is 1, the heap supports look-aside lists. For more information, see
/// Remarks.If HeapInformation is 2, the low-fragmentation heap (LFH) has been enabled for the heap. Enabling the LFH disables look-aside lists.
///
///
///
///
///
///
/// A pointer to a buffer that receives the heap information. The format of this data depends on the value of the HeapInformationClass parameter.
///
/// The size of the heap information being queried, in bytes.
///
///
/// A pointer to a variable that receives the length of data written to the HeapInformation buffer. If the buffer is too small, the function fails and
/// ReturnLength specifies the minimum size required for the buffer.
///
/// If you do not want to receive this information, specify NULL.
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI HeapQueryInformation( _In_opt_ HANDLE HeapHandle, _In_ HEAP_INFORMATION_CLASS HeapInformationClass, _Out_ PVOID HeapInformation, _In_
// SIZE_T HeapInformationLength, _Out_opt_ PSIZE_T ReturnLength);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366703(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366703")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapQueryInformation([In] IntPtr HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, IntPtr HeapInformation, SizeT HeapInformationLength, out SizeT ReturnLength);
///
/// Reallocates a block of memory from a heap. This function enables you to resize a memory block and change other memory block properties. The allocated
/// memory is not movable.
///
///
/// A handle to the heap from which the memory is to be reallocated. This handle is a returned by either the HeapCreate or GetProcessHeap function.
///
///
///
/// The heap reallocation options. Specifying a value overrides the corresponding value specified in the flOptions parameter when the heap was created by
/// using the HeapCreate function. This parameter can be one or more of the following values.
///
///
///
///
/// Value
/// Meaning
///
/// -
/// HEAP_GENERATE_EXCEPTIONS0x00000004
///
/// The operating-system raises an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.To ensure that
/// exceptions are generated for all calls to this function, specify HEAP_GENERATE_EXCEPTIONS in the call to HeapCreate. In this case, it is not
/// necessary to additionally specify HEAP_GENERATE_EXCEPTIONS in this function call.
///
///
/// -
/// HEAP_NO_SERIALIZE0x00000001
///
/// Serialized access will not be used. For more information, see Remarks.To ensure that serialized access is disabled for all calls to this function,
/// specify HEAP_NO_SERIALIZE in the call to HeapCreate. In this case, it is not necessary to additionally specify HEAP_NO_SERIALIZE in this function
/// call.This value should not be specified when accessing the process heap. The system may create additional threads within the application's
/// process, such as a CTRL+C handler, that simultaneously access the process heap.
///
///
/// -
/// HEAP_REALLOC_IN_PLACE_ONLY0x00000010
///
/// There can be no movement when reallocating a memory block. If this value is not specified, the function may move the block to a new location. If this
/// value is specified and the block cannot be resized without moving, the function fails, leaving the original memory block unchanged.
///
///
/// -
/// HEAP_ZERO_MEMORY0x00000008
///
/// If the reallocation request is for a larger size, the additional region of memory beyond the original size be initialized to zero. The contents of
/// the memory block up to its original size are unaffected.
///
///
///
///
///
///
/// A pointer to the block of memory that the function reallocates. This pointer is returned by an earlier call to the HeapAlloc or
/// HeapReAlloc function.
///
///
/// The new size of the memory block, in bytes. A memory block's size can be increased or decreased by using this function.
///
/// If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You create a non-growable heap by calling
/// the HeapCreate function with a nonzero value.
///
///
///
/// If the function succeeds, the return value is a pointer to the reallocated memory block.
/// If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.
///
/// If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate either of the exceptions listed in the
/// following table. For more information, see GetExceptionCode.
///
///
///
///
/// Exception code
/// Description
///
/// -
/// STATUS_NO_MEMORY
/// The allocation attempt failed because of a lack of available memory or heap corruption.
///
/// -
/// STATUS_ACCESS_VIOLATION
/// The allocation attempt failed because of heap corruption or improper function parameters.
///
///
///
/// If the function fails, it does not call SetLastError. An application cannot call GetLastError for extended error information.
///
// LPVOID WINAPI HeapReAlloc( _In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ LPVOID lpMem, _In_ SIZE_T dwBytes);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366704(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366704")]
public static extern IntPtr HeapReAlloc(IntPtr hHeap, HeapFlags dwFlags, IntPtr lpMem, SizeT dwBytes);
/// Enables features for a specified heap.
///
/// A handle to the heap where information is to be set. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
///
/// The class of information to be set. This parameter can be one of the following values from the HEAP_INFORMATION_CLASS enumeration type.
///
///
///
/// Value
/// Meaning
///
/// -
/// HeapCompatibilityInformation0
///
/// Enables heap features. Only the low-fragmentation heap (LFH) is supported. However, it is not necessary for applications to enable the LFH because
/// the system uses the LFH as needed to service memory allocation requests. Windows XP and Windows Server 2003: The LFH is not enabled by default. To
/// enable the LFH for the specified heap, set the variable pointed to by the HeapInformation parameter to 2. After the LFH is enabled for a heap, it
/// cannot be disabled.The LFH cannot be enabled for heaps created with HEAP_NO_SERIALIZE or for heaps created with a fixed size. The LFH also cannot be
/// enabled if you are using the heap debugging tools in Debugging Tools for Windows or Microsoft Application Verifier.When a process is run under any
/// debugger, certain heap debug options are automatically enabled for all heaps in the process. These heap debug options prevent the use of the LFH. To
/// enable the low-fragmentation heap when running under a debugger, set the _NO_DEBUG_HEAP environment variable to 1.
///
///
/// -
/// HeapEnableTerminationOnCorruption1
///
/// Enables the terminate-on-corruption feature. If the heap manager detects an error in any heap used by the process, it calls the Windows Error
/// Reporting service and terminates the process.After a process enables this feature, it cannot be disabled.Windows Server 2003 and Windows XP: This
/// value is not supported until Windows Vista and Windows XP with SP3. The function succeeds but the HeapEnableTerminationOnCorruption value is ignored.
///
///
/// -
/// HeapOptimizeResources3
///
/// If HeapSetInformation is called with HeapHandle set to NULL, then all heaps in the process with a low-fragmentation heap (LFH) will have their caches
/// optimized, and the memory will be decommitted if possible. If a heap pointer is supplied in HeapHandle, then only that heap will be optimized.Note
/// that the HEAP_OPTIMIZE_RESOURCES_INFORMATION structure passed in HeapInformation must be properly initialized.Note This value was added in Windows 8.1.
///
///
///
///
///
///
/// The heap information buffer. The format of this data depends on the value of the HeapInformationClass parameter.
///
/// If the HeapInformationClass parameter is HeapCompatibilityInformation, the HeapInformation parameter is a pointer to a ULONG variable.
///
///
/// If the HeapInformationClass parameter is HeapEnableTerminationOnCorruption, the HeapInformation parameter should be NULL and
/// HeapInformationLength should be 0
///
///
/// The size of the HeapInformation buffer, in bytes.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.
///
// BOOL WINAPI HeapSetInformation( _In_opt_ HANDLE HeapHandle, _In_ HEAP_INFORMATION_CLASS HeapInformationClass, _In_ PVOID HeapInformation, _In_ SIZE_T
// HeapInformationLength);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366705")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapSetInformation([In] IntPtr HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, [In] IntPtr HeapInformation, uint HeapInformationLength);
/// Retrieves the size of a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.
///
/// A handle to the heap in which the memory block resides. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
///
/// The heap size options. Specifying the following value overrides the corresponding value specified in the flOptions parameter when the heap was
/// created by using the HeapCreate function.
///
///
/// A pointer to the memory block whose size the function will obtain. This is a pointer returned by the HeapAlloc or HeapReAlloc function. The memory
/// block must be from the heap specified by the hHeap parameter.
///
///
/// If the function succeeds, the return value is the requested size of the allocated memory block, in bytes.
///
/// If the function fails, the return value is (SIZE_T)-1. The function does not call SetLastError. An application cannot call GetLastError for extended
/// error information.
///
///
/// If the lpMem parameter refers to a heap allocation that is not in the heap specified by the hHeap parameter, the behavior of the HeapSize function is undefined.
///
///
[PInvokeData("HeapApi.h", MSDNShortId = "aa366706")]
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.SysInt)]
public static extern IntPtr HeapSize(IntPtr hHeap, HeapFlags dwFlags, IntPtr lpMem);
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapSummary([In] IntPtr hHeap, HeapFlags dwFlags, out HEAP_SUMMARY lpSummary);
///
/// Releases ownership of the critical section object, or lock, that is associated with a specified heap. It reverses the action of the HeapLock function.
///
/// A handle to the heap to be unlocked. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI HeapUnlock( _In_ HANDLE hHeap);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366707(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366707")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapUnlock([In] IntPtr hHeap);
///
/// Validates the specified heap. The function scans all the memory blocks in the heap and verifies that the heap control structures maintained by the
/// heap manager are in a consistent state. You can also use the HeapValidate function to validate a single memory block within a specified heap
/// without checking the validity of the entire heap.
///
/// A handle to the heap to be validated. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
/// The heap access options. This parameter can be the following value.
///
///
///
/// Value
/// Meaning
///
/// -
/// HEAP_NO_SERIALIZE0x00000001
///
/// Serialized access will not be used. For more information, see Remarks.To ensure that serialized access is disabled for all calls to this function,
/// specify HEAP_NO_SERIALIZE in the call to HeapCreate. In this case, it is not necessary to additionally specify HEAP_NO_SERIALIZE in this function
/// call.This value should not be specified when accessing the process default heap. The system may create additional threads within the
/// application's process, such as a CTRL+C handler, that simultaneously access the process default heap.
///
///
///
///
///
///
/// A pointer to a memory block within the specified heap. This parameter may be NULL.
/// If this parameter is NULL, the function attempts to validate the entire heap specified by hHeap.
///
/// If this parameter is not NULL, the function attempts to validate the memory block pointed to by lpMem. It does not attempt to validate the
/// rest of the heap.
///
///
///
/// If the specified heap or memory block is valid, the return value is nonzero.
///
/// If the specified heap or memory block is invalid, the return value is zero. On a system set up for debugging, the HeapValidate function then
/// displays debugging messages that describe the part of the heap or memory block that is invalid, and stops at a hard-coded breakpoint so that you can
/// examine the system to determine the source of the invalidity. The HeapValidate function does not set the thread's last error value. There is
/// no extended error information for this function; do not call GetLastError.
///
///
// BOOL WINAPI HeapValidate( _In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ LPCVOID lpMem);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366708(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366708")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapValidate([In] IntPtr hHeap, HeapFlags dwFlags, [In] IntPtr lpMem);
/// Enumerates the memory blocks in the specified heap.
/// A handle to the heap. This handle is returned by either the HeapCreate or GetProcessHeap function.
///
/// A pointer to a PROCESS_HEAP_ENTRY structure that maintains state information for a particular heap enumeration.
///
/// If the HeapWalk function succeeds, returning the value TRUE, this structure's members contain information about the next memory block
/// in the heap.
///
///
/// To initiate a heap enumeration, set the lpData field of the PROCESS_HEAP_ENTRY structure to NULL. To continue a particular heap
/// enumeration, call the HeapWalk function repeatedly, with no changes to hHeap, lpEntry, or any of the members of the PROCESS_HEAP_ENTRY structure.
///
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
/// If the heap enumeration terminates successfully by reaching the end of the heap, the function returns FALSE, and GetLastError returns
/// the error code ERROR_NO_MORE_ITEMS.
///
///
// BOOL WINAPI HeapWalk( _In_ HANDLE hHeap, _Inout_ LPPROCESS_HEAP_ENTRY lpEntry);// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366710(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("HeapApi.h", MSDNShortId = "aa366710")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool HeapWalk([In] IntPtr hHeap, ref PROCESS_HEAP_ENTRY lpEntry);
/// Specifies flags for a HeapOptimizeResources operation initiated with HeapSetInformation.
[StructLayout(LayoutKind.Sequential)]
public struct HEAP_OPTIMIZE_RESOURCES_INFORMATION
{
/// The version
public uint Version;
/// The flags
public uint Flags;
}
[StructLayout(LayoutKind.Sequential)]
public struct HEAP_SUMMARY
{
public uint cb;
public SizeT cbAllocated;
public SizeT cbCommitted;
public SizeT cbReserved;
public SizeT cbMaxReserve;
}
///
/// Contains information about a heap element. The HeapWalk function uses a PROCESS_HEAP_ENTRY structure to enumerate the elements of a heap.
///
// typedef struct _PROCESS_HEAP_ENTRY { PVOID lpData; DWORD cbData; BYTE cbOverhead; BYTE iRegionIndex; WORD wFlags; union { struct { HANDLE hMem; DWORD
// dwReserved[3]; } Block; struct { DWORD dwCommittedSize; DWORD dwUnCommittedSize; LPVOID lpFirstBlock; LPVOID lpLastBlock; } Region; };}
// PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY; https://msdn.microsoft.com/en-us/library/windows/desktop/aa366798(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "aa366798")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_HEAP_ENTRY
{
///
/// A pointer to the data portion of the heap element.
/// To initiate a HeapWalk heap enumeration, set lpData to NULL.
/// If PROCESS_HEAP_REGION is used in the wFlags member, lpData points to the first virtual address used by the region.
/// If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, lpData points to the beginning of the range of uncommitted memory.
///
public IntPtr lpData;
///
/// The size of the data portion of the heap element, in bytes.
///
/// If PROCESS_HEAP_REGION is used in wFlags, cbData specifies the total size, in bytes, of the address space that is reserved
/// for this region.
///
///
/// If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, cbData specifies the size, in bytes, of the range of uncommitted memory.
///
///
public uint cbData;
///
///
/// The size of the data used by the system to maintain information about the heap element, in bytes. These overhead bytes are in addition to the
/// cbData bytes of the data portion of the heap element.
///
///
/// If PROCESS_HEAP_REGION is used in wFlags, cbOverhead specifies the size, in bytes, of the heap control structures that
/// describe the region.
///
///
/// If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, cbOverhead specifies the size, in bytes, of the control structures that
/// describe this uncommitted range.
///
///
public byte cbOverhead;
///
///
/// A handle to the heap region that contains the heap element. A heap consists of one or more regions of virtual memory, each with a unique region index.
///
///
/// In the first heap entry returned for most heap regions, HeapWalk uses the PROCESS_HEAP_REGION in the wFlags member. When
/// this value is used, the members of the Region structure contain additional information about the region.
///
///
/// The HeapAlloc function sometimes uses the VirtualAlloc function to allocate large blocks from a growable heap. The heap manager
/// treats such a large block allocation as a separate region with a unique region index. HeapWalk does not use PROCESS_HEAP_REGION in
/// the heap entry returned for a large block region, so the members of the Region structure are not valid. You can use the
/// VirtualQuery function to get additional information about a large block region.
///
///
public byte iRegionIndex;
///
///
/// The properties of the heap element. Some values affect the meaning of other members of this PROCESS_HEAP_ENTRY data structure. The
/// following values are defined.
///
///
///
///
/// Value
/// Meaning
///
/// -
/// PROCESS_HEAP_ENTRY_BUSY0x0004
///
/// The heap element is an allocated block.If PROCESS_HEAP_ENTRY_MOVEABLE is also specified, the Block structure becomes valid. The hMem member of
/// the Block structure contains a handle to the allocated, moveable memory block.
///
///
/// -
/// PROCESS_HEAP_ENTRY_DDESHARE0x0020
/// This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.
///
/// -
/// PROCESS_HEAP_ENTRY_MOVEABLE0x0010
///
/// This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.The block was allocated with
/// LMEM_MOVEABLE or GMEM_MOVEABLE, and the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated,
/// moveable memory block.
///
///
/// -
/// PROCESS_HEAP_REGION0x0001
///
/// The heap element is located at the beginning of a region of contiguous virtual memory in use by the heap.The lpData member of the structure
/// points to the first virtual address used by the region; the cbData member specifies the total size, in bytes, of the address space that is
/// reserved for this region; and the cbOverhead member specifies the size, in bytes, of the heap control structures that describe the region.The
/// Region structure becomes valid. The dwCommittedSize, dwUnCommittedSize, lpFirstBlock, and lpLastBlock members of the structure contain additional
/// information about the region.
///
///
/// -
/// PROCESS_HEAP_UNCOMMITTED_RANGE0x0002
///
/// The heap element is located in a range of uncommitted memory within the heap region.The lpData member points to the beginning of the range of
/// uncommitted memory; the cbData member specifies the size, in bytes, of the range of uncommitted memory; and the cbOverhead member specifies the
/// size, in bytes, of the control structures that describe this uncommitted range.
///
///
///
///
///
public PROCESS_HEAP wFlags;
/// A union
public BLOCK_REGION_UNION union;
/// Union of child structures.
[StructLayout(LayoutKind.Explicit)]
public struct BLOCK_REGION_UNION
{
///
/// This structure is valid only if both the PROCESS_HEAP_ENTRY_BUSY and PROCESS_HEAP_ENTRY_MOVEABLE are specified in wFlags.
///
[FieldOffset(0)]
public BLOCK_DATA Block;
/// This structure is valid only if the wFlags member specifies PROCESS_HEAP_REGION.
[FieldOffset(0)]
public REGION_DATA Region;
///
/// This structure is valid only if both the PROCESS_HEAP_ENTRY_BUSY and PROCESS_HEAP_ENTRY_MOVEABLE are specified in wFlags.
///
[StructLayout(LayoutKind.Sequential)]
public struct BLOCK_DATA
{
/// Handle to the allocated, moveable memory block.
public IntPtr hMem;
/// Reserved; not used.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
public uint[] dwReserved;
}
/// This structure is valid only if the wFlags member specifies PROCESS_HEAP_REGION.
[StructLayout(LayoutKind.Sequential)]
public struct REGION_DATA
{
///
/// Number of bytes in the heap region that are currently committed as free memory blocks, busy memory blocks, or heap control structures.
/// This is an optional field that is set to zero if the number of committed bytes is not available.
///
public uint dwCommittedSize;
///
/// Number of bytes in the heap region that are currently uncommitted. This is an optional field that is set to zero if the number of
/// uncommitted bytes is not available.
///
public uint dwUnCommittedSize;
/// Pointer to the first valid memory block in this heap region.
public IntPtr lpFirstBlock;
/// Pointer to the first invalid memory block in this heap region.
public IntPtr lpLastBlock;
}
}
}
/// Safe handle for memory heaps.
///
public class SafePrivateHeapBlockHandle : GenericSafeHandle
{
private SafePrivateHeapHandle hHeap;
/// Initializes a new instance of the class.
public SafePrivateHeapBlockHandle(SafePrivateHeapHandle hHeap) : this(hHeap, IntPtr.Zero) { }
/// Initializes a new instance of the class.
/// A handle to a heap created using .
/// The handle created by .
/// if set to true this safe handle disposes the handle when done.
public SafePrivateHeapBlockHandle(SafePrivateHeapHandle hHeap, IntPtr ptr, bool own = true) : base(ptr, h => HeapFree(hHeap, 0, h), own)
{
this.hHeap = hHeap;
}
///
/// Initializes a new instance of the class and allocates the specified amount of memory from the process heap.
///
/// A handle to a heap created using .
/// The size. This value cannot be zero.
public SafePrivateHeapBlockHandle(SafePrivateHeapHandle hHeap, int size) : this(hHeap, HeapAlloc(hHeap, HeapFlags.HEAP_ZERO_MEMORY, (IntPtr)size)) { }
/// Retrieves the size of this memory block.
/// The size in bytes of this memory block.
public long Size => HeapSize(hHeap, 0, handle).ToInt64();
}
/// Safe handle for memory heaps.
///
public class SafePrivateHeapHandle : GenericSafeHandle
{
/// Initializes a new instance of the class.
public SafePrivateHeapHandle() : this(IntPtr.Zero) { }
/// Initializes a new instance of the class.
/// The handle created by .
/// if set to true this safe handle disposes the handle when done.
public SafePrivateHeapHandle(IntPtr ptr, bool own = true) : base(ptr, HeapDestroy, own) { }
/// Gets a block of memory from this private heap.
/// The size of the block.
/// A safe handle for the memory that will call HeapFree on disposal.
public SafePrivateHeapBlockHandle GetBlock(int size) => new SafePrivateHeapBlockHandle(this, size);
}
/// Safe handle for memory heaps.
///
public class SafeProcessHeapBlockHandle : GenericSafeHandle
{
/// Initializes a new instance of the class.
public SafeProcessHeapBlockHandle() : this(IntPtr.Zero) { }
/// Initializes a new instance of the class.
/// The handle created by .
/// if set to true this safe handle disposes the handle when done.
public SafeProcessHeapBlockHandle(IntPtr ptr, bool own = true) : base(ptr, h => HeapFree(GetProcessHeap(), 0, h), own) { }
///
/// Initializes a new instance of the class and allocates the specified amount of memory from the process heap.
///
/// The size. This value cannot be zero.
public SafeProcessHeapBlockHandle(ulong size) : this(HeapAlloc(GetProcessHeap(), HeapFlags.HEAP_ZERO_MEMORY, (IntPtr)size)) { }
/// Retrieves the size of this memory block.
/// The size in bytes of this memory block.
public long Size => HeapSize(GetProcessHeap(), 0, handle).ToInt64();
}
}
}