- Implemented IMallocSpy hooks in IMalloc.

- Moved memory related functions into ifs.c.
- Implemented stubs for the MallocSpy.
oldstable
Juergen Schmied 2002-07-29 23:30:20 +00:00 committed by Alexandre Julliard
parent 22780c814d
commit c1f9d386eb
6 changed files with 534 additions and 231 deletions

View File

@ -126,9 +126,6 @@ HINSTANCE16 COMPOBJ_hInstance = 0;
HINSTANCE COMPOBJ_hInstance32 = 0; HINSTANCE COMPOBJ_hInstance32 = 0;
static int COMPOBJ_Attach = 0; static int COMPOBJ_Attach = 0;
LPMALLOC16 currentMalloc16=NULL;
LPMALLOC currentMalloc32=NULL;
HTASK16 hETask = 0; HTASK16 hETask = 0;
WORD Table_ETask[62]; WORD Table_ETask[62];
@ -212,6 +209,35 @@ DWORD WINAPI CoBuildVersion(void)
return (rmm<<16)+rup; return (rmm<<16)+rup;
} }
LPMALLOC16 currentMalloc16=NULL;
/***********************************************************************
* CoGetMalloc [COMPOBJ.4]
* RETURNS
* The current win16 IMalloc
*/
HRESULT WINAPI CoGetMalloc16(
DWORD dwMemContext, /* [in] unknown */
LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
) {
if(!currentMalloc16)
currentMalloc16 = IMalloc16_Constructor();
*lpMalloc = currentMalloc16;
return S_OK;
}
/***********************************************************************
* CoCreateStandardMalloc [COMPOBJ.71]
*/
HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
LPMALLOC16 *lpMalloc)
{
/* FIXME: docu says we shouldn't return the same allocator as in
* CoGetMalloc16 */
*lpMalloc = IMalloc16_Constructor();
return S_OK;
}
/****************************************************************************** /******************************************************************************
* CoInitialize [COMPOBJ.2] * CoInitialize [COMPOBJ.2]
* Set the win16 IMalloc used for memory management * Set the win16 IMalloc used for memory management
@ -367,49 +393,6 @@ void WINAPI CoUninitialize(void)
} }
} }
/***********************************************************************
* CoGetMalloc [COMPOBJ.4]
* RETURNS
* The current win16 IMalloc
*/
HRESULT WINAPI CoGetMalloc16(
DWORD dwMemContext, /* [in] unknown */
LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
) {
if(!currentMalloc16)
currentMalloc16 = IMalloc16_Constructor();
*lpMalloc = currentMalloc16;
return S_OK;
}
/******************************************************************************
* CoGetMalloc [OLE32.20]
*
* RETURNS
* The current win32 IMalloc
*/
HRESULT WINAPI CoGetMalloc(
DWORD dwMemContext, /* [in] unknown */
LPMALLOC *lpMalloc /* [out] current win32 malloc interface */
) {
if(!currentMalloc32)
currentMalloc32 = IMalloc_Constructor();
*lpMalloc = currentMalloc32;
return S_OK;
}
/***********************************************************************
* CoCreateStandardMalloc [COMPOBJ.71]
*/
HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
LPMALLOC16 *lpMalloc)
{
/* FIXME: docu says we shouldn't return the same allocator as in
* CoGetMalloc16 */
*lpMalloc = IMalloc16_Constructor();
return S_OK;
}
/****************************************************************************** /******************************************************************************
* CoDisconnectObject [COMPOBJ.15] * CoDisconnectObject [COMPOBJ.15]
* CoDisconnectObject [OLE32.8] * CoDisconnectObject [OLE32.8]
@ -1781,55 +1764,6 @@ HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime ) /* [out] the current time *
return S_OK; return S_OK;
} }
/***********************************************************************
* CoTaskMemAlloc (OLE32.43)
* RETURNS
* pointer to newly allocated block
*/
LPVOID WINAPI CoTaskMemAlloc(
ULONG size /* [in] size of memoryblock to be allocated */
) {
LPMALLOC lpmalloc;
HRESULT ret = CoGetMalloc(0,&lpmalloc);
if (FAILED(ret))
return NULL;
return IMalloc_Alloc(lpmalloc,size);
}
/***********************************************************************
* CoTaskMemFree (OLE32.44)
*/
VOID WINAPI CoTaskMemFree(
LPVOID ptr /* [in] pointer to be freed */
) {
LPMALLOC lpmalloc;
HRESULT ret = CoGetMalloc(0,&lpmalloc);
if (FAILED(ret))
return;
IMalloc_Free(lpmalloc, ptr);
}
/***********************************************************************
* CoTaskMemRealloc (OLE32.45)
* RETURNS
* pointer to newly allocated block
*/
LPVOID WINAPI CoTaskMemRealloc(
LPVOID pvOld,
ULONG size) /* [in] size of memoryblock to be allocated */
{
LPMALLOC lpmalloc;
HRESULT ret = CoGetMalloc(0,&lpmalloc);
if (FAILED(ret))
return NULL;
return IMalloc_Realloc(lpmalloc, pvOld, size);
}
/*********************************************************************** /***********************************************************************
* CoLoadLibrary (OLE32.30) * CoLoadLibrary (OLE32.30)
*/ */

View File

@ -35,75 +35,7 @@
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(relay); WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* --- IUnknown implementation */
typedef struct
{
/* IUnknown fields */
ICOM_VFIELD(IUnknown);
DWORD ref;
} IUnknownImpl;
/******************************************************************************
* IUnknown_AddRef [VTABLE:IUNKNOWN.1]
*/
static ULONG WINAPI IUnknown_fnAddRef(LPUNKNOWN iface) {
ICOM_THIS(IUnknownImpl,iface);
TRACE("(%p)->AddRef()\n",This);
return ++(This->ref);
}
/******************************************************************************
* IUnknown_Release [VTABLE:IUNKNOWN.2]
*/
static ULONG WINAPI IUnknown_fnRelease(LPUNKNOWN iface) {
ICOM_THIS(IUnknownImpl,iface);
TRACE("(%p)->Release()\n",This);
if (!--(This->ref)) {
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
/******************************************************************************
* IUnknown_QueryInterface [VTABLE:IUNKNOWN.0]
*/
static HRESULT WINAPI IUnknown_fnQueryInterface(LPUNKNOWN iface,REFIID refiid,LPVOID *obj) {
ICOM_THIS(IUnknownImpl,iface);
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
*obj = This;
return 0;
}
return OLE_E_ENUM_NOMORE;
}
static ICOM_VTABLE(IUnknown) uvt =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IUnknown_fnQueryInterface,
IUnknown_fnAddRef,
IUnknown_fnRelease
};
/******************************************************************************
* IUnknown_Constructor [INTERNAL]
*/
LPUNKNOWN
IUnknown_Constructor() {
IUnknownImpl* unk;
unk = (IUnknownImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IUnknownImpl));
ICOM_VTBL(unk) = &uvt;
unk->ref = 1;
return (LPUNKNOWN)unk;
}
/* --- IMalloc16 implementation */ /* --- IMalloc16 implementation */
@ -245,57 +177,135 @@ IMalloc16_Constructor()
} }
/* --- IMalloc32 implementation */ /******************************************************************************
* IMalloc32 implementation
*
* NOTES
* For supporting CoRegisterMallocSpy the IMalloc implementation must know if
* a given memory block was allocated with a spy active.
*
*****************************************************************************/
/* set the vtable later */
extern ICOM_VTABLE(IMalloc) VT_IMalloc32;
typedef struct typedef struct {
{
/* IUnknown fields */
ICOM_VFIELD(IMalloc); ICOM_VFIELD(IMalloc);
DWORD ref; DWORD dummy; /* nothing, we are static */
} IMalloc32Impl; IMallocSpy * pSpy; /* the spy when active */
DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
BOOL SpyReleasePending; /* CoRevokeMallocSpy called with spyed allocations left*/
LPVOID * SpyedBlocks; /* root of the table */
int SpyedBlockTableLength; /* size of the table*/
} _Malloc32;
/* this is the static object instance */
_Malloc32 Malloc32 = {&VT_IMalloc32, 0, NULL, 0, 0, NULL, 0};
/* with a spy active all calls from pre to post methods are threadsave */
static CRITICAL_SECTION IMalloc32_SpyCS = CRITICAL_SECTION_INIT("IMalloc32_SpyCS");
/* resize the old table */
static int SetSpyedBlockTableLength ( int NewLength )
{
Malloc32.SpyedBlocks = (LPVOID*)LocalReAlloc((HLOCAL)Malloc32.SpyedBlocks, NewLength, GMEM_ZEROINIT);
Malloc32.SpyedBlockTableLength = NewLength;
return Malloc32.SpyedBlocks ? 1 : 0;
}
/* add a location to the table */
static int AddMemoryLocation(LPVOID * pMem)
{
LPVOID * Current;
/* allocate the table if not already allocated */
if (!Malloc32.SpyedBlockTableLength) {
if (!SetSpyedBlockTableLength(0x1000)) return 0;
}
/* find a free location */
Current = Malloc32.SpyedBlocks;
while (*Current) {
Current++;
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
/* no more space in table, grow it */
if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
}
};
/* put the location in our table */
*Current = pMem;
Malloc32.SpyedAllocationsLeft++;
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
return 1;
}
static int RemoveMemoryLocation(LPVOID * pMem)
{
LPVOID * Current = Malloc32.SpyedBlocks;
/* find the location */
while (*Current != pMem) {
Current++;
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) return 0; /* not found */
}
/* location found */
Malloc32.SpyedAllocationsLeft--;
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
*Current = NULL;
return 1;
}
/****************************************************************************** /******************************************************************************
* IMalloc32_QueryInterface [VTABLE] * IMalloc32_QueryInterface [VTABLE]
*/ */
static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) { static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
ICOM_THIS(IMalloc32Impl,iface);
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj); TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
if (IsEqualIID(&IID_IUnknown,refiid) || if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
IsEqualIID(&IID_IMalloc,refiid)) { *obj = (LPMALLOC)&Malloc32;
*obj = This;
return S_OK; return S_OK;
} }
return E_NOINTERFACE; return E_NOINTERFACE;
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_AddRef [VTABLE] * IMalloc32_AddRefRelease [VTABLE]
*/ */
static ULONG WINAPI IMalloc_fnAddRef(LPMALLOC iface) { static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
ICOM_THIS(IMalloc32Impl,iface); return 1;
TRACE("(%p)->AddRef()\n",This);
return 1; /* cannot be freed */
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_Release [VTABLE] * IMalloc32_Alloc [VTABLE]
*/ */
static ULONG WINAPI IMalloc_fnRelease(LPMALLOC iface) { static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
ICOM_THIS(IMalloc32Impl,iface);
TRACE("(%p)->Release()\n",This);
return 1; /* cannot be freed */
}
/******************************************************************************
* IMalloc32_Alloc [VTABLE]
*/
static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface,DWORD cb) {
LPVOID addr; LPVOID addr;
ICOM_THIS(IMalloc32Impl,iface);
TRACE("(%ld)\n",cb);
if(Malloc32.pSpy) {
EnterCriticalSection(&IMalloc32_SpyCS);
cb = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
if (0==cb) {
/* PreAlloc can force Alloc to fail */
LeaveCriticalSection(&IMalloc32_SpyCS);
return NULL;
}
}
addr = HeapAlloc(GetProcessHeap(),0,cb); addr = HeapAlloc(GetProcessHeap(),0,cb);
TRACE("(%p)->Alloc(%ld) -> %p\n",This,cb,addr);
if(Malloc32.pSpy) {
addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr);
if (addr) AddMemoryLocation(addr);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
TRACE("--(%p)\n",addr);
return addr; return addr;
} }
@ -303,76 +313,431 @@ static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface,DWORD cb) {
* IMalloc32_Realloc [VTABLE] * IMalloc32_Realloc [VTABLE]
*/ */
static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) { static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
ICOM_THIS(IMalloc32Impl,iface);
TRACE("(%p)->Realloc(%p,%ld)\n",This,pv,cb); LPVOID pNewMemory;
return HeapReAlloc(GetProcessHeap(),0,pv,cb);
TRACE("(%p,%ld)\n",pv,cb);
if(Malloc32.pSpy) {
LPVOID pRealMemory;
BOOL fSpyed;
EnterCriticalSection(&IMalloc32_SpyCS);
fSpyed = RemoveMemoryLocation(pv);
cb = IMallocSpy_PreRealloc(Malloc32.pSpy, pv, cb, &pRealMemory, fSpyed);
/* check if can release the spy */
if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
IMallocSpy_Release(Malloc32.pSpy);
Malloc32.SpyReleasePending = FALSE;
Malloc32.pSpy = NULL;
}
if (0==cb) {
/* PreRealloc can force Realloc to fail */
LeaveCriticalSection(&IMalloc32_SpyCS);
return NULL;
}
pv = pRealMemory;
}
pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb);
if(Malloc32.pSpy) {
pNewMemory = IMallocSpy_PostRealloc(Malloc32.pSpy, pNewMemory, TRUE);
if (pNewMemory) AddMemoryLocation(pNewMemory);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
TRACE("--(%p)\n",pNewMemory);
return pNewMemory;
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_Free [VTABLE] * IMalloc32_Free [VTABLE]
*/ */
static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) { static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
ICOM_THIS(IMalloc32Impl,iface);
TRACE("(%p)->Free(%p)\n",This,pv); BOOL fSpyed = 0;
TRACE("(%p)\n",pv);
if(Malloc32.pSpy) {
EnterCriticalSection(&IMalloc32_SpyCS);
fSpyed = RemoveMemoryLocation(pv);
pv = IMallocSpy_PreFree(Malloc32.pSpy, pv, fSpyed);
}
HeapFree(GetProcessHeap(),0,pv); HeapFree(GetProcessHeap(),0,pv);
if(Malloc32.pSpy) {
IMallocSpy_PostFree(Malloc32.pSpy, fSpyed);
/* check if can release the spy */
if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
IMallocSpy_Release(Malloc32.pSpy);
Malloc32.SpyReleasePending = FALSE;
Malloc32.pSpy = NULL;
}
LeaveCriticalSection(&IMalloc32_SpyCS);
}
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_GetSize [VTABLE] * IMalloc32_GetSize [VTABLE]
*
* NOTES
* FIXME returns:
* win95: size allocated (4 byte boundarys)
* win2k: size originally requested !!! (allocated on 8 byte boundarys)
*/ */
static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) { static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
ICOM_CTHIS(IMalloc,iface);
TRACE("(%p)->GetSize(%p)\n",This,pv); DWORD cb;
return HeapSize(GetProcessHeap(),0,pv); BOOL fSpyed = 0;
TRACE("(%p)\n",pv);
if(Malloc32.pSpy) {
EnterCriticalSection(&IMalloc32_SpyCS);
pv = IMallocSpy_PreGetSize(Malloc32.pSpy, pv, fSpyed);
}
cb = HeapSize(GetProcessHeap(),0,pv);
if(Malloc32.pSpy) {
cb = IMallocSpy_PostGetSize(Malloc32.pSpy, cb, fSpyed);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
return cb;
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_DidAlloc [VTABLE] * IMalloc32_DidAlloc [VTABLE]
*/ */
static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) { static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
ICOM_CTHIS(IMalloc32Impl,iface);
TRACE("(%p)->DidAlloc(%p)\n",This,pv); BOOL fSpyed = 0;
return -1; int didAlloc;
TRACE("(%p)\n",pv);
if(Malloc32.pSpy) {
EnterCriticalSection(&IMalloc32_SpyCS);
pv = IMallocSpy_PreDidAlloc(Malloc32.pSpy, pv, fSpyed);
}
didAlloc = -1;
if(Malloc32.pSpy) {
didAlloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, pv, fSpyed, didAlloc);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
return didAlloc;
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_HeapMinimize [VTABLE] * IMalloc32_HeapMinimize [VTABLE]
*/ */
static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) { static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
ICOM_THIS(IMalloc32Impl,iface); TRACE("()\n");
TRACE("(%p)->HeapMinimize()\n",This);
if(Malloc32.pSpy) {
EnterCriticalSection(&IMalloc32_SpyCS);
IMallocSpy_PreHeapMinimize(Malloc32.pSpy);
}
if(Malloc32.pSpy) {
IMallocSpy_PostHeapMinimize(Malloc32.pSpy);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
} }
static ICOM_VTABLE(IMalloc) VT_IMalloc32 = static ICOM_VTABLE(IMalloc) VT_IMalloc32 =
{ {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IMalloc_fnQueryInterface, IMalloc_fnQueryInterface,
IMalloc_fnAddRef, IMalloc_fnAddRefRelease,
IMalloc_fnRelease, IMalloc_fnAddRefRelease,
IMalloc_fnAlloc, IMalloc_fnAlloc,
IMalloc_fnRealloc, IMalloc_fnRealloc,
IMalloc_fnFree, IMalloc_fnFree,
IMalloc_fnGetSize, IMalloc_fnGetSize,
IMalloc_fnDidAlloc, IMalloc_fnDidAlloc,
IMalloc_fnHeapMinimize IMalloc_fnHeapMinimize
}; };
/****************************************************************************** /******************************************************************************
* IMalloc32_Constructor [VTABLE] * IMallocSpy implementation
*/ *****************************************************************************/
LPMALLOC
IMalloc_Constructor() {
IMalloc32Impl* This;
This = (IMalloc32Impl*)HeapAlloc(GetProcessHeap(),0,sizeof(IMalloc32Impl)); /* set the vtable later */
ICOM_VTBL(This) = &VT_IMalloc32; extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
This->ref = 1;
return (LPMALLOC)This; typedef struct {
ICOM_VFIELD(IMallocSpy);
DWORD ref;
} _MallocSpy;
/* this is the static object instance */
_MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
/******************************************************************************
* IMalloc32_QueryInterface [VTABLE]
*/
static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
{
TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMallocSpy,refiid)) {
*obj = (LPMALLOC)&MallocSpy;
return S_OK;
}
return E_NOINTERFACE;
} }
/**************************************************************************** /******************************************************************************
* API Functions * IMalloc32_AddRef [VTABLE]
*/ */
static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(count=%lu)\n", This, This->ref);
return ++(This->ref);
}
/******************************************************************************
* IMalloc32_AddRelease [VTABLE]
*
* NOTES
* Our MallocSpy is static. If the count reaches 0 we dump the leaks
*/
static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(count=%lu)\n", This, This->ref);
if (!--(This->ref)) {
/* our allocation list MUST be empty here */
}
return This->ref;
}
static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%lu)\n", This, cbRequest);
return cbRequest;
}
static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p)\n", This, pActual);
return pActual;
}
static PVOID WINAPI IMallocSpy_fnPreFree(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
return pRequest;
}
static void WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%u)\n", This, fSpyed);
}
static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %lu %u)\n", This, pRequest, cbRequest, fSpyed);
*ppNewRequest = pRequest;
return cbRequest;
}
static PVOID WINAPI IMallocSpy_fnPostRealloc(LPMALLOCSPY iface, void* pActual, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %u)\n", This, pActual, fSpyed);
return pActual;
}
static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
return pRequest;
}
static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
return cbActual;
}
static PVOID WINAPI IMallocSpy_fnPreDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
return pRequest;
}
static int WINAPI IMallocSpy_fnPostDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed, int fActual)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->(%p %u %u)\n", This, pRequest, fSpyed, fActual);
return fActual;
}
static int WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->()\n", This);
return 0;
}
static int WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
{
ICOM_THIS (_MallocSpy, iface);
TRACE ("(%p)->()\n", This);
return 0;
}
static void MallocSpyDumpLeaks() {
TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
}
static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IMallocSpy_fnQueryInterface,
IMallocSpy_fnAddRef,
IMallocSpy_fnRelease,
IMallocSpy_fnPreAlloc,
IMallocSpy_fnPostAlloc,
IMallocSpy_fnPreFree,
IMallocSpy_fnPostFree,
IMallocSpy_fnPreRealloc,
IMallocSpy_fnPostRealloc,
IMallocSpy_fnPreGetSize,
IMallocSpy_fnPostGetSize,
IMallocSpy_fnPreDidAlloc,
IMallocSpy_fnPostDidAlloc,
IMallocSpy_fnPreHeapMinimize,
IMallocSpy_fnPostHeapMinimize
};
/******************************************************************************
* CoGetMalloc [OLE32.20]
*
* RETURNS
* The win32 IMalloc
*/
HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC *lpMalloc)
{
*lpMalloc = (LPMALLOC)&Malloc32;
return S_OK;
}
/***********************************************************************
* CoTaskMemAlloc [OLE32.43]
* RETURNS
* pointer to newly allocated block
*/
LPVOID WINAPI CoTaskMemAlloc(ULONG size)
{
return IMalloc_Alloc((LPMALLOC)&Malloc32,size);
}
/***********************************************************************
* CoTaskMemFree [OLE32.44]
*/
VOID WINAPI CoTaskMemFree(LPVOID ptr)
{
IMalloc_Free((LPMALLOC)&Malloc32, ptr);
}
/***********************************************************************
* CoTaskMemRealloc [OLE32.45]
* RETURNS
* pointer to newly allocated block
*/
LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, ULONG size)
{
return IMalloc_Realloc((LPMALLOC)&Malloc32, pvOld, size);
}
/***********************************************************************
* CoRegisterMallocSpy [OLE32.37]
*
* NOTES
* if a mallocspy is already registered, we cant do it again since
* only the spy knows, how to free a memory block
*/
HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
{
IMallocSpy* pSpy;
HRESULT hres = E_INVALIDARG;
TRACE("\n");
/* HACK TO ACTIVATE OUT SPY */
if (pMallocSpy == (LPVOID)-1) pMallocSpy =(IMallocSpy*)&MallocSpy;
if(Malloc32.pSpy) return CO_E_OBJISREG;
EnterCriticalSection(&IMalloc32_SpyCS);
if (SUCCEEDED(IUnknown_QueryInterface(pMallocSpy, &IID_IMallocSpy, (LPVOID*)&pSpy))) {
Malloc32.pSpy = pSpy;
hres = S_OK;
}
LeaveCriticalSection(&IMalloc32_SpyCS);
return hres;
}
/***********************************************************************
* CoRevokeMallocSpy [OLE32.41]
*
* NOTES
* we can't rewoke a malloc spy as long as memory blocks allocated with
* the spy are active since only the spy knows how to free them
*/
HRESULT WINAPI CoRevokeMallocSpy(void)
{
HRESULT hres = S_OK;
TRACE("\n");
EnterCriticalSection(&IMalloc32_SpyCS);
/* if it's our spy it's time to dump the leaks */
if (Malloc32.pSpy == (IMallocSpy*)&MallocSpy) {
MallocSpyDumpLeaks();
}
if (Malloc32.SpyedAllocationsLeft) {
TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
Malloc32.SpyReleasePending = TRUE;
hres = E_ACCESSDENIED;
} else {
IMallocSpy_Release(Malloc32.pSpy);
Malloc32.pSpy = NULL;
}
LeaveCriticalSection(&IMalloc32_SpyCS);
return S_OK;
}
/****************************************************************************** /******************************************************************************
* IsValidInterface [OLE32.78] * IsValidInterface [OLE32.78]

View File

@ -56,6 +56,5 @@ ICOM_DEFINE(IMalloc16,IUnknown)
/**********************************************************************/ /**********************************************************************/
extern LPMALLOC16 IMalloc16_Constructor(); extern LPMALLOC16 IMalloc16_Constructor();
extern LPMALLOC IMalloc_Constructor();
#endif /* __WINE_OLE_IFS_H */ #endif /* __WINE_OLE_IFS_H */

View File

@ -36,11 +36,11 @@ init OLE32_DllEntryPoint
34 stdcall CoMarshalInterface(ptr ptr ptr long ptr long) CoMarshalInterface 34 stdcall CoMarshalInterface(ptr ptr ptr long ptr long) CoMarshalInterface
35 stub CoQueryReleaseObject 35 stub CoQueryReleaseObject
36 stdcall CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject 36 stdcall CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject
37 stub CoRegisterMallocSpy # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED 37 stdcall CoRegisterMallocSpy (ptr) CoRegisterMallocSpy
38 stdcall CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter 38 stdcall CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter
39 stub CoReleaseMarshalData # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED 39 stub CoReleaseMarshalData # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
40 stdcall CoRevokeClassObject(long) CoRevokeClassObject 40 stdcall CoRevokeClassObject(long) CoRevokeClassObject
41 stub CoRevokeMallocSpy # stdcall () return 0,ERR_NOTIMPLEMENTED 41 stdcall CoRevokeMallocSpy() CoRevokeMallocSpy
42 stdcall CoSetState(ptr) CoSetState 42 stdcall CoSetState(ptr) CoSetState
43 stdcall CoTaskMemAlloc(long) CoTaskMemAlloc 43 stdcall CoTaskMemAlloc(long) CoTaskMemAlloc
44 stdcall CoTaskMemFree(ptr) CoTaskMemFree 44 stdcall CoTaskMemFree(ptr) CoTaskMemFree

View File

@ -22,6 +22,7 @@
#include "winerror.h" #include "winerror.h"
#include "ole32_main.h" #include "ole32_main.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/obj_misc.h" /* FIXME: CoRegisterMallocSpy */
WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -39,9 +40,11 @@ BOOL WINAPI OLE32_DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImp
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
OLE32_hInstance = hinstDLL; OLE32_hInstance = hinstDLL;
COMPOBJ_InitProcess(); COMPOBJ_InitProcess();
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
if (TRACE_ON(ole)) CoRevokeMallocSpy();
COMPOBJ_UninitProcess(); COMPOBJ_UninitProcess();
OLE32_hInstance = 0; OLE32_hInstance = 0;
break; break;

View File

@ -24,6 +24,8 @@
#ifndef __WINE_WINE_OBJ_MISC_H #ifndef __WINE_WINE_OBJ_MISC_H
#define __WINE_WINE_OBJ_MISC_H #define __WINE_WINE_OBJ_MISC_H
#include "wine/obj_base.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */
@ -103,7 +105,7 @@ ICOM_DEFINE(IEnumUnknown,IUnknown)
#define ICOM_INTERFACE IMallocSpy #define ICOM_INTERFACE IMallocSpy
#define IMallocSpy_METHODS \ #define IMallocSpy_METHODS \
ICOM_METHOD1 (ULONG,PreAlloc, ULONG,cbRequest) \ ICOM_METHOD1 (ULONG,PreAlloc, ULONG,cbRequest) \
ICOM_VMETHOD1( PostAlloc, void*,pActual) \ ICOM_METHOD1 (PVOID,PostAlloc, void*,pActual) \
ICOM_METHOD2 (PVOID,PreFree, void*,pRequest, BOOL,fSpyed) \ ICOM_METHOD2 (PVOID,PreFree, void*,pRequest, BOOL,fSpyed) \
ICOM_VMETHOD1( PostFree, BOOL,fSpyed) \ ICOM_VMETHOD1( PostFree, BOOL,fSpyed) \
ICOM_METHOD4 (ULONG,PreRealloc, void*,pRequest, ULONG,cbRequest, void**,ppNewRequest, BOOL,fSpyed) \ ICOM_METHOD4 (ULONG,PreRealloc, void*,pRequest, ULONG,cbRequest, void**,ppNewRequest, BOOL,fSpyed) \