[OLE32][WINESYNC] Fix Wine's implementation of IMalloc.DidAlloc based from Wine 5.7 (#2662)

CORE-15262

This fixes the exceptions raised when calling "Scan folder" a second time in SUMo 5.10.16.
The problem was reported to WineHQ : https://bugs.winehq.org/show_bug.cgi?id=48941

Import Wine commits by Nikolay Sivov, with the help of Doug Lyons:
- 08f4b6ee0a
  ole32: Fix IMalloc::DidAlloc() return value to reflect block validity.
- 1e3bc9f3a6
  ole32: Improve thread safety in DidAlloc().
- 06d36b1adf
  ole32: Fix spy callback arguments for IMalloc::GetSize().
This commit is contained in:
Kyle Katarn 2020-05-01 15:01:19 +02:00 committed by GitHub
parent 3bee3b92ab
commit 8bd6b9b6c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -114,6 +114,20 @@ static BOOL AddMemoryLocation(LPVOID * pMem)
return TRUE; 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 RemoveMemoryLocation(LPCVOID pMem) static BOOL RemoveMemoryLocation(LPCVOID pMem)
{ {
LPVOID * Current; LPVOID * Current;
@ -122,15 +136,9 @@ static BOOL RemoveMemoryLocation(LPCVOID pMem)
if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000)) if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000))
return FALSE; return FALSE;
Current = Malloc32.SpyedBlocks; if (!(Current = mallocspy_is_allocation_spyed(pMem)))
return FALSE;
/* find the location */
while (*Current != pMem) {
Current++;
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength)
return FALSE; /* not found */
}
/* location found */ /* location found */
Malloc32.SpyedAllocationsLeft--; Malloc32.SpyedAllocationsLeft--;
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/ /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
@ -288,50 +296,64 @@ static void WINAPI IMalloc_fnFree(IMalloc *iface, void *pv)
* win95: size allocated (4 byte boundarys) * win95: size allocated (4 byte boundarys)
* win2k: size originally requested !!! (allocated on 8 byte boundarys) * win2k: size originally requested !!! (allocated on 8 byte boundarys)
*/ */
static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *pv) static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *mem)
{ {
SIZE_T cb; BOOL spyed_block = FALSE, spy_active = FALSE;
BOOL fSpyed = FALSE; SIZE_T size;
TRACE("(%p)\n",pv); TRACE("(%p)\n", mem);
if(Malloc32.pSpy) { if (!mem)
EnterCriticalSection(&IMalloc32_SpyCS); return (SIZE_T)-1;
pv = IMallocSpy_PreGetSize(Malloc32.pSpy, pv, fSpyed);
}
cb = HeapSize(GetProcessHeap(),0,pv); if (Malloc32.pSpy)
{
EnterCriticalSection(&IMalloc32_SpyCS);
spyed_block = !!mallocspy_is_allocation_spyed(mem);
spy_active = TRUE;
mem = IMallocSpy_PreGetSize(Malloc32.pSpy, mem, spyed_block);
}
if(Malloc32.pSpy) { size = HeapSize(GetProcessHeap(), 0, mem);
cb = IMallocSpy_PostGetSize(Malloc32.pSpy, cb, fSpyed);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
return cb; if (spy_active)
{
size = IMallocSpy_PostGetSize(Malloc32.pSpy, size, spyed_block);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
return size;
} }
/****************************************************************************** /******************************************************************************
* IMalloc32_DidAlloc [VTABLE] * IMalloc32_DidAlloc [VTABLE]
*/ */
static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *pv) static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *mem)
{ {
BOOL fSpyed = FALSE; BOOL spyed_block = FALSE, spy_active = FALSE;
int didAlloc; int did_alloc;
TRACE("(%p)\n",pv); TRACE("(%p)\n", mem);
if(Malloc32.pSpy) { if (!mem)
EnterCriticalSection(&IMalloc32_SpyCS); return -1;
pv = IMallocSpy_PreDidAlloc(Malloc32.pSpy, pv, fSpyed);
}
didAlloc = -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);
}
if(Malloc32.pSpy) { did_alloc = HeapValidate(GetProcessHeap(), 0, mem);
didAlloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, pv, fSpyed, didAlloc);
LeaveCriticalSection(&IMalloc32_SpyCS); if (spy_active)
} {
return didAlloc; did_alloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, mem, spyed_block, did_alloc);
LeaveCriticalSection(&IMalloc32_SpyCS);
}
return did_alloc;
} }
/****************************************************************************** /******************************************************************************