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.

1188 lines
37 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft OLE
  3. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  4. // All rights reserved.
  5. //
  6. // File: vsnode.cxx
  7. //
  8. // Contents: Implementation for in-memory Virtual Stream Node class.
  9. //
  10. // Classes: VirtualStmNode (vsn)
  11. //
  12. // Functions: VirtualStmNode()
  13. // ~VirtualStmNode
  14. // Init
  15. // AppendSisterStm
  16. // Create
  17. // Read
  18. // Write
  19. // Open
  20. // Close
  21. // Seek
  22. // SetSize
  23. // Commit
  24. // Revert
  25. // Stat
  26. // CopyTo
  27. // AddRefCount
  28. // QueryInterface
  29. // LockRegion
  30. // UnlockRegion
  31. // Clone
  32. // Rename
  33. // Destroy
  34. //
  35. // NOTE: All above functions are public
  36. //
  37. // History: DeanE 21-Mar-96 Created
  38. // Narindk 24-Apr-96 Added more functions.
  39. // georgis 02-Apr-98 UpdateCRC
  40. //--------------------------------------------------------------------------
  41. #include <dfheader.hxx>
  42. #pragma hdrstop
  43. // Debug object declaration
  44. DH_DECLARE;
  45. //+--------------------------------------------------------------------------
  46. // Member: VirtualStmNode::VirtualStmNode, public
  47. //
  48. // Synopsis: Constructor. No work done here and this method cannot
  49. // fail. See ::Init method for real initialization work.
  50. //
  51. // Arguments: None.
  52. //
  53. // Returns: Nothing.
  54. //
  55. // History: DeanE 21-Mar-96 Created
  56. //---------------------------------------------------------------------------
  57. VirtualStmNode::VirtualStmNode() : _ptszName(NULL),
  58. _cb(0),
  59. _pvsnSister(NULL),
  60. _pvcnParent(NULL),
  61. _pstm(NULL)
  62. {
  63. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::VirtualStmNode"));
  64. _dwCRC.dwCRCName = CRC_PRECONDITION;
  65. _dwCRC.dwCRCData = CRC_PRECONDITION;
  66. _dwCRC.dwCRCSum = CRC_PRECONDITION;
  67. }
  68. //+--------------------------------------------------------------------------
  69. // Member: VirtualStmNode::~VirtualStmNode, public
  70. //
  71. // Synopsis: Destructor. Frees resources associated with this object,
  72. // including closing the storage if open and removing this
  73. // tree from memory.
  74. //
  75. // Arguments: None.
  76. //
  77. // Returns: Nothing.
  78. //
  79. // History: DeanE 21-Mar-96 Created
  80. //---------------------------------------------------------------------------
  81. VirtualStmNode::~VirtualStmNode()
  82. {
  83. ULONG ulRef = 0;
  84. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::~VirtualStmNode"));
  85. if(NULL != _ptszName)
  86. {
  87. delete _ptszName;
  88. _ptszName = NULL;
  89. }
  90. if ( NULL != _pstm )
  91. {
  92. ulRef = _pstm->Release();
  93. // Object is being destructed, assert if reference count is non zero.
  94. DH_ASSERT(0 == ulRef);
  95. _pstm = NULL;
  96. }
  97. }
  98. //+--------------------------------------------------------------------------
  99. // Member: VirtualStmNode::Init, public
  100. //
  101. // Synopsis: Initializes a stream node - does not open or create the
  102. // actual stream.
  103. //
  104. // Arguments: [tszName] - Name of this stream
  105. // [cb] - Size of this stream
  106. //
  107. // Returns: S_OK if node initialized successfully, otherwise an error.
  108. //
  109. // History: DeanE 21-Mar-96 Created
  110. // Narindk 24-Apr-96 Enhanced
  111. //---------------------------------------------------------------------------
  112. HRESULT VirtualStmNode::Init( LPTSTR tszName, ULONG cb)
  113. {
  114. HRESULT hr = S_OK;
  115. DH_VDATESTRINGPTR(tszName);
  116. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Init"));
  117. DH_ASSERT(NULL != tszName);
  118. if(S_OK == hr)
  119. {
  120. _ptszName = new TCHAR[_tcslen(tszName)+1];
  121. if (_ptszName == NULL)
  122. {
  123. hr = E_OUTOFMEMORY;
  124. }
  125. else
  126. {
  127. _tcscpy(_ptszName, tszName);
  128. _cb = cb;
  129. }
  130. }
  131. return(hr);
  132. }
  133. //+--------------------------------------------------------------------------
  134. // Member: VirtualStmNode::AppendSisterStm, public
  135. //
  136. // Synopsis: Appends the node passed to the end of this nodes' sister
  137. // node chain.
  138. //
  139. // Arguments: [pcnNew] - The new node to append.
  140. //
  141. // Returns: S_OK for success or an error code.
  142. //
  143. // History: 17-Apr-96 Narindk Created
  144. //---------------------------------------------------------------------------
  145. HRESULT VirtualStmNode::AppendSisterStm(VirtualStmNode *pvsnNew)
  146. {
  147. HRESULT hr = S_OK;
  148. VirtualStmNode *pvsnTrav = this;
  149. DH_VDATEPTRIN(pvsnNew, VirtualStmNode);
  150. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::AppendSisterStm"));
  151. DH_ASSERT(NULL != pvsnNew);
  152. if(S_OK == hr)
  153. {
  154. // Find the last sister in the chain
  155. while (NULL != pvsnTrav->_pvsnSister)
  156. {
  157. pvsnTrav = pvsnTrav->_pvsnSister;
  158. }
  159. // Append the new node as a sister of the last node,
  160. // and make the new node point to this nodes parent as it's parent
  161. pvsnTrav->_pvsnSister = pvsnNew;
  162. pvsnNew->_pvcnParent = pvsnTrav->_pvcnParent;
  163. }
  164. return hr;
  165. }
  166. //+--------------------------------------------------------------------------
  167. // Member: VirtualStmNode::Create, public
  168. //
  169. // Synopsis: Wrapper for IStorage::CreateStream that will create and
  170. // open a new IStream object within this storage object.
  171. //
  172. // Arguments: [grfmode] - Access mode for creating & opening new storage
  173. // object.
  174. // [dwReserved1] - Reserved by OLE for future use, must be zero.
  175. // [dwReserved2] - Reserved by OLE for future use, must be zero.
  176. //
  177. // Returns: S_OK Stream created successfully.
  178. // STG_E_ACCESSDENIED Insufficient permissions to create.
  179. // STG_E_INVALIDPOINTER Bad pointer was passed in.
  180. // STG_E_FILEALREADYEXISTS File with specified name exists and
  181. // mode is set to STGM_FAILIFTHERE.
  182. // STG_TOOMANYOPENFILES too many open files
  183. // STG_E_INSUFFICIENTMEMORY Out of memory.
  184. // STG_E_INVALIDFLAG Unsuppoeted value in grfmode.
  185. // STG_E_INVALIDPARAMETER Invalid parameter.
  186. // STG_E_INVALIDNAME Invalid value for ptcsName.
  187. // STG_E_REVERTED Object has been invalidated by a revert
  188. // operation above it in transaction tree.
  189. //
  190. // History: 18-Apr-96 NarindK Created
  191. //---------------------------------------------------------------------------
  192. HRESULT VirtualStmNode::Create(
  193. DWORD grfMode,
  194. DWORD dwReserved1,
  195. DWORD dwReserved2)
  196. {
  197. HRESULT hr = S_OK;
  198. LPOLESTR pOleStrTemp = NULL;
  199. DH_ASSERT(0 == dwReserved1);
  200. DH_ASSERT(0 == dwReserved2);
  201. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Create"));
  202. DH_ASSERT(NULL != _pvcnParent);
  203. DH_ASSERT(NULL != _pvcnParent->_pstg);
  204. if(S_OK == hr)
  205. {
  206. // Convert _ptszName to OLECHAR
  207. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  208. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  209. }
  210. if(S_OK == hr)
  211. {
  212. hr = _pvcnParent->_pstg->CreateStream(
  213. pOleStrTemp,
  214. grfMode,
  215. dwReserved1,
  216. dwReserved2,
  217. &_pstm);
  218. DH_HRCHECK(hr, TEXT("IStorage::CreateStream")) ;
  219. DH_TRACE ((DH_LVL_DFLIB, TEXT("CreateStream:%s"), _ptszName));
  220. }
  221. // Clean up
  222. if(NULL != pOleStrTemp)
  223. {
  224. delete pOleStrTemp;
  225. pOleStrTemp = NULL;
  226. }
  227. return hr;
  228. }
  229. //+--------------------------------------------------------------------------
  230. // Member: VirtualStmNode::Read, public
  231. //
  232. // Synopsis: Reads data from the stream starting at current seek pointer.
  233. //
  234. // Arguments: [pv] - Points to buffer in which stream data should be stored.
  235. // [cb] - Specifies number of bytes to read from the stream.
  236. // [pcbRead] - Points to the number if bytes actually read from
  237. // from the stream. Caller can specify it as NULL if not
  238. // interested in this value.
  239. //
  240. // Returns: S_OK Data successfully read from stream.
  241. // S_FALSE Data couldn't be read from the stream.
  242. // STG_E_ACCESSDENIED Insufficient access.
  243. // STG_E_INVALIDPOINTER Bad pointer passed in pv.
  244. // STG_E_REVERTED Object has been invalidated by a revert
  245. // operation above it in transaction tree.
  246. // STG_E_WRITEFAULT Disk error during a write operaion.
  247. // Other errors Any ILockBytes or system errors.
  248. //
  249. // History: 18-Apr-96 NarindK Created
  250. //---------------------------------------------------------------------------
  251. HRESULT VirtualStmNode::Read(
  252. PVOID pv,
  253. ULONG cb,
  254. ULONG *pcbRead)
  255. {
  256. HRESULT hr = S_OK;
  257. LPSTREAM pstm = NULL;
  258. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Read"));
  259. DH_ASSERT(_pstm != NULL);
  260. if(S_OK == hr)
  261. {
  262. hr = _pstm->Read(pv, cb, pcbRead);
  263. DH_HRCHECK(hr, TEXT("VirtualStmNode::Read"));
  264. }
  265. // BUBUG: To check invalid parameter checking, may have to remove DH_
  266. // validate macros.
  267. return hr;
  268. }
  269. //+--------------------------------------------------------------------------
  270. // Member: VirtualStmNode::Write, public
  271. //
  272. // Synopsis: Writes data cb bytes from buffer pointed to by pv into stream
  273. // starting at current seek pointer.
  274. //
  275. // Arguments: [pv] - Points to buffer containing data to be written to stream
  276. // [cb] - Specifies number of bytes to write into the stream.
  277. // [pcbWritten] - Points to the number if bytes actually written
  278. // to the stream. Caller can specify it as NULL if not
  279. // interested in this value.
  280. //
  281. // Returns: S_OK Data successfully read from stream.
  282. // S_E_MEDIUMFULL No space left on device.
  283. // STG_E_ACCESSDENIED Insufficient access.
  284. // STG_E_CANTSAVE Data cannot be written for reasons other
  285. // than no access or space.
  286. // STG_E_INVALIDPOINTER Bad pointer passed in pv.
  287. // STG_E_REVERTED Object has been invalidated by a revert
  288. // operation above it in transaction tree.
  289. // STG_E_WRITEFAULT Disk error during a write operaion.
  290. // Other errors Any ILockBytes or system errors.
  291. //
  292. // History: 18-Apr-96 NarindK Created
  293. //---------------------------------------------------------------------------
  294. HRESULT VirtualStmNode::Write(
  295. PVOID pv,
  296. ULONG cb,
  297. ULONG *pcbWritten)
  298. {
  299. HRESULT hr = S_OK;
  300. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Write"));
  301. DH_ASSERT(_pstm != NULL);
  302. if(S_OK == hr)
  303. {
  304. hr = _pstm->Write(pv, cb, pcbWritten);
  305. DH_HRCHECK(hr, TEXT("VirtualStmNode::Write"));
  306. }
  307. if (( S_OK == hr) && (NULL != pcbWritten))
  308. {
  309. if (cb != *pcbWritten)
  310. {
  311. hr = E_FAIL;
  312. DH_TRACE((
  313. DH_LVL_ERROR,
  314. TEXT("VirtualStmNode::Write - bytes: Expected=%lu, Actual=%lu"),
  315. cb,
  316. *pcbWritten));
  317. DH_ASSERT(
  318. !TEXT("Expected and actual bytes written mismatch!"));
  319. }
  320. }
  321. // BUBUG: To check invalid parameter checking, may have to remove DH_
  322. // validate macros.
  323. return hr;
  324. }
  325. //+--------------------------------------------------------------------------
  326. // Member: VirtualStmNode::Open, public
  327. //
  328. // Synopsis: Opens an existing named stream according to grfMode.
  329. // OLE doesn't support opening streams in
  330. // transacted mode, also doesn't allow opening the same stream
  331. // from same open IStorage instance.
  332. //
  333. // Arguments: [pvReserved1] - Reserved for future use. Must be NULL.
  334. // [grfmode] - Mode in which stream should be opened.
  335. // [dwReserved2] - Reserved for future use. Must be NULL.
  336. //
  337. // Returns: HRESULT
  338. // S_OK Stream was opened successfully.
  339. // STG_E_ACCESSDENIED Insufficient access to open stream.
  340. // STG_E_FILENOTFOUND Stream of specified name doesn't exist.
  341. // STG_E_INVALIDFLAG Unsupported value in grfMode.
  342. // STG_E_INVALIDNAME Invalid name.
  343. // STG_E_INVALIDPOINTER Bad pointer passed in pv.
  344. // STG_E_REVERTED Object has been invalidated by a revert
  345. // operation above it in transaction tree.
  346. // STG_E_INVALIDPARAMETER Invalid parameter.
  347. //
  348. // History: NarindK 24-Apr-96 Created
  349. //---------------------------------------------------------------------------
  350. HRESULT VirtualStmNode::Open(
  351. PVOID pvReserved1,
  352. DWORD grfmode,
  353. DWORD dwReserved2)
  354. {
  355. HRESULT hr = S_OK;
  356. LPSTREAM pstm = NULL;
  357. LPOLESTR pOleStrTemp = NULL;
  358. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Open"));
  359. DH_ASSERT(NULL == pvReserved1);
  360. DH_ASSERT(0 == dwReserved2);
  361. DH_ASSERT(NULL != _pvcnParent);
  362. DH_ASSERT(NULL != _pvcnParent->_pstg);
  363. if(S_OK == hr)
  364. {
  365. // Convert _ptszName to OLECHAR
  366. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  367. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  368. }
  369. if(S_OK == hr)
  370. {
  371. hr = _pvcnParent->_pstg->OpenStream(pOleStrTemp,
  372. pvReserved1,
  373. grfmode,
  374. dwReserved2,
  375. &pstm);
  376. DH_HRCHECK(hr, TEXT("IStorage::OpenStream"));
  377. DH_TRACE ((DH_LVL_DFLIB, TEXT("OpenStream:%s"), _ptszName));
  378. }
  379. if((S_OK == hr) && (NULL == _pstm))
  380. {
  381. _pstm = pstm;
  382. }
  383. DH_HRCHECK(hr, TEXT("VirtualStmNode::Open"));
  384. // Clean up
  385. if(NULL != pOleStrTemp)
  386. {
  387. delete pOleStrTemp;
  388. pOleStrTemp = NULL;
  389. }
  390. return hr;
  391. }
  392. //+--------------------------------------------------------------------------
  393. // Member: VirtualStmNode::Close, public
  394. //
  395. // Synopsis: Closes an open stream.
  396. //
  397. // Arguments: none
  398. //
  399. // Returns: HRESULT
  400. //
  401. // History: NarindK 25-Apr-96 Created
  402. //---------------------------------------------------------------------------
  403. HRESULT VirtualStmNode::Close()
  404. {
  405. HRESULT hr = S_OK;
  406. ULONG ulRef = 0;
  407. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Close"));
  408. DH_ASSERT(NULL != _pstm);
  409. // When we create the stream, it is open. We do not call release
  410. // on _pstm normally till the VirtualStmNode object is destructed, or
  411. // if explicitly this function is used to close the stream.
  412. if ( NULL != _pstm )
  413. {
  414. ulRef = _pstm->Release();
  415. }
  416. else
  417. {
  418. DH_ASSERT(!TEXT("_pstm is already NULL!"));
  419. }
  420. DH_HRCHECK(hr, TEXT("VirtualStmNode::Close"));
  421. if(0 == ulRef)
  422. {
  423. _pstm = NULL;
  424. }
  425. return(hr);
  426. }
  427. //+--------------------------------------------------------------------------
  428. // Member: VirtualStmNode::Seek, public
  429. //
  430. // Synopsis: Adjusts the location of seek pointer on the stream.
  431. //
  432. // Arguments: [dlibMove]
  433. // [dwOrigin]
  434. // [plibNewPosition]
  435. //
  436. // Returns: HRESULT
  437. //
  438. // History: NarindK 25-Apr-96 Created
  439. //---------------------------------------------------------------------------
  440. HRESULT VirtualStmNode::Seek(
  441. LARGE_INTEGER dlibMove,
  442. DWORD dwOrigin,
  443. ULARGE_INTEGER *plibNewPosition)
  444. {
  445. HRESULT hr = S_OK;
  446. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Seek"));
  447. DH_ASSERT(_pstm != NULL);
  448. if(S_OK == hr)
  449. {
  450. hr = _pstm->Seek(dlibMove, dwOrigin, plibNewPosition);
  451. DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek"));
  452. }
  453. return hr;
  454. }
  455. //+--------------------------------------------------------------------------
  456. // Member: VirtualStmNode::SetSize, public
  457. //
  458. // Synopsis: Changes the size of the stream.
  459. //
  460. // Arguments: [libNewSize] Specifies new size of stream
  461. //
  462. // Returns: HRESULT
  463. // S_OK Stream size was successfully changed.
  464. // STG_E_MEDIUMFULL Lack of space prohibited change of size
  465. // STG_E_INVALIDFUNCTIONS High DWORD of libNewSize != 0
  466. // STG_E_WRITEFAULT Disk error during a write operation.
  467. // STG_E_REVERTED Object has been invalidated by a revert
  468. // operation above it in transaction tree.
  469. // Other errors Any ILockBytes or system errors.
  470. //
  471. // History: NarindK 29-Apr-96 Created
  472. //---------------------------------------------------------------------------
  473. HRESULT VirtualStmNode::SetSize(ULARGE_INTEGER libNewSize)
  474. {
  475. HRESULT hr = S_OK;
  476. LPSTREAM pstm = NULL;
  477. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::SetSize"));
  478. DH_ASSERT(_pstm != NULL);
  479. if(S_OK == hr)
  480. {
  481. hr = _pstm->SetSize(libNewSize);
  482. DH_HRCHECK(hr, TEXT("VirtualStmNode::SetSize"));
  483. }
  484. return hr;
  485. }
  486. //+--------------------------------------------------------------------------
  487. // Member: VirtualStmNode::Commit, public
  488. //
  489. // Synopsis: Commits any changes made to IStorage object containing the
  490. // stream.
  491. //
  492. // Arguments: [grfCommitFlags] Controls how obect is committed to IStorage
  493. //
  494. // Returns: HRESULT
  495. // S_OK Stream successfully committed.
  496. // STG_E_MEDIUMFULL Commit failde due to lack of space
  497. // STG_E_WRITEFAULT Disk error during a write operation.
  498. // STG_E_REVERTED Object has been invalidated by a revert
  499. // operation above it in transaction tree.
  500. // Other errors Any ILockBytes or system errors.
  501. //
  502. // History: NarindK 29-Apr-96 Created
  503. //---------------------------------------------------------------------------
  504. HRESULT VirtualStmNode::Commit(DWORD grfCommitFlags)
  505. {
  506. HRESULT hr = S_OK;
  507. LPSTREAM pstm = NULL;
  508. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Commit"));
  509. DH_ASSERT(_pstm != NULL);
  510. if(S_OK == hr)
  511. {
  512. hr = _pstm->Commit(grfCommitFlags);
  513. DH_HRCHECK(hr, TEXT("VirtualStmNode::Commit"));
  514. }
  515. return hr;
  516. }
  517. //+--------------------------------------------------------------------------
  518. // Member: VirtualStmNode::Revert, public
  519. //
  520. // Synopsis: Discards any changes made to stream object since it was opened
  521. // or last committed in transacted mode. This function is a noop
  522. // in direct mode.
  523. //
  524. // Arguments: none
  525. //
  526. // Returns: HRESULT
  527. // S_OK Stream successfully committed.
  528. // STG_E_WRITEFAULT Disk error during a write operation.
  529. // STG_E_REVERTED Object has been invalidated by a revert
  530. // operation above it in transaction tree.
  531. // Other errors Any ILockBytes or system errors.
  532. //
  533. // History: NarindK 29-Apr-96 Created
  534. //
  535. // Notes: OLE doesn't support IStream objects being opened in transacted
  536. // mode, os most applications don't need to call this function.
  537. //---------------------------------------------------------------------------
  538. HRESULT VirtualStmNode::Revert()
  539. {
  540. HRESULT hr = S_OK;
  541. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Revert"));
  542. DH_ASSERT(_pstm != NULL);
  543. if(S_OK == hr)
  544. {
  545. hr = _pstm->Revert();
  546. DH_HRCHECK(hr, TEXT("VirtualStmNode::Revert"));
  547. }
  548. return hr;
  549. }
  550. //+--------------------------------------------------------------------------
  551. // Member: VirtualStmNode::Stat, public
  552. //
  553. // Synopsis: Returns relevant statistics concerning this open stream.
  554. //
  555. // Arguments: [pStatStg] - pointer to STATSTG structure.
  556. // [grfStatFlag] - Controls levels of returned statistics.
  557. //
  558. // Returns: S_OK Stastics were successfully returned.
  559. // STG_E_ACCESSDENIED Stm cannot be accessed.
  560. // STG_E_REVERTED Object invalidated by a revert operation
  561. // above it in transaction tree.
  562. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  563. // STG_E_INVALIDPOINTER Invalid pointer.
  564. ////
  565. // History: NarindK 8-May-96 Created
  566. //---------------------------------------------------------------------------
  567. HRESULT VirtualStmNode::Stat(
  568. STATSTG *pStatStg,
  569. DWORD grfStatFlag)
  570. {
  571. HRESULT hr = S_OK;
  572. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Stat"));
  573. DH_ASSERT(_pstm != NULL);
  574. DH_ASSERT(NULL != pStatStg);
  575. DH_ASSERT((
  576. (grfStatFlag == STATFLAG_DEFAULT) ||
  577. (grfStatFlag == STATFLAG_NONAME)));
  578. if(S_OK == hr)
  579. {
  580. hr = _pstm->Stat(pStatStg, grfStatFlag);
  581. DH_HRCHECK(hr, TEXT("VirtualStmNode::Stat"));
  582. }
  583. // BUGBUG: May remove to need DH_ assert macros to do invalid parameter
  584. // checking.
  585. return hr;
  586. }
  587. //+--------------------------------------------------------------------------
  588. // Member: VirtualStmNode::CopyTo, public
  589. //
  590. // Synopsis: Copies data from one stream to another strea, starting at the
  591. // current seek pointer in each stream.
  592. //
  593. // Arguments: [pvsn] - pointer to VirtualStmNode into whose stream the data
  594. // should be copied into.
  595. // [cb] - Specifies number of bytes to be read from source stream
  596. // [pcbRead] - Contains the number of bytes actually read from the
  597. // source stream.
  598. // [pcbWritten] - Contains number of bytes actually written to the
  599. // destination stream.
  600. //
  601. // Returns: S_OK Stream successfully copied.
  602. // STG_E_MEDIUMFULL Lack of space prohibited copy.
  603. // STG_E_READFAULT Disk error during read.
  604. // STG_E_WRITEFAULT Disk error during write opearion.
  605. // STG_E_INVALIDPOINTER Invalid pointer.
  606. // STG_E_REVERTED Object invalidated by a revert operation
  607. // above it in transaction tree.
  608. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  609. // Other errors
  610. //
  611. // History: NarindK 9-May-96 Created
  612. //
  613. // Notes: BUGBUG: Currently not updating the _cb datasize member
  614. // of virtualstmnode objects involved. required?
  615. //---------------------------------------------------------------------------
  616. HRESULT VirtualStmNode::CopyTo(
  617. VirtualStmNode *pvsnDest,
  618. ULARGE_INTEGER cb,
  619. ULARGE_INTEGER *pcbRead,
  620. ULARGE_INTEGER *pcbWritten)
  621. {
  622. HRESULT hr = S_OK;
  623. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::CopyTo"));
  624. DH_VDATEPTROUT(pvsnDest, VirtualStmNode);
  625. DH_ASSERT(NULL != _pstm);
  626. DH_ASSERT(NULL != pvsnDest);
  627. DH_ASSERT(NULL != pvsnDest->_pstm);
  628. if(S_OK == hr)
  629. {
  630. hr = _pstm->CopyTo(pvsnDest->_pstm, cb, pcbRead, pcbWritten);
  631. DH_HRCHECK(hr, TEXT("VirtualStmNode::CopyTo"));
  632. }
  633. return hr;
  634. }
  635. //+--------------------------------------------------------------------------
  636. // Member: VirtualStmNode::AddRefCount, public
  637. //
  638. // Synopsis: Increments the reference count on IStream object.
  639. //
  640. // Arguments: none
  641. //
  642. // Returns: HRESULT
  643. //
  644. // History: NarindK 21-May-96 Created
  645. //---------------------------------------------------------------------------
  646. HRESULT VirtualStmNode::AddRefCount()
  647. {
  648. HRESULT hr = S_OK;
  649. ULONG ulTmp = 0;
  650. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::AddRefCount"));
  651. DH_ASSERT(_pstm != NULL);
  652. if(S_OK == hr)
  653. {
  654. ulTmp = _pstm->AddRef();
  655. }
  656. DH_HRCHECK(hr, TEXT("VirtualStmNode::AddRefCount"));
  657. return(hr);
  658. }
  659. //+--------------------------------------------------------------------------
  660. // Member: VirtualStmNode::QueryInterface, public
  661. //
  662. // Synopsis: Returns pointers to supported objects.
  663. //
  664. // Arguments: none
  665. //
  666. // Returns: HRESULT
  667. //
  668. // History: NarindK 21-May-96 Created
  669. //---------------------------------------------------------------------------
  670. HRESULT VirtualStmNode::QueryInterface(
  671. REFIID riid,
  672. LPVOID *ppvObj)
  673. {
  674. HRESULT hr = S_OK;
  675. DH_VDATEPTROUT(ppvObj, IUnknown *) ;
  676. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::QueryInterface"));
  677. DH_ASSERT(NULL != ppvObj);
  678. DH_ASSERT(NULL != _pstm);
  679. if(S_OK == hr)
  680. {
  681. // Initilze the out parameter
  682. *ppvObj = NULL;
  683. hr = _pstm->QueryInterface(riid, ppvObj);
  684. }
  685. DH_HRCHECK(hr, TEXT("VirtualStmNode::QueryInterface"));
  686. if(S_OK == hr)
  687. {
  688. DH_ASSERT(NULL != *ppvObj);
  689. }
  690. else
  691. {
  692. DH_ASSERT(NULL == *ppvObj);
  693. }
  694. return(hr);
  695. }
  696. //+--------------------------------------------------------------------------
  697. // Member: VirtualStmNode::LockRegion, public
  698. //
  699. // Synopsis: Locks a range of bytes in the stream.
  700. //
  701. // Arguments: [libOffset] - Specifies beginning of region to lock.
  702. // [cb] - Specifies length of region to be locked in bytes.
  703. // [dwLockType]- Specifies kind of lock beng requested.
  704. //
  705. // Returns: HRESULT
  706. // S_OK Range of bytes was successfully locked.
  707. // STG_E_INVALIDFUNCTION Function not supported in this release
  708. // STG_E_LOCKVIOLATION Requested lock supported, but can't be
  709. // granted presently becoz of existing
  710. // lock.
  711. //
  712. // History: NarindK 22-May-96 Created
  713. //---------------------------------------------------------------------------
  714. HRESULT VirtualStmNode::LockRegion(
  715. ULARGE_INTEGER libOffset,
  716. ULARGE_INTEGER cb,
  717. DWORD dwLockType)
  718. {
  719. HRESULT hr = S_OK;
  720. LPSTREAM pstm = NULL;
  721. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::LockRegion"));
  722. DH_ASSERT(_pstm != NULL);
  723. if(S_OK == hr)
  724. {
  725. hr = _pstm->LockRegion(libOffset, cb, dwLockType);
  726. }
  727. DH_HRCHECK(hr, TEXT("VirtualStmNode::LockRegion"));
  728. return(hr);
  729. }
  730. //+--------------------------------------------------------------------------
  731. // Member: VirtualStmNode::UnlockRegion, public
  732. //
  733. // Synopsis: Unlocks a region of stream previously locked by IStream::
  734. // LockRegion
  735. //
  736. // Arguments: [libOffset] - Specifies beginning of region to lock.
  737. // [cb] - Specifies length of region to be locked in bytes.
  738. // [dwLockType]- Specifies kind of lock beng requested.
  739. //
  740. // Returns: HRESULT
  741. // S_OK Requested unlock granted.
  742. // STG_E_INVALIDFUNCTION Function not supported in this release
  743. // STG_E_LOCKVIOLATION Requested unlock can't be granted.
  744. //
  745. // History: NarindK 22-May-96 Created
  746. //---------------------------------------------------------------------------
  747. HRESULT VirtualStmNode::UnlockRegion(
  748. ULARGE_INTEGER libOffset,
  749. ULARGE_INTEGER cb,
  750. DWORD dwLockType)
  751. {
  752. HRESULT hr = S_OK;
  753. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::UnlockRegion"));
  754. DH_ASSERT(_pstm != NULL);
  755. if(S_OK == hr)
  756. {
  757. hr = _pstm->UnlockRegion(libOffset, cb, dwLockType);
  758. }
  759. DH_HRCHECK(hr, TEXT("VirtualStmNode::UnlockRegion"));
  760. return(hr);
  761. }
  762. //+--------------------------------------------------------------------------
  763. // Member: VirtualStmNode::Clone, public
  764. //
  765. // Synopsis: Returns a new IStream object that is clone of this stream.
  766. //
  767. // Arguments: [ppstm] - Points to where new stream to be returned.
  768. //
  769. // Returns: HRESULT
  770. // S_OK Stream successfully copied.
  771. // E_OUTOFMEMORY Out of memory
  772. // STG_E_INVALIDPOINTER Bad pointer was passed in.
  773. // STG_E_INSUFFICIENTMEMORY Not enough memory
  774. // STG_E_WRITEFAULT Disk error during a write operation.
  775. // STG_E_REVERTED Object has been invalidated by a revert
  776. // operation above it in transaction tree.
  777. // Other errors Any ILockBytes or system errors.
  778. //
  779. // History: NarindK 22-May-96 Created
  780. //---------------------------------------------------------------------------
  781. HRESULT VirtualStmNode::Clone(LPSTREAM *ppstm)
  782. {
  783. HRESULT hr = S_OK;
  784. LPSTREAM pstm = NULL;
  785. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Clone"));
  786. DH_ASSERT(_pstm != NULL);
  787. if(S_OK == hr)
  788. {
  789. // Initialize out parameter
  790. *ppstm = NULL;
  791. hr = _pstm->Clone(ppstm);
  792. }
  793. DH_HRCHECK(hr, TEXT("VirtualStmNode::Clone"));
  794. if(S_OK == hr)
  795. {
  796. DH_ASSERT(NULL != *ppstm);
  797. }
  798. else
  799. {
  800. DH_ASSERT(NULL == *ppstm);
  801. }
  802. return(hr);
  803. }
  804. //+--------------------------------------------------------------------------
  805. // Member: VirtualStmNode::Rename, public
  806. //
  807. // Synopsis: Wrapper for IStorage::RenameElement that renames a stream
  808. // contained in an Storage object subject to transaction state
  809. // of IStorage object.
  810. //
  811. // Arguments: [pptcsNewName] - Points to pointer to new name for the element.
  812. //
  813. // Returns: S_OK Object was successfully renamed.
  814. // STG_E_ACCESSDENIED Named element ptcsNewName alreadys exists.
  815. // STG_E_FILENOTFOUND Element couldn't be found.
  816. // STG_E_REVERTED Object invalidated by a revert operation
  817. // above it in transaction tree.
  818. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
  819. // STG_E_INVALIDPOINTER Invalid pointer.
  820. // STG_E_INVALIDNAME Invalid name.
  821. // STG_E_INVALIDPARAMETER Invalid parameter
  822. // STG_E_TOOMANYOPENFILES too many open files.
  823. //
  824. // History: 8-July-96 NarindK Created
  825. //---------------------------------------------------------------------------
  826. HRESULT VirtualStmNode::Rename(LPCTSTR ptcsNewName)
  827. {
  828. HRESULT hr = S_OK;
  829. LPOLESTR pOleStrOld = NULL;
  830. LPOLESTR pOleStrNew = NULL;
  831. DH_VDATESTRINGPTR(ptcsNewName);
  832. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Rename"));
  833. DH_ASSERT(NULL != _pvcnParent);
  834. DH_ASSERT(NULL != _pvcnParent->_pstg);
  835. if(S_OK == hr)
  836. {
  837. // Convert _ptszName to OLECHAR
  838. hr = TStringToOleString(_ptszName, &pOleStrOld);
  839. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  840. }
  841. if(S_OK == hr)
  842. {
  843. // Convert ptcsNewName to OLECHAR
  844. hr = TStringToOleString((LPTSTR)ptcsNewName, &pOleStrNew);
  845. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  846. }
  847. if(S_OK == hr)
  848. {
  849. hr = _pvcnParent->_pstg->RenameElement(pOleStrOld, pOleStrNew);
  850. DH_HRCHECK(hr, TEXT("IStorage::Rename")) ;
  851. }
  852. if(S_OK == hr)
  853. {
  854. // Change the name of VirtualStmNode i.e. its _ptszName variable also
  855. // First delete the old name
  856. if(NULL != _ptszName)
  857. {
  858. delete _ptszName;
  859. _ptszName = NULL;
  860. }
  861. // Now copy the new name by allocating enough memory
  862. _ptszName = new TCHAR[_tcslen(ptcsNewName)+1];
  863. if (_ptszName == NULL)
  864. {
  865. hr = E_OUTOFMEMORY;
  866. }
  867. else
  868. {
  869. _tcscpy(_ptszName, ptcsNewName);
  870. }
  871. }
  872. // Clean up
  873. if(NULL != pOleStrOld)
  874. {
  875. delete pOleStrOld;
  876. pOleStrOld = NULL;
  877. }
  878. if(NULL != pOleStrNew)
  879. {
  880. delete pOleStrNew;
  881. pOleStrNew = NULL;
  882. }
  883. // BUGBUG: to do valid parameter checking, may need to change prototype
  884. // of function to take old name too. Also remove DH_ validation checking
  885. return hr;
  886. }
  887. //+--------------------------------------------------------------------------
  888. // Member: VirtualStmNode::Destroy, public
  889. //
  890. // Synopsis: Wrapper for IStorage::DestroyElement that removes a stream
  891. // from this storage, subject to transaction mode in which it
  892. // was opened. The wrapper for IStorage::DestoryElement that
  893. // destroys a storage from this storage is in VirtualCtrNode::
  894. // Destroy.
  895. //
  896. // Arguments: None
  897. //
  898. // Returns: S_OK Object was successfully renamed.
  899. // STG_E_ACCESSDENIED insufficient permissions.
  900. // STG_E_FILENOTFOUND Element couldn't be found.
  901. // STG_E_REVERTED Object invalidated by a revert operation
  902. // above it in transaction tree.
  903. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
  904. // STG_E_INVALIDPOINTER Invalid pointer.
  905. // STG_E_INVALIDNAME Invalid name.
  906. // STG_E_INVALIDPARAMETER Invalid parameter
  907. // STG_E_TOOMANYOPENFILES too many open files.
  908. //
  909. // History: 8-July-96 NarindK Created
  910. //
  911. // Notes: The existing open instance of this element from this parent
  912. // instance becomes invalid after this function is called.
  913. //
  914. // Use utility function DestroyStream from util.cxx that is a
  915. // wrapper for this function and also readjusts the VirtualDF
  916. // tree.
  917. //---------------------------------------------------------------------------
  918. HRESULT VirtualStmNode::Destroy()
  919. {
  920. HRESULT hr = S_OK;
  921. LPOLESTR pOleStrTemp = NULL;
  922. VirtualStmNode *pvsnTemp = NULL;
  923. VirtualStmNode *pvsnOldSister = NULL;
  924. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Destroy"));
  925. DH_ASSERT(NULL != _pvcnParent);
  926. DH_ASSERT(NULL != _pvcnParent->_pstg);
  927. if(S_OK == hr)
  928. {
  929. // Convert _ptszName to OLECHAR
  930. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  931. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  932. }
  933. if(S_OK == hr)
  934. {
  935. hr = _pvcnParent->_pstg->DestroyElement(pOleStrTemp);
  936. DH_HRCHECK(hr, TEXT("IStorage::DestroyElement")) ;
  937. }
  938. // Clean up
  939. if(NULL != pOleStrTemp)
  940. {
  941. delete pOleStrTemp;
  942. pOleStrTemp = NULL;
  943. }
  944. return hr;
  945. }
  946. //+--------------------------------------------------------------------------
  947. // Member: VirtualStmNode::CalculateCRCs
  948. //
  949. // Synopsis: Updates the name and data crc
  950. //
  951. // Arguments: None.
  952. //
  953. // Returns: HRESULT
  954. //
  955. // History: 02-Apr-98 georgis Created
  956. //---------------------------------------------------------------------------
  957. HRESULT VirtualStmNode::UpdateCRC(DWORD dwChunkSize)
  958. {
  959. HRESULT hr=S_OK;
  960. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::UpdateCRC"));
  961. // Calculate the CRC for the stream data
  962. hr=CalculateStreamDataCRC(_pstm,0,&_dwCRC.dwCRCData,dwChunkSize);
  963. DH_HRCHECK(hr, TEXT("CalculateStreamDataCRC"));
  964. // Calculate the CRC for the stream name
  965. if ( S_OK == hr )
  966. {
  967. hr = CalculateCRCForName(_ptszName, &_dwCRC.dwCRCName);
  968. DH_HRCHECK(hr, TEXT("CalculateCRCForName")) ;
  969. }
  970. // Munge in dwCRCSum
  971. _dwCRC.dwCRCSum=CRC_PRECONDITION;
  972. MUNGECRC(_dwCRC.dwCRCSum,_dwCRC.dwCRCData);
  973. MUNGECRC(_dwCRC.dwCRCSum,_dwCRC.dwCRCName);
  974. return hr;
  975. }