[PATCH v2 1/5] ole32: Add support for loading enhmetafiles from presentation and contents streams to data cache.

Huw Davies huw at codeweavers.com
Tue Apr 3 04:19:03 CDT 2018


On Fri, Mar 30, 2018 at 12:11:33PM -0500, Sergio Gómez Del Real wrote:
> Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
> ---
>  dlls/ole32/datacache.c | 185 ++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 122 insertions(+), 63 deletions(-)
> 
> diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
> index 325a98b33b..799e14a867 100644
> --- a/dlls/ole32/datacache.c
> +++ b/dlls/ole32/datacache.c
> @@ -701,7 +764,62 @@ fail:
>      GlobalUnlock( hglobal );
>      GlobalFree( hglobal );
>      return E_FAIL;
> +}
>  
> +static HRESULT load_emf( DataCacheEntry *cache_entry, IStream *stm )
> +{
> +    HRESULT hr;
> +
> +    if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
> +    {
> +        STGMEDIUM stgmed;
> +
> +        hr = load_mf_pict( cache_entry, stm );
> +        if (SUCCEEDED( hr ))
> +            hr = synthesize_emf( cache_entry->stgmedium.u.hMetaFilePict, &stgmed );
> +        if (SUCCEEDED( hr ))
> +        {
> +            ReleaseStgMedium( &cache_entry->stgmedium );

I think we want to release this even if synthesize_emf fails,
otherwise we'll be stuck with a mfpict in there, that will likely
confuse things later on.

> +            hr = copy_stg_medium( CF_ENHMETAFILE, &cache_entry->stgmedium, &stgmed );
> +            ReleaseStgMedium( &stgmed );

I didn't mean a deep copy here.  Just &cache_entry->stgmedium = stgmed; would do.

> +        }
> +    }
> +    else
> +    {
> +        STATSTG stat;
> +        void *data;

If data were a BYTE * you won't need the cast later on.

> +        DWORD size_bits;
> +        ULONG read;
> +
> +        hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
> +
> +        if (SUCCEEDED( hr ))
> +        {
> +            data = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart );
> +            if (!data) return E_OUTOFMEMORY;
> +
> +            hr = IStream_Read( stm, data, stat.cbSize.u.LowPart, &read );
> +            if (hr != S_OK || read != stat.cbSize.u.LowPart)
> +            {
> +                HeapFree( GetProcessHeap(), 0, data );
> +                return E_FAIL;
> +            }
> +
> +            size_bits = read - sizeof(DWORD) - sizeof(ENHMETAHEADER);
> +            if (size_bits <= 0)
> +            {
> +                HeapFree( GetProcessHeap(), 0, data );
> +                return E_FAIL;
> +            }
> +            cache_entry->stgmedium.u.hEnhMetaFile = SetEnhMetaFileBits( size_bits, (BYTE *)data + (read - size_bits) );
> +            cache_entry->stgmedium.tymed = TYMED_ENHMF;
> +            cache_entry->stgmedium.pUnkForRelease = NULL;
> +
> +            HeapFree( GetProcessHeap(), 0, data );
> +        }
> +    }
> +
> +    return hr;
>  }



More information about the wine-devel mailing list