1 /* 2 * PROJECT: ReactOS Win32 Base API 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/win32/kernel32/include/baseheap.h 5 * PURPOSE: Base Heap Structures 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 */ 8 9 // 10 // Some important implementation notes. 11 // 12 // Firstly, the Global* APIs in Win32 are largely similar to the Local* APIs, 13 // but there are a number of small differences (for example, there is no such 14 // thing as DDE/Shared Local memory, and the re-allocation semantics are also 15 // simpler, because you cannot force a move). 16 // 17 // Note something VERY IMPORTANT: This implementation *depends* on the fact 18 // that all heap pointers are, at the very least, 8 byte aligned, and that heap 19 // handles are actually pointers inside our HandleEntry->Object, which happens 20 // to be at offset 0x4, which means testing with bit 3 tells us if the handle 21 // is a pointer or a real "handle". On 64-bit, heap pointers should be 16-byte 22 // aligned, and our offset should be 0x8, so the trick works anyways, but using 23 // the 4th bit. 24 // 25 // Apart from MSDN, a wonderful source of information about how this works is 26 // available on Raymond's blog, in a 4-parter series starting at: 27 // http://blogs.msdn.com/oldnewthing/archive/2004/11/04/252258.aspx. 28 // 29 // Finally, as Raymond points out, be aware that some applications depend on 30 // the way this implementation was done, since global memory handles are a 31 // straight-forward overlay on top of the RTL Handle implementation, and rogue 32 // applications can easily do the conversion manually without calling the right 33 // API for it (such as GlobalLock). 34 // 35 36 // Tracing Support 37 // Define _BASE_HANDLE_TRACE for Traces 38 // 39 #ifdef _BASE_HANDLE_TRACE_ 40 #define BH_PRINT DbgPrint 41 #else 42 #define BH_PRINT DPRINT 43 #endif 44 #define BASE_TRACE_ALLOC(x, y) \ 45 BH_PRINT("[BASE_HEAP] %s : Allocating %lx bytes with flags: %lx\n", \ 46 __FUNCTION__, x, y) 47 #define BASE_TRACE_ALLOC2(x) \ 48 BH_PRINT("[BASE_HEAP] %s : Allocated %p\n", \ 49 __FUNCTION__, x) 50 #define BASE_TRACE_PTR(x, y) \ 51 BH_PRINT("[BASE_HEAP] %s : Using handle: %p for pointer: %p\n", \ 52 __FUNCTION__, x, y) 53 #define BASE_TRACE_HANDLE(x, y) \ 54 BH_PRINT("[BASE_HEAP] %s : Using handle: %lx for block: %p\n", \ 55 __FUNCTION__, x, y) 56 #define BASE_TRACE_DEALLOC(x) \ 57 BH_PRINT("[BASE_HEAP] %s : Freeing %p\n", \ 58 __FUNCTION__, x) 59 #define BASE_TRACE_FAILURE() \ 60 BH_PRINT("[BASE_HEAP] %s : Failing %d\n", \ 61 __FUNCTION__, __LINE__) 62 63 // 64 // The handle structure for global heap handles. 65 // Notice that it nicely overlays with RTL_HANDLE_ENTRY. 66 // KEEP IT THAT WAY! ;-) 67 // 68 typedef struct _BASE_HEAP_HANDLE_ENTRY 69 { 70 USHORT Flags; 71 USHORT LockCount; 72 union 73 { 74 PVOID Object; 75 ULONG OldSize; 76 }; 77 } BASE_HEAP_HANDLE_ENTRY, *PBASE_HEAP_HANDLE_ENTRY; 78 79 // 80 // Handle entry flags 81 // Note that 0x0001 is the shared/generic RTL_HANDLE_VALID 82 // 83 #define BASE_HEAP_ENTRY_FLAG_MOVABLE 0x0002 84 #define BASE_HEAP_ENTRY_FLAG_REUSABLE 0x0004 85 #define BASE_HEAP_ENTRY_FLAG_REUSE 0x0008 86 #define BASE_HEAP_ENTRY_FLAG_DDESHARE 0x0010 87 88 // 89 // Easy way to check if the global handle is actually an entry in our table 90 // 91 #define BASE_HEAP_IS_HANDLE_ENTRY \ 92 (ULONG_PTR)FIELD_OFFSET(BASE_HEAP_HANDLE_ENTRY, Object) 93 94 // 95 // Tags for the entire heap allocation for this global memory. 96 // They are set part of the User Flags of the RTL Heap. 97 // 98 #define BASE_HEAP_FLAG_MOVABLE HEAP_SETTABLE_USER_FLAG1 99 #define BASE_HEAP_FLAG_DDESHARE HEAP_SETTABLE_USER_FLAG2 100 101 // 102 // Internal Handle Functions 103 // 104 #define BaseHeapAllocEntry() \ 105 (PBASE_HEAP_HANDLE_ENTRY)RtlAllocateHandle(&BaseHeapHandleTable, NULL) 106 107 #define BaseHeapGetEntry(h) \ 108 (PBASE_HEAP_HANDLE_ENTRY) \ 109 CONTAINING_RECORD(h, \ 110 BASE_HEAP_HANDLE_ENTRY, \ 111 Object); 112 113 #define BaseHeapValidateEntry(he) \ 114 RtlIsValidHandle(&BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he) 115 116 #define BaseHeapFreeEntry(he) \ 117 RtlFreeHandle(&BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)he); 118 119