Changeset 9400 for trunk/src/ole32/ifs.c


Ignore:
Timestamp:
Nov 12, 2002, 6:07:48 PM (23 years ago)
Author:
sandervl
Message:

Wine resync

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ole32/ifs.c

    r8441 r9400  
    2828#include "ole2.h"
    2929#include "windef.h"
     30#include "winbase.h"
    3031#include "winerror.h"
    3132
    3233#include "wine/obj_base.h"
    33 #include "wine/winbase16.h"
    34 #include "ifs.h"
    3534
    3635#include "wine/debug.h"
    3736
    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
     41WINE_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 */
     52extern ICOM_VTABLE(IMalloc) VT_IMalloc32;
     53
     54typedef 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 */
     68static CRITICAL_SECTION IMalloc32_SpyCS = CRITICAL_SECTION_INIT("IMalloc32_SpyCS");
     69
     70/* resize the old table */
     71static 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 */
     79static 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
     105static 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 */
     125static 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 */
     139static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
     140        return 1;
     141}
     142
     143/******************************************************************************
     144 *      IMalloc32_Alloc                 [VTABLE]
     145 */
     146static 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 */
     178static 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 */
     222static 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 */
     258static 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 */
     283static 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 */
     307static 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
     324static ICOM_VTABLE(IMalloc) VT_IMalloc32 =
     325#endif
    87326{
    88327        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
    92337};
    93338
    94339/******************************************************************************
    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 */
     344extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
     345
     346typedef 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 */
     357static 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 */
     372static 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 */
     388static 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 */
    241397    }
    242     ICOM_VTBL(This) = (ICOM_VTABLE(IMalloc16)*)msegvt16;
    243     This->ref = 1;
    244     return (LPMALLOC16)MapLS( This );
    245 }
     398    return This->ref;
     399}
     400
     401static 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}
     407static 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
     414static 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}
     420static void  WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
     421{
     422    ICOM_THIS (_MallocSpy, iface);
     423    TRACE ("(%p)->(%u)\n", This, fSpyed);
     424}
     425
     426static 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
     434static 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
     441static 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
     448static 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
     455static 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
     462static 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
     469static int WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
     470{
     471    ICOM_THIS (_MallocSpy, iface);
     472    TRACE ("(%p)->()\n", This);
     473    return 0;
     474}
     475
     476static int WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
     477{
     478    ICOM_THIS (_MallocSpy, iface);
     479    TRACE ("(%p)->()\n", This);
     480    return 0;
     481}
     482
     483static void MallocSpyDumpLeaks() {
     484        TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
     485}
     486
     487#ifdef __WIN32OS2__
     488       ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
     489#else
     490static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
    246491#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
    358509};
    359510
    360511/******************************************************************************
    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 */
     517HRESULT 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 */
     528LPVOID WINAPI CoTaskMemAlloc(ULONG size)
     529{
     530        return IMalloc_Alloc((LPMALLOC)&Malloc32,size);
     531}
     532/***********************************************************************
     533 *           CoTaskMemFree      [OLE32.44]
     534 */
     535VOID 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 */
     545LPVOID 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 */
     557HRESULT 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 */
     588HRESULT 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}
    376612
    377613/******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.