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.

1277 lines
36 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: simpstm.cxx
  7. //
  8. // Contents: CStdStream implementation
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 04-Aug-94 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "simphead.cxx"
  18. #pragma hdrstop
  19. #include <ole.hxx>
  20. #include <logfile.hxx>
  21. #include <expparam.hxx>
  22. #if DBG == 1 && defined(SECURE_SIMPLE_MODE)
  23. void CSimpStream::CheckSeekPointer(void)
  24. {
  25. LONG lHighChk;
  26. ULONG ulLowChk;
  27. lHighChk = 0;
  28. ulLowChk = SetFilePointer(_hFile, 0, &lHighChk, FILE_CURRENT);
  29. if (ulLowChk == 0xFFFFFFFF)
  30. {
  31. //An error occurred while checking.
  32. simpDebugOut((DEB_ERROR, "SetFilePointer call failed with %lu\n",
  33. GetLastError()));
  34. }
  35. else if ((ulLowChk != _ulSeekPos) || (lHighChk != 0))
  36. {
  37. simpDebugOut((DEB_ERROR, "Seek pointer mismatch."
  38. " Cached = %lu, Real = %lu, High = %lu\n",
  39. _ulSeekPos, ulLowChk, lHighChk));
  40. simpAssert((ulLowChk == _ulSeekPos) && (lHighChk == 0));
  41. }
  42. }
  43. #define CheckSeek() CheckSeekPointer()
  44. #else
  45. #define CheckSeek()
  46. #endif // DBG == 1 && defined(SECURE_SIMPLE_MODE)
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Member: CSimpStream::Init, public
  50. //
  51. // Synopsis: Initialize stream object
  52. //
  53. // Arguments: [pstgParent] -- Pointer to parent
  54. // [hFile] -- File handle for writes
  55. // [ulSeekStart] -- Beginning seek pointer
  56. //
  57. // Returns: Appropriate status code
  58. //
  59. // Modifies:
  60. //
  61. // History: 04-Aug-94 PhilipLa Created
  62. //
  63. // Notes:
  64. //
  65. //----------------------------------------------------------------------------
  66. SCODE CSimpStream::Init(
  67. CSimpStorage *pstgParent,
  68. HANDLE hFile,
  69. ULONG ulSeekStart)
  70. {
  71. simpDebugOut((DEB_ITRACE, "In CSimpStream::Init:%p()\n", this));
  72. _ulSeekStart = ulSeekStart;
  73. _hFile = hFile;
  74. _pstgParent = pstgParent;
  75. _cReferences = 1;
  76. #ifdef SECURE_SIMPLE_MODE
  77. _ulHighWater = ulSeekStart;
  78. #endif
  79. _ulSeekPos = ulSeekStart;
  80. if (SetFilePointer(_hFile, ulSeekStart, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  81. {
  82. return STG_SCODE(GetLastError());
  83. }
  84. CheckSeek();
  85. if (!SetEndOfFile(_hFile))
  86. {
  87. return STG_SCODE(GetLastError());
  88. }
  89. simpDebugOut((DEB_ITRACE, "Out CSimpStream::Init\n"));
  90. return S_OK;
  91. }
  92. //+--------------------------------------------------------------
  93. //
  94. // Member: CSimpStream::Read, public
  95. //
  96. // Synopsis: Read from a stream
  97. //
  98. // Arguments: [pb] - Buffer
  99. // [cb] - Count of bytes to read
  100. // [pcbRead] - Return number of bytes read
  101. //
  102. // Returns: Appropriate status code
  103. //
  104. // Modifies: [pcbRead]
  105. //
  106. // History: 04-Aug-94 PhilipLa Created
  107. //
  108. //---------------------------------------------------------------
  109. STDMETHODIMP CSimpStream::Read(VOID HUGEP *pb, ULONG cb, ULONG *pcbRead)
  110. {
  111. ULONG cbRead;
  112. ULONG *pcb;
  113. SCODE sc;
  114. olLog(("%p::In CSimpStream::Read(%p, %lu, %p)\n",
  115. this, pb, cb, pcbRead));
  116. SIMP_VALIDATE(Read(pb, cb, pcbRead));
  117. pcb = (pcbRead != NULL) ? pcbRead : &cbRead;
  118. #ifdef SECURE_SIMPLE_MODE
  119. if (_ulSeekPos + cb > _ulHighWater)
  120. {
  121. ULONG cbTotalSize;
  122. cbTotalSize = GetFileSize(_hFile, NULL);
  123. if (_ulSeekPos + cb > cbTotalSize)
  124. {
  125. //Truncate.
  126. cb = (_ulSeekPos > cbTotalSize) ? 0 : cbTotalSize - _ulSeekPos;
  127. }
  128. //Part of this read would come from uninitialized space, so
  129. // we need to return zeroes instead.
  130. if (_ulSeekPos > _ulHighWater)
  131. {
  132. if (SetFilePointer(_hFile,
  133. _ulSeekPos + cb,
  134. NULL,
  135. FILE_BEGIN) == 0xFFFFFFFF)
  136. {
  137. //We can't get the seek pointer where it will need to
  138. // end up, so return zero bytes and be done with it.
  139. *pcb = 0;
  140. return S_OK;
  141. }
  142. //Actually, the whole thing is coming from uninitialized
  143. // space. Why someone would do this is a mystery, but
  144. // let's return zeroes anyway.
  145. memset(pb, SECURECHAR, cb);
  146. *pcb = cb;
  147. _ulSeekPos += cb;
  148. }
  149. else
  150. {
  151. ULONG cbBytesToRead = _ulHighWater - _ulSeekPos;
  152. if (FAILED(sc = Read(pb, cbBytesToRead, pcb)))
  153. {
  154. CheckSeek();
  155. return sc;
  156. }
  157. cb -= *pcb;
  158. if ((*pcb != cbBytesToRead) ||
  159. (SetFilePointer(_hFile,
  160. _ulSeekPos + cb,
  161. NULL,
  162. FILE_BEGIN) == 0xFFFFFFFF))
  163. {
  164. //Either the Read call returned a weird number of bytes,
  165. // Or
  166. //We can't actually get the seek pointer where we need
  167. // it, so return fewer bytes than we normally would,
  168. // with a success code.
  169. CheckSeek();
  170. return S_OK;
  171. }
  172. //Zero the rest of the buffer.
  173. memset((BYTE *)pb + *pcb, SECURECHAR, cb);
  174. *pcb += cb;
  175. _ulSeekPos += cb;
  176. }
  177. CheckSeek();
  178. return S_OK;
  179. }
  180. #endif
  181. //Maps directly to ReadFile call
  182. BOOL f = ReadFile(_hFile,
  183. pb,
  184. cb,
  185. pcb,
  186. NULL);
  187. _ulSeekPos += *pcb;
  188. CheckSeek();
  189. if (!f)
  190. return STG_SCODE(GetLastError());
  191. olLog(("%p::Out CSimpStream::Read(). *pcbRead == %lu, ret = %lx\n",
  192. this, *pcb, S_OK));
  193. return S_OK;
  194. }
  195. //+--------------------------------------------------------------
  196. //
  197. // Member: CSimpStream::Write, public
  198. //
  199. // Synopsis: Write to a stream
  200. //
  201. // Arguments: [pb] - Buffer
  202. // [cb] - Count of bytes to write
  203. // [pcbWritten] - Return of bytes written
  204. //
  205. // Returns: Appropriate status code
  206. //
  207. // Modifies: [pcbWritten]
  208. //
  209. // History: 04-Aug-94 PhilipLa Created
  210. //
  211. //---------------------------------------------------------------
  212. STDMETHODIMP CSimpStream::Write(
  213. VOID const HUGEP *pb,
  214. ULONG cb,
  215. ULONG *pcbWritten)
  216. {
  217. ULONG cbWritten;
  218. ULONG *pcb;
  219. BOOL f = TRUE;
  220. SCODE sc = S_OK;
  221. olLog(("%p::In CSimpStream::Write(%p, %lu, %p)\n",
  222. this, pb, cb, pcbWritten));
  223. SIMP_VALIDATE(Write(pb, cb, pcbWritten));
  224. pcb = (pcbWritten != NULL) ? pcbWritten : &cbWritten;
  225. if (_ulSeekPos + cb >= OLOCKREGIONBEGIN)
  226. return STG_E_DOCFILETOOLARGE;
  227. #ifdef SECURE_SIMPLE_MODE
  228. if (_ulSeekPos > _ulHighWater)
  229. {
  230. //We're leaving a gap in the file, so we need to fill in that
  231. // gap. Sad but true.
  232. ULONG cbBytesToWrite = _ulSeekPos - _ulHighWater;
  233. ULONG cbWrittenSecure;
  234. if (SetFilePointer(_hFile,
  235. _ulHighWater,
  236. NULL,
  237. FILE_BEGIN) != 0xFFFFFFFF)
  238. {
  239. while (cbBytesToWrite > 0)
  240. {
  241. if (!(f = WriteFile(_hFile,
  242. s_bufSecure,
  243. min(MINISTREAMSIZE, cbBytesToWrite),
  244. &cbWrittenSecure,
  245. NULL)))
  246. {
  247. break;
  248. }
  249. cbBytesToWrite -= cbWrittenSecure;
  250. }
  251. if ((!f) && (SetFilePointer(_hFile,
  252. _ulSeekPos,
  253. NULL,
  254. FILE_BEGIN) == 0xFFFFFFFF))
  255. {
  256. return STG_SCODE(GetLastError());
  257. }
  258. }
  259. CheckSeek();
  260. }
  261. #endif
  262. //Maps directly to WriteFile call
  263. f = WriteFile(_hFile,
  264. pb,
  265. cb,
  266. pcb,
  267. NULL);
  268. _ulSeekPos += *pcb;
  269. #ifdef SECURE_SIMPLE_MODE
  270. if (_ulSeekPos > _ulHighWater)
  271. _ulHighWater = _ulSeekPos;
  272. #endif
  273. if (!f)
  274. {
  275. sc = STG_SCODE(GetLastError());
  276. }
  277. CheckSeek();
  278. olLog(("%p::Out CSimpStream::Write(). "
  279. "*pcbWritten == %lu, ret = %lx\n",
  280. this, *pcb, sc));
  281. return sc;
  282. }
  283. //+--------------------------------------------------------------
  284. //
  285. // Member: CSimpStream::Seek, public
  286. //
  287. // Synopsis: Seek to a point in a stream
  288. //
  289. // Arguments: [dlibMove] - Offset to move by
  290. // [dwOrigin] - SEEK_SET, SEEK_CUR, SEEK_END
  291. // [plibNewPosition] - Return of new offset
  292. //
  293. // Returns: Appropriate status code
  294. //
  295. // Modifies: [plibNewPosition]
  296. //
  297. // History: 04-Aug-94 PhilipLa Created
  298. //
  299. //
  300. //---------------------------------------------------------------
  301. STDMETHODIMP CSimpStream::Seek(LARGE_INTEGER dlibMove,
  302. DWORD dwOrigin,
  303. ULARGE_INTEGER *plibNewPosition)
  304. {
  305. SCODE sc = S_OK;
  306. LONG lMove;
  307. ULONG ulPos = 0;
  308. simpAssert((dwOrigin == STREAM_SEEK_SET) || (dwOrigin == STREAM_SEEK_CUR) ||
  309. (dwOrigin == STREAM_SEEK_END));
  310. olLog(("%p::In CSimpStream::Seek(%ld, %lu, %p)\n",
  311. this, LIGetLow(dlibMove), dwOrigin, plibNewPosition));
  312. SIMP_VALIDATE(Seek(dlibMove, dwOrigin, plibNewPosition));
  313. // Truncate dlibMove to 32 bits
  314. if (dwOrigin == STREAM_SEEK_SET)
  315. {
  316. // Make sure we don't seek too far
  317. if (LIGetHigh(dlibMove) != 0)
  318. LISet32(dlibMove, 0xffffffff);
  319. }
  320. else
  321. {
  322. // High dword must be zero for positive values or -1 for
  323. // negative values
  324. // Additionally, for negative values, the low dword can't
  325. // exceed -0x80000000 because the 32nd bit is the sign
  326. // bit
  327. if (LIGetHigh(dlibMove) > 0 ||
  328. (LIGetHigh(dlibMove) == 0 &&
  329. LIGetLow(dlibMove) >= 0x80000000))
  330. LISet32(dlibMove, 0x7fffffff);
  331. else if (LIGetHigh(dlibMove) < -1 ||
  332. (LIGetHigh(dlibMove) == -1 &&
  333. LIGetLow(dlibMove) <= 0x7fffffff))
  334. LISet32(dlibMove, 0x80000000);
  335. }
  336. lMove = (LONG)LIGetLow(dlibMove);
  337. switch(dwOrigin)
  338. {
  339. case STREAM_SEEK_SET:
  340. ulPos = _ulSeekStart + lMove;
  341. break;
  342. case STREAM_SEEK_END:
  343. ULONG cbSize;
  344. cbSize = GetFileSize(_hFile, NULL);
  345. if (lMove < 0)
  346. {
  347. if ((ULONG)(-lMove) > (cbSize - _ulSeekStart))
  348. return STG_E_INVALIDFUNCTION;
  349. }
  350. ulPos = cbSize+lMove;
  351. break;
  352. case STREAM_SEEK_CUR:
  353. ulPos = SetFilePointer(_hFile, 0, NULL, FILE_CURRENT);
  354. if (lMove < 0)
  355. {
  356. if ((ULONG)(-lMove) > (ulPos - _ulSeekStart))
  357. return STG_E_INVALIDFUNCTION;
  358. }
  359. ulPos += lMove;
  360. break;
  361. }
  362. ulPos = SetFilePointer(_hFile,
  363. ulPos,
  364. NULL,
  365. FILE_BEGIN);
  366. if (plibNewPosition != NULL)
  367. {
  368. ULISet32(*plibNewPosition, ulPos - _ulSeekStart);
  369. }
  370. _ulSeekPos = ulPos;
  371. CheckSeek();
  372. olLog(("%p::Out CSimpStream::Seek(). ulPos == %lu, ret == %lx\n",
  373. this, ulPos, sc));
  374. return sc;
  375. }
  376. //+--------------------------------------------------------------
  377. //
  378. // Member: CSimpStream::SetSize, public
  379. //
  380. // Synopsis: Sets the size of a stream
  381. //
  382. // Arguments: [ulNewSize] - New size
  383. //
  384. // Returns: Appropriate status code
  385. //
  386. // History: 04-Aug-94 PhilipLa Created
  387. //
  388. //---------------------------------------------------------------
  389. STDMETHODIMP CSimpStream::SetSize(ULARGE_INTEGER ulNewSize)
  390. {
  391. ULONG ulCurrentPos;
  392. SCODE sc;
  393. olLog(("%p::In CSimpStream::SetSize(%lu)\n",
  394. this, ULIGetLow(ulNewSize)));
  395. SIMP_VALIDATE(SetSize(ulNewSize));
  396. ulCurrentPos = SetFilePointer(_hFile, 0, NULL, FILE_CURRENT);
  397. if (ulCurrentPos == 0xFFFFFFFF)
  398. {
  399. return STG_SCODE(GetLastError());
  400. }
  401. if (ULIGetHigh(ulNewSize) != 0 ||
  402. ulCurrentPos + ULIGetLow(ulNewSize) >= OLOCKREGIONBEGIN)
  403. return STG_E_DOCFILETOOLARGE;
  404. if (SetFilePointer(_hFile,
  405. ULIGetLow(ulNewSize) + _ulSeekStart,
  406. NULL,
  407. FILE_BEGIN) == 0xFFFFFFFF)
  408. {
  409. CheckSeek();
  410. return STG_SCODE(GetLastError());
  411. }
  412. if (!SetEndOfFile(_hFile))
  413. {
  414. SetFilePointer(_hFile, ulCurrentPos, NULL, FILE_BEGIN);
  415. CheckSeek();
  416. return STG_SCODE(GetLastError());
  417. }
  418. #ifdef SECURE_SIMPLE_MODE
  419. // if we are shrinking the stream below the highwater mark, reset it
  420. if (ULIGetLow(ulNewSize) + _ulSeekStart < _ulHighWater)
  421. {
  422. _ulHighWater = ULIGetLow(ulNewSize) + _ulSeekStart;
  423. }
  424. #endif
  425. if (SetFilePointer(_hFile, ulCurrentPos, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  426. {
  427. _ulSeekPos = ULIGetLow(ulNewSize) + _ulSeekStart;
  428. CheckSeek();
  429. return STG_SCODE(GetLastError());
  430. }
  431. CheckSeek();
  432. olLog(("%p::Out CSimpStream::SetSize(). ret == %lx\n", this, S_OK));
  433. return S_OK;
  434. }
  435. //+--------------------------------------------------------------
  436. //
  437. // Member: CSimpStream::CopyTo, public
  438. //
  439. // Synopsis: Copies information from one stream to another
  440. //
  441. // Arguments: [pstm] - Destination
  442. // [cb] - Number of bytes to copy
  443. // [pcbRead] - Return number of bytes read
  444. // [pcbWritten] - Return number of bytes written
  445. //
  446. // Returns: Appropriate status code
  447. //
  448. // Modifies: [pcbRead]
  449. // [pcbWritten]
  450. //
  451. // History: 04-Aug-94 PhilipLa Created
  452. //
  453. //---------------------------------------------------------------
  454. STDMETHODIMP CSimpStream::CopyTo(IStream *pstm,
  455. ULARGE_INTEGER cb,
  456. ULARGE_INTEGER *pcbRead,
  457. ULARGE_INTEGER *pcbWritten)
  458. {
  459. simpDebugOut((DEB_TRACE, "In CSimpStream::CopyTo("
  460. "%p, %lu, %p, %p)\n", pstm, ULIGetLow(cb),
  461. pcbRead, pcbWritten));
  462. simpDebugOut((DEB_TRACE, "Out CSimpStream::CopyTo\n"));
  463. return STG_E_INVALIDFUNCTION;
  464. }
  465. //+--------------------------------------------------------------
  466. //
  467. // Member: CSimpStream::Release, public
  468. //
  469. // Synopsis: Releases a stream
  470. //
  471. // Returns: Appropriate status code
  472. //
  473. // History: 04-Aug-94 PhilipLa Created
  474. //
  475. //---------------------------------------------------------------
  476. STDMETHODIMP_(ULONG) CSimpStream::Release(void)
  477. {
  478. LONG lRet;
  479. olLog(("%p::In CSimpStream::Release()\n", this));
  480. simpDebugOut((DEB_TRACE, "In CSimpStream::Release()\n"));
  481. simpAssert(_cReferences > 0);
  482. lRet = AtomicDec(&_cReferences);
  483. if (lRet == 0)
  484. {
  485. #ifdef SECURE_SIMPLE_MODE
  486. _pstgParent->ReleaseCurrentStream(_ulHighWater);
  487. #else
  488. _pstgParent->ReleaseCurrentStream();
  489. #endif
  490. delete this;
  491. }
  492. else if (lRet < 0)
  493. lRet = 0;
  494. simpDebugOut((DEB_TRACE, "Out CSimpStream::Release\n"));
  495. olLog(("%p::Out CSimpStream::Release(). ret == %lu\n", this, lRet));
  496. FreeLogFile();
  497. return lRet;
  498. }
  499. //+--------------------------------------------------------------
  500. //
  501. // Member: CSimpStream::Stat, public
  502. //
  503. // Synopsis: Fills in a buffer of information about this object
  504. //
  505. // Arguments: [pstatstg] - Buffer
  506. //
  507. // Returns: Appropriate status code
  508. //
  509. // Modifies: [pstatstg]
  510. //
  511. // History: 04-Aug-94 PhilipLa Created
  512. //
  513. //---------------------------------------------------------------
  514. STDMETHODIMP CSimpStream::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  515. {
  516. SCODE sc = S_OK;
  517. simpDebugOut((DEB_TRACE, "In CSimpStream::Stat(%p, %lu)\n",
  518. pstatstg, grfStatFlag));
  519. SIMP_VALIDATE(Stat(pstatstg, grfStatFlag));
  520. memset (pstatstg, 0, sizeof(STATSTG));
  521. if (!(grfStatFlag & STATFLAG_NONAME))
  522. {
  523. return STG_E_INVALIDFLAG;
  524. }
  525. pstatstg->cbSize.LowPart = _ulSeekPos - _ulSeekStart;
  526. pstatstg->cbSize.HighPart = 0;
  527. pstatstg->type = STGTY_STREAM;
  528. pstatstg->grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  529. simpDebugOut((DEB_TRACE, "Out CSimpStream::Stat\n"));
  530. return sc;
  531. }
  532. //+--------------------------------------------------------------
  533. //
  534. // Member: CSimpStream::Clone, public
  535. //
  536. // Synopsis: Clones a stream
  537. //
  538. // Returns: Appropriate status code
  539. //
  540. // History: 04-Aug-94 PhilipLa Created
  541. //
  542. //---------------------------------------------------------------
  543. STDMETHODIMP CSimpStream::Clone(IStream **ppstm)
  544. {
  545. simpDebugOut((DEB_TRACE, "In CSimpStream::Clone(%p)\n",
  546. ppstm));
  547. simpDebugOut((DEB_TRACE, "Out CSimpStream::Clone\n"));
  548. return STG_E_INVALIDFUNCTION;
  549. }
  550. //+--------------------------------------------------------------
  551. //
  552. // Member: CSimpStream::AddRef, public
  553. //
  554. // Synopsis: Increments the ref count
  555. //
  556. // Returns: Appropriate status code
  557. //
  558. // History: 04-Aug-94 PhilipLa Created
  559. //
  560. //---------------------------------------------------------------
  561. STDMETHODIMP_(ULONG) CSimpStream::AddRef(void)
  562. {
  563. ULONG ulRet;
  564. olLog(("%p::In CSimpStream::AddRef()\n", this));
  565. simpDebugOut((DEB_TRACE, "In CSimpStream::AddRef()\n"));
  566. AtomicInc(&_cReferences);
  567. ulRet = _cReferences;
  568. simpDebugOut((DEB_TRACE, "Out CSimpStream::AddRef\n"));
  569. olLog(("%p::Out CSimpStream::AddRef(). ret == %lu\n", this, ulRet));
  570. return ulRet;
  571. }
  572. //+--------------------------------------------------------------
  573. //
  574. // Member: CSimpStream::LockRegion, public
  575. //
  576. // Synopsis: Nonfunctional
  577. //
  578. // Returns: Appropriate status code
  579. //
  580. // History: 04-Aug-94 PhilipLa Created
  581. //
  582. //---------------------------------------------------------------
  583. STDMETHODIMP CSimpStream::LockRegion(ULARGE_INTEGER libOffset,
  584. ULARGE_INTEGER cb,
  585. DWORD dwLockType)
  586. {
  587. simpDebugOut((DEB_TRACE, "In CSimpStream::LockRegion("
  588. "%lu, %lu\n", ULIGetLow(cb), dwLockType));
  589. simpDebugOut((DEB_TRACE, "Out CSimpStream::LockRegion\n"));
  590. return ResultFromScode(STG_E_INVALIDFUNCTION);
  591. }
  592. //+--------------------------------------------------------------
  593. //
  594. // Member: CSimpStream::UnlockRegion, public
  595. //
  596. // Synopsis: Nonfunctional
  597. //
  598. // Returns: Appropriate status code
  599. //
  600. // History: 04-Aug-94 PhilipLa Created
  601. //
  602. //---------------------------------------------------------------
  603. STDMETHODIMP CSimpStream::UnlockRegion(ULARGE_INTEGER libOffset,
  604. ULARGE_INTEGER cb,
  605. DWORD dwLockType)
  606. {
  607. simpDebugOut((DEB_TRACE, "In CSimpStream::UnlockRegion(%lu, %lu)\n",
  608. ULIGetLow(cb), dwLockType));
  609. simpDebugOut((DEB_TRACE, "Out CSimpStream::UnlockRegion\n"));
  610. return ResultFromScode(STG_E_INVALIDFUNCTION);
  611. }
  612. //+--------------------------------------------------------------
  613. //
  614. // Member: CSimpStream::Commit, public
  615. //
  616. // Synopsis: No-op in current implementation
  617. //
  618. // Returns: Appropriate status code
  619. //
  620. // History: 04-Aug-94 PhilipLa Created
  621. //
  622. //---------------------------------------------------------------
  623. STDMETHODIMP CSimpStream::Commit(DWORD grfCommitFlags)
  624. {
  625. simpDebugOut((DEB_TRACE, "In CSimpStream::Commit(%lu)\n",
  626. grfCommitFlags));
  627. simpDebugOut((DEB_TRACE, "Out CSimpStream::Commit\n"));
  628. return STG_E_UNIMPLEMENTEDFUNCTION;
  629. }
  630. //+--------------------------------------------------------------
  631. //
  632. // Member: CSimpStream::Revert, public
  633. //
  634. // Synopsis: No-op in current implementation
  635. //
  636. // Returns: Appropriate status code
  637. //
  638. // History: 04-Aug-94 PhilipLa Created
  639. //
  640. //---------------------------------------------------------------
  641. STDMETHODIMP CSimpStream::Revert(void)
  642. {
  643. simpDebugOut((DEB_TRACE, "In CSimpStream::Revert()\n"));
  644. simpDebugOut((DEB_TRACE, "Out CSimpStream::Revert\n"));
  645. return STG_E_INVALIDFUNCTION;
  646. }
  647. //+--------------------------------------------------------------
  648. //
  649. // Member: CSimpStream::QueryInterface, public
  650. //
  651. // Synopsis: Returns an object for the requested interface
  652. //
  653. // Arguments: [iid] - Interface ID
  654. // [ppvObj] - Object return
  655. //
  656. // Returns: Appropriate status code
  657. //
  658. // Modifies: [ppvObj]
  659. //
  660. // History: 04-Aug-94 PhilipLa Created
  661. //
  662. //---------------------------------------------------------------
  663. STDMETHODIMP CSimpStream::QueryInterface(REFIID iid, void **ppvObj)
  664. {
  665. SCODE sc;
  666. olLog(("%p::In CSimpStream::QueryInterface(?, %p)\n",
  667. this, ppvObj));
  668. simpDebugOut((DEB_TRACE, "In CSimpStream::QueryInterface(?, %p)\n",
  669. ppvObj));
  670. SIMP_VALIDATE(QueryInterface(iid, ppvObj));
  671. sc = S_OK;
  672. if (IsEqualIID(iid, IID_IStream) || IsEqualIID(iid, IID_IUnknown))
  673. {
  674. *ppvObj = (IStream *)this;
  675. CSimpStream::AddRef();
  676. }
  677. else if (IsEqualIID(iid, IID_IMarshal))
  678. {
  679. *ppvObj = (IMarshal *)this;
  680. CSimpStream::AddRef();
  681. }
  682. else
  683. sc = E_NOINTERFACE;
  684. simpDebugOut((DEB_TRACE, "Out CSimpStream::QueryInterface => %p\n",
  685. ppvObj));
  686. olLog(("%p::Out CSimpStream::QueryInterface(). "
  687. "*ppvObj == %p, ret == %lx\n", this, *ppvObj, sc));
  688. return ResultFromScode(sc);
  689. }
  690. //+--------------------------------------------------------------
  691. //
  692. // Member: CSimpStream::GetUnmarshalClass, public
  693. //
  694. // Synopsis: Returns the class ID
  695. //
  696. // Arguments: [riid] - IID of object
  697. // [pv] - Unreferenced
  698. // [dwDestContext] - Unreferenced
  699. // [pvDestContext] - Unreferenced
  700. // [mshlflags] - Unreferenced
  701. // [pcid] - CLSID return
  702. //
  703. // Returns: Invalid function.
  704. //
  705. // Modifies: [pcid]
  706. //
  707. // History: 04-Aug-94 PhilipLa Created
  708. //
  709. //---------------------------------------------------------------
  710. STDMETHODIMP CSimpStream::GetUnmarshalClass(REFIID riid,
  711. void *pv,
  712. DWORD dwDestContext,
  713. LPVOID pvDestContext,
  714. DWORD mshlflags,
  715. LPCLSID pcid)
  716. {
  717. return STG_E_INVALIDFUNCTION;
  718. }
  719. //+--------------------------------------------------------------
  720. //
  721. // Member: CSimpStream::GetMarshalSizeMax, public
  722. //
  723. // Synopsis: Returns the size needed for the marshal buffer
  724. //
  725. // Arguments: [riid] - IID of object being marshaled
  726. // [pv] - Unreferenced
  727. // [dwDestContext] - Unreferenced
  728. // [pvDestContext] - Unreferenced
  729. // [mshlflags] - Unreferenced
  730. // [pcbSize] - Size return
  731. //
  732. // Returns: Appropriate status code
  733. //
  734. // Modifies: [pcbSize]
  735. //
  736. // History: 04-Aug-94 PhilipLa Created
  737. //
  738. //---------------------------------------------------------------
  739. STDMETHODIMP CSimpStream::GetMarshalSizeMax(REFIID riid,
  740. void *pv,
  741. DWORD dwDestContext,
  742. LPVOID pvDestContext,
  743. DWORD mshlflags,
  744. LPDWORD pcbSize)
  745. {
  746. return STG_E_INVALIDFUNCTION;
  747. }
  748. //+--------------------------------------------------------------
  749. //
  750. // Member: CSimpStream::MarshalInterface, public
  751. //
  752. // Synopsis: Marshals a given object
  753. //
  754. // Arguments: [pstStm] - Stream to write marshal data into
  755. // [riid] - Interface to marshal
  756. // [pv] - Unreferenced
  757. // [dwDestContext] - Unreferenced
  758. // [pvDestContext] - Unreferenced
  759. // [mshlflags] - Unreferenced
  760. //
  761. // Returns: Appropriate status code
  762. //
  763. // History: 04-Aug-94 PhilipLa Created
  764. //
  765. //---------------------------------------------------------------
  766. STDMETHODIMP CSimpStream::MarshalInterface(IStream *pstStm,
  767. REFIID riid,
  768. void *pv,
  769. DWORD dwDestContext,
  770. LPVOID pvDestContext,
  771. DWORD mshlflags)
  772. {
  773. return STG_E_INVALIDFUNCTION;
  774. }
  775. //+--------------------------------------------------------------
  776. //
  777. // Member: CSimpStream::UnmarshalInterface, public
  778. //
  779. // Synopsis: Non-functional
  780. //
  781. // Arguments: [pstStm] -
  782. // [riid] -
  783. // [ppvObj] -
  784. //
  785. // Returns: Appropriate status code
  786. //
  787. // Modifies: [ppvObj]
  788. //
  789. // History: 04-Aug-94 PhilipLa Created
  790. //
  791. //---------------------------------------------------------------
  792. STDMETHODIMP CSimpStream::UnmarshalInterface(IStream *pstStm,
  793. REFIID riid,
  794. void **ppvObj)
  795. {
  796. return STG_E_INVALIDFUNCTION;
  797. }
  798. //+--------------------------------------------------------------
  799. //
  800. // Member: CSimpStream::ReleaseMarshalData, public
  801. //
  802. // Synopsis: Non-functional
  803. //
  804. // Arguments: [pstStm] -
  805. //
  806. // Returns: Appropriate status code
  807. //
  808. // History: 18-Sep-92 PhilipLa Created
  809. //
  810. //---------------------------------------------------------------
  811. STDMETHODIMP CSimpStream::ReleaseMarshalData(IStream *pstStm)
  812. {
  813. return STG_E_INVALIDFUNCTION;
  814. }
  815. //+--------------------------------------------------------------
  816. //
  817. // Member: CSimpStream::DisconnectObject, public
  818. //
  819. // Synopsis: Non-functional
  820. //
  821. // Arguments: [dwRevserved] -
  822. //
  823. // Returns: Appropriate status code
  824. //
  825. // History: 18-Sep-92 PhilipLa Created
  826. //
  827. //---------------------------------------------------------------
  828. STDMETHODIMP CSimpStream::DisconnectObject(DWORD dwReserved)
  829. {
  830. return STG_E_INVALIDFUNCTION;
  831. }
  832. //+---------------------------------------------------------------------------
  833. //
  834. // Member: CSimpStreamOpen::Init, public
  835. //
  836. // Synopsis: Initialize stream object for simple mode read
  837. //
  838. // Arguments: [pstgParent] -- Pointer to parent
  839. // [hFile] -- File handle for writes
  840. // [ulSeekStart] -- Beginning seek pointer
  841. // [grfMode] -- open mode of the stream
  842. // [pdfl] -- CDfNameList entry for this stream
  843. //
  844. // Returns: Appropriate status code
  845. //
  846. // History: 04-Jun-96 HenryLee Created
  847. //
  848. // Notes:
  849. //
  850. //----------------------------------------------------------------------------
  851. SCODE CSimpStreamOpen::Init(CSimpStorageOpen *pstgParent, HANDLE hFile,
  852. ULONG ulSeekStart, DWORD grfMode, CDfNameList *pdfl)
  853. {
  854. simpDebugOut((DEB_ITRACE, "In CSimpStreamOpen::Init:%p()\n", this));
  855. simpAssert (pdfl != NULL);
  856. _ulSeekStart = ulSeekStart;
  857. _pdfl = pdfl;
  858. _hFile = hFile;
  859. _pstgParent = pstgParent;
  860. _cReferences = 1;
  861. _grfMode = grfMode;
  862. if (SetFilePointer(_hFile, ulSeekStart, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  863. {
  864. return HRESULT_FROM_WIN32(GetLastError());
  865. }
  866. #ifdef SECURE_SIMPLE_MODE
  867. _ulHighWater = ulSeekStart + pdfl->GetSize();
  868. #endif
  869. _ulSeekPos = ulSeekStart;
  870. simpDebugOut((DEB_ITRACE, "Out CSimpStreamOpen::Init\n"));
  871. return S_OK;
  872. }
  873. //+--------------------------------------------------------------
  874. //
  875. // Member: CSimpStreamOpen::Read, public
  876. //
  877. // Synopsis: Read from a stream for simple mode open
  878. //
  879. // Arguments: [pb] - Buffer
  880. // [cb] - Count of bytes to read
  881. // [pcbRead] - Return of bytes written
  882. //
  883. // Returns: Appropriate status code
  884. //
  885. // Modifies: [pcbRead]
  886. //
  887. // History: 04-Aug-96 HenryLee Created
  888. //
  889. //---------------------------------------------------------------
  890. STDMETHODIMP CSimpStreamOpen::Read ( VOID *pb, ULONG cb, ULONG *pcbRead)
  891. {
  892. SCODE sc = S_OK;
  893. simpAssert (_pdfl != NULL);
  894. // cannot read past end of stream
  895. if (_ulSeekPos + cb > _ulSeekStart + _pdfl->GetSize())
  896. cb = _ulSeekStart + _pdfl->GetSize() - _ulSeekPos;
  897. sc = CSimpStream::Read (pb, cb, pcbRead);
  898. return sc;
  899. }
  900. //+--------------------------------------------------------------
  901. //
  902. // Member: CSimpStreamOpen::Write, public
  903. //
  904. // Synopsis: Write to a stream for simple mode open
  905. //
  906. // Arguments: [pb] - Buffer
  907. // [cb] - Count of bytes to write
  908. // [pcbWritten] - Return of bytes written
  909. //
  910. // Returns: Appropriate status code
  911. //
  912. // Modifies: [pcbWritten]
  913. //
  914. // History: 04-Jun-96 HenryLee Created
  915. //
  916. //---------------------------------------------------------------
  917. STDMETHODIMP CSimpStreamOpen::Write(VOID const *pb, ULONG cb, ULONG *pcbWritten)
  918. {
  919. SCODE sc = S_OK;
  920. simpAssert (_pdfl != NULL);
  921. if ((_grfMode & (STGM_READ|STGM_WRITE|STGM_READWRITE)) == STGM_READ)
  922. return STG_E_ACCESSDENIED;
  923. // cannot write past end of stream
  924. if (_ulSeekPos + cb > _ulSeekStart + _pdfl->GetSize())
  925. return STG_E_WRITEFAULT;
  926. sc = CSimpStream::Write (pb, cb, pcbWritten);
  927. return sc;
  928. }
  929. //+--------------------------------------------------------------
  930. //
  931. // Member: CSimpStreamOpen::SetSize, public
  932. //
  933. // Synopsis: Sets the size of a stream for simple mode read
  934. //
  935. // Arguments: [ulNewSize] - New size
  936. //
  937. // Returns: Appropriate status code
  938. //
  939. // History: 04-Jun-96 HenryLee Created
  940. //
  941. //---------------------------------------------------------------
  942. STDMETHODIMP CSimpStreamOpen::SetSize(ULARGE_INTEGER ulNewSize)
  943. {
  944. simpDebugOut((DEB_TRACE, "In CSimpStream2::SetSize()\n"));
  945. simpAssert (_pdfl != NULL);
  946. return STG_E_INVALIDFUNCTION;
  947. simpDebugOut((DEB_TRACE, "Out CSimpStreamOpen::SetSize\n"));
  948. }
  949. //+--------------------------------------------------------------
  950. //
  951. // Member: CSimpStreamOpen::Release, public
  952. //
  953. // Synopsis: Releases a stream
  954. //
  955. // Returns: Appropriate status code
  956. //
  957. // History: 04-Jun-96 HenryLee Created
  958. //
  959. //---------------------------------------------------------------
  960. STDMETHODIMP_(ULONG) CSimpStreamOpen::Release()
  961. {
  962. simpDebugOut((DEB_TRACE, "In CSimpStreamOpen::Release()\n"));
  963. simpAssert(_cReferences > 0);
  964. LONG lRet = AtomicDec(&_cReferences);
  965. if (lRet == 0)
  966. {
  967. ((CSimpStorageOpen *)_pstgParent)->ReleaseCurrentStream();
  968. delete this;
  969. }
  970. else if (lRet < 0)
  971. lRet = 0;
  972. simpDebugOut((DEB_TRACE, "Out CSimpStreamOpen::Release\n"));
  973. return lRet;
  974. }
  975. //+--------------------------------------------------------------
  976. //
  977. // Member: CSimpStreamOpen::Seek, public
  978. //
  979. // Synopsis: Seek to a point in a stream
  980. //
  981. // Arguments: [dlibMove] - Offset to move by
  982. // [dwOrigin] - SEEK_SET, SEEK_CUR, SEEK_END
  983. // [plibNewPosition] - Return of new offset
  984. //
  985. // Returns: Appropriate status code
  986. //
  987. // Modifies: [plibNewPosition]
  988. //
  989. // History: 04-Sep-96 HenryLee Created
  990. //
  991. //
  992. //---------------------------------------------------------------
  993. STDMETHODIMP CSimpStreamOpen::Seek(LARGE_INTEGER dlibMove,
  994. DWORD dwOrigin,
  995. ULARGE_INTEGER *plibNewPosition)
  996. {
  997. SCODE sc = S_OK;
  998. LONG lMove;
  999. ULONG ulPos = 0;
  1000. simpDebugOut((DEB_TRACE, "%p::In CSimpStreamOpen::Seek(%ld, %lu, %p)\n",
  1001. this, LIGetLow(dlibMove), dwOrigin, plibNewPosition));
  1002. SIMP_VALIDATE(Seek(dlibMove, dwOrigin, plibNewPosition));
  1003. // Truncate dlibMove to 32 bits
  1004. if (dwOrigin == STREAM_SEEK_SET)
  1005. {
  1006. if (LIGetHigh(dlibMove) != 0) // Make sure we don't seek too far
  1007. LISet32(dlibMove, 0xffffffff);
  1008. }
  1009. else
  1010. {
  1011. // High dword must be zero for positive values or -1 for
  1012. // negative values
  1013. // Additionally, for negative values, the low dword can't
  1014. // exceed -0x80000000 because the 32nd bit is the sign
  1015. // bit
  1016. if (LIGetHigh(dlibMove) > 0 ||
  1017. (LIGetHigh(dlibMove) == 0 && LIGetLow(dlibMove) >= 0x80000000))
  1018. LISet32(dlibMove, 0x7fffffff);
  1019. else if (LIGetHigh(dlibMove) < -1 ||
  1020. (LIGetHigh(dlibMove) == -1 && LIGetLow(dlibMove) <= 0x7fffffff))
  1021. LISet32(dlibMove, 0x80000000);
  1022. }
  1023. lMove = (LONG)LIGetLow(dlibMove);
  1024. switch(dwOrigin)
  1025. {
  1026. case STREAM_SEEK_SET:
  1027. if (lMove < 0 || (ULONG) lMove > _pdfl->GetSize())
  1028. return STG_E_INVALIDFUNCTION;
  1029. ulPos = _ulSeekStart + lMove;
  1030. break;
  1031. case STREAM_SEEK_END:
  1032. if (lMove > 0 || (lMove < 0 && (ULONG)(-lMove) > _pdfl->GetSize()))
  1033. return STG_E_INVALIDFUNCTION;
  1034. ulPos = _ulSeekStart + _pdfl->GetSize() + lMove;
  1035. break;
  1036. case STREAM_SEEK_CUR:
  1037. ulPos = SetFilePointer(_hFile, 0, NULL, FILE_CURRENT);
  1038. if ((ULONG) (ulPos + lMove) > _ulSeekStart + _pdfl->GetSize() ||
  1039. (LONG) (ulPos + lMove) < _ulSeekStart)
  1040. return STG_E_INVALIDFUNCTION;
  1041. ulPos += lMove;
  1042. break;
  1043. }
  1044. ulPos = SetFilePointer(_hFile,
  1045. ulPos,
  1046. NULL,
  1047. FILE_BEGIN);
  1048. if (plibNewPosition != NULL)
  1049. {
  1050. ULISet32(*plibNewPosition, ulPos - _ulSeekStart);
  1051. }
  1052. _ulSeekPos = ulPos;
  1053. simpDebugOut((DEB_TRACE, "%p::Out CSimpStreamOpen::Seek(). ulPos==%lu,"
  1054. " ret==%lx\n", this, ulPos, sc));
  1055. return sc;
  1056. }
  1057. //+--------------------------------------------------------------
  1058. //
  1059. // Member: CSimpStreamOpen::Stat, public
  1060. //
  1061. // Synopsis: Fills in a buffer of information about this object
  1062. //
  1063. // Arguments: [pstatstg] - Buffer
  1064. //
  1065. // Returns: Appropriate status code
  1066. //
  1067. // Modifies: [pstatstg]
  1068. //
  1069. // History: 04-Aug-94 PhilipLa Created
  1070. //
  1071. //---------------------------------------------------------------
  1072. STDMETHODIMP CSimpStreamOpen::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  1073. {
  1074. SCODE sc = S_OK;
  1075. simpDebugOut((DEB_TRACE, "In CSimpStreamOpen::Stat(%p, %lu)\n",
  1076. pstatstg, grfStatFlag));
  1077. SIMP_VALIDATE(Stat(pstatstg, grfStatFlag));
  1078. simpAssert (_pdfl != NULL);
  1079. memset (pstatstg, 0, sizeof(STATSTG));
  1080. if (!(grfStatFlag & STATFLAG_NONAME))
  1081. {
  1082. pstatstg->pwcsName = (WCHAR *) CoTaskMemAlloc (
  1083. _pdfl->GetName()->GetLength()+sizeof(WCHAR));
  1084. if (pstatstg->pwcsName)
  1085. {
  1086. memcpy (pstatstg->pwcsName, _pdfl->GetName()->GetBuffer(),
  1087. _pdfl->GetName()->GetLength());
  1088. pstatstg->pwcsName[_pdfl->GetName()->GetLength()/sizeof(WCHAR)] =
  1089. L'\0';
  1090. }
  1091. else sc = STG_E_INSUFFICIENTMEMORY;
  1092. }
  1093. pstatstg->cbSize.LowPart = _pdfl->GetSize();
  1094. pstatstg->cbSize.HighPart = 0;
  1095. pstatstg->type = STGTY_STREAM;
  1096. pstatstg->grfMode = _grfMode;
  1097. simpDebugOut((DEB_TRACE, "Out CSimpStreamOpen::Stat\n"));
  1098. return sc;
  1099. }