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(); } } }