|
|
|
@@ -4,7 +4,7 @@
|
|
|
|
|
use crate::ffi::c_void;
|
|
|
|
|
use crate::ptr;
|
|
|
|
|
use crate::sync::atomic::{AtomicPtr, Ordering};
|
|
|
|
|
use crate::sys::c;
|
|
|
|
|
use crate::sys::c::{self, windows_targets};
|
|
|
|
|
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
|
|
|
|
|
use core::mem::MaybeUninit;
|
|
|
|
|
|
|
|
|
@@ -17,74 +17,71 @@
|
|
|
|
|
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
|
|
|
|
|
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
|
|
|
|
|
|
|
|
|
|
#[link(name = "kernel32")]
|
|
|
|
|
extern "system" {
|
|
|
|
|
// Get a handle to the default heap of the current process, or null if the operation fails.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY: Successful calls to this function within the same process are assumed to
|
|
|
|
|
// always return the same handle, which remains valid for the entire lifetime of the process.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
|
|
|
|
|
fn GetProcessHeap() -> c::HANDLE;
|
|
|
|
|
// Get a handle to the default heap of the current process, or null if the operation fails.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY: Successful calls to this function within the same process are assumed to
|
|
|
|
|
// always return the same handle, which remains valid for the entire lifetime of the process.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
|
|
|
|
|
windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);
|
|
|
|
|
|
|
|
|
|
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
|
|
|
|
|
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
|
|
|
|
|
// set to `HEAP_ZERO_MEMORY`.
|
|
|
|
|
//
|
|
|
|
|
// Returns a pointer to the newly-allocated memory or null if the operation fails.
|
|
|
|
|
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
|
|
|
|
|
//
|
|
|
|
|
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
|
|
|
|
|
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID;
|
|
|
|
|
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
|
|
|
|
|
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
|
|
|
|
|
// set to `HEAP_ZERO_MEMORY`.
|
|
|
|
|
//
|
|
|
|
|
// Returns a pointer to the newly-allocated memory or null if the operation fails.
|
|
|
|
|
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
|
|
|
|
|
//
|
|
|
|
|
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
|
|
|
|
|
windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
|
|
|
|
|
|
|
|
|
|
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
|
|
|
|
|
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
|
|
|
|
|
// or allocating at a new location, copying memory, and freeing the original location.
|
|
|
|
|
//
|
|
|
|
|
// Returns a pointer to the reallocated memory or null if the operation fails.
|
|
|
|
|
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
|
|
|
|
// If the operation fails the given block will never have been freed.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to zero.
|
|
|
|
|
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
|
|
|
|
|
// `HeapReAlloc`, that has not already been freed.
|
|
|
|
|
// If the block was successfully reallocated at a new location, pointers pointing to
|
|
|
|
|
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
|
|
|
|
|
//
|
|
|
|
|
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
|
|
|
|
|
fn HeapReAlloc(
|
|
|
|
|
hHeap: c::HANDLE,
|
|
|
|
|
dwFlags: c::DWORD,
|
|
|
|
|
lpMem: c::LPVOID,
|
|
|
|
|
dwBytes: c::SIZE_T,
|
|
|
|
|
) -> c::LPVOID;
|
|
|
|
|
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
|
|
|
|
|
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
|
|
|
|
|
// or allocating at a new location, copying memory, and freeing the original location.
|
|
|
|
|
//
|
|
|
|
|
// Returns a pointer to the reallocated memory or null if the operation fails.
|
|
|
|
|
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
|
|
|
|
// If the operation fails the given block will never have been freed.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to zero.
|
|
|
|
|
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
|
|
|
|
|
// `HeapReAlloc`, that has not already been freed.
|
|
|
|
|
// If the block was successfully reallocated at a new location, pointers pointing to
|
|
|
|
|
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
|
|
|
|
|
//
|
|
|
|
|
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
|
|
|
|
|
windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
|
|
|
|
|
hheap: c::HANDLE,
|
|
|
|
|
dwflags : u32,
|
|
|
|
|
lpmem: *const core::ffi::c_void,
|
|
|
|
|
dwbytes: usize
|
|
|
|
|
) -> *mut core::ffi::c_void);
|
|
|
|
|
|
|
|
|
|
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
|
|
|
|
|
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to zero.
|
|
|
|
|
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
|
|
|
|
|
// that has not already been freed.
|
|
|
|
|
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
|
|
|
|
|
// must not be dereferenced ever again.
|
|
|
|
|
//
|
|
|
|
|
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
|
|
|
|
|
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL;
|
|
|
|
|
}
|
|
|
|
|
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
|
|
|
|
|
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY:
|
|
|
|
|
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
|
|
|
|
// - `dwFlags` must be set to zero.
|
|
|
|
|
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
|
|
|
|
|
// that has not already been freed.
|
|
|
|
|
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
|
|
|
|
|
// must not be dereferenced ever again.
|
|
|
|
|
//
|
|
|
|
|
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
|
|
|
|
|
//
|
|
|
|
|
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
|
|
|
|
|
windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
|
|
|
|
|
|
|
|
|
|
// Cached handle to the default heap of the current process.
|
|
|
|
|
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.
|
|
|
|
|