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