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.

315 lines
5.4 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: stream.cxx
  4. //
  5. // Contents: Stream interface on flat File.
  6. //
  7. // Classes: CStreamOnFile
  8. //
  9. // Macros: DEFINE_INTERFACE_XMIT_ROUTINES
  10. //
  11. // History: 08-08-95 Rickhi Created
  12. //
  13. //--------------------------------------------------------------------
  14. #include <ole2.h>
  15. #include <stream.hxx>
  16. CStreamOnFile::CStreamOnFile(const WCHAR *pwszFileName, SCODE &sc, BOOL fRead) :
  17. _clRefs(1),
  18. _hFile(NULL),
  19. _lOffset(0),
  20. _cSize(0),
  21. _cbData(0),
  22. _fRead(fRead)
  23. {
  24. _pbData = new BYTE[2048]; // should be big enough
  25. if (!_pbData)
  26. {
  27. sc = E_OUTOFMEMORY;
  28. return;
  29. }
  30. _cbData = 2048;
  31. // open the file.
  32. DWORD fdwCreate = (_fRead) ? OPEN_EXISTING : CREATE_ALWAYS;
  33. _hFile = CreateFile(pwszFileName,
  34. GENERIC_READ | GENERIC_WRITE, // fdwAccess
  35. FILE_SHARE_READ | FILE_SHARE_WRITE, // fdwShareMode
  36. NULL, // lpsaSecurity
  37. fdwCreate, // creation options
  38. FILE_ATTRIBUTE_NORMAL, // attributes & flags
  39. NULL // hTemplateFile
  40. );
  41. if (_hFile == INVALID_HANDLE_VALUE)
  42. {
  43. sc = HRESULT_FROM_WIN32(GetLastError());
  44. return;
  45. }
  46. // read the file into the memory block
  47. DWORD cbRead = 0;
  48. if (_fRead && ! ReadFile(_hFile,
  49. _pbData,
  50. _cbData,
  51. &cbRead,
  52. NULL))
  53. {
  54. sc = HRESULT_FROM_WIN32(GetLastError());
  55. return;
  56. }
  57. if (_fRead)
  58. {
  59. _cSize = _cbData;
  60. }
  61. sc = S_OK;
  62. }
  63. CStreamOnFile::~CStreamOnFile(void)
  64. {
  65. if (_hFile)
  66. {
  67. if (!_fRead)
  68. {
  69. // write the data to the file
  70. DWORD cbWritten = 0;
  71. if (!WriteFile(_hFile,
  72. _pbData,
  73. _cbData,
  74. &cbWritten,
  75. NULL))
  76. {
  77. SCODE sc = HRESULT_FROM_WIN32(GetLastError());
  78. }
  79. }
  80. CloseHandle(_hFile);
  81. }
  82. }
  83. STDMETHODIMP CStreamOnFile::QueryInterface(
  84. REFIID iidInterface,
  85. void FAR* FAR* ppvObj)
  86. {
  87. HRESULT hresult = S_OK;
  88. // We only support IUnknown and IStream
  89. if (IsEqualIID(iidInterface, IID_IUnknown) ||
  90. IsEqualIID(iidInterface, IID_IStream))
  91. {
  92. *ppvObj = this;
  93. AddRef();
  94. }
  95. else
  96. {
  97. *ppvObj = NULL;
  98. hresult = E_NOINTERFACE;
  99. }
  100. return hresult;
  101. }
  102. STDMETHODIMP_(ULONG) CStreamOnFile::AddRef(void)
  103. {
  104. InterlockedIncrement(&_clRefs);
  105. return _clRefs;
  106. }
  107. STDMETHODIMP_(ULONG) CStreamOnFile::Release(void)
  108. {
  109. if (InterlockedDecrement(&_clRefs) == 0)
  110. {
  111. delete this;
  112. return 0;
  113. }
  114. return _clRefs;
  115. }
  116. STDMETHODIMP CStreamOnFile::Read(
  117. VOID HUGEP* pv,
  118. ULONG cb,
  119. ULONG FAR* pcbRead)
  120. {
  121. HRESULT hresult = S_OK;
  122. if (pcbRead)
  123. {
  124. *pcbRead = 0L;
  125. }
  126. if ((LONG)cb + _lOffset > _cSize)
  127. {
  128. cb = _cSize - _lOffset;
  129. hresult = STG_E_READFAULT;
  130. }
  131. memcpy(pv, _pbData + _lOffset, (size_t) cb);
  132. _lOffset += cb;
  133. if (pcbRead != NULL)
  134. {
  135. *pcbRead = cb;
  136. }
  137. return hresult;
  138. }
  139. STDMETHODIMP CStreamOnFile::Write(
  140. VOID const HUGEP* pv,
  141. ULONG cbToWrite,
  142. ULONG FAR* pcbWritten)
  143. {
  144. HRESULT hresult = S_OK;
  145. if (pcbWritten)
  146. {
  147. *pcbWritten = 0L;
  148. }
  149. if (cbToWrite + _lOffset > _cbData)
  150. {
  151. return E_OUTOFMEMORY;
  152. }
  153. // copy in the new data
  154. memcpy(_pbData + _lOffset, pv, (size_t) cbToWrite);
  155. _lOffset += cbToWrite;
  156. if (pcbWritten != NULL)
  157. {
  158. *pcbWritten = cbToWrite;
  159. }
  160. // We assume maxium size of buffer is the size to send on the network.
  161. if (_cSize < _lOffset)
  162. {
  163. _cSize = _lOffset;
  164. }
  165. return hresult;
  166. }
  167. STDMETHODIMP CStreamOnFile::Seek(
  168. LARGE_INTEGER dlibMoveIN,
  169. DWORD dwOrigin,
  170. ULARGE_INTEGER FAR* plibNewPosition)
  171. {
  172. HRESULT hresult = S_OK;
  173. LONG dlibMove = dlibMoveIN.LowPart;
  174. ULONG cbNewPos = dlibMove;
  175. switch(dwOrigin)
  176. {
  177. case STREAM_SEEK_SET:
  178. if (dlibMove >= 0)
  179. {
  180. _lOffset = dlibMove;
  181. }
  182. else
  183. {
  184. hresult = STG_E_SEEKERROR;
  185. }
  186. break;
  187. case STREAM_SEEK_CUR:
  188. if (!(dlibMove < 0 && (-dlibMove > _lOffset)))
  189. {
  190. _lOffset += (ULONG) dlibMove;
  191. }
  192. else
  193. {
  194. hresult = STG_E_SEEKERROR;
  195. }
  196. break;
  197. case STREAM_SEEK_END:
  198. if (!(dlibMove < 0 && ((ULONG) -dlibMove) > _cbData))
  199. {
  200. _lOffset = _cbData + dlibMove;
  201. }
  202. else
  203. {
  204. hresult = STG_E_SEEKERROR;
  205. }
  206. break;
  207. default:
  208. hresult = STG_E_SEEKERROR;
  209. }
  210. if (plibNewPosition != NULL)
  211. {
  212. ULISet32(*plibNewPosition, _lOffset);
  213. }
  214. return hresult;
  215. }
  216. STDMETHODIMP CStreamOnFile::SetSize(ULARGE_INTEGER cb)
  217. {
  218. return E_NOTIMPL;
  219. }
  220. STDMETHODIMP CStreamOnFile::CopyTo(
  221. IStream FAR* pstm,
  222. ULARGE_INTEGER cb,
  223. ULARGE_INTEGER FAR* pcbRead,
  224. ULARGE_INTEGER FAR* pcbWritten)
  225. {
  226. return E_NOTIMPL;
  227. }
  228. STDMETHODIMP CStreamOnFile::Commit(DWORD grfCommitFlags)
  229. {
  230. return NOERROR;
  231. }
  232. STDMETHODIMP CStreamOnFile::Revert(void)
  233. {
  234. return NOERROR;
  235. }
  236. STDMETHODIMP CStreamOnFile::LockRegion(
  237. ULARGE_INTEGER libOffset,
  238. ULARGE_INTEGER cb,
  239. DWORD dwLockType)
  240. {
  241. return STG_E_INVALIDFUNCTION;
  242. }
  243. STDMETHODIMP CStreamOnFile::UnlockRegion(
  244. ULARGE_INTEGER libOffset,
  245. ULARGE_INTEGER cb,
  246. DWORD dwLockType)
  247. {
  248. return STG_E_INVALIDFUNCTION;
  249. }
  250. STDMETHODIMP CStreamOnFile::Stat(
  251. STATSTG FAR* pstatstg,
  252. DWORD statflag)
  253. {
  254. memset(pstatstg, 0, sizeof(STATSTG));
  255. return E_NOTIMPL;
  256. }
  257. STDMETHODIMP CStreamOnFile::Clone(IStream FAR * FAR *ppstm)
  258. {
  259. return E_NOTIMPL;
  260. }