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.

392 lines
12 KiB

  1. // =================================================================================
  2. // HFILE Stream Implementation
  3. // =================================================================================
  4. #include "pch.hxx"
  5. #include "hfilestm.h"
  6. #include "unicnvrt.h"
  7. #include "Error.h"
  8. #include <BadStrFunctions.h>
  9. extern HRESULT HrGetLastError(void);
  10. // =================================================================================
  11. // CreateStreamOnHFile
  12. // =================================================================================
  13. OESTDAPI_(HRESULT) CreateStreamOnHFile (LPTSTR lpszFile,
  14. DWORD dwDesiredAccess,
  15. DWORD dwShareMode,
  16. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  17. DWORD dwCreationDistribution,
  18. DWORD dwFlagsAndAttributes,
  19. HANDLE hTemplateFile,
  20. LPSTREAM *lppstmHFile)
  21. {
  22. HRESULT hr;
  23. LPWSTR pwszFile = PszToUnicode(CP_ACP, lpszFile);
  24. if (!pwszFile && lpszFile)
  25. return E_OUTOFMEMORY;
  26. hr = CreateStreamOnHFileW(pwszFile, dwDesiredAccess, dwShareMode,
  27. lpSecurityAttributes, dwCreationDistribution,
  28. dwFlagsAndAttributes, hTemplateFile, lppstmHFile);
  29. MemFree(pwszFile);
  30. return hr;
  31. }
  32. OESTDAPI_(HRESULT) CreateStreamOnHFileW(LPWSTR lpwszFile,
  33. DWORD dwDesiredAccess,
  34. DWORD dwShareMode,
  35. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  36. DWORD dwCreationDistribution,
  37. DWORD dwFlagsAndAttributes,
  38. HANDLE hTemplateFile,
  39. LPSTREAM *lppstmHFile)
  40. {
  41. // Locals
  42. HRESULT hr = S_OK;
  43. LPHFILESTM lpstmHFile = NULL;
  44. DWORD nBufferLength;
  45. HANDLE hFile = INVALID_HANDLE_VALUE;
  46. WCHAR wszFile[MAX_PATH],
  47. wszTempDir[MAX_PATH];
  48. // Check Params
  49. Assert (lppstmHFile);
  50. Assert (dwDesiredAccess & GENERIC_READ || dwDesiredAccess & GENERIC_WRITE);
  51. // Temp File ?
  52. if (lpwszFile == NULL)
  53. {
  54. // Get Temp Dir
  55. nBufferLength = AthGetTempPathW(ARRAYSIZE(wszTempDir), wszTempDir);
  56. if (nBufferLength == 0 || nBufferLength > ARRAYSIZE(wszTempDir))
  57. {
  58. hr = E_FAIL;
  59. goto exit;
  60. }
  61. // Get Temp File Name
  62. UINT uFile = AthGetTempFileNameW(wszTempDir, L"tmp", 0, wszFile);
  63. if (uFile == 0)
  64. {
  65. hr = E_FAIL;
  66. goto exit;
  67. }
  68. // Reset file name
  69. lpwszFile = wszFile;
  70. // Delete When Done
  71. dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
  72. // Always create a new temp file
  73. dwCreationDistribution = OPEN_EXISTING;
  74. }
  75. // Open the file
  76. hFile = AthCreateFileW(lpwszFile, dwDesiredAccess, dwShareMode,
  77. lpSecurityAttributes, dwCreationDistribution,
  78. dwFlagsAndAttributes, hTemplateFile);
  79. // Error
  80. if (hFile == INVALID_HANDLE_VALUE)
  81. {
  82. hr = hrCreateFile;
  83. return hr;
  84. }
  85. // Create Object
  86. lpstmHFile = new CHFileStm (hFile, dwDesiredAccess);
  87. if (lpstmHFile == NULL)
  88. {
  89. hr = hrMemory;
  90. goto exit;
  91. }
  92. exit:
  93. // Cleanup
  94. if (FAILED (hr))
  95. {
  96. if (hFile != INVALID_HANDLE_VALUE)
  97. CloseHandle_F16 (hFile);
  98. SafeRelease (lpstmHFile);
  99. }
  100. // Set return
  101. *lppstmHFile = (LPSTREAM)lpstmHFile;
  102. // Done
  103. return hr;
  104. }
  105. // =================================================================================
  106. // CHFileStm::Constructor
  107. // =================================================================================
  108. CHFileStm::CHFileStm (HANDLE hFile, DWORD dwDesiredAccess)
  109. {
  110. m_cRef = 1;
  111. m_hFile = hFile;
  112. m_dwDesiredAccess = dwDesiredAccess;
  113. }
  114. // =================================================================================
  115. // CHFileStm::Deconstructor
  116. // =================================================================================
  117. CHFileStm::~CHFileStm ()
  118. {
  119. if (m_hFile != INVALID_HANDLE_VALUE)
  120. {
  121. CloseHandle_F16 (m_hFile);
  122. }
  123. }
  124. // =================================================================================
  125. // CHFileStm::AddRef
  126. // =================================================================================
  127. ULONG CHFileStm::AddRef ()
  128. {
  129. ++m_cRef;
  130. return m_cRef;
  131. }
  132. // =================================================================================
  133. // CHFileStm::Release
  134. // =================================================================================
  135. ULONG CHFileStm::Release ()
  136. {
  137. ULONG ulCount = --m_cRef;
  138. if (!ulCount)
  139. delete this;
  140. return ulCount;
  141. }
  142. // =================================================================================
  143. // CHFileStm::QueryInterface
  144. // =================================================================================
  145. STDMETHODIMP CHFileStm::QueryInterface (REFIID iid, LPVOID* ppvObj)
  146. {
  147. if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IStream))
  148. {
  149. *ppvObj = this;
  150. AddRef();
  151. return(S_OK);
  152. }
  153. return E_NOINTERFACE;
  154. }
  155. // =================================================================================
  156. // CHFileStm::Read
  157. // =================================================================================
  158. STDMETHODIMP CHFileStm::Read (LPVOID lpv, ULONG cb, ULONG *pcbRead)
  159. {
  160. // Locals
  161. HRESULT hr = S_OK;
  162. BOOL fReturn;
  163. DWORD dwRead;
  164. // Check Params
  165. Assert (lpv);
  166. Assert (m_hFile != INVALID_HANDLE_VALUE);
  167. // Read some bytes from m_hFile
  168. fReturn = ReadFile (m_hFile, lpv, cb, &dwRead, NULL);
  169. if (!fReturn)
  170. {
  171. hr = HrGetLastError();
  172. AssertSz (FALSE, "CHFileStm::Read Failed, you might want to take a look at this."); hr = E_FAIL;
  173. goto exit;
  174. }
  175. // Write byte
  176. if (pcbRead)
  177. *pcbRead = dwRead;
  178. exit:
  179. // Done
  180. return hr;
  181. }
  182. // =================================================================================
  183. // CHFileStm::Write
  184. // =================================================================================
  185. STDMETHODIMP CHFileStm::Write (const void *lpv, ULONG cb, ULONG *pcbWritten)
  186. {
  187. // Locals
  188. HRESULT hr = S_OK;
  189. BOOL fReturn;
  190. DWORD dwWritten;
  191. // Check Params
  192. Assert (lpv);
  193. Assert (m_hFile != INVALID_HANDLE_VALUE);
  194. // Read some bytes from m_hFile
  195. fReturn = WriteFile (m_hFile, lpv, cb, &dwWritten, NULL);
  196. if (!fReturn)
  197. {
  198. AssertSz (FALSE, "CHFileStm::Write Failed, you might want to take a look at this.");
  199. hr = STG_E_MEDIUMFULL; //Bug #50704 (v-snatar) // changed from E_FAILE to propagate the error so that
  200. // OnPreviewUpdate( ) properly displays "Out Of Space" error message
  201. goto exit;
  202. }
  203. // Write byte
  204. if (pcbWritten)
  205. *pcbWritten = dwWritten;
  206. exit:
  207. // Done
  208. return hr;
  209. }
  210. // =================================================================================
  211. // CHFileStm::Seek
  212. // =================================================================================
  213. STDMETHODIMP CHFileStm::Seek (LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
  214. {
  215. // Locals
  216. HRESULT hr = S_OK;
  217. DWORD dwReturn;
  218. LONG LowPart; // Cast to signed, could be negative
  219. Assert (m_hFile != INVALID_HANDLE_VALUE);
  220. // Cast lowpart
  221. LowPart = (LONG)dlibMove.LowPart;
  222. IF_WIN32( Assert (dlibMove.HighPart == 0); )
  223. // Seek the file pointer
  224. switch (dwOrigin)
  225. {
  226. case STREAM_SEEK_SET:
  227. dwReturn = SetFilePointer (m_hFile, LowPart, NULL, FILE_BEGIN);
  228. break;
  229. case STREAM_SEEK_CUR:
  230. dwReturn = SetFilePointer (m_hFile, LowPart, NULL, FILE_CURRENT);
  231. break;
  232. case STREAM_SEEK_END:
  233. dwReturn = SetFilePointer (m_hFile, LowPart, NULL, FILE_END);
  234. break;
  235. default:
  236. dwReturn = 0xFFFFFFFF;
  237. }
  238. // Failure ?
  239. if (dwReturn == 0xFFFFFFFF)
  240. {
  241. AssertSz (FALSE, "CHFileStm::Seek Failed, you might want to take a look at this.");
  242. hr = E_FAIL;
  243. goto exit;
  244. }
  245. // Return Position
  246. if (plibNewPosition)
  247. {
  248. plibNewPosition->QuadPart = dwReturn;
  249. }
  250. exit:
  251. // Done
  252. return hr;
  253. }
  254. // =================================================================================
  255. // CHFileStm::Commit
  256. // =================================================================================
  257. STDMETHODIMP CHFileStm::Commit (DWORD grfCommitFlags)
  258. {
  259. // Locals
  260. HRESULT hr = S_OK;
  261. Assert (m_hFile != INVALID_HANDLE_VALUE);
  262. // Flush the buffers
  263. if (FlushFileBuffers (m_hFile) == FALSE)
  264. {
  265. AssertSz (FALSE, "FlushFileBuffers failed");
  266. hr = E_FAIL;
  267. goto exit;
  268. }
  269. exit:
  270. // Done
  271. return hr;
  272. }
  273. // =================================================================================
  274. // CHFileStm::SetSize
  275. // =================================================================================
  276. STDMETHODIMP CHFileStm::SetSize (ULARGE_INTEGER uli)
  277. {
  278. // Seek to dwSize
  279. if (SetFilePointer (m_hFile, uli.LowPart, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  280. {
  281. AssertSz (FALSE, "SetFilePointer failed");
  282. return E_FAIL;
  283. }
  284. // SetEndOfFile
  285. if (SetEndOfFile (m_hFile) == FALSE)
  286. {
  287. AssertSz (FALSE, "SetEndOfFile failed");
  288. return E_FAIL;
  289. }
  290. // Done
  291. return S_OK;
  292. }
  293. // =================================================================================
  294. // CHFileStm::CopyTo
  295. // =================================================================================
  296. STDMETHODIMP CHFileStm::CopyTo (LPSTREAM, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
  297. {
  298. return E_NOTIMPL;
  299. }
  300. // =================================================================================
  301. // CHFileStm::Revert
  302. // =================================================================================
  303. STDMETHODIMP CHFileStm::Revert ()
  304. {
  305. return E_NOTIMPL;
  306. }
  307. // =================================================================================
  308. // CHFileStm::LockRegion
  309. // =================================================================================
  310. STDMETHODIMP CHFileStm::LockRegion (ULARGE_INTEGER, ULARGE_INTEGER,DWORD)
  311. {
  312. return E_NOTIMPL;
  313. }
  314. // =================================================================================
  315. // CHFileStm::UnlockRegion
  316. // =================================================================================
  317. STDMETHODIMP CHFileStm::UnlockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
  318. {
  319. return E_NOTIMPL;
  320. }
  321. // =================================================================================
  322. // CHFileStm::Stat
  323. // =================================================================================
  324. STDMETHODIMP CHFileStm::Stat (STATSTG*, DWORD)
  325. {
  326. return E_NOTIMPL;
  327. }
  328. // =================================================================================
  329. // CHFileStm::Clone
  330. // =================================================================================
  331. STDMETHODIMP CHFileStm::Clone (LPSTREAM*)
  332. {
  333. return E_NOTIMPL;
  334. }