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.

991 lines
25 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation 1999
  3. Module Name:
  4. ByteBuffer
  5. Abstract:
  6. The IByteBuffer interface is provided to read, write and manage stream
  7. objects. This object essentially is a wrapper for the IStream object.
  8. Author:
  9. Doug Barlow (dbarlow) 6/16/1999
  10. Notes:
  11. This is a rewrite of the original code by Mike Gallagher and Chris Dudley.
  12. --*/
  13. #ifndef WIN32_LEAN_AND_MEAN
  14. #define WIN32_LEAN_AND_MEAN
  15. #endif
  16. #include "stdafx.h"
  17. #include "ByteBuffer.h"
  18. #include "Conversion.h"
  19. #define SetXL(xl, low, high) do { xl.LowPart = low; xl.HighPart = high; } while (0)
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CByteBuffer
  22. STDMETHODIMP
  23. CByteBuffer::get_Stream(
  24. /* [retval][out] */ LPSTREAM __RPC_FAR *ppStream)
  25. {
  26. HRESULT hReturn = S_OK;
  27. try
  28. {
  29. *ppStream = Stream();
  30. (*ppStream)->AddRef();
  31. }
  32. catch (HRESULT hError)
  33. {
  34. hReturn = hError;
  35. }
  36. catch (...)
  37. {
  38. hReturn = E_INVALIDARG;
  39. }
  40. return hReturn;
  41. }
  42. STDMETHODIMP CByteBuffer::put_Stream(
  43. /* [in] */ LPSTREAM pStream)
  44. {
  45. HRESULT hReturn = S_OK;
  46. LPSTREAM pOldStream = m_pStreamBuf;
  47. try
  48. {
  49. pStream->AddRef();
  50. m_pStreamBuf = pStream;
  51. if (NULL != pOldStream)
  52. pOldStream->Release();
  53. }
  54. catch (HRESULT hError)
  55. {
  56. hReturn = hError;
  57. }
  58. catch (...)
  59. {
  60. hReturn = E_INVALIDARG;
  61. }
  62. return hReturn;
  63. }
  64. /*++
  65. Clone:
  66. The Clone method creates a new object with its own seek pointer that
  67. references the same bytes as the original IByteBuffer object.
  68. Arguments:
  69. ppByteBuffer [out] When successful, points to the location of an
  70. IByteBuffer pointer to the new stream object. If an error occurs, this
  71. parameter is NULL.
  72. Return Value:
  73. The return value is an HRESULT. A value of S_OK indicates the call was
  74. successful.
  75. Remarks:
  76. This method creates a new stream object for accessing the same bytes but
  77. using a separate seek pointer. The new stream object sees the same data as
  78. the source stream object. Changes written to one object are immediately
  79. visible in the other. Range locking is shared between the stream objects.
  80. The initial setting of the seek pointer in the cloned stream instance is
  81. the same as the current setting of the seek pointer in the original stream
  82. at the time of the clone operation.
  83. Author:
  84. Doug Barlow (dbarlow) 6/16/1999
  85. --*/
  86. #undef __SUBROUTINE__
  87. #define __SUBROUTINE__ TEXT("CByteBuffer::Clone")
  88. STDMETHODIMP
  89. CByteBuffer::Clone(
  90. /* [out][in] */ LPBYTEBUFFER __RPC_FAR *ppByteBuffer)
  91. {
  92. HRESULT hReturn = S_OK;
  93. CByteBuffer *pNewBuf = NULL;
  94. LPSTREAM pNewStream = NULL;
  95. try
  96. {
  97. HRESULT hr;
  98. *ppByteBuffer = NULL;
  99. pNewBuf = NewByteBuffer();
  100. if (NULL == pNewBuf)
  101. throw (HRESULT)E_OUTOFMEMORY;
  102. hr = Stream()->Clone(&pNewStream);
  103. if (FAILED(hr))
  104. throw hr;
  105. hr = pNewBuf->put_Stream(pNewStream);
  106. if (FAILED(hr))
  107. throw hr;
  108. pNewStream->Release();
  109. pNewStream = NULL;
  110. *ppByteBuffer = pNewBuf;
  111. pNewBuf = NULL;
  112. }
  113. catch (HRESULT hError)
  114. {
  115. hReturn = hError;
  116. }
  117. catch (...)
  118. {
  119. hReturn = E_INVALIDARG;
  120. }
  121. if (NULL != pNewBuf)
  122. pNewBuf->Release();
  123. if (NULL != pNewStream)
  124. pNewStream->Release();
  125. return hReturn;
  126. }
  127. /*++
  128. Commit:
  129. The Commit method ensures that any changes made to an object open in
  130. transacted mode are reflected in the parent storage.
  131. Arguments:
  132. grfCommitFlags [in] Controls how the changes for the stream object are
  133. committed. See the STGC enumeration for a definition of these values.
  134. Return Value:
  135. The return value is an HRESULT. A value of S_OK indicates the call was
  136. successful.
  137. Remarks:
  138. This method ensures that changes to a stream object opened in transacted
  139. mode are reflected in the parent storage. Changes that have been made to
  140. the stream since it was opened or last committed are reflected to the
  141. parent storage object. If the parent is opened in transacted mode, the
  142. parent may still revert at a later time rolling back the changes to this
  143. stream object. The compound file implementation does not support opening
  144. streams in transacted mode, so this method has very little effect other
  145. than to flush memory buffers.
  146. Author:
  147. Doug Barlow (dbarlow) 6/16/1999
  148. --*/
  149. #undef __SUBROUTINE__
  150. #define __SUBROUTINE__ TEXT("CByteBuffer::Commit")
  151. STDMETHODIMP
  152. CByteBuffer::Commit(
  153. /* [in] */ LONG grfCommitFlags)
  154. {
  155. HRESULT hReturn = S_OK;
  156. try
  157. {
  158. hReturn = Stream()->Commit(grfCommitFlags);
  159. }
  160. catch (HRESULT hError)
  161. {
  162. hReturn = hError;
  163. }
  164. catch (...)
  165. {
  166. hReturn = E_INVALIDARG;
  167. }
  168. return hReturn;
  169. }
  170. /*++
  171. CopyTo:
  172. The CopyTo method copies a specified number of bytes from the current seek
  173. pointer in the object to the current seek pointer in another object.
  174. Arguments:
  175. pByteBuffer [in] Points to the destination stream. The stream pointed to by
  176. pByteBuffer can be a new stream or a clone of the source stream.
  177. cb [in] Specifies the number of bytes to copy from the source stream.
  178. pcbRead [out] Pointer to the location where this method writes the actual
  179. number of bytes read from the source. You can set this pointer to NULL
  180. to indicate that you are not interested in this value. In this case,
  181. this method does not provide the actual number of bytes read.
  182. pcbWritten [out] Pointer to the location where this method writes the
  183. actual number of bytes written to the destination. You can set this
  184. pointer to NULL to indicate that you are not interested in this value.
  185. In this case, this method does not provide the actual number of bytes
  186. written.
  187. Return Value:
  188. The return value is an HRESULT. A value of S_OK indicates the call was
  189. successful.
  190. Remarks:
  191. This method copies the specified bytes from one stream to another. It can
  192. also be used to copy a stream to itself. The seek pointer in each stream
  193. instance is adjusted for the number of bytes read or written.
  194. Author:
  195. Doug Barlow (dbarlow) 6/16/1999
  196. --*/
  197. #undef __SUBROUTINE__
  198. #define __SUBROUTINE__ TEXT("CByteBuffer::CopyTo")
  199. STDMETHODIMP
  200. CByteBuffer::CopyTo(
  201. /* [out][in] */ LPBYTEBUFFER __RPC_FAR *ppByteBuffer,
  202. /* [in] */ LONG cb,
  203. /* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbRead,
  204. /* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbWritten)
  205. {
  206. HRESULT hReturn = S_OK;
  207. CByteBuffer *pMyBuffer = NULL;
  208. LPSTREAM pStream = NULL;
  209. try
  210. {
  211. HRESULT hr;
  212. ULARGE_INTEGER xulcb, xulRead, xulWritten;
  213. if (NULL == *ppByteBuffer)
  214. {
  215. *ppByteBuffer = pMyBuffer = NewByteBuffer();
  216. if (NULL == *ppByteBuffer)
  217. throw (HRESULT)E_OUTOFMEMORY;
  218. }
  219. hr = (*ppByteBuffer)->get_Stream(&pStream);
  220. if (FAILED(hr))
  221. throw hr;
  222. SetXL(xulcb, cb, 0);
  223. SetXL(xulRead, 0, 0);
  224. SetXL(xulWritten, 0, 0);
  225. hr = Stream()->CopyTo(pStream, xulcb, &xulRead, &xulWritten);
  226. if (FAILED(hr))
  227. throw hr;
  228. pStream->Release();
  229. pStream = NULL;
  230. if (NULL != pcbRead)
  231. *pcbRead = xulRead.LowPart;
  232. if (NULL != pcbWritten)
  233. *pcbWritten = xulWritten.LowPart;
  234. pMyBuffer = NULL;
  235. }
  236. catch (HRESULT hError)
  237. {
  238. hReturn = hError;
  239. }
  240. catch (...)
  241. {
  242. hReturn = E_INVALIDARG;
  243. }
  244. if (NULL != pMyBuffer)
  245. {
  246. pMyBuffer->Release();
  247. *ppByteBuffer = NULL;
  248. }
  249. if (NULL != pStream)
  250. pStream->Release();
  251. return hReturn;
  252. }
  253. /*++
  254. Initialize:
  255. The Initialize method prepares the IByteBuffer object for use. This method
  256. must be called prior to calling any other methods in the IByteBuffer
  257. interface.
  258. Arguments:
  259. lSize - The initial size in bytes of the data the stream is to contain.
  260. pData - If not NULL, the initial data to write to the stream.
  261. Return Value:
  262. The return value is an HRESULT. A value of S_OK indicates the call was
  263. successful.
  264. Remarks:
  265. When using a new IByteBuffer stream, call this method prior to using any of
  266. the other IByteBuffer methods.
  267. Author:
  268. Doug Barlow (dbarlow) 6/16/1999
  269. --*/
  270. #undef __SUBROUTINE__
  271. #define __SUBROUTINE__ TEXT("CByteBuffer::Initialize")
  272. STDMETHODIMP
  273. CByteBuffer::Initialize(
  274. /* [defaultvalue][in] */ LONG lSize,
  275. /* [defaultvalue][in] */ BYTE __RPC_FAR *pData)
  276. {
  277. HRESULT hReturn = S_OK;
  278. try
  279. {
  280. HRESULT hr;
  281. ULARGE_INTEGER xul;
  282. LARGE_INTEGER xl;
  283. SetXL(xul, 0, 0);
  284. SetXL(xl, 0, 0);
  285. hr = Stream()->SetSize(xul);
  286. if (FAILED(hr))
  287. throw hr;
  288. hr = Stream()->Seek(xl, STREAM_SEEK_SET, NULL);
  289. if (FAILED(hr))
  290. throw hr;
  291. if ((0 != lSize) && (NULL != pData))
  292. {
  293. hr = Stream()->Write(pData, lSize, NULL);
  294. if (FAILED(hr))
  295. throw hr;
  296. }
  297. }
  298. catch (HRESULT hError)
  299. {
  300. hReturn = hError;
  301. }
  302. catch (...)
  303. {
  304. hReturn = E_INVALIDARG;
  305. }
  306. return hReturn;
  307. }
  308. /*++
  309. LockRegion:
  310. The LockRegion method restricts access to a specified range of bytes in the
  311. buffer object.
  312. Arguments:
  313. libOffset [in] Integer that specifies the byte offset for the beginning of
  314. the range.
  315. cb [in] Integer that specifies the length of the range, in bytes, to be
  316. restricted.
  317. dwLockType [in] Specifies the restrictions being requested on accessing the
  318. range.
  319. Return Value:
  320. The return value is an HRESULT. A value of S_OK indicates the call was
  321. successful.
  322. Remarks:
  323. The byte range can extend past the current end of the stream. Locking
  324. beyond the end of a stream is useful as a method of communication between
  325. different instances of the stream without changing data that is actually
  326. part of the stream.
  327. Three types of locking can be supported: locking to exclude other writers,
  328. locking to exclude other readers or writers, and locking that allows only
  329. one requestor to obtain a lock on the given range, which is usually an
  330. alias for one of the other two lock types. A given stream instance might
  331. support either of the first two types, or both. The lock type is specified
  332. by dwLockType, using a value from the LOCKTYPE enumeration.
  333. Any region locked with IByteBuffer::LockRegion must later be explicitly
  334. unlocked by calling IByteBuffer::UnlockRegion with exactly the same values
  335. for the libOffset, cb, and dwLockType parameters. The region must be
  336. unlocked before the stream is released. Two adjacent regions cannot be
  337. locked separately and then unlocked with a single unlock call.
  338. Author:
  339. Doug Barlow (dbarlow) 6/16/1999
  340. --*/
  341. #undef __SUBROUTINE__
  342. #define __SUBROUTINE__ TEXT("CByteBuffer::LockRegion")
  343. STDMETHODIMP
  344. CByteBuffer::LockRegion(
  345. /* [in] */ LONG libOffset,
  346. /* [in] */ LONG cb,
  347. /* [in] */ LONG dwLockType)
  348. {
  349. HRESULT hReturn = S_OK;
  350. try
  351. {
  352. ULARGE_INTEGER xulOffset, xulcb;
  353. SetXL(xulOffset, libOffset, 0);
  354. SetXL(xulcb, cb, 0);
  355. hReturn = Stream()->LockRegion(xulOffset, xulcb, dwLockType);
  356. }
  357. catch (HRESULT hError)
  358. {
  359. hReturn = hError;
  360. }
  361. catch (...)
  362. {
  363. hReturn = E_INVALIDARG;
  364. }
  365. return hReturn;
  366. }
  367. /*++
  368. Read:
  369. The Read method reads a specified number of bytes from the buffer object
  370. into memory starting at the current seek pointer.
  371. Arguments:
  372. pByte [out] Points to the buffer into which the stream data is read. If an
  373. error occurs, this value is NULL.
  374. cb [in] Specifies the number of bytes of data to attempt to read from the
  375. stream object.
  376. pcbRead [out] Address of a LONG variable that receives the actual number of
  377. bytes read from the stream object. You can set this pointer to NULL to
  378. indicate that you are not interested in this value. In this case, this
  379. method does not provide the actual number of bytes read.
  380. Return Value:
  381. The return value is an HRESULT. A value of S_OK indicates the call was
  382. successful.
  383. Remarks:
  384. This method reads bytes from this stream object into memory. The stream
  385. object must be opened in STGM_READ mode. This method adjusts the seek
  386. pointer by the actual number of bytes read.
  387. The number of bytes actually read is also returned in the pcbRead
  388. parameter.
  389. Notes to Callers
  390. The actual number of bytes read can be fewer than the number of bytes
  391. requested if an error occurs or if the end of the stream is reached during
  392. the read operation.
  393. Some implementations might return an error if the end of the stream is
  394. reached during the read. You must be prepared to deal with the error
  395. return or S_OK return values on end of stream reads.
  396. Author:
  397. Doug Barlow (dbarlow) 6/16/1999
  398. --*/
  399. #undef __SUBROUTINE__
  400. #define __SUBROUTINE__ TEXT("CByteBuffer::Read")
  401. STDMETHODIMP
  402. CByteBuffer::Read(
  403. /* [out][in] */ BYTE __RPC_FAR *pByte,
  404. /* [in] */ LONG cb,
  405. /* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbRead)
  406. {
  407. HRESULT hReturn = S_OK;
  408. try
  409. {
  410. hReturn = Stream()->Read(pByte, cb, (LPDWORD)pcbRead);
  411. }
  412. catch (HRESULT hError)
  413. {
  414. hReturn = hError;
  415. }
  416. catch (...)
  417. {
  418. hReturn = E_INVALIDARG;
  419. }
  420. return hReturn;
  421. }
  422. /*++
  423. Revert:
  424. The Revert method discards all changes that have been made to a transacted
  425. stream since the last IByteBuffer::Commit call.
  426. Arguments:
  427. None.
  428. Return Value:
  429. The return value is an HRESULT. A value of S_OK indicates the call was
  430. successful and the stream was reverted to its previous version.
  431. Remarks:
  432. This method discards changes made to a transacted stream since the last
  433. commit operation.
  434. Author:
  435. Doug Barlow (dbarlow) 6/16/1999
  436. --*/
  437. #undef __SUBROUTINE__
  438. #define __SUBROUTINE__ TEXT("CByteBuffer::Revert")
  439. STDMETHODIMP
  440. CByteBuffer::Revert(
  441. void)
  442. {
  443. HRESULT hReturn = S_OK;
  444. try
  445. {
  446. hReturn = Stream()->Revert();
  447. }
  448. catch (HRESULT hError)
  449. {
  450. hReturn = hError;
  451. }
  452. catch (...)
  453. {
  454. hReturn = E_INVALIDARG;
  455. }
  456. return hReturn;
  457. }
  458. /*++
  459. Seek:
  460. The Seek method changes the seek pointer to a new location relative to the
  461. beginning of the buffer, to the end of the buffer, or to the current seek
  462. pointer.
  463. Arguments:
  464. dLibMove [in] Displacement to be added to the location indicated by
  465. dwOrigin. If dwOrigin is STREAM_SEEK_SET, this is interpreted as an
  466. unsigned value rather than signed.
  467. dwOrigin [in] Specifies the origin for the displacement specified in
  468. dlibMove. The origin can be the beginning of the file, the current
  469. seek pointer, or the end of the file. See the STREAM_SEEK enumeration
  470. for the values.
  471. pLibnewPosition [out] Pointer to the location where this method writes the
  472. value of the new seek pointer from the beginning of the stream. You
  473. can set this pointer to NULL to indicate that you are not interested in
  474. this value. In this case, this method does not provide the new seek
  475. pointer.
  476. Return Value:
  477. The return value is an HRESULT. A value of S_OK indicates the call was
  478. successful.
  479. Remarks:
  480. IByteBuffer::Seek changes the seek pointer so subsequent reads and writes
  481. can take place at a different location in the stream object. It is an
  482. error to seek before the beginning of the stream. It is not, however, an
  483. error to seek past the end of the stream. Seeking past the end of the
  484. stream is useful for subsequent writes, as the stream will at that time be
  485. extended to the seek position immediately before the write is done.
  486. You can also use this method to obtain the current value of the seek
  487. pointer by calling this method with the dwOrigin parameter set to
  488. STREAM_SEEK_CUR and the dlibMove parameter set to 0 so the seek pointer is
  489. not changed. The current seek pointer is returned in the plibNewPosition
  490. parameter.
  491. Author:
  492. Doug Barlow (dbarlow) 6/16/1999
  493. --*/
  494. #undef __SUBROUTINE__
  495. #define __SUBROUTINE__ TEXT("CByteBuffer::Seek")
  496. STDMETHODIMP
  497. CByteBuffer::Seek(
  498. /* [in] */ LONG dLibMove,
  499. /* [in] */ LONG dwOrigin,
  500. /* [defaultvalue][out][in] */ LONG __RPC_FAR *pLibnewPosition)
  501. {
  502. HRESULT hReturn = S_OK;
  503. try
  504. {
  505. LARGE_INTEGER xlMove;
  506. ULARGE_INTEGER xulNewPos;
  507. SetXL(xlMove, dLibMove, 0);
  508. SetXL(xulNewPos, 0, 0);
  509. hReturn = Stream()->Seek(xlMove, dwOrigin, &xulNewPos);
  510. if (NULL != pLibnewPosition)
  511. *pLibnewPosition = xulNewPos.LowPart;
  512. }
  513. catch (HRESULT hError)
  514. {
  515. hReturn = hError;
  516. }
  517. catch (...)
  518. {
  519. hReturn = E_INVALIDARG;
  520. }
  521. return hReturn;
  522. }
  523. /*++
  524. SetSize:
  525. The SetSize method changes the size of the stream object.
  526. Arguments:
  527. libNewSize [in] Specifies the new size of the stream as a number of bytes
  528. Return Value:
  529. The return value is an HRESULT. A value of S_OK indicates the call was
  530. successful.
  531. Remarks:
  532. IByteBuffer::SetSize changes the size of the stream object. Call this
  533. method to preallocate space for the stream. If the libNewSize parameter is
  534. larger than the current stream size, the stream is extended to the
  535. indicated size by filling the intervening space with bytes of undefined
  536. value. This operation is similar to the IByteBuffer::Write method if the
  537. seek pointer is past the current end-of-stream.
  538. If the libNewSize parameter is smaller than the current stream, then the
  539. stream is truncated to the indicated size.
  540. The seek pointer is not affected by the change in stream size.
  541. Calling IByteBuffer::SetSize can be an effective way of trying to obtain a
  542. large chunk of contiguous space.
  543. Author:
  544. Doug Barlow (dbarlow) 6/16/1999
  545. --*/
  546. #undef __SUBROUTINE__
  547. #define __SUBROUTINE__ TEXT("CByteBuffer::SetSize")
  548. STDMETHODIMP
  549. CByteBuffer::SetSize(
  550. /* [in] */ LONG libNewSize)
  551. {
  552. HRESULT hReturn = S_OK;
  553. try
  554. {
  555. ULARGE_INTEGER xul;
  556. SetXL(xul, libNewSize, 0);
  557. hReturn = Stream()->SetSize(xul);
  558. }
  559. catch (HRESULT hError)
  560. {
  561. hReturn = hError;
  562. }
  563. catch (...)
  564. {
  565. hReturn = E_INVALIDARG;
  566. }
  567. return hReturn;
  568. }
  569. /*++
  570. Stat:
  571. The Stat method retrieves statistical information from the stream object.
  572. Arguments:
  573. pstatstg [out] Points to a STATSTG structure where this method places
  574. information about this stream object. This data in this structure
  575. is meaningless if an error occurs.
  576. grfStatFlag [in] Ignored.
  577. Return Value:
  578. The return value is an HRESULT. A value of S_OK indicates the call was
  579. successful.
  580. Remarks:
  581. IByteBuffer::Stat retrieves a pointer to the STATSTG structure that
  582. contains information about this open stream.
  583. Author:
  584. Doug Barlow (dbarlow) 6/16/1999
  585. --*/
  586. #undef __SUBROUTINE__
  587. #define __SUBROUTINE__ TEXT("CByteBuffer::Stat")
  588. STDMETHODIMP
  589. CByteBuffer::Stat(
  590. /* [out][in] */ LPSTATSTRUCT pstatstg,
  591. /* [in] */ LONG grfStatFlag)
  592. {
  593. HRESULT hReturn = S_OK;
  594. try
  595. {
  596. HRESULT hr;
  597. STATSTG stg;
  598. hr = Stream()->Stat(&stg, STATFLAG_NONAME);
  599. if (FAILED(hr))
  600. throw hr;
  601. pstatstg->type = stg.type;
  602. pstatstg->cbSize = stg.cbSize.LowPart;
  603. pstatstg->grfMode = stg.grfMode;
  604. pstatstg->grfLocksSupported = stg.grfLocksSupported;
  605. pstatstg->grfStateBits = stg.grfStateBits;
  606. }
  607. catch (HRESULT hError)
  608. {
  609. hReturn = hError;
  610. }
  611. catch (...)
  612. {
  613. hReturn = E_INVALIDARG;
  614. }
  615. return hReturn;
  616. }
  617. /*++
  618. UnlockRegion:
  619. The UnlockRegion method removes the access restriction on a range of bytes
  620. previously restricted with IByteBuffer::LockRegion.
  621. Arguments:
  622. libOffset [in] Specifies the byte offset for the beginning of the range.
  623. cb [in] Specifies, in bytes, the length of the range to be restricted.
  624. dwLockType [in] Specifies the access restrictions previously placed on the
  625. range.
  626. Return Value:
  627. The return value is an HRESULT. A value of S_OK indicates the call was
  628. successful.
  629. Remarks:
  630. IByteBuffer::UnlockRegion unlocks a region previously locked with the
  631. IByteBuffer::LockRegion method. Locked regions must later be explicitly
  632. unlocked by calling IByteBuffer::UnlockRegion with exactly the same values
  633. for the libOffset, cb, and dwLockType parameters. The region must be
  634. unlocked before the stream is released. Two adjacent regions cannot be
  635. locked separately and then unlocked with a single unlock call.
  636. Author:
  637. Doug Barlow (dbarlow) 6/16/1999
  638. --*/
  639. #undef __SUBROUTINE__
  640. #define __SUBROUTINE__ TEXT("CByteBuffer::UnlockRegion")
  641. STDMETHODIMP
  642. CByteBuffer::UnlockRegion(
  643. /* [in] */ LONG libOffset,
  644. /* [in] */ LONG cb,
  645. /* [in] */ LONG dwLockType)
  646. {
  647. HRESULT hReturn = S_OK;
  648. try
  649. {
  650. ULARGE_INTEGER xulOffset, xulcb;
  651. SetXL(xulOffset, libOffset, 0);
  652. SetXL(xulcb, cb, 0);
  653. hReturn = Stream()->UnlockRegion(xulOffset, xulcb, dwLockType);
  654. }
  655. catch (HRESULT hError)
  656. {
  657. hReturn = hError;
  658. }
  659. catch (...)
  660. {
  661. hReturn = E_INVALIDARG;
  662. }
  663. return hReturn;
  664. }
  665. /*++
  666. Write:
  667. The Write method writes a specified number from bytes into the stream
  668. object starting at the current seek pointer.
  669. Arguments:
  670. pByte [in] Address of the buffer containing the data that is to be written
  671. to the stream. A valid pointer must be provided for this parameter
  672. even when cb is zero.
  673. cb [in] The number of bytes of data to attempt to write into the stream.
  674. Can be zero.
  675. pcbWritten [out] Address of a LONG variable where this method writes the
  676. actual number of bytes written to the stream object. The caller can
  677. set this pointer to NULL, in which case, this method does not provide
  678. the actual number of bytes written.
  679. Return Value:
  680. The return value is an HRESULT. A value of S_OK indicates the call was
  681. successful.
  682. Remarks:
  683. IByteBuffer::Write writes the specified data to a stream object. The seek
  684. pointer is adjusted for the number of bytes actually written. The number
  685. of bytes actually written is returned in the pcbWritten parameter. If the
  686. byte count is zero bytes, the write operation has no effect.
  687. If the seek pointer is currently past the end of the stream and the byte
  688. count is nonzero, this method increases the size of the stream to the seek
  689. pointer and writes the specified bytes starting at the seek pointer. The
  690. fill bytes written to the stream are not initialized to any particular
  691. value. This is the same as the end-of-file behavior in the MS-DOS FAT file
  692. system.
  693. With a zero byte count and a seek pointer past the end of the stream, this
  694. method does not create the fill bytes to increase the stream to the seek
  695. pointer. In this case, you must call the IByteBuffer::SetSize method to
  696. increase the size of the stream and write the fill bytes.
  697. The pcbWritten parameter can have a value even if an error occurs.
  698. In the COM-provided implementation, stream objects are not sparse. Any
  699. fill bytes are eventually allocated on the disk and assigned to the stream.
  700. Author:
  701. Doug Barlow (dbarlow) 6/16/1999
  702. --*/
  703. #undef __SUBROUTINE__
  704. #define __SUBROUTINE__ TEXT("CByteBuffer::Write")
  705. STDMETHODIMP
  706. CByteBuffer::Write(
  707. /* [out][in] */ BYTE __RPC_FAR *pByte,
  708. /* [in] */ LONG cb,
  709. /* [out][in] */ LONG __RPC_FAR *pcbWritten)
  710. {
  711. HRESULT hReturn = S_OK;
  712. try
  713. {
  714. hReturn = Stream()->Write(pByte, cb, (LPDWORD)pcbWritten);
  715. }
  716. catch (HRESULT hError)
  717. {
  718. hReturn = hError;
  719. }
  720. catch (...)
  721. {
  722. hReturn = E_INVALIDARG;
  723. }
  724. return hReturn;
  725. }