| [5602] | 1 | /*
|
|---|
| [6711] | 2 | * basic interfaces
|
|---|
| [5602] | 3 | *
|
|---|
| [6711] | 4 | * Copyright 1997 Marcus Meissner
|
|---|
| [8441] | 5 | *
|
|---|
| 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.
|
|---|
| 10 | *
|
|---|
| 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.
|
|---|
| 15 | *
|
|---|
| 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|---|
| [5602] | 19 | */
|
|---|
| 20 |
|
|---|
| [7926] | 21 | #include "config.h"
|
|---|
| 22 |
|
|---|
| [5602] | 23 | #include <ctype.h>
|
|---|
| 24 | #include <stdlib.h>
|
|---|
| 25 | #include <string.h>
|
|---|
| 26 | #include <assert.h>
|
|---|
| [7926] | 27 |
|
|---|
| 28 | #include "ole2.h"
|
|---|
| 29 | #include "windef.h"
|
|---|
| [9400] | 30 | #include "winbase.h"
|
|---|
| [5602] | 31 | #include "winerror.h"
|
|---|
| [7926] | 32 |
|
|---|
| 33 | #include "wine/obj_base.h"
|
|---|
| 34 |
|
|---|
| [8441] | 35 | #include "wine/debug.h"
|
|---|
| [5602] | 36 |
|
|---|
| [9400] | 37 | WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|---|
| [5602] | 38 |
|
|---|
| [9400] | 39 | /******************************************************************************
|
|---|
| 40 | * IMalloc32 implementation
|
|---|
| 41 | *
|
|---|
| 42 | * NOTES
|
|---|
| 43 | * For supporting CoRegisterMallocSpy the IMalloc implementation must know if
|
|---|
| 44 | * a given memory block was allocated with a spy active.
|
|---|
| 45 | *
|
|---|
| 46 | *****************************************************************************/
|
|---|
| 47 | /* set the vtable later */
|
|---|
| 48 | extern ICOM_VTABLE(IMalloc) VT_IMalloc32;
|
|---|
| 49 |
|
|---|
| 50 | typedef struct {
|
|---|
| 51 | ICOM_VFIELD(IMalloc);
|
|---|
| 52 | DWORD dummy; /* nothing, we are static */
|
|---|
| 53 | IMallocSpy * pSpy; /* the spy when active */
|
|---|
| 54 | DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
|
|---|
| 55 | BOOL SpyReleasePending; /* CoRevokeMallocSpy called with spyed allocations left*/
|
|---|
| 56 | LPVOID * SpyedBlocks; /* root of the table */
|
|---|
| 57 | int SpyedBlockTableLength; /* size of the table*/
|
|---|
| 58 | } _Malloc32;
|
|---|
| 59 |
|
|---|
| 60 | /* this is the static object instance */
|
|---|
| 61 | _Malloc32 Malloc32 = {&VT_IMalloc32, 0, NULL, 0, 0, NULL, 0};
|
|---|
| 62 |
|
|---|
| 63 | /* with a spy active all calls from pre to post methods are threadsave */
|
|---|
| 64 | static CRITICAL_SECTION IMalloc32_SpyCS = CRITICAL_SECTION_INIT("IMalloc32_SpyCS");
|
|---|
| 65 |
|
|---|
| 66 | /* resize the old table */
|
|---|
| 67 | static int SetSpyedBlockTableLength ( int NewLength )
|
|---|
| [5602] | 68 | {
|
|---|
| [9400] | 69 | Malloc32.SpyedBlocks = (LPVOID*)LocalReAlloc((HLOCAL)Malloc32.SpyedBlocks, NewLength, GMEM_ZEROINIT);
|
|---|
| 70 | Malloc32.SpyedBlockTableLength = NewLength;
|
|---|
| 71 | return Malloc32.SpyedBlocks ? 1 : 0;
|
|---|
| 72 | }
|
|---|
| [5602] | 73 |
|
|---|
| [9400] | 74 | /* add a location to the table */
|
|---|
| 75 | static int AddMemoryLocation(LPVOID * pMem)
|
|---|
| 76 | {
|
|---|
| 77 | LPVOID * Current;
|
|---|
| 78 |
|
|---|
| 79 | /* allocate the table if not already allocated */
|
|---|
| 80 | if (!Malloc32.SpyedBlockTableLength) {
|
|---|
| 81 | if (!SetSpyedBlockTableLength(0x1000)) return 0;
|
|---|
| 82 | }
|
|---|
| 83 |
|
|---|
| 84 | /* find a free location */
|
|---|
| 85 | Current = Malloc32.SpyedBlocks;
|
|---|
| 86 | while (*Current) {
|
|---|
| 87 | Current++;
|
|---|
| 88 | if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
|
|---|
| 89 | /* no more space in table, grow it */
|
|---|
| 90 | if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
|
|---|
| 91 | }
|
|---|
| 92 | };
|
|---|
| 93 |
|
|---|
| 94 | /* put the location in our table */
|
|---|
| 95 | *Current = pMem;
|
|---|
| 96 | Malloc32.SpyedAllocationsLeft++;
|
|---|
| 97 | /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
|
|---|
| 98 | return 1;
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | static int RemoveMemoryLocation(LPVOID * pMem)
|
|---|
| 102 | {
|
|---|
| 103 | LPVOID * Current = Malloc32.SpyedBlocks;
|
|---|
| 104 |
|
|---|
| 105 | /* find the location */
|
|---|
| 106 | while (*Current != pMem) {
|
|---|
| 107 | Current++;
|
|---|
| 108 | if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) return 0; /* not found */
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | /* location found */
|
|---|
| 112 | Malloc32.SpyedAllocationsLeft--;
|
|---|
| 113 | /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
|
|---|
| 114 | *Current = NULL;
|
|---|
| 115 | return 1;
|
|---|
| 116 | }
|
|---|
| 117 |
|
|---|
| [5602] | 118 | /******************************************************************************
|
|---|
| [9400] | 119 | * IMalloc32_QueryInterface [VTABLE]
|
|---|
| [5602] | 120 | */
|
|---|
| [9400] | 121 | static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
|
|---|
| 122 |
|
|---|
| 123 | TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
|
|---|
| 124 |
|
|---|
| 125 | if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
|
|---|
| 126 | *obj = (LPMALLOC)&Malloc32;
|
|---|
| 127 | return S_OK;
|
|---|
| 128 | }
|
|---|
| 129 | return E_NOINTERFACE;
|
|---|
| [5602] | 130 | }
|
|---|
| 131 |
|
|---|
| 132 | /******************************************************************************
|
|---|
| [9400] | 133 | * IMalloc32_AddRefRelease [VTABLE]
|
|---|
| [5602] | 134 | */
|
|---|
| [9400] | 135 | static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
|
|---|
| 136 | return 1;
|
|---|
| [5602] | 137 | }
|
|---|
| 138 |
|
|---|
| 139 | /******************************************************************************
|
|---|
| [9400] | 140 | * IMalloc32_Alloc [VTABLE]
|
|---|
| [5602] | 141 | */
|
|---|
| [9400] | 142 | static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
|
|---|
| [5602] | 143 |
|
|---|
| [9400] | 144 | LPVOID addr;
|
|---|
| [5602] | 145 |
|
|---|
| [10623] | 146 | TRACE("%s: (cb=%ld)\n", __FUNCTION__, cb);
|
|---|
| [9400] | 147 |
|
|---|
| 148 | if(Malloc32.pSpy) {
|
|---|
| 149 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 150 | cb = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
|
|---|
| 151 | if (0==cb) {
|
|---|
| 152 | /* PreAlloc can force Alloc to fail */
|
|---|
| 153 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 154 | return NULL;
|
|---|
| 155 | }
|
|---|
| [6711] | 156 | }
|
|---|
| [9400] | 157 |
|
|---|
| 158 |
|
|---|
| 159 | addr = HeapAlloc(GetProcessHeap(),0,cb);
|
|---|
| 160 |
|
|---|
| 161 | if(Malloc32.pSpy) {
|
|---|
| 162 | addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr);
|
|---|
| 163 | if (addr) AddMemoryLocation(addr);
|
|---|
| 164 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| [10623] | 167 | TRACE("%s: success, memory ptr: %p\n", __FUNCTION__, addr);
|
|---|
| [9400] | 168 | return addr;
|
|---|
| [5602] | 169 | }
|
|---|
| 170 |
|
|---|
| 171 | /******************************************************************************
|
|---|
| [9400] | 172 | * IMalloc32_Realloc [VTABLE]
|
|---|
| [5602] | 173 | */
|
|---|
| [9400] | 174 | static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
|
|---|
| [5602] | 175 |
|
|---|
| [9400] | 176 | LPVOID pNewMemory;
|
|---|
| [5602] | 177 |
|
|---|
| [10623] | 178 | TRACE("%s: (%p,cb=%ld)\n",__FUNCTION__, pv,cb);
|
|---|
| [5602] | 179 |
|
|---|
| [9400] | 180 | if(Malloc32.pSpy) {
|
|---|
| 181 | LPVOID pRealMemory;
|
|---|
| 182 | BOOL fSpyed;
|
|---|
| [5602] | 183 |
|
|---|
| [9400] | 184 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 185 | fSpyed = RemoveMemoryLocation(pv);
|
|---|
| 186 | cb = IMallocSpy_PreRealloc(Malloc32.pSpy, pv, cb, &pRealMemory, fSpyed);
|
|---|
| [5602] | 187 |
|
|---|
| [9400] | 188 | /* check if can release the spy */
|
|---|
| 189 | if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
|
|---|
| 190 | IMallocSpy_Release(Malloc32.pSpy);
|
|---|
| 191 | Malloc32.SpyReleasePending = FALSE;
|
|---|
| 192 | Malloc32.pSpy = NULL;
|
|---|
| 193 | }
|
|---|
| 194 |
|
|---|
| 195 | if (0==cb) {
|
|---|
| 196 | /* PreRealloc can force Realloc to fail */
|
|---|
| 197 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 198 | return NULL;
|
|---|
| 199 | }
|
|---|
| 200 | pv = pRealMemory;
|
|---|
| 201 | }
|
|---|
| 202 |
|
|---|
| 203 | pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb);
|
|---|
| 204 |
|
|---|
| 205 | if(Malloc32.pSpy) {
|
|---|
| 206 | pNewMemory = IMallocSpy_PostRealloc(Malloc32.pSpy, pNewMemory, TRUE);
|
|---|
| 207 | if (pNewMemory) AddMemoryLocation(pNewMemory);
|
|---|
| 208 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 209 | }
|
|---|
| 210 |
|
|---|
| [10623] | 211 | TRACE("s%: --(%p)\n", __FUNCTION__, pNewMemory);
|
|---|
| [9400] | 212 | return pNewMemory;
|
|---|
| 213 | }
|
|---|
| 214 |
|
|---|
| [5602] | 215 | /******************************************************************************
|
|---|
| [9400] | 216 | * IMalloc32_Free [VTABLE]
|
|---|
| [5602] | 217 | */
|
|---|
| [9400] | 218 | static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
|
|---|
| [5602] | 219 |
|
|---|
| [9400] | 220 | BOOL fSpyed = 0;
|
|---|
| 221 |
|
|---|
| [10623] | 222 | TRACE("%s: (pv=%p)\n", __FUNCTION__, pv);
|
|---|
| [9400] | 223 |
|
|---|
| 224 | if(Malloc32.pSpy) {
|
|---|
| 225 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 226 | fSpyed = RemoveMemoryLocation(pv);
|
|---|
| 227 | pv = IMallocSpy_PreFree(Malloc32.pSpy, pv, fSpyed);
|
|---|
| [6711] | 228 | }
|
|---|
| [9400] | 229 |
|
|---|
| 230 | HeapFree(GetProcessHeap(),0,pv);
|
|---|
| 231 |
|
|---|
| 232 | if(Malloc32.pSpy) {
|
|---|
| 233 | IMallocSpy_PostFree(Malloc32.pSpy, fSpyed);
|
|---|
| 234 |
|
|---|
| 235 | /* check if can release the spy */
|
|---|
| 236 | if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
|
|---|
| 237 | IMallocSpy_Release(Malloc32.pSpy);
|
|---|
| 238 | Malloc32.SpyReleasePending = FALSE;
|
|---|
| 239 | Malloc32.pSpy = NULL;
|
|---|
| 240 | }
|
|---|
| 241 |
|
|---|
| 242 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 243 | }
|
|---|
| [5602] | 244 | }
|
|---|
| 245 |
|
|---|
| 246 | /******************************************************************************
|
|---|
| [9400] | 247 | * IMalloc32_GetSize [VTABLE]
|
|---|
| 248 | *
|
|---|
| 249 | * NOTES
|
|---|
| 250 | * FIXME returns:
|
|---|
| 251 | * win95: size allocated (4 byte boundarys)
|
|---|
| 252 | * win2k: size originally requested !!! (allocated on 8 byte boundarys)
|
|---|
| [5602] | 253 | */
|
|---|
| [21916] | 254 | static DWORD WINAPI IMalloc_fnGetSize(LPCMALLOC iface,LPVOID pv) {
|
|---|
| [9400] | 255 |
|
|---|
| 256 | DWORD cb;
|
|---|
| 257 | BOOL fSpyed = 0;
|
|---|
| 258 |
|
|---|
| [10623] | 259 | TRACE("%s: (pv=%p)\n", __FUNCTION__, pv);
|
|---|
| [9400] | 260 |
|
|---|
| 261 | if(Malloc32.pSpy) {
|
|---|
| 262 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 263 | pv = IMallocSpy_PreGetSize(Malloc32.pSpy, pv, fSpyed);
|
|---|
| 264 | }
|
|---|
| 265 |
|
|---|
| 266 | cb = HeapSize(GetProcessHeap(),0,pv);
|
|---|
| 267 |
|
|---|
| 268 | if(Malloc32.pSpy) {
|
|---|
| 269 | cb = IMallocSpy_PostGetSize(Malloc32.pSpy, cb, fSpyed);
|
|---|
| 270 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 | return cb;
|
|---|
| [5602] | 274 | }
|
|---|
| 275 |
|
|---|
| 276 | /******************************************************************************
|
|---|
| [9400] | 277 | * IMalloc32_DidAlloc [VTABLE]
|
|---|
| [5602] | 278 | */
|
|---|
| [21916] | 279 | static INT WINAPI IMalloc_fnDidAlloc(LPCMALLOC iface,LPVOID pv) {
|
|---|
| [9400] | 280 |
|
|---|
| 281 | BOOL fSpyed = 0;
|
|---|
| 282 | int didAlloc;
|
|---|
| 283 |
|
|---|
| [10623] | 284 | TRACE("%s: (%p)\n", __FUNCTION__, pv);
|
|---|
| [9400] | 285 |
|
|---|
| 286 | if(Malloc32.pSpy) {
|
|---|
| 287 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 288 | pv = IMallocSpy_PreDidAlloc(Malloc32.pSpy, pv, fSpyed);
|
|---|
| 289 | }
|
|---|
| 290 |
|
|---|
| 291 | didAlloc = -1;
|
|---|
| 292 |
|
|---|
| 293 | if(Malloc32.pSpy) {
|
|---|
| 294 | didAlloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, pv, fSpyed, didAlloc);
|
|---|
| 295 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 296 | }
|
|---|
| 297 | return didAlloc;
|
|---|
| [5602] | 298 | }
|
|---|
| 299 |
|
|---|
| 300 | /******************************************************************************
|
|---|
| [9400] | 301 | * IMalloc32_HeapMinimize [VTABLE]
|
|---|
| [5602] | 302 | */
|
|---|
| [21916] | 303 | static LPVOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
|
|---|
| [9400] | 304 | TRACE("()\n");
|
|---|
| 305 |
|
|---|
| 306 | if(Malloc32.pSpy) {
|
|---|
| 307 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 308 | IMallocSpy_PreHeapMinimize(Malloc32.pSpy);
|
|---|
| 309 | }
|
|---|
| 310 |
|
|---|
| 311 | if(Malloc32.pSpy) {
|
|---|
| 312 | IMallocSpy_PostHeapMinimize(Malloc32.pSpy);
|
|---|
| 313 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 314 | }
|
|---|
| [5602] | 315 | }
|
|---|
| 316 |
|
|---|
| [9400] | 317 | #ifdef __WIN32OS2__
|
|---|
| 318 | ICOM_VTABLE(IMalloc) VT_IMalloc32 =
|
|---|
| 319 | #else
|
|---|
| 320 | static ICOM_VTABLE(IMalloc) VT_IMalloc32 =
|
|---|
| 321 | #endif
|
|---|
| 322 | {
|
|---|
| 323 | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|---|
| 324 | IMalloc_fnQueryInterface,
|
|---|
| 325 | IMalloc_fnAddRefRelease,
|
|---|
| 326 | IMalloc_fnAddRefRelease,
|
|---|
| 327 | IMalloc_fnAlloc,
|
|---|
| 328 | IMalloc_fnRealloc,
|
|---|
| 329 | IMalloc_fnFree,
|
|---|
| 330 | IMalloc_fnGetSize,
|
|---|
| 331 | IMalloc_fnDidAlloc,
|
|---|
| 332 | IMalloc_fnHeapMinimize
|
|---|
| 333 | };
|
|---|
| 334 |
|
|---|
| [5602] | 335 | /******************************************************************************
|
|---|
| [9400] | 336 | * IMallocSpy implementation
|
|---|
| 337 | *****************************************************************************/
|
|---|
| 338 |
|
|---|
| 339 | /* set the vtable later */
|
|---|
| 340 | extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
|
|---|
| 341 |
|
|---|
| 342 | typedef struct {
|
|---|
| 343 | ICOM_VFIELD(IMallocSpy);
|
|---|
| 344 | DWORD ref;
|
|---|
| 345 | } _MallocSpy;
|
|---|
| 346 |
|
|---|
| 347 | /* this is the static object instance */
|
|---|
| 348 | _MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
|
|---|
| 349 |
|
|---|
| 350 | /******************************************************************************
|
|---|
| 351 | * IMalloc32_QueryInterface [VTABLE]
|
|---|
| [5602] | 352 | */
|
|---|
| [9400] | 353 | static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
|
|---|
| [7926] | 354 | {
|
|---|
| [9400] | 355 |
|
|---|
| 356 | TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
|
|---|
| 357 |
|
|---|
| 358 | if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMallocSpy,refiid)) {
|
|---|
| 359 | *obj = (LPMALLOC)&MallocSpy;
|
|---|
| 360 | return S_OK;
|
|---|
| 361 | }
|
|---|
| 362 | return E_NOINTERFACE;
|
|---|
| [5602] | 363 | }
|
|---|
| 364 |
|
|---|
| 365 | /******************************************************************************
|
|---|
| [9400] | 366 | * IMalloc32_AddRef [VTABLE]
|
|---|
| [5602] | 367 | */
|
|---|
| [9400] | 368 | static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
|
|---|
| [7926] | 369 | {
|
|---|
| [9400] | 370 |
|
|---|
| 371 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 372 |
|
|---|
| 373 | TRACE ("(%p)->(count=%lu)\n", This, This->ref);
|
|---|
| 374 |
|
|---|
| 375 | return ++(This->ref);
|
|---|
| [5602] | 376 | }
|
|---|
| 377 |
|
|---|
| 378 | /******************************************************************************
|
|---|
| [9400] | 379 | * IMalloc32_AddRelease [VTABLE]
|
|---|
| 380 | *
|
|---|
| 381 | * NOTES
|
|---|
| 382 | * Our MallocSpy is static. If the count reaches 0 we dump the leaks
|
|---|
| [5602] | 383 | */
|
|---|
| [9400] | 384 | static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
|
|---|
| [5602] | 385 | {
|
|---|
| [9400] | 386 |
|
|---|
| 387 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 388 |
|
|---|
| 389 | TRACE ("(%p)->(count=%lu)\n", This, This->ref);
|
|---|
| 390 |
|
|---|
| 391 | if (!--(This->ref)) {
|
|---|
| 392 | /* our allocation list MUST be empty here */
|
|---|
| 393 | }
|
|---|
| 394 | return This->ref;
|
|---|
| [5602] | 395 | }
|
|---|
| 396 |
|
|---|
| [9400] | 397 | static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
|
|---|
| 398 | {
|
|---|
| 399 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 400 | TRACE ("(%p)->(%lu)\n", This, cbRequest);
|
|---|
| 401 | return cbRequest;
|
|---|
| [5602] | 402 | }
|
|---|
| [9400] | 403 | static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
|
|---|
| 404 | {
|
|---|
| 405 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 406 | TRACE ("(%p)->(%p)\n", This, pActual);
|
|---|
| 407 | return pActual;
|
|---|
| 408 | }
|
|---|
| [5602] | 409 |
|
|---|
| [9400] | 410 | static PVOID WINAPI IMallocSpy_fnPreFree(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
|---|
| 411 | {
|
|---|
| 412 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 413 | TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
|---|
| 414 | return pRequest;
|
|---|
| [5602] | 415 | }
|
|---|
| [9400] | 416 | static void WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
|
|---|
| 417 | {
|
|---|
| 418 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 419 | TRACE ("(%p)->(%u)\n", This, fSpyed);
|
|---|
| 420 | }
|
|---|
| [5602] | 421 |
|
|---|
| [9400] | 422 | static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
|
|---|
| [7926] | 423 | {
|
|---|
| [9400] | 424 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 425 | TRACE ("(%p)->(%p %lu %u)\n", This, pRequest, cbRequest, fSpyed);
|
|---|
| 426 | *ppNewRequest = pRequest;
|
|---|
| 427 | return cbRequest;
|
|---|
| 428 | }
|
|---|
| [5602] | 429 |
|
|---|
| [9400] | 430 | static PVOID WINAPI IMallocSpy_fnPostRealloc(LPMALLOCSPY iface, void* pActual, BOOL fSpyed)
|
|---|
| 431 | {
|
|---|
| 432 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 433 | TRACE ("(%p)->(%p %u)\n", This, pActual, fSpyed);
|
|---|
| 434 | return pActual;
|
|---|
| [5602] | 435 | }
|
|---|
| 436 |
|
|---|
| [9400] | 437 | static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
|---|
| 438 | {
|
|---|
| 439 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 440 | TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
|---|
| 441 | return pRequest;
|
|---|
| 442 | }
|
|---|
| [5602] | 443 |
|
|---|
| [9400] | 444 | static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
|
|---|
| [5602] | 445 | {
|
|---|
| [9400] | 446 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 447 | TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
|
|---|
| 448 | return cbActual;
|
|---|
| 449 | }
|
|---|
| [5602] | 450 |
|
|---|
| [9400] | 451 | static PVOID WINAPI IMallocSpy_fnPreDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
|---|
| 452 | {
|
|---|
| 453 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 454 | TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
|---|
| 455 | return pRequest;
|
|---|
| 456 | }
|
|---|
| [5602] | 457 |
|
|---|
| [9400] | 458 | static int WINAPI IMallocSpy_fnPostDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed, int fActual)
|
|---|
| 459 | {
|
|---|
| 460 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 461 | TRACE ("(%p)->(%p %u %u)\n", This, pRequest, fSpyed, fActual);
|
|---|
| 462 | return fActual;
|
|---|
| [5602] | 463 | }
|
|---|
| 464 |
|
|---|
| [9400] | 465 | static int WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
|
|---|
| 466 | {
|
|---|
| 467 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 468 | TRACE ("(%p)->()\n", This);
|
|---|
| 469 | return 0;
|
|---|
| [5602] | 470 | }
|
|---|
| 471 |
|
|---|
| [9400] | 472 | static int WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
|
|---|
| 473 | {
|
|---|
| 474 | ICOM_THIS (_MallocSpy, iface);
|
|---|
| 475 | TRACE ("(%p)->()\n", This);
|
|---|
| 476 | return 0;
|
|---|
| [5602] | 477 | }
|
|---|
| 478 |
|
|---|
| [9400] | 479 | static void MallocSpyDumpLeaks() {
|
|---|
| 480 | TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
|
|---|
| [5602] | 481 | }
|
|---|
| 482 |
|
|---|
| [9400] | 483 | #ifdef __WIN32OS2__
|
|---|
| 484 | ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
|
|---|
| 485 | #else
|
|---|
| 486 | static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
|
|---|
| 487 | #endif
|
|---|
| 488 | {
|
|---|
| 489 | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|---|
| 490 | IMallocSpy_fnQueryInterface,
|
|---|
| 491 | IMallocSpy_fnAddRef,
|
|---|
| 492 | IMallocSpy_fnRelease,
|
|---|
| 493 | IMallocSpy_fnPreAlloc,
|
|---|
| 494 | IMallocSpy_fnPostAlloc,
|
|---|
| 495 | IMallocSpy_fnPreFree,
|
|---|
| 496 | IMallocSpy_fnPostFree,
|
|---|
| 497 | IMallocSpy_fnPreRealloc,
|
|---|
| 498 | IMallocSpy_fnPostRealloc,
|
|---|
| 499 | IMallocSpy_fnPreGetSize,
|
|---|
| 500 | IMallocSpy_fnPostGetSize,
|
|---|
| 501 | IMallocSpy_fnPreDidAlloc,
|
|---|
| 502 | IMallocSpy_fnPostDidAlloc,
|
|---|
| 503 | IMallocSpy_fnPreHeapMinimize,
|
|---|
| 504 | IMallocSpy_fnPostHeapMinimize
|
|---|
| 505 | };
|
|---|
| 506 |
|
|---|
| [5602] | 507 | /******************************************************************************
|
|---|
| [9400] | 508 | * CoGetMalloc [OLE32.20]
|
|---|
| 509 | *
|
|---|
| 510 | * RETURNS
|
|---|
| 511 | * The win32 IMalloc
|
|---|
| [5602] | 512 | */
|
|---|
| [9400] | 513 | HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC *lpMalloc)
|
|---|
| 514 | {
|
|---|
| 515 | *lpMalloc = (LPMALLOC)&Malloc32;
|
|---|
| 516 | return S_OK;
|
|---|
| [5602] | 517 | }
|
|---|
| 518 |
|
|---|
| [9400] | 519 | /***********************************************************************
|
|---|
| 520 | * CoTaskMemAlloc [OLE32.43]
|
|---|
| 521 | * RETURNS
|
|---|
| 522 | * pointer to newly allocated block
|
|---|
| [5602] | 523 | */
|
|---|
| [9400] | 524 | LPVOID WINAPI CoTaskMemAlloc(ULONG size)
|
|---|
| 525 | {
|
|---|
| 526 | return IMalloc_Alloc((LPMALLOC)&Malloc32,size);
|
|---|
| [5602] | 527 | }
|
|---|
| [9400] | 528 | /***********************************************************************
|
|---|
| 529 | * CoTaskMemFree [OLE32.44]
|
|---|
| [5602] | 530 | */
|
|---|
| [9400] | 531 | VOID WINAPI CoTaskMemFree(LPVOID ptr)
|
|---|
| 532 | {
|
|---|
| 533 | IMalloc_Free((LPMALLOC)&Malloc32, ptr);
|
|---|
| [5602] | 534 | }
|
|---|
| 535 |
|
|---|
| [9400] | 536 | /***********************************************************************
|
|---|
| 537 | * CoTaskMemRealloc [OLE32.45]
|
|---|
| 538 | * RETURNS
|
|---|
| 539 | * pointer to newly allocated block
|
|---|
| [5602] | 540 | */
|
|---|
| [9400] | 541 | LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, ULONG size)
|
|---|
| 542 | {
|
|---|
| 543 | return IMalloc_Realloc((LPMALLOC)&Malloc32, pvOld, size);
|
|---|
| [5602] | 544 | }
|
|---|
| 545 |
|
|---|
| [9400] | 546 | /***********************************************************************
|
|---|
| 547 | * CoRegisterMallocSpy [OLE32.37]
|
|---|
| 548 | *
|
|---|
| 549 | * NOTES
|
|---|
| 550 | * if a mallocspy is already registered, we cant do it again since
|
|---|
| 551 | * only the spy knows, how to free a memory block
|
|---|
| [5602] | 552 | */
|
|---|
| [9400] | 553 | HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
|
|---|
| 554 | {
|
|---|
| 555 | IMallocSpy* pSpy;
|
|---|
| 556 | HRESULT hres = E_INVALIDARG;
|
|---|
| 557 |
|
|---|
| 558 | TRACE("\n");
|
|---|
| 559 |
|
|---|
| 560 | /* HACK TO ACTIVATE OUT SPY */
|
|---|
| 561 | if (pMallocSpy == (LPVOID)-1) pMallocSpy =(IMallocSpy*)&MallocSpy;
|
|---|
| 562 |
|
|---|
| 563 | if(Malloc32.pSpy) return CO_E_OBJISREG;
|
|---|
| 564 |
|
|---|
| 565 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 566 |
|
|---|
| 567 | if (SUCCEEDED(IUnknown_QueryInterface(pMallocSpy, &IID_IMallocSpy, (LPVOID*)&pSpy))) {
|
|---|
| 568 | Malloc32.pSpy = pSpy;
|
|---|
| 569 | hres = S_OK;
|
|---|
| 570 | }
|
|---|
| 571 |
|
|---|
| 572 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 573 |
|
|---|
| 574 | return hres;
|
|---|
| [5602] | 575 | }
|
|---|
| 576 |
|
|---|
| [9400] | 577 | /***********************************************************************
|
|---|
| 578 | * CoRevokeMallocSpy [OLE32.41]
|
|---|
| 579 | *
|
|---|
| 580 | * NOTES
|
|---|
| 581 | * we can't rewoke a malloc spy as long as memory blocks allocated with
|
|---|
| 582 | * the spy are active since only the spy knows how to free them
|
|---|
| 583 | */
|
|---|
| 584 | HRESULT WINAPI CoRevokeMallocSpy(void)
|
|---|
| [5602] | 585 | {
|
|---|
| [9400] | 586 | HRESULT hres = S_OK;
|
|---|
| 587 | TRACE("\n");
|
|---|
| [5602] | 588 |
|
|---|
| [9400] | 589 | EnterCriticalSection(&IMalloc32_SpyCS);
|
|---|
| [5602] | 590 |
|
|---|
| [9400] | 591 | /* if it's our spy it's time to dump the leaks */
|
|---|
| 592 | if (Malloc32.pSpy == (IMallocSpy*)&MallocSpy) {
|
|---|
| 593 | MallocSpyDumpLeaks();
|
|---|
| 594 | }
|
|---|
| 595 |
|
|---|
| 596 | if (Malloc32.SpyedAllocationsLeft) {
|
|---|
| 597 | TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
|
|---|
| 598 | Malloc32.SpyReleasePending = TRUE;
|
|---|
| 599 | hres = E_ACCESSDENIED;
|
|---|
| 600 | } else {
|
|---|
| 601 | IMallocSpy_Release(Malloc32.pSpy);
|
|---|
| 602 | Malloc32.pSpy = NULL;
|
|---|
| 603 | }
|
|---|
| 604 | LeaveCriticalSection(&IMalloc32_SpyCS);
|
|---|
| 605 |
|
|---|
| 606 | return S_OK;
|
|---|
| [5602] | 607 | }
|
|---|
| 608 |
|
|---|
| 609 | /******************************************************************************
|
|---|
| [6711] | 610 | * IsValidInterface [OLE32.78]
|
|---|
| [5602] | 611 | *
|
|---|
| 612 | * RETURNS
|
|---|
| 613 | * True, if the passed pointer is a valid interface
|
|---|
| 614 | */
|
|---|
| 615 | BOOL WINAPI IsValidInterface(
|
|---|
| [6711] | 616 | LPUNKNOWN punk /* [in] interface to be tested */
|
|---|
| [5602] | 617 | ) {
|
|---|
| [6711] | 618 | return !(
|
|---|
| 619 | IsBadReadPtr(punk,4) ||
|
|---|
| 620 | IsBadReadPtr(ICOM_VTBL(punk),4) ||
|
|---|
| [5602] | 621 | #ifdef __WIN32OS2__
|
|---|
| [6711] | 622 | IsBadReadPtr(ICOM_VTBL(punk)->fnQueryInterface,9) ||
|
|---|
| 623 | IsBadCodePtr((FARPROC)ICOM_VTBL(punk)->fnQueryInterface)
|
|---|
| [5602] | 624 | #else
|
|---|
| [6711] | 625 | IsBadReadPtr(ICOM_VTBL(punk)->QueryInterface,9) ||
|
|---|
| 626 | IsBadCodePtr((FARPROC)ICOM_VTBL(punk)->QueryInterface)
|
|---|
| [5602] | 627 | #endif
|
|---|
| [6711] | 628 | );
|
|---|
| [5602] | 629 | }
|
|---|