diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in index 83c71ce9493..f2174f4e3eb 100644 --- a/dlls/combase/Makefile.in +++ b/dlls/combase/Makefile.in @@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin C_SRCS = \ errorinfo.c \ + malloc.c \ roapi.c \ string.c \ usrmarshal.c 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/combase/malloc.c b/dlls/combase/malloc.c new file mode 100644 index 00000000000..2be03ae1e31 --- /dev/null +++ b/dlls/combase/malloc.c @@ -0,0 +1,456 @@ +/* + * 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(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("%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("%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("%p.\n",addr); + return addr; +} + +static void * WINAPI allocator_Realloc(IMalloc *iface, void *pv, SIZE_T cb) +{ + void *addr; + + TRACE("%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("%p.\n", addr); + return addr; +} + +static void WINAPI allocator_Free(IMalloc *iface, void *mem) +{ + BOOL spyed_block = FALSE, spy_active = FALSE; + + TRACE("%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("%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("%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("\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/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