⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datacache.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
  {
    *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 + -