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.

701 lines
17 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: filllkb.cxx
  7. //
  8. // Contents: IFillLockBytes and ILockBytes wrapper for async docfiles
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 19-Dec-95 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "astghead.cxx"
  18. #pragma hdrstop
  19. #include "filllkb.hxx"
  20. #include <valid.h>
  21. #include "filelkb.hxx"
  22. #define ULIGetLow(x) x.LowPart
  23. #define UNTERMINATED 0
  24. #define TERMINATED_NORMAL 1
  25. #define TERMINATED_ABNORMAL 2
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Member: CFillLockBytes::CFillLockBytes, public
  29. //
  30. // Synopsis: Default constructor
  31. //
  32. // History: 28-Dec-95 PhilipLa Created
  33. //
  34. //----------------------------------------------------------------------------
  35. CFillLockBytes::CFillLockBytes(ILockBytes *pilb)
  36. {
  37. _pilb = pilb;
  38. _ulHighWater = 0;
  39. _ulFailurePoint = 0;
  40. _dwTerminate = UNTERMINATED;
  41. _hNotifyEvent = INVALID_HANDLE_VALUE;
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Member: CFillLockBytes::~CFillLockBytes, public
  46. //
  47. // Synopsis: Destructor
  48. //
  49. // History: 28-Dec-95 PhilipLa Created
  50. //
  51. //----------------------------------------------------------------------------
  52. CFillLockBytes::~CFillLockBytes()
  53. {
  54. astgAssert(_pilb == NULL);
  55. if (_hNotifyEvent != INVALID_HANDLE_VALUE)
  56. {
  57. CloseHandle(_hNotifyEvent);
  58. }
  59. }
  60. //+---------------------------------------------------------------------------
  61. //
  62. // Member: CFillLockBytes::Init, public
  63. //
  64. // Synopsis:
  65. //
  66. // Arguments:
  67. //
  68. // Returns: Appropriate status code
  69. //
  70. // Modifies:
  71. //
  72. // History: 11-Jan-96 PhilipLa Created
  73. //
  74. // Notes:
  75. //
  76. //----------------------------------------------------------------------------
  77. SCODE CFillLockBytes::Init(void)
  78. {
  79. SCODE sc;
  80. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Init:%p()\n", this));
  81. _hNotifyEvent = CreateEvent(NULL,
  82. TRUE,
  83. FALSE,
  84. NULL);
  85. if (_hNotifyEvent == NULL)
  86. {
  87. return Win32ErrorToScode(GetLastError());
  88. }
  89. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Init\n"));
  90. return S_OK;
  91. }
  92. //+--------------------------------------------------------------
  93. //
  94. // Member: CFillLockBytes::QueryInterface, public
  95. //
  96. // Synopsis: Returns an object for the requested interface
  97. //
  98. // Arguments: [iid] - Interface ID
  99. // [ppvObj] - Object return
  100. //
  101. // Returns: Appropriate status code
  102. //
  103. // Modifies: [ppvObj]
  104. //
  105. // History: 26-Mar-92 DrewB Created
  106. //
  107. //---------------------------------------------------------------
  108. //BUGBUG: Delegate to wrapped ILockBytes? Probably not.
  109. STDMETHODIMP CFillLockBytes::QueryInterface(REFIID iid, void **ppvObj)
  110. {
  111. SCODE sc;
  112. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::QueryInterface(?, %p)\n",
  113. ppvObj));
  114. astgChk(ValidateOutPtrBuffer(ppvObj));
  115. *ppvObj = NULL;
  116. sc = S_OK;
  117. if (IsEqualIID(iid, IID_IUnknown))
  118. {
  119. *ppvObj = (ILockBytes *)this;
  120. CFillLockBytes::AddRef();
  121. }
  122. else if (IsEqualIID(iid, IID_ILockBytes))
  123. {
  124. *ppvObj = (ILockBytes *)this;
  125. CFillLockBytes::AddRef();
  126. }
  127. else if (IsEqualIID(iid, IID_IFillLockBytes))
  128. {
  129. *ppvObj = (IFillLockBytes *)this;
  130. CFillLockBytes::AddRef();
  131. }
  132. else
  133. {
  134. sc = E_NOINTERFACE;
  135. }
  136. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::QueryInterface => %p\n",
  137. ppvObj));
  138. Err:
  139. return ResultFromScode(sc);
  140. }
  141. //+--------------------------------------------------------------
  142. //
  143. // Member: CFillLockBytes::AddRef, public
  144. //
  145. // Synopsis: Increments the ref count
  146. //
  147. // Returns: Appropriate status code
  148. //
  149. // History: 16-Mar-92 DrewB Created
  150. //
  151. //---------------------------------------------------------------
  152. STDMETHODIMP_(ULONG) CFillLockBytes::AddRef(void)
  153. {
  154. return _pilb->AddRef();
  155. }
  156. //+---------------------------------------------------------------------------
  157. //
  158. // Member: CFillLockBytes::Release, public
  159. //
  160. // History: 28-Dec-95 PhilipLa Created
  161. //
  162. //----------------------------------------------------------------------------
  163. STDMETHODIMP_(ULONG) CFillLockBytes::Release(void)
  164. {
  165. LONG lRet;
  166. lRet = _pilb->Release();
  167. if (lRet == 0)
  168. {
  169. _pilb = NULL;
  170. delete this;
  171. }
  172. return lRet;
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // Member: CFillLockBytes::ReadAt, public
  177. //
  178. // Synopsis:
  179. //
  180. // Arguments:
  181. //
  182. // Returns: Appropriate status code
  183. //
  184. // Modifies:
  185. //
  186. // History: 28-Dec-95 PhilipLa Created
  187. //
  188. // Notes:
  189. //
  190. //----------------------------------------------------------------------------
  191. STDMETHODIMP CFillLockBytes::ReadAt(ULARGE_INTEGER ulOffset,
  192. VOID HUGEP *pv,
  193. ULONG cb,
  194. ULONG *pcbRead)
  195. {
  196. SCODE sc;
  197. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::ReadAt:%p()\n", this));
  198. if (_dwTerminate == TERMINATED_ABNORMAL)
  199. {
  200. sc = STG_E_INCOMPLETE;
  201. }
  202. else if ((_dwTerminate == TERMINATED_NORMAL) ||
  203. (ULIGetLow(ulOffset) + cb <= _ulHighWater))
  204. {
  205. sc = _pilb->ReadAt(ulOffset, pv, cb, pcbRead);
  206. }
  207. else
  208. {
  209. *pcbRead = 0;
  210. _ulFailurePoint = cb + ULIGetLow(ulOffset);
  211. sc = STG_E_PENDING;
  212. }
  213. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::ReadAt\n"));
  214. return sc;
  215. }
  216. //+---------------------------------------------------------------------------
  217. //
  218. // Member: CFillLockBytes::WriteAt, public
  219. //
  220. // Synopsis:
  221. //
  222. // Arguments:
  223. //
  224. // Returns: Appropriate status code
  225. //
  226. // Modifies:
  227. //
  228. // History: 28-Dec-95 PhilipLa Created
  229. //
  230. // Notes:
  231. //
  232. //----------------------------------------------------------------------------
  233. STDMETHODIMP CFillLockBytes::WriteAt(ULARGE_INTEGER ulOffset,
  234. VOID const HUGEP *pv,
  235. ULONG cb,
  236. ULONG *pcbWritten)
  237. {
  238. SCODE sc;
  239. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::WriteAt:%p()\n", this));
  240. if (_dwTerminate == TERMINATED_ABNORMAL)
  241. {
  242. sc = STG_E_INCOMPLETE;
  243. }
  244. else if ((_dwTerminate == TERMINATED_NORMAL) ||
  245. (ULIGetLow(ulOffset) + cb <= _ulHighWater))
  246. {
  247. sc = _pilb->WriteAt(ulOffset, pv, cb, pcbWritten);
  248. }
  249. else
  250. {
  251. *pcbWritten = 0;
  252. _ulFailurePoint = cb + ULIGetLow(ulOffset);
  253. sc = STG_E_PENDING;
  254. }
  255. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::WriteAt\n"));
  256. return sc;
  257. }
  258. //+---------------------------------------------------------------------------
  259. //
  260. // Member: CFillLockBytes::Flush, public
  261. //
  262. // Synopsis:
  263. //
  264. // Arguments:
  265. //
  266. // Returns: Appropriate status code
  267. //
  268. // Modifies:
  269. //
  270. // History: 28-Dec-95 PhilipLa Created
  271. //
  272. // Notes:
  273. //
  274. //----------------------------------------------------------------------------
  275. STDMETHODIMP CFillLockBytes::Flush(void)
  276. {
  277. SCODE sc;
  278. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Flush:%p()\n", this));
  279. sc = _pilb->Flush();
  280. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Flush\n"));
  281. return sc;
  282. }
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Member: CFillLockBytes::SetSize, public
  286. //
  287. // Synopsis:
  288. //
  289. // Arguments:
  290. //
  291. // Returns: Appropriate status code
  292. //
  293. // Modifies:
  294. //
  295. // History: 28-Dec-95 PhilipLa Created
  296. //
  297. // Notes:
  298. //
  299. //----------------------------------------------------------------------------
  300. STDMETHODIMP CFillLockBytes::SetSize(ULARGE_INTEGER cb)
  301. {
  302. SCODE sc;
  303. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::SetSize:%p()\n", this));
  304. if (_dwTerminate == TERMINATED_ABNORMAL)
  305. {
  306. sc = STG_E_INCOMPLETE;
  307. }
  308. else if ((_dwTerminate == TERMINATED_NORMAL) ||
  309. (ULIGetLow(cb) <= _ulHighWater))
  310. {
  311. sc = _pilb->SetSize(cb);
  312. }
  313. else
  314. {
  315. _ulFailurePoint = ULIGetLow(cb);
  316. sc = STG_E_PENDING;
  317. }
  318. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::SetSize\n"));
  319. return sc;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Member: CFillLockBytes::LockRegion, public
  324. //
  325. // Synopsis:
  326. //
  327. // Arguments:
  328. //
  329. // Returns: Appropriate status code
  330. //
  331. // Modifies:
  332. //
  333. // History: 28-Dec-95 PhilipLa Created
  334. //
  335. // Notes:
  336. //
  337. //----------------------------------------------------------------------------
  338. STDMETHODIMP CFillLockBytes::LockRegion(ULARGE_INTEGER libOffset,
  339. ULARGE_INTEGER cb,
  340. DWORD dwLockType)
  341. {
  342. SCODE sc;
  343. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::LockRegion:%p()\n", this));
  344. if (_dwTerminate == TERMINATED_ABNORMAL)
  345. {
  346. sc = STG_E_INCOMPLETE;
  347. }
  348. else
  349. {
  350. sc = _pilb->LockRegion(libOffset, cb, dwLockType);
  351. }
  352. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::LockRegion\n"));
  353. return sc;
  354. }
  355. //+---------------------------------------------------------------------------
  356. //
  357. // Member: CFillLockBytes::UnlockRegion, public
  358. //
  359. // Synopsis:
  360. //
  361. // Arguments:
  362. //
  363. // Returns: Appropriate status code
  364. //
  365. // Modifies:
  366. //
  367. // History: 28-Dec-95 PhilipLa Created
  368. //
  369. // Notes:
  370. //
  371. //----------------------------------------------------------------------------
  372. STDMETHODIMP CFillLockBytes::UnlockRegion(ULARGE_INTEGER libOffset,
  373. ULARGE_INTEGER cb,
  374. DWORD dwLockType)
  375. {
  376. SCODE sc;
  377. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::UnlockRegion:%p()\n", this));
  378. if (_dwTerminate == TERMINATED_ABNORMAL)
  379. {
  380. sc = STG_E_INCOMPLETE;
  381. }
  382. else
  383. {
  384. sc = _pilb->UnlockRegion(libOffset, cb, dwLockType);
  385. }
  386. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::UnlockRegion\n"));
  387. return sc;
  388. }
  389. //+---------------------------------------------------------------------------
  390. //
  391. // Member: CFillLockBytes::Stat, public
  392. //
  393. // Synopsis:
  394. //
  395. // Arguments:
  396. //
  397. // Returns: Appropriate status code
  398. //
  399. // Modifies:
  400. //
  401. // History: 28-Dec-95 PhilipLa Created
  402. //
  403. // Notes:
  404. //
  405. //----------------------------------------------------------------------------
  406. STDMETHODIMP CFillLockBytes::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
  407. {
  408. SCODE sc;
  409. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Stat:%p()\n", this));
  410. if (_dwTerminate == TERMINATED_ABNORMAL)
  411. {
  412. sc = STG_E_INCOMPLETE;
  413. }
  414. else
  415. {
  416. sc = _pilb->Stat(pstatstg, grfStatFlag);
  417. //BUGBUG: Do we need any post-processing here?
  418. }
  419. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Stat\n"));
  420. return sc;
  421. }
  422. //+---------------------------------------------------------------------------
  423. //
  424. // Member: CFillLockBytes::FillAppend, public
  425. //
  426. // Synopsis:
  427. //
  428. // Arguments:
  429. //
  430. // Returns: Appropriate status code
  431. //
  432. // Modifies:
  433. //
  434. // History: 28-Dec-95 PhilipLa Created
  435. //
  436. // Notes:
  437. //
  438. //----------------------------------------------------------------------------
  439. STDMETHODIMP CFillLockBytes::FillAppend(void const *pv,
  440. ULONG cb,
  441. ULONG *pcbWritten)
  442. {
  443. SCODE sc;
  444. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::FillAppend:%p()\n", this));
  445. if (_dwTerminate != UNTERMINATED)
  446. {
  447. sc = STG_E_TERMINATED;
  448. }
  449. else
  450. {
  451. ULONG cbWritten;
  452. ULARGE_INTEGER uli;
  453. uli.QuadPart = _ulHighWater;
  454. sc = _pilb->WriteAt(uli, pv, cb, &cbWritten);
  455. _ulHighWater += cbWritten;
  456. if (pcbWritten != NULL)
  457. {
  458. *pcbWritten = cbWritten;
  459. }
  460. if (!PulseEvent(_hNotifyEvent))
  461. {
  462. sc = Win32ErrorToScode(GetLastError());
  463. }
  464. }
  465. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::FillAppend\n"));
  466. return sc;
  467. }
  468. //+---------------------------------------------------------------------------
  469. //
  470. // Member: CFillLockBytes::FillAt, public
  471. //
  472. // Synopsis:
  473. //
  474. // Arguments:
  475. //
  476. // Returns: Appropriate status code
  477. //
  478. // Modifies:
  479. //
  480. // History: 28-Dec-95 PhilipLa Created
  481. //
  482. // Notes:
  483. //
  484. //----------------------------------------------------------------------------
  485. STDMETHODIMP CFillLockBytes::FillAt(ULARGE_INTEGER ulOffset,
  486. void const *pv,
  487. ULONG cb,
  488. ULONG *pcbWritten)
  489. {
  490. //BUGBUG: Implement
  491. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::FillAt:%p()\n", this));
  492. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::FillAt\n"));
  493. return STG_E_UNIMPLEMENTEDFUNCTION;
  494. }
  495. //+---------------------------------------------------------------------------
  496. //
  497. // Member: CFillLockBytes::SetFillSize, public
  498. //
  499. // Synopsis:
  500. //
  501. // Arguments:
  502. //
  503. // Returns: Appropriate status code
  504. //
  505. // Modifies:
  506. //
  507. // History: 28-Dec-95 PhilipLa Created
  508. //
  509. // Notes:
  510. //
  511. //----------------------------------------------------------------------------
  512. STDMETHODIMP CFillLockBytes::SetFillSize(ULARGE_INTEGER ulSize)
  513. {
  514. SCODE sc;
  515. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::SetFillSize:%p()\n", this));
  516. if (_dwTerminate == TERMINATED_ABNORMAL)
  517. {
  518. sc = STG_E_INCOMPLETE;
  519. }
  520. else
  521. {
  522. sc = _pilb->SetSize(ulSize);
  523. }
  524. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::SetFillSize\n"));
  525. return sc;
  526. }
  527. //+---------------------------------------------------------------------------
  528. //
  529. // Member: CFillLockBytes::Terminate, public
  530. //
  531. // Synopsis:
  532. //
  533. // Arguments:
  534. //
  535. // Returns: Appropriate status code
  536. //
  537. // Modifies:
  538. //
  539. // History: 28-Dec-95 PhilipLa Created
  540. //
  541. // Notes:
  542. //
  543. //----------------------------------------------------------------------------
  544. STDMETHODIMP CFillLockBytes::Terminate(BOOL bCanceled)
  545. {
  546. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Terminate:%p()\n", this));
  547. _dwTerminate = (bCanceled) ? TERMINATED_ABNORMAL : TERMINATED_NORMAL;
  548. if (!SetEvent(_hNotifyEvent))
  549. {
  550. return Win32ErrorToScode(GetLastError());
  551. }
  552. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Terminate\n"));
  553. return S_OK;
  554. }
  555. //+---------------------------------------------------------------------------
  556. //
  557. // Member: CFillLockBytes::GetFailureInfo, public
  558. //
  559. // Synopsis:
  560. //
  561. // Arguments:
  562. //
  563. // Returns: Appropriate status code
  564. //
  565. // Modifies:
  566. //
  567. // History: 11-Jan-96 PhilipLa Created
  568. //
  569. // Notes:
  570. //
  571. //----------------------------------------------------------------------------
  572. SCODE CFillLockBytes::GetFailureInfo(ULONG *pulWaterMark,
  573. ULONG *pulFailurePoint)
  574. {
  575. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetFailureInfo:%p()\n", this));
  576. *pulWaterMark = _ulHighWater;
  577. *pulFailurePoint = _ulFailurePoint;
  578. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetFailureInfo\n"));
  579. return S_OK;
  580. }
  581. //+---------------------------------------------------------------------------
  582. //
  583. // Member: CFillLockBytes::GetNotificationEvent, public
  584. //
  585. // Synopsis:
  586. //
  587. // Arguments:
  588. //
  589. // Returns: Appropriate status code
  590. //
  591. // Modifies:
  592. //
  593. // History: 11-Jan-96 PhilipLa Created
  594. //
  595. // Notes:
  596. //
  597. //----------------------------------------------------------------------------
  598. HANDLE CFillLockBytes::GetNotificationEvent(void)
  599. {
  600. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetNotificationEvent:%p()\n", this));
  601. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetNotificationEvent\n"));
  602. return _hNotifyEvent;
  603. }
  604. //+---------------------------------------------------------------------------
  605. //
  606. // Member: CFillLockBytes::GetTerminationStatus, public
  607. //
  608. // Synopsis:
  609. //
  610. // Arguments:
  611. //
  612. // Returns: Appropriate status code
  613. //
  614. // Modifies:
  615. //
  616. // History: 11-Jan-96 PhilipLa Created
  617. //
  618. // Notes:
  619. //
  620. //----------------------------------------------------------------------------
  621. SCODE CFillLockBytes::GetTerminationStatus(DWORD *pdwFlags)
  622. {
  623. astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetTerminationStatus:%p()\n", this));
  624. *pdwFlags = _dwTerminate;
  625. astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetTerminationStatus\n"));
  626. return S_OK;
  627. }