Malloc spy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- implemented IMallocSpy hooks in IMalloc
- moved memory related functions into ifs.c
- implemented stubs for the MallocSpy

---
This is only the infrastructure, I'm going to implement a real spy next.
If you call CoRegisterMallocSpy with -1 then it registers the internal spy 
(different than in windows!!!).
This happends if TRACE_ON(ole) is true in DllMain()

juergen.
Index: wine/dlls/ole32/compobj.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj.c,v
retrieving revision 1.62
diff -d -u -r1.62 compobj.c
--- wine/dlls/ole32/compobj.c	25 Jul 2002 23:55:55 -0000	1.62
+++ wine/dlls/ole32/compobj.c	28 Jul 2002 19:43:50 -0000
@@ -126,9 +126,6 @@
 HINSTANCE       COMPOBJ_hInstance32 = 0;
 static int      COMPOBJ_Attach = 0;
 
-LPMALLOC16 currentMalloc16=NULL;
-LPMALLOC currentMalloc32=NULL;
-
 HTASK16 hETask = 0;
 WORD Table_ETask[62];
 
@@ -212,6 +209,35 @@
     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]
  * Set the win16 IMalloc used for memory management
@@ -367,49 +393,6 @@
   }
 }
 
-/***********************************************************************
- *           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	[OLE32.8]
@@ -1779,55 +1762,6 @@
 {
     GetSystemTimeAsFileTime( lpFileTime );
     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);
 }
 
 /***********************************************************************
Index: wine/dlls/ole32/ifs.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ifs.c,v
retrieving revision 1.21
diff -d -u -r1.21 ifs.c
--- wine/dlls/ole32/ifs.c	1 Jul 2002 18:10:34 -0000	1.21
+++ wine/dlls/ole32/ifs.c	28 Jul 2002 19:43:51 -0000
@@ -35,75 +35,7 @@
 
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(relay);
-
-/* --- 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;
-}
-
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
 /* --- IMalloc16 implementation */
 
@@ -245,57 +177,135 @@
 }
 
 
-/* --- 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
-{
-        /* IUnknown fields */
+typedef struct {
         ICOM_VFIELD(IMalloc);
-        DWORD                   ref;
-} IMalloc32Impl;
+        DWORD dummy;                /* nothing, we are static */
+	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) {
-	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) ||
-	    IsEqualIID(&IID_IMalloc,refiid)) {
-		*obj = This;
+	if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
+		*obj = (LPMALLOC)&Malloc32;
 		return S_OK;
 	}
 	return E_NOINTERFACE;
 }
 
 /******************************************************************************
- *		IMalloc32_AddRef	[VTABLE]
+ *	IMalloc32_AddRefRelease		[VTABLE]
  */
-static ULONG WINAPI IMalloc_fnAddRef(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->AddRef()\n",This);
-	return 1; /* cannot be freed */
+static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
+	return 1;
 }
 
 /******************************************************************************
- *		IMalloc32_Release	[VTABLE]
+ *	IMalloc32_Alloc 		[VTABLE]
  */
-static ULONG WINAPI IMalloc_fnRelease(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->Release()\n",This);
-	return 1; /* cannot be freed */
-}
+static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
 
-/******************************************************************************
- * IMalloc32_Alloc [VTABLE]
- */
-static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface,DWORD cb) {
 	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);
-	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;
 }
 
@@ -303,76 +313,431 @@
  * IMalloc32_Realloc [VTABLE]
  */
 static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->Realloc(%p,%ld)\n",This,pv,cb);
-	return HeapReAlloc(GetProcessHeap(),0,pv,cb);
+
+	LPVOID pNewMemory;
+
+	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]
  */
 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);
+
+	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]
+ *
+ * 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) {
-	ICOM_CTHIS(IMalloc,iface);
-	TRACE("(%p)->GetSize(%p)\n",This,pv);
-	return HeapSize(GetProcessHeap(),0,pv);
+
+	DWORD cb;
+	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]
  */
 static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
-	ICOM_CTHIS(IMalloc32Impl,iface);
-	TRACE("(%p)->DidAlloc(%p)\n",This,pv);
-	return -1;
+
+	BOOL fSpyed = 0;
+	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]
  */
 static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->HeapMinimize()\n",This);
+	TRACE("()\n");
+
+	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 =
 {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IMalloc_fnQueryInterface,
-    IMalloc_fnAddRef,
-  IMalloc_fnRelease,
-  IMalloc_fnAlloc,
-  IMalloc_fnRealloc,
-  IMalloc_fnFree,
-  IMalloc_fnGetSize,
-  IMalloc_fnDidAlloc,
-  IMalloc_fnHeapMinimize
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IMalloc_fnQueryInterface,
+	IMalloc_fnAddRefRelease,
+	IMalloc_fnAddRefRelease,
+	IMalloc_fnAlloc,
+	IMalloc_fnRealloc,
+	IMalloc_fnFree,
+	IMalloc_fnGetSize,
+	IMalloc_fnDidAlloc,
+	IMalloc_fnHeapMinimize
 };
 
 /******************************************************************************
- * IMalloc32_Constructor [VTABLE]
+ *	IMallocSpy implementation
+ *****************************************************************************/
+
+/* set the vtable later */
+extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
+
+typedef struct {
+        ICOM_VFIELD(IMallocSpy);
+        DWORD ref;
+} _MallocSpy;
+
+/* this is the static object instance */
+_MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
+
+/******************************************************************************
+ *	IMalloc32_QueryInterface	[VTABLE]
  */
-LPMALLOC
-IMalloc_Constructor() {
-	IMalloc32Impl* This;
+static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
+{
 
-	This = (IMalloc32Impl*)HeapAlloc(GetProcessHeap(),0,sizeof(IMalloc32Impl));
-	ICOM_VTBL(This) = &VT_IMalloc32;
-	This->ref = 1;
-	return (LPMALLOC)This;
+	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]
Index: wine/dlls/ole32/ifs.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ifs.h,v
retrieving revision 1.3
diff -d -u -r1.3 ifs.h
--- wine/dlls/ole32/ifs.h	9 Mar 2002 23:39:09 -0000	1.3
+++ wine/dlls/ole32/ifs.h	28 Jul 2002 19:43:51 -0000
@@ -56,6 +56,5 @@
 /**********************************************************************/
 
 extern LPMALLOC16 IMalloc16_Constructor();
-extern LPMALLOC IMalloc_Constructor();
 
 #endif /* __WINE_OLE_IFS_H */
Index: wine/dlls/ole32/ole32.spec
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole32.spec,v
retrieving revision 1.37
diff -d -u -r1.37 ole32.spec
--- wine/dlls/ole32/ole32.spec	19 Jul 2002 00:23:27 -0000	1.37
+++ wine/dlls/ole32/ole32.spec	28 Jul 2002 19:43:52 -0000
@@ -36,11 +36,11 @@
  34 stdcall CoMarshalInterface(ptr ptr ptr long ptr long) CoMarshalInterface
  35 stub CoQueryReleaseObject
  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
  39 stub CoReleaseMarshalData       # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
  40 stdcall CoRevokeClassObject(long) CoRevokeClassObject
- 41 stub CoRevokeMallocSpy          # stdcall () return 0,ERR_NOTIMPLEMENTED
+ 41 stdcall CoRevokeMallocSpy() CoRevokeMallocSpy
  42 stdcall CoSetState(ptr) CoSetState
  43 stdcall CoTaskMemAlloc(long) CoTaskMemAlloc
  44 stdcall CoTaskMemFree(ptr) CoTaskMemFree
Index: wine/dlls/ole32/ole32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/ole32_main.c,v
retrieving revision 1.7
diff -d -u -r1.7 ole32_main.c
--- wine/dlls/ole32/ole32_main.c	9 Mar 2002 23:39:09 -0000	1.7
+++ wine/dlls/ole32/ole32_main.c	28 Jul 2002 19:43:52 -0000
@@ -22,6 +22,7 @@
 #include "winerror.h"
 #include "ole32_main.h"
 #include "wine/debug.h"
+#include "wine/obj_misc.h" /* FIXME: CoRegisterMallocSpy */
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
@@ -39,9 +40,11 @@
     case DLL_PROCESS_ATTACH:
         OLE32_hInstance = hinstDLL;
         COMPOBJ_InitProcess();
+	if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
 	break;
 
     case DLL_PROCESS_DETACH:
+        if (TRACE_ON(ole)) CoRevokeMallocSpy();
         COMPOBJ_UninitProcess();
         OLE32_hInstance = 0;
 	break;
Index: wine/include/wine/obj_misc.h
===================================================================
RCS file: /home/wine/wine/include/wine/obj_misc.h,v
retrieving revision 1.13
diff -d -u -r1.13 obj_misc.h
--- wine/include/wine/obj_misc.h	31 May 2002 23:06:50 -0000	1.13
+++ wine/include/wine/obj_misc.h	28 Jul 2002 19:44:52 -0000
@@ -24,6 +24,8 @@
 #ifndef __WINE_WINE_OBJ_MISC_H
 #define __WINE_WINE_OBJ_MISC_H
 
+#include "wine/obj_base.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* defined(__cplusplus) */
@@ -103,7 +105,7 @@
 #define ICOM_INTERFACE IMallocSpy
 #define IMallocSpy_METHODS \
     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_VMETHOD1(      PostFree,        BOOL,fSpyed) \
     ICOM_METHOD4 (ULONG,PreRealloc,      void*,pRequest, ULONG,cbRequest, void**,ppNewRequest, BOOL,fSpyed) \

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux