Actually, I discovered a few more issues with the GIT (i should have written proper test cases instead of relying on the apps), so rather than do an incremental patch, I just regenerated it. ChangeLog: * GIT should not dereference ppv when unmarshalling interface * Correctly eliminate refcounting in the GIT * Add warning when given riid does not match * IMallocSpy cannot cause an allocation failure when cb == 0 * Deal with the case of loading an empty PIDL from a stream better in ILLoadFromStream
Index: dlls/ole32/git.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/git.c,v retrieving revision 1.4 diff -u -r1.4 git.c --- dlls/ole32/git.c 17 Jun 2003 03:57:18 -0000 1.4 +++ dlls/ole32/git.c 17 Jul 2003 16:42:27 -0000 @@ -55,7 +55,7 @@ typedef struct StdGITEntry { DWORD cookie; - IID iid; /* IID of the interface */ + IID iid; /* IID of the interface */ IStream* stream; /* Holds the marshalled interface */ struct StdGITEntry* next; @@ -107,13 +107,11 @@ void* StdGlobalInterfaceTable_Construct() { StdGlobalInterfaceTableImpl* newGIT; - TRACE("constructing\n"); - newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); if (newGIT == 0) return newGIT; newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl; - newGIT->ref = 0; /* Initialise the reference count */ + newGIT->ref = 1; /* Initialise the reference count */ newGIT->firstEntry = NULL; /* we start with an empty table */ newGIT->lastEntry = NULL; newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */ @@ -128,6 +126,7 @@ FIXME("Revoke held interfaces here\n"); HeapFree(GetProcessHeap(), 0, self); + StdGlobalInterfaceTableInstance = NULL; } /*** @@ -169,21 +168,21 @@ } else return E_NOINTERFACE; /* Now inc the refcount */ - /* we don't use refcounts for now: StdGlobalInterfaceTable_AddRef(iface); */ + StdGlobalInterfaceTable_AddRef(iface); return S_OK; } ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) { StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface; - self->ref++; + /* self->ref++; */ return self->ref; } ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) { StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface; - self->ref--; + /* self->ref--; */ if (self->ref == 0) { /* Hey ho, it's time to go, so long again 'till next weeks show! */ StdGlobalInterfaceTable_Destroy(self); @@ -208,6 +207,7 @@ if (pUnk == NULL) return E_INVALIDARG; /* marshal the interface */ + TRACE("About to marshal the interface\n"); hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream); if (hres) return hres; entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry)); @@ -260,10 +260,14 @@ entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie); if (entry == NULL) return E_INVALIDARG; - if (!IsEqualIID(&entry->iid, &riid)) return E_INVALIDARG; - + if (!IsEqualIID(&entry->iid, riid)) { + WARN("entry->iid (%s) != riid\n", debugstr_guid(&entry->iid)); + return E_INVALIDARG; + } + TRACE("entry=%p\n", entry); + /* unmarshal the interface */ - hres = CoGetInterfaceAndReleaseStream(entry->stream, riid, *ppv); + hres = CoGetInterfaceAndReleaseStream(entry->stream, riid, ppv); if (hres) return hres; return S_OK; Index: dlls/ole32/ifs.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/ifs.c,v retrieving revision 1.26 diff -u -r1.26 ifs.c --- dlls/ole32/ifs.c 10 Apr 2003 18:17:35 -0000 1.26 +++ dlls/ole32/ifs.c 17 Jul 2003 16:42:28 -0000 @@ -144,16 +144,18 @@ TRACE("(%ld)\n",cb); if(Malloc32.pSpy) { + DWORD preAllocResult; + EnterCriticalSection(&IMalloc32_SpyCS); - cb = IMallocSpy_PreAlloc(Malloc32.pSpy, cb); - if (0==cb) { - /* PreAlloc can force Alloc to fail */ - LeaveCriticalSection(&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) { Index: dlls/shell32/pidl.c =================================================================== RCS file: /home/wine/wine/dlls/shell32/pidl.c,v retrieving revision 1.84 diff -u -r1.84 pidl.c --- dlls/shell32/pidl.c 19 May 2003 21:42:44 -0000 1.84 +++ dlls/shell32/pidl.c 17 Jul 2003 16:42:29 -0000 @@ -279,25 +279,35 @@ IStream_AddRef (pStream); if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead))) - { *ppPidl = SHAlloc (wLen); - if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead))) - { ret = S_OK; - } - else - { SHFree(*ppPidl); + { + TRACE("PIDL length is %d\n", wLen); + if (wLen != 0) { + *ppPidl = SHAlloc (wLen); + if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead))) { + TRACE("Stream read OK\n"); + ret = S_OK; + } else { + WARN("reading pidl failed\n"); + SHFree(*ppPidl); + *ppPidl = NULL; + } + } else { *ppPidl = NULL; + ret = S_OK; } } /* we are not yet fully compatible */ - if (!pcheck(*ppPidl)) - { SHFree(*ppPidl); + if (*ppPidl && !pcheck(*ppPidl)) + { + WARN("Check failed\n"); + SHFree(*ppPidl); *ppPidl = NULL; } - + IStream_Release (pStream); - + TRACE("done\n"); return ret; }