ole32: Add handling of the dirty state to the data cache and fix InitNew to not call Load.
This commit is contained in:
parent
e9cc0744cc
commit
e5c82d3aa4
|
@ -88,21 +88,20 @@ typedef struct PresentationDataHeader
|
||||||
typedef struct DataCacheEntry
|
typedef struct DataCacheEntry
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
|
||||||
/* format of this entry */
|
/* format of this entry */
|
||||||
FORMATETC fmtetc;
|
FORMATETC fmtetc;
|
||||||
|
|
||||||
/* cached data */
|
/* cached data */
|
||||||
STGMEDIUM stgmedium;
|
STGMEDIUM stgmedium;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This storage pointer is set through a call to
|
* This storage pointer is set through a call to
|
||||||
* IPersistStorage_Load. This is where the visual
|
* IPersistStorage_Load. This is where the visual
|
||||||
* representation of the object is stored.
|
* representation of the object is stored.
|
||||||
*/
|
*/
|
||||||
IStorage *storage;
|
IStorage *storage;
|
||||||
|
/* connection ID */
|
||||||
DWORD id;
|
DWORD id;
|
||||||
|
/* dirty flag */
|
||||||
|
BOOL dirty;
|
||||||
} DataCacheEntry;
|
} DataCacheEntry;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -140,10 +139,12 @@ struct DataCache
|
||||||
IAdviseSink* sinkInterface;
|
IAdviseSink* sinkInterface;
|
||||||
IStorage *presentationStorage;
|
IStorage *presentationStorage;
|
||||||
|
|
||||||
|
/* list of cache entries */
|
||||||
struct list cache_list;
|
struct list cache_list;
|
||||||
|
|
||||||
/* last id assigned to an entry */
|
/* last id assigned to an entry */
|
||||||
DWORD last_cache_id;
|
DWORD last_cache_id;
|
||||||
|
/* dirty flag */
|
||||||
|
BOOL dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DataCache DataCache;
|
typedef struct DataCache DataCache;
|
||||||
|
@ -257,6 +258,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
|
||||||
(*cache_entry)->stgmedium.pUnkForRelease = NULL;
|
(*cache_entry)->stgmedium.pUnkForRelease = NULL;
|
||||||
(*cache_entry)->storage = NULL;
|
(*cache_entry)->storage = NULL;
|
||||||
(*cache_entry)->id = This->last_cache_id++;
|
(*cache_entry)->id = This->last_cache_id++;
|
||||||
|
(*cache_entry)->dirty = TRUE;
|
||||||
list_add_tail(&This->cache_list, &(*cache_entry)->entry);
|
list_add_tail(&This->cache_list, &(*cache_entry)->entry);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -557,6 +559,7 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
|
||||||
static HRESULT DataCacheEntry_SetData(DataCacheEntry *This,
|
static HRESULT DataCacheEntry_SetData(DataCacheEntry *This,
|
||||||
STGMEDIUM *stgmedium, BOOL fRelease)
|
STGMEDIUM *stgmedium, BOOL fRelease)
|
||||||
{
|
{
|
||||||
|
This->dirty = TRUE;
|
||||||
ReleaseStgMedium(&This->stgmedium);
|
ReleaseStgMedium(&This->stgmedium);
|
||||||
if (fRelease)
|
if (fRelease)
|
||||||
{
|
{
|
||||||
|
@ -1052,17 +1055,24 @@ static HRESULT WINAPI DataCache_GetClassID(
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* DataCache_IsDirty (IPersistStorage)
|
* 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.
|
* See Windows documentation for more details on IPersistStorage methods.
|
||||||
*/
|
*/
|
||||||
static HRESULT WINAPI DataCache_IsDirty(
|
static HRESULT WINAPI DataCache_IsDirty(
|
||||||
IPersistStorage* iface)
|
IPersistStorage* iface)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", iface);
|
DataCache *This = impl_from_IPersistStorage(iface);
|
||||||
|
DataCacheEntry *cache_entry;
|
||||||
|
|
||||||
return S_FALSE;
|
TRACE("(%p)\n", iface);
|
||||||
|
|
||||||
|
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,
|
IPersistStorage* iface,
|
||||||
IStorage* pStg)
|
IStorage* pStg)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %p)\n", iface, pStg);
|
DataCache *This = impl_from_IPersistStorage(iface);
|
||||||
|
|
||||||
return IPersistStorage_Load(iface, pStg);
|
TRACE("(%p, %p)\n", iface, pStg);
|
||||||
|
|
||||||
|
if (This->presentationStorage != NULL)
|
||||||
|
IStorage_Release(This->presentationStorage);
|
||||||
|
|
||||||
|
This->presentationStorage = 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);
|
if (cache_entry->storage) IStorage_Release(cache_entry->storage);
|
||||||
cache_entry->storage = pStg;
|
cache_entry->storage = pStg;
|
||||||
IStorage_AddRef(pStg);
|
IStorage_AddRef(pStg);
|
||||||
|
cache_entry->dirty = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,6 +1179,8 @@ static HRESULT WINAPI DataCache_Load(
|
||||||
CoTaskMemFree(elem.pwcsName);
|
CoTaskMemFree(elem.pwcsName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
This->dirty = FALSE;
|
||||||
|
|
||||||
IEnumSTATSTG_Release(pEnum);
|
IEnumSTATSTG_Release(pEnum);
|
||||||
|
|
||||||
IStorage_AddRef(This->presentationStorage);
|
IStorage_AddRef(This->presentationStorage);
|
||||||
|
@ -1179,21 +1202,37 @@ static HRESULT WINAPI DataCache_Save(
|
||||||
IStorage* pStg,
|
IStorage* pStg,
|
||||||
BOOL fSameAsLoad)
|
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) &&
|
dirty = This->dirty;
|
||||||
(this->presentationStorage!=NULL) )
|
if (!dirty)
|
||||||
{
|
{
|
||||||
return IStorage_CopyTo(this->presentationStorage,
|
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
|
||||||
0,
|
{
|
||||||
NULL,
|
dirty = cache_entry->dirty;
|
||||||
NULL,
|
if (dirty)
|
||||||
pStg);
|
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->sinkInterface = 0;
|
||||||
newObject->presentationStorage = NULL;
|
newObject->presentationStorage = NULL;
|
||||||
list_init(&newObject->cache_list);
|
list_init(&newObject->cache_list);
|
||||||
|
newObject->last_cache_id = 1;
|
||||||
|
newObject->dirty = FALSE;
|
||||||
|
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1105,9 +1105,7 @@ static void test_data_cache(void)
|
||||||
ok_ole_success(hr, "IPersistStorage_InitNew");
|
ok_ole_success(hr, "IPersistStorage_InitNew");
|
||||||
|
|
||||||
hr = IPersistStorage_IsDirty(pPS);
|
hr = IPersistStorage_IsDirty(pPS);
|
||||||
todo_wine {
|
|
||||||
ok_ole_success(hr, "IPersistStorage_IsDirty");
|
ok_ole_success(hr, "IPersistStorage_IsDirty");
|
||||||
}
|
|
||||||
|
|
||||||
hr = IPersistStorage_GetClassID(pPS, &clsid);
|
hr = IPersistStorage_GetClassID(pPS, &clsid);
|
||||||
ok_ole_success(hr, "IPersistStorage_GetClassID");
|
ok_ole_success(hr, "IPersistStorage_GetClassID");
|
||||||
|
|
Loading…
Reference in New Issue