//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000 - 2000 // // File: snapinpersistence.cpp // // Contents: // // Classes: CComponentPersistor, CDPersistor // //____________________________________________________________________________ #include "stdafx.h" #include "mtnode.h" #include "regutil.h" /*+-------------------------------------------------------------------------* * * struct less_component * * PURPOSE: implements viewID and CLSID based comparison for CComponent* pointers * This allows to sort components before pesisting *+-------------------------------------------------------------------------*/ struct less_component // define the struct to perform the comparison { typedef std::pair comp_type; bool operator ()(const comp_type& arg1, const comp_type& arg2) const { return arg1.first != arg2.first ? arg1.first < arg2.first : arg1.second->GetCLSID() < arg2.second->GetCLSID(); } }; /*+-------------------------------------------------------------------------* * * struct less_compdata * * PURPOSE: implements CLSID based comparison for CComponentData* pointers * This allows to sort component data before pesisting *+-------------------------------------------------------------------------*/ struct less_compdata // define the struct to perform the comparison { bool operator ()(const CComponentData* pCD1, const CComponentData* pCD2) const { return pCD1->GetCLSID() < pCD2->GetCLSID(); } }; /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage * * PURPOSE: gets CXML_IStorage for snapin. creates & inits one there is none * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * CXML_IStorage *& pXMLStorage [out] xml storage for the snapin * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage(int idView, const CLSID& clsid, CXML_IStorage *& pXMLStorage) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage")); // init out parameter pXMLStorage = NULL; // try to find it first bool bFound = false; sc = ScFindXmlStorage( idView, clsid, bFound, pXMLStorage ); if (sc) return sc; if (bFound) { // recheck sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc; // return the ponter we found return sc; } // insert the new one typedef std::map col_t; col_t::iterator it = m_XMLStorage.insert(col_t::value_type( key_t( idView, clsid ), CXML_IStorage())).first; pXMLStorage = &it->second; // recheck sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScFindXmlStorage * * PURPOSE: Finds the storage. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] whether data was found * CXML_IStorage *& pXMLStorage [out] pointer to found data * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages:: ScFindXmlStorage(int idView, const CLSID& clsid, bool& bFound, CXML_IStorage *& pXMLStorage) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScFindXmlStorage")); // init out parameters bFound = false; pXMLStorage = NULL; typedef std::map col_t; col_t::iterator it = m_XMLStorage.find( key_t( idView, clsid ) ); // give a try to find it by the hash value if ( it == m_XMLStorage.end() ) { bool bFoundInHash = false; sc = ScCheckForStreamsAndStoragesByHashValue( idView, clsid, bFoundInHash ); if (sc) return sc; if ( !bFoundInHash ) // if not found - return return sc; // try again - it may be in the map by now it = m_XMLStorage.find( key_t( idView, clsid ) ); if ( it == m_XMLStorage.end() ) // if still not found - return return sc; } // found! bFound = true; pXMLStorage = &it->second; #ifdef DBG // set the snapin name to identify the problems in debug tstring strSnapin; GetSnapinNameFromCLSID( clsid, strSnapin ); pXMLStorage->m_dbg_Data.SetTraceInfo(TraceSnapinPersistenceError, true, strSnapin); #endif // #ifdef DBG return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScFindXmlStream * * PURPOSE: Finds the stream. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] whether data was found * CXML_IStream *& pXMLStream [out] pointer to found data * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages:: ScFindXmlStream(int idView, const CLSID& clsid, bool& bFound, CXML_IStream *& pXMLStream) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScFindXmlStream")); // init out parameters bFound = false; pXMLStream = NULL; typedef std::map col_t; col_t::iterator it = m_XMLStream.find( key_t( idView, clsid ) ); // give a try to find it by the hash value if ( it == m_XMLStream.end() ) { bool bFoundInHash = false; sc = ScCheckForStreamsAndStoragesByHashValue( idView, clsid, bFoundInHash ); if (sc) return sc; if ( !bFoundInHash ) // if not found - return return sc; // try again - it may be in the map by now it = m_XMLStream.find( key_t( idView, clsid ) ); if ( it == m_XMLStream.end() ) // if still not found - return return sc; } // found! bFound = true; pXMLStream = &it->second; #ifdef DBG // set the snapin name to identify the problems in debug tstring strSnapin; GetSnapinNameFromCLSID( clsid, strSnapin ); pXMLStream->m_dbg_Data.SetTraceInfo(TraceSnapinPersistenceError, true, strSnapin); #endif // #ifdef DBG return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetXmlStream * * PURPOSE: * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * CXML_IStream *& pXMLStream [out] xml stream for the snapin * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetXmlStream(int idView, const CLSID& clsid, CXML_IStream *& pXMLStream) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetXmlStream")); // init out parameter pXMLStream = NULL; // try to find it first bool bFound = false; sc = ScFindXmlStream( idView, clsid, bFound, pXMLStream ); if (sc) return sc; if (bFound) { // recheck sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc; // return the ponter we found return sc; } // insert the new one typedef std::map col_t; col_t::iterator it = m_XMLStream.insert(col_t::value_type( key_t( idView, clsid ), CXML_IStream())).first; pXMLStream = &it->second; // recheck sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScInitIStorage * * PURPOSE: Initializes IStorage from the given source data * * PARAMETERS: * int idView [in] view number * LPCWSTR szHash [in] hash key (name of storage element) identifying the snapin * IStorage *pSource [in] source data for initialization * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScInitIStorage( int idView, LPCWSTR szHash, IStorage *pSource ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScInitIStorage")); // parameter check; sc = ScCheckPointers( pSource ); if (sc) return sc; // insert the new one typedef std::map col_t; col_t::iterator it = m_StorageByHash.insert( col_t::value_type(hash_t(idView, szHash), CXML_IStorage())).first; CXML_IStorage *pXMLStorage = &it->second; // recheck the pointer sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc; sc = pXMLStorage->ScInitializeFrom( pSource ); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScInitIStream * * PURPOSE: Initializes IStream from the given source data * * PARAMETERS: * int idView [in] view number * LPCWSTR szHash [in] hash key (name of storage element) identifying the snapin * IStream *pSource [in] source data for initialization * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScInitIStream ( int idView, LPCWSTR szHash, IStream *pSource ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScInitIStream")); // parameter check; sc = ScCheckPointers( pSource ); if (sc) return sc; // insert the new one typedef std::map col_t; col_t::iterator it = m_StreamByHash.insert( col_t::value_type(hash_t(idView, szHash), CXML_IStream())).first; CXML_IStream *pXMLStream = &it->second; // recheck the pointer sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc; sc = pXMLStream->ScInitializeFrom( pSource ); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetIStorage * * PURPOSE: returns existing or creates a new IStorage for the component * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * IStorage **ppStorage [out] - storage for the component * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetIStorage( int idView, const CLSID& clsid, IStorage **ppStorage ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetIStorage")); // paramter check sc = ScCheckPointers( ppStorage ); if (sc) return sc; // init an out parameter *ppStorage = NULL; CXML_IStorage *pXMLStorage = NULL; sc = ScGetXmlStorage( idView, clsid, pXMLStorage ); if (sc) return sc; // recheck the pointer sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc; // get the interface sc = pXMLStorage->ScGetIStorage(ppStorage); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetIStream * * PURPOSE: returns existing or creates a new IStream for the component * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * IStream **ppStream [out] - stream fro the component * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetIStream ( int idView, const CLSID& clsid, IStream **ppStream ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetIStream")); // paramter check sc = ScCheckPointers( ppStream ); if (sc) return sc; // init an out parameter *ppStream = NULL; CXML_IStream *pXMLStream = NULL; sc = ScGetXmlStream( idView, clsid, pXMLStream ); if (sc) return sc; // recheck the pointer sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc; // get the interface sc = pXMLStream->ScGetIStream(ppStream); if (sc) return sc; return sc; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::HasStream * * PURPOSE: Checks if snapins stream is available * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * * RETURNS: * bool - true == found * \***************************************************************************/ bool CMTSnapinNodeStreamsAndStorages::HasStream(int idView, const CLSID& clsid) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::HasStream")); bool bFound = false; CXML_IStream * pUnused = NULL; sc = ScFindXmlStream( idView, clsid, bFound, pUnused ); if (sc) return false; // not found if error return bFound; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::HasStorage * * PURPOSE: Checks if snapins storage is available * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * * RETURNS: * bool - true == found * \***************************************************************************/ bool CMTSnapinNodeStreamsAndStorages::HasStorage(int idView, const CLSID& clsid) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::HasStorage")); bool bFound = false; CXML_IStorage * pUnused = NULL; sc = ScFindXmlStorage( idView, clsid, bFound, pUnused ); if (sc) return false; // not found if error return bFound; } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue * * PURPOSE: Looks up streams and storages by a generated hash value. * if the streams/storages are found, they are moved to the * the list of 'recognized' storages - those identified by the CLSID. * This is a required step to recognize the streams and storages retrieved * from a structured storage based console, where they are identified by the * hash value. It is not possible to map from the hash value to the key * in unique way, so the collections of data are kept untill the request * comes and the hash can be mapped by matching with the one generated from * the key supplied by request. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] - true if at least one matching hash value was found * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue( int idView, const CLSID& clsid, bool& bFound ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue")); bFound = false; wchar_t buff[MAX_PATH]; std::wstring strHashValue = CMTNode::GetComponentStreamName( buff, clsid ); // process streams { typedef std::map col_t; col_t::iterator it = m_StreamByHash.begin(); while ( it != m_StreamByHash.end() ) { if ( it->first.second == strHashValue ) { bFound = true; // put to a 'recognized' list int idView = it->first.first; m_XMLStream[key_t(idView, clsid)] = it->second; // for sanity: make sure it is not in the storage map! ASSERT( m_StorageByHash.find(it->first) == m_StorageByHash.end() ); m_StorageByHash.erase( it->first ); // remove from hash table it = m_StreamByHash.erase( it ); } else ++ it; } if ( bFound ) return sc; } // process storages { typedef std::map col_t; col_t::iterator it = m_StorageByHash.begin(); while ( it != m_StorageByHash.end() ) { if ( it->first.second == strHashValue ) { bFound = true; // put to a 'recognized' list int idView = it->first.first; m_XMLStorage[key_t(idView, clsid)] = it->second; // for sanity: make sure it is not in the stream map! ASSERT( m_StreamByHash.find( it->first ) == m_StreamByHash.end() ); m_StreamByHash.erase( it->first ); // remove from hash table it = m_StorageByHash.erase( it ); } else ++it; } } return sc; } /*+-------------------------------------------------------------------------* * * CMTSnapinNodeStreamsAndStorages::RemoveView * * PURPOSE: removes information about one view * * PARAMETERS: * int idView [in] view number * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CMTSnapinNodeStreamsAndStorages::RemoveView(int nViewId) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::RemoveView")); { // remove streams std::map::iterator it_stream; for (it_stream = m_XMLStream.begin();it_stream != m_XMLStream.end();) { if (it_stream->first.first == nViewId) it_stream = m_XMLStream.erase(it_stream); else ++it_stream; } } { // remove storages std::map::iterator it_storage; for (it_storage = m_XMLStorage.begin();it_storage != m_XMLStorage.end();) { if (it_storage->first.first == nViewId) it_storage = m_XMLStorage.erase(it_storage); else ++it_storage; } } { // remove streams by hash std::map::iterator it_stream; for (it_stream = m_StreamByHash.begin();it_stream != m_StreamByHash.end();) { if (it_stream->first.first == nViewId) it_stream = m_StreamByHash.erase(it_stream); else ++it_stream; } } { // remove storages by hash std::map::iterator it_storage; for (it_storage = m_StorageByHash.begin();it_storage != m_StorageByHash.end();) { if (it_storage->first.first == nViewId) it_storage = m_StorageByHash.erase(it_storage); else ++it_storage; } } } /***************************************************************************\ * * METHOD: CMTSnapinNodeStreamsAndStorages::Persist * * PURPOSE: persists stream and storage collections * * PARAMETERS: * CPersistor& persistor [in] peristor for the operation * bool bPersistViewId [in] whether to store view identifier * (ComponentDatas are saved with thi parameter set to false, * since the view id has no meaning for them) * * RETURNS: * SC - result code * \***************************************************************************/ void CMTSnapinNodeStreamsAndStorages::Persist(CPersistor& persistor, bool bPersistViewId) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::Persist")); if (persistor.IsStoring()) { // define iterators for saving std::map::iterator itStorages; std::map::iterator itStreams; std::map::iterator itStoragesByHash; std::map::iterator itStreamsByHash; // init iterators to point to the start of the collections itStorages = m_XMLStorage.begin(); itStreams = m_XMLStream.begin(); itStoragesByHash = m_StorageByHash.begin(); itStreamsByHash = m_StreamByHash.begin(); // we have 4 collections to save here. // while saving them one by one would not change the functionality, // console file is more readable when they are sorted by the snapin's clsid. // following code does not do any explicit sorting, but persist in the // certain order assurring the result is a sorted array of persisted data // These 4 iterators represents 4 lines (queues) of sorted items, so // in order to get the proper result we just need to merge them correctly. // This is done by the following loop which splits the persistence in two steps: // 1. Pick the right line (iterator) to persist it's first item. // 2. Persist the selected item. // There are 4 boolean variables indicating which item to save (only one can be 'true') // thus the second part is strigth-forward - test variables and do the persisting. // The iterator is picked by the following rules. // 1.1 Only lines with items compete. // 1.2 If there are items in lines key'ed by guids (in contrast to hash values) // they are processed first, leaving hash values at the end. // 1.3 If still there are 2 lines competing - their key's are compared and one // with a smaller key is choosen while ( 1 ) { // see what collection has data to save bool bSaveStorage = ( itStorages != m_XMLStorage.end() ); bool bSaveStream = ( itStreams != m_XMLStream.end() ); bool bSaveStorageByHash = ( itStoragesByHash != m_StorageByHash.end() ); bool bSaveStreamByHash = ( itStreamsByHash != m_StreamByHash.end() ); // exit if nothind to tsave - assume we are done if ( !( bSaveStorage || bSaveStream || bSaveStorageByHash || bSaveStreamByHash )) break; // if both main collections are willing to save - let the smaller key win if ( bSaveStorage && bSaveStream ) { bSaveStorage = ( itStorages->first < itStreams->first ); bSaveStream = !bSaveStorage; } // if not done with a main collections - dont save by hash if ( bSaveStorage || bSaveStream ) bSaveStorageByHash = bSaveStreamByHash = false; // if both hash collections are willing to save - let the smaller key win if ( bSaveStorageByHash && bSaveStreamByHash ) { bSaveStorageByHash = ( itStoragesByHash->first < itStreamsByHash->first ); bSaveStreamByHash = !bSaveStorageByHash; } // only variable one can be set ! ASSERT ( 1 == ( (int)bSaveStorage + (int)bSaveStream + (int)bSaveStorageByHash + (int)bSaveStreamByHash) ); // add the tag for snapin entry CPersistor persistorChild(persistor, GetItemXMLType()); // save one winning entry if ( bSaveStorage ) { // persist a key CLSID clsid = itStorages->first.second; int idView = itStorages->first.first; persistorChild.Persist( clsid, XML_NAME_CLSID_SNAPIN ); if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView); // persist data persistorChild.Persist( itStorages->second ); // advance to the next entry ++itStorages; } else if (bSaveStream) { // persist a key CLSID clsid = itStreams->first.second; int idView = itStreams->first.first; persistorChild.Persist( clsid, XML_NAME_CLSID_SNAPIN ); if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView); // persist data persistorChild.Persist( itStreams->second ); // advance to the next entry ++itStreams; } else if ( bSaveStorageByHash ) { // persist a key std::wstring hash = itStoragesByHash->first.second; int idView = itStoragesByHash->first.first; if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView); CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash ); // persist data persistorChild.Persist( itStoragesByHash->second ); // advance to the next entry ++itStoragesByHash; } else if (bSaveStreamByHash) { // persist a key std::wstring hash = itStreamsByHash->first.second; int idView = itStreamsByHash->first.first; if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView); CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash ); // persist data persistorChild.Persist( itStreamsByHash->second ); // advance to the next entry ++itStreamsByHash; } else { ASSERT( false ); // should not come here! break; } } } else { XMLListCollectionBase::Persist(persistor); } } /*+-------------------------------------------------------------------------* * * CMTSnapinNodeStreamsAndStorages::OnNewElement * * PURPOSE: called for each component data found loading XML doc * * PARAMETERS: * CPersistor& persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CMTSnapinNodeStreamsAndStorages::OnNewElement(CPersistor& persistor) { DECLARE_SC(sc, TEXT("CDPersistor::OnNewElement")); // persistor is 'locked' on particular child element, so that // a simple CPersistor constructor can be used to create child's peristor. // Creating the child persistor is also necessary to release that 'lock' CPersistor persistorChild(persistor, GetItemXMLType()); CLSID clsid; std::wstring hash; bool bByHash = false; ZeroMemory(&clsid,sizeof(clsid)); // look how entry is key'ed - by regular key of by a hash value if ( persistorChild.HasElement( XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN ) ) { CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash ); bByHash = true; } else persistorChild.Persist(clsid, XML_NAME_CLSID_SNAPIN); // persist the view id - default to value used to store component data int idView = VIEW_ID_DOCUMENT; persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView, attr_optional); // now we should look what data do we have // and persist if recognized if (persistorChild.HasElement(CXML_IStream::_GetXMLType(),NULL)) { CXML_IStream *pXMLStream = NULL; if (bByHash) { pXMLStream = &m_StreamByHash[ hash_t(idView, hash) ]; } else { sc = ScGetXmlStream( idView, clsid, pXMLStream ); if (sc) sc.Throw(); } sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) sc.Throw(); persistorChild.Persist( *pXMLStream ); } else if (persistorChild.HasElement(CXML_IStorage::_GetXMLType(),NULL)) { CXML_IStorage *pXMLStorage = NULL; if (bByHash) { pXMLStorage = &m_StorageByHash[ hash_t(idView, hash) ]; } else { sc = ScGetXmlStorage( idView, clsid, pXMLStorage ); if (sc) sc.Throw(); } sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) sc.Throw(); persistorChild.Persist( *pXMLStorage ); } } /*+-------------------------------------------------------------------------* *+-------------------------------------------------------------------------* *+-------------------------------------------------------------------------* *+-------------------------------------------------------------------------*/ /*+-------------------------------------------------------------------------* * * CComponentPersistor::Persist * * PURPOSE: persists IComponent collection related to snapin ( and its extensions) * * PARAMETERS: * CPersistor &persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CComponentPersistor::Persist(CPersistor &persistor) { DECLARE_SC(sc, TEXT("CComponentPersistor::Persist")); // let the base class do the job BC::Persist( persistor, true /*bPersistViewId*/ ); } /***************************************************************************\ * * METHOD: CComponentPersistor::ScReset * * PURPOSE: Restores component xml streams/storages into "Just loaded" state * * PARAMETERS: * * RETURNS: * SC - result code * \***************************************************************************/ SC CComponentPersistor::ScReset() { DECLARE_SC(sc, TEXT("CComponentPersistor::ScReset")); // save contents to string std::wstring strContents; sc = ScSaveToString(&strContents); if (sc) return sc; // cleanup (anything not saved should go away) m_XMLStorage.clear(); m_XMLStream.clear(); // load from string sc = ScLoadFromString(strContents.c_str()); if (sc) return sc; return sc; } //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * * CDPersistor::Persist * * PURPOSE: persists collection of component datas * * PARAMETERS: * CPersistor& persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CDPersistor::Persist(CPersistor& persistor) { DECLARE_SC(sc, TEXT("CDPersistor::Persist")); // let the base class do the job BC::Persist( persistor, false /*bPersistViewId*/ ); } /***************************************************************************\ * * METHOD: CDPersistor::ScReset * * PURPOSE: Restores component data xml streams/storages into "Just loaded" state * * PARAMETERS: * * RETURNS: * SC - result code * \***************************************************************************/ SC CDPersistor::ScReset() { DECLARE_SC(sc, TEXT("CDPersistor::ScReset")); // save contents to string std::wstring strContents; sc = ScSaveToString(&strContents); if (sc) return sc; // cleanup (anything not saved should go away) m_XMLStorage.clear(); m_XMLStream.clear(); // load from string sc = ScLoadFromString(strContents.c_str()); if (sc) return sc; return sc; }