~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ole32/ifs.c

Version: ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.