Reactos
at master 91 lines 2.7 kB view raw
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 22 if (GetLastError() == ERROR_NO_MORE_ITEMS) 23 return _HEAPEND; 24 25 return _HEAPBADNODE; 26 } 27 __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) 28 { 29 return _HEAPBADNODE; 30 } 31 __endtry 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 49 _VALIDATE_RETURN(entry != nullptr, EINVAL, _HEAPBADPTR); 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}