Huw Davies : ole32: Create initial cache entries for the CLSID_Picture_ classes.
Alexandre Julliard
julliard at winehq.org
Tue Jun 6 15:23:32 CDT 2017
Module: wine
Branch: master
Commit: 966e8a2c241fa4f5dc06a9c95246883f978cd6e6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=966e8a2c241fa4f5dc06a9c95246883f978cd6e6
Author: Huw Davies <huw at codeweavers.com>
Date: Tue Jun 6 11:46:51 2017 +0100
ole32: Create initial cache entries for the CLSID_Picture_ classes.
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ole32/datacache.c | 113 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 91 insertions(+), 22 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index d97e288..9809c7a 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -160,7 +160,9 @@ struct DataCache
*/
DWORD sinkAspects;
DWORD sinkAdviseFlag;
- IAdviseSink* sinkInterface;
+ IAdviseSink *sinkInterface;
+
+ CLSID clsid;
IStorage *presentationStorage;
/* list of cache entries */
@@ -360,9 +362,10 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD
}
static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DWORD advf,
- DataCacheEntry **cache_entry)
+ BOOL automatic, DataCacheEntry **cache_entry)
{
HRESULT hr;
+ DWORD id = automatic ? 1 : This->last_cache_id;
DataCacheEntry *entry;
hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed);
@@ -375,11 +378,16 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
if (!entry)
return E_OUTOFMEMORY;
- if (!init_cache_entry(entry, formatetc, advf, This->last_cache_id))
+ if (!init_cache_entry(entry, formatetc, advf, id))
goto fail;
- list_add_tail(&This->cache_list, &entry->entry);
- This->last_cache_id++;
+ if (automatic)
+ list_add_head(&This->cache_list, &entry->entry);
+ else
+ {
+ list_add_tail(&This->cache_list, &entry->entry);
+ This->last_cache_id++;
+ }
if (cache_entry) *cache_entry = entry;
return hr;
@@ -1042,6 +1050,54 @@ static inline DWORD tymed_from_cf( DWORD cf )
}
}
+/****************************************************************
+ * create_automatic_entry
+ *
+ * Creates an appropriate cache entry for one of the CLSID_Picture_
+ * classes. The connection id of the entry is one. Any pre-existing
+ * automatic entry is re-assigned a new connection id, and moved to
+ * the end of the list.
+ */
+static HRESULT create_automatic_entry(DataCache *cache, const CLSID *clsid)
+{
+ static const struct data
+ {
+ const CLSID *clsid;
+ FORMATETC fmt;
+ } data[] =
+ {
+ { &CLSID_Picture_Dib, { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { &CLSID_Picture_Metafile, { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { &CLSID_Picture_EnhMetafile, { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+ { NULL }
+ };
+ const struct data *ptr = data;
+ struct list *head;
+ DataCacheEntry *entry;
+
+ if (IsEqualCLSID( &cache->clsid, clsid )) return S_OK;
+
+ /* move and reassign any pre-existing automatic entry */
+ if ((head = list_head( &cache->cache_list )))
+ {
+ entry = LIST_ENTRY( head, DataCacheEntry, entry );
+ if (entry->id == 1)
+ {
+ list_remove( &entry->entry );
+ entry->id = cache->last_cache_id++;
+ list_add_tail( &cache->cache_list, &entry->entry );
+ }
+ }
+
+ while (ptr->clsid)
+ {
+ if (IsEqualCLSID( clsid, ptr->clsid ))
+ return DataCache_CreateEntry( cache, &ptr->fmt, 0, TRUE, NULL );
+ ptr++;
+ }
+ return S_OK;
+}
+
/*********************************************************
* Method implementation for the non delegating IUnknown
* part of the DataCache class.
@@ -1363,22 +1419,9 @@ static ULONG WINAPI DataCache_IPersistStorage_Release(
static HRESULT WINAPI DataCache_GetClassID(IPersistStorage *iface, CLSID *clsid)
{
DataCache *This = impl_from_IPersistStorage( iface );
- HRESULT hr;
- STATSTG statstg;
-
- TRACE( "(%p, %p)\n", iface, clsid );
-
- if (This->presentationStorage)
- {
- hr = IStorage_Stat( This->presentationStorage, &statstg, STATFLAG_NONAME );
- if (SUCCEEDED(hr))
- {
- *clsid = statstg.clsid;
- return S_OK;
- }
- }
- *clsid = CLSID_NULL;
+ TRACE( "(%p, %p) returning %s\n", iface, clsid, debugstr_guid(&This->clsid) );
+ *clsid = This->clsid;
return S_OK;
}
@@ -1415,6 +1458,8 @@ static HRESULT WINAPI DataCache_InitNew(
IStorage* pStg)
{
DataCache *This = impl_from_IPersistStorage(iface);
+ CLSID clsid;
+ HRESULT hr;
TRACE("(%p, %p)\n", iface, pStg);
@@ -1425,6 +1470,15 @@ static HRESULT WINAPI DataCache_InitNew(
IStorage_AddRef(This->presentationStorage);
This->dirty = TRUE;
+ ReadClassStg( pStg, &clsid );
+ hr = create_automatic_entry( This, &clsid );
+ if (FAILED(hr))
+ {
+ IStorage_Release( pStg );
+ This->presentationStorage = NULL;
+ return hr;
+ }
+ This->clsid = clsid;
return S_OK;
}
@@ -1440,7 +1494,7 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD adv
cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
if (!cache_entry)
- hr = DataCache_CreateEntry( This, fmt, advf, &cache_entry );
+ hr = DataCache_CreateEntry( This, fmt, advf, FALSE, &cache_entry );
if (SUCCEEDED( hr ))
{
DataCacheEntry_DiscardData( cache_entry );
@@ -1537,11 +1591,22 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
DataCache *This = impl_from_IPersistStorage(iface);
HRESULT hr;
IStream *stm;
+ CLSID clsid;
+ DataCacheEntry *entry, *cursor2;
TRACE("(%p, %p)\n", iface, pStg);
IPersistStorage_HandsOffStorage( iface );
+ LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry )
+ DataCacheEntry_Destroy( This, entry );
+
+ ReadClassStg( pStg, &clsid );
+ hr = create_automatic_entry( This, &clsid );
+ if (FAILED( hr )) return hr;
+
+ This->clsid = clsid;
+
hr = IStorage_OpenStream( pStg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
0, &stm );
if (SUCCEEDED( hr ))
@@ -2191,7 +2256,7 @@ static HRESULT WINAPI DataCache_Cache(
return CACHE_S_SAMECACHE;
}
- hr = DataCache_CreateEntry(This, &fmt_cpy, advf, &cache_entry);
+ hr = DataCache_CreateEntry(This, &fmt_cpy, advf, FALSE, &cache_entry);
if (SUCCEEDED(hr))
{
@@ -2622,12 +2687,16 @@ static DataCache* DataCache_Construct(
newObject->sinkAspects = 0;
newObject->sinkAdviseFlag = 0;
newObject->sinkInterface = 0;
+ newObject->clsid = CLSID_NULL;
newObject->presentationStorage = NULL;
list_init(&newObject->cache_list);
newObject->last_cache_id = 2;
newObject->dirty = FALSE;
newObject->running_object = NULL;
+ create_automatic_entry( newObject, clsid );
+ newObject->clsid = *clsid;
+
return newObject;
}
More information about the wine-cvs
mailing list