using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class Kernel32 { /// The memory allocation attributes. [Flags] public enum GMEM { /// Combines GMEM_MOVEABLE and GMEM_ZEROINIT. GHND = 0x0042, /// Allocates fixed memory. The return value is a pointer. GMEM_FIXED = 0x0000, /// /// Allocates movable memory. Memory blocks are never moved in physical memory, but they can be moved within the default heap. /// The return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function. /// This value cannot be combined with GMEM_FIXED. /// GMEM_MOVEABLE = 0x0002, /// Initializes memory contents to zero. GMEM_ZEROINIT = 0x0040, /// Combines GMEM_FIXED and GMEM_ZEROINIT. GPTR = 0x0040, /// /// The function modifies the attributes of the memory object only (the dwBytes parameter is ignored). This value can only be /// used with . /// GMEM_MODIFY = 0x0080, } /// The memory allocation attributes. [PInvokeData("MinWinBase.h")] [Flags] public enum LMEM { /// Allocates fixed memory. The return value is a pointer to the memory object. LMEM_FIXED = 0x0000, /// /// Allocates movable memory. Memory blocks are never moved in physical memory, but they can be moved within the default heap. /// The return value is a handle to the memory object. To translate the handle to a pointer, use the LocalLock function. This /// value cannot be combined with LMEM_FIXED. /// LMEM_MOVEABLE = 0x0002, /// Obsolete. [Obsolete] LMEM_NOCOMPACT = 0x0010, /// Obsolete. [Obsolete] LMEM_NODISCARD = 0x0020, /// Initializes memory contents to zero. LMEM_ZEROINIT = 0x0040, /// /// If the LMEM_MODIFY flag is specified in LocalReAlloc, this parameter modifies the attributes of the memory object, and the /// uBytes parameter is ignored. /// LMEM_MODIFY = 0x0080, /// Obsolete. [Obsolete] LMEM_DISCARDABLE = 0x0F00, /// Valid flags. LMEM_VALID_FLAGS = 0x0F72, /// Indicates that the local handle is not valid LMEM_INVALID_HANDLE = 0x8000, /// Combines LMEM_MOVEABLE and LMEM_ZEROINIT. LHND = LMEM_MOVEABLE | LMEM_ZEROINIT, /// Combines LMEM_FIXED and LMEM_ZEROINIT. LPTR = LMEM_FIXED | LMEM_ZEROINIT, /// Same as LMEM_MOVEABLE. NONZEROLHND = LMEM_MOVEABLE, /// Same as LMEM_FIXED. NONZEROLPTR = LMEM_FIXED } /// Allocates the specified number of bytes from the heap. /// /// /// The memory allocation attributes. If zero is specified, the default is GMEM_FIXED. This parameter can be one or more of /// the following values, except for the incompatible combinations that are specifically noted. /// /// /// /// /// Value /// Meaning /// /// /// GHND0x0042 /// Combines GMEM_MOVEABLE and GMEM_ZEROINIT. /// /// /// GMEM_FIXED0x0000 /// Allocates fixed memory. The return value is a pointer. /// /// /// GMEM_MOVEABLE0x0002 /// /// Allocates movable memory. Memory blocks are never moved in physical memory, but they can be moved within the default heap.The /// return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function.This value /// cannot be combined with GMEM_FIXED. /// /// /// /// GMEM_ZEROINIT0x0040 /// Initializes memory contents to zero. /// /// /// GPTR0x0040 /// Combines GMEM_FIXED and GMEM_ZEROINIT. /// /// /// /// The following values are obsolete, but are provided for compatibility with 16-bit Windows. They are ignored. /// /// /// The number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies GMEM_MOVEABLE, the function /// returns a handle to a memory object that is marked as discarded. /// /// /// If the function succeeds, the return value is a handle to the newly allocated memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HGLOBAL WINAPI GlobalAlloc( _In_ UINT uFlags, _In_ SIZE_T dwBytes); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366574(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366574")] public static extern HGLOBAL GlobalAlloc(GMEM uFlags, SizeT dwBytes); /// Retrieves information about the specified global memory object. /// /// A handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function. /// /// /// If the function succeeds, the return value specifies the allocation values and the lock count for the memory object. /// /// If the function fails, the return value is GMEM_INVALID_HANDLE, indicating that the global handle is not valid. To get /// extended error information, call GetLastError. /// /// // UINT WINAPI GlobalFlags( _In_ HGLOBAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366577(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366577")] public static extern GMEM GlobalFlags([In] HGLOBAL hMem); /// Frees the specified global memory object and invalidates its handle. /// /// A handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function. /// It is not safe to free memory allocated with LocalAlloc. /// /// /// If the function succeeds, the return value is NULL. /// /// If the function fails, the return value is equal to a handle to the global memory object. To get extended error information, call GetLastError. /// /// // HGLOBAL WINAPI GlobalFree( _In_ HGLOBAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366579(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366579")] public static extern HGLOBAL GlobalFree(HGLOBAL hMem); /// Retrieves the handle associated with the specified pointer to a global memory block. /// /// A pointer to the first byte of the global memory block. This pointer is returned by the GlobalLock function. /// /// /// If the function succeeds, the return value is a handle to the specified global memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HGLOBAL WINAPI GlobalHandle( _In_ LPCVOID pMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366582(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366582")] public static extern HGLOBAL GlobalHandle([In] IntPtr pMem); /// /// Locks a global memory object and returns a pointer to the first byte of the object's memory block. /// /// Note The global functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a global function should be used. For more /// information, see Global and Local Functions. /// /// /// /// A handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function. /// /// /// If the function succeeds, the return value is a pointer to the first byte of the memory block. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// /// /// /// The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, /// GlobalLock increments the count by one, and the GlobalUnlock function decrements the count by one. Each successful call /// that a process makes to GlobalLock for an object must be matched by a corresponding call to GlobalUnlock. Locked /// memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory /// block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded. /// /// /// Memory objects allocated with GMEM_FIXED always have a lock count of zero. For these objects, the value of the returned /// pointer is equal to the value of the specified handle. /// /// If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL. /// Discarded objects always have a lock count of zero. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-globallock LPVOID GlobalLock( HGLOBAL hMem ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "0d7deac2-c9c4-4adc-8a0a-edfc512a4d6c")] public static extern IntPtr GlobalLock(HGLOBAL hMem); /// Changes the size or attributes of a specified global memory object. The size can increase or decrease. /// /// A handle to the global memory object to be reallocated. This handle is returned by either the GlobalAlloc or /// GlobalReAlloc function. /// /// /// The new size of the memory block, in bytes. If uFlags specifies GMEM_MODIFY, this parameter is ignored. /// /// /// /// The reallocation options. If GMEM_MODIFY is specified, the function modifies the attributes of the memory object only (the /// dwBytes parameter is ignored.) Otherwise, the function reallocates the memory object. /// /// You can optionally combine GMEM_MODIFY with the following value. /// /// /// /// Value /// Meaning /// /// /// GMEM_MOVEABLE0x0002 /// /// Allocates movable memory.If the memory is a locked GMEM_MOVEABLE memory block or a GMEM_FIXED memory block and this flag is not /// specified, the memory can only be reallocated in place. /// /// /// /// /// If this parameter does not specify GMEM_MODIFY, you can use the following value. /// /// /// /// Value /// Meaning /// /// /// GMEM_ZEROINIT0x0040 /// Causes the additional memory contents to be initialized to zero if the memory object is growing in size. /// /// /// /// /// /// If the function succeeds, the return value is a handle to the reallocated memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HGLOBAL WINAPI GlobalReAlloc( _In_ HGLOBAL hMem, _In_ SIZE_T dwBytes, _In_ UINT uFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366590(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366590")] public static extern HGLOBAL GlobalReAlloc([In] HGLOBAL hMem, SizeT dwBytes, GMEM uFlags); /// Retrieves the current size of the specified global memory object, in bytes. /// /// A handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function. /// /// /// If the function succeeds, the return value is the size of the specified global memory object, in bytes. /// /// If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error /// information, call GetLastError. /// /// // SIZE_T WINAPI GlobalSize( _In_ HGLOBAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366593(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366593")] public static extern SizeT GlobalSize([In] HGLOBAL hMem); /// /// /// Decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE. This function has no /// effect on memory objects allocated with GMEM_FIXED. /// /// /// Note The global functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a global function should be used. For more /// information, see Global and Local Functions. /// /// /// /// A handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function. /// /// /// /// If the memory object is still locked after decrementing the lock count, the return value is a nonzero value. If the memory object /// is unlocked after decrementing the lock count, the function returns zero and GetLastError returns NO_ERROR. /// /// If the function fails, the return value is zero and GetLastError returns a value other than NO_ERROR. /// /// /// /// The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the /// GlobalLock function increments the count by one, and GlobalUnlock decrements the count by one. For each call that a /// process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or /// discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory /// object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded. /// /// /// Memory objects allocated with GMEM_FIXED always have a lock count of zero. If the specified memory block is fixed memory, /// this function returns TRUE. /// /// If the memory object is already unlocked, GlobalUnlock returns FALSE and GetLastError reports ERROR_NOT_LOCKED. /// /// A process should not rely on the return value to determine the number of times it must subsequently call GlobalUnlock for /// a memory object. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-globalunlock BOOL GlobalUnlock( HGLOBAL hMem ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "580a2873-7f06-47a1-acf5-c2b3c96e15e7")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GlobalUnlock(HGLOBAL hMem); /// Determines whether the calling process has read access to the memory at the specified address. /// A pointer to a memory address. /// /// If the calling process has read access to the specified memory, the return value is zero. /// /// If the calling process does not have read access to the specified memory, the return value is nonzero. To get extended error /// information, call GetLastError. /// /// /// If the application is compiled as a debugging version, and the process does not have read access to the specified memory /// location, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, /// and returns a nonzero value. This behavior is by design, as a debugging aid. /// /// // BOOL WINAPI IsBadCodePtr( _In_ FARPROC lpfn); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366712(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366712")] [Obsolete("This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use.")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsBadCodePtr(IntPtr lpfn); /// Verifies that the calling process has read access to the specified range of memory. /// A pointer to the first byte of the memory block. /// The size of the memory block, in bytes. If this parameter is zero, the return value is zero. /// /// If the calling process has read access to all bytes in the specified memory range, the return value is zero. /// If the calling process does not have read access to all bytes in the specified memory range, the return value is nonzero. /// /// If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified /// memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as /// usual, and returns a nonzero value. This behavior is by design, as a debugging aid. /// /// // BOOL WINAPI IsBadReadPtr( _In_ const VOID *lp, _In_ UINT_PTR ucb); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366713(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366713")] [Obsolete("This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use.")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsBadReadPtr([In] IntPtr lp, SizeT ucb); /// Verifies that the calling process has read access to the specified range of memory. /// A pointer to a null-terminated string, either Unicode or ASCII. /// /// The maximum size of the string, in TCHARs. The function checks for read access in all characters up to the string's /// terminating null character or up to the number of characters specified by this parameter, whichever is smaller. If this parameter /// is zero, the return value is zero. /// /// /// /// If the calling process has read access to all characters up to the string's terminating null character or up to the number of /// characters specified by ucchMax, the return value is zero. /// /// /// If the calling process does not have read access to all characters up to the string's terminating null character or up to the /// number of characters specified by ucchMax, the return value is nonzero. /// /// /// If the application is compiled as a debugging version, and the process does not have read access to the entire memory range /// specified, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, /// and returns a nonzero value This behavior is by design, as a debugging aid. /// /// // BOOL WINAPI IsBadStringPtr( _In_ LPCTSTR lpsz, _In_ UINT_PTR ucchMax); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366714(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "aa366714")] [Obsolete("This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use.")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsBadStringPtr(string lpsz, SizeT ucchMax); /// Verifies that the calling process has write access to the specified range of memory. /// A pointer to the first byte of the memory block. /// The size of the memory block, in bytes. If this parameter is zero, the return value is zero. /// /// If the calling process has write access to all bytes in the specified memory range, the return value is zero. /// If the calling process does not have write access to all bytes in the specified memory range, the return value is nonzero. /// /// If the application is run under a debugger and the process does not have write access to all bytes in the specified memory range, /// the function causes a first chance STATUS_ACCESS_VIOLATION exception. The debugger can be configured to break for this condition. /// After resuming process execution in the debugger, the function continues as usual and returns a nonzero value This behavior is by /// design and serves as a debugging aid. /// /// // BOOL WINAPI IsBadWritePtr( _In_ LPVOID lp, _In_ UINT_PTR ucb); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366716(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366716")] [Obsolete("This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use.")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsBadWritePtr([In] IntPtr lp, SizeT ucb); /// /// Allocates the specified number of bytes from the heap. /// /// Note The local functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a local function should be used. For more /// information, see Global and Local Functions. /// /// /// /// /// The memory allocation attributes. The default is the LMEM_FIXED value. This parameter can be one or more of the following /// values, except for the incompatible combinations that are specifically noted. /// /// /// /// Value /// Meaning /// /// /// LHND 0x0042 /// Combines LMEM_MOVEABLE and LMEM_ZEROINIT. /// /// /// LMEM_FIXED 0x0000 /// Allocates fixed memory. The return value is a pointer to the memory object. /// /// /// LMEM_MOVEABLE 0x0002 /// /// Allocates movable memory. Memory blocks are never moved in physical memory, but they can be moved within the default heap. The /// return value is a handle to the memory object. To translate the handle to a pointer, use the LocalLock function. This value /// cannot be combined with LMEM_FIXED. /// /// /// /// LMEM_ZEROINIT 0x0040 /// Initializes memory contents to zero. /// /// /// LPTR 0x0040 /// Combines LMEM_FIXED and LMEM_ZEROINIT. /// /// /// NONZEROLHND /// Same as LMEM_MOVEABLE. /// /// /// NONZEROLPTR /// Same as LMEM_FIXED. /// /// /// The following values are obsolete, but are provided for compatibility with 16-bit Windows. They are ignored. /// /// /// /// The number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies LMEM_MOVEABLE, the function /// returns a handle to a memory object that is marked as discarded. /// /// /// /// If the function succeeds, the return value is a handle to the newly allocated memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// /// /// /// Windows memory management does not provide a separate local heap and global heap. Therefore, the LocalAlloc and /// GlobalAlloc functions are essentially the same. /// /// /// The movable-memory flags LHND, LMEM_MOVABLE, and NONZEROLHND add unnecessary overhead and require locking to /// be used safely. They should be avoided unless documentation specifically states that they should be used. /// /// /// New applications should use the heap functions unless the documentation specifically states that a local function should be used. /// For example, some Windows functions allocate memory that must be freed with LocalFree. /// /// /// If the heap does not contain sufficient free space to satisfy the request, LocalAlloc returns NULL. Because /// NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a /// NULL pointer. /// /// /// If the LocalAlloc function succeeds, it allocates at least the amount requested. If the amount allocated is greater than /// the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the LocalSize function. /// /// To free the memory, use the LocalFree function. It is not safe to free memory allocated with LocalAlloc using GlobalFree. /// Examples /// The following code shows a simple use of LocalAlloc and LocalFree. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-localalloc DECLSPEC_ALLOCATOR HLOCAL LocalAlloc( UINT // uFlags, SIZE_T uBytes ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "da8cd2be-ff4c-4da5-813c-8759a58228c9")] public static extern HLOCAL LocalAlloc(LMEM uFlags, SizeT uBytes); /// Retrieves information about the specified local memory object. /// /// A handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function. /// /// /// If the function succeeds, the return value specifies the allocation values and the lock count for the memory object. /// /// If the function fails, the return value is LMEM_INVALID_HANDLE, indicating that the local handle is not valid. To get /// extended error information, call GetLastError. /// /// // UINT WINAPI LocalFlags( _In_ HLOCAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366728(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366728")] public static extern LMEM LocalFlags([In] HLOCAL hMem); /// /// Frees the specified local memory object and invalidates its handle. /// /// Note The local functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a local function should be used. For more /// information, see Global and Local Functions. /// /// /// /// /// A handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function. It is not safe to /// free memory allocated with GlobalAlloc. /// /// /// /// If the function succeeds, the return value is NULL. /// /// If the function fails, the return value is equal to a handle to the local memory object. To get extended error information, call GetLastError. /// /// /// /// /// If the process tries to examine or modify the memory after it has been freed, heap corruption may occur or an access violation /// exception (EXCEPTION_ACCESS_VIOLATION) may be generated. /// /// If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL. /// /// The LocalFree function will free a locked memory object. A locked memory object has a lock count greater than zero. The /// LocalLock function locks a local memory object and increments the lock count by one. The LocalUnlock function unlocks it and /// decrements the lock count by one. To get the lock count of a local memory object, use the LocalFlags function. /// /// /// If an application is running under a debug version of the system, LocalFree will issue a message that tells you that a /// locked object is being freed. If you are debugging the application, LocalFree will enter a breakpoint just before freeing /// a locked object. This allows you to verify the intended behavior, then continue execution. /// /// Examples /// For an example, see LocalAlloc. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-localfree HLOCAL LocalFree( _Frees_ptr_opt_ HLOCAL hMem ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "a0393983-cb43-4dfa-91a6-d82a5fb8de12")] public static extern HLOCAL LocalFree(HLOCAL hMem); /// Retrieves the handle associated with the specified pointer to a local memory object. /// /// A pointer to the first byte of the local memory object. This pointer is returned by the LocalLock function. /// /// /// If the function succeeds, the return value is a handle to the specified local memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // HLOCAL WINAPI LocalHandle( _In_ LPCVOID pMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366733(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366733")] public static extern HLOCAL LocalHandle([In] IntPtr pMem); /// Locks a local memory object and returns a pointer to the first byte of the object's memory block. /// /// A handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function. /// /// /// If the function succeeds, the return value is a pointer to the first byte of the memory block. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// // LPVOID WINAPI LocalLock( _In_ HLOCAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366737(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366737")] public static extern IntPtr LocalLock([In] HLOCAL hMem); /// /// Changes the size or the attributes of a specified local memory object. The size can increase or decrease. /// /// Note The local functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a local function should be used. For more /// information, see Global and Local Functions. /// /// /// /// /// A handle to the local memory object to be reallocated. This handle is returned by either the LocalAlloc or LocalReAlloc function. /// /// /// /// The new size of the memory block, in bytes. If uFlags specifies LMEM_MODIFY, this parameter is ignored. /// /// /// /// The reallocation options. If LMEM_MODIFY is specified, the function modifies the attributes of the memory object only (the /// uBytes parameter is ignored.) Otherwise, the function reallocates the memory object. /// /// You can optionally combine LMEM_MODIFY with the following value. /// /// /// Value /// Meaning /// /// /// LMEM_MOVEABLE 0x0002 /// /// Allocates fixed or movable memory. If the memory is a locked LMEM_MOVEABLE memory block or a LMEM_FIXED memory block and this /// flag is not specified, the memory can only be reallocated in place. /// /// /// /// If this parameter does not specify LMEM_MODIFY, you can use the following value. /// /// /// Value /// Meaning /// /// /// LMEM_ZEROINIT 0x0040 /// Causes the additional memory contents to be initialized to zero if the memory object is growing in size. /// /// /// /// /// If the function succeeds, the return value is a handle to the reallocated memory object. /// If the function fails, the return value is NULL. To get extended error information, call GetLastError. /// /// /// If LocalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid. /// /// If LocalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the /// memory block. To access the memory, a process can simply cast the return value to a pointer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-localrealloc DECLSPEC_ALLOCATOR HLOCAL LocalReAlloc( // _Frees_ptr_opt_ HLOCAL hMem, SIZE_T uBytes, UINT uFlags ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "88527ddd-e0c2-4a41-825e-d3a6df77fd2a")] public static extern HLOCAL LocalReAlloc(HLOCAL hMem, SizeT uBytes, LMEM uFlags); /// /// Retrieves the current size of the specified local memory object, in bytes. /// /// Note The local functions have greater overhead and provide fewer features than other memory management functions. New /// applications should use the heap functions unless documentation states that a local function should be used. For more /// information, see Global and Local Functions. /// /// /// /// A handle to the local memory object. This handle is returned by the LocalAlloc, LocalReAlloc, or LocalHandle function. /// /// /// /// If the function succeeds, the return value is the size of the specified local memory object, in bytes. If the specified handle is /// not valid or if the object has been discarded, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The size of a memory block may be larger than the size requested when the memory was allocated. /// /// To verify that the specified object's memory block has not been discarded, call the LocalFlags function before calling LocalSize. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-localsize SIZE_T LocalSize( HLOCAL hMem ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "d1337845-d89c-4cd5-a584-36fe0c682c1a")] public static extern SizeT LocalSize(HLOCAL hMem); /// /// Decrements the lock count associated with a memory object that was allocated with LMEM_MOVEABLE. This function has no /// effect on memory objects allocated with LMEM_FIXED. /// /// /// A handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function. /// /// /// /// If the memory object is still locked after decrementing the lock count, the return value is nonzero. If the memory object is /// unlocked after decrementing the lock count, the function returns zero and GetLastError returns NO_ERROR. /// /// If the function fails, the return value is zero and GetLastError returns a value other than NO_ERROR. /// // BOOL WINAPI LocalUnlock( _In_ HLOCAL hMem); https://msdn.microsoft.com/en-us/library/windows/desktop/aa366747(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "aa366747")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LocalUnlock([In] HLOCAL hMem); /// Provides a handle to heap allocated memory. [StructLayout(LayoutKind.Sequential)] public struct HGLOBAL : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HGLOBAL(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HGLOBAL NULL => new HGLOBAL(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HGLOBAL h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HGLOBAL(IntPtr h) => new HGLOBAL(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HGLOBAL h1, HGLOBAL h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HGLOBAL h1, HGLOBAL h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HGLOBAL h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Provides a handle to a local heap allocation. [StructLayout(LayoutKind.Sequential)] public struct HLOCAL : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HLOCAL(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HLOCAL NULL => new HLOCAL(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HLOCAL h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HLOCAL(IntPtr h) => new HLOCAL(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HLOCAL h1, HLOCAL h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HLOCAL h1, HLOCAL h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HLOCAL h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } } }