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.

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