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.

2283 lines
74 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // cachenode.cpp
  5. //
  6. // Classes:
  7. // CCacheNode
  8. //
  9. // Functions:
  10. //
  11. // History:
  12. // Gopalk Creation Aug 23, 1996
  13. //-----------------------------------------------------------------------------
  14. #include <le2int.h>
  15. #include <olepres.h>
  16. #include <cachenod.h>
  17. #include <mf.h>
  18. #include <emf.h>
  19. #include <gen.h>
  20. // forward declaration
  21. HRESULT wGetData(LPDATAOBJECT lpSrcDataObj, LPFORMATETC lpforetc,
  22. LPSTGMEDIUM lpmedium);
  23. //+----------------------------------------------------------------------------
  24. //
  25. // Member:
  26. // CCacheNode::Initialize, private
  27. //
  28. // Synopsis:
  29. // Routine used by the CCacheNode constructors to do common
  30. // initialization.
  31. //
  32. // Arguments:
  33. // [advf] -- ADVF flag
  34. // [pOleCache] -- COleCache this cache node belongs to
  35. //
  36. // Notes:
  37. // [pOleCache] is not reference counted; the cache node is
  38. // considered to be a part of the implementation of COleCache,
  39. // and is owned by COleCache.
  40. //
  41. // History:
  42. // 13-Feb-95 t-ScottH initialize m_dwPresBitsPos and new
  43. // data member m_dwPresFlag
  44. // 11/05/93 - ChrisWe - file inspection and cleanup
  45. //
  46. //-----------------------------------------------------------------------------
  47. void CCacheNode::Initialize(DWORD advf, LPSTORAGE pStg)
  48. {
  49. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Initialize(%lx, %p)\n",
  50. this, advf, pStg));
  51. // initialize member variables
  52. m_clsid = CLSID_NULL;
  53. m_advf = advf;
  54. m_lWidth = 0;
  55. m_lHeight = 0;
  56. m_dwFlags = 0;
  57. m_pStg = pStg;
  58. m_iStreamNum = OLE_INVALID_STREAMNUM;
  59. m_dwPresBitsPos = 0;
  60. m_fConvert = FALSE;
  61. m_pPresObj = NULL;
  62. m_pPresObjAfterFreeze = NULL;
  63. m_pDataObject = NULL;
  64. m_dwAdvConnId = 0;
  65. #ifdef _DEBUG
  66. m_dwPresFlag = 0;
  67. #endif // _DEBUG
  68. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Initialize()\n", this));
  69. return;
  70. }
  71. //+----------------------------------------------------------------------------
  72. //
  73. // Member:
  74. // CCacheNode::CCacheNode, public
  75. //
  76. // Synopsis:
  77. // Constructor - use this constructor when the cache node is
  78. // to be loaded later
  79. //
  80. // Arguments:
  81. // [pOleCache] -- pointer to the COleCache that owns this node
  82. //
  83. // Notes:
  84. //
  85. // History:
  86. // 11/05/93 - ChrisWe - file inspection and cleanup
  87. //
  88. //-----------------------------------------------------------------------------
  89. CCacheNode::CCacheNode()
  90. {
  91. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::CacheNode()\n", this));
  92. m_foretc.cfFormat = 0;
  93. m_foretc.ptd = NULL;
  94. m_foretc.dwAspect = 0;
  95. m_foretc.lindex = DEF_LINDEX;
  96. m_foretc.tymed = TYMED_HGLOBAL;
  97. Initialize(0, NULL);
  98. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::CacheNode()\n", this));
  99. }
  100. //+----------------------------------------------------------------------------
  101. //
  102. // Member:
  103. // CCacheNode::CCacheNode, public
  104. //
  105. // Synopsis:
  106. // constructor - use this constructor when all the data to
  107. // initialize the cache node is available now
  108. //
  109. // Arguments:
  110. // [lpFormatEtc] - the format for the presentation that this
  111. // cache node will hold
  112. // [advf] - the advise control flags, from ADVF_*
  113. // [pOleCache] -- pointer to the COleCache that owns this node
  114. //
  115. // Notes:
  116. //
  117. // History:
  118. // 11/05/93 - ChrisWe - file inspection and cleanup
  119. //
  120. //-----------------------------------------------------------------------------
  121. CCacheNode::CCacheNode(LPFORMATETC lpFormatEtc, DWORD advf, LPSTORAGE pStg)
  122. {
  123. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::CacheNode(%p, %lx, %p)\n",
  124. this, lpFormatEtc, advf, pStg));
  125. UtCopyFormatEtc(lpFormatEtc, &m_foretc);
  126. BITMAP_TO_DIB(m_foretc);
  127. Initialize(advf, pStg);
  128. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::CacheNode()\n", this));
  129. }
  130. //+----------------------------------------------------------------------------
  131. //
  132. // Member:
  133. // CCacheNode::~CCacheNode, private
  134. //
  135. // Synopsis:
  136. // destructor
  137. //
  138. // Notes:
  139. //
  140. // History:
  141. // 11/05/93 - ChrisWe - file inspection and cleanup
  142. //
  143. //-----------------------------------------------------------------------------
  144. CCacheNode::~CCacheNode()
  145. {
  146. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::~CacheNode()\n", this ));
  147. // Destroy the presentation objects
  148. if(m_pPresObj) {
  149. m_pPresObj->Release();
  150. m_pPresObj = NULL;
  151. }
  152. if(m_pPresObjAfterFreeze) {
  153. m_pPresObjAfterFreeze->Release();
  154. m_pPresObjAfterFreeze = NULL;
  155. }
  156. // Delete the ptd if it is non-null
  157. if(m_foretc.ptd) {
  158. PubMemFree(m_foretc.ptd);
  159. m_foretc.ptd = NULL;
  160. }
  161. // Assert that there is no pending advise connection
  162. Win4Assert(!m_dwAdvConnId);
  163. if(m_dwAdvConnId) {
  164. Win4Assert(m_pDataObject);
  165. TearDownAdviseConnection(m_pDataObject);
  166. }
  167. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::~CacheNode()\n", this));
  168. }
  169. //+----------------------------------------------------------------------------
  170. //
  171. // Member:
  172. // CCacheNode::SetStg, public
  173. //
  174. // Synopsis:
  175. // Set storage in which the presentation gets saved
  176. //
  177. // Arguments:
  178. // [pStg] -- Storage pointer
  179. //
  180. // Returns:
  181. // OLE_E_ALREADY_INITIALIZED or NOERROR
  182. //
  183. // History:
  184. // Gopalk Creation Aug 26, 1996
  185. //
  186. //-----------------------------------------------------------------------------
  187. HRESULT CCacheNode::SetStg(LPSTORAGE pStg)
  188. {
  189. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::SetStg(%p)\n", this, pStg));
  190. HRESULT error;
  191. if(m_pStg) {
  192. error = CO_E_ALREADYINITIALIZED;
  193. Win4Assert(FALSE);
  194. }
  195. else {
  196. // Save the storage without addref
  197. m_pStg = pStg;
  198. error = NOERROR;
  199. }
  200. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::SetStg(%lx)\n", this, error));
  201. return(error);
  202. }
  203. //+----------------------------------------------------------------------------
  204. //
  205. // Member:
  206. // CCacheNode::Load, public
  207. //
  208. // Synopsis:
  209. // Load a cache node from a stream; only loads the presentation
  210. // header. (REVIEW, need to see presentation object::Load)
  211. //
  212. // Arguments:
  213. // [lpstream] -- the stream to load the presentation out of
  214. // [iStreamNum] -- the stream number
  215. //
  216. // Returns:
  217. // REVIEW
  218. // DV_E_LINDEX, for invalid lindex in stream
  219. // S_OK
  220. //
  221. // Notes:
  222. // As part of the loading, the presentation object gets created,
  223. // and loaded from the stream.
  224. //
  225. // History:
  226. // 11/06/93 - ChrisWe - file inspection and cleanup
  227. //
  228. //-----------------------------------------------------------------------------
  229. HRESULT CCacheNode::Load(LPSTREAM lpstream, int iStreamNum, BOOL fDelayLoad)
  230. {
  231. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Load(%lx, %d)\n",
  232. this, lpstream, iStreamNum));
  233. HRESULT error = NOERROR;
  234. if(IsNativeCache()) {
  235. // Native Cache node
  236. // Update state
  237. SetLoadedStateFlag();
  238. ClearFrozenStateFlag();
  239. // We make the conservative assumption that the native cache
  240. // is not blank
  241. SetDataPresentFlag();
  242. }
  243. else {
  244. // Normal cache node.
  245. // Read the presentation stream header
  246. m_foretc.ptd = NULL;
  247. m_fConvert = FALSE;
  248. error = UtReadOlePresStmHeader(lpstream, &m_foretc, &m_advf, &m_fConvert);
  249. if(error==NOERROR) {
  250. // Set the starting position of pres object data
  251. SetPresBitsPos(lpstream, m_dwPresBitsPos);
  252. // Assume that the presentation is blank
  253. ClearDataPresentFlag();
  254. m_lWidth = 0;
  255. m_lHeight = 0;
  256. // Load desired state
  257. if(m_foretc.cfFormat) {
  258. if(fDelayLoad) {
  259. DWORD dwBuf[4];
  260. // Read the extent and size of presentation data
  261. dwBuf[0] = 0L;
  262. dwBuf[1] = 0L;
  263. dwBuf[2] = 0L;
  264. dwBuf[3] = 0L;
  265. error = lpstream->Read(dwBuf, sizeof(dwBuf), NULL);
  266. if(error == NOERROR) {
  267. Win4Assert(!dwBuf[0]);
  268. m_lWidth = dwBuf[1];
  269. m_lHeight = dwBuf[2];
  270. if(dwBuf[3]) {
  271. SetDataPresentFlag();
  272. Win4Assert(m_lWidth!=0 && m_lHeight!=0);
  273. }
  274. else {
  275. Win4Assert(m_lWidth==0 && m_lHeight==0);
  276. }
  277. }
  278. }
  279. else {
  280. // Create the pres object
  281. error = CreateOlePresObj(&m_pPresObj, m_fConvert);
  282. // Load the data into pres object
  283. if(error == NOERROR)
  284. error = m_pPresObj->Load(lpstream, FALSE);
  285. // Update data present flag
  286. if(!m_pPresObj->IsBlank())
  287. SetDataPresentFlag();
  288. }
  289. }
  290. // Update rest of state
  291. if(error == NOERROR) {
  292. SetLoadedStateFlag();
  293. SetLoadedCacheFlag();
  294. ClearFrozenStateFlag();
  295. m_iStreamNum = iStreamNum;
  296. }
  297. }
  298. // Clean up if presentation could not be loaded
  299. if(error != NOERROR) {
  300. // Delete the ptd if it is non-null
  301. if(m_foretc.ptd)
  302. PubMemFree(m_foretc.ptd);
  303. if(m_pPresObj) {
  304. m_pPresObj->Release();
  305. m_pPresObj = NULL;
  306. }
  307. // Initialize. Gopalk
  308. INIT_FORETC(m_foretc);
  309. m_advf = 0;
  310. m_fConvert = FALSE;
  311. m_iStreamNum = OLE_INVALID_STREAMNUM;
  312. ClearLoadedStateFlag();
  313. ClearLoadedCacheFlag();
  314. ClearFrozenStateFlag();
  315. ClearDataPresentFlag();
  316. }
  317. }
  318. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Load ( %lx )\n", this, error));
  319. return error;
  320. }
  321. //+----------------------------------------------------------------------------
  322. //
  323. // Member:
  324. // CCacheNode::Save, public
  325. //
  326. // Synopsis:
  327. // Saves a cache node, including its presentation object,
  328. // to a stream.
  329. //
  330. // Arguments:
  331. // [pstgSave] -- the storage that will contain the stream
  332. // [fSameAsLoad] -- is this storage the same one we loaded from
  333. // [iStreamNum] -- the stream number to save to
  334. // [fDrawCache] -- used to indicate whether or not the cached
  335. // presentation is to be used for drawing; if false,
  336. // the presentation is discarded after saving
  337. // [fSaveIfSavedBefore] -- instructs the method to save this
  338. // cache node, even if it's been saved before
  339. // [lpCntCachesNotSaved] -- a running count of the number of
  340. // caches that have not been saved
  341. //
  342. // Returns:
  343. // REVIEW
  344. // S_OK
  345. //
  346. // Notes:
  347. //
  348. // History:
  349. // 03/10/94 - AlexT - Don't call SaveCompleted if we don't save!
  350. // (see logRtn, below)
  351. // 01/11/94 - AlexGo - fixed compile error (signed/unsigned
  352. // mismatch)
  353. // 11/06/93 - ChrisWe - file inspection and cleanup
  354. //
  355. //-----------------------------------------------------------------------------
  356. HRESULT CCacheNode::Save(LPSTORAGE pstgSave, BOOL fSameAsLoad, int iStreamNum)
  357. {
  358. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Save(%p, %lu, %d)\n",
  359. this, pstgSave, fSameAsLoad, iStreamNum));
  360. HRESULT error = NOERROR;
  361. OLECHAR szNewName[sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR)];
  362. // Create the new presentation stream name
  363. if(IsNormalCache()) {
  364. _xstrcpy(szNewName, OLE_PRESENTATION_STREAM);
  365. if(iStreamNum)
  366. UtGetPresStreamName(szNewName, iStreamNum);
  367. }
  368. if(InLoadedState() && (IsNativeCache() || m_iStreamNum>0)) {
  369. // The cache node is in loaded state
  370. // The CONTENTS stream need not be updated for both Save and SaveAs cases
  371. // when the native cache node is in loaded state because the container
  372. // does copy the CONTENTS stream before invoking SaveAs on the cache.
  373. if(IsNormalCache()) {
  374. if(fSameAsLoad) {
  375. // We are being asked to save to the current storage
  376. if(m_iStreamNum!=iStreamNum) {
  377. // We are being asked to save in to a different stream
  378. // We can rename the old stream to a new name
  379. OLECHAR szOldName[sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR)];
  380. // Assert that the new stream number is less
  381. // than the current stream number
  382. Win4Assert(m_iStreamNum>iStreamNum);
  383. // Create the old presentation stream name
  384. _xstrcpy(szOldName, OLE_PRESENTATION_STREAM);
  385. if(m_iStreamNum!=0)
  386. UtGetPresStreamName(szOldName, m_iStreamNum);
  387. // Delete the stream with the new name, if there is one
  388. pstgSave->DestroyElement(szNewName);
  389. // Rename the old stream
  390. error = pstgSave->RenameElement(szOldName, szNewName);
  391. // If NOERROR, update the state
  392. if(error==NOERROR) {
  393. m_iStreamNum = iStreamNum;
  394. SetLoadedStateFlag();
  395. }
  396. }
  397. }
  398. else {
  399. // We are being asked to save to a new storage and
  400. // we are in loaded state. We can do efficient stream copy
  401. LPSTREAM lpstream;
  402. // Open or Create the new stream in the given storage
  403. error = OpenOrCreateStream(pstgSave, szNewName, &lpstream);
  404. if(error==NOERROR) {
  405. LPSTREAM pstmSrc;
  406. // Get source stream
  407. if(pstmSrc = GetStm(FALSE /*fSeekToPresBits*/, STGM_READ)) {
  408. ULARGE_INTEGER ularge_int;
  409. // initialize to copy all of stream
  410. ULISet32(ularge_int, (DWORD)-1L);
  411. error = pstmSrc->CopyTo(lpstream, ularge_int, NULL, NULL);
  412. // release the source stream
  413. pstmSrc->Release();
  414. }
  415. // Remember the starting position of presentation bits
  416. m_dwSavedPresBitsPos = m_dwPresBitsPos;
  417. // Assuming that we opened an existing pres stream,
  418. // truncate the rest of it before releasing it
  419. StSetSize(lpstream, 0, TRUE);
  420. lpstream->Release();
  421. }
  422. }
  423. }
  424. }
  425. else {
  426. // Either the node is not in loaded state or it represents presentation 0
  427. LPOLEPRESOBJECT pPresObj;
  428. if(IsNativeCache()) {
  429. // Native cache needs to be saved in CONTENTS stream
  430. STGMEDIUM stgmed;
  431. FORMATETC foretc;
  432. // Open or Create "CONTENTS" stream
  433. error = OpenOrCreateStream(pstgSave, OLE_CONTENTS_STREAM, &stgmed.pstm);
  434. if(error==NOERROR) {
  435. stgmed.pUnkForRelease = NULL;
  436. stgmed.tymed = TYMED_ISTREAM;
  437. foretc = m_foretc;
  438. foretc.tymed = TYMED_ISTREAM;
  439. // Get the latest presentation.
  440. if(m_pPresObjAfterFreeze && !m_pPresObjAfterFreeze->IsBlank()) {
  441. Win4Assert(InFrozenState());
  442. pPresObj = m_pPresObjAfterFreeze;
  443. }
  444. else if(m_pPresObj)
  445. pPresObj = m_pPresObj;
  446. else {
  447. // PresObj has not yet been created. This happens
  448. // for newly created static presentation without a
  449. // corresponding set data.
  450. BOOL bIsBlank = IsBlank();
  451. Win4Assert(bIsBlank);
  452. if(!bIsBlank && fSameAsLoad)
  453. {
  454. error = NO_ERROR;
  455. goto scoop;
  456. }
  457. error = CreateOlePresObj(&m_pPresObj, FALSE /* fConvert */);
  458. pPresObj = m_pPresObj;
  459. }
  460. // Save the native presentation
  461. if(error==NOERROR)
  462. error = pPresObj->GetDataHere(&foretc, &stgmed);
  463. // Assuming that we opened an existing CONTENTS stream,
  464. // truncate the rest of it before releasing it
  465. StSetSize(stgmed.pstm, 0, TRUE);
  466. scoop:
  467. stgmed.pstm->Release();
  468. }
  469. }
  470. else {
  471. // Normal cache needs to be saved in PRESENTATION stream
  472. LPSTREAM lpstream;
  473. // Ensure that PresObj exists for presentation 0
  474. if(m_iStreamNum==0 && InLoadedState() &&
  475. m_foretc.cfFormat && !m_pPresObj) {
  476. // This can happen only after a discard cache. We force
  477. // load the presentation for the following save to succeed
  478. error = CreateAndLoadPresObj(FALSE);
  479. Win4Assert(error == NOERROR);
  480. }
  481. if(error == NOERROR) {
  482. // Open or Create the new stream in the given storage
  483. error = OpenOrCreateStream(pstgSave, szNewName, &lpstream);
  484. if(error == NOERROR) {
  485. // Write the presentation stream header
  486. error = UtWriteOlePresStmHeader(lpstream, &m_foretc, m_advf);
  487. if(error == NOERROR) {
  488. // Remember the starting position of presentation bits
  489. if(fSameAsLoad)
  490. SetPresBitsPos(lpstream, m_dwPresBitsPos);
  491. else
  492. SetPresBitsPos(lpstream, m_dwSavedPresBitsPos);
  493. if(m_foretc.cfFormat != NULL) {
  494. // Get the latest presentation.
  495. if(m_pPresObjAfterFreeze &&
  496. !m_pPresObjAfterFreeze->IsBlank()) {
  497. Win4Assert(InFrozenState());
  498. pPresObj = m_pPresObjAfterFreeze;
  499. }
  500. else
  501. pPresObj = m_pPresObj;
  502. // Save the presentation
  503. if(pPresObj)
  504. error = pPresObj->Save(lpstream);
  505. else {
  506. // This happens for newly created presentations that
  507. // are blank. Write header that represents blank
  508. // presentation
  509. Win4Assert(IsBlank());
  510. Win4Assert(m_iStreamNum!=0);
  511. DWORD dwBuf[4];
  512. dwBuf[0] = 0L;
  513. dwBuf[1] = 0L;
  514. dwBuf[2] = 0L;
  515. dwBuf[3] = 0L;
  516. error = lpstream->Write(dwBuf, sizeof(dwBuf), NULL);
  517. }
  518. }
  519. }
  520. // Assuming that we opened an existing pres stream, truncate the
  521. // stream to the current position and release it
  522. StSetSize(lpstream, 0, TRUE);
  523. lpstream->Release();
  524. }
  525. }
  526. }
  527. // If NOERROR and fSameAsLoad, update state
  528. if(error==NOERROR && fSameAsLoad) {
  529. SetLoadedStateFlag();
  530. if(IsNormalCache())
  531. m_iStreamNum = iStreamNum;
  532. }
  533. }
  534. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Save(%lx)\n", this, error));
  535. return error;
  536. }
  537. //+----------------------------------------------------------------------------
  538. //
  539. // Member:
  540. // CCacheNode::SetPresBitsPos, private
  541. //
  542. // Synopsis:
  543. // Sets CCacheNode::m_dwPresBitsPos to the point where the
  544. // presentation begins in the stream associated with this cache
  545. // node.
  546. //
  547. // Arguments:
  548. // [lpStream] -- the stream the cache node is being saved to
  549. //
  550. // Notes:
  551. //
  552. // History:
  553. // 11/06/93 - ChrisWe - created
  554. //
  555. //-----------------------------------------------------------------------------
  556. void CCacheNode::SetPresBitsPos(LPSTREAM lpStream, DWORD& dwPresBitsPos)
  557. {
  558. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::SetPresBitsPos(%p)\n",
  559. this, lpStream));
  560. LARGE_INTEGER large_int;
  561. ULARGE_INTEGER ularge_int;
  562. // Retrieve the current position at which the pres object data starts
  563. LISet32(large_int, 0);
  564. lpStream->Seek(large_int, STREAM_SEEK_CUR, &ularge_int);
  565. dwPresBitsPos = ularge_int.LowPart;
  566. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::SetPresBitsPos()\n", this));
  567. return;
  568. }
  569. //+----------------------------------------------------------------------------
  570. //
  571. // Member:
  572. // CCacheNode::CreatePresObject, public
  573. //
  574. // Synopsis:
  575. // Create the presentation object for the cache node. If there
  576. // is no clipboard format (cfFormat), then query the source data
  577. // object for one of our preferred formats. If there is no
  578. // source data object, no error is returned, but no presentation
  579. // is created
  580. //
  581. // Arguments:
  582. // [lpSrcDataObj] -- data object to use as the basis for the
  583. // new presentation
  584. // [fConvert] -- REVIEW, what's this for?
  585. //
  586. // Returns:
  587. //
  588. // Notes:
  589. //
  590. // History:
  591. // 11/06/93 - ChrisWe - file inspection and cleanup
  592. //
  593. //-----------------------------------------------------------------------------
  594. /* HRESULT CCacheNode::CreatePresObject(LPDATAOBJECT lpSrcDataObj, BOOL fConvert)
  595. {
  596. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::CreatePresObject(%p, %lu)\n",
  597. this, lpSrcDataObj, fConvert));
  598. // Is the nodes formatetc supported by the data object
  599. BOOL fFormatSupported = TRUE;
  600. HRESULT error = NOERROR;
  601. // Assert that pres object has not yet been created
  602. Win4Assert(!m_pPresObj);
  603. // Check whether object supports the cachenode's format. If the
  604. // cachenode format field is NULL, the query will be made for
  605. // standard formats
  606. if(lpSrcDataObj)
  607. fFormatSupported = QueryFormatSupport(lpSrcDataObj);
  608. // Create the pres object if we know the format of this node
  609. if(m_foretc.cfFormat!=NULL) {
  610. // Change BITMAP to DIB
  611. BITMAP_TO_DIB(m_foretc);
  612. error = CreateOlePresObject(&m_pPresObj, fConvert);
  613. if(error==NOERROR && !fFormatSupported)
  614. error = ResultFromScode(CACHE_S_FORMATETC_NOTSUPPORTED);
  615. }
  616. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::CreatePresObj(%lx)\n",
  617. this, error));
  618. return error;
  619. } */
  620. //+----------------------------------------------------------------------------
  621. //
  622. // Member:
  623. // CCacheNode::CreateOlePresObj, private
  624. //
  625. // Synopsis:
  626. // Creates a presentation object, according to the clipboard
  627. // format m_foretc.cfFormat
  628. //
  629. // Arguments:
  630. // [ppPresObject] -- pointer to where to return the pointer to
  631. // the newly created presentation object
  632. // [fConvert] -- REVIEW, what's this for?
  633. //
  634. // Returns:
  635. // DV_E_CLIPFORMAT, if object doesn't support one of the standard
  636. // formats
  637. // E_OUTOFMEMORY, if we can't allocate the presentation object
  638. // S_OK
  639. //
  640. // Notes:
  641. //
  642. // History:
  643. // 13-Feb-95 t-ScottH added m_dwPresFlag to track type of
  644. // IOlePresObject
  645. // 11/06/93 - ChrisWe - file inspection and cleanup
  646. //
  647. //-----------------------------------------------------------------------------
  648. HRESULT CCacheNode::CreateOlePresObj(LPOLEPRESOBJECT* ppPresObj, BOOL fConvert)
  649. {
  650. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::CreateOlePresObj(%p,%lu)\n",
  651. this, ppPresObj, fConvert));
  652. HRESULT error = NOERROR;
  653. switch(m_foretc.cfFormat)
  654. {
  655. case NULL:
  656. // Pres object cannot be created
  657. *ppPresObj = NULL;
  658. error = DV_E_CLIPFORMAT;
  659. break;
  660. case CF_METAFILEPICT:
  661. *ppPresObj = new CMfObject(NULL, m_foretc.dwAspect, fConvert);
  662. #ifdef _DEBUG
  663. // for use with debugger extensions and dump method
  664. m_dwPresFlag = CN_PRESOBJ_MF;
  665. #endif // _DEBUG
  666. break;
  667. case CF_ENHMETAFILE:
  668. *ppPresObj = new CEMfObject(NULL, m_foretc.dwAspect);
  669. #ifdef _DEBUG
  670. // for use with debugger extensions and dump method
  671. m_dwPresFlag = CN_PRESOBJ_EMF;
  672. #endif // _DEBUG
  673. break;
  674. default:
  675. *ppPresObj = new CGenObject(NULL, m_foretc.cfFormat, m_foretc.dwAspect);
  676. #ifdef _DEBUG
  677. // for use with debugger extensions and dump method
  678. m_dwPresFlag = CN_PRESOBJ_GEN;
  679. #endif // _DEBUG
  680. }
  681. if(error==NOERROR && !*ppPresObj)
  682. error = ResultFromScode(E_OUTOFMEMORY);
  683. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::CreateOlePresObj(%lx)\n",
  684. this, error));
  685. return error;
  686. }
  687. //+----------------------------------------------------------------------------
  688. //
  689. // Member:
  690. // CCacheNode::GetStm, public
  691. //
  692. // Synopsis:
  693. // Get the stream the presentation is stored in. Optionally
  694. // position the stream at the point where the presentation
  695. // data begins
  696. //
  697. // Arguments:
  698. // [fSeekToPresBits] -- position the stream so that the
  699. // presentation bits would be the next read/written
  700. // [dwStgAccess] -- the access mode (STGM_*) to open the stream
  701. // with
  702. //
  703. // Returns:
  704. // NULL, if there is no stream, or the stream cannot be opened
  705. //
  706. // Notes:
  707. //
  708. // History:
  709. // 11/06/93 - ChrisWe - file inspection and cleanup
  710. //
  711. //-----------------------------------------------------------------------------
  712. LPSTREAM CCacheNode::GetStm(BOOL fSeekToPresBits, DWORD dwStgAccess)
  713. {
  714. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::GetStm(%lu, %lx)\n",
  715. this, fSeekToPresBits, dwStgAccess));
  716. LPSTREAM pstm = NULL;
  717. OLECHAR szName[sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR)];
  718. // This function should only get called for normal cache nodes
  719. Win4Assert(IsNormalCache());
  720. Win4Assert(this!=NULL);
  721. // There has to be a valid stream number and storage
  722. if(m_iStreamNum!=OLE_INVALID_STREAMNUM && m_pStg) {
  723. // Generate the stream name
  724. _xstrcpy(szName, OLE_PRESENTATION_STREAM);
  725. if(m_iStreamNum)
  726. UtGetPresStreamName(szName, m_iStreamNum);
  727. // Attempt to open the stream
  728. if(m_pStg->OpenStream(szName, NULL, (dwStgAccess | STGM_SHARE_EXCLUSIVE),
  729. NULL, &pstm) == NOERROR) {
  730. // if we're to position the stream at the presentation, do so
  731. if(fSeekToPresBits) {
  732. LARGE_INTEGER large_int;
  733. LISet32(large_int, m_dwPresBitsPos);
  734. if(pstm->Seek(large_int, STREAM_SEEK_SET, NULL)!=NOERROR) {
  735. // We could not seek to pres object bits
  736. // Release the stream and return null
  737. pstm->Release();
  738. pstm = NULL;
  739. }
  740. }
  741. }
  742. }
  743. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::GetStm(%p)\n", this, pstm));
  744. return(pstm);
  745. }
  746. //+----------------------------------------------------------------------------
  747. //
  748. // Member:
  749. // CCacheNode::Update, public
  750. //
  751. // Synopsis:
  752. // Updates the presentation object in this cache node from
  753. // the given data object. The update is only done if the
  754. // [grfUpdf] flags match m_advf specifications, and if
  755. // there is actually a presentation to update.
  756. //
  757. // Arguments:
  758. // [lpDataObj] -- the data object to use as a source of data
  759. // [grfUpdf] -- the update control flags
  760. //
  761. // Returns:
  762. // S_FALSE
  763. // S_OK
  764. //
  765. // Notes:
  766. //
  767. // History:
  768. // 11/06/93 - ChrisWe - file inspection and cleanup
  769. //
  770. //-----------------------------------------------------------------------------
  771. HRESULT CCacheNode::Update(LPDATAOBJECT lpDataObj, DWORD grfUpdf, BOOL& fUpdated)
  772. {
  773. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Update(%p, %lx)\n",
  774. this, lpDataObj, grfUpdf));
  775. STGMEDIUM medium; // the medium of the presentation
  776. FORMATETC foretc; // the format of the presentation
  777. HRESULT error = ResultFromScode(CACHE_S_SAMECACHE);
  778. // There should be a data object for updating
  779. if(!lpDataObj) {
  780. error = ResultFromScode(E_INVALIDARG);
  781. goto errRtn;
  782. }
  783. // If cfFormat is NULL, try setting it
  784. if(!m_foretc.cfFormat) {
  785. if(QueryFormatSupport(lpDataObj)) {
  786. // We could update our cfFormat
  787. ClearLoadedStateFlag();
  788. }
  789. else {
  790. // We still could not set the cfFormat
  791. error = ResultFromScode(OLE_E_BLANK);
  792. goto errRtn;
  793. }
  794. }
  795. // Check the flags and update
  796. // If the update flag is UPDFCACHE_ONLYIFBLANK and the pres object is
  797. // is not blank, simply return
  798. if((grfUpdf & UPDFCACHE_ONLYIFBLANK) && (!IsBlank()))
  799. goto errRtn;
  800. // If the update flag UPDFCACHE_NODATACACHE is not set and the pres object
  801. // flag is ADVF_NODATA, simply return
  802. if(!(grfUpdf & UPDFCACHE_NODATACACHE) && (m_advf & ADVF_NODATA))
  803. goto errRtn;
  804. // Update if both NODATA flags are set
  805. if((grfUpdf & UPDFCACHE_NODATACACHE) && (m_advf & ADVF_NODATA))
  806. goto update;
  807. // Update if both ONSAVE flags are set
  808. if((grfUpdf & UPDFCACHE_ONSAVECACHE) && (m_advf & ADVFCACHE_ONSAVE))
  809. goto update;
  810. // Update if both ONSTOP flags are set
  811. if((grfUpdf & UPDFCACHE_ONSTOPCACHE) && (m_advf & ADVF_DATAONSTOP))
  812. goto update;
  813. // Update if this cache node is blank
  814. if((grfUpdf & UPDFCACHE_IFBLANK) && IsBlank())
  815. goto update;
  816. // Update if this is a normal cache node that gets live updates
  817. if((grfUpdf & UPDFCACHE_NORMALCACHE) &&
  818. !(m_advf & (ADVF_NODATA | ADVFCACHE_ONSAVE | ADVF_DATAONSTOP)))
  819. goto update;
  820. // If we have reached here, do not update
  821. goto errRtn;
  822. update:
  823. // Initialize the medium
  824. medium.tymed = TYMED_NULL;
  825. medium.hGlobal = NULL;
  826. medium.pUnkForRelease = NULL;
  827. // Make a copy of the desired format; this may mutate below
  828. foretc = m_foretc;
  829. // Let the object create the medium.
  830. if(wGetData(lpDataObj, &foretc, &medium) == NOERROR) {
  831. // Make the cache take the ownership of the data
  832. error = SetDataWDO(&foretc, &medium, TRUE, fUpdated, lpDataObj);
  833. if(error != NOERROR)
  834. ReleaseStgMedium(&medium);
  835. }
  836. else
  837. error = ResultFromScode(E_FAIL);
  838. errRtn:
  839. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Update(%lx)\n",this, error));
  840. return error;
  841. }
  842. //+----------------------------------------------------------------------------
  843. //
  844. // Member:
  845. // CCacheNode::SetDataWDO, public
  846. //
  847. // Synopsis:
  848. // Data is set into the presentation object, if this cache node
  849. // is not frozen. If the cache node is frozen, then the
  850. // new presentation data is stashed into the m_pPresObjAfterFreeze
  851. // presentation object, which is created, if there isn't already
  852. // one. If data is successfully set in the presentation object,
  853. // and the node is not frozen, the cache is notified that this
  854. // is dirty.
  855. //
  856. // Arguments:
  857. // [lpForetc] -- the format of the new data
  858. // [lpStgmed] -- the storage medium the new data is one
  859. // [fRelease] -- passed on to the presentation object; indicates
  860. // whether or not to release the storage medium
  861. // [pDataObj] -- pointer to the revelant source data object
  862. //
  863. // Returns:
  864. // E_FAIL
  865. // REVIEW, result from presentationObject::SetData
  866. // S_OK
  867. //
  868. // Notes:
  869. //
  870. // History:
  871. // 11/06/93 - ChrisWe - file inspection and cleanup
  872. //
  873. //-----------------------------------------------------------------------------
  874. HRESULT CCacheNode::SetDataWDO(LPFORMATETC lpForetc, LPSTGMEDIUM lpStgmed,
  875. BOOL fRelease, BOOL& fUpdated, IDataObject *pDataObj)
  876. {
  877. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::SetDataWDO(%p, %p, %lu, %p)\n",
  878. this, lpForetc, lpStgmed, fRelease, pDataObj));
  879. HRESULT hresult = NOERROR;
  880. // Initialize
  881. fUpdated = FALSE;
  882. // If the cache node is in frozen state, save the data in the
  883. // m_pPresObjAfterFreeze
  884. if(InFrozenState()) {
  885. // If PresObjAfterFreeze has not yet been created, create it
  886. if(!m_pPresObjAfterFreeze)
  887. hresult = CreateOlePresObj(&m_pPresObjAfterFreeze, FALSE);
  888. // Hold the data in PresObjAfterFreeze
  889. if(hresult == NOERROR)
  890. hresult = m_pPresObjAfterFreeze->SetDataWDO(lpForetc, lpStgmed,
  891. fRelease, pDataObj);
  892. }
  893. else {
  894. // If PresObj has not yet been created, create it
  895. if(!m_pPresObj)
  896. hresult = CreateOlePresObj(&m_pPresObj, FALSE /* fConvert */);
  897. // Hold the data in PresObj
  898. if(hresult == NOERROR)
  899. hresult = m_pPresObj->SetDataWDO(lpForetc, lpStgmed,
  900. fRelease, pDataObj);
  901. // Update state
  902. if(hresult == NOERROR) {
  903. // Set or clear the data present flag
  904. if(m_pPresObj->IsBlank())
  905. ClearDataPresentFlag();
  906. else
  907. SetDataPresentFlag();
  908. // Indicate that the cache node has been updated
  909. fUpdated = TRUE;
  910. }
  911. }
  912. // If suceeded in holding the data, clear loaded state flag
  913. if(hresult == NOERROR)
  914. ClearLoadedStateFlag();
  915. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::SetDataWDO(%lx)\n", this, hresult));
  916. return hresult;
  917. }
  918. //+----------------------------------------------------------------------------
  919. //
  920. // Member:
  921. // CCacheNode::GetExtent, public
  922. //
  923. // Synopsis:
  924. // Extents of this cache node presentation
  925. //
  926. // Arguments:
  927. // [dwAspect][in] -- Aspect for which the extent is desired
  928. // [pSizel] [in/out] -- Sizel structure for returning the extent
  929. //
  930. //
  931. // Returns:
  932. // NOERROR on success
  933. //
  934. // History:
  935. // Gopalk Creation Sep 04, 96
  936. //
  937. //-----------------------------------------------------------------------------
  938. HRESULT CCacheNode::GetExtent(DWORD dwAspect, SIZEL* pSizel)
  939. {
  940. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::GetExtent(%lx, %p)\n",
  941. this, dwAspect, pSizel));
  942. HRESULT error = NOERROR;
  943. if(!(dwAspect & m_foretc.dwAspect))
  944. error = ResultFromScode(DV_E_DVASPECT);
  945. else if(IsBlank()) {
  946. // This case also catches new blank presentation caches
  947. pSizel->cx = 0;
  948. pSizel->cy = 0;
  949. error = ResultFromScode(OLE_E_BLANK);
  950. }
  951. else {
  952. // Check for existence of pres object
  953. if(!m_pPresObj && IsNormalCache()) {
  954. // The Presobj has not yet been created
  955. // This happens for old presentation caches only
  956. Win4Assert(InLoadedState());
  957. pSizel->cx = m_lWidth;
  958. pSizel->cy = m_lHeight;
  959. }
  960. else {
  961. // If PresObj has not yet been created for native cache,
  962. // create and load the PresObj
  963. if(!m_pPresObj && IsNativeCache())
  964. error = CreateAndLoadPresObj(FALSE);
  965. // Get extent information from PresObj
  966. if(error == NOERROR)
  967. error = m_pPresObj->GetExtent(dwAspect, pSizel);
  968. }
  969. // Ensure extents are positive
  970. if(error == NOERROR) {
  971. pSizel->cx = LONG_ABS(pSizel->cx);
  972. pSizel->cy = LONG_ABS(pSizel->cy);
  973. // Sanity check
  974. Win4Assert(pSizel->cx != 1234567890);
  975. Win4Assert(pSizel->cx != 1234567890);
  976. }
  977. }
  978. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::GetExtent(%lx)\n", this, error));
  979. return error;
  980. }
  981. //+----------------------------------------------------------------------------
  982. //
  983. // Member:
  984. // CCacheNode::GetData, public
  985. //
  986. // Synopsis:
  987. // Obtains the cache node presentation data
  988. //
  989. // Arguments:
  990. // [pforetc] [in] -- FormatEtc of the presentation desired
  991. // [pmedium] [out] -- Storage medium in which data is returned
  992. //
  993. //
  994. // Returns:
  995. // NOERROR on success
  996. //
  997. // History:
  998. // Gopalk Creation Sep 04, 96
  999. //
  1000. //-----------------------------------------------------------------------------
  1001. HRESULT CCacheNode::GetData(LPFORMATETC pforetc, LPSTGMEDIUM pmedium)
  1002. {
  1003. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::GetData(%p, %p)\n",
  1004. this, pforetc, pmedium));
  1005. HRESULT error = NOERROR;
  1006. if(IsBlank()) {
  1007. // This case also catches new blank presentation caches
  1008. error = ResultFromScode(OLE_E_BLANK);
  1009. }
  1010. else {
  1011. // Check for existence of pres object
  1012. if(!m_pPresObj) {
  1013. // The PresObj has not yet been created, create and load it
  1014. // This happens for old presentation caches only
  1015. Win4Assert(InLoadedState());
  1016. error = CreateAndLoadPresObj(FALSE);
  1017. }
  1018. // Get data from pres object
  1019. if(error == NOERROR)
  1020. error = m_pPresObj->GetData(pforetc, pmedium);
  1021. }
  1022. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::GetData(%lx)\n", this, error));
  1023. return error;
  1024. }
  1025. //+----------------------------------------------------------------------------
  1026. //
  1027. // Member:
  1028. // CCacheNode::GetDataHere, public
  1029. //
  1030. // Synopsis:
  1031. // Obtains the cache node presentation data
  1032. //
  1033. // Arguments:
  1034. // [pforetc] [in] -- FormatEtc of the presentation desired
  1035. // [pmedium] [in/out] -- Storage medium in which data is returned
  1036. //
  1037. //
  1038. // Returns:
  1039. // NOERROR on success
  1040. //
  1041. // History:
  1042. // Gopalk Creation Sep 04, 96
  1043. //
  1044. //-----------------------------------------------------------------------------
  1045. HRESULT CCacheNode::GetDataHere(LPFORMATETC pforetc, LPSTGMEDIUM pmedium)
  1046. {
  1047. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::GetData(%p, %p)\n",
  1048. this, pforetc, pmedium));
  1049. HRESULT error = NOERROR;
  1050. if(IsBlank()) {
  1051. // This case also catches new blank presentation caches
  1052. error = ResultFromScode(OLE_E_BLANK);
  1053. }
  1054. else {
  1055. // Check for existence of pres object
  1056. if(!m_pPresObj) {
  1057. // The PresObj has not yet been created, create and load it
  1058. // This happens for old presentation caches only
  1059. Win4Assert(InLoadedState());
  1060. error = CreateAndLoadPresObj(FALSE);
  1061. }
  1062. // Get data from pres object
  1063. if(error == NOERROR)
  1064. error = m_pPresObj->GetDataHere(pforetc, pmedium);
  1065. }
  1066. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::GetDataHere(%lx)\n", this, error));
  1067. return error;
  1068. }
  1069. //+----------------------------------------------------------------------------
  1070. //
  1071. // Member:
  1072. // CCacheNode::Draw, public
  1073. //
  1074. // Synopsis:
  1075. // Draws the presentation data on the specified hDC
  1076. //
  1077. // Arguments:
  1078. //
  1079. //
  1080. // Returns:
  1081. // NOERROR on success
  1082. //
  1083. // History:
  1084. // Gopalk Creation Sep 04, 96
  1085. //
  1086. //-----------------------------------------------------------------------------
  1087. HRESULT CCacheNode::Draw(void* pvAspect, HDC hicTargetDev, HDC hdcDraw,
  1088. LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
  1089. BOOL (CALLBACK *pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue)
  1090. {
  1091. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Draw(%p, %p, %p, %p, %p, %p)\n",
  1092. this, pvAspect, lprcBounds, lprcWBounds, pfnContinue, dwContinue));
  1093. HRESULT error = NOERROR;
  1094. if(IsBlank()) {
  1095. // This case also catches new blank presentation caches
  1096. error = ResultFromScode(OLE_E_BLANK);
  1097. }
  1098. else {
  1099. // Check for existence of pres object
  1100. if(!m_pPresObj) {
  1101. // The PresObj has not yet been created, create and load it
  1102. // This happens for old presentation caches only
  1103. Win4Assert(InLoadedState());
  1104. error = CreateAndLoadPresObj(FALSE);
  1105. }
  1106. // Get draw from pres object
  1107. if(error == NOERROR)
  1108. error = m_pPresObj->Draw(pvAspect, hicTargetDev, hdcDraw, lprcBounds,
  1109. lprcWBounds, pfnContinue, dwContinue);
  1110. }
  1111. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Draw(%lx)\n", this, error));
  1112. return error;
  1113. }
  1114. //+----------------------------------------------------------------------------
  1115. //
  1116. // Member:
  1117. // CCacheNode::GetColorSet, public
  1118. //
  1119. // Synopsis:
  1120. // Draws the presentation data on the specified hDC
  1121. //
  1122. // Arguments:
  1123. //
  1124. //
  1125. // Returns:
  1126. // NOERROR on success
  1127. //
  1128. // History:
  1129. // Gopalk Creation Sep 04, 96
  1130. //
  1131. //-----------------------------------------------------------------------------
  1132. HRESULT CCacheNode::GetColorSet(void* pvAspect, HDC hicTargetDev,
  1133. LPLOGPALETTE* ppColorSet)
  1134. {
  1135. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::GetColorSet(%p, %p)\n",
  1136. this, pvAspect, ppColorSet));
  1137. HRESULT error = NOERROR;
  1138. if(IsBlank()) {
  1139. // This case also catches new blank presentation caches
  1140. error = ResultFromScode(OLE_E_BLANK);
  1141. }
  1142. else {
  1143. // Check for existence of pres object
  1144. if(!m_pPresObj) {
  1145. // The PresObj has not yet been created, create and load it
  1146. // This happens for old presentation caches only
  1147. Win4Assert(InLoadedState());
  1148. error = CreateAndLoadPresObj(FALSE);
  1149. }
  1150. // Get color set from pres object
  1151. if(error == NOERROR)
  1152. error = m_pPresObj->GetColorSet(pvAspect, hicTargetDev, ppColorSet);
  1153. }
  1154. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::GetColorSet(%lx)\n", this, error));
  1155. return error;
  1156. }
  1157. //+----------------------------------------------------------------------------
  1158. //
  1159. // Member:
  1160. // CCacheNode::CreateAndLoadPresObj, private
  1161. //
  1162. // Synopsis:
  1163. // Creates and loads the pres object
  1164. //
  1165. // Arguments:
  1166. // [fHeaderOnly] - True if only pres obj header needs to be loaded
  1167. // This option is used for GetExtent as there is no
  1168. // need to load entire pres obj for getting extents
  1169. // Further, this routine should be called only for
  1170. // previously cached presentations
  1171. // Returns:
  1172. // NOERROR on success
  1173. //
  1174. // History:
  1175. // Gopalk Creation Sep 04, 96
  1176. //
  1177. //-----------------------------------------------------------------------------
  1178. HRESULT CCacheNode::CreateAndLoadPresObj(BOOL fHeaderOnly)
  1179. {
  1180. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::CreateAndLoadPresObj(%lx)\n",
  1181. this, fHeaderOnly));
  1182. HRESULT error = NOERROR;
  1183. // Check for existence of pres object
  1184. if(!m_pPresObj) {
  1185. if(IsNativeCache()) {
  1186. // Native cache node
  1187. // Check if cache has storage
  1188. if(m_pStg) {
  1189. BOOL fOle10Native, fUpdated;
  1190. STGMEDIUM stgmed;
  1191. // Is the native an Ole 1.0 class
  1192. if(CoIsOle1Class(m_clsid))
  1193. fOle10Native = TRUE;
  1194. else
  1195. fOle10Native = FALSE;
  1196. // Obtain global with the native data.
  1197. // Due to auto convert case, the native stream may be in the
  1198. // old CfFormat and consequently, trying to read in the new
  1199. // CfFormat can fail. Gopalk
  1200. stgmed.pUnkForRelease = NULL;
  1201. stgmed.tymed = m_foretc.tymed;
  1202. stgmed.hGlobal = UtGetHPRESFromNative(m_pStg, NULL, m_foretc.cfFormat,
  1203. fOle10Native);
  1204. // We may be dealing with old-styled static object. Such
  1205. // objects are supposed to be converted during loading, but
  1206. // some are not, for reasons such as lack of access rights.
  1207. if(!stgmed.hGlobal)
  1208. {
  1209. // Convert OlePres to CONTENTS in-memory.
  1210. IStream *pMemStm = NULL;
  1211. HRESULT hr;
  1212. hr = CreateStreamOnHGlobal(NULL, TRUE, &pMemStm);
  1213. if(SUCCEEDED(hr) && pMemStm)
  1214. {
  1215. UINT uiStatus = 0;
  1216. hr = UtOlePresStmToContentsStm(m_pStg, OLE_PRESENTATION_STREAM, pMemStm, &uiStatus);
  1217. if(SUCCEEDED(hr) && uiStatus == 0)
  1218. {
  1219. // rewind the stream
  1220. LARGE_INTEGER dlibMove = {0};
  1221. pMemStm->Seek(dlibMove, STREAM_SEEK_SET, NULL);
  1222. // 2nd try
  1223. stgmed.hGlobal = UtGetHPRESFromNative(NULL, pMemStm, m_foretc.cfFormat, fOle10Native);
  1224. }
  1225. pMemStm->Release();
  1226. }
  1227. }
  1228. // Set the data on native cache node
  1229. if(stgmed.hGlobal) {
  1230. error = SetData(&m_foretc, &stgmed, TRUE, fUpdated);
  1231. if(error != NOERROR)
  1232. ReleaseStgMedium(&stgmed);
  1233. }
  1234. else {
  1235. // This happens when the native data is not in the correct format
  1236. Win4Assert(FALSE);
  1237. error = ResultFromScode(DV_E_CLIPFORMAT);
  1238. }
  1239. }
  1240. else {
  1241. Win4Assert(FALSE);
  1242. error = ResultFromScode(OLE_E_BLANK);
  1243. }
  1244. }
  1245. else {
  1246. // Normal cache node
  1247. error = CreateOlePresObj(&m_pPresObj, m_fConvert);
  1248. // Load the data into pres object
  1249. if(error == NOERROR) {
  1250. LPSTREAM pStream;
  1251. // Open presentation stream and seek to the pres obj bits
  1252. pStream = GetStm(TRUE, STGM_READ);
  1253. if(pStream) {
  1254. // Load pres object
  1255. error = m_pPresObj->Load(pStream, fHeaderOnly);
  1256. pStream->Release();
  1257. }
  1258. else {
  1259. // This can happen only when m_pStg is NULL
  1260. Win4Assert(!m_pStg);
  1261. Win4Assert(FALSE);
  1262. error = ResultFromScode(OLE_E_BLANK);
  1263. }
  1264. }
  1265. // Assert that the state matches current state
  1266. if(error == NOERROR) {
  1267. SIZEL extent;
  1268. Win4Assert(m_pPresObj->IsBlank()==IsBlank());
  1269. m_pPresObj->GetExtent(m_foretc.dwAspect, &extent);
  1270. Win4Assert(extent.cx==m_lWidth && extent.cy==m_lHeight);
  1271. }
  1272. }
  1273. }
  1274. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::CreateAndLoadPresObj(%lx)\n",
  1275. this, error));
  1276. return error;
  1277. }
  1278. //+----------------------------------------------------------------------------
  1279. //
  1280. // Member:
  1281. // CCacheNode::DiscardPresentation, public
  1282. //
  1283. // Synopsis:
  1284. // Discards the presentation objects so that we hit the storage
  1285. // for presentation data in future
  1286. //
  1287. // Arguments:
  1288. // NONE
  1289. //
  1290. // Returns:
  1291. // NOERROR on success
  1292. //
  1293. // History:
  1294. // Gopalk Creation Sep 04, 96
  1295. //
  1296. //-----------------------------------------------------------------------------
  1297. HRESULT CCacheNode::DiscardPresentation(LPSTREAM pGivenStream)
  1298. {
  1299. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::DiscardPresentation()\n", this));
  1300. HRESULT error = NOERROR;
  1301. LPSTREAM pStream;
  1302. // We are being forced to destroy presentation object rather than
  1303. // discarding its presentation data due to a flaw in the current design
  1304. // of presentation objects. The presentation objects do not discard their
  1305. // extent information along with their presentation data. This causes us
  1306. // to get latest extent information in future IOleCache::GetExtent() calls
  1307. // which is not the desired behavior. Gopalk
  1308. // Revert state
  1309. if(IsNativeCache()) {
  1310. // Native Cache node
  1311. // Update state
  1312. SetLoadedStateFlag();
  1313. ClearFrozenStateFlag();
  1314. // We make the conservative assumption that the native cache
  1315. // is not blank
  1316. SetDataPresentFlag();
  1317. }
  1318. else {
  1319. // Normal cache node
  1320. if(m_iStreamNum == OLE_INVALID_STREAMNUM) {
  1321. // New cache node
  1322. Win4Assert(!InLoadedState());
  1323. // Simply update state
  1324. ClearFrozenStateFlag();
  1325. ClearDataPresentFlag();
  1326. m_lWidth = 0;
  1327. m_lHeight = 0;
  1328. }
  1329. else {
  1330. // Old cache node
  1331. if(InLoadedState()) {
  1332. // The cache node is still in loaded state
  1333. BOOL fUpdated;
  1334. SIZEL Extent;
  1335. // Unfreeze the cache node to get the latest saved presentation
  1336. if(InFrozenState())
  1337. Unfreeze(fUpdated);
  1338. Win4Assert(!m_pPresObjAfterFreeze);
  1339. Win4Assert(!InFrozenState());
  1340. // Obtain the latest extent.
  1341. // This could happen due to Unfreeze above
  1342. if(m_pPresObj) {
  1343. error = m_pPresObj->GetExtent(m_foretc.dwAspect, &Extent);
  1344. m_lWidth = Extent.cx;
  1345. m_lHeight = Extent.cy;
  1346. }
  1347. // Update state
  1348. if(error == NOERROR)
  1349. SetLoadedCacheFlag();
  1350. }
  1351. else {
  1352. // Open presentation stream and read header from it
  1353. pStream = GetStm(TRUE, STGM_READ);
  1354. if(pStream) {
  1355. // Read presentation header
  1356. if(m_foretc.cfFormat) {
  1357. DWORD dwBuf[4];
  1358. // Read the extent and size of presentation data
  1359. dwBuf[0] = 0L;
  1360. dwBuf[1] = 0L;
  1361. dwBuf[2] = 0L;
  1362. dwBuf[3] = 0L;
  1363. error = pStream->Read(dwBuf, sizeof(dwBuf), NULL);
  1364. if(error == NOERROR) {
  1365. Win4Assert(!dwBuf[0]);
  1366. m_lWidth = dwBuf[1];
  1367. m_lHeight = dwBuf[2];
  1368. if(dwBuf[3]) {
  1369. SetDataPresentFlag();
  1370. Win4Assert(m_lWidth!=0 && m_lHeight!=0);
  1371. }
  1372. else {
  1373. ClearDataPresentFlag();
  1374. Win4Assert(m_lWidth==0 && m_lHeight==0);
  1375. }
  1376. }
  1377. }
  1378. else {
  1379. // Assume that the presentation is blank
  1380. ClearDataPresentFlag();
  1381. m_lWidth = 0;
  1382. m_lHeight = 0;
  1383. }
  1384. // Update rest of the state
  1385. if(error == NOERROR) {
  1386. SetLoadedStateFlag();
  1387. SetLoadedCacheFlag();
  1388. ClearFrozenStateFlag();
  1389. }
  1390. // Release the stream
  1391. pStream->Release();
  1392. }
  1393. else {
  1394. // This can happen only when m_pStg is NULL
  1395. Win4Assert(!m_pStg);
  1396. error = ResultFromScode(E_UNEXPECTED);
  1397. }
  1398. }
  1399. }
  1400. }
  1401. // Destroy both presentation objects
  1402. if(m_pPresObj && error==NOERROR) {
  1403. m_pPresObj->Release();
  1404. m_pPresObj = NULL;
  1405. }
  1406. if(m_pPresObjAfterFreeze && error==NOERROR) {
  1407. m_pPresObjAfterFreeze->Release();
  1408. m_pPresObjAfterFreeze = NULL;
  1409. }
  1410. LEDebugOut((DEB_ITRACE, "%p _OUT CCacheNode::DiscardPresentation(%lx)\n",
  1411. this, error));
  1412. return error;
  1413. }
  1414. //+----------------------------------------------------------------------------
  1415. //
  1416. // Member:
  1417. // CCacheNode::Freeze, public
  1418. //
  1419. // Synopsis:
  1420. // Freeze the cachenode. From here on, OnDataChange() is ignored
  1421. // until this node is unfrozen (Unfreeze().) This is not
  1422. // persistent across Save/Load. (If we receive OnDataChange(),
  1423. // the new data is stashed away in m_pPresAfterFreeze, but is
  1424. // not exported to the outside of the cache node.)
  1425. //
  1426. // Arguments:
  1427. // none
  1428. //
  1429. // Returns:
  1430. // VIEW_S_ALREADY_FROZEN
  1431. // S_OK
  1432. //
  1433. // Notes:
  1434. //
  1435. // History:
  1436. // 11/06/93 - ChrisWe - file inspection and cleanup
  1437. //
  1438. //-----------------------------------------------------------------------------
  1439. HRESULT CCacheNode::Freeze()
  1440. {
  1441. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::Freeze()\n", this));
  1442. HRESULT hresult = NOERROR;
  1443. if(InFrozenState())
  1444. hresult = ResultFromScode(VIEW_S_ALREADY_FROZEN);
  1445. else
  1446. SetFrozenStateFlag();
  1447. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::Freeze(%lx)\n", this, hresult));
  1448. return hresult;
  1449. }
  1450. //+----------------------------------------------------------------------------
  1451. //
  1452. // Member:
  1453. // CCacheNode::Unfreeze, public
  1454. //
  1455. // Synopsis:
  1456. // Unfreeze the cachenode. If there have been changes to
  1457. // the presentation data since the node was frozen, the node
  1458. // is updated to reflect those changes. From this point on,
  1459. // OnDataChange() notifications are no longer ignored.
  1460. //
  1461. // Arguments:
  1462. // fChanged [out] - set to TRUE when cache node is updated
  1463. //
  1464. // Returns:
  1465. // OLE_E_NOCONNECTION, if the node was not frozen (REVIEW scode)
  1466. // S_OK
  1467. //
  1468. // Notes:
  1469. //
  1470. // History:
  1471. // 11/06/93 - ChrisWe - file inspection and cleanup
  1472. //
  1473. //-----------------------------------------------------------------------------
  1474. HRESULT CCacheNode::Unfreeze(BOOL& fUpdated)
  1475. {
  1476. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::UnFreeze(%p)\n", this, &fUpdated));
  1477. HRESULT hresult = NOERROR;
  1478. // Initilaize
  1479. fUpdated = FALSE;
  1480. if(InFrozenState()) {
  1481. // Cache node is no longer in frozen state
  1482. ClearFrozenStateFlag();
  1483. // Check to see if we have m_pPresObjAfterFreeze
  1484. if(m_pPresObjAfterFreeze) {
  1485. // Check if the frozen presentation object is blank
  1486. if(m_pPresObjAfterFreeze->IsBlank()) {
  1487. // Release and reset the frozen presentation object
  1488. m_pPresObjAfterFreeze->Release();
  1489. m_pPresObjAfterFreeze = NULL;
  1490. }
  1491. else {
  1492. // Release the original presentation object
  1493. if(m_pPresObj)
  1494. m_pPresObj->Release();
  1495. // Make m_pPresObjAfterFreeze the current one and set
  1496. // data present flag
  1497. m_pPresObj = m_pPresObjAfterFreeze;
  1498. SetDataPresentFlag();
  1499. // Cache node is updated
  1500. fUpdated = TRUE;
  1501. // Reset the m_pPresObjAfterFreeze to NULL
  1502. m_pPresObjAfterFreeze = NULL;
  1503. }
  1504. }
  1505. }
  1506. else {
  1507. // The cachenode is not frozen
  1508. hresult = ResultFromScode(OLE_E_NOCONNECTION);
  1509. }
  1510. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::UnFreeze(%lx)\n", this, hresult));
  1511. return hresult;
  1512. }
  1513. //+----------------------------------------------------------------------------
  1514. //
  1515. // Member:
  1516. // CCacheNode::QueryFormatSupport, private
  1517. //
  1518. // Synopsis:
  1519. // Check to see if the data object supports the presentation
  1520. // format specified for this cache node. If no format is
  1521. // specified, check for any of our preferred formats. If
  1522. // the format is CF_DIB, and that is not available, check for
  1523. // CF_BITMAP.
  1524. //
  1525. // Arguments:
  1526. // [lpDataObj] -- the data object
  1527. //
  1528. // Returns:
  1529. // TRUE if the format is supported, FALSE otherwise
  1530. //
  1531. // Notes:
  1532. //
  1533. // History:
  1534. // 11/09/93 - ChrisWe - no longer necessary to reset format
  1535. // after UtQueryPictFormat, since that leaves descriptor
  1536. // untouched now
  1537. // 11/09/93 - ChrisWe - file inspection and cleanup
  1538. //
  1539. //-----------------------------------------------------------------------------
  1540. BOOL CCacheNode::QueryFormatSupport(LPDATAOBJECT lpDataObj)
  1541. {
  1542. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::QueryFormatSupport(%p)\n",
  1543. this, lpDataObj));
  1544. BOOL fRet = FALSE;
  1545. if(lpDataObj) {
  1546. if(m_foretc.cfFormat) {
  1547. // Check to see if cachenode format is supported
  1548. if(lpDataObj->QueryGetData(&m_foretc) == NOERROR)
  1549. fRet = TRUE;
  1550. else {
  1551. // If the cachenode format was DIB that was not supported,
  1552. // check to see if BITMAP is supported instead
  1553. if(m_foretc.cfFormat == CF_DIB) {
  1554. FORMATETC foretc = m_foretc;
  1555. foretc.cfFormat = CF_BITMAP;
  1556. foretc.tymed = TYMED_GDI;
  1557. if (lpDataObj->QueryGetData(&foretc) == NOERROR)
  1558. fRet = TRUE;
  1559. }
  1560. }
  1561. }
  1562. else {
  1563. // Check for our preferred formats
  1564. fRet = UtQueryPictFormat(lpDataObj, &m_foretc);
  1565. if(fRet)
  1566. BITMAP_TO_DIB(m_foretc);
  1567. }
  1568. }
  1569. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::QueryFormatSupport(%lu)\n",
  1570. this, fRet));
  1571. return fRet;
  1572. }
  1573. //+----------------------------------------------------------------------------
  1574. //
  1575. // Member:
  1576. // CCacheNode::SetupAdviseConnection, private
  1577. //
  1578. // Synopsis:
  1579. // Set up data advise sourced by the server object, and sunk
  1580. // by this cache node, if there is a valid data object.
  1581. //
  1582. // Arguments:
  1583. // none
  1584. //
  1585. // Returns:
  1586. // OLE_E_BLANK, if no presentation object exists or can be
  1587. // created
  1588. // DATA_E_FORMATETC
  1589. // OLE_E_ADVISENOTSUPPORTED
  1590. // S_OK, indicates successful advise, or no data object
  1591. //
  1592. // Notes:
  1593. //
  1594. // History:
  1595. // 11/09/93 - ChrisWe - file inspection and cleanup
  1596. //
  1597. //-----------------------------------------------------------------------------
  1598. HRESULT CCacheNode::SetupAdviseConnection(LPDATAOBJECT pDataObj,
  1599. IAdviseSink* pAdviseSink)
  1600. {
  1601. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::SetupAdviseConnection(%p, %p)\n",
  1602. this, pDataObj, pAdviseSink));
  1603. DWORD grfAdvf;
  1604. HRESULT hresult = NOERROR;
  1605. if(pDataObj && pAdviseSink) {
  1606. // Assert that there is no pending advise connection
  1607. Win4Assert(!m_pDataObject && !m_dwAdvConnId);
  1608. // If cfFormat is NULL, try setting it
  1609. if(!m_foretc.cfFormat) {
  1610. if(QueryFormatSupport(pDataObj)) {
  1611. // We could update our cfFormat
  1612. ClearLoadedStateFlag();
  1613. }
  1614. else {
  1615. // We still could not set the cfFormat
  1616. hresult = ResultFromScode(OLE_E_BLANK);
  1617. }
  1618. }
  1619. // Check if cfFormat is set and ADVF_NODATA is not set in advise flags
  1620. if(m_foretc.cfFormat && !(m_advf & ADVF_NODATA)) {
  1621. // copy and massage the base advise control flags
  1622. grfAdvf = m_advf;
  1623. // only the DDE layer looks for these 2 bits
  1624. grfAdvf |= (ADVFDDE_ONSAVE | ADVFDDE_ONCLOSE);
  1625. // If we were to get data when it is saved, get it instead when
  1626. // the object is stopped
  1627. if(grfAdvf & ADVFCACHE_ONSAVE) {
  1628. grfAdvf &= (~ADVFCACHE_ONSAVE);
  1629. grfAdvf |= ADVF_DATAONSTOP;
  1630. }
  1631. // These two flags are not meaningful to the cache
  1632. // REVIEW, why not?
  1633. grfAdvf &= (~(ADVFCACHE_NOHANDLER | ADVFCACHE_FORCEBUILTIN));
  1634. // If we already have data, then remove the ADVF_PRIMEFIRST
  1635. if(!IsBlank())
  1636. grfAdvf &= (~ADVF_PRIMEFIRST);
  1637. // Set up the advise with the data object, using massaged flags
  1638. hresult = pDataObj->DAdvise(&m_foretc, grfAdvf, pAdviseSink,
  1639. &m_dwAdvConnId);
  1640. if(hresult!=NOERROR) {
  1641. // The advise failed. If the requested format was CF_DIB,
  1642. // try for CF_BITMAP instead.
  1643. if(m_foretc.cfFormat == CF_DIB) {
  1644. FORMATETC foretc;
  1645. // create new format descriptor
  1646. foretc = m_foretc;
  1647. foretc.cfFormat = CF_BITMAP;
  1648. foretc.tymed = TYMED_GDI;
  1649. // request advise
  1650. hresult = pDataObj->DAdvise(&foretc, grfAdvf, pAdviseSink,
  1651. &m_dwAdvConnId);
  1652. }
  1653. }
  1654. // Save the data object for future sanity check
  1655. if(hresult == NOERROR)
  1656. m_pDataObject = pDataObj;
  1657. }
  1658. }
  1659. else {
  1660. Win4Assert(FALSE);
  1661. hresult = ResultFromScode(E_INVALIDARG);
  1662. }
  1663. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::SetupAdviseConnection(%lx)\n",
  1664. this, hresult));
  1665. return hresult;
  1666. }
  1667. //+----------------------------------------------------------------------------
  1668. //
  1669. // Member:
  1670. // CCacheNode::TearDownAdviseConnection, private
  1671. //
  1672. // Synopsis:
  1673. // Remove advise connection from data object to this sink. Returns
  1674. // immediately if there is no advise connection.
  1675. //
  1676. // Arguments:
  1677. // none
  1678. //
  1679. // Returns:
  1680. // S_OK
  1681. //
  1682. // Notes:
  1683. //
  1684. // History:
  1685. // 11/09/93 - ChrisWe - file inspection and cleanup
  1686. //
  1687. //-----------------------------------------------------------------------------
  1688. HRESULT CCacheNode::TearDownAdviseConnection(LPDATAOBJECT pDataObj)
  1689. {
  1690. LEDebugOut((DEB_ITRACE, "%p _IN CCacheNode::TearDownAdviseConnection(%p)\n",
  1691. this, pDataObj));
  1692. HRESULT error = NOERROR;
  1693. // Check if currently there is an advisory connection
  1694. if(m_dwAdvConnId) {
  1695. // Check for valid data object
  1696. if(pDataObj) {
  1697. // Assert that Advise and Unadvise are on the same dataobject
  1698. Win4Assert(pDataObj==m_pDataObject);
  1699. // UnAdvise
  1700. pDataObj->DUnadvise(m_dwAdvConnId);
  1701. }
  1702. // clear the connection ID
  1703. m_dwAdvConnId = 0;
  1704. m_pDataObject = NULL;
  1705. }
  1706. else
  1707. Win4Assert(!m_pDataObject);
  1708. LEDebugOut((DEB_ITRACE, "%p OUT CCacheNode::TearDownAdviseConnection(%lx)\n",
  1709. this, error));
  1710. return error;
  1711. }
  1712. //+----------------------------------------------------------------------------
  1713. //
  1714. // Member:
  1715. // CCacheNode::SaveTOCEntry, private
  1716. //
  1717. // Synopsis:
  1718. // Saves the TOC information in the given stream
  1719. //
  1720. // Arguments:
  1721. // pStream [in] - Stream in which to save TOC
  1722. //
  1723. // Returns:
  1724. // NOERROR on success
  1725. //
  1726. // History:
  1727. // Gopalk Creation Sep 04, 96
  1728. //
  1729. //-----------------------------------------------------------------------------
  1730. HRESULT CCacheNode::SaveTOCEntry(LPSTREAM pStream, BOOL fSameAsLoad)
  1731. {
  1732. LEDebugOut((DEB_ITRACE, "%p _IN SaveTOCEntry(%p)\n", pStream));
  1733. HRESULT error;
  1734. DWORD dwBuf[9];
  1735. SIZEL Extent;
  1736. // Save the clipboard format
  1737. error = WriteClipformatStm(pStream, m_foretc.cfFormat);
  1738. if(error == NOERROR) {
  1739. // Obtain rest of formatetc
  1740. if(m_foretc.ptd)
  1741. dwBuf[0] = m_foretc.ptd->tdSize;
  1742. else
  1743. dwBuf[0] = 0;
  1744. dwBuf[1] = m_foretc.dwAspect;
  1745. dwBuf[2] = m_foretc.lindex;
  1746. dwBuf[3] = m_foretc.tymed;
  1747. // Initialize extents
  1748. dwBuf[4] = 1234567890;
  1749. dwBuf[5] = 1234567890;
  1750. // Obtain latest extent if this is a normal cache
  1751. if(IsNormalCache()) {
  1752. if(m_pPresObjAfterFreeze && !m_pPresObjAfterFreeze->IsBlank()) {
  1753. Win4Assert(InFrozenState());
  1754. error = m_pPresObjAfterFreeze->GetExtent(m_foretc.dwAspect, &Extent);
  1755. }
  1756. else if(m_pPresObj)
  1757. error = m_pPresObj->GetExtent(m_foretc.dwAspect, &Extent);
  1758. else {
  1759. Extent.cx = m_lWidth;
  1760. Extent.cy = m_lHeight;
  1761. }
  1762. // Gen PresObj returns OLE_E_BLANK for cfformats other than DIB and BITMAP
  1763. if(error == NOERROR) {
  1764. dwBuf[4] = Extent.cx;
  1765. dwBuf[5] = Extent.cy;
  1766. }
  1767. else if(error == ResultFromScode(OLE_E_BLANK)) {
  1768. Win4Assert(m_foretc.cfFormat != CF_DIB);
  1769. Win4Assert(m_foretc.cfFormat != CF_METAFILEPICT);
  1770. Win4Assert(m_foretc.cfFormat != CF_ENHMETAFILE);
  1771. dwBuf[4] = 0;
  1772. dwBuf[5] = 0;
  1773. }
  1774. }
  1775. // Obtain cache node flags, advise flags and presentation bits position
  1776. dwBuf[6] = m_dwFlags;
  1777. dwBuf[7] = m_advf;
  1778. if(fSameAsLoad)
  1779. dwBuf[8] = m_dwPresBitsPos;
  1780. else
  1781. dwBuf[8] = m_dwSavedPresBitsPos;
  1782. #if DBG==1
  1783. if (IsNormalCache()) {
  1784. Win4Assert(dwBuf[8]);
  1785. }
  1786. #endif
  1787. // Save the obtained state
  1788. error = pStream->Write(dwBuf, sizeof(dwBuf), NULL);
  1789. // Finally, save target device
  1790. if(error==NOERROR && m_foretc.ptd)
  1791. error = pStream->Write(m_foretc.ptd, m_foretc.ptd->tdSize, NULL);
  1792. }
  1793. LEDebugOut((DEB_ITRACE, "%p OUT SaveTOCEntry(%lx)\n", NULL, error));
  1794. return error;
  1795. }
  1796. //+----------------------------------------------------------------------------
  1797. //
  1798. // Member:
  1799. // CCacheNode::LoadTOCEntry, private
  1800. //
  1801. // Synopsis:
  1802. // Loads the TOC information in the given stream
  1803. //
  1804. // Arguments:
  1805. // pStream [in] - Stream from which to load TOC
  1806. // iStreamNum [in/out] - Presentation stream number of the cache
  1807. //
  1808. // Returns:
  1809. // NOERROR on success
  1810. //
  1811. // History:
  1812. // Gopalk Creation Sep 04, 96
  1813. //
  1814. //-----------------------------------------------------------------------------
  1815. HRESULT CCacheNode::LoadTOCEntry(LPSTREAM pStream, int& iStreamNum)
  1816. {
  1817. LEDebugOut((DEB_ITRACE, "%p _IN LoadTOCEntry(%p)\n", pStream));
  1818. HRESULT error;
  1819. DWORD cfFormat, dwBuf[9];
  1820. ULONG ulBytesRead;
  1821. // Load the clipboard format
  1822. error = ReadClipformatStm(pStream, &cfFormat);
  1823. if(error == NOERROR) {
  1824. // Load remaining state
  1825. error = pStream->Read(dwBuf, sizeof(dwBuf), &ulBytesRead);
  1826. if(ulBytesRead == sizeof(dwBuf)) {
  1827. // Load target device
  1828. if(dwBuf[0]) {
  1829. m_foretc.ptd = (DVTARGETDEVICE *) PubMemAlloc(dwBuf[0]);
  1830. if(m_foretc.ptd) {
  1831. error = pStream->Read(m_foretc.ptd, dwBuf[0], &ulBytesRead);
  1832. if(ulBytesRead != dwBuf[0]) {
  1833. PubMemFree(m_foretc.ptd);
  1834. m_foretc.ptd = NULL;
  1835. error = ResultFromScode(E_FAIL);
  1836. }
  1837. }
  1838. else
  1839. error = ResultFromScode(E_OUTOFMEMORY);
  1840. }
  1841. else
  1842. m_foretc.ptd = NULL;
  1843. // Check if TOC data was read successfully
  1844. if(error == NOERROR) {
  1845. // Update cache node data
  1846. m_foretc.cfFormat = (CLIPFORMAT) cfFormat;
  1847. m_foretc.dwAspect = dwBuf[1];
  1848. m_foretc.lindex = dwBuf[2];
  1849. m_foretc.tymed = dwBuf[3];
  1850. m_lWidth = dwBuf[4];
  1851. m_lHeight = dwBuf[5];
  1852. m_dwFlags = dwBuf[6];
  1853. m_advf = dwBuf[7];
  1854. m_dwPresBitsPos = dwBuf[8];
  1855. // Update state on the node
  1856. SetLoadedStateFlag();
  1857. ClearFrozenStateFlag();
  1858. if(IsNormalCache()) {
  1859. SetLoadedCacheFlag();
  1860. m_iStreamNum = iStreamNum++;
  1861. }
  1862. #if DBG==1
  1863. // Sanity Checks
  1864. if (IsNormalCache()) {
  1865. Win4Assert(m_lWidth!=1234567890);
  1866. Win4Assert(m_lHeight!=1234567890);
  1867. Win4Assert(m_dwPresBitsPos);
  1868. }
  1869. #endif
  1870. }
  1871. }
  1872. else
  1873. error = ResultFromScode(E_FAIL);
  1874. }
  1875. LEDebugOut((DEB_ITRACE, "%p OUT LoadTOCEntry(%lx)\n", NULL, error));
  1876. return error;
  1877. }
  1878. //+----------------------------------------------------------------------------
  1879. //
  1880. // Member:
  1881. // CCacheNode::operator=, public
  1882. //
  1883. // Synopsis:
  1884. // Assignment operator implementation for cache node
  1885. //
  1886. // Arguments:
  1887. // [rCN] -- CacheNode object that is on the RHS
  1888. // of assignment statement
  1889. //
  1890. // Returns:
  1891. // CacheNode object that is on the LHS of the assignment
  1892. // statement so that chaining of assinments is possible
  1893. //
  1894. // History:
  1895. // Gopalk Creation Sep 04, 96
  1896. //
  1897. //-----------------------------------------------------------------------------
  1898. const CCacheNode& CCacheNode::operator=(const CCacheNode& rCN)
  1899. {
  1900. // Check to see, if this a=a case
  1901. if(this==&rCN)
  1902. return(*this);
  1903. // Self destroy
  1904. CCacheNode::~CCacheNode();
  1905. // Now, make a copy
  1906. if(!UtCopyFormatEtc((LPFORMATETC) &rCN.m_foretc, &m_foretc))
  1907. SetOutOfMemoryFlag();
  1908. m_advf = rCN.m_advf;
  1909. m_lWidth = rCN.m_lWidth;
  1910. m_lHeight = rCN.m_lHeight;
  1911. m_dwFlags = rCN.m_dwFlags;
  1912. m_pStg = rCN.m_pStg;
  1913. m_iStreamNum = rCN.m_iStreamNum;
  1914. m_dwPresBitsPos = rCN.m_dwPresBitsPos;
  1915. m_pPresObj = rCN.m_pPresObj;
  1916. if(m_pPresObj)
  1917. m_pPresObj->AddRef();
  1918. m_pPresObjAfterFreeze = rCN.m_pPresObjAfterFreeze;
  1919. if(m_pPresObjAfterFreeze)
  1920. m_pPresObjAfterFreeze->AddRef();
  1921. m_pDataObject = rCN.m_pDataObject;
  1922. m_dwAdvConnId = rCN.m_dwAdvConnId;
  1923. #ifdef _DEBUG
  1924. m_dwPresFlag = rCN.m_dwPresFlag;
  1925. #endif // _DEBUG
  1926. return(*this);
  1927. }
  1928. //+----------------------------------------------------------------------------
  1929. //
  1930. // Member:
  1931. // CCacheNode::operator==, public
  1932. //
  1933. // Synopsis:
  1934. // Equality operator implementation for cache node
  1935. //
  1936. // Arguments:
  1937. // [rCN] -- CacheNode object that is on the RHS
  1938. // of the equality expression
  1939. //
  1940. // Returns:
  1941. // 1 if both the CacheNode objects are equal, 0 otherwise
  1942. //
  1943. // History:
  1944. // Gopalk Creation Sep 04, 96
  1945. //
  1946. //-----------------------------------------------------------------------------
  1947. /*int CCacheNode::operator==(CCacheNode& rCN)
  1948. {
  1949. if(m_foretc.cfFormat == rCN.m_foretc.cfFormat)
  1950. if(m_foretc.dwAspect == rCN.m_foretc.dwAspect)
  1951. if(m_foretc.lindex == rCN.m_foretc.lindex)
  1952. if(UtCompareTargetDevice(m_foretc.ptd, rCN.m_foretc.ptd))
  1953. return(1);
  1954. return(0);
  1955. }
  1956. */
  1957. //+----------------------------------------------------------------------------
  1958. //
  1959. // Function:
  1960. // wGetData, internal
  1961. //
  1962. // Synopsis:
  1963. // Fetch the data from the data object in the requested format.
  1964. // If the fetch fails, and the requested format was CF_DIB,
  1965. // try CF_BITMAP as an alternative.
  1966. //
  1967. // Arguments:
  1968. // [lpSrcDataObj] -- source data object
  1969. // [lpforetc] -- desired data format
  1970. // [lpmedium] -- if successful, the storage medium containing
  1971. // the requested data
  1972. //
  1973. // Returns:
  1974. // DATA_E_FORMATETC
  1975. // S_OK
  1976. //
  1977. // Notes:
  1978. //
  1979. // History:
  1980. // 11/09/93 - ChrisWe - modified to not alter the requested
  1981. // format unless the subsequent CF_BITMAP request succeeds.
  1982. // 11/09/93 - ChrisWe - file inspection and cleanup
  1983. //
  1984. //-----------------------------------------------------------------------------
  1985. HRESULT wGetData(LPDATAOBJECT lpSrcDataObj, LPFORMATETC lpforetc,
  1986. LPSTGMEDIUM lpmedium)
  1987. {
  1988. LEDebugOut((DEB_ITRACE, "%p _IN wGetData(%p, %p, %p)\n",
  1989. NULL, lpSrcDataObj, lpforetc, lpmedium));
  1990. HRESULT hresult;
  1991. // Get the data in the requested format
  1992. hresult = lpSrcDataObj->GetData(lpforetc, lpmedium);
  1993. if(hresult!=NOERROR) {
  1994. // GetData failed. If the requested format was CF_DIB,
  1995. // then try CF_BITMAP instead.
  1996. if(lpforetc->cfFormat == CF_DIB) {
  1997. FORMATETC foretc;
  1998. // copy the base format descriptor; try CF_BITMAP
  1999. foretc = *lpforetc;
  2000. foretc.cfFormat = CF_BITMAP;
  2001. foretc.tymed = TYMED_GDI;
  2002. hresult = lpSrcDataObj->GetData(&foretc, lpmedium);
  2003. if(hresult == NOERROR) {
  2004. lpforetc->cfFormat = CF_BITMAP;
  2005. lpforetc->tymed = TYMED_GDI;
  2006. }
  2007. }
  2008. // GetData failed. If the requested format was CF_ENHMETAFILE,
  2009. // retry for metafilepict instead.
  2010. if(lpforetc->cfFormat == CF_ENHMETAFILE) {
  2011. FORMATETC foretc;
  2012. foretc = *lpforetc;
  2013. foretc.cfFormat = CF_METAFILEPICT;
  2014. foretc.tymed = TYMED_MFPICT;
  2015. hresult = lpSrcDataObj->GetData(&foretc, lpmedium);
  2016. if(hresult == NOERROR) {
  2017. lpforetc->cfFormat = CF_METAFILEPICT;
  2018. lpforetc->tymed = TYMED_MFPICT;
  2019. }
  2020. }
  2021. }
  2022. AssertOutStgmedium(hresult, lpmedium);
  2023. LEDebugOut((DEB_ITRACE, "%p OUT wGetData(%lx)\n", NULL, hresult));
  2024. return hresult;
  2025. }