ReactOS 0.4.16-dev-853-g88d9285
heapwalk.cpp
Go to the documentation of this file.
1//
2// heapwalk.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Implementation of _heapwalk().
7//
8#include <corecrt_internal.h>
9#include <malloc.h>
10
11
12
13// Calls HeapWalk and guards against access violations in case a bad pointer is
14// passed to the CRT _heapwalk function (or in case the heap is corrupt).
15static int __cdecl try_walk(PROCESS_HEAP_ENTRY* const win32_entry) throw()
16{
17 __try
18 {
19 if (HeapWalk(__acrt_heap, win32_entry))
20 return _HEAPOK;
21
23 return _HEAPEND;
24
25 return _HEAPBADNODE;
26 }
28 {
29 return _HEAPBADNODE;
30 }
32}
33
34// Walks the heap, returning information on one entry at a time. If there are
35// multiple threads in the process that are allocating using the process heap,
36// the caller must lock the heap for the duration of the heap walk, by calling
37// the Windows API HeapLock. See the documentation of HeapWalk for more
38// information.
39//
40// The return value is one of the following:
41// * _HEAPOK The call completed successfully and returned a node
42// * _HEAPBADPTR The provided 'entry' pointer is invalid
43// * _HEAPBADBEGIN The initial node cannot be found in the heap
44// * _HEAPBADNODE A node was malformed or the heap is corrupt
45// * _HEAPEND The end of the heap was successfully reached
46extern "C" int __cdecl _heapwalk(_HEAPINFO* const entry)
47{
48 // Validation section
50
51 PROCESS_HEAP_ENTRY win32_entry = { 0 };
52 win32_entry.wFlags = 0;
53 win32_entry.iRegionIndex = 0;
54 win32_entry.lpData = entry->_pentry;
55
56 // If _pentry is nullptr, then we're just starting the heap walk:
57 if (win32_entry.lpData == nullptr)
58 {
59 if (!HeapWalk(__acrt_heap, &win32_entry))
60 return _HEAPBADBEGIN;
61 }
62 else
63 {
64 if (entry->_useflag == _USEDENTRY)
65 {
66 if (!HeapValidate(__acrt_heap, 0, entry->_pentry))
67 return _HEAPBADNODE;
68
69 win32_entry.wFlags = PROCESS_HEAP_ENTRY_BUSY;
70 }
71
72 int const status = try_walk(&win32_entry);
73 if (status != _HEAPOK)
74 return status;
75 }
76
77 for (;;)
78 {
79 if (win32_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
80 {
81 entry->_pentry = static_cast<int*>(win32_entry.lpData);
82 entry->_size = win32_entry.cbData;
83 entry->_useflag = _USEDENTRY;
84 return _HEAPOK;
85 }
86
87 int const status = try_walk(&win32_entry);
88 if (status != _HEAPOK)
89 return status;
90 }
91}
#define EINVAL
Definition: acclib.h:90
#define __cdecl
Definition: accygwin.h:79
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
#define _HEAPOK
Definition: malloc.h:29
#define _HEAPBADBEGIN
Definition: malloc.h:30
#define _HEAPBADNODE
Definition: malloc.h:31
#define _HEAPEND
Definition: malloc.h:32
#define _HEAPBADPTR
Definition: malloc.h:33
#define _USEDENTRY
Definition: malloc.h:37
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
HANDLE __acrt_heap
Definition: heap_handle.cpp:15
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
BOOL WINAPI HeapWalk(HANDLE hHeap, LPPROCESS_HEAP_ENTRY lpEntry)
Definition: heapmem.c:291
static int __cdecl try_walk(PROCESS_HEAP_ENTRY *const win32_entry)
Definition: heapwalk.cpp:15
int __cdecl _heapwalk(_HEAPINFO *const entry)
Definition: heapwalk.cpp:46
uint32_t entry
Definition: isohybrid.c:63
#define __try
Definition: pseh2_64.h:172
#define __except
Definition: pseh2_64.h:173
#define __endtry
Definition: pseh2_64.h:175
#define GetExceptionCode()
Definition: exception.h:68
Definition: winbase.h:1293
WORD wFlags
Definition: winbase.h:1298
PVOID lpData
Definition: winbase.h:1294
BYTE iRegionIndex
Definition: winbase.h:1297
DWORD cbData
Definition: winbase.h:1295
Definition: ps.c:97
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define PROCESS_HEAP_ENTRY_BUSY
Definition: winbase.h:362
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:337