// Microsoft OLE // Copyright (C) Microsoft Corporation, 1992 - 1996. // All rights reserved. // // File: vcnode.cxx // // Contents: Implementation for in-memory Virtual Container Node class. // // Classes: VirtualCtrNode (vcn) // // Functions: VirtualCtrNode() // ~VirtualCtrNode() // Init // AppendChildCtr // AppendSisterCtr // AppendFirstChildStm // CreateRoot // CreateRootEx // Create // Open // OpenRoot // OpenRootEx // Close // Commit // Rename // Destroy // Stat // EnumElements // SetElementTimes // SetClass // SetStateBits // MoveElementTo // Revert // CopyTo // AddRefCount // QueryInterface // CreateRootOnCustomILockBytes // OpenRootOnCustomILockBytes // // NOTE: All above functions are public // // History: DeanE 21-Mar-96 Created // Narindk 24-Apr-96 Added more functions // SCousens 2-Feb-97 Added Open/CreateRoot for NSS files //-------------------------------------------------------------------------- #include #pragma hdrstop // Debug object declaration // DH_DECLARE; //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::VirtualCtrNode, public // // Synopsis: Constructor. // // Arguments: None. // // Returns: Nothing. // // History: DeanE 21-Mar-96 Created //--------------------------------------------------------------------------- VirtualCtrNode::VirtualCtrNode() : _pvcnChild(NULL), _pvcnSister(NULL), _pvcnParent(NULL), _pvsnStream(NULL), _cStreams(0), _ptszName(NULL), _cChildren(0), _dwCRC(CRC_PRECONDITION), _pstg(NULL) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::VirtualCtrNode")); } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::~VirtualCtrNode, public // // Synopsis: Destructor. Frees resources associated with this object, // including closing the storage if open and removing this // tree from memory. // // Arguments: None. // // Returns: Nothing. // // History: DeanE 21-Mar-96 Created //--------------------------------------------------------------------------- VirtualCtrNode::~VirtualCtrNode() { ULONG ulRef = 0; DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::~VirtualCtrNode")); if(NULL != _ptszName) { delete _ptszName; _ptszName = NULL; } if ( NULL != _pstg ) { ulRef = _pstg->Release(); // Assert if ulRef is not zero, object is being destructed. DH_ASSERT(0 == ulRef); _pstg = NULL; } } //+-------------------------------------------------------------------------- // Member: VirtualStmNode::Init, public // // Synopsis: Initializes a storage node - does not open or create the // actual storage. // // Arguments: [tszName] - Name of this storage // [cStg] - Number of storages contained in this storage. // [cStm] - Number of streams contained in this storage. // // Returns: S_OK if node initialized successfully, otherwise an error. // // Notes: BUGBUG - Not Nashville Safe... // // History: Narindk 18-Apr-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Init( LPTSTR tszName, ULONG cStg, ULONG cStm) { HRESULT hr = S_OK; DH_VDATESTRINGPTR(tszName); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Init")); DH_ASSERT(NULL != tszName); if( S_OK == hr) { _ptszName = new TCHAR[_tcslen(tszName)+1]; if (_ptszName == NULL) { hr = E_OUTOFMEMORY; } else { _tcscpy(_ptszName, tszName); _cChildren = cStg; _cStreams = cStm; } } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::AppendChildCtr, public // // Synopsis: Appends the node passed to the end of this nodes' child // node chain. // // Arguments: [pcnNew] - The new node to append. // // Returns: S_OK for success or an error code. // // History: 17-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::AppendChildCtr(VirtualCtrNode *pvcnNew) { HRESULT hr = S_OK; VirtualCtrNode *pvcnTrav = this; DH_VDATEPTRIN(pvcnNew, VirtualCtrNode); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AppendChildCtr")); DH_ASSERT(NULL != pvcnNew); if(S_OK == hr) { // Find the last child in the structure while (NULL != pvcnTrav->_pvcnChild) { pvcnTrav = pvcnTrav->_pvcnChild; } // Append the new node as a child of the last node, // and make the new node point to the last node as it's parent pvcnTrav->_pvcnChild = pvcnNew; pvcnNew->_pvcnParent = pvcnTrav; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::AppendSisterCtr, public // // Synopsis: Appends the node passed to the end of this nodes' sister // node chain. // // Arguments: [pcnNew] - The new node to append. // // Returns: S_OK for success or an error code. // // History: 17-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::AppendSisterCtr(VirtualCtrNode *pvcnNew) { HRESULT hr = S_OK; VirtualCtrNode *pvcnTrav = this; DH_VDATEPTRIN(pvcnNew, VirtualCtrNode); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AppendSisterCtr")); DH_ASSERT(NULL != pvcnNew); if(S_OK == hr) { // Find the last sister in the chain while (NULL != pvcnTrav->_pvcnSister) { pvcnTrav = pvcnTrav->_pvcnSister; } // Append the new node as a sister of the last node, // and make the new node point to this nodes parent as it's parent pvcnTrav->_pvcnSister = pvcnNew; pvcnNew->_pvcnParent = pvcnTrav->_pvcnParent; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::AppendFirstChildStm, public // // Synopsis: Appends the first stream to its parent storage // // Arguments: [pcnNew] - The new node to append. // // Returns: S_OK for success or an error code. // // History: 17-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::AppendFirstChildStm(VirtualStmNode *pvsnNew) { HRESULT hr = S_OK; VirtualCtrNode *pvcnCurrent= this; DH_VDATEPTRIN(pvsnNew, VirtualStmNode); DH_FUNCENTRY(&hr,DH_LVL_DFLIB,TEXT("VirtualCtrNode::AppendFirstChildStm")); DH_ASSERT(NULL != pvsnNew); if(S_OK == hr) { // Append the new stream node (first stream node) to parent storage, // and make the new stream node point to storage as it's parent pvcnCurrent->_pvsnStream = pvsnNew; pvsnNew->_pvcnParent = pvcnCurrent; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::CreateRoot, public // // Synopsis: Wrapper for StgCreateDocFile that will create a new root // compound file in the file system. // // Arguments: [grfmode] - Access mode for opening new compound file. // [dwReserved] - Reserved by OLE for future use, must be zero. // // Returns: S_OK for success or an error code. // // History: 18-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::CreateRoot(DWORD grfMode, DWORD dwReserved, DSKSTG DiskStgType) { HRESULT hr = S_OK; LPOLESTR pOleStrTemp = NULL; DH_ASSERT(0 == dwReserved); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CreateRoot")); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = StgCreateDocfile(pOleStrTemp, grfMode, dwReserved, &_pstg); DH_HRCHECK(hr, TEXT("StgCreateDocFile")) ; DH_TRACE ((DH_LVL_DFLIB, TEXT("StgCreateRootStorage:%s"), _ptszName)); if (S_OK == hr) { if(!StorageIsFlat()) DH_LOG ((LOG_INFO, TEXT("Created docfile:%s"), _ptszName)); else DH_LOG ((LOG_INFO, TEXT("Created flatfile:%s"), _ptszName)); } } // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::CreateRootEx, public (overload) // // Synopsis: Wrapper for StgCreateDocFileEx that will create a new root // compound file in the file system. // // Arguments: [grfMode] - Access mode for opening new compound file. // [stgfmt] - Storage Format - enum. // [grfAttrs] - Attributes (zero for now) // [pStgOptions] - STGOPTIONS. // [pTransaction]- Reserved by OLE for future use, must be zero. // [riid] - should be IID_IStorage to get an IStorage // // Returns: S_OK for success or an error code. // // History: 28-Jan-97 SCousens Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::CreateRootEx(DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS *pStgOptions, PVOID pTransaction, REFIID riid) { HRESULT hr = S_OK; LPOLESTR pOleStrTemp = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CreateRoot")); DH_ASSERT(0 == stgfmt); // want value of 0 DH_ASSERT(0 == grfAttrs); // want 0 DH_ASSERT(NULL == pStgOptions); // want value of NULL for wrapper DH_ASSERT(NULL == pTransaction); DH_ASSERT(IsEqualIID (IID_IStorage, riid)); // want IStorages. may change if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = StgCreateStorageEx (pOleStrTemp, grfMode, stgfmt, grfAttrs, pStgOptions, pTransaction, riid, (void**)&_pstg); DH_HRCHECK(hr, TEXT("StgCreateDocFileEx")) ; DH_TRACE ((DH_LVL_DFLIB, TEXT("StgCreateRootStorageEx:%s"), _ptszName)); if (S_OK == hr) { DH_LOG ((LOG_INFO, TEXT("Created docfile:%s"), _ptszName)); } } // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Create, public // // Synopsis: Wrapper for IStorage::CreateStorage that will create and // open a new IStorage object within this storage object. // // Arguments: [grfmode] - Access mode for creating & opening new storage // object. // [dwReserved1] - Reserved by OLE for future use, must be zero. // [dwReserved2] - Reserved by OLE for future use, must be zero. // // Returns: S_OK for success or an error code. // // History: 18-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Create( DWORD grfMode, DWORD dwReserved1, DWORD dwReserved2) { HRESULT hr = S_OK; LPSTORAGE pstg = NULL; LPOLESTR pOleStrTemp = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Create")); DH_ASSERT(0 == dwReserved1); DH_ASSERT(0 == dwReserved2); DH_ASSERT(NULL != _pvcnParent); DH_ASSERT(NULL != _pvcnParent->_pstg); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = _pvcnParent->_pstg->CreateStorage( pOleStrTemp, grfMode, dwReserved1, dwReserved2, &_pstg); DH_HRCHECK(hr, TEXT("IStorage::CreateStorage")) ; DH_TRACE ((DH_LVL_DFLIB, TEXT("CreateStorage:%s"), _ptszName)); } // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Open, public // // Synopsis: Wrapper for IStorage::OpenStorage that will open the named // IStorage object within this storage object. // // Arguments: [grfmode] - Access mode for opening the storage object. // [dwReserved] - Reserved by OLE for future use, must be zero. // // Returns: S_OK for success or an error code. // // History: 24-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Open( LPSTORAGE pstgPriority, DWORD grfmode, SNB snbExclude, DWORD dwReserved) { HRESULT hr = S_OK; LPOLESTR pOleStrTemp = NULL; LPSTORAGE pstg = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Open")); DH_ASSERT(0 == dwReserved); // Check if it is root storage, if it is, then call OpenRoot and // return here else proceed. if(NULL == this->_pvcnParent) { DH_LOG ((LOG_INFO, TEXT("Test called Open to open root storage. Calling OpenRoot."))); hr = this->OpenRoot (pstgPriority, grfmode, snbExclude, dwReserved); DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRoot")); return hr; } DH_ASSERT(NULL != _pvcnParent->_pstg); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } // Open the storage. if(S_OK == hr) { hr = _pvcnParent->_pstg->OpenStorage( pOleStrTemp, pstgPriority, grfmode, snbExclude, dwReserved, &pstg); DH_HRCHECK(hr, TEXT("IStorage::OpenStorage")); DH_TRACE ((DH_LVL_DFLIB, TEXT("OpenStorage:%s"), _ptszName)); } // Save it if function succeeds if _pstg is NULL. if((S_OK == hr) && (NULL == _pstg)) { _pstg = pstg; } DH_HRCHECK(hr, TEXT("VirtualCtrNode::Open")); // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return(hr); } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::OpenRoot, public // // Synopsis: Wrapper for IStorage::OpenStorage that will open the named // IStorage object within this storage object. // // Arguments: [grfmode] - Access mode for creating & opening new storage // object. // [dwReserved1] - Reserved by OLE for future use, must be zero. // [dwReserved2] - Reserved by OLE for future use, must be zero. // // Returns: S_OK for success or an error code. // // History: 24-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::OpenRoot( LPSTORAGE pstgPriority, DWORD grfmode, SNB snbExclude, DWORD dwReserved, DSKSTG DiskStgType) { HRESULT hr = S_OK; IStorage *pstg = NULL; LPOLESTR pOleStrTemp = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::OpenRoot")); DH_ASSERT(0 == dwReserved); // Make sure this is the Root. DH_ASSERT(NULL == this->_pvcnParent); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } // Open the root storage if(S_OK == hr) { #if (WINVER<0x500) //NT5 is lockviolation fixed DG_INTEGER dgi(0); ULONG ulRandNum = 0; USHORT usErr = 0; int i = 0; // Try opening the docfile // StgOpenStorage returns STG_E_LOCKVIOLATION is concurrent API calls // are made, so this is the hack for workaround the problem. // BUGBUG : Remove this loop once the feature is implemented in OLE. // BUGBUG : ntbug#114779 Affects DCOM95 only. ntbug#41249 fixed for(i=0; i_pvcnParent); DH_ASSERT(0 == stgfmt); // want value of 0 DH_ASSERT(0 == grfAttrs); // want 0 DH_ASSERT(NULL == pStgOptions); // want value of NULL DH_ASSERT(NULL == pTransaction); DH_ASSERT(IsEqualIID (IID_IStorage, riid)); // want IStorages. may change if (S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } // Open the root storage if (S_OK == hr) { DG_INTEGER dgi(0); ULONG ulRandNum = 0; USHORT usErr = 0; int i = 0; // Try opening the docfile // StgOpenStorage returns STG_E_LOCKVIOLATION is concurrent API calls // are made, so this is the hack for workaround the problem. // BUGBUG : Remove this loop once the feature is implemented in OLE. for(i=0; iRelease(); } else { DH_ASSERT(!TEXT("_pStg is already NULL!")); } DH_HRCHECK(hr, TEXT("VirtualCtrNode::Close")); if(0 == ulRef) { _pstg = NULL; } return(hr); } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Commit, public // // Synopsis: Wrapper for IStorage::Commit that will commit any changes // made to an IStorage object since it was opened or last // committed to persistent storage. // // Arguments: [grfCommitFlags] - Controls how object is committed to IStorage. // // Returns: S_OK Commit operation was successful. // STG_E_NOTCURRENT Another opening of storage object has commi // tted changes, possibility of overwriting. // STG_E_MEDIUMFULL No space left on device to commit. // STG_E_TOOMANYOPENFILES too many open files. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // STG_E_INVALIDFLAG Invalid flag. // STG_E_INVALIDPARAMETER Inalid parameter // // History: 29-Apr-96 NarindK Created // 12-Mar-97 MikeW Removed HRCHECK after Commit //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Commit(DWORD grfCommitFlags) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Commit")); DH_ASSERT(NULL != _pstg); if ( S_OK == hr ) { hr = _pstg->Commit(grfCommitFlags); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Rename, public // // Synopsis: Wrapper for IStorage::RenameElement that renames an element // contained in an Storage object subject to transaction state // of IStorage object. // // Arguments: [pptcsNewName] - Points to pointer to new name for the element. // // Returns: S_OK Object was successfully renamed. // STG_E_ACCESSDENIED Named element ptcsNewName alreadys exists. // STG_E_FILENOTFOUND Element couldn't be found. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDNAME Invalid name. // STG_E_INVALIDPARAMETER Invalid parameter // STG_E_TOOMANYOPENFILES too many open files. // // History: 29-Apr-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Rename(LPCTSTR ptcsNewName) { HRESULT hr = S_OK; LPOLESTR pOleStrOld = NULL; LPOLESTR pOleStrNew = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Rename")); DH_VDATESTRINGPTR(ptcsNewName); DH_ASSERT(NULL != _pvcnParent); DH_ASSERT(NULL != _pvcnParent->_pstg); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrOld); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { // Convert ptcsNewName to OLECHAR hr = TStringToOleString((LPTSTR)ptcsNewName, &pOleStrNew); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = _pvcnParent->_pstg->RenameElement(pOleStrOld, pOleStrNew); DH_HRCHECK(hr, TEXT("IStorage::Rename")) ; } if(S_OK == hr) { // Change the name of VirtualCtrNode i.e. its _ptszName variable also // First delete the old name if(NULL != _ptszName) { delete _ptszName; _ptszName = NULL; } // Now copy the new name by allocating enough memory _ptszName = new TCHAR[_tcslen(ptcsNewName)+1]; if (_ptszName == NULL) { hr = E_OUTOFMEMORY; } else { _tcscpy(_ptszName, ptcsNewName); } } // Clean up if(NULL != pOleStrOld) { delete pOleStrOld; pOleStrOld = NULL; } if(NULL != pOleStrNew) { delete pOleStrNew; pOleStrNew = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Destroy, public // // Synopsis: Wrapper for IStorage::DestroyElement that removes an element // storage from this storage, subject to transaction mode in // which it was opened. The wrapper for IStorage::DestroyElement // that destorys a stream element from this storage is in // VirtualStmNode::Destroy. // // Arguments: None // // Returns: S_OK Object was successfully renamed. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_FILENOTFOUND Element couldn't be found. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // STG_E_INSUFFICIENTMEMORY Not enough memory to rename element. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDNAME Invalid name. // STG_E_INVALIDPARAMETER Invalid parameter // STG_E_TOOMANYOPENFILES too many open files. // // History: 29-Apr-96 NarindK Created // // Notes: The existing open instance of this element from this parent // instance becomes invalid after this function is called. // // Use DestroyStorage in the util.cxx which is a wrapper to call // this function and also readjusts the VirtualDF tree. //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Destroy() { HRESULT hr = S_OK; LPSTORAGE pstg = NULL; LPOLESTR pOleStrTemp = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Destroy")); DH_ASSERT(NULL != _pvcnParent); DH_ASSERT(NULL != _pvcnParent->_pstg); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = _pvcnParent->_pstg->DestroyElement(pOleStrTemp); DH_HRCHECK(hr, TEXT("IStorage::DestroyElement")) ; } // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Stat, public // // Synopsis: Returns relevant statistics concerning this open storage. // // Arguments: [pStatStg] - pointer to STATSTG structure. // [grfStatFlag] - Controls levels of returned statistics. // // Returns: S_OK Statistics were successfully returned. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // STG_E_INSUFFICIENTMEMORY Not enough memory. // STG_E_INVALIDPOINTER Invalid pointer. // // History: NarindK 8-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Stat( STATSTG *pStatStg, DWORD grfStatFlag) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Stat")); DH_ASSERT(_pstg != NULL); DH_ASSERT(NULL != pStatStg); DH_ASSERT(( (grfStatFlag == STATFLAG_DEFAULT) || (grfStatFlag == STATFLAG_NONAME))); if(S_OK == hr) { hr = _pstg->Stat(pStatStg, grfStatFlag); DH_HRCHECK(hr, TEXT("IStorage::Stat")); } // BUGBUG: May remove to need DH_ assert macros to do invalid parameter // checking. return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::EnumElements, public // // Synopsis: Enumerates the elements immediately contained within this // storage object. // // Arguments: [dwReserved1] - Reserved by OLE // [dwReserved2] - Reserved by OLE // [dwReserved3] - Reserved by OLE // [ppenumStatStg] - Points to where to return enumerator, NULL // if an error. // // Returns: S_OK Enumeration successful. // STG_E_INSUFFICIENTMEMORY Not enough memory. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDPARAMETER Invalid parameter. // E_OUTOFMEMORY Not enough memory. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // // History: NarindK 10-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::EnumElements( DWORD dwReserved1, PVOID pReserved2, DWORD dwReserved3, LPENUMSTATSTG *ppenumStatStg) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::EnumElements")); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { hr = _pstg->EnumElements( dwReserved1, pReserved2, dwReserved3, ppenumStatStg); DH_HRCHECK(hr, TEXT("IStorage::EnumElements")); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::SetElementTimes, public // // Synopsis: Sets the modification, access, and creation times of the // indicated element of this storage object. // // Arguments: [lpszName] - Points to name of element to change // [pctime] - Points to new creation time // [patime] - Points to new access time // [pmtime] - Points to new modification time // // Returns: S_OK Time values successfully set. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_FILENOTFOUND Element not found. // STG_E_FILEALREADYEXITS Specified file already exists. // STG_E_TOOMANYOPENFILES too many open files // STG_E_INSUFFICIENTMEMORY Not enough memory. // STG_E_INVALIDNAME Invalid name. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDPARAMETER Invalid parameter. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // // History: NarindK 10-May-96 Created // // Notes: Ole implemntation doesn't support setting time on stream elem // so no function corresponding to VirtualStmNode for this. // //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::SetElementTimes( FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime) { HRESULT hr = S_OK; LPOLESTR pOleStrTemp = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetElementTimes")); DH_ASSERT(NULL != _pvcnParent); DH_ASSERT(NULL != _pvcnParent->_pstg); if(S_OK == hr) { // Convert _ptszName to OLECHAR hr = TStringToOleString(_ptszName, &pOleStrTemp); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = _pvcnParent->_pstg->SetElementTimes( pOleStrTemp, pctime, patime, pmtime); DH_HRCHECK(hr, TEXT("IStorage::SetElementTimes")); } // Clean up if(NULL != pOleStrTemp) { delete pOleStrTemp; pOleStrTemp = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::SetClass, public // // Synopsis: Persistently stores the object's CLSID. // // Arguments: [rclsid] - Specifies CLSID to be associated with this storage. // // Returns: S_OK CLSID successfully stored. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // STG_E_MEDIUMFULL Not enough space on device. // // History: NarindK 9-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::SetClass(REFCLSID rclsid) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetClass")); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { hr = _pstg->SetClass(rclsid); DH_HRCHECK(hr, TEXT("IStorage::SetClass")); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::SetStateBits, public // // Synopsis: Stores upto 32 bits of state information in this IStorage. // // Arguments: [grfStateBits] - New values of bits to be set // [grfMask] - Binary mask to indicate significant bits. // // Returns: S_OK State successfully set. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_INVALIDPARAMETER Invalid parameter // STG_E_INVALIDFLAG Invalid flag in grfStateBits or grfMask // // History: NarindK 9-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::SetStateBits( DWORD grfStateBits, DWORD grfMask) { HRESULT hr = S_OK; LPSTORAGE pstg = NULL; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::SetStateBits")); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { hr = _pstg->SetStateBits(grfStateBits, grfMask); DH_HRCHECK(hr, TEXT("IStorage::SetStateBits")); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::MoveElementTo, public // // Synopsis: Moves an IStorage/IStream element to indicated new destination // container. // // Arguments: [ptszName] - Name of child IStorage/IStream present in this // this _pstg to be moved // [pvcnDest] - Pointer to destination virtual container // [lpszNewname] - Points to new name to element in its new // container // [grfFlags] - Specifies if to move as move or copy // // Returns: S_OK Storage moved successfully. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_FILENOTFOUND Element not found. // STG_E_FILEALREADYEXITS Specified file already exists. // STG_E_TOOMANYOPENFILES too many open files // STG_E_INSUFFICIENTMEMORY Not enough memory. // STG_E_INVALIDNAME Invalid name. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDPARAMETER Invalid parameter // STG_E_INVALIDFLAG Invalid flag in grfFlags // STG_E_REVERTED Object invalidated by a revert operation // above it in transaction tree. // // History: NarindK 13-May-96 Created // // Notes: This moves a child storage/stream with name ptszName in present // storage _pstg to a destination storage. Make sure that the // child storage/stream to be moved is closed and the destination // storage is open. // The VirtualDF tree needs to be readjusted after this call. // Different methods of VirtualDF may need to be called as the // case may be - AdjustTreeOnStgMoveElement, AdjustTreeOnStmMove // Element, AdjustTreeOnStgCopyElement, AdjustTreeOnStmCopyElement //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::MoveElementTo( LPCTSTR ptszName, VirtualCtrNode *pvcnDest, LPCTSTR ptszNewName, DWORD grfFlags) { HRESULT hr = S_OK; LPOLESTR pOleStrOld = NULL; LPOLESTR pOleStrNew = NULL; DH_VDATESTRINGPTR(ptszName); DH_VDATESTRINGPTR(ptszNewName); DH_VDATEPTRIN(pvcnDest, VirtualCtrNode); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::MoveElementTo")); DH_ASSERT(_pstg != NULL); DH_ASSERT(NULL != pvcnDest); DH_ASSERT(pvcnDest->_pstg != NULL); DH_ASSERT(NULL != ptszName); DH_ASSERT(NULL != ptszNewName); DH_ASSERT((grfFlags == STGMOVE_COPY) || (grfFlags == STGMOVE_MOVE)); if(S_OK == hr) { // Convert ptszName to OLECHAR hr = TStringToOleString((LPTSTR)ptszName, &pOleStrOld); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { // Convert ptszNewName to OLECHAR hr = TStringToOleString((LPTSTR)ptszNewName, &pOleStrNew); DH_HRCHECK(hr, TEXT("TStringToOleString")) ; } if(S_OK == hr) { hr = _pstg->MoveElementTo( pOleStrOld, pvcnDest->_pstg, pOleStrNew, grfFlags); DH_HRCHECK(hr, TEXT("IStorage::MoveElementTo")); } // Clean up if(NULL != pOleStrOld) { delete pOleStrOld; pOleStrOld = NULL; } if(NULL != pOleStrNew) { delete pOleStrNew; pOleStrNew = NULL; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::Revert, public // // Synopsis: Discards all changes made in or made visible to thsi storage // object since it was opened or last committed. // // Arguments: none // // Returns: HRESULT // S_OK Revert operation successful. // STG_E_INSUFFICIENTMEMORY Out of memory. // STG_E_TOOMANYOPENFILES Too many open files. // STG_E_REVERTED Object has been invalidated by a revert // operation above it in transaction tree. // // History: NarindK 20-May-96 Created // // Notes: //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::Revert() { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::Revert")); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { hr = _pstg->Revert(); DH_HRCHECK(hr, TEXT("VirtualCtrNode::Revert")); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::CopyTo, public // // Synopsis: Copies an IStorage element to indicated new destination // container. // // Arguments: [ciidExclude] - Speciefies number of elements in array pointed // to by rgiidExclude. // [rgiidExclude]- Specifies an array of interface identifiers the // caller takes responsibility of moving from // source to destination. // [snbExclude] - Points to a bloack of named elements not to // to be copied into destination container. // [pvcnDest]- Points to the open storage object where this // open storage object is copied. // // Returns: S_OK Storage copied successfully. // STG_E_ACCESSDENIED insufficient permissions. // STG_E_TOOMANYOPENFILES too many open files // STG_E_INSUFFICIENTMEMORY Not enough memory. // STG_E_INVALIDPOINTER Invalid pointer. // STG_E_INVALIDPARAMETER Invalid parameter // STG_E_MEDIUMFULL Storage medium is full // STG_E_DESTLACKSINTERFACE Destination lacks an interface of the // source object to be copied. // // History: NarindK 20-May-96 Created // // Notes: This copies contents of storage _pstg to a destination storage. // The storage to be copied from and the destination storage to // be copied into is open. // VirtualDF tree needs to be readjusted after this call. Virtual // DF's AdjustTreeOnCopyTo may be used. //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::CopyTo( DWORD ciidExclude, IID const* rgiidExclude, SNB snbExclude, VirtualCtrNode *pvcnDest) { HRESULT hr = S_OK; DH_VDATEPTRIN(pvcnDest, VirtualCtrNode); DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CopyTo")); DH_ASSERT(NULL != _pstg); DH_ASSERT(NULL != pvcnDest); DH_ASSERT(NULL != pvcnDest->_pstg); if(S_OK == hr) { hr = _pstg->CopyTo( ciidExclude, rgiidExclude, snbExclude, pvcnDest->_pstg); DH_HRCHECK(hr, TEXT("IStorage::CopyTo")); } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::AddRefCount, public // // Synopsis: Increments the reference count on IStorage object. // // Arguments: none // // Returns: HRESULT // // History: NarindK 21-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::AddRefCount() { HRESULT hr = S_OK; ULONG ulTmp = 0; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::AddRefCount")); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { ulTmp = _pstg->AddRef(); } DH_HRCHECK(hr, TEXT("VirtualCtrNode::AddRefCount")); return(hr); } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::QueryInterface, public // // Synopsis: Returns pointers to supported objects. // // Arguments: none // // Returns: HRESULT // // History: NarindK 21-May-96 Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::QueryInterface( REFIID riid, LPVOID *ppvObj) { HRESULT hr = S_OK; LPSTORAGE pstg = NULL; DH_VDATEPTROUT(ppvObj, IUnknown *) ; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::QueryInterface")); DH_ASSERT(ppvObj != NULL); DH_ASSERT(_pstg != NULL); if(S_OK == hr) { // Initilze the out parameter *ppvObj = NULL; hr = _pstg->QueryInterface(riid, ppvObj); } DH_HRCHECK(hr, TEXT("VirtualCtrNode::QueryInterface")); if(S_OK == hr) { DH_ASSERT(NULL != *ppvObj); } else { DH_ASSERT(NULL == *ppvObj); } return(hr); } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::CreateRootOnCustomILockBytes,public // // Synopsis: Wrapper for StgCreateDocFileOnILockBytes that will create a new // root compound file in the file system based on custom ILockBytes // // Arguments: [grfmode] - Access mode for creating new compound file. // [pILockBytes] - Pointer to ILockBytes // // Returns: S_OK for success or an error code. // // History: 1-Aug-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::CreateRootOnCustomILockBytes( DWORD grfMode, ILockBytes *pILockBytes) { HRESULT hr = S_OK; DH_FUNCENTRY( &hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::CreateRootOnCustomILockBytes")); if(S_OK == hr) { hr = StgCreateDocfileOnILockBytes( pILockBytes, grfMode, 0, &_pstg); DH_HRCHECK(hr, TEXT("StgCreateDocFileOnLockBytes")) ; } return hr; } //+-------------------------------------------------------------------------- // Member: VirtualCtrNode::OpenRootOnCustomILockBytes, public // // Synopsis: Wrapper for StgOpenStorageOnILockBytes that will open the named // IStorage root object on custom ILOckBytes provided. // // Arguments: [pstgPrioirty] - Points to previous opening of root stg // [grfmode] - Access mode for creating & opening new storage // object. // [snbExclude] - Points to a block of named elements not to // to be excluded in open call. // [dwReserved] - Reserved by OLE for future use, must be zero. // [pILockBytes] - Pointer to ILockBytes // // Returns: S_OK for success or an error code. // // History: 3-Aug-96 NarindK Created //--------------------------------------------------------------------------- HRESULT VirtualCtrNode::OpenRootOnCustomILockBytes( LPSTORAGE pstgPriority, DWORD grfmode, SNB snbExclude, DWORD dwReserved, ILockBytes *pILockBytes) { HRESULT hr = S_OK; IStorage *pstg = NULL; DH_FUNCENTRY( &hr, DH_LVL_DFLIB, _TEXT("VirtualCtrNode::OpenRootOnCustomILockBytes")); // Make sure this is the Root. DH_ASSERT(NULL == this->_pvcnParent); // Open the root storage if(S_OK == hr) { hr = StgOpenStorageOnILockBytes( pILockBytes, pstgPriority, grfmode, snbExclude, dwReserved, &pstg); DH_HRCHECK(hr, TEXT("StgOpenStorage")); } if((S_OK == hr) && (NULL == _pstg)) { _pstg = pstg; } DH_HRCHECK(hr, TEXT("VirtualCtrNode::OpenRootOnCustomILockBytes")); return(hr); }