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.

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