📄 datacache.c
字号:
{
*ppvObject = (IOleCacheControl*)&(this->lpvtblIOleCacheControl);
}
/*
* Check that we obtained an interface.
*/
if ((*ppvObject)==0)
{
WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
/*
* Query Interface always increases the reference count by one when it is
* successful.
*/
IUnknown_AddRef((IUnknown*)*ppvObject);
return S_OK;
}
/************************************************************************
* DataCache_NDIUnknown_AddRef (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*
* This version of QueryInterface will not delegate it's implementation
* to the outer unknown.
*/
static ULONG WINAPI DataCache_NDIUnknown_AddRef(
IUnknown* iface)
{
DataCache *this = impl_from_NDIUnknown(iface);
return InterlockedIncrement(&this->ref);
}
/************************************************************************
* DataCache_NDIUnknown_Release (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*
* This version of QueryInterface will not delegate it's implementation
* to the outer unknown.
*/
static ULONG WINAPI DataCache_NDIUnknown_Release(
IUnknown* iface)
{
DataCache *this = impl_from_NDIUnknown(iface);
ULONG ref;
/*
* Decrease the reference count on this object.
*/
ref = InterlockedDecrement(&this->ref);
/*
* If the reference count goes down to 0, perform suicide.
*/
if (ref == 0) DataCache_Destroy(this);
return ref;
}
/*********************************************************
* Method implementation for the IDataObject
* part of the DataCache class.
*/
/************************************************************************
* DataCache_IDataObject_QueryInterface (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
IDataObject* iface,
REFIID riid,
void** ppvObject)
{
DataCache *this = impl_from_IDataObject(iface);
return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
}
/************************************************************************
* DataCache_IDataObject_AddRef (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IDataObject_AddRef(
IDataObject* iface)
{
DataCache *this = impl_from_IDataObject(iface);
return IUnknown_AddRef(this->outerUnknown);
}
/************************************************************************
* DataCache_IDataObject_Release (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IDataObject_Release(
IDataObject* iface)
{
DataCache *this = impl_from_IDataObject(iface);
return IUnknown_Release(this->outerUnknown);
}
/************************************************************************
* DataCache_GetData
*
* Get Data from a source dataobject using format pformatetcIn->cfFormat
* See Windows documentation for more details on GetData.
*/
static HRESULT WINAPI DataCache_GetData(
IDataObject* iface,
LPFORMATETC pformatetcIn,
STGMEDIUM* pmedium)
{
DataCache *This = impl_from_IDataObject(iface);
DataCacheEntry *cache_entry;
memset(pmedium, 0, sizeof(*pmedium));
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetcIn);
if (!cache_entry)
return OLE_E_BLANK;
return DataCacheEntry_GetData(cache_entry, pmedium);
}
static HRESULT WINAPI DataCache_GetDataHere(
IDataObject* iface,
LPFORMATETC pformatetc,
STGMEDIUM* pmedium)
{
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DataCache_QueryGetData(
IDataObject* iface,
LPFORMATETC pformatetc)
{
FIXME("stub\n");
return E_NOTIMPL;
}
/************************************************************************
* DataCache_EnumFormatEtc (IDataObject)
*
* The data cache doesn't implement this method.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
IDataObject* iface,
LPFORMATETC pformatectIn,
LPFORMATETC pformatetcOut)
{
TRACE("()\n");
return E_NOTIMPL;
}
/************************************************************************
* DataCache_IDataObject_SetData (IDataObject)
*
* This method is delegated to the IOleCache2 implementation.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_IDataObject_SetData(
IDataObject* iface,
LPFORMATETC pformatetc,
STGMEDIUM* pmedium,
BOOL fRelease)
{
IOleCache2* oleCache = NULL;
HRESULT hres;
TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
if (FAILED(hres))
return E_UNEXPECTED;
hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
IOleCache2_Release(oleCache);
return hres;
}
/************************************************************************
* DataCache_EnumFormatEtc (IDataObject)
*
* The data cache doesn't implement this method.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_EnumFormatEtc(
IDataObject* iface,
DWORD dwDirection,
IEnumFORMATETC** ppenumFormatEtc)
{
TRACE("()\n");
return E_NOTIMPL;
}
/************************************************************************
* DataCache_DAdvise (IDataObject)
*
* The data cache doesn't support connections.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_DAdvise(
IDataObject* iface,
FORMATETC* pformatetc,
DWORD advf,
IAdviseSink* pAdvSink,
DWORD* pdwConnection)
{
TRACE("()\n");
return OLE_E_ADVISENOTSUPPORTED;
}
/************************************************************************
* DataCache_DUnadvise (IDataObject)
*
* The data cache doesn't support connections.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_DUnadvise(
IDataObject* iface,
DWORD dwConnection)
{
TRACE("()\n");
return OLE_E_NOCONNECTION;
}
/************************************************************************
* DataCache_EnumDAdvise (IDataObject)
*
* The data cache doesn't support connections.
*
* See Windows documentation for more details on IDataObject methods.
*/
static HRESULT WINAPI DataCache_EnumDAdvise(
IDataObject* iface,
IEnumSTATDATA** ppenumAdvise)
{
TRACE("()\n");
return OLE_E_ADVISENOTSUPPORTED;
}
/*********************************************************
* Method implementation for the IDataObject
* part of the DataCache class.
*/
/************************************************************************
* DataCache_IPersistStorage_QueryInterface (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
IPersistStorage* iface,
REFIID riid,
void** ppvObject)
{
DataCache *this = impl_from_IPersistStorage(iface);
return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
}
/************************************************************************
* DataCache_IPersistStorage_AddRef (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IPersistStorage_AddRef(
IPersistStorage* iface)
{
DataCache *this = impl_from_IPersistStorage(iface);
return IUnknown_AddRef(this->outerUnknown);
}
/************************************************************************
* DataCache_IPersistStorage_Release (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IPersistStorage_Release(
IPersistStorage* iface)
{
DataCache *this = impl_from_IPersistStorage(iface);
return IUnknown_Release(this->outerUnknown);
}
/************************************************************************
* DataCache_GetClassID (IPersistStorage)
*
* The data cache doesn't implement this method.
*
* See Windows documentation for more details on IPersistStorage methods.
*/
static HRESULT WINAPI DataCache_GetClassID(
IPersistStorage* iface,
CLSID* pClassID)
{
DataCache *This = impl_from_IPersistStorage(iface);
DataCacheEntry *cache_entry;
TRACE("(%p, %p)\n", iface, pClassID);
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
if (cache_entry->storage != NULL)
{
STATSTG statstg;
HRESULT hr = IStorage_Stat(cache_entry->storage, &statstg, STATFLAG_NONAME);
if (SUCCEEDED(hr))
{
memcpy(pClassID, &statstg.clsid, sizeof(*pClassID));
return S_OK;
}
}
}
memcpy(pClassID, &CLSID_NULL, sizeof(*pClassID));
return S_OK;
}
/************************************************************************
* DataCache_IsDirty (IPersistStorage)
*
* See Windows documentation for more details on IPersistStorage methods.
*/
static HRESULT WINAPI DataCache_IsDirty(
IPersistStorage* iface)
{
DataCache *This = impl_from_IPersistStorage(iface);
DataCacheEntry *cache_entry;
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;
}
/************************************************************************
* DataCache_InitNew (IPersistStorage)
*
* The data cache implementation of IPersistStorage_InitNew simply stores
* the storage pointer.
*
* See Windows documentation for more details on IPersistStorage methods.
*/
static HRESULT WINAPI DataCache_InitNew(
IPersistStorage* iface,
IStorage* pStg)
{
DataCache *This = impl_from_IPersistStorage(iface);
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;
}
/************************************************************************
* DataCache_Load (IPersistStorage)
*
* The data cache implementation of IPersistStorage_Load doesn't
* actually load anything. Instead, it holds on to the storage pointer
* and it will load the presentation information when the
* IDataObject_GetData or IViewObject2_Draw methods are called.
*
* See Windows documentation for more details on IPersistStorage methods.
*/
static HRESULT WINAPI DataCache_Load(
IPersistStorage* iface,
IStorage* pStg)
{
DataCache *This = impl_from_IPersistStorage(iface);
STATSTG elem;
IEnumSTATSTG *pEnum;
HRESULT hr;
TRACE("(%p, %p)\n", iface, pStg);
if (This->presentationStorage != NULL)
IStorage_Release(This->presentationStorage);
This->presentationStorage = pStg;
hr = IStorage_EnumElements(pStg, 0, NULL, 0, &pEnum);
if (FAILED(hr)) return hr;
while ((hr = IEnumSTATSTG_Next(pEnum, 1, &elem, NULL)) == S_OK)
{
if (DataCache_IsPresentationStream(&elem))
{
IStream *pStm;
hr = IStorage_OpenStream(This->presentationStorage, elem.pwcsName,
NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0,
&pStm);
if (SUCCEEDED(hr))
{
PresentationDataHeader header;
ULONG actual_read;
CLIPFORMAT clipformat;
hr = read_clipformat(pStm, &clipformat);
if (hr == S_OK)
hr = IStream_Read(pStm, &header, sizeof(header),
&actual_read);
/* can't use SUCCEEDED(hr): S_FALSE counts as an error */
if (hr == S_OK && actual_read == sizeof(header))
{
DataCacheEntry *cache_entry;
FORMATETC fmtetc;
fmtetc.cfFormat = clipformat;
fmtetc.ptd = NULL; /* FIXME */
fmtetc.dwAspect = header.dvAspect;
fmtetc.lindex = header.lindex;
fmtetc.tymed = header.tymed;
TRACE("loading entry with formatetc: %s\n", debugstr_formatetc(&fmtetc));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -