On Thu, Sep 15, 2011 at 02:09:56PM +0200, Bernhard Loos wrote:
--- dlls/oleaut32/olepicture.c | 148 +++++++++++++------------------------- dlls/oleaut32/tests/olepicture.c | 16 ++--- 2 files changed, 54 insertions(+), 110 deletions(-)
Did make check work for you even? Marvin does not like it at least. This will break NonStatable streams, also seekability of streams can not be assumed. Ciao, Marcus
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index 8081785..725207f 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1324,15 +1324,13 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This, */ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) { HRESULT hr; - BOOL headerisdata; - BOOL statfailed = FALSE; - ULONG xread, toread; - ULONG headerread; + ULONG xread, toread = 0; BYTE *xbuf; DWORD header[2]; WORD magic; - STATSTG statstg; OLEPictureImpl *This = impl_from_IPersistStream(iface); + ULARGE_INTEGER end, start; + LARGE_INTEGER offset;
TRACE("(%p,%p)\n",This,pStm);
@@ -1348,104 +1346,56 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) * At least in Visual Basic 6, resource streams, valid headers are * header[0] == "lt\0\0", * header[1] == length_of_stream. - * - * Also handle streams where we do not have a working "Stat" method by - * reading all data until the end of the stream. */ - hr = IStream_Stat(pStm,&statstg,STATFLAG_NONAME); - if (hr != S_OK) { - TRACE("stat failed with hres %x, proceeding to read all data.\n",hr); - statfailed = TRUE; - /* we will read at least 8 byte ... just right below */ - statstg.cbSize.QuadPart = 8; - } + offset.QuadPart = 0;
- toread = 0; - headerread = 0; - headerisdata = FALSE; do { - hr = IStream_Read(pStm, header, 8, &xread); - if (hr != S_OK || xread!=8) { - ERR("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread); - return (hr?hr:E_FAIL); - } - headerread += xread; - xread = 0; - - if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) { - if (toread != 0 && toread != header[1]) - FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n", - toread, header[1]); - toread = header[1]; - if (toread == 0) break; - } else { - if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */ - !memcmp(&(header[0]), "BM", 2) || /* BMP header */ - !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */ - (header[0] == EMR_HEADER) || /* EMF header */ - (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */ - (header[1]==0) - ) {/* Found start of bitmap data */ - headerisdata = TRUE; - if (toread == 0) - toread = statstg.cbSize.QuadPart-8; - else toread -= 8; - xread = 8; - } else { - FIXME("Unknown stream header magic: %08x\n", header[0]); - toread = header[1]; - } - } - } while (!headerisdata); - - if (statfailed) { /* we don't know the size ... read all we get */ - int sizeinc = 4096; - int origsize = sizeinc; - ULONG nread = 42; - - TRACE("Reading all data from stream.\n"); - xbuf = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, origsize); - if (headerisdata) - memcpy (xbuf, header, 8); - while (1) { - while (xread < origsize) { - hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread); - xread += nread; - if (hr != S_OK || !nread) - break; - } - if (!nread || hr != S_OK) /* done, or error */ - break; - if (xread == origsize) { - origsize += sizeinc; - sizeinc = 2*sizeinc; /* exponential increase */ - xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize); - } - } - if (hr != S_OK) - TRACE("hr in no-stat loader case is %08x\n", hr); - TRACE("loaded %d bytes.\n", xread); - This->datalen = xread; - This->data = xbuf; - } else { - This->datalen = toread+(headerisdata?8:0); - xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, This->datalen); - if (!xbuf) - return E_OUTOFMEMORY; - - if (headerisdata) - memcpy (xbuf, header, 8); - - while (xread < This->datalen) { - ULONG nread; - hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread); - xread += nread; - if (hr != S_OK || !nread) - break; - } - if (xread != This->datalen) - ERR("Could only read %d of %d bytes out of stream?\n",xread,This->datalen); + hr = IStream_Seek(pStm, offset, STREAM_SEEK_CUR, &start); + if (FAILED(hr)) + return hr; + + hr = IStream_Read(pStm, header, 8, &xread); + if (FAILED(hr) || xread!=8) { + ERR("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread); + return (FAILED(hr)?hr:E_FAIL); + } + + if (memcmp(&(header[0]),"lt", 2)) { + if (!toread) { + hr = IStream_Seek(pStm, offset, STREAM_SEEK_END, &end); + if (FAILED(hr)) + return hr; + toread = end.QuadPart - start.QuadPart; + } + offset.QuadPart = start.QuadPart; + hr = IStream_Seek(pStm, offset, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + return hr; + break; + } + else { + toread = header[1]; + if (toread == 0) + break; + } + } while (1); + + This->datalen = toread; + xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, This->datalen); + if (!xbuf) + return E_OUTOFMEMORY; + + xread = 0; + while (xread < This->datalen) { + ULONG nread; + hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread); + xread += nread; + if (FAILED(hr) || !nread) + break; } + if (xread != This->datalen) + ERR("Could only read %d of %d bytes out of stream?\n",xread,This->datalen); + if (This->datalen == 0) { /* Marks the "NONE" picture */ This->desc.picType = PICTYPE_NONE; return S_OK; diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 54de1cb..b1fad94 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -1063,20 +1063,14 @@ static HRESULT WINAPI NoStatStreamImpl_Read( { NoStatStreamImpl* const This = impl_from_IStream(iface); void* supportBuffer; - ULONG bytesReadBuffer; - ULONG bytesToReadFromBuffer;
- if (pcbRead==0) - pcbRead = &bytesReadBuffer; - bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); supportBuffer = GlobalLock(This->supportHandle); - memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer); - This->currentPosition.u.LowPart+=bytesToReadFromBuffer; - *pcbRead = bytesToReadFromBuffer; + memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, cb); + This->currentPosition.u.LowPart+=cb; GlobalUnlock(This->supportHandle); - if(*pcbRead == cb) - return S_OK; - return S_FALSE; + if(pcbRead) + *pcbRead = cb; + return S_OK; }
static HRESULT WINAPI NoStatStreamImpl_Write(
-- Working, but not speaking, for the following german company: SUSE LINUX Products GmbH, HRB 16746 (AG Nuernberg) Geschaeftsfuehrer: Jeff Hawn, Jennifer Guild, Felix Imendoerffer