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.

407 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. filestream.cpp
  5. Abstract:
  6. Implementation of IStream over a win32 file.
  7. Author:
  8. Michael J. Grier (MGrier) 23-Feb-2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "helpers.h"
  13. #include <windows.h>
  14. #define UNUSED(x)
  15. BOOL
  16. MySetFilePointerEx(
  17. HANDLE File, // handle to file
  18. LARGE_INTEGER DistanceToMove, // bytes to move pointer
  19. PLARGE_INTEGER NewFilePointer, // new file pointer
  20. DWORD MoveMethod // starting point
  21. )
  22. {
  23. LONG DistanceToMoveLow = static_cast<LONG>(DistanceToMove.LowPart);
  24. LONG DistanceToMoveHigh = DistanceToMove.HighPart;
  25. DWORD NewPositionLow = SetFilePointer(File, DistanceToMoveLow, &DistanceToMoveHigh, MoveMethod);
  26. if (NewPositionLow == INVALID_SET_FILE_POINTER)
  27. {
  28. if (GetLastError() != NO_ERROR)
  29. return FALSE;
  30. }
  31. if (NewFilePointer != NULL)
  32. {
  33. NewFilePointer->LowPart = NewPositionLow;
  34. NewFilePointer->HighPart = DistanceToMoveHigh;
  35. }
  36. return TRUE;
  37. }
  38. CFileStreamBase::~CFileStreamBase()
  39. {
  40. const DWORD dwLastError = ::GetLastError();
  41. Close();
  42. ::SetLastError(dwLastError);
  43. }
  44. bool
  45. CFileStreamBase::OpenForWrite(wstring pszPath)
  46. {
  47. if (m_hFile != INVALID_HANDLE_VALUE)
  48. return false;
  49. m_hFile = ::CreateFileW(
  50. pszPath.c_str(),
  51. GENERIC_WRITE,
  52. 0,
  53. NULL,
  54. CREATE_ALWAYS,
  55. FILE_ATTRIBUTE_NORMAL,
  56. NULL);
  57. return (m_hFile != INVALID_HANDLE_VALUE);
  58. }
  59. bool
  60. CFileStreamBase::OpenForRead(wstring pszPath)
  61. {
  62. if (m_hFile != INVALID_HANDLE_VALUE)
  63. return false;
  64. m_hFile = ::CreateFileW(
  65. pszPath.c_str(),
  66. GENERIC_READ,
  67. FILE_SHARE_READ,
  68. NULL,
  69. OPEN_EXISTING,
  70. FILE_ATTRIBUTE_NORMAL,
  71. NULL);
  72. return (m_hFile != INVALID_HANDLE_VALUE);
  73. }
  74. bool
  75. CFileStreamBase::Close()
  76. {
  77. if (m_hFile != INVALID_HANDLE_VALUE)
  78. {
  79. if (!::CloseHandle(m_hFile))
  80. {
  81. return false;
  82. }
  83. m_hFile = INVALID_HANDLE_VALUE;
  84. }
  85. return true;
  86. }
  87. ULONG
  88. CFileStreamBase::AddRef()
  89. {
  90. return ::InterlockedIncrement(&m_cRef);
  91. }
  92. ULONG
  93. CFileStreamBase::Release()
  94. {
  95. const ULONG ulRefCount = ::InterlockedDecrement(&m_cRef);
  96. if ( ulRefCount == 0 )
  97. {
  98. delete this;
  99. return 0;
  100. }
  101. else
  102. {
  103. return ulRefCount;
  104. }
  105. }
  106. HRESULT
  107. CFileStreamBase::QueryInterface(
  108. REFIID riid,
  109. PVOID *ppvObj
  110. )
  111. {
  112. HRESULT hr = NOERROR;
  113. IUnknown *pIUnknown = NULL;
  114. if (ppvObj != NULL)
  115. *ppvObj = NULL;
  116. if (ppvObj == NULL)
  117. {
  118. hr = E_POINTER;
  119. goto Exit;
  120. }
  121. if ((riid == IID_IUnknown) ||
  122. (riid == IID_ISequentialStream) ||
  123. (riid == IID_IStream))
  124. pIUnknown = static_cast<IStream *>(this);
  125. if (pIUnknown == NULL)
  126. {
  127. hr = E_NOINTERFACE;
  128. goto Exit;
  129. }
  130. pIUnknown->AddRef();
  131. *ppvObj = pIUnknown;
  132. hr = NOERROR;
  133. Exit:
  134. return hr;
  135. }
  136. HRESULT
  137. CFileStreamBase::Read(
  138. void *pv,
  139. ULONG cb,
  140. ULONG *pcbRead
  141. )
  142. {
  143. HRESULT hr = NOERROR;
  144. ULONG cbRead = 0;
  145. if (pcbRead != NULL)
  146. *pcbRead = 0;
  147. if (m_hFile == INVALID_HANDLE_VALUE)
  148. {
  149. hr = E_UNEXPECTED;
  150. goto Exit;
  151. }
  152. if (!m_bSeenFirstCharacter)
  153. {
  154. #ifdef AWFUL_SPACE_HACK
  155. while (true)
  156. {
  157. CHAR ch;
  158. ReadFile(m_hFile, &ch, 1, &cbRead, NULL);
  159. if ((ch != '\n') && (ch != '\r') && (ch != ' ') && (ch != '\t')) {
  160. m_bSeenFirstCharacter = true;
  161. LARGE_INTEGER li;
  162. li.QuadPart = -1;
  163. ::MySetFilePointerEx(m_hFile, li, NULL, FILE_CURRENT);
  164. break;
  165. }
  166. }
  167. #endif
  168. }
  169. if (!::ReadFile(m_hFile, pv, cb, &cbRead, NULL))
  170. {
  171. hr = HRESULT_FROM_WIN32(::GetLastError());
  172. goto Exit;
  173. }
  174. if (cbRead == 0)
  175. hr = S_FALSE;
  176. else
  177. hr = NOERROR;
  178. if (pcbRead != NULL)
  179. *pcbRead = cbRead;
  180. Exit:
  181. return hr;
  182. }
  183. HRESULT
  184. CFileStreamBase::Write(
  185. void const *pv,
  186. ULONG cb,
  187. ULONG *pcbWritten
  188. )
  189. {
  190. HRESULT hr = NOERROR;
  191. ULONG cbWritten = 0;
  192. if (pcbWritten != NULL)
  193. *pcbWritten = 0;
  194. if (m_hFile == INVALID_HANDLE_VALUE)
  195. {
  196. hr = E_UNEXPECTED;
  197. goto Exit;
  198. }
  199. if (!::WriteFile(m_hFile, pv, cb, &cbWritten, NULL))
  200. {
  201. hr = HRESULT_FROM_WIN32(::GetLastError());
  202. goto Exit;
  203. }
  204. if (cbWritten == 0)
  205. hr = S_FALSE;
  206. else
  207. hr = NOERROR;
  208. if (pcbWritten != NULL)
  209. *pcbWritten = cbWritten;
  210. Exit:
  211. return hr;
  212. }
  213. HRESULT
  214. CFileStreamBase::Seek(
  215. LARGE_INTEGER dlibMove,
  216. DWORD dwOrigin,
  217. ULARGE_INTEGER *plibNewPosition
  218. )
  219. {
  220. HRESULT hr = NOERROR;
  221. DWORD dwWin32Origin = 0;
  222. if (m_hFile == INVALID_HANDLE_VALUE)
  223. {
  224. hr = E_UNEXPECTED;
  225. goto Exit;
  226. }
  227. switch (dwOrigin)
  228. {
  229. default:
  230. hr = E_INVALIDARG;
  231. goto Exit;
  232. case STREAM_SEEK_SET:
  233. dwWin32Origin = FILE_BEGIN;
  234. break;
  235. case STREAM_SEEK_CUR:
  236. dwWin32Origin = FILE_CURRENT;
  237. break;
  238. case STREAM_SEEK_END:
  239. dwWin32Origin = FILE_END;
  240. break;
  241. }
  242. if (!::MySetFilePointerEx(
  243. m_hFile,
  244. dlibMove,
  245. (LARGE_INTEGER *) plibNewPosition,
  246. dwWin32Origin))
  247. {
  248. hr = HRESULT_FROM_WIN32(::GetLastError());
  249. goto Exit;
  250. }
  251. hr = NOERROR;
  252. Exit:
  253. return hr;
  254. }
  255. HRESULT
  256. CFileStreamBase::SetSize(
  257. ULARGE_INTEGER libNewSize
  258. )
  259. {
  260. UNUSED(libNewSize);
  261. return E_NOTIMPL;
  262. }
  263. HRESULT
  264. CFileStreamBase::CopyTo(
  265. IStream *pstm,
  266. ULARGE_INTEGER cb,
  267. ULARGE_INTEGER *pcbRead,
  268. ULARGE_INTEGER *pcbWritten
  269. )
  270. {
  271. if (pcbRead != NULL)
  272. pcbRead->QuadPart = 0;
  273. if (pcbWritten != NULL)
  274. pcbWritten->QuadPart = 0;
  275. return E_NOTIMPL;
  276. }
  277. HRESULT
  278. CFileStreamBase::Commit(
  279. DWORD grfCommitFlags
  280. )
  281. {
  282. HRESULT hr = NOERROR;
  283. if (grfCommitFlags != 0)
  284. return E_INVALIDARG;
  285. if (!Close())
  286. hr = HRESULT_FROM_WIN32 (GetLastError());
  287. return hr;
  288. }
  289. HRESULT
  290. CFileStreamBase::Revert()
  291. {
  292. return E_NOTIMPL;
  293. }
  294. HRESULT
  295. CFileStreamBase::LockRegion(
  296. ULARGE_INTEGER libOffset,
  297. ULARGE_INTEGER cb,
  298. DWORD dwLockType
  299. )
  300. {
  301. UNUSED(libOffset);
  302. UNUSED(cb);
  303. UNUSED(dwLockType);
  304. return E_NOTIMPL;
  305. }
  306. HRESULT
  307. CFileStreamBase::UnlockRegion(
  308. ULARGE_INTEGER libOffset,
  309. ULARGE_INTEGER cb,
  310. DWORD dwLockType
  311. )
  312. {
  313. UNUSED(libOffset);
  314. UNUSED(cb);
  315. UNUSED(dwLockType);
  316. return E_NOTIMPL;
  317. }
  318. HRESULT
  319. CFileStreamBase::Stat(
  320. STATSTG *pstatstg,
  321. DWORD grfStatFlag
  322. )
  323. {
  324. if (pstatstg != NULL)
  325. memset(pstatstg, 0, sizeof(*pstatstg));
  326. return E_NOTIMPL;
  327. }
  328. HRESULT
  329. CFileStreamBase::Clone(
  330. IStream **ppIStream
  331. )
  332. {
  333. if (ppIStream != NULL)
  334. *ppIStream = NULL;
  335. return E_NOTIMPL;
  336. }