mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:42:58 +00:00
[UCRT] Import Microsoft.Windows.SDK.CRTSource version 10.0.22621.3
Imported from https://www.nuget.org/packages/Microsoft.Windows.SDK.CRTSource/10.0.22621.3 License: MIT
This commit is contained in:
parent
f1b60c66f0
commit
04e0dc4a7a
568 changed files with 115483 additions and 0 deletions
110
sdk/lib/ucrt/heap/free_base.cpp
Normal file
110
sdk/lib/ucrt/heap/free_base.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue