ReactOS 0.4.16-dev-715-ga1a169f
free_base.cpp
Go to the documentation of this file.
1//
2// free_base.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Implementation of _free_base(). This is defined in a different source file
7// from the free() function to allow free() to be replaced by the user.
8//
9#include <corecrt_internal.h>
10#include <malloc.h>
11
12#if _UCRT_HEAP_MISMATCH_ANY && (defined _M_IX86 || defined _M_AMD64)
13
14 // Gets a handle to MSVCRT's private heap, if msvcrt is loaded for the
15 // current process. Otherwise returns nullptr.
16 extern "C" HANDLE __cdecl __acrt_get_msvcrt_heap_handle()
17 {
18 static HANDLE global_msvcrt_heap_handle_cache = reinterpret_cast<HANDLE>(1);
19
20 HANDLE const cached_msvcrt_heap_handle = __crt_interlocked_read_pointer(&global_msvcrt_heap_handle_cache);
21 if (cached_msvcrt_heap_handle != reinterpret_cast<HANDLE>(1))
22 {
23 return cached_msvcrt_heap_handle;
24 }
25
26 HMODULE const msvcrt_module_handle = GetModuleHandleW(L"msvcrt.dll");
27 if (!msvcrt_module_handle)
28 {
29 // If msvcrt is not loaded, its heap does not exist:
30 __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, nullptr);
31 return nullptr;
32 }
33
34 typedef intptr_t (__cdecl* fp_get_heap_handle)();
35
36 // Get the exported function _get_heap_handle() from MSVCRT
37 fp_get_heap_handle const get_msvcrt_heap_handle =
38 reinterpret_cast<fp_get_heap_handle>(GetProcAddress(
39 msvcrt_module_handle,
40 "_get_heap_handle"));
41
42 if (!get_msvcrt_heap_handle)
43 {
44 __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, nullptr);
45 return nullptr;
46 }
47
48 HANDLE const new_msvcrt_heap_handle = reinterpret_cast<HANDLE>(get_msvcrt_heap_handle());
49 __crt_interlocked_exchange_pointer(&global_msvcrt_heap_handle_cache, new_msvcrt_heap_handle);
50 return new_msvcrt_heap_handle;
51 }
52
53#endif // _UCRT_HEAP_MISMATCH_ANY && (defined _M_IX86 || defined _M_AMD64)
54
55#if _UCRT_HEAP_MISMATCH_RECOVERY && (defined _M_IX86 || defined _M_AMD64)
56
57 static __forceinline HANDLE __cdecl select_heap(void* const block)
58 {
59 HANDLE const msvcrt_heap_handle = __acrt_get_msvcrt_heap_handle();
60 if (!msvcrt_heap_handle)
61 {
62 return __acrt_heap;
63 }
64
66 {
67 return __acrt_heap;
68 }
69
70 if (HeapValidate(msvcrt_heap_handle, 0, block))
71 {
72 return msvcrt_heap_handle;
73 }
74
75 return __acrt_heap;
76 }
77
78#else // ^^^ Heap Mismatch Recovery ^^^ // vvv No Heap Mismatch Recovery vvv //
79
80 static __forceinline HANDLE __cdecl select_heap(void* const block)
81 {
83
84 return __acrt_heap;
85 }
86
87#endif
88
89
90// This function implements the logic of free(). It is called directly by the
91// free() function in the Release CRT, and it is called by the debug heap in the
92// Debug CRT.
93//
94// This function must be marked noinline, otherwise free and
95// _free_base will have identical COMDATs, and the linker will fold
96// them when calling one from the CRT. This is necessary because free
97// needs to support users patching in custom implementations.
98extern "C" void __declspec(noinline) __cdecl _free_base(void* const block)
99{
100 if (block == nullptr)
101 {
102 return;
103 }
104
105 if (!HeapFree(select_heap(block), 0, block))
106 {
108 }
109}
110
#define __cdecl
Definition: accygwin.h:79
int __cdecl __acrt_errno_from_os_error(unsigned long)
Definition: errno.cpp:103
_ACRTIMP void __cdecl _free_base(_Pre_maybenull_ _Post_invalid_ void *_Block)
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapFree(x, y, z)
Definition: compat.h:735
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define noinline
Definition: types.h:64
void __declspec(noinline) __cdecl _free_base(void *const block)
Definition: free_base.cpp:98
static __forceinline HANDLE __cdecl select_heap(void *const block)
Definition: free_base.cpp:80
HANDLE __acrt_heap
Definition: heap_handle.cpp:15
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define L(x)
Definition: ntvdm.h:50
#define errno
Definition: errno.h:18
int intptr_t
Definition: vcruntime.h:134
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
static unsigned int block
Definition: xmlmemory.c:101