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.

634 lines
15 KiB

  1. //-------------------------------------------------------------------------
  2. //
  3. // Microsoft OLE
  4. // Copyright (C) Microsoft Corporation, 1994 - 1995.
  5. //
  6. // File: ilbfile.cxx
  7. //
  8. // Contents: Implementation of CFileBytes class methods - derived from
  9. // ILockBytes class.
  10. //
  11. // Derivation: ILockBytes
  12. //
  13. // Functions:
  14. //
  15. // History: 06-Nov-92 AlexT Created
  16. // 30-July-1996 NarindK Modified for stgbase tests.
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <dfheader.hxx>
  20. #pragma hdrstop
  21. #include "ilkbhdr.hxx"
  22. //-------------------------------------------------------------------------
  23. //
  24. // Member: CFileBytes::CFileBytes, public
  25. //
  26. // Synopsis: constructor
  27. //
  28. // Arguments: none
  29. //
  30. // Returns: none
  31. //
  32. // History: 30-July-96 Narindk Modified
  33. //
  34. // Notes: Returns a fully initialized CFileBytes (ref count == 1)
  35. //
  36. //--------------------------------------------------------------------------
  37. CFileBytes::CFileBytes(void):
  38. _hf(HFILE_ERROR),
  39. _ulRef(1),
  40. _cFail0(0),
  41. _cWrite0(0),
  42. _pszFileName(NULL)
  43. {
  44. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::CFileBytes"));
  45. }
  46. //-------------------------------------------------------------------------
  47. //
  48. // Member: CFileBytes::~CFileBytes, public
  49. //
  50. // Synopsis: Destructor
  51. //
  52. // Arguments: none
  53. //
  54. // Returns: none
  55. //
  56. // History: 30-July-96 Narindk Modified
  57. //
  58. // Notes:
  59. //
  60. //--------------------------------------------------------------------------
  61. CFileBytes::~CFileBytes(void)
  62. {
  63. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::~CFileBytes"));
  64. // Clean up
  65. if(NULL != _pszFileName)
  66. {
  67. delete _pszFileName;
  68. _pszFileName = NULL;
  69. }
  70. }
  71. //-------------------------------------------------------------------------
  72. //
  73. // Member: CFileBytes::Init, public
  74. //
  75. // Synopsis: Initialize function
  76. //
  77. // Arguments: [ptcPath] - Pointer to file name
  78. // [dwMode] - Mode to access/create file
  79. //
  80. // Returns: HRESULT
  81. //
  82. // History: 30-July-96 Narindk Modified
  83. //
  84. // Notes:
  85. //
  86. //--------------------------------------------------------------------------
  87. HRESULT CFileBytes::Init(TCHAR *ptcPath, DWORD dwMode)
  88. {
  89. HRESULT hr = S_OK;
  90. LPSTR pszFileName = NULL;
  91. int bufferSize = 0;
  92. OFSTRUCT of;
  93. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Init"));
  94. if(S_OK == hr)
  95. {
  96. _pszFileName = (CHAR *) new TCHAR[_tcslen(ptcPath) + 1 * sizeof(TCHAR)];
  97. if(NULL == _pszFileName)
  98. {
  99. hr = E_OUTOFMEMORY;
  100. }
  101. }
  102. // Copy ptcPath to _pszFileName. If NT, will need tp convert it to single
  103. // byte.
  104. if(S_OK == hr)
  105. {
  106. #if defined(_NT1X_) && !defined(_MAC)
  107. bufferSize = (_tcslen(ptcPath) + 1) * sizeof(TCHAR);
  108. if (0 == WideCharToMultiByte(
  109. CP_ACP,
  110. 0,
  111. ptcPath,
  112. -1,
  113. _pszFileName,
  114. bufferSize,
  115. NULL,
  116. NULL))
  117. {
  118. hr = HRESULT_FROM_WIN32(GetLastError());
  119. DH_HRCHECK(hr, TEXT("WideCharToMultiByte")) ;
  120. delete [] _pszFileName;
  121. _pszFileName = NULL;
  122. }
  123. #else
  124. _tcscpy(_pszFileName, ptcPath);
  125. #endif
  126. }
  127. if(S_OK == hr)
  128. {
  129. _hf = OpenFile(_pszFileName, &of, dwMode);
  130. if (HFILE_ERROR == _hf)
  131. {
  132. hr = E_FAIL;
  133. }
  134. }
  135. return hr;
  136. }
  137. //-------------------------------------------------------------------------
  138. //
  139. // Member: CFileBytes::FailWrite0, public
  140. //
  141. // Synopsis: Function to simulate Write failure
  142. //
  143. // Arguments: [cFail0] - failure value
  144. //
  145. // Returns: HRESULT
  146. //
  147. // History: 30-July-96 Narindk Modified
  148. //
  149. // Notes:
  150. //
  151. //-------------------------------------------------------------------------
  152. void CFileBytes::FailWrite0(int cFail0)
  153. {
  154. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::FailWrite0"));
  155. _cWrite0 = 0;
  156. _cFail0 = cFail0;
  157. }
  158. //+-------------------------------------------------------------------------
  159. //
  160. // Member: CFileBytes::QueryInterface, public
  161. //
  162. // Synopsis: Given a riid, returns associated interface
  163. //
  164. // Arguments: [riid] - interface id
  165. // [ppvObj] - place holder for interface
  166. //
  167. // Returns: Always fails
  168. //
  169. // History: 30-July-96 Narindk Modified
  170. //
  171. // Notes: Not used in tests
  172. //
  173. //--------------------------------------------------------------------------
  174. STDMETHODIMP CFileBytes::QueryInterface(
  175. REFIID /* UNREF riid */,
  176. LPVOID FAR *ppvObj)
  177. {
  178. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::QueryInterface"));
  179. *ppvObj = NULL;
  180. return STG_E_INVALIDFUNCTION;
  181. }
  182. //+-------------------------------------------------------------------------
  183. //
  184. // Member: CFileBytes::AddRef, public
  185. //
  186. // Synopsis: add reference
  187. //
  188. // Arguments: none
  189. //
  190. // Returns: ULONG post reference count
  191. //
  192. // History: 30-July-96 Narindk Modified
  193. //
  194. //--------------------------------------------------------------------------
  195. STDMETHODIMP_(ULONG) CFileBytes::AddRef(void)
  196. {
  197. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::AddRef"));
  198. _ulRef++;
  199. DH_TRACE(
  200. (DH_LVL_ADDREL,
  201. TEXT("AddRef - Object %lx, refs: %ld \n"),
  202. this, _ulRef));
  203. return _ulRef;
  204. }
  205. //+-------------------------------------------------------------------------
  206. //
  207. // Member: CFileBytes::Release, public
  208. //
  209. // Synopsis: release reference
  210. // closes file when reference count reaches zero
  211. //
  212. // Arguments: void
  213. //
  214. // Returns: ULONG post reference count
  215. //
  216. // History: 30-July-96 Narindk Modified
  217. //
  218. //--------------------------------------------------------------------------
  219. STDMETHODIMP_(ULONG) CFileBytes::Release(void)
  220. {
  221. ULONG ulTmp = 0;
  222. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::Release"));
  223. if ( _ulRef > 0 )
  224. {
  225. ulTmp = --_ulRef ;
  226. DH_TRACE(
  227. (DH_LVL_ADDREL,
  228. TEXT("Release - Object %lx, refs: %ld \n"),
  229. this, _ulRef));
  230. if (0 == _ulRef)
  231. {
  232. if (HFILE_ERROR != _hf)
  233. {
  234. _lclose(_hf);
  235. }
  236. DH_TRACE(
  237. (DH_LVL_ADDREL,
  238. TEXT("Release - Deleting Object %lx"), this));
  239. delete this;
  240. }
  241. }
  242. else
  243. {
  244. DH_ASSERT(!"Release() called on pointer with 0 refs!") ;
  245. ulTmp = 0 ;
  246. }
  247. return ulTmp;
  248. }
  249. //+-------------------------------------------------------------------------
  250. //
  251. // Member: CFileBytes::ReadAt
  252. //
  253. // Synopsis: Reads bytes from file
  254. //
  255. // Arguments: [ulOffset] - byte offset
  256. // [pv] - input buffer
  257. // [cb] - count of bytes to read
  258. // [pcbRead] - count of bytes read
  259. //
  260. // Returns: HRESULT
  261. //
  262. // History: 30-July-96 Narindk Modified
  263. //
  264. //--------------------------------------------------------------------------
  265. STDMETHODIMP CFileBytes::ReadAt(
  266. ULARGE_INTEGER uliOffset,
  267. VOID HUGEP *pv,
  268. ULONG cb,
  269. ULONG *pcbRead)
  270. {
  271. HRESULT hr = S_OK;
  272. LONG lOffset = 0;
  273. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::ReadAt"));
  274. DH_ASSERT(0 == ULIGetHigh(uliOffset));
  275. DH_ASSERT(HFILE_ERROR != _hf);
  276. if(S_OK == hr)
  277. {
  278. lOffset = (LONG) ULIGetLow(uliOffset);
  279. _llseek(_hf, lOffset, 0);
  280. *pcbRead = _hread(_hf, pv, cb);
  281. if (HFILE_ERROR == *pcbRead)
  282. {
  283. *pcbRead = 0;
  284. hr = STG_E_READFAULT;
  285. }
  286. }
  287. return hr;
  288. }
  289. //+-------------------------------------------------------------------------
  290. //
  291. // Member: CFileBytes::WriteAt, public
  292. //
  293. // Synopsis: Writes bytes to file
  294. //
  295. // Arguments: [uliOffset] - byte offset
  296. // [pv] - output buffer
  297. // [cb] - count of bytes to write
  298. // [pcbWritten] - count of bytes written
  299. //
  300. // Returns: HRESULT
  301. //
  302. // History: 30-July-96 Narindk Modified
  303. //
  304. // Notes: This implementation doesn't write partial buffers.
  305. //
  306. //--------------------------------------------------------------------------
  307. STDMETHODIMP CFileBytes::WriteAt(
  308. ULARGE_INTEGER uliOffset,
  309. VOID const HUGEP *pv,
  310. ULONG cb,
  311. ULONG FAR *pcbWritten)
  312. {
  313. HRESULT hr = S_OK;
  314. LONG lOffset = 0;
  315. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::WriteAt"));
  316. DH_ASSERT(0 == ULIGetHigh(uliOffset));
  317. DH_ASSERT(HFILE_ERROR != _hf);
  318. if(S_OK == hr)
  319. {
  320. lOffset = (LONG) ULIGetLow(uliOffset);
  321. if (0 == lOffset)
  322. {
  323. // Check for simulated write failures
  324. if (_cFail0 > 0)
  325. {
  326. _cWrite0++;
  327. if (_cWrite0 == _cFail0)
  328. {
  329. hr = STG_E_WRITEFAULT;
  330. }
  331. }
  332. }
  333. }
  334. if(S_OK == hr)
  335. {
  336. _llseek(_hf, lOffset, 0);
  337. *pcbWritten = _hwrite(_hf, (char *) pv, cb);
  338. if (HFILE_ERROR == *pcbWritten)
  339. {
  340. *pcbWritten = 0;
  341. hr = STG_E_WRITEFAULT;
  342. }
  343. }
  344. return hr;
  345. }
  346. //+-------------------------------------------------------------------------
  347. //
  348. // Member: CFileBytes::Flush, public
  349. //
  350. // Synopsis: flushes file; not implemented, always return S_OK
  351. //
  352. // Effects: none
  353. //
  354. // Returns: S_OK
  355. //
  356. // History: 30-July-96 Narindk Modified
  357. //
  358. //--------------------------------------------------------------------------
  359. STDMETHODIMP CFileBytes::Flush(void)
  360. {
  361. HRESULT hr = S_OK;
  362. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Flush"));
  363. DH_ASSERT(HFILE_ERROR != _hf);
  364. return hr;
  365. }
  366. //+-------------------------------------------------------------------------
  367. //
  368. // Member: CFileBytes::SetSize, public
  369. //
  370. // Synopsis: sets memory buffer size. May change buffer size
  371. //
  372. // Arguments: [ulicb] - new memory size
  373. //
  374. // Returns: HRESULT
  375. //
  376. // Algorithm: realloc the buffer
  377. //
  378. // History: 30-July-96 Narindk Modified
  379. //
  380. //--------------------------------------------------------------------------
  381. STDMETHODIMP CFileBytes::SetSize(ULARGE_INTEGER ulicb)
  382. {
  383. HRESULT hr = S_OK;
  384. BYTE ch = 0;
  385. ULONG cb = 0;
  386. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::SetSize"));
  387. DH_ASSERT(0 == ULIGetHigh(ulicb));
  388. DH_ASSERT(HFILE_ERROR != _hf);
  389. if(S_OK == hr)
  390. {
  391. cb = ULIGetLow(ulicb);
  392. _llseek(_hf, cb, 0);
  393. _hwrite(_hf, (char *) &ch, 0);
  394. }
  395. return hr;
  396. }
  397. //+-------------------------------------------------------------------------
  398. //
  399. // Member: CFileBytes::LockRegion, public
  400. //
  401. // Synopsis: not supported (intentionally)
  402. //
  403. // Arguments: [libOffset] - lock range offset
  404. // [cb] - lock range size
  405. // [dwLockType] - lock type
  406. //
  407. // Returns: STG_E_INVALIDFUNCTION
  408. //
  409. // History: 30-July-96 Narindk Modified
  410. //
  411. //--------------------------------------------------------------------------
  412. STDMETHODIMP CFileBytes::LockRegion(
  413. ULARGE_INTEGER /* UNREF libOffset */,
  414. ULARGE_INTEGER /* UNREF cb */,
  415. DWORD /* UNREF dwLockType */)
  416. {
  417. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::LockRegion"));
  418. DH_ASSERT(0 && !TEXT("Can't lock CFileBytes"));
  419. DH_ASSERT(HFILE_ERROR != _hf);
  420. return STG_E_INVALIDFUNCTION;
  421. }
  422. //+-------------------------------------------------------------------------
  423. //
  424. // Member: CFileBytes::UnLockRegion, public
  425. //
  426. // Synopsis: not supported (intentionally)
  427. //
  428. // Arguments: [libOffset] - lock range offset
  429. // [cb] - lock range size
  430. // [dwLockType] - lock type
  431. //
  432. // Returns: STG_E_INVALIDFUNCTION
  433. //
  434. // History: 30-July-96 Narindk Modified
  435. //
  436. //--------------------------------------------------------------------------
  437. STDMETHODIMP CFileBytes::UnlockRegion(
  438. ULARGE_INTEGER /* UNREF libOffset */,
  439. ULARGE_INTEGER /* cb */,
  440. DWORD /* dwLockType */)
  441. {
  442. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::UnlockRegion"));
  443. DH_ASSERT(0 && !TEXT("Can't Unlock CFileBytes"));
  444. DH_ASSERT(HFILE_ERROR != _hf);
  445. return STG_E_INVALIDFUNCTION;
  446. }
  447. //+-------------------------------------------------------------------------
  448. //
  449. // Member: CFileBytes::Stat, public
  450. //
  451. // Synopsis: Provide instance information
  452. //
  453. // Arguments: [pstatstg] - status buffer
  454. // [grfStatFlag] - status flags
  455. //
  456. // Returns: HRESULT
  457. //
  458. // History: 30-July-96 Narindk Modified
  459. //
  460. // Notes: No time stamps. Modifies pstatstg.
  461. //
  462. //--------------------------------------------------------------------------
  463. STDMETHODIMP CFileBytes::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag)
  464. {
  465. HRESULT hr = S_OK;
  466. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Stat"));
  467. DH_ASSERT(HFILE_ERROR != _hf);
  468. if(S_OK == hr)
  469. {
  470. memset(pstatstg, 0, sizeof(STATSTG));
  471. if (0 == (grfStatFlag & STATFLAG_NONAME))
  472. {
  473. // MakeUnicode String doesn't do any parameter validation, so use
  474. // it correctly.
  475. #ifdef _MAC
  476. _tcscpy(pstatstg->pwcsName, _pszFileName);
  477. #else
  478. hr = MakeUnicodeString(_pszFileName, &(pstatstg->pwcsName));
  479. #endif
  480. DH_HRCHECK(hr, TEXT("TStrToWstr")) ;
  481. if (NULL == pstatstg->pwcsName)
  482. {
  483. hr = E_OUTOFMEMORY;
  484. }
  485. }
  486. }
  487. if(S_OK == hr)
  488. {
  489. pstatstg->type = STGTY_LOCKBYTES;
  490. ULISet32(pstatstg->cbSize, _llseek(_hf, 0, 2));
  491. pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE;
  492. }
  493. return hr;
  494. }
  495. //-------------------------------------------------------------------------
  496. //
  497. // Member: CFileBytes::GetSize, public
  498. //
  499. // Synopsis: Function to return size
  500. //
  501. // Arguments: none
  502. //
  503. // Returns: ULARGE_INTEGER
  504. //
  505. // History: 30-July-96 Narindk Created
  506. //
  507. // Notes:
  508. //
  509. //-------------------------------------------------------------------------
  510. ULARGE_INTEGER CFileBytes::GetSize()
  511. {
  512. HRESULT hr = S_OK;
  513. ULARGE_INTEGER ulSize;
  514. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::GetSize"));
  515. DH_ASSERT(HFILE_ERROR != _hf);
  516. ulSize.LowPart = GetFileSize((HANDLE) _hf, &(ulSize.HighPart));
  517. if(0xFFFFFFFF == ulSize.LowPart)
  518. {
  519. hr = HRESULT_FROM_WIN32(GetLastError());
  520. DH_HRCHECK(hr, TEXT("GetFileSize")) ;
  521. }
  522. DH_ASSERT(0xFFFFFFFF != ulSize.LowPart);
  523. return ulSize;
  524. }
  525. //+-------------------------------------------------------------------------