Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
6.4 KiB

  1. // Stream.cpp -- Implementation for class CStream
  2. #include "stdafx.h"
  3. HRESULT CStream::OpenStream(IUnknown *punkOuter, ILockBytes *pLockBytes, DWORD grfMode,
  4. IStreamITEx **ppStream
  5. )
  6. {
  7. CStream *pStream= New CStream(punkOuter);
  8. if (!pStream)
  9. {
  10. pLockBytes->Release();
  11. return STG_E_INSUFFICIENTMEMORY;
  12. }
  13. IStreamITEx *pIStream = NULL;
  14. HRESULT hr= pStream->m_ImpIStream.InitOpenStream(pLockBytes, grfMode);
  15. if (hr == NOERROR)
  16. {
  17. pIStream = (IStreamITEx *) &pStream->m_ImpIStream;
  18. pStream->AddRef();
  19. }
  20. else
  21. delete pStream;
  22. *ppStream= pIStream;
  23. return hr;
  24. }
  25. HRESULT CStream::CImpIStream::InitOpenStream(ILockBytes *pLockBytes, DWORD grfMode)
  26. {
  27. m_pLockBytes = pLockBytes;
  28. m_grfMode = grfMode;
  29. // Note: We assume that pLockBytes was AddRef'd before it was given to us.
  30. return NO_ERROR;
  31. }
  32. // ISequentialStream methods:
  33. HRESULT __stdcall CStream::CImpIStream::Read
  34. (void __RPC_FAR *pv,ULONG cb,ULONG __RPC_FAR *pcbRead)
  35. {
  36. DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
  37. if (grfAccess != STGM_READ && grfAccess != STGM_READWRITE)
  38. return STG_E_ACCESSDENIED;
  39. CSyncWith sw(m_cs);
  40. ULONG cbRead = 0;
  41. HRESULT hr = m_pLockBytes->ReadAt(m_ullStreamPosition.Uli(), pv, cb, &cbRead);
  42. m_ullStreamPosition += cbRead;
  43. if (pcbRead)
  44. *pcbRead = cbRead;
  45. return hr;
  46. }
  47. HRESULT __stdcall CStream::CImpIStream::Write
  48. (const void __RPC_FAR *pv, ULONG cb,
  49. ULONG __RPC_FAR *pcbWritten
  50. )
  51. {
  52. DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
  53. if (grfAccess != STGM_WRITE && grfAccess != STGM_READWRITE)
  54. return STG_E_ACCESSDENIED;
  55. CSyncWith sw(m_cs);
  56. ULONG cbWritten = 0;
  57. HRESULT hr = m_pLockBytes->WriteAt(m_ullStreamPosition.Uli(), pv, cb, &cbWritten);
  58. m_ullStreamPosition += cbWritten;
  59. if (pcbWritten)
  60. *pcbWritten = cbWritten;
  61. return hr;
  62. }
  63. // IStream methods:
  64. HRESULT __stdcall CStream::CImpIStream::Seek
  65. (LARGE_INTEGER dlibMove, DWORD dwOrigin,
  66. ULARGE_INTEGER __RPC_FAR *plibNewPosition
  67. )
  68. {
  69. HRESULT hr = NO_ERROR;
  70. CSyncWith sw(m_cs);
  71. STATSTG statstg;
  72. hr = m_pLockBytes->Stat(&statstg, STATFLAG_NONAME);
  73. if (!SUCCEEDED(hr))
  74. return hr;
  75. CULINT ullNewPosition;
  76. switch (dwOrigin)
  77. {
  78. case STREAM_SEEK_SET:
  79. ullNewPosition = *(ULARGE_INTEGER *) &dlibMove;
  80. break;
  81. case STREAM_SEEK_CUR:
  82. ullNewPosition = m_ullStreamPosition + *(ULARGE_INTEGER *) &dlibMove;
  83. break;
  84. case STREAM_SEEK_END:
  85. ullNewPosition = statstg.cbSize;
  86. ullNewPosition += *(ULARGE_INTEGER *) &dlibMove;
  87. break;
  88. default:
  89. return STG_E_INVALIDFUNCTION;
  90. }
  91. if (ullNewPosition > statstg.cbSize)
  92. return STG_E_INVALIDPOINTER;
  93. m_ullStreamPosition = ullNewPosition;
  94. if (plibNewPosition)
  95. *plibNewPosition = ullNewPosition.Uli();
  96. return hr;
  97. }
  98. HRESULT __stdcall CStream::CImpIStream::SetSize(ULARGE_INTEGER libNewSize)
  99. {
  100. DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
  101. if (grfAccess != STGM_WRITE && grfAccess != STGM_READWRITE)
  102. return STG_E_ACCESSDENIED;
  103. return m_pLockBytes->SetSize(libNewSize);
  104. }
  105. HRESULT __stdcall CStream::CImpIStream::CopyTo
  106. (IStream __RPC_FAR *pstm, ULARGE_INTEGER cb,
  107. ULARGE_INTEGER __RPC_FAR *pcbRead,
  108. ULARGE_INTEGER __RPC_FAR *pcbWritten
  109. )
  110. {
  111. BYTE abBuffer[CB_MAX_COPY_SEGMENT];
  112. CULINT ullRequested, ullRead(0), ullWritten(0);
  113. ullRequested = cb;
  114. HRESULT hr = NO_ERROR;
  115. CSyncWith sw(m_cs);
  116. ULONG ulSegment;
  117. for (; ullRequested.NonZero(); ullRequested -= ulSegment)
  118. {
  119. ulSegment = CB_MAX_COPY_SEGMENT;
  120. if (ulSegment > ullRequested)
  121. ulSegment = ullRequested.Uli().LowPart;
  122. ULONG cbRead = 0;
  123. hr = Read(abBuffer, ulSegment, &cbRead);
  124. ullRead += cbRead;
  125. if (!SUCCEEDED(hr))
  126. break;
  127. ULONG cbWritten = 0;
  128. hr = pstm->Write(abBuffer, ulSegment, &cbWritten);
  129. ullWritten += cbWritten;
  130. if (!SUCCEEDED(hr))
  131. break;
  132. }
  133. if (pcbRead)
  134. *pcbRead = ullRead.Uli();
  135. if (pcbWritten)
  136. *pcbWritten = ullWritten.Uli();
  137. return hr;
  138. }
  139. HRESULT __stdcall CStream::CImpIStream::Commit(DWORD grfCommitFlags)
  140. {
  141. return NO_ERROR;
  142. }
  143. HRESULT __stdcall CStream::CImpIStream::Revert(void)
  144. {
  145. RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
  146. return E_NOTIMPL;
  147. }
  148. HRESULT __stdcall CStream::CImpIStream::LockRegion
  149. (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  150. DWORD dwLockType
  151. )
  152. {
  153. return m_pLockBytes->LockRegion(libOffset, cb, dwLockType);
  154. }
  155. HRESULT __stdcall CStream::CImpIStream::UnlockRegion
  156. (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  157. DWORD dwLockType
  158. )
  159. {
  160. return m_pLockBytes->UnlockRegion(libOffset, cb, dwLockType);
  161. }
  162. HRESULT __stdcall CStream::CImpIStream::Stat
  163. (STATSTG __RPC_FAR *pstatstg, DWORD grfStatFlag)
  164. {
  165. HRESULT hr = m_pLockBytes->Stat(pstatstg, grfStatFlag);
  166. if (SUCCEEDED(hr))
  167. pstatstg->type = STGTY_STREAM;
  168. return hr;
  169. }
  170. HRESULT __stdcall CStream::CImpIStream::Clone
  171. (IStream __RPC_FAR *__RPC_FAR *ppstm)
  172. {
  173. CImpIStream *pStreamNew = NULL;
  174. m_pLockBytes->AddRef();
  175. HRESULT hr = CStream::OpenStream(NULL, m_pLockBytes, m_grfMode,
  176. (IStreamITEx **)&pStreamNew
  177. );
  178. if (SUCCEEDED(hr))
  179. {
  180. pStreamNew->m_ullStreamPosition = m_ullStreamPosition;
  181. *ppstm = (IStream *) pStreamNew;
  182. }
  183. return hr;
  184. }
  185. HRESULT STDMETHODCALLTYPE CStream::CImpIStream::SetDataSpaceName
  186. (const WCHAR *pwcsDataSpaceName)
  187. {
  188. RonM_ASSERT(FALSE);
  189. return E_NOTIMPL;
  190. }
  191. HRESULT STDMETHODCALLTYPE CStream::CImpIStream::GetDataSpaceName
  192. (WCHAR **ppwcsDataSpaceName)
  193. {
  194. RonM_ASSERT(FALSE);
  195. return E_NOTIMPL;
  196. }
  197. HRESULT STDMETHODCALLTYPE CStream::CImpIStream::Flush()
  198. {
  199. return m_pLockBytes->Flush();
  200. }