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(