2 * Copyright 2011 André Hentschel
3 * Copyright 2013 Mislav Blažević
4 * Copyright 2015 Mark Jansen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
27 #include "wine/unicode.h"
30 static HANDLE
SdbpHeap(void);
32 #if SDBAPI_DEBUG_ALLOC
34 typedef struct SHIM_ALLOC_ENTRY
42 } SHIM_ALLOC_ENTRY
, *PSHIM_ALLOC_ENTRY
;
45 static RTL_AVL_TABLE g_SdbpAllocationTable
;
48 static RTL_GENERIC_COMPARE_RESULTS
49 NTAPI
ShimAllocCompareRoutine(_In_ PRTL_AVL_TABLE Table
, _In_ PVOID FirstStruct
, _In_ PVOID SecondStruct
)
51 PVOID First
= ((PSHIM_ALLOC_ENTRY
)FirstStruct
)->Address
;
52 PVOID Second
= ((PSHIM_ALLOC_ENTRY
)SecondStruct
)->Address
;
55 return GenericLessThan
;
56 else if (First
== Second
)
58 return GenericGreaterThan
;
61 static PVOID NTAPI
ShimAllocAllocateRoutine(_In_ PRTL_AVL_TABLE Table
, _In_ CLONG ByteSize
)
63 return HeapAlloc(SdbpHeap(), HEAP_ZERO_MEMORY
, ByteSize
);
66 static VOID NTAPI
ShimAllocFreeRoutine(_In_ PRTL_AVL_TABLE Table
, _In_ PVOID Buffer
)
68 HeapFree(SdbpHeap(), 0, Buffer
);
71 static void SdbpInsertAllocation(PVOID address
, SIZE_T size
, int line
, const char* file
)
73 SHIM_ALLOC_ENTRY Entry
= {0};
75 Entry
.Address
= address
;
79 RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable
, &Entry
, sizeof(Entry
), NULL
);
82 static void SdbpUpdateAllocation(PVOID address
, PVOID newaddress
, SIZE_T size
, int line
, const char* file
)
84 SHIM_ALLOC_ENTRY Lookup
= {0};
85 PSHIM_ALLOC_ENTRY Entry
;
86 Lookup
.Address
= address
;
87 Entry
= RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable
, &Lookup
);
89 if (address
== newaddress
)
95 Lookup
.Address
= newaddress
;
99 Lookup
.Prev
= address
;
100 RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable
, &Lookup
, sizeof(Lookup
), NULL
);
101 Entry
->Next
= newaddress
;
105 static void SdbpRemoveAllocation(PVOID address
, int line
, const char* file
)
108 SHIM_ALLOC_ENTRY Lookup
= {0};
109 PSHIM_ALLOC_ENTRY Entry
;
111 sprintf(buf
, "\r\n===============\r\n%s(%d): SdbpFree called, tracing alloc:\r\n", file
, line
);
112 OutputDebugStringA(buf
);
114 Lookup
.Address
= address
;
115 while (Lookup
.Address
)
117 Entry
= RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable
, &Lookup
);
121 RtlDeleteElementGenericTableAvl(&g_SdbpAllocationTable
, Entry
);
123 sprintf(buf
, " > %s(%d): %s%sAlloc( %d ) ==> %p\r\n", Lookup
.File
, Lookup
.Line
,
124 Lookup
.Next
? "Invalidated " : "", Lookup
.Prev
? "Re" : "", Lookup
.Size
, Lookup
.Address
);
125 OutputDebugStringA(buf
);
126 Lookup
.Address
= Lookup
.Prev
;
130 Lookup
.Address
= NULL
;
133 sprintf(buf
, "\r\n===============\r\n");
134 OutputDebugStringA(buf
);
139 static HANDLE g_Heap
;
140 void SdbpHeapInit(void)
142 #if SDBAPI_DEBUG_ALLOC
143 RtlInitializeGenericTableAvl(&g_SdbpAllocationTable
, ShimAllocCompareRoutine
,
144 ShimAllocAllocateRoutine
, ShimAllocFreeRoutine
, NULL
);
146 g_Heap
= HeapCreate(0, 0x10000, 0);
149 void SdbpHeapDeinit(void)
151 #if SDBAPI_DEBUG_ALLOC
152 if (g_SdbpAllocationTable
.NumberGenericTableElements
!= 0)
158 DWORD
SdbpStrlen(PCWSTR string
)
160 return (lstrlenW(string
) + 1) * sizeof(WCHAR
);
163 static HANDLE
SdbpHeap(void)
168 LPVOID
SdbpAlloc(SIZE_T size
169 #if SDBAPI_DEBUG_ALLOC
170 , int line
, const char* file
174 LPVOID mem
= HeapAlloc(SdbpHeap(), HEAP_ZERO_MEMORY
, size
);
175 #if SDBAPI_DEBUG_ALLOC
176 SdbpInsertAllocation(mem
, size
, line
, file
);
181 LPVOID
SdbpReAlloc(LPVOID mem
, SIZE_T size
182 #if SDBAPI_DEBUG_ALLOC
183 , int line
, const char* file
187 LPVOID newmem
= HeapReAlloc(SdbpHeap(), HEAP_ZERO_MEMORY
, mem
, size
);
188 #if SDBAPI_DEBUG_ALLOC
189 SdbpUpdateAllocation(mem
, newmem
, size
, line
, file
);
194 void SdbpFree(LPVOID mem
195 #if SDBAPI_DEBUG_ALLOC
196 , int line
, const char* file
200 #if SDBAPI_DEBUG_ALLOC
201 SdbpRemoveAllocation(mem
, line
, file
);
203 HeapFree(SdbpHeap(), 0, mem
);