From 2514b5140069b68a20c219bfa966de70cf1d72a8 Mon Sep 17 00:00:00 2001 From: Alexander Morozov <amorozov@etersoft.ru> Date: Tue, 7 Dec 2010 20:41:16 +0300 Subject: [PATCH] oleaut32: MSDN says that Load can only seek and read from stream (eterbug #6343). --- dlls/oleaut32/olepicture.c | 94 +++++++++++++++----------------------------- 1 files changed, 32 insertions(+), 62 deletions(-) diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index fbec73d..f9ad70d 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1322,15 +1322,15 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This, * Currently implemented: BITMAP, ICON, JPEG, GIF, WMF, EMF */ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) { + LARGE_INTEGER cur, zero = {{0, 0}}; + ULARGE_INTEGER ucur, end; HRESULT hr; BOOL headerisdata; - BOOL statfailed = FALSE; ULONG xread, toread; ULONG headerread; BYTE *xbuf; DWORD header[2]; WORD magic; - STATSTG statstg; OLEPictureImpl *This = impl_from_IPersistStream(iface); TRACE("(%p,%p)\n",This,pStm); @@ -1347,17 +1347,17 @@ 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; - } + hr = IStream_Seek(pStm, zero, STREAM_SEEK_CUR, &ucur); + if (hr != S_OK) + return hr; + hr = IStream_Seek(pStm, zero, STREAM_SEEK_END, &end); + if (hr != S_OK) + return hr; + cur.QuadPart = ucur.QuadPart; + hr = IStream_Seek(pStm, cur, STREAM_SEEK_SET, NULL); + if (hr != S_OK) + return hr; toread = 0; headerread = 0; @@ -1371,7 +1371,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) headerread += xread; xread = 0; - if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) { + if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] + headerread <= end.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]); @@ -1382,12 +1382,12 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) !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] > end.QuadPart) || /* invalid size */ (header[1]==0) ) {/* Found start of bitmap data */ headerisdata = TRUE; if (toread == 0) - toread = statstg.cbSize.QuadPart-8; + toread = end.QuadPart-8; else toread -= 8; xread = 8; } else { @@ -1397,54 +1397,24 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) } } 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); + 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); + if (This->datalen == 0) { /* Marks the "NONE" picture */ This->desc.picType = PICTYPE_NONE; return S_OK; -- 1.7.3.2