Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/ole32/datacache.c | 156 ++++++++++++++----------------------------------- 1 file changed, 44 insertions(+), 112 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 60ddd386ba..ba253d9330 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -90,12 +90,8 @@ typedef struct PresentationDataHeader DWORD dwSize; } PresentationDataHeader;
-enum stream_type -{ - no_stream, - pres_stream, - contents_stream -}; +#define STREAM_NUMBER_NOT_SET -2 +#define STREAM_NUMBER_CONTENTS -1 /* CONTENTS stream */
typedef struct DataCacheEntry { @@ -104,19 +100,16 @@ typedef struct DataCacheEntry FORMATETC fmtetc; /* cached data */ STGMEDIUM stgmedium; - /* - * This stream pointer is set through a call to - * IPersistStorage_Load. This is where the visual - * representation of the object is stored. - */ - IStream *stream; - enum stream_type stream_type; /* connection ID */ DWORD id; /* dirty flag */ BOOL dirty; - /* stream number (-1 if not set ) */ - unsigned short stream_number; + /* stream number that the entry was loaded from. + This is used to defer loading until the data is actually needed. */ + int load_stream_num; + /* stream number that the entry will be saved to. + This may differ from above if cache entries have been Uncache()d for example. */ + int save_stream_num; /* sink id set when object is running */ DWORD sink_id; /* Advise sink flags */ @@ -260,8 +253,6 @@ static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) static void DataCacheEntry_Destroy(DataCache *cache, DataCacheEntry *cache_entry) { list_remove(&cache_entry->entry); - if (cache_entry->stream) - IStream_Release(cache_entry->stream); CoTaskMemFree(cache_entry->fmtetc.ptd); ReleaseStgMedium(&cache_entry->stgmedium); if(cache_entry->sink_id) @@ -355,11 +346,10 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD
entry->stgmedium.tymed = TYMED_NULL; entry->stgmedium.pUnkForRelease = NULL; - entry->stream = NULL; - entry->stream_type = no_stream; entry->id = id; entry->dirty = TRUE; - entry->stream_number = -1; + entry->load_stream_num = STREAM_NUMBER_NOT_SET; + entry->save_stream_num = STREAM_NUMBER_NOT_SET; entry->sink_id = 0; entry->advise_flags = advf;
@@ -518,60 +508,18 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat) return hr; }
-/************************************************************************ - * DataCacheEntry_OpenPresStream - * - * This method will find the stream for the given presentation. It makes - * no attempt at fallback. - * - * Param: - * this - Pointer to the DataCache object - * drawAspect - The aspect of the object that we wish to draw. - * pStm - A returned stream. It points to the beginning of the - * - presentation data, including the header. - * - * Errors: - * S_OK The requested stream has been opened. - * OLE_E_BLANK The requested stream could not be found. - * Quite a few others I'm too lazy to map correctly. - * - * Notes: - * Algorithm: Scan the elements of the presentation storage, looking - * for presentation streams. For each presentation stream, - * load the header and check to see if the aspect matches. - * - * If a fallback is desired, just opening the first presentation stream - * is a possibility. - */ -static HRESULT DataCacheEntry_OpenPresStream(DataCacheEntry *cache_entry, IStream **ppStm) -{ - HRESULT hr; - LARGE_INTEGER offset; - - if (cache_entry->stream) - { - /* Rewind the stream before returning it. */ - offset.QuadPart = 0; - - hr = IStream_Seek( cache_entry->stream, offset, STREAM_SEEK_SET, NULL ); - if (SUCCEEDED( hr )) - { - *ppStm = cache_entry->stream; - IStream_AddRef( cache_entry->stream ); - } - } - else - hr = OLE_E_BLANK; - - return hr; -} +static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm ) { - WCHAR name[] = {2,'O','l','e','P','r','e','s', + WCHAR pres[] = {2,'O','l','e','P','r','e','s', '0' + (stream_number / 100) % 10, '0' + (stream_number / 10) % 10, '0' + stream_number % 10, 0}; + const WCHAR *name = pres; + + if (stream_number == STREAM_NUMBER_NOT_SET) return E_FAIL; + if (stream_number == STREAM_NUMBER_CONTENTS) name = CONTENTS;
return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); } @@ -589,9 +537,9 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) static const LARGE_INTEGER offset_zero; ULONG read;
- if (cache_entry->stream_type != pres_stream) + if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS) { - FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type ); + FIXME( "Unimplemented for CONTENTS stream\n" ); return E_FAIL; }
@@ -658,9 +606,9 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) BITMAPFILEHEADER file; BITMAPINFOHEADER *info;
- if (cache_entry->stream_type != contents_stream) + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) { - FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type ); + FIXME( "Unimplemented for presentation stream\n" ); return E_FAIL; }
@@ -746,12 +694,13 @@ fail: * This method returns a metafile handle if it is successful. * it will return 0 if not. */ -static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry) +static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *stg) { HRESULT hr; IStream *stm;
- hr = DataCacheEntry_OpenPresStream( cache_entry, &stm ); + if (!stg) return OLE_E_BLANK; + hr = open_pres_stream( stg, cache_entry->load_stream_num, &stm ); if (FAILED(hr)) return hr;
switch (cache_entry->fmtetc.cfFormat) @@ -1004,14 +953,13 @@ static HRESULT save_view_cache(DataCacheEntry *entry, IStream *stream) return hr; }
-static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; static HRESULT create_stream(DataCacheEntry *cache_entry, IStorage *storage, BOOL contents, IStream **stream) { WCHAR pres[] = {2,'O','l','e','P','r','e','s', - '0' + (cache_entry->stream_number / 100) % 10, - '0' + (cache_entry->stream_number / 10) % 10, - '0' + cache_entry->stream_number % 10, 0}; + '0' + (cache_entry->save_stream_num / 100) % 10, + '0' + (cache_entry->save_stream_num / 10) % 10, + '0' + cache_entry->save_stream_num % 10, 0}; const WCHAR *name;
if (contents) @@ -1031,7 +979,7 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag IStream *stream; BOOL contents = (cache_entry->id == 1);
- TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc)); + TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->save_stream_num, debugstr_formatetc(&cache_entry->fmtetc));
hr = create_stream(cache_entry, storage, contents, &stream); if (FAILED(hr)) @@ -1216,11 +1164,11 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, return copy_stg_medium(cache_entry->fmtetc.cfFormat, &cache_entry->stgmedium, stgmedium); }
-static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium) +static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, IStorage *stg, FORMATETC *fmt, STGMEDIUM *stgmedium) { - if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->stream) + if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET) { - HRESULT hr = DataCacheEntry_LoadData(cache_entry); + HRESULT hr = DataCacheEntry_LoadData(cache_entry, stg); if (FAILED(hr)) return hr; } @@ -1239,15 +1187,6 @@ static inline HRESULT DataCacheEntry_DiscardData(DataCacheEntry *cache_entry) return S_OK; }
-static inline void DataCacheEntry_HandsOffStorage(DataCacheEntry *cache_entry) -{ - if (cache_entry->stream) - { - IStream_Release(cache_entry->stream); - cache_entry->stream = NULL; - } -} - static inline DWORD tymed_from_cf( DWORD cf ) { switch( cf ) @@ -1470,7 +1409,7 @@ static HRESULT WINAPI DataCache_GetData( if (!cache_entry) return OLE_E_BLANK;
- return DataCacheEntry_GetData(cache_entry, pformatetcIn, pmedium); + return DataCacheEntry_GetData(cache_entry, This->presentationStorage, pformatetcIn, pmedium); }
static HRESULT WINAPI DataCache_GetDataHere( @@ -1703,8 +1642,7 @@ static HRESULT WINAPI DataCache_InitNew( }
-static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, IStream *stm, - enum stream_type type ) +static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, int stream_number ) { DataCacheEntry *cache_entry; HRESULT hr = S_OK; @@ -1717,10 +1655,8 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD adv if (SUCCEEDED( hr )) { DataCacheEntry_DiscardData( cache_entry ); - if (cache_entry->stream) IStream_Release( cache_entry->stream ); - cache_entry->stream = stm; - IStream_AddRef( stm ); - cache_entry->stream_type = type; + cache_entry->load_stream_num = stream_number; + cache_entry->save_stream_num = stream_number; cache_entry->dirty = FALSE; } return hr; @@ -1753,7 +1689,7 @@ static HRESULT parse_pres_streams( DataCache *cache, IStorage *stg ) fmtetc.lindex = header.lindex; fmtetc.tymed = tymed_from_cf( clipformat );
- add_cache_entry( cache, &fmtetc, header.advf, stm, pres_stream ); + add_cache_entry( cache, &fmtetc, header.advf, stream_number ); } IStream_Release( stm ); stream_number++; @@ -1771,7 +1707,7 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg ) const FORMATETC *fmt; IStream *stm;
- hr = IStorage_OpenStream( stg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm ); + hr = open_pres_stream( stg, STREAM_NUMBER_CONTENTS, &stm ); if (FAILED( hr )) return hr;
hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME ); @@ -1786,7 +1722,7 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg ) goto done; }
- hr = add_cache_entry( This, fmt, 0, stm, contents_stream ); + hr = add_cache_entry( This, fmt, 0, STREAM_NUMBER_CONTENTS );
done: IStream_Release( stm ); @@ -1852,17 +1788,17 @@ static HRESULT WINAPI DataCache_Save(IPersistStorage* iface, IStorage *stg, BOOL DataCache *This = impl_from_IPersistStorage(iface); DataCacheEntry *cache_entry; HRESULT hr = S_OK; - unsigned short stream_number = 0; + int stream_number = 0;
TRACE("(%p, %p, %d)\n", iface, stg, same_as_load);
/* assign stream numbers to the cache entries */ LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) { - if (cache_entry->stream_number != stream_number) + if (cache_entry->save_stream_num != stream_number) { cache_entry->dirty = TRUE; /* needs to be written out again */ - cache_entry->stream_number = stream_number; + cache_entry->save_stream_num = stream_number; } stream_number++; } @@ -1916,7 +1852,6 @@ static HRESULT WINAPI DataCache_HandsOffStorage( IPersistStorage* iface) { DataCache *this = impl_from_IPersistStorage(iface); - DataCacheEntry *cache_entry;
TRACE("(%p)\n", iface);
@@ -1926,9 +1861,6 @@ static HRESULT WINAPI DataCache_HandsOffStorage( this->presentationStorage = NULL; }
- LIST_FOR_EACH_ENTRY(cache_entry, &this->cache_list, DataCacheEntry, entry) - DataCacheEntry_HandsOffStorage(cache_entry); - return S_OK; }
@@ -2018,9 +1950,9 @@ static HRESULT WINAPI DataCache_Draw( continue;
/* if the data hasn't been loaded yet, do it now */ - if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream) + if ((cache_entry->stgmedium.tymed == TYMED_NULL) && (cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET)) { - hres = DataCacheEntry_LoadData(cache_entry); + hres = DataCacheEntry_LoadData(cache_entry, This->presentationStorage); if (FAILED(hres)) continue; } @@ -2278,9 +2210,9 @@ static HRESULT WINAPI DataCache_GetExtent( continue;
/* if the data hasn't been loaded yet, do it now */ - if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream) + if ((cache_entry->stgmedium.tymed == TYMED_NULL) && (cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET)) { - hres = DataCacheEntry_LoadData(cache_entry); + hres = DataCacheEntry_LoadData(cache_entry, This->presentationStorage); if (FAILED(hres)) continue; }