Source code of Windows XP (NT5)
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.

2415 lines
68 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) 1992, Microsoft Corporation.
  5. //
  6. // File: expst.cxx
  7. //
  8. // Contents: CExposedStream code
  9. //
  10. // History: 28-Feb-92 PhilipLa Created.
  11. // 20-Jun-96 MikeHill Fixed the PropSet version of
  12. // Lock to check the result of TakeSem.
  13. // 1-Jul-96 MikeHill - Removed Win32 SEH from PropSet code.
  14. // - Receive NTPROP in propset Open method.
  15. // 11-Feb-97 Danl - Changed CMappedStream to IMappedStream
  16. // - Added QI support for IMappedStream.
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <exphead.cxx>
  20. #pragma hdrstop
  21. #include <pbstream.hxx>
  22. #include <expst.hxx>
  23. #include <lock.hxx>
  24. #include <seekptr.hxx>
  25. #include <marshl.hxx>
  26. #include <logfile.hxx>
  27. #include <privguid.h> // IID_IMappedStream
  28. #include <expparam.hxx>
  29. #ifndef LARGE_STREAMS
  30. // Maximum stream size supported by exposed streams
  31. // This is MAX_ULONG with one subtracted so that
  32. // the seek pointer has a spot to sit even at the
  33. // end of the stream
  34. #define CBMAXSTREAM 0xfffffffeUL
  35. // Maximum seek pointer value
  36. #define CBMAXSEEK (CBMAXSTREAM+1)
  37. #endif
  38. #if DBG
  39. DWORD MyGetLastError()
  40. {
  41. return GetLastError();
  42. }
  43. #endif
  44. //+--------------------------------------------------------------
  45. //
  46. // Member: CExposedStream::CExposedStream, public
  47. //
  48. // Synopsis: Empty object constructor
  49. //
  50. // History: 30-Mar-92 DrewB Created
  51. //
  52. //---------------------------------------------------------------
  53. CExposedStream::CExposedStream(void)
  54. {
  55. olDebugOut((DEB_ITRACE, "In CExposedStream::CExposedStream()\n"));
  56. _pdfb = NULL;
  57. _ppc = NULL;
  58. _cReferences = 0;
  59. _psp = NULL;
  60. _pst = NULL;
  61. olDebugOut((DEB_ITRACE, "Out CExposedStream::CExposedStream\n"));
  62. }
  63. //+--------------------------------------------------------------
  64. //
  65. // Member: CExposedStream::Init, public
  66. //
  67. // Synopsis: Base constructor
  68. //
  69. // Arguments: [pst] - Public stream
  70. // [pdfb] - DocFile basis
  71. // [ppc] - Context
  72. // [psp] - Seek pointer or NULL for new seek pointer
  73. //
  74. // Returns: Appropriate status code
  75. //
  76. // History: 28-Feb-92 DrewB Created
  77. //
  78. //---------------------------------------------------------------
  79. SCODE CExposedStream::Init(CPubStream *pst,
  80. CDFBasis *pdfb,
  81. CPerContext *ppc,
  82. CSeekPointer *psp)
  83. {
  84. SCODE sc;
  85. olDebugOut((DEB_ITRACE, "In CExposedStream::Init("
  86. "%p, %p, %p, %p)\n",
  87. pst, pdfb, ppc, psp));
  88. if (psp == NULL)
  89. {
  90. CSeekPointer *pspTemp;
  91. olMem(pspTemp = new (pdfb->GetMalloc()) CSeekPointer(0));
  92. _psp = P_TO_BP(CBasedSeekPointerPtr, pspTemp);
  93. }
  94. else
  95. _psp = P_TO_BP(CBasedSeekPointerPtr, psp);
  96. _ppc = ppc;
  97. _pst = P_TO_BP(CBasedPubStreamPtr, pst);
  98. _pdfb = P_TO_BP(CBasedDFBasisPtr, pdfb);
  99. _pdfb->vAddRef();
  100. _cReferences = 1;
  101. _sig = CEXPOSEDSTREAM_SIG;
  102. olDebugOut((DEB_ITRACE, "Out CExposedStream::Init\n"));
  103. return S_OK;
  104. EH_Err:
  105. return sc;
  106. }
  107. SCODE CExposedStream::InitMarshal(CPubStream *pst,
  108. CDFBasis *pdfb,
  109. CPerContext *ppc,
  110. DWORD dwAsyncFlags,
  111. IDocfileAsyncConnectionPoint *pdacp,
  112. CSeekPointer *psp)
  113. {
  114. SCODE sc;
  115. sc = CExposedStream::Init(pst,
  116. pdfb,
  117. ppc,
  118. psp);
  119. if (SUCCEEDED(sc))
  120. {
  121. sc = _cpoint.InitMarshal(this, dwAsyncFlags, pdacp);
  122. }
  123. return sc;
  124. }
  125. //+--------------------------------------------------------------
  126. //
  127. // Member: CExposedStream::~CExposedStream, public
  128. //
  129. // Synopsis: Destructor
  130. //
  131. // Returns: Appropriate status code
  132. //
  133. // History: 28-Feb-92 DrewB Created from pbstream source
  134. //
  135. //---------------------------------------------------------------
  136. CExposedStream::~CExposedStream(void)
  137. {
  138. olDebugOut((DEB_ITRACE, "In CExposedStream::~CExposedStream\n"));
  139. olAssert(_cReferences == 0);
  140. _sig = CEXPOSEDSTREAM_SIGDEL;
  141. //In order to call into the tree, we need to take the mutex.
  142. //The mutex may get deleted in _ppc->Release(), so we can't
  143. //release it here. The mutex actually gets released in
  144. //CPerContext::Release() or in the CPerContext destructor.
  145. SCODE sc;
  146. #if !defined(MULTIHEAP)
  147. // TakeSem and ReleaseSem are moved to the Release Method
  148. // so that the deallocation for this object is protected
  149. if (_ppc)
  150. {
  151. sc = TakeSem();
  152. SetWriteAccess();
  153. olAssert(SUCCEEDED(sc));
  154. }
  155. #ifdef ASYNC
  156. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  157. #endif
  158. #endif //MULTIHEAP
  159. if (_pst)
  160. _pst->CPubStream::vRelease();
  161. if (_psp)
  162. _psp->CSeekPointer::vRelease();
  163. if (_pdfb)
  164. _pdfb->CDFBasis::vRelease();
  165. #if !defined(MULTIHEAP)
  166. if (_ppc)
  167. {
  168. if (_ppc->Release() > 0)
  169. ReleaseSem(sc);
  170. }
  171. #ifdef ASYNC
  172. //Mutex has been released, so we can release the connection point
  173. // without fear of deadlock.
  174. if (pdacp != NULL)
  175. pdacp->Release();
  176. #endif
  177. #endif // MULTIHEAP
  178. olDebugOut((DEB_ITRACE, "Out CExposedStream::~CExposedStream\n"));
  179. }
  180. //+--------------------------------------------------------------
  181. //
  182. // Member: CExposedStream::Read, public
  183. //
  184. // Synopsis: Read from a stream
  185. //
  186. // Arguments: [pb] - Buffer
  187. // [cb] - Count of bytes to read
  188. // [pcbRead] - Return number of bytes read
  189. //
  190. // Returns: Appropriate status code
  191. //
  192. // Modifies: [pcbRead]
  193. //
  194. // History: 28-Feb-92 DrewB Created from pbstream source
  195. //
  196. //---------------------------------------------------------------
  197. STDMETHODIMP CExposedStream::Read(VOID HUGEP *pb, ULONG cb, ULONG *pcbRead)
  198. {
  199. SCODE sc;
  200. SAFE_SEM;
  201. SAFE_ACCESS;
  202. ULONG cbRead = 0;
  203. olLog(("%p::In CExposedStream::Read(%p, %lu, %p)\n",
  204. this, pb, cb, pcbRead));
  205. olDebugOut((DEB_TRACE, "In CExposedStream::Read %p(%p, %lu, %p)\n",
  206. this, pb, cb, pcbRead));
  207. OL_VALIDATE(Read(pb, cb, pcbRead));
  208. olChk(Validate());
  209. BEGIN_PENDING_LOOP;
  210. olChk(TakeSafeSem());
  211. SafeReadAccess();
  212. sc = _pst->ReadAt(_psp->GetPos(), pb, cb, (ULONG STACKBASED *)&cbRead);
  213. #ifndef LARGE_STREAMS
  214. olAssert(CBMAXSEEK-_psp->GetPos() >= cbRead);
  215. #endif
  216. _psp->SetPos(_psp->GetPos()+cbRead);
  217. pb = (BYTE *)pb + cbRead;
  218. cb -= cbRead;
  219. END_PENDING_LOOP;
  220. olDebugOut((DEB_TRACE, "Out CExposedStream::Read => %lu\n", cbRead));
  221. EH_Err:
  222. if (pcbRead)
  223. {
  224. // May fault and leave stream seek pointer changed
  225. // This is acceptable
  226. *pcbRead = cbRead;
  227. olLog(("%p::Out CExposedStream::Read(). *pcbRead == %lu, ret = %lx\n",
  228. this, *pcbRead, sc));
  229. }
  230. else
  231. {
  232. olLog(("%p::Out CExposedStream::Read(). ret == %lx\n", this, sc));
  233. }
  234. return ResultFromScode(sc);
  235. }
  236. //+--------------------------------------------------------------
  237. //
  238. // Member: CExposedStream::Write, public
  239. //
  240. // Synopsis: Write to a stream
  241. //
  242. // Arguments: [pb] - Buffer
  243. // [cb] - Count of bytes to write
  244. // [pcbWritten] - Return of bytes written
  245. //
  246. // Returns: Appropriate status code
  247. //
  248. // Modifies: [pcbWritten]
  249. //
  250. // History: 28-Feb-92 DrewB Created from pbstream source
  251. //
  252. //---------------------------------------------------------------
  253. STDMETHODIMP CExposedStream::Write(
  254. VOID const HUGEP *pb,
  255. ULONG cb,
  256. ULONG *pcbWritten)
  257. {
  258. SCODE sc;
  259. SAFE_SEM;
  260. SAFE_ACCESS;
  261. ULONG cbWritten = 0;
  262. olLog(("%p::In CExposedStream::Write(%p, %lu, %p)\n",
  263. this, pb, cb, pcbWritten));
  264. olDebugOut((DEB_TRACE, "In CExposedStream::Write %p(%p, %lu, %p)\n",
  265. this, pb, cb, pcbWritten));
  266. OL_VALIDATE(Write(pb, cb, pcbWritten));
  267. olChk(Validate());
  268. BEGIN_PENDING_LOOP;
  269. olChk(TakeSafeSem());
  270. SafeWriteAccess();
  271. #ifdef DIRECTWRITERLOCK
  272. olChk(ValidateWriteAccess());
  273. #endif
  274. sc = _pst->WriteAt(_psp->GetPos(), pb, cb,
  275. (ULONG STACKBASED *)&cbWritten);
  276. #ifndef LARGE_STREAMS
  277. olAssert(CBMAXSEEK-_psp->GetPos() >= cbWritten);
  278. #endif
  279. _psp->SetPos(_psp->GetPos()+cbWritten);
  280. pb = (BYTE *)pb + cbWritten;
  281. cb -= cbWritten;
  282. END_PENDING_LOOP;
  283. olDebugOut((DEB_TRACE, "Out CExposedStream::Write => %lu\n",
  284. cbWritten));
  285. EH_Err:
  286. if (pcbWritten)
  287. {
  288. // May fault but that's acceptable
  289. *pcbWritten = cbWritten;
  290. olLog(("%p::Out CExposedStream::Write(). "
  291. "*pcbWritten == %lu, ret = %lx\n",
  292. this, *pcbWritten, sc));
  293. }
  294. else
  295. {
  296. olLog(("%p::Out CExposedStream::Write(). ret == %lx\n", this, sc));
  297. }
  298. return ResultFromScode(sc);
  299. }
  300. //+--------------------------------------------------------------
  301. //
  302. // Member: CExposedStream::Seek, public
  303. //
  304. // Synopsis: Seek to a point in a stream
  305. //
  306. // Arguments: [dlibMove] - Offset to move by
  307. // [dwOrigin] - SEEK_SET, SEEK_CUR, SEEK_END
  308. // [plibNewPosition] - Return of new offset
  309. //
  310. // Returns: Appropriate status code
  311. //
  312. // Modifies: [plibNewPosition]
  313. //
  314. // History: 28-Feb-92 DrewB Created from pbstream source
  315. //
  316. //
  317. //---------------------------------------------------------------
  318. STDMETHODIMP CExposedStream::Seek(LARGE_INTEGER dlibMove,
  319. DWORD dwOrigin,
  320. ULARGE_INTEGER *plibNewPosition)
  321. {
  322. SCODE sc;
  323. SAFE_SEM;
  324. SAFE_ACCESS;
  325. #ifdef LARGE_STREAMS
  326. LONGLONG lMove;
  327. #else
  328. LONG lMove;
  329. #endif
  330. ULARGE_INTEGER ulPos;
  331. olLog(("%p::In CExposedStream::Seek(%ld, %lu, %p)\n",
  332. this, LIGetLow(dlibMove), dwOrigin, plibNewPosition));
  333. olDebugOut((DEB_TRACE, "In CExposedStream::Seek %p(%ld, %lu, %p)\n",
  334. this, LIGetLow(dlibMove), dwOrigin, plibNewPosition));
  335. OL_VALIDATE(Seek(dlibMove, dwOrigin, plibNewPosition));
  336. if (dwOrigin == STREAM_SEEK_SET)
  337. {
  338. #ifdef LARGE_STREAMS
  339. if (dlibMove.QuadPart < 0)
  340. olErr (EH_Err, STG_E_INVALIDFUNCTION);
  341. #else
  342. // Truncate dlibMove to 32 bits
  343. // Make sure we don't seek too far
  344. if (LIGetHigh(dlibMove) != 0)
  345. LISet32(dlibMove, 0xffffffff);
  346. #endif
  347. }
  348. else
  349. {
  350. #ifndef LARGE_STREAMS
  351. // High dword must be zero for positive values or -1 for
  352. // negative values
  353. // Additionally, for negative values, the low dword can't
  354. // exceed -0x80000000 because the 32nd bit is the sign
  355. // bit
  356. if (LIGetHigh(dlibMove) > 0 ||
  357. (LIGetHigh(dlibMove) == 0 &&
  358. LIGetLow(dlibMove) >= 0x80000000))
  359. LISet32(dlibMove, 0x7fffffff);
  360. else if (LIGetHigh(dlibMove) < -1 ||
  361. (LIGetHigh(dlibMove) == -1 &&
  362. LIGetLow(dlibMove) <= 0x7fffffff))
  363. LISet32(dlibMove, 0x80000000);
  364. #endif
  365. }
  366. #ifdef LARGE_STREAMS
  367. lMove = dlibMove.QuadPart;
  368. #else
  369. lMove = (LONG)LIGetLow(dlibMove);
  370. #endif
  371. olChk(Validate());
  372. //ASYNC Note: We probably don't need this pending loop in Seek
  373. BEGIN_PENDING_LOOP;
  374. olChk(TakeSafeSem());
  375. olChk(_pst->CheckReverted());
  376. SafeReadAccess();
  377. #ifdef LARGE_STREAMS
  378. ulPos.QuadPart = _psp->GetPos();
  379. #else
  380. ULISet32(ulPos, _psp->GetPos());
  381. #endif
  382. switch(dwOrigin)
  383. {
  384. case STREAM_SEEK_SET:
  385. #ifdef LARGE_STREAMS
  386. ulPos.QuadPart = lMove;
  387. #else
  388. ULISetLow(ulPos, (ULONG)lMove);
  389. #endif
  390. break;
  391. case STREAM_SEEK_END:
  392. #ifdef LARGE_STREAMS
  393. ULONGLONG cbSize;
  394. #else
  395. ULONG cbSize;
  396. #endif
  397. olChk(_pst->GetSize(&cbSize));
  398. if (lMove < 0)
  399. {
  400. #ifdef LARGE_STREAMS
  401. if ((ULONGLONG)(-lMove) > cbSize)
  402. #else
  403. if ((ULONG)(-lMove) > cbSize)
  404. #endif
  405. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  406. }
  407. #ifdef LARGE_STREAMS
  408. ulPos.QuadPart = cbSize+lMove;
  409. #else
  410. else if ((ULONG)lMove > CBMAXSEEK-cbSize)
  411. lMove = (LONG)(CBMAXSEEK-cbSize);
  412. ULISetLow(ulPos, cbSize+lMove);
  413. #endif
  414. break;
  415. case STREAM_SEEK_CUR:
  416. if (lMove < 0)
  417. {
  418. #ifdef LARGE_STREAMS
  419. if ((ULONGLONG)(-lMove) > _psp->GetPos())
  420. #else
  421. if ((ULONG)(-lMove) > _psp->GetPos())
  422. #endif
  423. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  424. }
  425. #ifdef LARGE_STREAMS
  426. ulPos.QuadPart = _psp->GetPos()+lMove;
  427. #else
  428. else if ((ULONG)lMove > CBMAXSEEK-_psp->GetPos())
  429. lMove = (LONG)(CBMAXSEEK-_psp->GetPos());
  430. ULISetLow(ulPos, _psp->GetPos()+lMove);
  431. #endif
  432. break;
  433. }
  434. #ifdef LARGE_STREAMS
  435. _psp->SetPos(ulPos.QuadPart);
  436. #else
  437. _psp->SetPos(ULIGetLow(ulPos));
  438. #endif
  439. if (plibNewPosition)
  440. // May fault but that's acceptable
  441. *plibNewPosition = ulPos;
  442. END_PENDING_LOOP;
  443. olDebugOut((DEB_TRACE, "Out CExposedStream::Seek => %lu\n",
  444. ULIGetLow(ulPos)));
  445. EH_Err:
  446. olLog(("%p::Out CExposedStream::Seek(). ulPos == %lu, ret == %lx\n",
  447. this, ULIGetLow(ulPos), sc));
  448. return ResultFromScode(sc);
  449. }
  450. //+--------------------------------------------------------------
  451. //
  452. // Member: CExposedStream::SetSize, public
  453. //
  454. // Synopsis: Sets the size of a stream
  455. //
  456. // Arguments: [ulNewSize] - New size
  457. //
  458. // Returns: Appropriate status code
  459. //
  460. // History: 28-Feb-92 DrewB Created from pbstream source
  461. //
  462. //---------------------------------------------------------------
  463. STDMETHODIMP CExposedStream::SetSize(ULARGE_INTEGER ulNewSize)
  464. {
  465. SCODE sc;
  466. SAFE_SEM;
  467. SAFE_ACCESS;
  468. olLog(("%p::In CExposedStream::SetSize(%lu)\n",
  469. this, ULIGetLow(ulNewSize)));
  470. olDebugOut((DEB_TRACE, "In CExposedStream::SetSize %p(%lu)\n",
  471. this, ULIGetLow(ulNewSize)));
  472. OL_VALIDATE(SetSize(ulNewSize));
  473. #ifndef LARGE_STREAMS
  474. if (ULIGetHigh(ulNewSize) != 0)
  475. olErr(EH_Err, STG_E_DOCFILETOOLARGE);
  476. #endif
  477. olChk(Validate());
  478. BEGIN_PENDING_LOOP;
  479. olChk(TakeSafeSem());
  480. SafeWriteAccess();
  481. #ifdef DIRECTWRITERLOCK
  482. olChk(ValidateWriteAccess());
  483. #endif
  484. #ifdef LARGE_STREAMS
  485. sc = _pst->SetSize(ulNewSize.QuadPart);
  486. #else
  487. sc = _pst->SetSize(ULIGetLow(ulNewSize));
  488. #endif
  489. END_PENDING_LOOP;
  490. olDebugOut((DEB_TRACE, "Out CExposedStream::SetSize\n"));
  491. EH_Err:
  492. olLog(("%p::Out CExposedStream::SetSize(). ret == %lx\n", this, sc));
  493. return ResultFromScode(sc);
  494. }
  495. //+--------------------------------------------------------------
  496. //
  497. // Member: CExposedStream::CopyTo, public
  498. //
  499. // Synopsis: Copies information from one stream to another
  500. //
  501. // Arguments: [pstm] - Destination
  502. // [cb] - Number of bytes to copy
  503. // [pcbRead] - Return number of bytes read
  504. // [pcbWritten] - Return number of bytes written
  505. //
  506. // Returns: Appropriate status code
  507. //
  508. // Modifies: [pcbRead]
  509. // [pcbWritten]
  510. //
  511. // History: 25-Mar-92 DrewB Created
  512. // 12-Jan-93 AlexT Rewritten without recursion
  513. //
  514. // Notes: We do our best to handle overlap correctly. This allows
  515. // CopyTo to be used to insert and remove space within a
  516. // stream.
  517. //
  518. // In the error case, we make no gurantees as to the
  519. // validity of pcbRead, pcbWritten, or either stream's
  520. // seek position.
  521. //
  522. //---------------------------------------------------------------
  523. STDMETHODIMP CExposedStream::CopyTo(IStream *pstm,
  524. ULARGE_INTEGER cb,
  525. ULARGE_INTEGER *pcbRead,
  526. ULARGE_INTEGER *pcbWritten)
  527. {
  528. SCODE sc;
  529. SAFE_SEM;
  530. olLog(("%p::In CExposedStream::CopyTo(%p, %lu, %p, %p)\n",
  531. this, pstm, ULIGetLow(cb), pcbRead, pcbWritten));
  532. olDebugOut((DEB_TRACE, "In CExposedStream::CopyTo("
  533. "%p, %lu, %p, %p)\n", pstm, ULIGetLow(cb),
  534. pcbRead, pcbWritten));
  535. OL_VALIDATE(CopyTo(pstm, cb, pcbRead, pcbWritten));
  536. olChk(Validate());
  537. BEGIN_PENDING_LOOP;
  538. olChk(TakeSafeSem());
  539. sc = CopyToWorker(pstm, cb, pcbRead, pcbWritten, &_ss);
  540. END_PENDING_LOOP;
  541. olDebugOut((DEB_TRACE, "Out CExposedStream::CopyTo => %lu, %lu\n",
  542. pcbRead ? ULIGetLow(*pcbRead) : 0,
  543. pcbWritten ? ULIGetLow(*pcbWritten) : 0));
  544. EH_Err:
  545. return sc;
  546. }
  547. SCODE CExposedStream::CopyToWorker(IStream *pstm,
  548. ULARGE_INTEGER cb,
  549. ULARGE_INTEGER *pcbRead,
  550. ULARGE_INTEGER *pcbWritten,
  551. CSafeSem *pss)
  552. {
  553. SCODE sc;
  554. #ifdef LARGE_STREAMS
  555. ULONGLONG ulCopySize;
  556. ULONGLONG ulSrcSize, ulSrcOrig;
  557. #else
  558. ULONG ulCopySize;
  559. ULONG ulSrcSize;
  560. ULONG ulSrcOrig;
  561. #endif
  562. ULARGE_INTEGER uliDestOrig;
  563. LARGE_INTEGER liDestPos;
  564. BYTE *pb = NULL;
  565. BOOL fOverlap;
  566. #ifdef LARGE_STREAMS
  567. ULONGLONG ulBytesCopied = 0;
  568. #else
  569. ULONG ulBytesCopied = 0;
  570. #endif
  571. ULONG ulBufferSize;
  572. #ifdef LARGE_STREAMS
  573. ulCopySize = cb.QuadPart;
  574. #else
  575. // Bound the size of the copy
  576. // 1. The maximum we can copy is 0xffffffff
  577. if (ULIGetHigh(cb) == 0)
  578. ulCopySize = ULIGetLow(cb);
  579. else
  580. ulCopySize = 0xffffffff;
  581. #endif
  582. // 2. We can only copy what's available in the source stream
  583. SetReadAccess();
  584. sc = _pst->GetSize(&ulSrcSize);
  585. ClearReadAccess();
  586. olChk(sc);
  587. ulSrcOrig = _psp->GetPos();
  588. if (ulSrcSize < ulSrcOrig)
  589. {
  590. // Nothing in source to copy
  591. ulCopySize = 0;
  592. }
  593. else if ((ulSrcSize - ulSrcOrig) < ulCopySize)
  594. {
  595. // Shrink ulCopySize to fit bytes in source
  596. ulCopySize = ulSrcSize - ulSrcOrig;
  597. }
  598. // 3. We can only copy what will fit in the destination
  599. LISet32(liDestPos, 0);
  600. olHChk(pstm->Seek(liDestPos, STREAM_SEEK_CUR, &uliDestOrig));
  601. #ifndef LARGE_STREAMS
  602. olAssert(ULIGetHigh(uliDestOrig) == 0);
  603. if (ulCopySize > CBMAXSEEK - ULIGetLow(uliDestOrig))
  604. ulCopySize = CBMAXSEEK - ULIGetLow(uliDestOrig);
  605. #endif
  606. ulBufferSize = (_pdfb->GetOpenFlags() & DF_LARGE) ?
  607. LARGESTREAMBUFFERSIZE : STREAMBUFFERSIZE;
  608. // We are allowed to fail here with out-of-memory
  609. olChk(GetBuffer(STREAMBUFFERSIZE, ulBufferSize, &pb, &ulBufferSize));
  610. // Since we have no reliable way to determine if the source and
  611. // destination represent the same stream, we assume they
  612. // do and always handle overlap.
  613. #ifdef LARGE_STREAMS
  614. fOverlap = (uliDestOrig.QuadPart > ulSrcOrig &&
  615. uliDestOrig.QuadPart < ulSrcOrig + ulCopySize);
  616. #else
  617. fOverlap = (ULIGetLow(uliDestOrig) > ulSrcOrig &&
  618. ULIGetLow(uliDestOrig) < ulSrcOrig + ulCopySize);
  619. #endif
  620. #ifdef LARGE_STREAMS
  621. ULONGLONG ulSrcCopyOffset;
  622. ULONGLONG ulDstCopyOffset;
  623. #else
  624. ULONG ulSrcCopyOffset;
  625. ULONG ulDstCopyOffset;
  626. #endif
  627. if (fOverlap)
  628. {
  629. // We're going to copy back to front, so determine the
  630. // stream end positions
  631. ulSrcCopyOffset = ulSrcOrig + ulCopySize;
  632. // uliDestOrig is the destination starting offset
  633. #ifdef LARGE_STREAMS
  634. ulDstCopyOffset = uliDestOrig.QuadPart + ulCopySize;
  635. #else
  636. ulDstCopyOffset = ULIGetLow(uliDestOrig) + ulCopySize;
  637. #endif
  638. }
  639. while (ulCopySize > 0)
  640. {
  641. // We can only copy up to ulBufferSize bytes at a time
  642. ULONG cbPart = (ULONG) min(ulCopySize, ulBufferSize);
  643. if (fOverlap)
  644. {
  645. // We're copying back to front so we need to seek to
  646. // set up the streams correctly
  647. ulSrcCopyOffset -= cbPart;
  648. ulDstCopyOffset -= cbPart;
  649. // Set source stream position
  650. _psp->SetPos(ulSrcCopyOffset);
  651. // Set destination stream position
  652. liDestPos.QuadPart = ulDstCopyOffset;
  653. olHChk(pstm->Seek(liDestPos, STREAM_SEEK_SET, NULL));
  654. }
  655. ULONG ulRead = 0;
  656. SetReadAccess();
  657. sc = _pst->ReadAt(_psp->GetPos(), pb, cbPart, &ulRead);
  658. ClearReadAccess();
  659. #ifndef LARGE_STREAMS
  660. olAssert(CBMAXSEEK-_psp->GetPos() >= ulRead);
  661. #endif
  662. _psp->SetPos(_psp->GetPos()+ulRead);
  663. olChk(sc);
  664. if (cbPart != ulRead)
  665. {
  666. // There was no error, but we were unable to read cbPart
  667. // bytes. Something's wrong (the underlying ILockBytes?)
  668. // but we can't control it; just return an error.
  669. olErr(EH_Err, STG_E_READFAULT);
  670. }
  671. // We release the tree mutex before calling out to Write
  672. // to avoid a deadlock in the async FillAppend method
  673. ULONG ulWritten;
  674. SCODE sc2;
  675. pss->Release();
  676. sc2 = pstm->Write(pb, cbPart, &ulWritten);
  677. olChk(pss->Take());
  678. olChk (sc2);
  679. if (cbPart != ulWritten)
  680. {
  681. // There was no error, but we were unable to write
  682. // ulWritten bytes. We can't trust the pstm
  683. // implementation, so all we can do here is return
  684. // an error.
  685. olErr(EH_Err, STG_E_WRITEFAULT);
  686. }
  687. olAssert(ulCopySize >= cbPart);
  688. ulCopySize -= cbPart;
  689. ulBytesCopied += cbPart;
  690. }
  691. if (fOverlap)
  692. {
  693. // Set the seek pointers to the correct location
  694. _psp->SetPos(ulSrcOrig + ulBytesCopied);
  695. liDestPos.QuadPart = uliDestOrig.QuadPart + ulBytesCopied;
  696. olHChk(pstm->Seek(liDestPos, STREAM_SEEK_SET, NULL));
  697. }
  698. // Fall through
  699. EH_Err:
  700. DfMemFree(pb);
  701. if (pcbRead)
  702. pcbRead->QuadPart = ulBytesCopied;
  703. if (pcbWritten)
  704. pcbWritten->QuadPart = ulBytesCopied;
  705. olLog(("%p::Out CExposedStream::CopyTo(). "
  706. "cbRead == %lu, cbWritten == %lu, ret == %lx\n",
  707. this, pcbRead ? ULIGetLow(*pcbRead) : 0,
  708. pcbWritten ? ULIGetLow(*pcbWritten) : 0, sc));
  709. return ResultFromScode(sc);
  710. }
  711. //+--------------------------------------------------------------
  712. //
  713. // Member: CExposedStream::Release, public
  714. //
  715. // Synopsis: Releases a stream
  716. //
  717. // Returns: Appropriate status code
  718. //
  719. // History: 28-Feb-92 DrewB Created from pbstream source
  720. //
  721. //---------------------------------------------------------------
  722. STDMETHODIMP_(ULONG) CExposedStream::Release(void)
  723. {
  724. LONG lRet;
  725. olLog(("%p::In CExposedStream::Release()\n", this));
  726. olDebugOut((DEB_TRACE, "In CExposedStream::Release()\n"));
  727. if (FAILED(Validate()))
  728. return 0;
  729. olAssert(_cReferences > 0);
  730. lRet = InterlockedDecrement(&_cReferences);
  731. if (lRet == 0)
  732. {
  733. #ifdef MULTIHEAP
  734. CSafeMultiHeap smh(_ppc);
  735. CPerContext *ppc = _ppc;
  736. SCODE sc = S_OK;
  737. if (_ppc)
  738. {
  739. sc = TakeSem();
  740. SetWriteAccess();
  741. olAssert(SUCCEEDED(sc));
  742. }
  743. #ifdef ASYNC
  744. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  745. #endif
  746. #endif //MULTIHEAP
  747. delete this;
  748. #ifdef MULTIHEAP
  749. if (ppc)
  750. {
  751. if (ppc->Release() == 0)
  752. g_smAllocator.Uninit();
  753. else
  754. if (SUCCEEDED(sc)) ppc->UntakeSem();
  755. }
  756. #ifdef ASYNC
  757. //Mutex has been released, so we can release the connection point
  758. // without fear of deadlock.
  759. if (pdacp != NULL)
  760. pdacp->Release();
  761. #endif
  762. #endif
  763. }
  764. else if (lRet < 0)
  765. lRet = 0;
  766. olDebugOut((DEB_TRACE, "Out CExposedStream::Release %p()=> %lu\n",
  767. this, lRet));
  768. olLog(("%p::Out CExposedStream::Release(). ret == %lu\n", this, lRet));
  769. FreeLogFile();
  770. return lRet;
  771. }
  772. //+--------------------------------------------------------------
  773. //
  774. // Member: CExposedStream::Stat, public
  775. //
  776. // Synopsis: Fills in a buffer of information about this object
  777. //
  778. // Arguments: [pstatstg] - Buffer
  779. //
  780. // Returns: Appropriate status code
  781. //
  782. // Modifies: [pstatstg]
  783. //
  784. // History: 24-Mar-92 DrewB Created
  785. //
  786. //---------------------------------------------------------------
  787. _OLESTDMETHODIMP CExposedStream::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  788. {
  789. SCODE sc;
  790. SAFE_SEM;
  791. SAFE_ACCESS;
  792. STATSTGW stat;
  793. olLog(("%p::In CExposedStream::Stat(%p)\n", this, pstatstg));
  794. olDebugOut((DEB_TRACE, "In CExposedStream::Stat(%p)\n",
  795. pstatstg));
  796. OL_VALIDATE(Stat(pstatstg, grfStatFlag));
  797. olChk(Validate());
  798. BEGIN_PENDING_LOOP;
  799. olChk(TakeSafeSem());
  800. SafeReadAccess();
  801. sc = _pst->Stat(&stat, grfStatFlag);
  802. END_PENDING_LOOP;
  803. if (SUCCEEDED(sc))
  804. {
  805. TRY
  806. {
  807. *pstatstg = stat;
  808. pstatstg->type = STGTY_STREAM;
  809. pstatstg->grfLocksSupported = 0;
  810. pstatstg->STATSTG_dwStgFmt = 0;
  811. pstatstg->ctime.dwLowDateTime = pstatstg->ctime.dwHighDateTime = 0;
  812. pstatstg->mtime.dwLowDateTime = pstatstg->mtime.dwHighDateTime = 0;
  813. pstatstg->atime.dwLowDateTime = pstatstg->atime.dwHighDateTime = 0;
  814. }
  815. CATCH(CException, e)
  816. {
  817. UNREFERENCED_PARM(e);
  818. if (stat.pwcsName)
  819. TaskMemFree(stat.pwcsName);
  820. sc = STG_E_INVALIDPOINTER;
  821. }
  822. END_CATCH
  823. }
  824. olDebugOut((DEB_TRACE, "Out CExposedStream::Stat\n"));
  825. // Fall through
  826. EH_Err:
  827. olLog(("%p::Out CExposedStream::Stat(). ret == %lx\n",
  828. this, sc));
  829. return _OLERETURN(sc);
  830. }
  831. //+--------------------------------------------------------------
  832. //
  833. // Member: CExposedStream::Clone, public
  834. //
  835. // Synopsis: Clones a stream
  836. //
  837. // Returns: Appropriate status code
  838. //
  839. // History: 28-Feb-92 DrewB Created
  840. //
  841. //---------------------------------------------------------------
  842. STDMETHODIMP CExposedStream::Clone(IStream **ppstm)
  843. {
  844. SafeCExposedStream pst;
  845. CSeekPointer *psp;
  846. SCODE sc;
  847. SAFE_SEM;
  848. SAFE_ACCESS;
  849. olLog(("%p::In CExposedStream::Clone(%p)\n", this, ppstm));
  850. olDebugOut((DEB_TRACE, "In CExposedStream::Clone(%p)\n", ppstm));
  851. OL_VALIDATE(Clone(ppstm));
  852. olChk(Validate());
  853. olChk(TakeSafeSem());
  854. olChk(_pst->CheckReverted());
  855. SafeReadAccess();
  856. olMem(psp = new (_pdfb->GetMalloc()) CSeekPointer(_psp->GetPos()));
  857. pst.Attach(new (_pdfb->GetMalloc()) CExposedStream);
  858. olMemTo(EH_psp, (CExposedStream *)pst);
  859. olChkTo(EH_pst, pst->Init(BP_TO_P(CPubStream *, _pst),
  860. BP_TO_P(CDFBasis *, _pdfb),
  861. _ppc, psp));
  862. _ppc->AddRef();
  863. _pst->vAddRef();
  864. #ifdef ASYNC
  865. if (_cpoint.IsInitialized())
  866. {
  867. olChkTo(EH_pstInit, pst->InitClone(&_cpoint));
  868. }
  869. #endif
  870. TRANSFER_INTERFACE(pst, IStream, ppstm);
  871. olDebugOut((DEB_TRACE, "Out CExposedStream::Clone => %p\n", *ppstm));
  872. EH_Err:
  873. olLog(("%p::Out CExposedStream::Clone(). *ppstm == %p, ret == %lx\n",
  874. this, *ppstm, sc));
  875. return ResultFromScode(sc);
  876. EH_pstInit:
  877. pst->Release();
  878. goto EH_Err;
  879. EH_pst:
  880. delete pst;
  881. EH_psp:
  882. psp->vRelease();
  883. goto EH_Err;
  884. }
  885. //+--------------------------------------------------------------
  886. //
  887. // Member: CExposedStream::AddRef, public
  888. //
  889. // Synopsis: Increments the ref count
  890. //
  891. // Returns: Appropriate status code
  892. //
  893. // History: 16-Mar-92 DrewB Created
  894. //
  895. //---------------------------------------------------------------
  896. STDMETHODIMP_(ULONG) CExposedStream::AddRef(void)
  897. {
  898. ULONG ulRet;
  899. olLog(("%p::In CExposedStream::AddRef()\n", this));
  900. olDebugOut((DEB_TRACE, "In CExposedStream::AddRef()\n"));
  901. if (FAILED(Validate()))
  902. return 0;
  903. InterlockedIncrement(&_cReferences);
  904. ulRet = _cReferences;
  905. olDebugOut((DEB_TRACE, "Out CExposedStream::AddRef %p() => %lu\n",
  906. this, _cReferences));
  907. olLog(("%p::Out CExposedStream::AddRef(). ret == %lu\n", this, ulRet));
  908. return ulRet;
  909. }
  910. //+--------------------------------------------------------------
  911. //
  912. // Member: CExposedStream::LockRegion, public
  913. //
  914. // Synopsis: Nonfunctional
  915. //
  916. // Returns: Appropriate status code
  917. //
  918. // History: 16-Mar-92 DrewB Created
  919. //
  920. //---------------------------------------------------------------
  921. STDMETHODIMP CExposedStream::LockRegion(ULARGE_INTEGER libOffset,
  922. ULARGE_INTEGER cb,
  923. DWORD dwLockType)
  924. {
  925. olDebugOut((DEB_TRACE, "In CExposedStream::LockRegion("
  926. "%lu, %lu\n", ULIGetLow(cb), dwLockType));
  927. olDebugOut((DEB_TRACE, "Out CExposedStream::LockRegion\n"));
  928. olLog(("%p::INVALID CALL TO CExposedStream::LockRegion()\n"));
  929. return ResultFromScode(STG_E_INVALIDFUNCTION);
  930. }
  931. //+--------------------------------------------------------------
  932. //
  933. // Member: CExposedStream::UnlockRegion, public
  934. //
  935. // Synopsis: Nonfunctional
  936. //
  937. // Returns: Appropriate status code
  938. //
  939. // History: 16-Mar-92 DrewB Created
  940. //
  941. //---------------------------------------------------------------
  942. STDMETHODIMP CExposedStream::UnlockRegion(ULARGE_INTEGER libOffset,
  943. ULARGE_INTEGER cb,
  944. DWORD dwLockType)
  945. {
  946. olDebugOut((DEB_TRACE, "In CExposedStream::UnlockRegion(%lu, %lu)\n",
  947. ULIGetLow(cb), dwLockType));
  948. olDebugOut((DEB_TRACE, "Out CExposedStream::UnlockRegion\n"));
  949. olLog(("%p::INVALID CALL TO CExposedStream::UnlockRegion()\n"));
  950. return ResultFromScode(STG_E_INVALIDFUNCTION);
  951. }
  952. //+--------------------------------------------------------------
  953. //
  954. // Member: CExposedStream::Commit, public
  955. //
  956. // Synopsis: No-op in current implementation
  957. //
  958. // Returns: Appropriate status code
  959. //
  960. // History: 16-Mar-92 DrewB Created
  961. //
  962. //---------------------------------------------------------------
  963. STDMETHODIMP CExposedStream::Commit(DWORD grfCommitFlags)
  964. {
  965. SCODE sc;
  966. SAFE_SEM;
  967. SAFE_ACCESS;
  968. olDebugOut((DEB_TRACE, "In CExposedStream::Commit(%lu)\n",
  969. grfCommitFlags));
  970. olLog(("%p::In CExposedStream::Commit(%lx)\n", this, grfCommitFlags));
  971. OL_VALIDATE(Commit(grfCommitFlags));
  972. olChk(Validate());
  973. BEGIN_PENDING_LOOP;
  974. olChk(TakeSafeSem());
  975. SafeWriteAccess();
  976. sc = _pst->Commit(grfCommitFlags);
  977. END_PENDING_LOOP;
  978. olDebugOut((DEB_TRACE, "Out CExposedStream::Commit\n"));
  979. EH_Err:
  980. olLog(("%p::Out CExposedStream::Commit(). ret == %lx\n", this, sc));
  981. return ResultFromScode(sc);
  982. }
  983. //+--------------------------------------------------------------
  984. //
  985. // Member: CExposedStream::Revert, public
  986. //
  987. // Synopsis: No-op in current implementation
  988. //
  989. // Returns: Appropriate status code
  990. //
  991. // History: 16-Mar-92 DrewB Created
  992. //
  993. //---------------------------------------------------------------
  994. STDMETHODIMP CExposedStream::Revert(void)
  995. {
  996. SCODE sc;
  997. olDebugOut((DEB_TRACE, "In CExposedStream::Revert()\n"));
  998. OL_VALIDATE(Revert());
  999. #ifdef MULTIHEAP
  1000. CSafeMultiHeap smh(_ppc);
  1001. #endif
  1002. //ASYNC Note: Don't need pending loop here.
  1003. sc = _pst->CheckReverted();
  1004. olDebugOut((DEB_TRACE, "Out CExposedStream::Revert\n"));
  1005. olLog(("%p::In CExposedStream::Revert()\n", this));
  1006. olLog(("%p::Out CExposedStream::Revert(). ret == %lx", this, sc));
  1007. return ResultFromScode(sc);
  1008. }
  1009. //+--------------------------------------------------------------
  1010. //
  1011. // Member: CExposedStream::QueryInterface, public
  1012. //
  1013. // Synopsis: Returns an object for the requested interface
  1014. //
  1015. // Arguments: [iid] - Interface ID
  1016. // [ppvObj] - Object return
  1017. //
  1018. // Returns: Appropriate status code
  1019. //
  1020. // Modifies: [ppvObj]
  1021. //
  1022. // History: 26-Mar-92 DrewB Created
  1023. //
  1024. //---------------------------------------------------------------
  1025. STDMETHODIMP CExposedStream::QueryInterface(REFIID iid, void **ppvObj)
  1026. {
  1027. SCODE sc;
  1028. #ifdef MULTIHEAP
  1029. CSafeMultiHeap smh(_ppc);
  1030. #endif
  1031. olLog(("%p::In CExposedStream::QueryInterface(?, %p)\n",
  1032. this, ppvObj));
  1033. olDebugOut((DEB_TRACE, "In CExposedStream::QueryInterface(?, %p)\n",
  1034. ppvObj));
  1035. OL_VALIDATE(QueryInterface(iid, ppvObj));
  1036. olChk(Validate());
  1037. olChk(_pst->CheckReverted());
  1038. sc = S_OK;
  1039. if (IsEqualIID(iid, IID_IStream) || IsEqualIID(iid, IID_IUnknown))
  1040. {
  1041. *ppvObj = (IStream *)this;
  1042. AddRef();
  1043. }
  1044. else if (IsEqualIID(iid, IID_IMarshal))
  1045. {
  1046. //If the ILockBytes we'd need to marshal doesn't support IMarshal
  1047. // then we want to do standard marshalling on the stream, mostly
  1048. // to prevent deadlock problems but also because you'll get better
  1049. // performance. So check, then do the right thing.
  1050. IMarshal *pim;
  1051. ILockBytes *plkb;
  1052. plkb = _ppc->GetOriginal();
  1053. if (plkb == NULL)
  1054. {
  1055. plkb = _ppc->GetBase();
  1056. }
  1057. sc = plkb->QueryInterface(IID_IMarshal, (void **)&pim);
  1058. if (FAILED(sc))
  1059. {
  1060. olErr(EH_Err, E_NOINTERFACE);
  1061. }
  1062. pim->Release();
  1063. #ifdef MULTIHEAP
  1064. if (_ppc->GetHeapBase() == NULL)
  1065. olErr (EH_Err, E_NOINTERFACE);
  1066. #endif
  1067. *ppvObj = (IMarshal *)this;
  1068. AddRef();
  1069. }
  1070. else if (IsEqualIID(iid, IID_IMappedStream))
  1071. {
  1072. *ppvObj = (IMappedStream *)this;
  1073. AddRef();
  1074. }
  1075. #ifdef ASYNC
  1076. else if (IsEqualIID(iid, IID_IConnectionPointContainer) &&
  1077. _cpoint.IsInitialized())
  1078. {
  1079. *ppvObj = (IConnectionPointContainer *)this;
  1080. CExposedStream::AddRef();
  1081. }
  1082. #endif
  1083. else
  1084. sc = E_NOINTERFACE;
  1085. olDebugOut((DEB_TRACE, "Out CExposedStream::QueryInterface => %p\n",
  1086. *ppvObj));
  1087. EH_Err:
  1088. olLog(("%p::Out CExposedStream::QueryInterface(). "
  1089. "*ppvObj == %p, ret == %lx\n", this, *ppvObj, sc));
  1090. return ResultFromScode(sc);
  1091. }
  1092. //+--------------------------------------------------------------
  1093. //
  1094. // Member: CExposedStream::Unmarshal, public
  1095. //
  1096. // Synopsis: Creates a duplicate stream from parts
  1097. //
  1098. // Arguments: [pstm] - Marshal stream
  1099. // [ppv] - Object return
  1100. // [mshlflags] - Marshal flags
  1101. //
  1102. // Returns: Appropriate status code
  1103. //
  1104. // Modifies: [ppv]
  1105. //
  1106. // History: 26-Feb-92 DrewB Created
  1107. //
  1108. //---------------------------------------------------------------
  1109. SCODE CExposedStream::Unmarshal(IStream *pstm,
  1110. void **ppv,
  1111. DWORD mshlflags)
  1112. {
  1113. SCODE sc;
  1114. CDfMutex mtx;
  1115. CPerContext *ppc;
  1116. CPubStream *pst;
  1117. CDFBasis *pdfb;
  1118. CGlobalContext *pgc;
  1119. CExposedStream *pest;
  1120. CSeekPointer *psp;
  1121. IStream *pstmStd = NULL;
  1122. #ifdef ASYNC
  1123. DWORD dwAsyncFlags;
  1124. IDocfileAsyncConnectionPoint *pdacp;
  1125. #endif
  1126. #ifdef POINTER_IDENTITY
  1127. CMarshalList *pml;
  1128. #endif
  1129. olDebugOut((DEB_ITRACE, "In CExposedStream::Unmarshal(%p, %p, %lu)\n",
  1130. pstm, ppv, mshlflags));
  1131. #ifdef MULTIHEAP
  1132. void *pvBaseOld;
  1133. void *pvBaseNew;
  1134. ContextId cntxid;
  1135. CPerContext pcSharedMemory (NULL); // bootstrap object
  1136. #endif
  1137. //First unmarshal the standard marshalled version
  1138. sc = CoUnmarshalInterface(pstm, IID_IStream, (void **)&pstmStd);
  1139. if (FAILED(sc))
  1140. {
  1141. // assume that entire standard marshaling stream has been read
  1142. olAssert (pstmStd == NULL);
  1143. sc = S_OK;
  1144. }
  1145. #ifdef MULTIHEAP
  1146. sc = UnmarshalSharedMemory(pstm, mshlflags, &pcSharedMemory, &cntxid);
  1147. if (!SUCCEEDED(sc))
  1148. {
  1149. #ifdef POINTER_IDENTITY
  1150. UnmarshalPointer(pstm, (void **) &pest);
  1151. #endif
  1152. UnmarshalPointer(pstm, (void **)&pst);
  1153. UnmarshalPointer(pstm, (void **)&pdfb);
  1154. UnmarshalPointer(pstm, (void **)&psp);
  1155. #ifdef ASYNC
  1156. ReleaseContext(pstm, TRUE, FALSE, mshlflags);
  1157. ReleaseConnection(pstm, mshlflags);
  1158. #else
  1159. ReleaseContext(pstStm, FALSE, mshlflags);
  1160. #endif
  1161. olChkTo(EH_std, sc);
  1162. }
  1163. pvBaseOld = DFBASEPTR;
  1164. #endif
  1165. #ifdef POINTER_IDENTITY
  1166. olChkTo(EH_mem, UnmarshalPointer(pstm, (void **)&pest));
  1167. #endif
  1168. olChkTo(EH_mem, UnmarshalPointer(pstm, (void **)&pst));
  1169. olChkTo(EH_mem, ValidateBuffer(pst, sizeof(CPubStream)));
  1170. olChkTo(EH_pst, UnmarshalPointer(pstm, (void **)&pdfb));
  1171. olChkTo(EH_pdfb, UnmarshalPointer(pstm, (void **)&psp));
  1172. olChkTo(EH_psp, UnmarshalPointer(pstm, (void **)&pgc));
  1173. olChkTo(EH_pgc, ValidateBuffer(pgc, sizeof(CGlobalContext)));
  1174. //So far, nothing has called into the tree so we don't really need
  1175. // to be holding the tree mutex. The UnmarshalContext call does
  1176. // call into the tree, though, so we need to make sure this is
  1177. // threadsafe. We'll do this my getting the mutex name from the
  1178. // CGlobalContext, then creating a new CDfMutex object. While
  1179. // this is obviously not optimal, since it's possible we could
  1180. // reuse an existing CDfMutex, the reuse strategy isn't threadsafe
  1181. // since we can't do a lookup without the possibility of the thing
  1182. // we're looking for being released by another thread.
  1183. TCHAR atcMutexName[CONTEXT_MUTEX_NAME_LENGTH];
  1184. pgc->GetMutexName(atcMutexName);
  1185. olChkTo(EH_pgc, mtx.Init(atcMutexName));
  1186. olChkTo(EH_pgc, mtx.Take(INFINITE));
  1187. //At this point we're holding the mutex.
  1188. #ifdef MULTIHEAP
  1189. #ifdef ASYNC
  1190. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1191. pgc,
  1192. &ppc,
  1193. mshlflags,
  1194. TRUE,
  1195. FALSE,
  1196. cntxid,
  1197. FALSE));
  1198. #else
  1199. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1200. pgc,
  1201. &ppc,
  1202. mshlflags,
  1203. FALSE,
  1204. cntxid,
  1205. FALSE));
  1206. #endif
  1207. if ((pvBaseNew = DFBASEPTR) != pvBaseOld)
  1208. {
  1209. pst = (CPubStream*) ((ULONG_PTR)pst - (ULONG_PTR)pvBaseOld
  1210. + (ULONG_PTR)pvBaseNew);
  1211. pest = (CExposedStream*) ((ULONG_PTR)pest - (ULONG_PTR)pvBaseOld
  1212. + (ULONG_PTR)pvBaseNew);
  1213. pdfb = (CDFBasis*) ((ULONG_PTR)pdfb - (ULONG_PTR)pvBaseOld
  1214. + (ULONG_PTR)pvBaseNew);
  1215. psp = (CSeekPointer*) ((ULONG_PTR)psp - (ULONG_PTR)pvBaseOld
  1216. + (ULONG_PTR)pvBaseNew);
  1217. }
  1218. #else
  1219. #ifdef ASYNC
  1220. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1221. pgc,
  1222. &ppc,
  1223. mshlflags,
  1224. TRUE,
  1225. FALSE,
  1226. FALSE));
  1227. #else
  1228. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1229. pgc,
  1230. &ppc,
  1231. mshlflags,
  1232. FALSE,
  1233. FALSE));
  1234. #endif //ASYNC
  1235. #endif
  1236. #ifdef ASYNC
  1237. olChkTo(EH_ppc, UnmarshalConnection(pstm,
  1238. &dwAsyncFlags,
  1239. &pdacp,
  1240. mshlflags));
  1241. #endif
  1242. // if we use up 1Gig of address space, use standard unmarshaling
  1243. if (gs_iSharedHeaps > (DOCFILE_SM_LIMIT / DOCFILE_SM_SIZE))
  1244. olErr (EH_ppc, STG_E_INSUFFICIENTMEMORY);
  1245. #ifdef POINTER_IDENTITY
  1246. olAssert (pest != NULL);
  1247. pml = (CMarshalList *) pest;
  1248. // Warning: these checks must remain valid across processes
  1249. if (SUCCEEDED(pest->Validate()) && pest->GetPub() == pst)
  1250. {
  1251. pest = (CExposedStream *) pml->FindMarshal(GetCurrentContextId());
  1252. }
  1253. else
  1254. {
  1255. pml = NULL;
  1256. pest = NULL;
  1257. }
  1258. if (pest == NULL)
  1259. {
  1260. #endif
  1261. olMemTo(EH_ppc, pest = new (pdfb->GetMalloc()) CExposedStream);
  1262. #ifdef ASYNC
  1263. olChkTo(EH_pest, pest->InitMarshal(pst,
  1264. pdfb,
  1265. ppc,
  1266. dwAsyncFlags,
  1267. pdacp,
  1268. psp));
  1269. //InitMarshal adds a reference on pdacp.
  1270. if (pdacp)
  1271. pdacp->Release();
  1272. #else
  1273. olChkTo(EH_pest, pest->Init(pst, pdfb, ppc, psp));
  1274. #endif
  1275. #ifdef POINTER_IDENTITY
  1276. if (pml) pml->AddMarshal(pest);
  1277. pst->vAddRef(); // CExposedStream::Init does not AddRef
  1278. psp->vAddRef();
  1279. }
  1280. else
  1281. {
  1282. pdfb->SetAccess(ppc);
  1283. pest->AddRef(); // reuse this object
  1284. ppc->Release(); // reuse percontext
  1285. }
  1286. #else
  1287. pst->vAddRef();
  1288. psp->vAddRef();
  1289. #endif
  1290. *ppv = pest;
  1291. #ifdef MULTIHEAP
  1292. if (pvBaseOld != pvBaseNew)
  1293. {
  1294. pcSharedMemory.SetThreadAllocatorState(NULL);
  1295. g_smAllocator.Uninit(); // delete the extra mapping
  1296. }
  1297. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  1298. #endif
  1299. mtx.Release();
  1300. //We're returning the custom marshalled version, so release the
  1301. //standard marshalled one.
  1302. if (pstmStd != NULL)
  1303. pstmStd->Release();
  1304. olDebugOut((DEB_ITRACE, "Out CExposedStream::Unmarshal => %p\n", *ppv));
  1305. return S_OK;
  1306. EH_pest:
  1307. delete pest;
  1308. EH_ppc:
  1309. ppc->Release();
  1310. EH_mtx:
  1311. mtx.Release();
  1312. goto EH_Err;
  1313. EH_pgc:
  1314. CoReleaseMarshalData(pstm); // release the ILockBytes
  1315. CoReleaseMarshalData(pstm); // release the ILockBytes
  1316. #ifdef ASYNC
  1317. ReleaseConnection(pstm, mshlflags);
  1318. #endif
  1319. EH_psp:
  1320. EH_pdfb:
  1321. EH_pst:
  1322. EH_mem:
  1323. EH_Err:
  1324. #ifdef MULTIHEAP
  1325. pcSharedMemory.SetThreadAllocatorState(NULL);
  1326. g_smAllocator.Uninit(); // delete the file mapping in error case
  1327. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  1328. #endif
  1329. EH_std:
  1330. if (pstmStd != NULL)
  1331. {
  1332. //We can return the standard marshalled version instead of an error.
  1333. *ppv = pstmStd;
  1334. return S_OK;
  1335. }
  1336. return sc;
  1337. }
  1338. //+--------------------------------------------------------------
  1339. //
  1340. // Member: CExposedStream::GetUnmarshalClass, public
  1341. //
  1342. // Synopsis: Returns the class ID
  1343. //
  1344. // Arguments: [riid] - IID of object
  1345. // [pv] - Unreferenced
  1346. // [dwDestContext] - Unreferenced
  1347. // [pvDestContext] - Unreferenced
  1348. // [mshlflags] - Unreferenced
  1349. // [pcid] - CLSID return
  1350. //
  1351. // Returns: Appropriate status code
  1352. //
  1353. // Modifies: [pcid]
  1354. //
  1355. // History: 04-May-92 DrewB Created
  1356. //
  1357. //---------------------------------------------------------------
  1358. STDMETHODIMP CExposedStream::GetUnmarshalClass(REFIID riid,
  1359. void *pv,
  1360. DWORD dwDestContext,
  1361. LPVOID pvDestContext,
  1362. DWORD mshlflags,
  1363. LPCLSID pcid)
  1364. {
  1365. SCODE sc;
  1366. #ifdef MULTIHEAP
  1367. CSafeMultiHeap smh(_ppc);
  1368. #endif
  1369. olLog(("%p::In CExposedStream::GetUnmarshalClass("
  1370. "riid, %p, %lu, %p, %lu, %p)\n",
  1371. this, pv, dwDestContext, pvDestContext, mshlflags, pcid));
  1372. olDebugOut((DEB_TRACE, "In CExposedStream::GetUnmarshalClass:%p("
  1373. "riid, %p, %lu, %p, %lu, %p)\n", this, pv, dwDestContext,
  1374. pvDestContext, mshlflags, pcid));
  1375. UNREFERENCED_PARM(pv);
  1376. UNREFERENCED_PARM(mshlflags);
  1377. olChk(ValidateOutBuffer(pcid, sizeof(CLSID)));
  1378. memset(pcid, 0, sizeof(CLSID));
  1379. olChk(ValidateIid(riid));
  1380. olChk(Validate());
  1381. olChk(_pst->CheckReverted());
  1382. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  1383. {
  1384. IMarshal *pmsh;
  1385. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  1386. dwDestContext, pvDestContext,
  1387. mshlflags, &pmsh)))
  1388. {
  1389. sc = GetScode(pmsh->GetUnmarshalClass(riid, pv, dwDestContext,
  1390. pvDestContext, mshlflags,
  1391. pcid));
  1392. pmsh->Release();
  1393. }
  1394. }
  1395. else if (pvDestContext != NULL)
  1396. {
  1397. sc = STG_E_INVALIDPARAMETER;
  1398. }
  1399. else
  1400. {
  1401. olChk(VerifyIid(riid, IID_IStream));
  1402. *pcid = CLSID_DfMarshal;
  1403. }
  1404. olDebugOut((DEB_TRACE, "Out CExposedStream::GetUnmarshalClass\n"));
  1405. EH_Err:
  1406. olLog(("%p::Out CExposedStream::GetUnmarshalClass(). ret == %lx\n",
  1407. this, sc));
  1408. return ResultFromScode(sc);
  1409. }
  1410. //+--------------------------------------------------------------
  1411. //
  1412. // Member: CExposedStream::GetMarshalSizeMax, public
  1413. //
  1414. // Synopsis: Returns the size needed for the marshal buffer
  1415. //
  1416. // Arguments: [riid] - IID of object being marshaled
  1417. // [pv] - Unreferenced
  1418. // [dwDestContext] - Unreferenced
  1419. // [pvDestContext] - Unreferenced
  1420. // [mshlflags] - Marshal flags
  1421. // [pcbSize] - Size return
  1422. //
  1423. // Returns: Appropriate status code
  1424. //
  1425. // Modifies: [pcbSize]
  1426. //
  1427. // History: 04-May-92 DrewB Created
  1428. //
  1429. //---------------------------------------------------------------
  1430. STDMETHODIMP CExposedStream::GetMarshalSizeMax(REFIID riid,
  1431. void *pv,
  1432. DWORD dwDestContext,
  1433. LPVOID pvDestContext,
  1434. DWORD mshlflags,
  1435. LPDWORD pcbSize)
  1436. {
  1437. SCODE sc;
  1438. #ifdef MULTIHEAP
  1439. CSafeMultiHeap smh(_ppc);
  1440. #endif
  1441. UNREFERENCED_PARM(pv);
  1442. olLog(("%p::In CExposedStream::GetMarshalSizeMax("
  1443. "riid, %p, %lu, %p, %lu, %p)\n",
  1444. this, pv, dwDestContext, pvDestContext, mshlflags, pcbSize));
  1445. olDebugOut((DEB_TRACE, "In CExposedStream::GetMarshalSizeMax:%p("
  1446. "riid, %p, %lu, %p, %lu, %p)\n", this, pv, dwDestContext,
  1447. pvDestContext, mshlflags, pcbSize));
  1448. olChk(Validate());
  1449. olChk(_pst->CheckReverted());
  1450. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  1451. {
  1452. IMarshal *pmsh;
  1453. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  1454. dwDestContext, pvDestContext,
  1455. mshlflags, &pmsh)))
  1456. {
  1457. sc = GetScode(pmsh->GetMarshalSizeMax(riid, pv, dwDestContext,
  1458. pvDestContext, mshlflags,
  1459. pcbSize));
  1460. pmsh->Release();
  1461. }
  1462. }
  1463. else if (pvDestContext != NULL)
  1464. {
  1465. sc = STG_E_INVALIDPARAMETER;
  1466. }
  1467. else
  1468. {
  1469. sc = GetStdMarshalSize(riid, IID_IStream, dwDestContext, pvDestContext,
  1470. mshlflags, pcbSize,
  1471. sizeof(CPubStream *)+sizeof(CDFBasis *)+
  1472. sizeof(CSeekPointer *),
  1473. #ifdef ASYNC
  1474. &_cpoint,
  1475. TRUE,
  1476. #endif
  1477. _ppc, FALSE);
  1478. DWORD cbSize = 0;
  1479. IMarshal *pmsh;
  1480. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  1481. dwDestContext, pvDestContext,
  1482. mshlflags, &pmsh)))
  1483. {
  1484. sc = GetScode(pmsh->GetMarshalSizeMax(riid, pv, dwDestContext,
  1485. pvDestContext, mshlflags,
  1486. &cbSize));
  1487. pmsh->Release();
  1488. *pcbSize += cbSize;
  1489. }
  1490. }
  1491. olDebugOut((DEB_TRACE, "Out CExposedStream::GetMarshalSizeMax\n"));
  1492. EH_Err:
  1493. olLog(("%p::Out CExposedStream::GetMarshalSizeMax(). *pcbSize == %lu, "
  1494. "ret == %lx\n", this, *pcbSize, sc));
  1495. return ResultFromScode(sc);
  1496. }
  1497. //+--------------------------------------------------------------
  1498. //
  1499. // Member: CExposedStream::MarshalInterface, public
  1500. //
  1501. // Synopsis: Marshals a given object
  1502. //
  1503. // Arguments: [pstStm] - Stream to write marshal data into
  1504. // [riid] - Interface to marshal
  1505. // [pv] - Unreferenced
  1506. // [dwDestContext] - Unreferenced
  1507. // [pvDestContext] - Unreferenced
  1508. // [mshlflags] - Marshal flags
  1509. //
  1510. // Returns: Appropriate status code
  1511. //
  1512. // History: 04-May-92 DrewB Created
  1513. //
  1514. //---------------------------------------------------------------
  1515. STDMETHODIMP CExposedStream::MarshalInterface(IStream *pstStm,
  1516. REFIID riid,
  1517. void *pv,
  1518. DWORD dwDestContext,
  1519. LPVOID pvDestContext,
  1520. DWORD mshlflags)
  1521. {
  1522. SCODE sc;
  1523. #ifdef MULTIHEAP
  1524. CSafeMultiHeap smh(_ppc);
  1525. #endif
  1526. olLog(("%p::In CExposedStream::MarshalInterface("
  1527. "%p, riid, %p, %lu, %p, %lu). Context == %lX\n",
  1528. this, pstStm, pv, dwDestContext, pvDestContext,
  1529. mshlflags, (ULONG)GetCurrentContextId()));
  1530. olDebugOut((DEB_TRACE, "In CExposedStream::MarshalInterface:%p("
  1531. "%p, riid, %p, %lu, %p, %lu)\n", this, pstStm, pv,
  1532. dwDestContext, pvDestContext, mshlflags));
  1533. UNREFERENCED_PARM(pv);
  1534. olChk(Validate());
  1535. olChk(_pst->CheckReverted());
  1536. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  1537. {
  1538. IMarshal *pmsh;
  1539. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  1540. dwDestContext, pvDestContext,
  1541. mshlflags, &pmsh)))
  1542. {
  1543. sc = GetScode(pmsh->MarshalInterface(pstStm, riid, pv,
  1544. dwDestContext, pvDestContext,
  1545. mshlflags));
  1546. pmsh->Release();
  1547. olChk(sc);
  1548. }
  1549. }
  1550. else if (pvDestContext != NULL)
  1551. {
  1552. sc = STG_E_INVALIDPARAMETER;
  1553. }
  1554. else
  1555. {
  1556. olChk(StartMarshal(pstStm, riid, IID_IStream, mshlflags));
  1557. //Always standard marshal, in case we get an error during
  1558. //unmarshalling of the custom stuff.
  1559. {
  1560. IMarshal *pmsh;
  1561. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  1562. dwDestContext, pvDestContext,
  1563. mshlflags, &pmsh)))
  1564. {
  1565. sc = pmsh->MarshalInterface(pstStm, riid, pv,
  1566. dwDestContext, pvDestContext,
  1567. mshlflags);
  1568. pmsh->Release();
  1569. }
  1570. olChk(sc);
  1571. }
  1572. #ifdef MULTIHEAP
  1573. olChk(MarshalSharedMemory(pstStm, _ppc));
  1574. #endif
  1575. #ifdef POINTER_IDENTITY
  1576. olChk(MarshalPointer(pstStm, (CExposedStream*) GetNextMarshal()));
  1577. #endif
  1578. olChk(MarshalPointer(pstStm, BP_TO_P(CPubStream *, _pst)));
  1579. olChk(MarshalPointer(pstStm, BP_TO_P(CDFBasis *, _pdfb)));
  1580. olChk(MarshalPointer(pstStm, BP_TO_P(CSeekPointer *, _psp)));
  1581. #ifdef ASYNC
  1582. olChk(MarshalContext(pstStm,
  1583. _ppc,
  1584. dwDestContext,
  1585. pvDestContext,
  1586. mshlflags,
  1587. TRUE,
  1588. FALSE));
  1589. #else
  1590. olChk(MarshalContext(pstStm,
  1591. _ppc,
  1592. dwDestContext,
  1593. pvDestContext,
  1594. mshlflags,
  1595. FALSE));
  1596. #endif
  1597. #ifdef ASYNC
  1598. olChk(MarshalConnection(pstStm,
  1599. &_cpoint,
  1600. dwDestContext,
  1601. pvDestContext,
  1602. mshlflags));
  1603. #endif
  1604. }
  1605. olDebugOut((DEB_TRACE, "Out CExposedStream::MarshalInterface\n"));
  1606. EH_Err:
  1607. olLog(("%p::Out CExposedStream::MarshalInterface(). ret == %lx\n",
  1608. this, sc));
  1609. return ResultFromScode(sc);
  1610. }
  1611. //+--------------------------------------------------------------
  1612. //
  1613. // Member: CExposedStream::UnmarshalInterface, public
  1614. //
  1615. // Synopsis: Non-functional
  1616. //
  1617. // Arguments: [pstStm] -
  1618. // [riid] -
  1619. // [ppvObj] -
  1620. //
  1621. // Returns: Appropriate status code
  1622. //
  1623. // Modifies: [ppvObj]
  1624. //
  1625. // History: 04-May-92 DrewB Created
  1626. //
  1627. //---------------------------------------------------------------
  1628. STDMETHODIMP CExposedStream::UnmarshalInterface(IStream *pstStm,
  1629. REFIID riid,
  1630. void **ppvObj)
  1631. {
  1632. olLog(("%p::INVALID CALL TO CExposedStream::UnmarshalInterface()\n"));
  1633. return ResultFromScode(STG_E_INVALIDFUNCTION);
  1634. }
  1635. //+--------------------------------------------------------------
  1636. //
  1637. // Member: CExposedStream::StaticReleaseMarshalData, public static
  1638. //
  1639. // Synopsis: Releases any references held in marshal data
  1640. //
  1641. // Arguments: [pstStm] - Marshal data stream
  1642. //
  1643. // Returns: Appropriate status code
  1644. //
  1645. // History: 02-Feb-94 DrewB Created
  1646. //
  1647. // Notes: Assumes standard marshal header has already been read
  1648. //
  1649. //---------------------------------------------------------------
  1650. SCODE CExposedStream::StaticReleaseMarshalData(IStream *pstStm,
  1651. DWORD mshlflags)
  1652. {
  1653. SCODE sc;
  1654. CPubStream *pst;
  1655. CDFBasis *pdfb;
  1656. CSeekPointer *psp;
  1657. #ifdef POINTER_IDENTITY
  1658. CExposedStream *pest;
  1659. #endif
  1660. olDebugOut((DEB_ITRACE, "In CExposedStream::StaticReleaseMarshalData:("
  1661. "%p, %lX)\n", pstStm, mshlflags));
  1662. //First release the standard marshalled stuff
  1663. olChk(CoReleaseMarshalData(pstStm));
  1664. // The final release of the exposed object may have shut down the
  1665. // shared memory heap, so do not access shared memory after this point
  1666. //Then do the rest of it
  1667. #ifdef MULTIHEAP
  1668. olChk(SkipSharedMemory(pstStm, mshlflags));
  1669. #endif
  1670. #ifdef POINTER_IDENTITY
  1671. olChk(UnmarshalPointer(pstStm, (void **) &pest));
  1672. #endif
  1673. olChk(UnmarshalPointer(pstStm, (void **)&pst));
  1674. olChk(UnmarshalPointer(pstStm, (void **)&pdfb));
  1675. olChk(UnmarshalPointer(pstStm, (void **)&psp));
  1676. #ifdef ASYNC
  1677. olChk(ReleaseContext(pstStm, TRUE, FALSE, mshlflags));
  1678. olChk(ReleaseConnection(pstStm, mshlflags));
  1679. #else
  1680. olChk(ReleaseContext(pstStm, FALSE, mshlflags));
  1681. #endif
  1682. #ifdef MULTIHEAP
  1683. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  1684. #endif
  1685. olDebugOut((DEB_ITRACE,
  1686. "Out CExposedStream::StaticReleaseMarshalData\n"));
  1687. EH_Err:
  1688. return sc;
  1689. }
  1690. //+--------------------------------------------------------------
  1691. //
  1692. // Member: CExposedStream::ReleaseMarshalData, public
  1693. //
  1694. // Synopsis: Non-functional
  1695. //
  1696. // Arguments: [pstStm] - Stream
  1697. //
  1698. // Returns: Appropriate status code
  1699. //
  1700. // History: 18-Sep-92 DrewB Created
  1701. //
  1702. //---------------------------------------------------------------
  1703. STDMETHODIMP CExposedStream::ReleaseMarshalData(IStream *pstStm)
  1704. {
  1705. SCODE sc;
  1706. DWORD mshlflags;
  1707. IID iid;
  1708. #ifdef MULTIHEAP
  1709. CSafeMultiHeap smh(_ppc);
  1710. #endif
  1711. olLog(("%p::In CExposedStream::ReleaseMarshalData(%p)\n", this, pstStm));
  1712. olDebugOut((DEB_TRACE, "In CExposedStream::ReleaseMarshalData:%p(%p)\n",
  1713. this, pstStm));
  1714. olChk(Validate());
  1715. olChk(_pst->CheckReverted());
  1716. olChk(SkipStdMarshal(pstStm, &iid, &mshlflags));
  1717. olAssert(IsEqualIID(iid, IID_IStream));
  1718. sc = StaticReleaseMarshalData(pstStm, mshlflags);
  1719. olDebugOut((DEB_TRACE, "Out CExposedStream::ReleaseMarshalData\n"));
  1720. EH_Err:
  1721. olLog(("%p::Out CExposedStream::ReleaseMarshalData(). ret == %lx\n",
  1722. this, sc));
  1723. return ResultFromScode(sc);
  1724. }
  1725. //+--------------------------------------------------------------
  1726. //
  1727. // Member: CExposedStream::DisconnectObject, public
  1728. //
  1729. // Synopsis: Non-functional
  1730. //
  1731. // Arguments: [dwRevserved] -
  1732. //
  1733. // Returns: Appropriate status code
  1734. //
  1735. // History: 18-Sep-92 DrewB Created
  1736. //
  1737. //---------------------------------------------------------------
  1738. STDMETHODIMP CExposedStream::DisconnectObject(DWORD dwReserved)
  1739. {
  1740. olLog(("%p::INVALID CALL TO CExposedStream::DisconnectObject()\n"));
  1741. return ResultFromScode(STG_E_INVALIDFUNCTION);
  1742. }
  1743. #ifdef NEWPROPS
  1744. //+-------------------------------------------------------------------
  1745. //
  1746. // Member: CExposedStream::Open
  1747. //
  1748. // Synopsis: Opens mapped view of exposed stream. Called by
  1749. // NtCreatePropertySet et al.
  1750. //
  1751. // Notes: Gets the size of the underlying stream and reads it
  1752. // into memory so that it can be "mapped."
  1753. //
  1754. //--------------------------------------------------------------------
  1755. VOID CExposedStream::Open(IN VOID *powner, LONG *phr)
  1756. {
  1757. #ifdef MULTIHEAP
  1758. CSafeMultiHeap smh(_ppc);
  1759. #endif
  1760. GetMappedStream().Open(powner, phr);
  1761. }
  1762. //+-------------------------------------------------------------------
  1763. //
  1764. // Member: CExposedStream::Close
  1765. //
  1766. // Synopsis: Operates on mapped view of exposed stream. Called by
  1767. // NtCreatePropertySet et al.
  1768. //
  1769. // Notes: Does nothing because the object may be mapped in
  1770. // another process.
  1771. //
  1772. //--------------------------------------------------------------------
  1773. VOID CExposedStream::Close(OUT LONG *phr)
  1774. {
  1775. #ifdef MULTIHEAP
  1776. CSafeMultiHeap smh(_ppc);
  1777. #endif
  1778. GetMappedStream().Close(phr);
  1779. }
  1780. //+-------------------------------------------------------------------
  1781. //
  1782. // Member: CExposedStream::ReOpen
  1783. //
  1784. // Synopsis: Operates on mapped view of exposed stream. Called by
  1785. // NtCreatePropertySet et al.
  1786. //
  1787. // Notes: Combined open and map.
  1788. //
  1789. //--------------------------------------------------------------------
  1790. VOID CExposedStream::ReOpen(IN OUT VOID **ppv, OUT LONG *phr)
  1791. {
  1792. #ifdef MULTIHEAP
  1793. CSafeMultiHeap smh(_ppc);
  1794. #endif
  1795. GetMappedStream().ReOpen(ppv,phr);
  1796. }
  1797. //+-------------------------------------------------------------------
  1798. //
  1799. // Member: CExposedStream::Quiesce
  1800. //
  1801. // Synopsis: Operates on mapped view of exposed stream. Called by
  1802. // NtCreatePropertySet et al.
  1803. //
  1804. // Notes: Meaningless for docfile mapped stream.
  1805. //
  1806. //--------------------------------------------------------------------
  1807. VOID CExposedStream::Quiesce(VOID)
  1808. {
  1809. #ifdef MULTIHEAP
  1810. CSafeMultiHeap smh(_ppc);
  1811. #endif
  1812. GetMappedStream().Quiesce();
  1813. }
  1814. //+-------------------------------------------------------------------
  1815. //
  1816. // Member: CExposedStream::Map
  1817. //
  1818. // Synopsis: Operates on mapped view of exposed stream. Called by
  1819. // NtCreatePropertySet et al.
  1820. //
  1821. // Notes: Return the address of the "mapping" buffer.
  1822. //
  1823. //--------------------------------------------------------------------
  1824. VOID CExposedStream::Map(BOOLEAN fCreate, VOID **ppv)
  1825. {
  1826. #ifdef MULTIHEAP
  1827. CSafeMultiHeap smh(_ppc);
  1828. #endif
  1829. GetMappedStream().Map(fCreate, ppv);
  1830. }
  1831. //+-------------------------------------------------------------------
  1832. //
  1833. // Member: CExposedStream::Unmap
  1834. //
  1835. // Synopsis: Operates on mapped view of exposed stream. Called by
  1836. // NtCreatePropertySet et al.
  1837. //
  1838. // Notes: Unmapping is merely zeroing the pointer. We don't
  1839. // flush because that's done explicitly by the
  1840. // CPropertyStorage class.
  1841. //
  1842. //
  1843. //--------------------------------------------------------------------
  1844. VOID CExposedStream::Unmap(BOOLEAN fFlush, VOID **pv)
  1845. {
  1846. #ifdef MULTIHEAP
  1847. CSafeMultiHeap smh(_ppc);
  1848. #endif
  1849. GetMappedStream().Unmap(fFlush, pv);
  1850. }
  1851. //+-------------------------------------------------------------------
  1852. //
  1853. // Member: CExposedStream::Flush
  1854. //
  1855. // Synopsis: Operates on mapped view of exposed stream. Called by
  1856. // NtCreatePropertySet et al.
  1857. // Flush the memory property set to disk and commit it.
  1858. //
  1859. // Signals: HRESULT from IStream methods.
  1860. //
  1861. // Notes: Calls the shared memory buffer to do the actual flush
  1862. // because that code path is shared with the "FlushBufferedData"
  1863. // call for IStorage::Commit.
  1864. //
  1865. //--------------------------------------------------------------------
  1866. VOID CExposedStream::Flush(OUT LONG *phr)
  1867. {
  1868. #ifdef MULTIHEAP
  1869. CSafeMultiHeap smh(_ppc);
  1870. #endif
  1871. GetMappedStream().Flush(phr);
  1872. }
  1873. //+-------------------------------------------------------------------
  1874. //
  1875. // Member: CExposedStream::GetSize
  1876. //
  1877. // Synopsis: Returns size of exposed stream. Called by
  1878. // NtCreatePropertySet et al.
  1879. //
  1880. // Notes:
  1881. //--------------------------------------------------------------------
  1882. ULONG CExposedStream::GetSize(OUT LONG *phr)
  1883. {
  1884. #ifdef MULTIHEAP
  1885. CSafeMultiHeap smh(_ppc);
  1886. #endif
  1887. return GetMappedStream().GetSize(phr);
  1888. }
  1889. //+-------------------------------------------------------------------
  1890. //
  1891. // Member: CExposedStream::SetSize
  1892. //
  1893. // Synopsis: Sets size of "map." Called by
  1894. // NtCreatePropertySet et al.
  1895. //
  1896. // Arguments: [cb] -- requested size.
  1897. // [fPersistent] -- FALSE if expanding in-memory read-only image
  1898. // [ppv] -- new mapped address.
  1899. //
  1900. // Signals: Not enough disk space.
  1901. //
  1902. // Notes: In a low memory situation we may not be able to
  1903. // get the requested amount of memory. In this
  1904. // case we must fall back on disk storage as the
  1905. // actual map.
  1906. //
  1907. //--------------------------------------------------------------------
  1908. VOID CExposedStream::SetSize(ULONG cb, BOOLEAN fPersistent, VOID **ppv, OUT LONG *phr)
  1909. {
  1910. #ifdef MULTIHEAP
  1911. CSafeMultiHeap smh(_ppc);
  1912. #endif
  1913. GetMappedStream().SetSize(cb, fPersistent, ppv, phr);
  1914. }
  1915. //+-------------------------------------------------------------------
  1916. //
  1917. // Member: CExposedStream::Lock
  1918. //
  1919. // Synopsis: Operates on mapped view of exposed stream. Called by
  1920. // NtCreatePropertySet et al.
  1921. //
  1922. // Notes:
  1923. //
  1924. //--------------------------------------------------------------------
  1925. NTSTATUS CExposedStream::Lock(BOOLEAN fExclusive)
  1926. {
  1927. SCODE sc;
  1928. #ifdef MULTIHEAP
  1929. CSafeMultiHeap smh(_ppc);
  1930. #endif
  1931. if( SUCCEEDED( sc = TakeSem() ))
  1932. {
  1933. SetDifferentBasisAccess(_pdfb, _ppc);
  1934. return GetMappedStream().Lock(fExclusive);
  1935. }
  1936. else
  1937. {
  1938. olDebugOut((DEB_IERROR, "Couldn't take CExposedStream::Lock(%lx)\n", sc));
  1939. return (STATUS_LOCK_NOT_GRANTED);
  1940. }
  1941. }
  1942. //+-------------------------------------------------------------------
  1943. //
  1944. // Member: CExposedStream::Unlock
  1945. //
  1946. // Synopsis: Operates on mapped view of exposed stream. Called by
  1947. // NtCreatePropertySet et al.
  1948. //
  1949. // Notes:
  1950. //
  1951. //--------------------------------------------------------------------
  1952. NTSTATUS CExposedStream::Unlock(VOID)
  1953. {
  1954. #ifdef MULTIHEAP
  1955. CSafeMultiHeap smh(_ppc);
  1956. #endif
  1957. NTSTATUS Status = GetMappedStream().Unlock();
  1958. ClearBasisAccess(_pdfb);
  1959. ReleaseSem(S_OK);
  1960. return Status;
  1961. }
  1962. //+-------------------------------------------------------------------
  1963. //
  1964. // Member: CExposedStream::QueryTimeStamps
  1965. //
  1966. // Synopsis: Operates on mapped view of exposed stream. Called by
  1967. // NtCreatePropertySet et al.
  1968. //
  1969. // Notes:
  1970. //
  1971. //--------------------------------------------------------------------
  1972. VOID CExposedStream::QueryTimeStamps(STATPROPSETSTG *pspss, BOOLEAN fNonSimple) const
  1973. {
  1974. #ifdef MULTIHEAP
  1975. CSafeMultiHeap smh(_ppc);
  1976. #endif
  1977. GetMappedStream().QueryTimeStamps(pspss, fNonSimple);
  1978. }
  1979. //+-------------------------------------------------------------------
  1980. //
  1981. // Member: CExposedStream::QueryModifyTime
  1982. //
  1983. // Synopsis: Operates on mapped view of exposed stream. Called by
  1984. // NtCreatePropertySet et al.
  1985. //
  1986. // Notes:
  1987. //
  1988. //--------------------------------------------------------------------
  1989. BOOLEAN CExposedStream::QueryModifyTime(OUT LONGLONG *pll) const
  1990. {
  1991. #ifdef MULTIHEAP
  1992. CSafeMultiHeap smh(_ppc);
  1993. #endif
  1994. return(GetMappedStream().QueryModifyTime(pll));
  1995. }
  1996. //+-------------------------------------------------------------------
  1997. //
  1998. // Member: CExposedStream::QuerySecurity
  1999. //
  2000. // Synopsis: Operates on mapped view of exposed stream. Called by
  2001. // NtCreatePropertySet et al.
  2002. //
  2003. // Notes:
  2004. //
  2005. //--------------------------------------------------------------------
  2006. BOOLEAN CExposedStream::QuerySecurity(OUT ULONG *pul) const
  2007. {
  2008. #ifdef MULTIHEAP
  2009. CSafeMultiHeap smh(_ppc);
  2010. #endif
  2011. return(GetMappedStream().QuerySecurity(pul));
  2012. }
  2013. //+-------------------------------------------------------------------
  2014. //
  2015. // Member: CExposedStream::IsWriteable
  2016. //
  2017. // Synopsis: Operates on mapped view of exposed stream. Called by
  2018. // NtCreatePropertySet et al.
  2019. //
  2020. // Notes:
  2021. //
  2022. //--------------------------------------------------------------------
  2023. BOOLEAN CExposedStream::IsWriteable() const
  2024. {
  2025. #ifdef MULTIHEAP
  2026. CSafeMultiHeap smh(_ppc);
  2027. #endif
  2028. return GetConstMappedStream().IsWriteable();
  2029. }
  2030. //+-------------------------------------------------------------------
  2031. //
  2032. // Member: CExposedStream::SetChangePending
  2033. //
  2034. // Synopsis: Operates on mapped view of exposed stream. Called by
  2035. // NtCreatePropertySet et al.
  2036. //
  2037. // Notes:
  2038. //
  2039. //--------------------------------------------------------------------
  2040. #if DBGPROP
  2041. BOOLEAN CExposedStream::SetChangePending(BOOLEAN f)
  2042. {
  2043. #ifdef MULTIHEAP
  2044. CSafeMultiHeap smh(_ppc);
  2045. #endif
  2046. return GetMappedStream().SetChangePending(f);
  2047. }
  2048. #endif
  2049. //+-------------------------------------------------------------------
  2050. //
  2051. // Member: CExposedStream::IsNtMappedStream
  2052. //
  2053. // Synopsis: Operates on mapped view of exposed stream. Called by
  2054. // NtCreatePropertySet et al.
  2055. //
  2056. // Notes:
  2057. //
  2058. //--------------------------------------------------------------------
  2059. #if DBGPROP
  2060. BOOLEAN CExposedStream::IsNtMappedStream(VOID) const
  2061. {
  2062. return FALSE;
  2063. }
  2064. #endif
  2065. //+-------------------------------------------------------------------
  2066. //
  2067. // Member: CExposedStream::GetParentHandle
  2068. //
  2069. // Synopsis: Operates on mapped view of exposed stream. Called by
  2070. // NtCreatePropertySet et al.
  2071. //
  2072. // Notes:
  2073. //
  2074. //--------------------------------------------------------------------
  2075. HANDLE CExposedStream::GetHandle(VOID) const
  2076. {
  2077. return INVALID_HANDLE_VALUE;
  2078. }
  2079. //+-------------------------------------------------------------------
  2080. //
  2081. // Member: CExposedStream::SetModified
  2082. //
  2083. // Synopsis: Operates on mapped view of exposed stream. Called by
  2084. // NtCreatePropertySet et al.
  2085. //
  2086. // Notes:
  2087. //
  2088. //--------------------------------------------------------------------
  2089. VOID CExposedStream::SetModified(OUT LONG *phr)
  2090. {
  2091. #ifdef MULTIHEAP
  2092. CSafeMultiHeap smh(_ppc);
  2093. #endif
  2094. GetMappedStream().SetModified(phr);
  2095. }
  2096. //+-------------------------------------------------------------------
  2097. //
  2098. // Member: CExposedStream::IsModified
  2099. //
  2100. // Synopsis: Operates on mapped view of exposed stream. Called by
  2101. // NtCreatePropertySet et al.
  2102. //
  2103. // Notes:
  2104. //
  2105. //--------------------------------------------------------------------
  2106. BOOLEAN CExposedStream::IsModified(VOID) const
  2107. {
  2108. #ifdef MULTIHEAP
  2109. CSafeMultiHeap smh(_ppc);
  2110. #endif
  2111. //return ((class CExposedStream*const)this)->GetMappedStream().IsModified();
  2112. return GetConstMappedStream().IsModified();
  2113. }
  2114. #ifdef DIRECTWRITERLOCK
  2115. //+--------------------------------------------------------------
  2116. //
  2117. // Member: CExposedStream::ValidateWriteAccess, public
  2118. //
  2119. // Synopsis: returns whether writer currently has write access
  2120. //
  2121. // Notes: tree mutex must be taken
  2122. //
  2123. // History: 30-Apr-96 HenryLee Created
  2124. //
  2125. //---------------------------------------------------------------
  2126. HRESULT CExposedStream::ValidateWriteAccess()
  2127. {
  2128. if (_pst->GetTransactedDepth() >= 1)
  2129. return S_OK;
  2130. return (!_pdfb->DirectWriterMode() || (*_ppc->GetRecursionCount())) ?
  2131. S_OK : STG_E_ACCESSDENIED;
  2132. };
  2133. #endif // DIRECTWRITERLOCK
  2134. #endif