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.

1701 lines
52 KiB

  1. // Microsoft OLE
  2. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  3. // All rights reserved.
  4. //
  5. // File: vcnode.cxx
  6. //
  7. // Contents: Implementation for in-memory Virtual Container Node class.
  8. //
  9. // Classes: VirtualCtrNode (vcn)
  10. //
  11. // Functions: VirtualCtrNode()
  12. // ~VirtualCtrNode()
  13. // Init
  14. // AppendChildCtr
  15. // AppendSisterCtr
  16. // AppendFirstChildStm
  17. // CreateRoot
  18. // CreateRootEx
  19. // Create
  20. // Open
  21. // OpenRoot
  22. // OpenRootEx
  23. // Close
  24. // Commit
  25. // Rename
  26. // Destroy
  27. // Stat
  28. // EnumElements
  29. // SetElementTimes
  30. // SetClass
  31. // SetStateBits
  32. // MoveElementTo
  33. // Revert
  34. // CopyTo
  35. // AddRefCount
  36. // QueryInterface
  37. // CreateRootOnCustomILockBytes
  38. // OpenRootOnCustomILockBytes
  39. //
  40. // NOTE: All above functions are public
  41. //
  42. // History: DeanE 21-Mar-96 Created
  43. // Narindk 24-Apr-96 Added more functions
  44. // SCousens 2-Feb-97 Added Open/CreateRoot for NSS files
  45. //--------------------------------------------------------------------------
  46. #include <dfheader.hxx>
  47. #pragma hdrstop
  48. // Debug object declaration
  49. //
  50. DH_DECLARE;
  51. //+--------------------------------------------------------------------------
  52. // Member: VirtualCtrNode::VirtualCtrNode, public
  53. //
  54. // Synopsis: Constructor.
  55. //
  56. // Arguments: None.
  57. //
  58. // Returns: Nothing.
  59. //
  60. // History: DeanE 21-Mar-96 Created
  61. //---------------------------------------------------------------------------
  62. VirtualCtrNode::VirtualCtrNode() :
  63. _pvcnChild(NULL),
  64. _pvcnSister(NULL),
  65. _pvcnParent(NULL),
  66. _pvsnStream(NULL),
  67. _cStreams(0),
  68. _ptszName(NULL),
  69. _cChildren(0),
  70. _dwCRC(CRC_PRECONDITION),
  71. _pstg(NULL)
  72. {
  73. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::VirtualCtrNode"));
  74. }
  75. //+--------------------------------------------------------------------------
  76. // Member: VirtualCtrNode::~VirtualCtrNode, public
  77. //
  78. // Synopsis: Destructor. Frees resources associated with this object,
  79. // including closing the storage if open and removing this
  80. // tree from memory.
  81. //
  82. // Arguments: None.
  83. //
  84. // Returns: Nothing.
  85. //
  86. // History: DeanE 21-Mar-96 Created
  87. //---------------------------------------------------------------------------
  88. VirtualCtrNode::~VirtualCtrNode()
  89. {
  90. ULONG ulRef = 0;
  91. DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::~VirtualCtrNode"));
  92. if(NULL != _ptszName)
  93. {
  94. delete _ptszName;
  95. _ptszName = NULL;
  96. }
  97. if ( NULL != _pstg )
  98. {
  99. ulRef = _pstg->Release();
  100. // Assert if ulRef is not zero, object is being destructed.
  101. DH_ASSERT(0 == ulRef);
  102. _pstg = NULL;
  103. }
  104. }
  105. //+--------------------------------------------------------------------------
  106. // Member: VirtualStmNode::Init, public
  107. //
  108. // Synopsis: Initializes a storage node - does not open or create the
  109. // actual storage.
  110. //
  111. // Arguments: [tszName] - Name of this storage
  112. // [cStg] - Number of storages contained in this storage.
  113. // [cStm] - Number of streams contained in this storage.
  114. //
  115. // Returns: S_OK if node initialized successfully, otherwise an error.
  116. //
  117. // Notes: BUGBUG - Not Nashville Safe...
  118. //
  119. // History: Narindk 18-Apr-96 Created
  120. //---------------------------------------------------------------------------
  121. HRESULT VirtualCtrNode::Init( LPTSTR tszName, ULONG cStg, ULONG cStm)
  122. {
  123. HRESULT hr = S_OK;
  124. DH_VDATESTRINGPTR(tszName);
  125. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Init"));
  126. DH_ASSERT(NULL != tszName);
  127. if( S_OK == hr)
  128. {
  129. _ptszName = new TCHAR[_tcslen(tszName)+1];
  130. if (_ptszName == NULL)
  131. {
  132. hr = E_OUTOFMEMORY;
  133. }
  134. else
  135. {
  136. _tcscpy(_ptszName, tszName);
  137. _cChildren = cStg;
  138. _cStreams = cStm;
  139. }
  140. }
  141. return hr;
  142. }
  143. //+--------------------------------------------------------------------------
  144. // Member: VirtualCtrNode::AppendChildCtr, public
  145. //
  146. // Synopsis: Appends the node passed to the end of this nodes' child
  147. // node chain.
  148. //
  149. // Arguments: [pcnNew] - The new node to append.
  150. //
  151. // Returns: S_OK for success or an error code.
  152. //
  153. // History: 17-Apr-96 NarindK Created
  154. //---------------------------------------------------------------------------
  155. HRESULT VirtualCtrNode::AppendChildCtr(VirtualCtrNode *pvcnNew)
  156. {
  157. HRESULT hr = S_OK;
  158. VirtualCtrNode *pvcnTrav = this;
  159. DH_VDATEPTRIN(pvcnNew, VirtualCtrNode);
  160. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AppendChildCtr"));
  161. DH_ASSERT(NULL != pvcnNew);
  162. if(S_OK == hr)
  163. {
  164. // Find the last child in the structure
  165. while (NULL != pvcnTrav->_pvcnChild)
  166. {
  167. pvcnTrav = pvcnTrav->_pvcnChild;
  168. }
  169. // Append the new node as a child of the last node,
  170. // and make the new node point to the last node as it's parent
  171. pvcnTrav->_pvcnChild = pvcnNew;
  172. pvcnNew->_pvcnParent = pvcnTrav;
  173. }
  174. return hr;
  175. }
  176. //+--------------------------------------------------------------------------
  177. // Member: VirtualCtrNode::AppendSisterCtr, public
  178. //
  179. // Synopsis: Appends the node passed to the end of this nodes' sister
  180. // node chain.
  181. //
  182. // Arguments: [pcnNew] - The new node to append.
  183. //
  184. // Returns: S_OK for success or an error code.
  185. //
  186. // History: 17-Apr-96 NarindK Created
  187. //---------------------------------------------------------------------------
  188. HRESULT VirtualCtrNode::AppendSisterCtr(VirtualCtrNode *pvcnNew)
  189. {
  190. HRESULT hr = S_OK;
  191. VirtualCtrNode *pvcnTrav = this;
  192. DH_VDATEPTRIN(pvcnNew, VirtualCtrNode);
  193. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AppendSisterCtr"));
  194. DH_ASSERT(NULL != pvcnNew);
  195. if(S_OK == hr)
  196. {
  197. // Find the last sister in the chain
  198. while (NULL != pvcnTrav->_pvcnSister)
  199. {
  200. pvcnTrav = pvcnTrav->_pvcnSister;
  201. }
  202. // Append the new node as a sister of the last node,
  203. // and make the new node point to this nodes parent as it's parent
  204. pvcnTrav->_pvcnSister = pvcnNew;
  205. pvcnNew->_pvcnParent = pvcnTrav->_pvcnParent;
  206. }
  207. return hr;
  208. }
  209. //+--------------------------------------------------------------------------
  210. // Member: VirtualCtrNode::AppendFirstChildStm, public
  211. //
  212. // Synopsis: Appends the first stream to its parent storage
  213. //
  214. // Arguments: [pcnNew] - The new node to append.
  215. //
  216. // Returns: S_OK for success or an error code.
  217. //
  218. // History: 17-Apr-96 NarindK Created
  219. //---------------------------------------------------------------------------
  220. HRESULT VirtualCtrNode::AppendFirstChildStm(VirtualStmNode *pvsnNew)
  221. {
  222. HRESULT hr = S_OK;
  223. VirtualCtrNode *pvcnCurrent= this;
  224. DH_VDATEPTRIN(pvsnNew, VirtualStmNode);
  225. DH_FUNCENTRY(&hr,DH_LVL_DFLIB,TEXT("VirtualCtrNode::AppendFirstChildStm"));
  226. DH_ASSERT(NULL != pvsnNew);
  227. if(S_OK == hr)
  228. {
  229. // Append the new stream node (first stream node) to parent storage,
  230. // and make the new stream node point to storage as it's parent
  231. pvcnCurrent->_pvsnStream = pvsnNew;
  232. pvsnNew->_pvcnParent = pvcnCurrent;
  233. }
  234. return hr;
  235. }
  236. //+--------------------------------------------------------------------------
  237. // Member: VirtualCtrNode::CreateRoot, public
  238. //
  239. // Synopsis: Wrapper for StgCreateDocFile that will create a new root
  240. // compound file in the file system.
  241. //
  242. // Arguments: [grfmode] - Access mode for opening new compound file.
  243. // [dwReserved] - Reserved by OLE for future use, must be zero.
  244. //
  245. // Returns: S_OK for success or an error code.
  246. //
  247. // History: 18-Apr-96 NarindK Created
  248. //---------------------------------------------------------------------------
  249. HRESULT VirtualCtrNode::CreateRoot(DWORD grfMode,
  250. DWORD dwReserved,
  251. DSKSTG DiskStgType)
  252. {
  253. HRESULT hr = S_OK;
  254. LPOLESTR pOleStrTemp = NULL;
  255. DH_ASSERT(0 == dwReserved);
  256. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CreateRoot"));
  257. if(S_OK == hr)
  258. {
  259. // Convert _ptszName to OLECHAR
  260. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  261. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  262. }
  263. if(S_OK == hr)
  264. {
  265. hr = StgCreateDocfile(pOleStrTemp, grfMode, dwReserved, &_pstg);
  266. DH_HRCHECK(hr, TEXT("StgCreateDocFile")) ;
  267. DH_TRACE ((DH_LVL_DFLIB, TEXT("StgCreateRootStorage:%s"), _ptszName));
  268. if (S_OK == hr)
  269. {
  270. if(!StorageIsFlat())
  271. DH_LOG ((LOG_INFO, TEXT("Created docfile:%s"), _ptszName));
  272. else
  273. DH_LOG ((LOG_INFO, TEXT("Created flatfile:%s"), _ptszName));
  274. }
  275. }
  276. // Clean up
  277. if(NULL != pOleStrTemp)
  278. {
  279. delete pOleStrTemp;
  280. pOleStrTemp = NULL;
  281. }
  282. return hr;
  283. }
  284. //+--------------------------------------------------------------------------
  285. // Member: VirtualCtrNode::CreateRootEx, public (overload)
  286. //
  287. // Synopsis: Wrapper for StgCreateDocFileEx that will create a new root
  288. // compound file in the file system.
  289. //
  290. // Arguments: [grfMode] - Access mode for opening new compound file.
  291. // [stgfmt] - Storage Format - enum.
  292. // [grfAttrs] - Attributes (zero for now)
  293. // [pStgOptions] - STGOPTIONS.
  294. // [pTransaction]- Reserved by OLE for future use, must be zero.
  295. // [riid] - should be IID_IStorage to get an IStorage
  296. //
  297. // Returns: S_OK for success or an error code.
  298. //
  299. // History: 28-Jan-97 SCousens Created
  300. //---------------------------------------------------------------------------
  301. HRESULT VirtualCtrNode::CreateRootEx(DWORD grfMode,
  302. DWORD stgfmt,
  303. DWORD grfAttrs,
  304. STGOPTIONS *pStgOptions,
  305. PVOID pTransaction,
  306. REFIID riid)
  307. {
  308. HRESULT hr = S_OK;
  309. LPOLESTR pOleStrTemp = NULL;
  310. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CreateRoot"));
  311. DH_ASSERT(0 == stgfmt); // want value of 0
  312. DH_ASSERT(0 == grfAttrs); // want 0
  313. DH_ASSERT(NULL == pStgOptions); // want value of NULL for wrapper
  314. DH_ASSERT(NULL == pTransaction);
  315. DH_ASSERT(IsEqualIID (IID_IStorage, riid)); // want IStorages. may change
  316. if(S_OK == hr)
  317. {
  318. // Convert _ptszName to OLECHAR
  319. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  320. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  321. }
  322. if(S_OK == hr)
  323. {
  324. hr = StgCreateStorageEx (pOleStrTemp,
  325. grfMode,
  326. stgfmt,
  327. grfAttrs,
  328. pStgOptions,
  329. pTransaction,
  330. riid,
  331. (void**)&_pstg);
  332. DH_HRCHECK(hr, TEXT("StgCreateDocFileEx")) ;
  333. DH_TRACE ((DH_LVL_DFLIB, TEXT("StgCreateRootStorageEx:%s"), _ptszName));
  334. if (S_OK == hr)
  335. {
  336. DH_LOG ((LOG_INFO, TEXT("Created docfile:%s"), _ptszName));
  337. }
  338. }
  339. // Clean up
  340. if(NULL != pOleStrTemp)
  341. {
  342. delete pOleStrTemp;
  343. pOleStrTemp = NULL;
  344. }
  345. return hr;
  346. }
  347. //+--------------------------------------------------------------------------
  348. // Member: VirtualCtrNode::Create, public
  349. //
  350. // Synopsis: Wrapper for IStorage::CreateStorage that will create and
  351. // open a new IStorage object within this storage object.
  352. //
  353. // Arguments: [grfmode] - Access mode for creating & opening new storage
  354. // object.
  355. // [dwReserved1] - Reserved by OLE for future use, must be zero.
  356. // [dwReserved2] - Reserved by OLE for future use, must be zero.
  357. //
  358. // Returns: S_OK for success or an error code.
  359. //
  360. // History: 18-Apr-96 NarindK Created
  361. //---------------------------------------------------------------------------
  362. HRESULT VirtualCtrNode::Create(
  363. DWORD grfMode,
  364. DWORD dwReserved1,
  365. DWORD dwReserved2)
  366. {
  367. HRESULT hr = S_OK;
  368. LPSTORAGE pstg = NULL;
  369. LPOLESTR pOleStrTemp = NULL;
  370. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Create"));
  371. DH_ASSERT(0 == dwReserved1);
  372. DH_ASSERT(0 == dwReserved2);
  373. DH_ASSERT(NULL != _pvcnParent);
  374. DH_ASSERT(NULL != _pvcnParent->_pstg);
  375. if(S_OK == hr)
  376. {
  377. // Convert _ptszName to OLECHAR
  378. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  379. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  380. }
  381. if(S_OK == hr)
  382. {
  383. hr = _pvcnParent->_pstg->CreateStorage(
  384. pOleStrTemp,
  385. grfMode,
  386. dwReserved1,
  387. dwReserved2,
  388. &_pstg);
  389. DH_HRCHECK(hr, TEXT("IStorage::CreateStorage")) ;
  390. DH_TRACE ((DH_LVL_DFLIB, TEXT("CreateStorage:%s"), _ptszName));
  391. }
  392. // Clean up
  393. if(NULL != pOleStrTemp)
  394. {
  395. delete pOleStrTemp;
  396. pOleStrTemp = NULL;
  397. }
  398. return hr;
  399. }
  400. //+--------------------------------------------------------------------------
  401. // Member: VirtualCtrNode::Open, public
  402. //
  403. // Synopsis: Wrapper for IStorage::OpenStorage that will open the named
  404. // IStorage object within this storage object.
  405. //
  406. // Arguments: [grfmode] - Access mode for opening the storage object.
  407. // [dwReserved] - Reserved by OLE for future use, must be zero.
  408. //
  409. // Returns: S_OK for success or an error code.
  410. //
  411. // History: 24-Apr-96 NarindK Created
  412. //---------------------------------------------------------------------------
  413. HRESULT VirtualCtrNode::Open(
  414. LPSTORAGE pstgPriority,
  415. DWORD grfmode,
  416. SNB snbExclude,
  417. DWORD dwReserved)
  418. {
  419. HRESULT hr = S_OK;
  420. LPOLESTR pOleStrTemp = NULL;
  421. LPSTORAGE pstg = NULL;
  422. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Open"));
  423. DH_ASSERT(0 == dwReserved);
  424. // Check if it is root storage, if it is, then call OpenRoot and
  425. // return here else proceed.
  426. if(NULL == this->_pvcnParent)
  427. {
  428. DH_LOG ((LOG_INFO,
  429. TEXT("Test called Open to open root storage. Calling OpenRoot.")));
  430. hr = this->OpenRoot (pstgPriority,
  431. grfmode,
  432. snbExclude,
  433. dwReserved);
  434. DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRoot"));
  435. return hr;
  436. }
  437. DH_ASSERT(NULL != _pvcnParent->_pstg);
  438. if(S_OK == hr)
  439. {
  440. // Convert _ptszName to OLECHAR
  441. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  442. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  443. }
  444. // Open the storage.
  445. if(S_OK == hr)
  446. {
  447. hr = _pvcnParent->_pstg->OpenStorage(
  448. pOleStrTemp,
  449. pstgPriority,
  450. grfmode,
  451. snbExclude,
  452. dwReserved,
  453. &pstg);
  454. DH_HRCHECK(hr, TEXT("IStorage::OpenStorage"));
  455. DH_TRACE ((DH_LVL_DFLIB, TEXT("OpenStorage:%s"), _ptszName));
  456. }
  457. // Save it if function succeeds if _pstg is NULL.
  458. if((S_OK == hr) && (NULL == _pstg))
  459. {
  460. _pstg = pstg;
  461. }
  462. DH_HRCHECK(hr, TEXT("VirtualCtrNode::Open"));
  463. // Clean up
  464. if(NULL != pOleStrTemp)
  465. {
  466. delete pOleStrTemp;
  467. pOleStrTemp = NULL;
  468. }
  469. return(hr);
  470. }
  471. //+--------------------------------------------------------------------------
  472. // Member: VirtualCtrNode::OpenRoot, public
  473. //
  474. // Synopsis: Wrapper for IStorage::OpenStorage that will open the named
  475. // IStorage object within this storage object.
  476. //
  477. // Arguments: [grfmode] - Access mode for creating & opening new storage
  478. // object.
  479. // [dwReserved1] - Reserved by OLE for future use, must be zero.
  480. // [dwReserved2] - Reserved by OLE for future use, must be zero.
  481. //
  482. // Returns: S_OK for success or an error code.
  483. //
  484. // History: 24-Apr-96 NarindK Created
  485. //---------------------------------------------------------------------------
  486. HRESULT VirtualCtrNode::OpenRoot(
  487. LPSTORAGE pstgPriority,
  488. DWORD grfmode,
  489. SNB snbExclude,
  490. DWORD dwReserved,
  491. DSKSTG DiskStgType)
  492. {
  493. HRESULT hr = S_OK;
  494. IStorage *pstg = NULL;
  495. LPOLESTR pOleStrTemp = NULL;
  496. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::OpenRoot"));
  497. DH_ASSERT(0 == dwReserved);
  498. // Make sure this is the Root.
  499. DH_ASSERT(NULL == this->_pvcnParent);
  500. if(S_OK == hr)
  501. {
  502. // Convert _ptszName to OLECHAR
  503. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  504. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  505. }
  506. // Open the root storage
  507. if(S_OK == hr)
  508. {
  509. #if (WINVER<0x500) //NT5 is lockviolation fixed
  510. DG_INTEGER dgi(0);
  511. ULONG ulRandNum = 0;
  512. USHORT usErr = 0;
  513. int i = 0;
  514. // Try opening the docfile
  515. // StgOpenStorage returns STG_E_LOCKVIOLATION is concurrent API calls
  516. // are made, so this is the hack for workaround the problem.
  517. // BUGBUG : Remove this loop once the feature is implemented in OLE.
  518. // BUGBUG : ntbug#114779 Affects DCOM95 only. ntbug#41249 fixed
  519. for(i=0; i<NRETRIES; i++) // NRETRIES has been defined as 20
  520. {
  521. #endif
  522. hr = StgOpenStorage(
  523. pOleStrTemp,
  524. pstgPriority,
  525. grfmode,
  526. snbExclude,
  527. dwReserved,
  528. &pstg);
  529. DH_HRCHECK(hr, TEXT("StgOpenStorage"));
  530. DH_TRACE ((DH_LVL_DFLIB, TEXT("StgOpenRootStorage:%s"), _ptszName));
  531. #if (WINVER<0x500) //NT5 is lockviolation fixed
  532. if ( (S_OK == hr) || (STG_E_LOCKVIOLATION != hr) )
  533. {
  534. break;
  535. }
  536. // Sleep for a random amount of time
  537. // Note: No particular reason why the below random numbers have been used
  538. usErr = dgi.Generate(&ulRandNum, 1, 100 );
  539. if (DG_RC_SUCCESS != usErr)
  540. {
  541. hr = E_FAIL;
  542. break;
  543. }
  544. else
  545. {
  546. Sleep(ulRandNum*50);
  547. }
  548. }
  549. #endif
  550. }
  551. if((S_OK == hr) && (NULL == _pstg))
  552. {
  553. _pstg = pstg;
  554. }
  555. DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRoot"));
  556. // Clean up
  557. if(NULL != pOleStrTemp)
  558. {
  559. delete pOleStrTemp;
  560. pOleStrTemp = NULL;
  561. }
  562. return(hr);
  563. }
  564. //+--------------------------------------------------------------------------
  565. // Member: VirtualCtrNode::OpenRootEx, public (overload)
  566. //
  567. // Synopsis: Wrapper for StgOpenStorageEx that will open a previously
  568. // created root compound file in the file system.
  569. //
  570. // Arguments: [grfMode] - Access mode for opening the compound file.
  571. // [stgfmt] - Storage Format - enum.
  572. // [grfAttrs] - Attributes
  573. // [pStgOptions] - STGOPTIONS, must be NULL as on build 1795.
  574. // [pTransaction]- Reserved by OLE for future use, must be zero.
  575. // [riid] - should be IID_IStorage to get an IStorage
  576. //
  577. // Returns: S_OK for success or an error code.
  578. //
  579. // History: 28-Jan-97 SCousens Created
  580. //---------------------------------------------------------------------------
  581. HRESULT VirtualCtrNode::OpenRootEx(
  582. DWORD grfMode,
  583. DWORD stgfmt,
  584. DWORD grfAttrs,
  585. STGOPTIONS *pStgOptions,
  586. PVOID pTransaction,
  587. REFIID riid)
  588. {
  589. HRESULT hr = S_OK;
  590. IStorage *pstg = NULL;
  591. LPOLESTR pOleStrTemp = NULL;
  592. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::OpenRoot"));
  593. // Make sure this is the Root.
  594. DH_ASSERT(NULL == this->_pvcnParent);
  595. DH_ASSERT(0 == stgfmt); // want value of 0
  596. DH_ASSERT(0 == grfAttrs); // want 0
  597. DH_ASSERT(NULL == pStgOptions); // want value of NULL
  598. DH_ASSERT(NULL == pTransaction);
  599. DH_ASSERT(IsEqualIID (IID_IStorage, riid)); // want IStorages. may change
  600. if (S_OK == hr)
  601. {
  602. // Convert _ptszName to OLECHAR
  603. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  604. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  605. }
  606. // Open the root storage
  607. if (S_OK == hr)
  608. {
  609. DG_INTEGER dgi(0);
  610. ULONG ulRandNum = 0;
  611. USHORT usErr = 0;
  612. int i = 0;
  613. // Try opening the docfile
  614. // StgOpenStorage returns STG_E_LOCKVIOLATION is concurrent API calls
  615. // are made, so this is the hack for workaround the problem.
  616. // BUGBUG : Remove this loop once the feature is implemented in OLE.
  617. for(i=0; i<NRETRIES; i++) // NRETRIES has been defined as 20
  618. {
  619. hr = StgOpenStorageEx(pOleStrTemp,
  620. grfMode,
  621. stgfmt,
  622. grfAttrs,
  623. pStgOptions,
  624. pTransaction,
  625. riid,
  626. (void**)&pstg);
  627. DH_HRCHECK(hr, TEXT("StgOpenStorageEx"));
  628. DH_TRACE ((DH_LVL_DFLIB, TEXT("StgOpenRootStorageEx:%s"), _ptszName));
  629. if ( (S_OK == hr) || (STG_E_LOCKVIOLATION != hr) )
  630. {
  631. break;
  632. }
  633. // Sleep for a random amount of time
  634. // Note: No particular reason why the below random numbers have been used
  635. usErr = dgi.Generate(&ulRandNum, 1, 100 );
  636. if (DG_RC_SUCCESS != usErr)
  637. {
  638. hr = E_FAIL;
  639. break;
  640. }
  641. else
  642. {
  643. Sleep(ulRandNum*50);
  644. DH_TRACE ((DH_LVL_TRACE4,
  645. TEXT("VirtualCtrNode::OpenRoot: Sleeping due to LOCKVIOLATION")));
  646. }
  647. }
  648. }
  649. if((S_OK == hr) && (NULL == _pstg))
  650. {
  651. _pstg = pstg;
  652. }
  653. DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRoot"));
  654. // Clean up
  655. if(NULL != pOleStrTemp)
  656. {
  657. delete pOleStrTemp;
  658. pOleStrTemp = NULL;
  659. }
  660. return(hr);
  661. }
  662. //+--------------------------------------------------------------------------
  663. // Member: VirtualCtrNode::Close, public
  664. //
  665. // Synopsis: Closes an open storage.
  666. //
  667. // Arguments: None
  668. //
  669. // Returns: HRESULT
  670. //
  671. // History: NarindK 25-Apr-96 Created
  672. //---------------------------------------------------------------------------
  673. HRESULT VirtualCtrNode::Close()
  674. {
  675. HRESULT hr = S_OK;
  676. ULONG ulRef = 0;
  677. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Close"));
  678. // When we create the storage, it is open. We do not call release
  679. // on _pstg normally till the VirtualCtrNode object is destructed, or
  680. // if explicitly this function is used to close the storage
  681. if ( NULL != _pstg )
  682. {
  683. ulRef = _pstg->Release();
  684. }
  685. else
  686. {
  687. DH_ASSERT(!TEXT("_pStg is already NULL!"));
  688. }
  689. DH_HRCHECK(hr, TEXT("VirtualCtrNode::Close"));
  690. if(0 == ulRef)
  691. {
  692. _pstg = NULL;
  693. }
  694. return(hr);
  695. }
  696. //+--------------------------------------------------------------------------
  697. // Member: VirtualCtrNode::Commit, public
  698. //
  699. // Synopsis: Wrapper for IStorage::Commit that will commit any changes
  700. // made to an IStorage object since it was opened or last
  701. // committed to persistent storage.
  702. //
  703. // Arguments: [grfCommitFlags] - Controls how object is committed to IStorage.
  704. //
  705. // Returns: S_OK Commit operation was successful.
  706. // STG_E_NOTCURRENT Another opening of storage object has commi
  707. // tted changes, possibility of overwriting.
  708. // STG_E_MEDIUMFULL No space left on device to commit.
  709. // STG_E_TOOMANYOPENFILES too many open files.
  710. // STG_E_REVERTED Object invalidated by a revert operation
  711. // above it in transaction tree.
  712. // STG_E_INVALIDFLAG Invalid flag.
  713. // STG_E_INVALIDPARAMETER Inalid parameter
  714. //
  715. // History: 29-Apr-96 NarindK Created
  716. // 12-Mar-97 MikeW Removed HRCHECK after Commit
  717. //---------------------------------------------------------------------------
  718. HRESULT VirtualCtrNode::Commit(DWORD grfCommitFlags)
  719. {
  720. HRESULT hr = S_OK;
  721. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Commit"));
  722. DH_ASSERT(NULL != _pstg);
  723. if ( S_OK == hr )
  724. {
  725. hr = _pstg->Commit(grfCommitFlags);
  726. }
  727. return hr;
  728. }
  729. //+--------------------------------------------------------------------------
  730. // Member: VirtualCtrNode::Rename, public
  731. //
  732. // Synopsis: Wrapper for IStorage::RenameElement that renames an element
  733. // contained in an Storage object subject to transaction state
  734. // of IStorage object.
  735. //
  736. // Arguments: [pptcsNewName] - Points to pointer to new name for the element.
  737. //
  738. // Returns: S_OK Object was successfully renamed.
  739. // STG_E_ACCESSDENIED Named element ptcsNewName alreadys exists.
  740. // STG_E_FILENOTFOUND Element couldn't be found.
  741. // STG_E_REVERTED Object invalidated by a revert operation
  742. // above it in transaction tree.
  743. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
  744. // STG_E_INVALIDPOINTER Invalid pointer.
  745. // STG_E_INVALIDNAME Invalid name.
  746. // STG_E_INVALIDPARAMETER Invalid parameter
  747. // STG_E_TOOMANYOPENFILES too many open files.
  748. //
  749. // History: 29-Apr-96 NarindK Created
  750. //---------------------------------------------------------------------------
  751. HRESULT VirtualCtrNode::Rename(LPCTSTR ptcsNewName)
  752. {
  753. HRESULT hr = S_OK;
  754. LPOLESTR pOleStrOld = NULL;
  755. LPOLESTR pOleStrNew = NULL;
  756. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Rename"));
  757. DH_VDATESTRINGPTR(ptcsNewName);
  758. DH_ASSERT(NULL != _pvcnParent);
  759. DH_ASSERT(NULL != _pvcnParent->_pstg);
  760. if(S_OK == hr)
  761. {
  762. // Convert _ptszName to OLECHAR
  763. hr = TStringToOleString(_ptszName, &pOleStrOld);
  764. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  765. }
  766. if(S_OK == hr)
  767. {
  768. // Convert ptcsNewName to OLECHAR
  769. hr = TStringToOleString((LPTSTR)ptcsNewName, &pOleStrNew);
  770. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  771. }
  772. if(S_OK == hr)
  773. {
  774. hr = _pvcnParent->_pstg->RenameElement(pOleStrOld, pOleStrNew);
  775. DH_HRCHECK(hr, TEXT("IStorage::Rename")) ;
  776. }
  777. if(S_OK == hr)
  778. {
  779. // Change the name of VirtualCtrNode i.e. its _ptszName variable also
  780. // First delete the old name
  781. if(NULL != _ptszName)
  782. {
  783. delete _ptszName;
  784. _ptszName = NULL;
  785. }
  786. // Now copy the new name by allocating enough memory
  787. _ptszName = new TCHAR[_tcslen(ptcsNewName)+1];
  788. if (_ptszName == NULL)
  789. {
  790. hr = E_OUTOFMEMORY;
  791. }
  792. else
  793. {
  794. _tcscpy(_ptszName, ptcsNewName);
  795. }
  796. }
  797. // Clean up
  798. if(NULL != pOleStrOld)
  799. {
  800. delete pOleStrOld;
  801. pOleStrOld = NULL;
  802. }
  803. if(NULL != pOleStrNew)
  804. {
  805. delete pOleStrNew;
  806. pOleStrNew = NULL;
  807. }
  808. return hr;
  809. }
  810. //+--------------------------------------------------------------------------
  811. // Member: VirtualCtrNode::Destroy, public
  812. //
  813. // Synopsis: Wrapper for IStorage::DestroyElement that removes an element
  814. // storage from this storage, subject to transaction mode in
  815. // which it was opened. The wrapper for IStorage::DestroyElement
  816. // that destorys a stream element from this storage is in
  817. // VirtualStmNode::Destroy.
  818. //
  819. // Arguments: None
  820. //
  821. // Returns: S_OK Object was successfully renamed.
  822. // STG_E_ACCESSDENIED insufficient permissions.
  823. // STG_E_FILENOTFOUND Element couldn't be found.
  824. // STG_E_REVERTED Object invalidated by a revert operation
  825. // above it in transaction tree.
  826. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
  827. // STG_E_INVALIDPOINTER Invalid pointer.
  828. // STG_E_INVALIDNAME Invalid name.
  829. // STG_E_INVALIDPARAMETER Invalid parameter
  830. // STG_E_TOOMANYOPENFILES too many open files.
  831. //
  832. // History: 29-Apr-96 NarindK Created
  833. //
  834. // Notes: The existing open instance of this element from this parent
  835. // instance becomes invalid after this function is called.
  836. //
  837. // Use DestroyStorage in the util.cxx which is a wrapper to call
  838. // this function and also readjusts the VirtualDF tree.
  839. //---------------------------------------------------------------------------
  840. HRESULT VirtualCtrNode::Destroy()
  841. {
  842. HRESULT hr = S_OK;
  843. LPSTORAGE pstg = NULL;
  844. LPOLESTR pOleStrTemp = NULL;
  845. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Destroy"));
  846. DH_ASSERT(NULL != _pvcnParent);
  847. DH_ASSERT(NULL != _pvcnParent->_pstg);
  848. if(S_OK == hr)
  849. {
  850. // Convert _ptszName to OLECHAR
  851. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  852. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  853. }
  854. if(S_OK == hr)
  855. {
  856. hr = _pvcnParent->_pstg->DestroyElement(pOleStrTemp);
  857. DH_HRCHECK(hr, TEXT("IStorage::DestroyElement")) ;
  858. }
  859. // Clean up
  860. if(NULL != pOleStrTemp)
  861. {
  862. delete pOleStrTemp;
  863. pOleStrTemp = NULL;
  864. }
  865. return hr;
  866. }
  867. //+--------------------------------------------------------------------------
  868. // Member: VirtualCtrNode::Stat, public
  869. //
  870. // Synopsis: Returns relevant statistics concerning this open storage.
  871. //
  872. // Arguments: [pStatStg] - pointer to STATSTG structure.
  873. // [grfStatFlag] - Controls levels of returned statistics.
  874. //
  875. // Returns: S_OK Statistics were successfully returned.
  876. // STG_E_ACCESSDENIED insufficient permissions.
  877. // STG_E_REVERTED Object invalidated by a revert operation
  878. // above it in transaction tree.
  879. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  880. // STG_E_INVALIDPOINTER Invalid pointer.
  881. //
  882. // History: NarindK 8-May-96 Created
  883. //---------------------------------------------------------------------------
  884. HRESULT VirtualCtrNode::Stat(
  885. STATSTG *pStatStg,
  886. DWORD grfStatFlag)
  887. {
  888. HRESULT hr = S_OK;
  889. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Stat"));
  890. DH_ASSERT(_pstg != NULL);
  891. DH_ASSERT(NULL != pStatStg);
  892. DH_ASSERT((
  893. (grfStatFlag == STATFLAG_DEFAULT) ||
  894. (grfStatFlag == STATFLAG_NONAME)));
  895. if(S_OK == hr)
  896. {
  897. hr = _pstg->Stat(pStatStg, grfStatFlag);
  898. DH_HRCHECK(hr, TEXT("IStorage::Stat"));
  899. }
  900. // BUGBUG: May remove to need DH_ assert macros to do invalid parameter
  901. // checking.
  902. return hr;
  903. }
  904. //+--------------------------------------------------------------------------
  905. // Member: VirtualCtrNode::EnumElements, public
  906. //
  907. // Synopsis: Enumerates the elements immediately contained within this
  908. // storage object.
  909. //
  910. // Arguments: [dwReserved1] - Reserved by OLE
  911. // [dwReserved2] - Reserved by OLE
  912. // [dwReserved3] - Reserved by OLE
  913. // [ppenumStatStg] - Points to where to return enumerator, NULL
  914. // if an error.
  915. //
  916. // Returns: S_OK Enumeration successful.
  917. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  918. // STG_E_INVALIDPOINTER Invalid pointer.
  919. // STG_E_INVALIDPARAMETER Invalid parameter.
  920. // E_OUTOFMEMORY Not enough memory.
  921. // STG_E_REVERTED Object invalidated by a revert operation
  922. // above it in transaction tree.
  923. //
  924. // History: NarindK 10-May-96 Created
  925. //---------------------------------------------------------------------------
  926. HRESULT VirtualCtrNode::EnumElements(
  927. DWORD dwReserved1,
  928. PVOID pReserved2,
  929. DWORD dwReserved3,
  930. LPENUMSTATSTG *ppenumStatStg)
  931. {
  932. HRESULT hr = S_OK;
  933. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::EnumElements"));
  934. DH_ASSERT(_pstg != NULL);
  935. if(S_OK == hr)
  936. {
  937. hr = _pstg->EnumElements(
  938. dwReserved1,
  939. pReserved2,
  940. dwReserved3,
  941. ppenumStatStg);
  942. DH_HRCHECK(hr, TEXT("IStorage::EnumElements"));
  943. }
  944. return hr;
  945. }
  946. //+--------------------------------------------------------------------------
  947. // Member: VirtualCtrNode::SetElementTimes, public
  948. //
  949. // Synopsis: Sets the modification, access, and creation times of the
  950. // indicated element of this storage object.
  951. //
  952. // Arguments: [lpszName] - Points to name of element to change
  953. // [pctime] - Points to new creation time
  954. // [patime] - Points to new access time
  955. // [pmtime] - Points to new modification time
  956. //
  957. // Returns: S_OK Time values successfully set.
  958. // STG_E_ACCESSDENIED insufficient permissions.
  959. // STG_E_FILENOTFOUND Element not found.
  960. // STG_E_FILEALREADYEXITS Specified file already exists.
  961. // STG_E_TOOMANYOPENFILES too many open files
  962. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  963. // STG_E_INVALIDNAME Invalid name.
  964. // STG_E_INVALIDPOINTER Invalid pointer.
  965. // STG_E_INVALIDPARAMETER Invalid parameter.
  966. // STG_E_REVERTED Object invalidated by a revert operation
  967. // above it in transaction tree.
  968. //
  969. // History: NarindK 10-May-96 Created
  970. //
  971. // Notes: Ole implemntation doesn't support setting time on stream elem
  972. // so no function corresponding to VirtualStmNode for this.
  973. //
  974. //---------------------------------------------------------------------------
  975. HRESULT VirtualCtrNode::SetElementTimes(
  976. FILETIME const *pctime,
  977. FILETIME const *patime,
  978. FILETIME const *pmtime)
  979. {
  980. HRESULT hr = S_OK;
  981. LPOLESTR pOleStrTemp = NULL;
  982. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetElementTimes"));
  983. DH_ASSERT(NULL != _pvcnParent);
  984. DH_ASSERT(NULL != _pvcnParent->_pstg);
  985. if(S_OK == hr)
  986. {
  987. // Convert _ptszName to OLECHAR
  988. hr = TStringToOleString(_ptszName, &pOleStrTemp);
  989. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  990. }
  991. if(S_OK == hr)
  992. {
  993. hr = _pvcnParent->_pstg->SetElementTimes(
  994. pOleStrTemp,
  995. pctime,
  996. patime,
  997. pmtime);
  998. DH_HRCHECK(hr, TEXT("IStorage::SetElementTimes"));
  999. }
  1000. // Clean up
  1001. if(NULL != pOleStrTemp)
  1002. {
  1003. delete pOleStrTemp;
  1004. pOleStrTemp = NULL;
  1005. }
  1006. return hr;
  1007. }
  1008. //+--------------------------------------------------------------------------
  1009. // Member: VirtualCtrNode::SetClass, public
  1010. //
  1011. // Synopsis: Persistently stores the object's CLSID.
  1012. //
  1013. // Arguments: [rclsid] - Specifies CLSID to be associated with this storage.
  1014. //
  1015. // Returns: S_OK CLSID successfully stored.
  1016. // STG_E_ACCESSDENIED insufficient permissions.
  1017. // STG_E_REVERTED Object invalidated by a revert operation
  1018. // above it in transaction tree.
  1019. // STG_E_MEDIUMFULL Not enough space on device.
  1020. //
  1021. // History: NarindK 9-May-96 Created
  1022. //---------------------------------------------------------------------------
  1023. HRESULT VirtualCtrNode::SetClass(REFCLSID rclsid)
  1024. {
  1025. HRESULT hr = S_OK;
  1026. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetClass"));
  1027. DH_ASSERT(_pstg != NULL);
  1028. if(S_OK == hr)
  1029. {
  1030. hr = _pstg->SetClass(rclsid);
  1031. DH_HRCHECK(hr, TEXT("IStorage::SetClass"));
  1032. }
  1033. return hr;
  1034. }
  1035. //+--------------------------------------------------------------------------
  1036. // Member: VirtualCtrNode::SetStateBits, public
  1037. //
  1038. // Synopsis: Stores upto 32 bits of state information in this IStorage.
  1039. //
  1040. // Arguments: [grfStateBits] - New values of bits to be set
  1041. // [grfMask] - Binary mask to indicate significant bits.
  1042. //
  1043. // Returns: S_OK State successfully set.
  1044. // STG_E_ACCESSDENIED insufficient permissions.
  1045. // STG_E_INVALIDPARAMETER Invalid parameter
  1046. // STG_E_INVALIDFLAG Invalid flag in grfStateBits or grfMask
  1047. //
  1048. // History: NarindK 9-May-96 Created
  1049. //---------------------------------------------------------------------------
  1050. HRESULT VirtualCtrNode::SetStateBits(
  1051. DWORD grfStateBits,
  1052. DWORD grfMask)
  1053. {
  1054. HRESULT hr = S_OK;
  1055. LPSTORAGE pstg = NULL;
  1056. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetStateBits"));
  1057. DH_ASSERT(_pstg != NULL);
  1058. if(S_OK == hr)
  1059. {
  1060. hr = _pstg->SetStateBits(grfStateBits, grfMask);
  1061. DH_HRCHECK(hr, TEXT("IStorage::SetStateBits"));
  1062. }
  1063. return hr;
  1064. }
  1065. //+--------------------------------------------------------------------------
  1066. // Member: VirtualCtrNode::MoveElementTo, public
  1067. //
  1068. // Synopsis: Moves an IStorage/IStream element to indicated new destination
  1069. // container.
  1070. //
  1071. // Arguments: [ptszName] - Name of child IStorage/IStream present in this
  1072. // this _pstg to be moved
  1073. // [pvcnDest] - Pointer to destination virtual container
  1074. // [lpszNewname] - Points to new name to element in its new
  1075. // container
  1076. // [grfFlags] - Specifies if to move as move or copy
  1077. //
  1078. // Returns: S_OK Storage moved successfully.
  1079. // STG_E_ACCESSDENIED insufficient permissions.
  1080. // STG_E_FILENOTFOUND Element not found.
  1081. // STG_E_FILEALREADYEXITS Specified file already exists.
  1082. // STG_E_TOOMANYOPENFILES too many open files
  1083. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  1084. // STG_E_INVALIDNAME Invalid name.
  1085. // STG_E_INVALIDPOINTER Invalid pointer.
  1086. // STG_E_INVALIDPARAMETER Invalid parameter
  1087. // STG_E_INVALIDFLAG Invalid flag in grfFlags
  1088. // STG_E_REVERTED Object invalidated by a revert operation
  1089. // above it in transaction tree.
  1090. //
  1091. // History: NarindK 13-May-96 Created
  1092. //
  1093. // Notes: This moves a child storage/stream with name ptszName in present
  1094. // storage _pstg to a destination storage. Make sure that the
  1095. // child storage/stream to be moved is closed and the destination
  1096. // storage is open.
  1097. // The VirtualDF tree needs to be readjusted after this call.
  1098. // Different methods of VirtualDF may need to be called as the
  1099. // case may be - AdjustTreeOnStgMoveElement, AdjustTreeOnStmMove
  1100. // Element, AdjustTreeOnStgCopyElement, AdjustTreeOnStmCopyElement
  1101. //---------------------------------------------------------------------------
  1102. HRESULT VirtualCtrNode::MoveElementTo(
  1103. LPCTSTR ptszName,
  1104. VirtualCtrNode *pvcnDest,
  1105. LPCTSTR ptszNewName,
  1106. DWORD grfFlags)
  1107. {
  1108. HRESULT hr = S_OK;
  1109. LPOLESTR pOleStrOld = NULL;
  1110. LPOLESTR pOleStrNew = NULL;
  1111. DH_VDATESTRINGPTR(ptszName);
  1112. DH_VDATESTRINGPTR(ptszNewName);
  1113. DH_VDATEPTRIN(pvcnDest, VirtualCtrNode);
  1114. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::MoveElementTo"));
  1115. DH_ASSERT(_pstg != NULL);
  1116. DH_ASSERT(NULL != pvcnDest);
  1117. DH_ASSERT(pvcnDest->_pstg != NULL);
  1118. DH_ASSERT(NULL != ptszName);
  1119. DH_ASSERT(NULL != ptszNewName);
  1120. DH_ASSERT((grfFlags == STGMOVE_COPY) ||
  1121. (grfFlags == STGMOVE_MOVE));
  1122. if(S_OK == hr)
  1123. {
  1124. // Convert ptszName to OLECHAR
  1125. hr = TStringToOleString((LPTSTR)ptszName, &pOleStrOld);
  1126. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  1127. }
  1128. if(S_OK == hr)
  1129. {
  1130. // Convert ptszNewName to OLECHAR
  1131. hr = TStringToOleString((LPTSTR)ptszNewName, &pOleStrNew);
  1132. DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
  1133. }
  1134. if(S_OK == hr)
  1135. {
  1136. hr = _pstg->MoveElementTo(
  1137. pOleStrOld,
  1138. pvcnDest->_pstg,
  1139. pOleStrNew,
  1140. grfFlags);
  1141. DH_HRCHECK(hr, TEXT("IStorage::MoveElementTo"));
  1142. }
  1143. // Clean up
  1144. if(NULL != pOleStrOld)
  1145. {
  1146. delete pOleStrOld;
  1147. pOleStrOld = NULL;
  1148. }
  1149. if(NULL != pOleStrNew)
  1150. {
  1151. delete pOleStrNew;
  1152. pOleStrNew = NULL;
  1153. }
  1154. return hr;
  1155. }
  1156. //+--------------------------------------------------------------------------
  1157. // Member: VirtualCtrNode::Revert, public
  1158. //
  1159. // Synopsis: Discards all changes made in or made visible to thsi storage
  1160. // object since it was opened or last committed.
  1161. //
  1162. // Arguments: none
  1163. //
  1164. // Returns: HRESULT
  1165. // S_OK Revert operation successful.
  1166. // STG_E_INSUFFICIENTMEMORY Out of memory.
  1167. // STG_E_TOOMANYOPENFILES Too many open files.
  1168. // STG_E_REVERTED Object has been invalidated by a revert
  1169. // operation above it in transaction tree.
  1170. //
  1171. // History: NarindK 20-May-96 Created
  1172. //
  1173. // Notes:
  1174. //---------------------------------------------------------------------------
  1175. HRESULT VirtualCtrNode::Revert()
  1176. {
  1177. HRESULT hr = S_OK;
  1178. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Revert"));
  1179. DH_ASSERT(_pstg != NULL);
  1180. if(S_OK == hr)
  1181. {
  1182. hr = _pstg->Revert();
  1183. DH_HRCHECK(hr, TEXT("VirtualCtrNode::Revert"));
  1184. }
  1185. return hr;
  1186. }
  1187. //+--------------------------------------------------------------------------
  1188. // Member: VirtualCtrNode::CopyTo, public
  1189. //
  1190. // Synopsis: Copies an IStorage element to indicated new destination
  1191. // container.
  1192. //
  1193. // Arguments: [ciidExclude] - Speciefies number of elements in array pointed
  1194. // to by rgiidExclude.
  1195. // [rgiidExclude]- Specifies an array of interface identifiers the
  1196. // caller takes responsibility of moving from
  1197. // source to destination.
  1198. // [snbExclude] - Points to a bloack of named elements not to
  1199. // to be copied into destination container.
  1200. // [pvcnDest]- Points to the open storage object where this
  1201. // open storage object is copied.
  1202. //
  1203. // Returns: S_OK Storage copied successfully.
  1204. // STG_E_ACCESSDENIED insufficient permissions.
  1205. // STG_E_TOOMANYOPENFILES too many open files
  1206. // STG_E_INSUFFICIENTMEMORY Not enough memory.
  1207. // STG_E_INVALIDPOINTER Invalid pointer.
  1208. // STG_E_INVALIDPARAMETER Invalid parameter
  1209. // STG_E_MEDIUMFULL Storage medium is full
  1210. // STG_E_DESTLACKSINTERFACE Destination lacks an interface of the
  1211. // source object to be copied.
  1212. //
  1213. // History: NarindK 20-May-96 Created
  1214. //
  1215. // Notes: This copies contents of storage _pstg to a destination storage.
  1216. // The storage to be copied from and the destination storage to
  1217. // be copied into is open.
  1218. // VirtualDF tree needs to be readjusted after this call. Virtual
  1219. // DF's AdjustTreeOnCopyTo may be used.
  1220. //---------------------------------------------------------------------------
  1221. HRESULT VirtualCtrNode::CopyTo(
  1222. DWORD ciidExclude,
  1223. IID const* rgiidExclude,
  1224. SNB snbExclude,
  1225. VirtualCtrNode *pvcnDest)
  1226. {
  1227. HRESULT hr = S_OK;
  1228. DH_VDATEPTRIN(pvcnDest, VirtualCtrNode);
  1229. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CopyTo"));
  1230. DH_ASSERT(NULL != _pstg);
  1231. DH_ASSERT(NULL != pvcnDest);
  1232. DH_ASSERT(NULL != pvcnDest->_pstg);
  1233. if(S_OK == hr)
  1234. {
  1235. hr = _pstg->CopyTo(
  1236. ciidExclude,
  1237. rgiidExclude,
  1238. snbExclude,
  1239. pvcnDest->_pstg);
  1240. DH_HRCHECK(hr, TEXT("IStorage::CopyTo"));
  1241. }
  1242. return hr;
  1243. }
  1244. //+--------------------------------------------------------------------------
  1245. // Member: VirtualCtrNode::AddRefCount, public
  1246. //
  1247. // Synopsis: Increments the reference count on IStorage object.
  1248. //
  1249. // Arguments: none
  1250. //
  1251. // Returns: HRESULT
  1252. //
  1253. // History: NarindK 21-May-96 Created
  1254. //---------------------------------------------------------------------------
  1255. HRESULT VirtualCtrNode::AddRefCount()
  1256. {
  1257. HRESULT hr = S_OK;
  1258. ULONG ulTmp = 0;
  1259. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AddRefCount"));
  1260. DH_ASSERT(_pstg != NULL);
  1261. if(S_OK == hr)
  1262. {
  1263. ulTmp = _pstg->AddRef();
  1264. }
  1265. DH_HRCHECK(hr, TEXT("VirtualCtrNode::AddRefCount"));
  1266. return(hr);
  1267. }
  1268. //+--------------------------------------------------------------------------
  1269. // Member: VirtualCtrNode::QueryInterface, public
  1270. //
  1271. // Synopsis: Returns pointers to supported objects.
  1272. //
  1273. // Arguments: none
  1274. //
  1275. // Returns: HRESULT
  1276. //
  1277. // History: NarindK 21-May-96 Created
  1278. //---------------------------------------------------------------------------
  1279. HRESULT VirtualCtrNode::QueryInterface(
  1280. REFIID riid,
  1281. LPVOID *ppvObj)
  1282. {
  1283. HRESULT hr = S_OK;
  1284. LPSTORAGE pstg = NULL;
  1285. DH_VDATEPTROUT(ppvObj, IUnknown *) ;
  1286. DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::QueryInterface"));
  1287. DH_ASSERT(ppvObj != NULL);
  1288. DH_ASSERT(_pstg != NULL);
  1289. if(S_OK == hr)
  1290. {
  1291. // Initilze the out parameter
  1292. *ppvObj = NULL;
  1293. hr = _pstg->QueryInterface(riid, ppvObj);
  1294. }
  1295. DH_HRCHECK(hr, TEXT("VirtualCtrNode::QueryInterface"));
  1296. if(S_OK == hr)
  1297. {
  1298. DH_ASSERT(NULL != *ppvObj);
  1299. }
  1300. else
  1301. {
  1302. DH_ASSERT(NULL == *ppvObj);
  1303. }
  1304. return(hr);
  1305. }
  1306. //+--------------------------------------------------------------------------
  1307. // Member: VirtualCtrNode::CreateRootOnCustomILockBytes,public
  1308. //
  1309. // Synopsis: Wrapper for StgCreateDocFileOnILockBytes that will create a new
  1310. // root compound file in the file system based on custom ILockBytes
  1311. //
  1312. // Arguments: [grfmode] - Access mode for creating new compound file.
  1313. // [pILockBytes] - Pointer to ILockBytes
  1314. //
  1315. // Returns: S_OK for success or an error code.
  1316. //
  1317. // History: 1-Aug-96 NarindK Created
  1318. //---------------------------------------------------------------------------
  1319. HRESULT VirtualCtrNode::CreateRootOnCustomILockBytes(
  1320. DWORD grfMode,
  1321. ILockBytes *pILockBytes)
  1322. {
  1323. HRESULT hr = S_OK;
  1324. DH_FUNCENTRY(
  1325. &hr,
  1326. DH_LVL_DFLIB,
  1327. _TEXT("VirtualCtrNode::CreateRootOnCustomILockBytes"));
  1328. if(S_OK == hr)
  1329. {
  1330. hr = StgCreateDocfileOnILockBytes(
  1331. pILockBytes,
  1332. grfMode,
  1333. 0,
  1334. &_pstg);
  1335. DH_HRCHECK(hr, TEXT("StgCreateDocFileOnLockBytes")) ;
  1336. }
  1337. return hr;
  1338. }
  1339. //+--------------------------------------------------------------------------
  1340. // Member: VirtualCtrNode::OpenRootOnCustomILockBytes, public
  1341. //
  1342. // Synopsis: Wrapper for StgOpenStorageOnILockBytes that will open the named
  1343. // IStorage root object on custom ILOckBytes provided.
  1344. //
  1345. // Arguments: [pstgPrioirty] - Points to previous opening of root stg
  1346. // [grfmode] - Access mode for creating & opening new storage
  1347. // object.
  1348. // [snbExclude] - Points to a block of named elements not to
  1349. // to be excluded in open call.
  1350. // [dwReserved] - Reserved by OLE for future use, must be zero.
  1351. // [pILockBytes] - Pointer to ILockBytes
  1352. //
  1353. // Returns: S_OK for success or an error code.
  1354. //
  1355. // History: 3-Aug-96 NarindK Created
  1356. //---------------------------------------------------------------------------
  1357. HRESULT VirtualCtrNode::OpenRootOnCustomILockBytes(
  1358. LPSTORAGE pstgPriority,
  1359. DWORD grfmode,
  1360. SNB snbExclude,
  1361. DWORD dwReserved,
  1362. ILockBytes *pILockBytes)
  1363. {
  1364. HRESULT hr = S_OK;
  1365. IStorage *pstg = NULL;
  1366. DH_FUNCENTRY(
  1367. &hr,
  1368. DH_LVL_DFLIB,
  1369. _TEXT("VirtualCtrNode::OpenRootOnCustomILockBytes"));
  1370. // Make sure this is the Root.
  1371. DH_ASSERT(NULL == this->_pvcnParent);
  1372. // Open the root storage
  1373. if(S_OK == hr)
  1374. {
  1375. hr = StgOpenStorageOnILockBytes(
  1376. pILockBytes,
  1377. pstgPriority,
  1378. grfmode,
  1379. snbExclude,
  1380. dwReserved,
  1381. &pstg);
  1382. DH_HRCHECK(hr, TEXT("StgOpenStorage"));
  1383. }
  1384. if((S_OK == hr) && (NULL == _pstg))
  1385. {
  1386. _pstg = pstg;
  1387. }
  1388. DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRootOnCustomILockBytes"));
  1389. return(hr);
  1390. }