Module: wine Branch: master Commit: e5c82d3aa4f8f945eedefddecbdc3bbc3cd585e9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e5c82d3aa4f8f945eedefddecb...
Author: Rob Shearman rob@codeweavers.com Date: Fri Dec 1 15:03:19 2006 +0000
ole32: Add handling of the dirty state to the data cache and fix InitNew to not call Load.
---
dlls/ole32/datacache.c | 89 ++++++++++++++++++++++++++++++++++------------- dlls/ole32/tests/ole2.c | 2 - 2 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 1d7a765..dba012c 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -88,21 +88,20 @@ typedef struct PresentationDataHeader typedef struct DataCacheEntry { struct list entry; - /* format of this entry */ FORMATETC fmtetc; - /* cached data */ STGMEDIUM stgmedium; - /* * This storage pointer is set through a call to * IPersistStorage_Load. This is where the visual * representation of the object is stored. */ IStorage *storage; - + /* connection ID */ DWORD id; + /* dirty flag */ + BOOL dirty; } DataCacheEntry;
/**************************************************************************** @@ -140,10 +139,12 @@ struct DataCache IAdviseSink* sinkInterface; IStorage *presentationStorage;
+ /* list of cache entries */ struct list cache_list; - /* last id assigned to an entry */ DWORD last_cache_id; + /* dirty flag */ + BOOL dirty; };
typedef struct DataCache DataCache; @@ -257,6 +258,7 @@ static HRESULT DataCache_CreateEntry(Dat (*cache_entry)->stgmedium.pUnkForRelease = NULL; (*cache_entry)->storage = NULL; (*cache_entry)->id = This->last_cache_id++; + (*cache_entry)->dirty = TRUE; list_add_tail(&This->cache_list, &(*cache_entry)->entry); return S_OK; } @@ -557,6 +559,7 @@ static HRESULT copy_stg_medium(CLIPFORMA static HRESULT DataCacheEntry_SetData(DataCacheEntry *This, STGMEDIUM *stgmedium, BOOL fRelease) { + This->dirty = TRUE; ReleaseStgMedium(&This->stgmedium); if (fRelease) { @@ -1052,17 +1055,24 @@ static HRESULT WINAPI DataCache_GetClass /************************************************************************ * DataCache_IsDirty (IPersistStorage) * - * Until we actually connect to a running object and retrieve new - * information to it, we never get dirty. - * * See Windows documentation for more details on IPersistStorage methods. */ static HRESULT WINAPI DataCache_IsDirty( IPersistStorage* iface) { - TRACE("(%p)\n", iface); + DataCache *This = impl_from_IPersistStorage(iface); + DataCacheEntry *cache_entry; + + TRACE("(%p)\n", iface);
- return S_FALSE; + if (This->dirty) + return S_OK; + + LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) + if (cache_entry->dirty) + return S_OK; + + return S_FALSE; }
/************************************************************************ @@ -1077,9 +1087,19 @@ static HRESULT WINAPI DataCache_InitNew( IPersistStorage* iface, IStorage* pStg) { - TRACE("(%p, %p)\n", iface, pStg); + DataCache *This = impl_from_IPersistStorage(iface); + + TRACE("(%p, %p)\n", iface, pStg); + + if (This->presentationStorage != NULL) + IStorage_Release(This->presentationStorage); + + This->presentationStorage = pStg;
- return IPersistStorage_Load(iface, pStg); + IStorage_AddRef(This->presentationStorage); + This->dirty = TRUE; + + return S_OK; }
/************************************************************************ @@ -1148,6 +1168,7 @@ static HRESULT WINAPI DataCache_Load( if (cache_entry->storage) IStorage_Release(cache_entry->storage); cache_entry->storage = pStg; IStorage_AddRef(pStg); + cache_entry->dirty = FALSE; } }
@@ -1158,6 +1179,8 @@ static HRESULT WINAPI DataCache_Load( CoTaskMemFree(elem.pwcsName); }
+ This->dirty = FALSE; + IEnumSTATSTG_Release(pEnum);
IStorage_AddRef(This->presentationStorage); @@ -1179,21 +1202,37 @@ static HRESULT WINAPI DataCache_Save( IStorage* pStg, BOOL fSameAsLoad) { - DataCache *this = impl_from_IPersistStorage(iface); + DataCache *This = impl_from_IPersistStorage(iface); + DataCacheEntry *cache_entry; + BOOL dirty = FALSE;
- TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad); + TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
- if ( (!fSameAsLoad) && - (this->presentationStorage!=NULL) ) - { - return IStorage_CopyTo(this->presentationStorage, - 0, - NULL, - NULL, - pStg); - } + dirty = This->dirty; + if (!dirty) + { + LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) + { + dirty = cache_entry->dirty; + if (dirty) + break; + } + }
- return S_OK; + /* this is a shortcut if nothing changed */ + if (!dirty && !fSameAsLoad && This->presentationStorage) + { + return IStorage_CopyTo(This->presentationStorage, 0, NULL, NULL, pStg); + } + + LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) + { + /* FIXME: actually do the save here */ + cache_entry->dirty = FALSE; + } + + This->dirty = FALSE; + return S_OK; }
/************************************************************************ @@ -2060,6 +2099,8 @@ static DataCache* DataCache_Construct( newObject->sinkInterface = 0; newObject->presentationStorage = NULL; list_init(&newObject->cache_list); + newObject->last_cache_id = 1; + newObject->dirty = FALSE;
return newObject; } diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c index 8c9a8b0..18a5a46 100644 --- a/dlls/ole32/tests/ole2.c +++ b/dlls/ole32/tests/ole2.c @@ -1105,9 +1105,7 @@ static void test_data_cache(void) ok_ole_success(hr, "IPersistStorage_InitNew");
hr = IPersistStorage_IsDirty(pPS); - todo_wine { ok_ole_success(hr, "IPersistStorage_IsDirty"); - }
hr = IPersistStorage_GetClassID(pPS, &clsid); ok_ole_success(hr, "IPersistStorage_GetClassID");