[PATCH 4/5] combase: Move IMalloc/IMallocSpy functionality.

Nikolay Sivov nsivov at codeweavers.com
Tue Aug 4 03:17:15 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/combase/Makefile.in  |   1 +
 dlls/combase/combase.c    | 457 +++++++++++++++++++++++++++++++++
 dlls/combase/combase.spec |  12 +-
 dlls/ole32/ifs.c          | 515 --------------------------------------
 dlls/ole32/ole32.spec     |  12 +-
 5 files changed, 470 insertions(+), 527 deletions(-)
 create mode 100644 dlls/combase/combase.c

diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in
index 83c71ce9493..7f7371f175a 100644
--- a/dlls/combase/Makefile.in
+++ b/dlls/combase/Makefile.in
@@ -6,6 +6,7 @@ DELAYIMPORTS = oleaut32
 EXTRADLLFLAGS = -mno-cygwin
 
 C_SRCS = \
+	combase.c \
 	errorinfo.c \
 	roapi.c \
 	string.c \
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c
new file mode 100644
index 00000000000..8d0f70c513c
--- /dev/null
+++ b/dlls/combase/combase.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright 1997 Marcus Meissner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "oleauto.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DECLARE_DEBUG_CHANNEL(olemalloc);
+
+static const IMallocVtbl allocator_vtbl;
+
+struct allocator
+{
+    IMalloc IMalloc_iface;
+    IMallocSpy *spy;
+    DWORD spyed_allocations;
+    BOOL spy_release_pending; /* CoRevokeMallocSpy called with spyed allocations left */
+    void **blocks;
+    DWORD blocks_length;
+};
+
+static struct allocator allocator = { .IMalloc_iface.lpVtbl = &allocator_vtbl };
+
+static CRITICAL_SECTION allocspy_cs;
+static CRITICAL_SECTION_DEBUG allocspy_cs_debug =
+{
+    0, 0, &allocspy_cs,
+    { &allocspy_cs_debug.ProcessLocksList, &allocspy_cs_debug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": allocspy_cs") }
+};
+static CRITICAL_SECTION allocspy_cs = { &allocspy_cs_debug, -1, 0, 0, 0, 0 };
+
+static BOOL mallocspy_grow(DWORD length)
+{
+    void **blocks;
+
+    if (!allocator.blocks) blocks = LocalAlloc(LMEM_ZEROINIT, length * sizeof(void *));
+    else blocks = LocalReAlloc(allocator.blocks, length * sizeof(void *), LMEM_ZEROINIT | LMEM_MOVEABLE);
+    if (blocks)
+    {
+        allocator.blocks = blocks;
+        allocator.blocks_length = length;
+    }
+
+    return blocks != NULL;
+}
+
+static void mallocspy_add_mem(void *mem)
+{
+    void **current;
+
+    if (!mem || (!allocator.blocks_length && !mallocspy_grow(0x1000)))
+        return;
+
+    /* Find a free location */
+    current = allocator.blocks;
+    while (*current)
+    {
+        current++;
+        if (current >= allocator.blocks + allocator.blocks_length)
+        {
+            DWORD old_length = allocator.blocks_length;
+            if (!mallocspy_grow(allocator.blocks_length + 0x1000))
+                return;
+            current = allocator.blocks + old_length;
+        }
+    }
+
+    *current = mem;
+    allocator.spyed_allocations++;
+}
+
+static void** mallocspy_is_allocation_spyed(const void *mem)
+{
+    void **current = allocator.blocks;
+
+    while (*current != mem)
+    {
+        current++;
+        if (current >= allocator.blocks + allocator.blocks_length)
+            return NULL;
+    }
+
+    return current;
+}
+
+static BOOL mallocspy_remove_spyed_memory(const void *mem)
+{
+    void **current;
+
+    if (!allocator.blocks_length)
+        return FALSE;
+
+    if (!(current = mallocspy_is_allocation_spyed(mem)))
+        return FALSE;
+
+    allocator.spyed_allocations--;
+    *current = NULL;
+    return TRUE;
+}
+
+static HRESULT WINAPI allocator_QueryInterface(IMalloc *iface, REFIID riid, void **obj)
+{
+    TRACE_(olemalloc)("%s, %p.\n", debugstr_guid(riid), obj);
+
+    if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMalloc, riid))
+    {
+        *obj = &allocator.IMalloc_iface;
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI allocator_AddRef(IMalloc *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI allocator_Release(IMalloc *iface)
+{
+    return 1;
+}
+
+static void * WINAPI allocator_Alloc(IMalloc *iface, SIZE_T cb)
+{
+    void *addr;
+
+    TRACE_(olemalloc)("%ld.\n", cb);
+
+    if (allocator.spy)
+    {
+        SIZE_T preAllocResult;
+
+        EnterCriticalSection(&allocspy_cs);
+        preAllocResult = IMallocSpy_PreAlloc(allocator.spy, cb);
+        if (cb && !preAllocResult)
+        {
+            /* PreAlloc can force Alloc to fail, but not if cb == 0 */
+            TRACE("returning null\n");
+            LeaveCriticalSection(&allocspy_cs);
+            return NULL;
+        }
+    }
+
+    addr = HeapAlloc(GetProcessHeap(), 0, cb);
+
+    if (allocator.spy)
+    {
+        addr = IMallocSpy_PostAlloc(allocator.spy, addr);
+        mallocspy_add_mem(addr);
+        LeaveCriticalSection(&allocspy_cs);
+    }
+
+    TRACE_(olemalloc)("%p.\n",addr);
+    return addr;
+}
+
+static void * WINAPI allocator_Realloc(IMalloc *iface, void *pv, SIZE_T cb)
+{
+    void *addr;
+
+    TRACE_(olemalloc)("%p, %ld.\n",pv,cb);
+
+    if (allocator.spy)
+    {
+        void *real_mem;
+        BOOL spyed;
+
+        EnterCriticalSection(&allocspy_cs);
+        spyed = mallocspy_remove_spyed_memory(pv);
+        cb = IMallocSpy_PreRealloc(allocator.spy, pv, cb, &real_mem, spyed);
+
+        /* check if can release the spy */
+        if (allocator.spy_release_pending && !allocator.spyed_allocations)
+        {
+            IMallocSpy_Release(allocator.spy);
+            allocator.spy_release_pending = FALSE;
+            allocator.spy = NULL;
+            LeaveCriticalSection(&allocspy_cs);
+        }
+
+        if (!cb)
+        {
+            /* PreRealloc can force Realloc to fail */
+            if (allocator.spy)
+                LeaveCriticalSection(&allocspy_cs);
+            return NULL;
+        }
+
+        pv = real_mem;
+    }
+
+    if (!pv) addr = HeapAlloc(GetProcessHeap(), 0, cb);
+    else if (cb) addr = HeapReAlloc(GetProcessHeap(), 0, pv, cb);
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, pv);
+        addr = NULL;
+    }
+
+    if (allocator.spy)
+    {
+        addr = IMallocSpy_PostRealloc(allocator.spy, addr, TRUE);
+        mallocspy_add_mem(addr);
+        LeaveCriticalSection(&allocspy_cs);
+    }
+
+    TRACE_(olemalloc)("%p.\n", addr);
+    return addr;
+}
+
+static void WINAPI allocator_Free(IMalloc *iface, void *mem)
+{
+    BOOL spyed_block = FALSE, spy_active = FALSE;
+
+    TRACE_(olemalloc)("%p.\n", mem);
+
+    if (!mem)
+        return;
+
+    if (allocator.spy)
+    {
+        EnterCriticalSection(&allocspy_cs);
+        spyed_block = mallocspy_remove_spyed_memory(mem);
+        spy_active = TRUE;
+        mem = IMallocSpy_PreFree(allocator.spy, mem, spyed_block);
+    }
+
+    HeapFree(GetProcessHeap(), 0, mem);
+
+    if (spy_active)
+    {
+        IMallocSpy_PostFree(allocator.spy, spyed_block);
+
+        /* check if can release the spy */
+        if (allocator.spy_release_pending && !allocator.spyed_allocations)
+        {
+            IMallocSpy_Release(allocator.spy);
+            allocator.spy_release_pending = FALSE;
+            allocator.spy = NULL;
+        }
+
+        LeaveCriticalSection(&allocspy_cs);
+    }
+}
+
+/******************************************************************************
+ * NOTES
+ *  FIXME returns:
+ *      win95:  size allocated (4 byte boundaries)
+ *      win2k:  size originally requested !!! (allocated on 8 byte boundaries)
+ */
+static SIZE_T WINAPI allocator_GetSize(IMalloc *iface, void *mem)
+{
+    BOOL spyed_block = FALSE, spy_active = FALSE;
+    SIZE_T size;
+
+    TRACE_(olemalloc)("%p.\n", mem);
+
+    if (!mem)
+        return (SIZE_T)-1;
+
+    if (allocator.spy)
+    {
+        EnterCriticalSection(&allocspy_cs);
+        spyed_block = !!mallocspy_is_allocation_spyed(mem);
+        spy_active = TRUE;
+        mem = IMallocSpy_PreGetSize(allocator.spy, mem, spyed_block);
+    }
+
+    size = HeapSize(GetProcessHeap(), 0, mem);
+
+    if (spy_active)
+    {
+        size = IMallocSpy_PostGetSize(allocator.spy, size, spyed_block);
+        LeaveCriticalSection(&allocspy_cs);
+    }
+
+    return size;
+}
+
+static INT WINAPI allocator_DidAlloc(IMalloc *iface, void *mem)
+{
+    BOOL spyed_block = FALSE, spy_active = FALSE;
+    int did_alloc;
+
+    TRACE_(olemalloc)("%p.\n", mem);
+
+    if (!mem)
+        return -1;
+
+    if (allocator.spy)
+    {
+        EnterCriticalSection(&allocspy_cs);
+        spyed_block = !!mallocspy_is_allocation_spyed(mem);
+        spy_active = TRUE;
+        mem = IMallocSpy_PreDidAlloc(allocator.spy, mem, spyed_block);
+    }
+
+    did_alloc = HeapValidate(GetProcessHeap(), 0, mem);
+
+    if (spy_active)
+    {
+        did_alloc = IMallocSpy_PostDidAlloc(allocator.spy, mem, spyed_block, did_alloc);
+        LeaveCriticalSection(&allocspy_cs);
+    }
+
+    return did_alloc;
+}
+
+static void WINAPI allocator_HeapMinimize(IMalloc *iface)
+{
+    BOOL spy_active = FALSE;
+
+    TRACE_(olemalloc)("\n");
+
+    if (allocator.spy)
+    {
+        EnterCriticalSection(&allocspy_cs);
+        spy_active = TRUE;
+        IMallocSpy_PreHeapMinimize(allocator.spy);
+    }
+
+    if (spy_active)
+    {
+        IMallocSpy_PostHeapMinimize(allocator.spy);
+        LeaveCriticalSection(&allocspy_cs);
+    }
+}
+
+static const IMallocVtbl allocator_vtbl =
+{
+    allocator_QueryInterface,
+    allocator_AddRef,
+    allocator_Release,
+    allocator_Alloc,
+    allocator_Realloc,
+    allocator_Free,
+    allocator_GetSize,
+    allocator_DidAlloc,
+    allocator_HeapMinimize
+};
+
+/******************************************************************************
+ *                CoGetMalloc        (combase.@)
+ */
+HRESULT WINAPI CoGetMalloc(DWORD context, IMalloc **imalloc)
+{
+    if (context != MEMCTX_TASK)
+    {
+        *imalloc = NULL;
+        return E_INVALIDARG;
+    }
+
+    *imalloc = &allocator.IMalloc_iface;
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *           CoTaskMemAlloc         (combase.@)
+ */
+void * WINAPI CoTaskMemAlloc(SIZE_T size)
+{
+    return IMalloc_Alloc(&allocator.IMalloc_iface, size);
+}
+
+/***********************************************************************
+ *           CoTaskMemFree          (combase.@)
+ */
+void WINAPI CoTaskMemFree(void *ptr)
+{
+    IMalloc_Free(&allocator.IMalloc_iface, ptr);
+}
+
+/***********************************************************************
+ *           CoTaskMemRealloc        (combase.@)
+ */
+void * WINAPI CoTaskMemRealloc(void *ptr, SIZE_T size)
+{
+    return IMalloc_Realloc(&allocator.IMalloc_iface, ptr, size);
+}
+
+/***********************************************************************
+ *           CoRegisterMallocSpy        (combase.@)
+ */
+HRESULT WINAPI CoRegisterMallocSpy(IMallocSpy *spy)
+{
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE("%p.\n", spy);
+
+    if (!spy) return E_INVALIDARG;
+
+    EnterCriticalSection(&allocspy_cs);
+
+    if (allocator.spy)
+        hr = CO_E_OBJISREG;
+    else if (SUCCEEDED(IMallocSpy_QueryInterface(spy, &IID_IMallocSpy, (void **)&spy)))
+    {
+        allocator.spy = spy;
+        hr = S_OK;
+    }
+
+    LeaveCriticalSection(&allocspy_cs);
+
+    return hr;
+}
+
+/***********************************************************************
+ *           CoRevokeMallocSpy (combase.@)
+ */
+HRESULT WINAPI CoRevokeMallocSpy(void)
+{
+    HRESULT hr = S_OK;
+
+    TRACE("\n");
+
+    EnterCriticalSection(&allocspy_cs);
+
+    if (!allocator.spy)
+        hr = CO_E_OBJNOTREG;
+    else if (allocator.spyed_allocations)
+    {
+        allocator.spy_release_pending = TRUE;
+        hr = E_ACCESSDENIED;
+    }
+    else
+    {
+        IMallocSpy_Release(allocator.spy);
+        allocator.spy = NULL;
+    }
+
+    LeaveCriticalSection(&allocspy_cs);
+
+    return hr;
+}
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index cb073ef2fcc..aa1c04ce0ac 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -109,7 +109,7 @@
 @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) ole32.CoGetInstanceFromFile
 @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) ole32.CoGetInstanceFromIStorage
 @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) ole32.CoGetInterfaceAndReleaseStream
-@ stdcall CoGetMalloc(long ptr) ole32.CoGetMalloc
+@ stdcall CoGetMalloc(long ptr)
 @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) ole32.CoGetMarshalSizeMax
 @ stub CoGetModuleType
 @ stdcall CoGetObjectContext(ptr ptr) ole32.CoGetObjectContext
@@ -139,7 +139,7 @@
 @ stub CoRegisterActivationFilter
 @ stdcall CoRegisterClassObject(ptr ptr long long ptr) ole32.CoRegisterClassObject
 @ stdcall CoRegisterInitializeSpy(ptr ptr) ole32.CoRegisterInitializeSpy
-@ stdcall CoRegisterMallocSpy(ptr) ole32.CoRegisterMallocSpy
+@ stdcall CoRegisterMallocSpy(ptr)
 @ stdcall CoRegisterMessageFilter(ptr ptr) ole32.CoRegisterMessageFilter
 @ stdcall CoRegisterPSClsid(ptr ptr) ole32.CoRegisterPSClsid
 @ stdcall CoRegisterSurrogate(ptr) ole32.CoRegisterSurrogate
@@ -151,15 +151,15 @@
 @ stdcall CoRevertToSelf() ole32.CoRevertToSelf
 @ stdcall CoRevokeClassObject(long) ole32.CoRevokeClassObject
 @ stdcall CoRevokeInitializeSpy(int64) ole32.CoRevokeInitializeSpy
-@ stdcall CoRevokeMallocSpy() ole32.CoRevokeMallocSpy
+@ stdcall CoRevokeMallocSpy()
 @ stub CoSetCancelObject
 @ stub CoSetErrorInfo
 @ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) ole32.CoSetProxyBlanket
 @ stdcall CoSuspendClassObjects() ole32.CoSuspendClassObjects
 @ stdcall CoSwitchCallContext(ptr ptr) ole32.CoSwitchCallContext
-@ stdcall CoTaskMemAlloc(long) ole32.CoTaskMemAlloc
-@ stdcall CoTaskMemFree(ptr) ole32.CoTaskMemFree
-@ stdcall CoTaskMemRealloc(ptr long) ole32.CoTaskMemRealloc
+@ stdcall CoTaskMemAlloc(long)
+@ stdcall CoTaskMemFree(ptr)
+@ stdcall CoTaskMemRealloc(ptr long)
 @ stub CoTestCancel
 @ stdcall CoUninitialize() ole32.CoUninitialize
 @ stub CoUnloadingWOW
diff --git a/dlls/ole32/ifs.c b/dlls/ole32/ifs.c
index a144833c7af..845bdeea4a5 100644
--- a/dlls/ole32/ifs.c
+++ b/dlls/ole32/ifs.c
@@ -32,521 +32,6 @@
 #include "ole2.h"
 #include "winerror.h"
 
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(olemalloc);
-
-/******************************************************************************
- *	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 */
-static const IMallocVtbl VT_IMalloc32;
-
-struct allocator
-{
-        IMalloc IMalloc_iface;
-	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 */
-        DWORD SpyedBlockTableLength;/* size of the table*/
-};
-
-static struct allocator Malloc32 = { .IMalloc_iface.lpVtbl = &VT_IMalloc32 };
-
-/* with a spy active all calls from pre to post methods are threadsafe */
-static CRITICAL_SECTION IMalloc32_SpyCS;
-static CRITICAL_SECTION_DEBUG critsect_debug =
-{
-    0, 0, &IMalloc32_SpyCS,
-    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { (DWORD_PTR)(__FILE__ ": IMalloc32_SpyCS") }
-};
-static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
-
-/* resize the old table */
-static BOOL SetSpyedBlockTableLength ( DWORD NewLength )
-{
-	LPVOID *NewSpyedBlocks;
-
-	if (!Malloc32.SpyedBlocks) NewSpyedBlocks = LocalAlloc(LMEM_ZEROINIT, NewLength * sizeof(PVOID));
-	else NewSpyedBlocks = LocalReAlloc(Malloc32.SpyedBlocks, NewLength * sizeof(PVOID), LMEM_ZEROINIT | LMEM_MOVEABLE);
-	if (NewSpyedBlocks) {
-		Malloc32.SpyedBlocks = NewSpyedBlocks;
-		Malloc32.SpyedBlockTableLength = NewLength;
-	}
-
-	return NewSpyedBlocks != NULL;
-}
-
-/* add a location to the table */
-static BOOL AddMemoryLocation(LPVOID * pMem)
-{
-        LPVOID * Current;
-
-	/* allocate the table if not already allocated */
-        if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000))
-            return FALSE;
-
-	/* find a free location */
-	Current = Malloc32.SpyedBlocks;
-	while (*Current) {
-            Current++;
-	    if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
-	        /* no more space in table, grow it */
-                DWORD old_length = Malloc32.SpyedBlockTableLength;
-                if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000))
-                    return FALSE;
-                Current = Malloc32.SpyedBlocks + old_length;
-	    }
-	};
-
-	/* put the location in our table */
-	*Current = pMem;
-        Malloc32.SpyedAllocationsLeft++;
-	/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
-        return TRUE;
-}
-
-static void** mallocspy_is_allocation_spyed(const void *mem)
-{
-    void **current = Malloc32.SpyedBlocks;
-
-    while (*current != mem)
-    {
-        current++;
-        if (current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength)
-            return NULL;
-    }
-
-    return current;
-}
-
-static BOOL mallocspy_remove_spyed_memory(const void *mem)
-{
-    void **current;
-
-    if (!Malloc32.SpyedBlockTableLength)
-        return FALSE;
-
-    if (!(current = mallocspy_is_allocation_spyed(mem)))
-        return FALSE;
-
-    Malloc32.SpyedAllocationsLeft--;
-    *current = NULL;
-    return TRUE;
-}
-
-/******************************************************************************
- *	IMalloc32_QueryInterface	[VTABLE]
- */
-static HRESULT WINAPI IMalloc_fnQueryInterface(IMalloc *iface, REFIID refiid, void **obj)
-{
-	TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
-
-	if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
-		*obj = &Malloc32;
-		return S_OK;
-	}
-	return E_NOINTERFACE;
-}
-
-/******************************************************************************
- *	IMalloc32_AddRefRelease		[VTABLE]
- */
-static ULONG WINAPI IMalloc_fnAddRefRelease(IMalloc *iface)
-{
-	return 1;
-}
-
-/******************************************************************************
- *	IMalloc32_Alloc 		[VTABLE]
- */
-static void * WINAPI IMalloc_fnAlloc(IMalloc *iface, SIZE_T cb)
-{
-	void *addr;
-
-	TRACE("(%ld)\n",cb);
-
-	if(Malloc32.pSpy) {
-	    SIZE_T preAllocResult;
-	    
-	    EnterCriticalSection(&IMalloc32_SpyCS);
-	    preAllocResult = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
-	    if ((cb != 0) && (preAllocResult == 0)) {
-		/* PreAlloc can force Alloc to fail, but not if cb == 0 */
-		TRACE("returning null\n");
-		LeaveCriticalSection(&IMalloc32_SpyCS);
-		return NULL;
-	    }
-	}
- 	
-	addr = HeapAlloc(GetProcessHeap(),0,cb);
-
-	if(Malloc32.pSpy) {
-	    addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr);
-	    if (addr) AddMemoryLocation(addr);
-	    LeaveCriticalSection(&IMalloc32_SpyCS);
-	}
-
-	TRACE("--(%p)\n",addr);
-	return addr;
-}
-
-/******************************************************************************
- * IMalloc32_Realloc [VTABLE]
- */
-static void * WINAPI IMalloc_fnRealloc(IMalloc *iface, void *pv, SIZE_T cb)
-{
-	void *pNewMemory;
-
-	TRACE("(%p,%ld)\n",pv,cb);
-
-	if(Malloc32.pSpy) {
-	    void *pRealMemory;
-	    BOOL fSpyed;
-
-	    EnterCriticalSection(&IMalloc32_SpyCS);
-            fSpyed = mallocspy_remove_spyed_memory(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;
-		LeaveCriticalSection(&IMalloc32_SpyCS);
-	    }
-
-	    if (0==cb) {
-		/* PreRealloc can force Realloc to fail */
-		if (Malloc32.pSpy)
-		    LeaveCriticalSection(&IMalloc32_SpyCS);
-		return NULL;
-	    }
-
-	    pv = pRealMemory;
-	}
-
-        if (!pv) pNewMemory = HeapAlloc(GetProcessHeap(),0,cb);
-	else if (cb) pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb);
-	else {
-	    HeapFree(GetProcessHeap(),0,pv);
-	    pNewMemory = NULL;
-	}
-
-	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(IMalloc *iface, void *mem)
-{
-    BOOL spyed_block = FALSE, spy_active = FALSE;
-
-    TRACE("(%p)\n", mem);
-
-    if (!mem)
-        return;
-
-    if (Malloc32.pSpy)
-    {
-        EnterCriticalSection(&IMalloc32_SpyCS);
-        spyed_block = mallocspy_remove_spyed_memory(mem);
-        spy_active = TRUE;
-        mem = IMallocSpy_PreFree(Malloc32.pSpy, mem, spyed_block);
-    }
-
-    HeapFree(GetProcessHeap(), 0, mem);
-
-    if (spy_active)
-    {
-        IMallocSpy_PostFree(Malloc32.pSpy, spyed_block);
-
-        /* 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 boundaries)
- *      win2k:  size originally requested !!! (allocated on 8 byte boundaries)
- */
-static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *mem)
-{
-    BOOL spyed_block = FALSE, spy_active = FALSE;
-    SIZE_T size;
-
-    TRACE("(%p)\n", mem);
-
-    if (!mem)
-        return (SIZE_T)-1;
-
-    if (Malloc32.pSpy)
-    {
-        EnterCriticalSection(&IMalloc32_SpyCS);
-        spyed_block = !!mallocspy_is_allocation_spyed(mem);
-        spy_active = TRUE;
-        mem = IMallocSpy_PreGetSize(Malloc32.pSpy, mem, spyed_block);
-    }
-
-    size = HeapSize(GetProcessHeap(), 0, mem);
-
-    if (spy_active)
-    {
-        size = IMallocSpy_PostGetSize(Malloc32.pSpy, size, spyed_block);
-        LeaveCriticalSection(&IMalloc32_SpyCS);
-    }
-
-    return size;
-}
-
-/******************************************************************************
- * IMalloc32_DidAlloc [VTABLE]
- */
-static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *mem)
-{
-    BOOL spyed_block = FALSE, spy_active = FALSE;
-    int did_alloc;
-
-    TRACE("(%p)\n", mem);
-
-    if (!mem)
-        return -1;
-
-    if (Malloc32.pSpy)
-    {
-        EnterCriticalSection(&IMalloc32_SpyCS);
-        spyed_block = !!mallocspy_is_allocation_spyed(mem);
-        spy_active = TRUE;
-        mem = IMallocSpy_PreDidAlloc(Malloc32.pSpy, mem, spyed_block);
-    }
-
-    did_alloc = HeapValidate(GetProcessHeap(), 0, mem);
-
-    if (spy_active)
-    {
-        did_alloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, mem, spyed_block, did_alloc);
-        LeaveCriticalSection(&IMalloc32_SpyCS);
-    }
-
-    return did_alloc;
-}
-
-/******************************************************************************
- * IMalloc32_HeapMinimize [VTABLE]
- */
-static void WINAPI IMalloc_fnHeapMinimize(IMalloc *iface)
-{
-    BOOL spy_active = FALSE;
-
-    TRACE("()\n");
-
-    if (Malloc32.pSpy)
-    {
-        EnterCriticalSection(&IMalloc32_SpyCS);
-        spy_active = TRUE;
-        IMallocSpy_PreHeapMinimize(Malloc32.pSpy);
-    }
-
-    if (spy_active)
-    {
-        IMallocSpy_PostHeapMinimize(Malloc32.pSpy);
-        LeaveCriticalSection(&IMalloc32_SpyCS);
-    }
-}
-
-static const IMallocVtbl VT_IMalloc32 =
-{
-	IMalloc_fnQueryInterface,
-	IMalloc_fnAddRefRelease,
-	IMalloc_fnAddRefRelease,
-	IMalloc_fnAlloc,
-	IMalloc_fnRealloc,
-	IMalloc_fnFree,
-	IMalloc_fnGetSize,
-	IMalloc_fnDidAlloc,
-	IMalloc_fnHeapMinimize
-};
-
-/******************************************************************************
- *		CoGetMalloc	[OLE32.@]
- *
- * Retrieves the current IMalloc interface for the process.
- *
- * PARAMS
- *  context [I] Should always be MEMCTX_TASK.
- *  imalloc [O] Address where memory allocator object will be stored.
- *
- * RETURNS
- *	Success: S_OK.
- *  Failure: HRESULT code.
- */
-HRESULT WINAPI CoGetMalloc(DWORD context, IMalloc **imalloc)
-{
-    if (context != MEMCTX_TASK) {
-        *imalloc = NULL;
-        return E_INVALIDARG;
-    }
-
-    *imalloc = &Malloc32.IMalloc_iface;
-    return S_OK;
-}
-
-/***********************************************************************
- *           CoTaskMemAlloc     [OLE32.@]
- *
- * Allocates memory using the current process memory allocator.
- *
- * PARAMS
- *  size [I] Size of the memory block to allocate.
- *
- * RETURNS
- * 	Success: Pointer to newly allocated memory block.
- *  Failure: NULL.
- */
-LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
-{
-        return IMalloc_Alloc(&Malloc32.IMalloc_iface,size);
-}
-
-/***********************************************************************
- *           CoTaskMemFree      [OLE32.@]
- *
- * Frees memory allocated from the current process memory allocator.
- *
- * PARAMS
- *  ptr [I] Memory block to free.
- *
- * RETURNS
- *  Nothing.
- */
-VOID WINAPI CoTaskMemFree(LPVOID ptr)
-{
-        IMalloc_Free(&Malloc32.IMalloc_iface, ptr);
-}
-
-/***********************************************************************
- *           CoTaskMemRealloc   [OLE32.@]
- *
- * Allocates memory using the current process memory allocator.
- *
- * PARAMS
- *  pvOld [I] Pointer to old memory block.
- *  size  [I] Size of the new memory block.
- *
- * RETURNS
- * 	Success: Pointer to newly allocated memory block.
- *  Failure: NULL.
- */
-LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, SIZE_T size)
-{
-        return IMalloc_Realloc(&Malloc32.IMalloc_iface, pvOld, size);
-}
-
-/***********************************************************************
- *           CoRegisterMallocSpy        [OLE32.@]
- *
- * Registers an object that receives notifications on memory allocations and
- * frees.
- *
- * PARAMS
- *  pMallocSpy [I] New spy object.
- *
- * RETURNS
- *  Success: S_OK.
- *  Failure: HRESULT code.
- *
- * NOTES
- *  if a mallocspy is already registered, we can't 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("%p\n", pMallocSpy);
-
-	if(!pMallocSpy) return E_INVALIDARG;
-
-        EnterCriticalSection(&IMalloc32_SpyCS);
-
-	if (Malloc32.pSpy)
-	    hres = CO_E_OBJISREG;
-	else if (SUCCEEDED(IMallocSpy_QueryInterface(pMallocSpy, &IID_IMallocSpy, (void**)&pSpy))) {
-	    Malloc32.pSpy = pSpy;
-	    hres = S_OK;
-	}
-
-	LeaveCriticalSection(&IMalloc32_SpyCS);
-
-	return hres;
-}
-
-/***********************************************************************
- *           CoRevokeMallocSpy  [OLE32.@]
- *
- * Revokes a previously registered object that receives notifications on memory
- * allocations and frees.
- *
- * PARAMS
- *  pMallocSpy [I] New spy object.
- *
- * RETURNS
- *  Success: S_OK.
- *  Failure: HRESULT code.
- *
- * NOTES
- *  we can't revoke 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 (!Malloc32.pSpy)
-	    hres = CO_E_OBJNOTREG;
-	else if (Malloc32.SpyedAllocationsLeft) {
-            TRACE("SpyReleasePending with %u allocations left\n", Malloc32.SpyedAllocationsLeft);
-	    Malloc32.SpyReleasePending = TRUE;
-	    hres = E_ACCESSDENIED;
-	} else {
-	    IMallocSpy_Release(Malloc32.pSpy);
-	    Malloc32.pSpy = NULL;
-        }
-	LeaveCriticalSection(&IMalloc32_SpyCS);
-
-	return hres;
-}
-
 /******************************************************************************
  *		IsValidInterface	[OLE32.@]
  *
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index 927a98ea123..78e8641cf36 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -38,7 +38,7 @@
 @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr)
 @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr)
 @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
-@ stdcall CoGetMalloc(long ptr)
+@ stdcall CoGetMalloc(long ptr) combase.CoGetMalloc
 @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
 @ stdcall CoGetObject(wstr ptr ptr ptr)
 @ stdcall CoGetObjectContext(ptr ptr)
@@ -67,7 +67,7 @@
 @ stdcall CoRegisterChannelHook(ptr ptr)
 @ stdcall CoRegisterClassObject(ptr ptr long long ptr)
 @ stdcall CoRegisterInitializeSpy(ptr ptr)
-@ stdcall CoRegisterMallocSpy (ptr)
+@ stdcall CoRegisterMallocSpy(ptr) combase.CoRegisterMallocSpy
 @ stdcall CoRegisterMessageFilter(ptr ptr)
 @ stdcall CoRegisterPSClsid(ptr ptr)
 @ stdcall CoRegisterSurrogate(ptr)
@@ -78,14 +78,14 @@
 @ stdcall CoRevertToSelf()
 @ stdcall CoRevokeClassObject(long)
 @ stdcall CoRevokeInitializeSpy(int64)
-@ stdcall CoRevokeMallocSpy()
+@ stdcall CoRevokeMallocSpy() combase.CoRevokeMallocSpy
 @ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long)
 @ stdcall CoSetState(ptr)
 @ stdcall CoSuspendClassObjects()
 @ stdcall CoSwitchCallContext(ptr ptr)
-@ stdcall CoTaskMemAlloc(long)
-@ stdcall CoTaskMemFree(ptr)
-@ stdcall CoTaskMemRealloc(ptr long)
+@ stdcall CoTaskMemAlloc(long) combase.CoTaskMemAlloc
+@ stdcall CoTaskMemFree(ptr) combase.CoTaskMemFree
+@ stdcall CoTaskMemRealloc(ptr long) combase.CoTaskMemRealloc
 @ stdcall CoTreatAsClass(ptr ptr)
 @ stdcall CoUninitialize()
 @ stub CoUnloadingWOW
-- 
2.27.0




More information about the wine-devel mailing list