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