On December 22, 2002 02:50 pm, Duane Clark wrote:
That area is then freed. When freed, COMCTL32_Free writes prev and next entries into himl.
Where? COMCTL32_Free() simply calls HeapFree():
BOOL WINAPI COMCTL32_Free (LPVOID lpMem) { TRACE("(%p)\n", lpMem); return HeapFree (COMCTL32_hHeap, 0, lpMem); }
The listview does not know that the imagelist was already destroyed, so it again calls ImageList_Destroy.
Yes, a common problem.
At the end of ImageList_Destroy, there is a call to ZeroMemory, which obliterates the prev and next pointers which had been written there. Then another COMCTL32_Free call detects the error. At least I assume it is an error.
Does this work any better? It shouldn't make any difference, but ...
There is something else funny here. I can't see why zeroing out an area we're just about to free is problematic.
Index: dlls/comctl32/imagelist.c =================================================================== RCS file: /var/cvs/wine/dlls/comctl32/imagelist.c,v retrieving revision 1.68 diff -u -r1.68 imagelist.c --- dlls/comctl32/imagelist.c 5 Dec 2002 20:33:09 -0000 1.68 +++ dlls/comctl32/imagelist.c 23 Dec 2002 04:37:55 -0000 @@ -693,7 +693,7 @@ if (himl->hbrBlend50) DeleteObject (himl->hbrBlend50);
- ZeroMemory(himl, sizeof(*himl)); + ZeroMemory(himl, sizeof(struct _IMAGELIST)); COMCTL32_Free (himl);
return TRUE;