Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
12 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // olecache.h
  5. //
  6. // Contents:
  7. // Better implementation of Ole presentation cache
  8. //
  9. // Classes:
  10. // COleCache - ole presentation cache
  11. // CCacheEnum - enumerator for COleCache
  12. //
  13. // Functions:
  14. //
  15. // History:
  16. // Gopalk Creation Aug 23, 1996
  17. //-----------------------------------------------------------------------------
  18. #ifndef _OLECACHE_H_
  19. #define _OLECACHE_H_
  20. #include <cachenod.h>
  21. #include <array.hxx>
  22. //+----------------------------------------------------------------------------
  23. //
  24. // Class:
  25. // COleCache
  26. //
  27. // Purpose:
  28. // Ole presentation cache maintains the presentations for
  29. // one embedding.
  30. //
  31. // For every unique FORMATETC, a cache node is created; cache
  32. // nodes encapsulate a presentation object and advise sink.
  33. //
  34. // COleCache handles persistence of cache nodes, saving (loading)
  35. // their presentation objects, format descriptions, and advise
  36. // options.
  37. //
  38. // Interface:
  39. // IUnknown (public IUnknown for aggregation purposes)
  40. // IOleCacheControl
  41. // IOleCache2
  42. // IPersistStorage
  43. // IViewObject2
  44. // IDataObject
  45. // m_UnkPrivate
  46. // the private IUnknown for aggregation purposes
  47. //
  48. // INTERNAL GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel);
  49. // returns the size of the aspect indicated
  50. //
  51. // Private Interface used by friend classes:
  52. // INTERNAL_(void) OnChange(DWORD dwAspect, LONG lindex,
  53. // BOOL fDirty);
  54. // CCacheNode instances use this to alert the cache to
  55. // changes to themselves so that the cache can be
  56. // marked dirty, if that is necessary
  57. // INTERNAL_(LPSTORAGE) GetStg(void);
  58. // CCacheNode uses this to obtain storage when cache
  59. // nodes are being saved
  60. //
  61. // INTERNAL_(void) DetachCacheEnum(CCacheEnum FAR* pCacheEnum);
  62. // When about to be destroyed, CCacheEnum instances
  63. // use this to request to be taken off
  64. // the list of cache enumerators that COleCache
  65. // maintains.
  66. //
  67. // Notes:
  68. // The constructor returns a pointer to the public IUnknown
  69. // of the object. The private one is available at m_UnkPrivate.
  70. //
  71. // The cache maintains its contents in an array. Ids of the
  72. // cache nodes, such as those returned from Cache(), start out
  73. // being the index of the node in the array. To detect
  74. // reuse of an array element, each id is incremented by the maximum
  75. // size of the array each time it is reused. To find an element by
  76. // id simply take (id % max_array_size). (id / max_array_size)
  77. // gives the number of times the array element has been used to
  78. // cache data. (We do not allocate all the array members at once,
  79. // but instead grow the array on demand, up to the maximum
  80. // compile-time array size, MAX_CACHELIST_ITEMS.)
  81. // If id's do not match
  82. // exactly, before taking the modulo value, we know that a
  83. // request has been made for an earlier generation of data that
  84. // no longer exists.
  85. //
  86. // The cache automatically maintains a "native format" node.
  87. // This node cannot be deleted by the user, and is always kept
  88. // up to date on disk. This node attempts to keep either a
  89. // CF_METAFILEPICT, or CF_DIB rendering, with preference in
  90. // this order.
  91. // REVIEW, it's not clear how this node ever gets loaded.
  92. //
  93. // History:
  94. // 31-Jan-95 t-ScottH add Dump method (_DEBUG only)
  95. // 11/15/93 - ChrisWe - file inspection and cleanup;
  96. // removed use of nested classes where possible;
  97. // got rid of obsolete declaration of GetOlePresStream;
  98. // moved presentation stream limits to ole2int.h;
  99. // coalesced many BOOL flags into a single unsigned
  100. // quantity
  101. //
  102. //-----------------------------------------------------------------------------
  103. // declare the array of cache node pointers
  104. // COleCache will maintain an array of these
  105. #define COLECACHEF_LOADEDSTATE 0x00000001
  106. #define COLECACHEF_NOSCRIBBLEMODE 0x00000002
  107. #define COLECACHEF_PBRUSHORMSDRAW 0x00000004
  108. #define COLECACHEF_STATIC 0x00000008
  109. #define COLECACHEF_FORMATKNOWN 0x00000010
  110. #define COLECACHEF_OUTOFMEMORY 0x00000020
  111. #define COLECACHEF_HANDSOFSTORAGE 0x00000040
  112. #define COLECACHEF_CLEANEDUP 0x00000080
  113. #define COLECACHEF_SAMEASLOAD 0x00000100
  114. #define COLECACHEF_APICREATE 0x00000200
  115. #ifdef _DEBUG
  116. // In debug builds, this flag is set if aggregated
  117. #define COLECACHEF_AGGREGATED 0x00001000
  118. #endif // _DEBUG
  119. // The following flag is used for clearing out native COLECACHE FLAGS.
  120. // Remember to update the following when native formats are either
  121. // added or removed
  122. #define COLECACHEF_NATIVEFLAGS (COLECACHEF_STATIC | \
  123. COLECACHEF_FORMATKNOWN | \
  124. COLECACHEF_PBRUSHORMSDRAW)
  125. // TOC signature
  126. #define TOCSIGNATURE 1229865294
  127. class COleCache : public IOleCacheControl, public IOleCache2,
  128. public IPersistStorage, public CRefExportCount,
  129. public CThreadCheck
  130. {
  131. public:
  132. COleCache(IUnknown* pUnkOuter, REFCLSID rclsid, DWORD dwCreateFlags=0);
  133. ~COleCache();
  134. // *** IUnknown methods ***
  135. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  136. STDMETHOD_(ULONG,AddRef)(void) ;
  137. STDMETHOD_(ULONG,Release)(void);
  138. // *** IOleCacheControl methods ***
  139. STDMETHOD(OnRun)(LPDATAOBJECT pDataObject);
  140. STDMETHOD(OnStop)(void);
  141. // *** IOleCache methods ***
  142. STDMETHOD(Cache)(LPFORMATETC lpFormatetc, DWORD advf, LPDWORD lpdwCacheId);
  143. STDMETHOD(Uncache)(DWORD dwCacheId);
  144. STDMETHOD(EnumCache)(LPENUMSTATDATA* ppenumStatData);
  145. STDMETHOD(InitCache)(LPDATAOBJECT pDataObject);
  146. STDMETHOD(SetData)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium, BOOL fRelease);
  147. // *** IOleCache2 methods ***
  148. STDMETHOD(UpdateCache)(LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved);
  149. STDMETHOD(DiscardCache)(DWORD dwDiscardOptions);
  150. // IPersist methods
  151. STDMETHOD(GetClassID)(LPCLSID pClassID);
  152. // IPersistStorage methods
  153. STDMETHOD(IsDirty)(void);
  154. STDMETHOD(InitNew)(LPSTORAGE pstg);
  155. STDMETHOD(Load)(LPSTORAGE pstg);
  156. STDMETHOD(Save)(LPSTORAGE pstgSave, BOOL fSameAsLoad);
  157. STDMETHOD(SaveCompleted)(LPSTORAGE pstgNew);
  158. STDMETHOD(HandsOffStorage)(void);
  159. // Other public methods, called by defhndlr and deflink
  160. HRESULT GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel);
  161. HRESULT Load(LPSTORAGE pstg, BOOL fCacheEmpty);
  162. HRESULT OnCrash();
  163. BOOL IsEmpty() {
  164. return(!m_pCacheArray->Length());
  165. }
  166. // Private IUnknown used in aggregation.
  167. // This has been implemented as a nested class because of
  168. // the member name collisions with the outer IUnknown.
  169. class CCacheUnkImpl : public IUnknown
  170. {
  171. public:
  172. // *** IUnknown methods ***
  173. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  174. STDMETHOD_(ULONG,AddRef)(void) ;
  175. STDMETHOD_(ULONG,Release)(void);
  176. };
  177. friend class CCacheUnkImpl;
  178. CCacheUnkImpl m_UnkPrivate; // vtable for private IUnknown
  179. // IDataObject implementation of the cache.
  180. // This has been implemented as a nested class because
  181. // IDataObject::SetData collides with IOleCache::SetData
  182. class CCacheDataImpl : public IDataObject
  183. {
  184. public:
  185. // IUnknown methods
  186. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  187. STDMETHOD_(ULONG,AddRef)(void);
  188. STDMETHOD_(ULONG,Release)(void);
  189. // IDataObject methods
  190. STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
  191. STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
  192. STDMETHOD(QueryGetData)(LPFORMATETC pformatetc);
  193. STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc,
  194. LPFORMATETC pformatetcOut);
  195. STDMETHOD(SetData)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium, BOOL fRelease);
  196. STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppenumFormatEtc);
  197. STDMETHOD(DAdvise)(FORMATETC* pFormatetc, DWORD advf, IAdviseSink* pAdvSink,
  198. DWORD* pdwConnection);
  199. STDMETHOD(DUnadvise)(DWORD dwConnection);
  200. STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppenumAdvise);
  201. };
  202. friend class CCacheDataImpl;
  203. CCacheDataImpl m_Data; // vtable for IDataObject
  204. // Other public methods
  205. BOOL IsOutOfMemory() {
  206. return(m_ulFlags & COLECACHEF_OUTOFMEMORY);
  207. }
  208. private:
  209. // Private methods
  210. LPCACHENODE Locate(LPFORMATETC lpGivenForEtc, DWORD* lpdwCacheId=NULL);
  211. LPCACHENODE Locate(DWORD dwAspect, LONG lindex, DVTARGETDEVICE* ptd);
  212. LPCACHENODE UpdateCacheNodeForNative(void);
  213. void FindObjectFormat(LPSTORAGE pstg);
  214. HRESULT LoadTOC(LPSTREAM lpstream, LPSTORAGE pStg);
  215. HRESULT SaveTOC(LPSTORAGE pStg, BOOL fSameAsLoad);
  216. void AspectsUpdated(DWORD dwAspect);
  217. void CleanupFn(void);
  218. // IViewObject2 implementation of cache.
  219. // This has been implemented as a nested class because GetExtent
  220. // collides with the method on COleCache
  221. class CCacheViewImpl : public IViewObject2
  222. {
  223. public:
  224. // IUnknown methods
  225. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  226. STDMETHOD_(ULONG,AddRef)(void);
  227. STDMETHOD_(ULONG,Release)(void);
  228. // IViewObject methods
  229. STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex,
  230. void FAR* pvAspect, DVTARGETDEVICE FAR* ptd,
  231. HDC hicTargetDev, HDC hdcDraw,
  232. LPCRECTL lprcBounds,
  233. LPCRECTL lprcWBounds,
  234. BOOL(CALLBACK *pfnContinue)(ULONG_PTR),
  235. ULONG_PTR dwContinue);
  236. STDMETHOD(GetColorSet)(DWORD dwDrawAspect, LONG lindex, void* pvAspect,
  237. DVTARGETDEVICE* ptd, HDC hicTargetDev,
  238. LPLOGPALETTE* ppColorSet);
  239. STDMETHOD(Freeze)(DWORD dwDrawAspect, LONG lindex, void* pvAspect,
  240. DWORD* pdwFreeze);
  241. STDMETHOD(Unfreeze)(DWORD dwFreeze);
  242. STDMETHOD(SetAdvise)(DWORD aspects, DWORD advf, LPADVISESINK pAdvSink);
  243. STDMETHOD(GetAdvise)(DWORD* pAspects, DWORD* pAdvf, LPADVISESINK* ppAdvSink);
  244. // IViewObject2 methods
  245. STDMETHOD(GetExtent)(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE* ptd,
  246. LPSIZEL lpsizel);
  247. };
  248. friend class CCacheViewImpl;
  249. CCacheViewImpl m_ViewObject; // vtable for IViewObject2
  250. // IAdviseSink implementation
  251. // This has been implemented as a nested class because of the need that
  252. // the QueryInterface method on the Advise Sink should not return
  253. // cache interfaces
  254. class CAdviseSinkImpl : public IAdviseSink
  255. {
  256. public:
  257. // IUnknown methods
  258. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  259. STDMETHOD_(ULONG,AddRef)(void);
  260. STDMETHOD_(ULONG,Release)(void);
  261. // IAdviseSink methods
  262. STDMETHOD_(void,OnDataChange)(FORMATETC* pFormatetc, STGMEDIUM* pStgmed);
  263. STDMETHOD_(void,OnViewChange)(DWORD aspect, LONG lindex);
  264. STDMETHOD_(void,OnRename)(IMoniker* pmk);
  265. STDMETHOD_(void,OnSave)(void);
  266. STDMETHOD_(void,OnClose)(void);
  267. };
  268. friend class CAdviseSinkImpl;
  269. CAdviseSinkImpl m_AdviseSink;
  270. // Private member variables
  271. IUnknown* m_pUnkOuter; // Aggregating IUnknown
  272. LPSTORAGE m_pStg; // Storage for cache
  273. CLSID m_clsid; // CLSID of object
  274. CLIPFORMAT m_cfFormat; // Native clipformat of the object
  275. unsigned long m_ulFlags; // Cache flags
  276. CArray<CCacheNode>* m_pCacheArray; // Cache array
  277. IAdviseSink* m_pViewAdvSink; // IViewObject Advise Sink
  278. DWORD m_advfView; // IViewObject Advise control flags
  279. DWORD m_aspectsView; // Aspects notified for view changes
  280. DWORD m_dwFrozenAspects; // Frozen Aspects
  281. IDataObject* m_pDataObject; // non-NULL if running; not ref counted
  282. };
  283. #endif //_OLECACHE_H_