Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111//// free_base.cpp//// Copyright (c) Microsoft Corporation. All rights reserved.//// Implementation of _free_base(). This is defined in a different source file// from the free() function to allow free() to be replaced by the user.//#include <corecrt_internal.h>#include <malloc.h>
#if _UCRT_HEAP_MISMATCH_ANY && (defined _M_IX86 || defined _M_AMD64)
// Gets a handle to MSVCRT's private heap, if msvcrt is loaded for the // current process. Otherwise returns nullptr. extern "C" HANDLE __cdecl __acrt_get_msvcrt_heap_handle() { static HANDLE global_msvcrt_heap_handle_cache = reinterpret_cast<HANDLE>(1);
HANDLE const cached_msvcrt_heap_handle = __crt_interlocked_read_pointer(&global_msvcrt_heap_handle_cache); if (cached_msvcrt_heap_handle != reinterpret_cast<HANDLE>(1)) { return cached_msvcrt_heap_handle; }
HMODULE const msvcrt_module_handle = GetModuleHandleW(L"msvcrt.dll"); if (!msvcrt_module_handle) { // If msvcrt is not loaded, its heap does not exist: __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, nullptr); return nullptr; }
typedef intptr_t (__cdecl* fp_get_heap_handle)();
// Get the exported function _get_heap_handle() from MSVCRT fp_get_heap_handle const get_msvcrt_heap_handle = reinterpret_cast<fp_get_heap_handle>(GetProcAddress( msvcrt_module_handle, "_get_heap_handle"));
if (!get_msvcrt_heap_handle) { __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, nullptr); return nullptr; }
HANDLE const new_msvcrt_heap_handle = reinterpret_cast<HANDLE>(get_msvcrt_heap_handle()); __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, new_msvcrt_heap_handle); return new_msvcrt_heap_handle; }
#endif // _UCRT_HEAP_MISMATCH_ANY && (defined _M_IX86 || defined _M_AMD64)
#if _UCRT_HEAP_MISMATCH_RECOVERY && (defined _M_IX86 || defined _M_AMD64)
static __forceinline HANDLE __cdecl select_heap(void* const block) { HANDLE const msvcrt_heap_handle = __acrt_get_msvcrt_heap_handle(); if (!msvcrt_heap_handle) { return __acrt_heap; }
if (HeapValidate(__acrt_heap, 0, block)) { return __acrt_heap; }
if (HeapValidate(msvcrt_heap_handle, 0, block)) { return msvcrt_heap_handle; }
return __acrt_heap; }
#else // ^^^ Heap Mismatch Recovery ^^^ // vvv No Heap Mismatch Recovery vvv //
static __forceinline HANDLE __cdecl select_heap(void* const block) { UNREFERENCED_PARAMETER(block);
return __acrt_heap; }
#endif
// This function implements the logic of free(). It is called directly by the// free() function in the Release CRT, and it is called by the debug heap in the// Debug CRT.//// This function must be marked noinline, otherwise free and// _free_base will have identical COMDATs, and the linker will fold// them when calling one from the CRT. This is necessary because free// needs to support users patching in custom implementations.extern "C" void __declspec(noinline) __cdecl _free_base(void* const block){ if (block == nullptr) { return; }
if (!HeapFree(select_heap(block), 0, block)) { errno = __acrt_errno_from_os_error(GetLastError()); }}