//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: MTNode.h // // Contents: // // Classes: // // Functions: // // History: 9/13/1996 RaviR Created // //____________________________________________________________________________ #ifndef _MTNODE_H_ #define _MTNODE_H_ #pragma once #include "refcount.h" // CRefCountedPtr #include "xmlimage.h" // CXMLImageList #define MMC_SYSTEMROOT_VARIABLE _T("systemroot") #define MMC_SYSTEMROOT_VARIABLE_PERC _T("%systemroot%") #define MMC_WINDIR_VARIABLE_PERC _T("%windir%") /////////////////////////////////////////////////////////////////////////////// // Classes referd to here declared in other local files. class CSnapIn; // from SnapIn.h class CSnapInsCache; // from SnapIn.h class CComponent; // from Node.h class CNode; // from Node.h class CSnapInNode; // from Node.h class CDoc; class CSPImageCache; // from ScopImag.h class CExtensionsCache; class CPersistor; class CBookmark; // from bookmark.h class CSnapinProperties; // from siprop.h /////////////////////////////////////////////////////////////////////////////// // Classes declared in this file class CComponentData; class CMTNode; class CMTSnapInNode; /////////////////////////////////////////////////////////////////////////////// // typedefs typedef CMTNode * PMTNODE; typedef CTypedPtrList CNodeList; typedef CList CHMTNODEList; typedef CComponentData* PCCOMPONENTDATA; typedef std::vector CComponentDataArray; typedef CArray CGuidArray; HRESULT CreateSnapIn (const CLSID& clsid, IComponentData** ppICD, bool fCreateDummyOnFailure = true); HRESULT LoadRequiredExtensions(CSnapIn* pSnapIn, IComponentData* pICD, CSnapInsCache* pCache = NULL); HRESULT AddRequiredExtension(CSnapIn* pSnapIn, CLSID& rcslid); void DisplayPolicyErrorMessage(const CLSID& clsid, bool bExtension); #include "snapinpersistence.h" //____________________________________________________________________________ // // Class: CComponentData //____________________________________________________________________________ // class CComponentData { DECLARE_NOT_COPIABLE (CComponentData) DECLARE_NOT_ASSIGNABLE (CComponentData) public: // Constructor & Destructor CComponentData(CSnapIn * pSnapIn); ~CComponentData(); // Attributes void SetComponentID(COMPONENTID nID) { ASSERT(nID >= 0); ASSERT(nID < 1000); m_ComponentID = nID; } void SetIComponentData(IComponentData* pICD) { m_spIComponentData = pICD; } BOOL IsInitialized() { return (m_spIFramePrivate != NULL); } CSnapIn* GetSnapIn(void) const { return m_spSnapIn; } const CLSID& GetCLSID() const { return m_spSnapIn->GetSnapInCLSID(); } IComponentData* GetIComponentData(void) const { return m_spIComponentData; } IFramePrivate* GetIFramePrivate(void) const { return m_spIFramePrivate; } IImageListPrivate* GetIImageListPrivate(void); COMPONENTID GetComponentID(void) const { return m_ComponentID; } LPUNKNOWN GetUnknownToLoad(void) const { return m_spIComponentData; } // IComponentData interface methods HRESULT Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param); HRESULT QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject); HRESULT GetNodeType(MMC_COOKIE cookie, GUID* pGuid); HRESULT GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem); // IComponentData2 helpers SC ScQueryDispatch(MMC_COOKIE, DATA_OBJECT_TYPES type, PPDISPATCH ppScopeNodeObject); // Operations // Initialization HRESULT Init(HMTNODE hMTNode); void ResetComponentID(COMPONENTID id) { m_spIFramePrivate->SetComponentID(m_ComponentID = id); } // loaded from stream/storage; initailized with the new one; or does not need initialization bool IsIComponentDataInitialized() { return m_bIComponentDataInitialized; } // loaded from stream/storage; initailized with the new one; or does not need initialization void SetIComponentDataInitialized() { m_bIComponentDataInitialized = true; } private: // Implementation CSnapInPtr m_spSnapIn; IComponentDataPtr m_spIComponentData; IFramePrivatePtr m_spIFramePrivate; COMPONENTID m_ComponentID; bool m_bIComponentDataInitialized; }; // class CComponentData /*+-------------------------------------------------------------------------* * class CMTNode * * * PURPOSE: * *+-------------------------------------------------------------------------*/ class CMTNode : public XMLListCollectionBase { DECLARE_NOT_COPIABLE (CMTNode) DECLARE_NOT_ASSIGNABLE (CMTNode) protected: // codes corresponding to legacy node types. enum eNodeCodes { NODE_CODE_SNAPIN = 1, NODE_CODE_FOLDER = 2, // codes 2,3,4 are no longer correspond to NODE_CODE_HTML = 3, // MTNode derived classes, but are retained NODE_CODE_OCX = 4, // for converting old .msc files NODE_CODE_ENUMERATED = 10 }; public: static CMTNode* FromScopeItem (HSCOPEITEM item); static HSCOPEITEM ToScopeItem (const CMTNode* pMTNode) { return (reinterpret_cast(pMTNode)); } static CMTNode* FromHandle (HMTNODE hMTNode) { return (reinterpret_cast(hMTNode)); } static HMTNODE ToHandle (const CMTNode* pMTNode) { return (reinterpret_cast(const_cast(pMTNode))); } // Constructor CMTNode(); virtual HRESULT Init(void); // Attributes virtual BOOL IsStaticNode() const {return FALSE;} BOOL IsDynamicNode() const {return !IsStaticNode();} virtual HRESULT IsExpandable(); HRESULT QueryDataObject(DATA_OBJECT_TYPES type, LPDATAOBJECT* ppdtobj); // Images UINT GetImage(void) { return m_nImage; } UINT GetOpenImage(void) { return m_nOpenImage; } UINT GetState(void); void SetImage(UINT nImage) { m_nImage = nImage; } void SetOpenImage(UINT nImage) { m_nOpenImage = nImage; } void SetState(UINT nState) { m_nState = nState; } void SetOwnerID(long id) { m_idOwner = id; } long GetOwnerID(void) const { return m_idOwner; } void SetPrimaryComponentData(CComponentData* pDI) { m_pPrimaryComponentData = pDI; } CComponentData* GetPrimaryComponentData() const { return m_pPrimaryComponentData; } virtual tstring GetDisplayName(); virtual void SetDisplayName(LPCTSTR pszName); protected: tstring GetCachedDisplayName() const {return m_strName.str();} void SetCachedDisplayName(LPCTSTR pszName); public: BOOL IsInitialized() { return m_bInit; } int GetDynExtCLSID ( LPCLSID *ppCLSID ); void SetNoPrimaryChildren(BOOL bState = TRUE); HRESULT OnRename(long fRename, LPOLESTR pszNewName); SC ScQueryDispatch(DATA_OBJECT_TYPES type, PPDISPATCH ppScopeNodeObject); HRESULT AddExtension(LPCLSID lpclsid); CSnapIn* GetPrimarySnapIn(void) const { return m_pPrimaryComponentData->GetSnapIn(); } COMPONENTID GetPrimaryComponentID(); CMTSnapInNode* GetStaticParent(void); const CLSID& GetPrimarySnapInCLSID(void); LPARAM GetUserParam(void) const { return m_lUserParam; } void SetUserParam(LPARAM lParam) { m_lUserParam = lParam; } HRESULT GetNodeType(GUID* pGuid); SC ScGetPropertyFromINodeProperties(LPDATAOBJECT pDataObject, BSTR bstrPropertyName, PBSTR pbstrPropertyValue); // Operations virtual CNode * GetNode(CViewData* pViewData, BOOL fRootNode = FALSE); // Method to create a node for this Master Node. HRESULT Expand(void); HRESULT Expand (CComponentData*, IDataObject*, BOOL); virtual bool AllowNewWindowFromHere() const { return (true); } // Reference counting methods. USHORT AddRef(); USHORT Release(); // Tree traversal methods. PMTNODE Next() const {return m_pNext;} PMTNODE Prev() const {return m_pPrev;} PMTNODE Child() const {return m_pChild;} PMTNODE LastChild() const {return m_pLastChild;} PMTNODE Parent() const {return m_pParent;} CMTNode * NextStaticNode(); //+------------------------------------------------------------------ // Tree Manipulation methods // // ScInsertChild: Inserts pmtn as a child after pmtnInsertAfter // (first child if pmtnInsertAfter is NULL) // // ScDeleteChild: Deletes child pmtn // // ScDeleteTrailingChildren: Deletes pmtnFirst and following children //--------------------------------------------------------------------- SC ScInsertChild(CMTNode* pmtn, CMTNode* pmtnInsertAfter); SC ScDeleteChild(CMTNode* pmtn); SC ScDeleteTrailingChildren(CMTNode* pmtnFirst); // Iterators that expand PMTNODE GetNext() const {return Next();} PMTNODE GetChild(); void CreatePathList(CHMTNODEList& path); // Returns true if the stucture of tree needs to be saved, // or if any of the nodes need to be saved. // Derived classes which want to do more complex IsDirty() testing // may over-ride this function. virtual HRESULT IsDirty(); HRESULT InitNew(PersistData*); // Saves the stream information for later use and sets the dirty flag. static SC ScLoad(PersistData*, CMTNode** ppRootNode); // Creates a new tree structure from the provided storage and returns it in ppRootNode. void ResetExpandedAtLeastOnce() {_SetFlag(FLAG_EXPANDED_AT_LEAST_ONCE, FALSE);} void SetExpandedAtLeastOnce() {_SetFlag(FLAG_EXPANDED_AT_LEAST_ONCE, TRUE);} BOOL WasExpandedAtLeastOnce() {return _IsFlagSet(FLAG_EXPANDED_AT_LEAST_ONCE);} void SetPropertyPageIsDisplayed(BOOL bSet) {_SetFlag(FLAG_PROPERTY_PAGE_IS_DISPLAYED, bSet);} BOOL IsPropertyPageDisplayed() {return _IsFlagSet(FLAG_PROPERTY_PAGE_IS_DISPLAYED);} // Flag to monitor if MMCN_REMOVE_CHILDREN was sent to the snapin owning the node void SetRemovingChildren(bool b) {_SetFlag(FLAG_REMOVING_CHILDREN, b);} bool AreChildrenBeingRemoved(); // Unique ID helper functions. (Each node will be assigned an unique id // within the .msc file.) static MTNODEID GetNextID() throw() {return m_NextID++;} static void ResetID() throw() {m_NextID = ROOTNODEID;} CMTNode* Find(MTNODEID id); MTNODEID GetID() const throw() {return m_ID;} void SetID(MTNODEID key) {m_ID = key;} HRESULT DestroyElements(); // recursive function HRESULT DoDestroyElements(); // non-recursvie part // Deletes any persistence data stored in the current file void SetDirty(bool bIsDirty = true) {m_bIsDirty = bIsDirty;} void ClearDirty() {m_bIsDirty = false;} virtual void NotifyAddedToTree() {} virtual HRESULT CloseView(int viewID); virtual HRESULT DeleteView(int viewID); virtual bool DoDelete(HWND hwnd) { return true; } virtual void OnChildrenChanged() {} CMTNode* GetLastChild(); virtual CSnapInNode* FindNode(int nViewID) { return NULL; } // Unique ID for the node instance. CBookmark* GetBookmark(); virtual void Reset(); protected: virtual ~CMTNode(); virtual HRESULT InitNew() {return S_OK;} // Provides the derived nodes the opportunity to initialize the persistent resources. virtual SC ScLoad(); public: virtual void Persist(CPersistor& persistor); // persists the node virtual void OnNewElement(CPersistor& persistor); static void PersistNewNode(CPersistor &persistor, CMTNode** ppNode); DEFINE_XML_TYPE(XML_TAG_MT_NODE); static wchar_t* GetViewStorageName(wchar_t* name, int idView); static SC ScGetComponentStreamName(wchar_t* szName, int cchName, const CLSID& clsid); static SC ScGetComponentStorageName(wchar_t* szName, int cchName, const CLSID& clsid); static int GetViewIdFromStorageName(const wchar_t* name); protected: // Allows the tree to re-attach to a persistence source. IStream* GetTreeStream() {return m_spTreeStream;} BOOL GetDirty() {return m_bIsDirty;} wchar_t* GetStorageName(wchar_t* name) {return _ltow(GetID(), name, 36);} IStorage* GetNodeStorage() {return m_spNodeStorage;} IStorage* GetViewStorage() {return m_spViewStorage;} IStorage* GetStorageForCD() {return m_spCDStorage;} PersistData* GetPersistData() {return m_spPersistData;} bool Loaded() {return m_bLoaded;} bool AreExtensionsExpanded(void) const { return m_bExtensionsExpanded; } private: // Helper methods // Tree manipulation helpers void AttachNext(PMTNODE pmn) {m_pNext = pmn;} void AttachPrev(PMTNODE pmn) {m_pPrev = pmn;} void AttachChild(PMTNODE pmn) {m_pChild = pmn;} void AttachLastChild(PMTNODE pmn) {m_pLastChild = pmn;} void AttachParent(PMTNODE pmn) {m_pParent = pmn;} // Helper for ScLoad(PersistData*, CMTNode**) static SC ScLoad(PersistData*, CMTNode** ppRootNode, CMTNode* pParent, CMTNode* pPrev); // Implementation private: PMTNODE m_pNext; PMTNODE m_pPrev; PMTNODE m_pChild; // First Child PMTNODE m_pLastChild; PMTNODE m_pParent; std::auto_ptr m_bookmark; // For node instance persistance PersistDataPtr m_spPersistData; IStoragePtr m_spNodeStorage; IStoragePtr m_spViewStorage; IStoragePtr m_spCDStorage; IStreamPtr m_spTreeStream; bool m_bIsDirty; USHORT m_cRef; USHORT m_usFlags; // m_bExpandedAtLeastOnce; enum ENUM_FLAGS { FLAG_EXPANDED_AT_LEAST_ONCE = 0x0001, FLAG_PROPERTY_PAGE_IS_DISPLAYED = 0x0002, FLAG_REMOVING_CHILDREN = 0x0004, }; void _SetFlag(ENUM_FLAGS flag, BOOL bSet); BOOL _IsFlagSet(ENUM_FLAGS flag){return ((m_usFlags & flag) == flag);} MTNODEID m_ID; // Unique id for this node within the .msc file. bool m_bLoaded; // when true, load should be called instead of init new static MTNODEID m_NextID; // The last unique identifier given out. HRESULT OpenStorageForNode(); // Opens the storage for this specific instance of a node. HRESULT OpenStorageForView(); // Opens the view storage for this specific instance of a node. HRESULT OpenStorageForCD(); // Opens the view storage for this specific instance of a node. private: HRESULT OpenTreeStream(); // Opens the stream to be used to contain this nodes data. void SetParent(CMTNode* pParent);// Sets the parent for this and all next nodes. protected: UINT m_nImage; UINT m_nOpenImage; UINT m_nState; CStringTableString m_strName; // Display name protected: enum StreamVersionIndicator { Stream_V0100 = 1, // MMC 1.0 Stream_V0110 = 2, // MMC 1.1 Stream_CurrentVersion = Stream_V0110, VersionedStreamMarker = 0xFFFFFFFF, }; private: long m_idOwner; // One of the SnapIns. LPARAM m_lUserParam; CComponentData* m_pPrimaryComponentData; BOOL m_bInit; bool m_bExtensionsExpanded; CGuidArray m_arrayDynExtCLSID; unsigned short m_usExpandFlags; enum ENUM_EXPAND_FLAGS { FLAG_NO_CHILDREN_FROM_PRIMARY = 0x0001, FLAG_NO_NAMESPACE_EXTNS = 0x0002, FLAG_NAMESPACE_EXTNS_CHECKED = 0x0004 }; }; // class CMTNode /*+-------------------------------------------------------------------------* * class ViewRootStorage * * * PURPOSE: * *+-------------------------------------------------------------------------*/ class ViewRootStorage { public: ViewRootStorage() {} ~ViewRootStorage() { Clear(); } void Initialize(IStorage* pRootStorage) { ASSERT(m_spRootStorage == NULL); ASSERT(pRootStorage != NULL); m_spRootStorage = pRootStorage; } IStorage* GetRootStorage() { return m_spRootStorage; } bool Insert(IStorage* pViewStorage, int idView) { ASSERT(pViewStorage != NULL); if ( NULL == m_Views.Find(idView)) { return m_Views.Insert(IStoragePtr(pViewStorage), idView); } return true; } bool Remove(int idView) { const bool bRemoved = m_Views.Remove(idView); return bRemoved; } IStorage* FindViewStorage(int idView) const { CAdapt *pspStorage = m_Views.Find(idView); return (pspStorage ? pspStorage->m_T : NULL); } void Clear() { m_Views.Clear(); m_spRootStorage = NULL; } private: // CAdapt is used to hide operator&() - which will be invoked by map // implementation to get address of the element. // Smart pointer's operator&() releases reference plus returns wrong type for a map. Map, int> m_Views; IStoragePtr m_spRootStorage; }; // class ViewRootStorage /*+-------------------------------------------------------------------------* * class CMTSnapInNode * * * PURPOSE: The root node of a primary snap-in. Added to the console and * the scope tree by MMC. Only a snap-in that is added from the * Add/Remove snapin page of the Snapin manager has a static node; * extensions of any type do not. * *+-------------------------------------------------------------------------*/ class CMTSnapInNode : public CMTNode, public CTiedObject { DECLARE_NOT_COPIABLE (CMTSnapInNode) DECLARE_NOT_ASSIGNABLE (CMTSnapInNode) public: // Constructor & Destructor CMTSnapInNode(Properties* pProps); ~CMTSnapInNode(); // SnapIn object model methods public: SC ScGetSnapIn(PPSNAPIN ppSnapIn); SC Scget_Name( PBSTR pbstrName); SC Scget_Extensions( PPEXTENSIONS ppExtensions); SC Scget_SnapinCLSID(PBSTR pbstrSnapinCLSID); SC Scget_Properties( PPPROPERTIES ppProperties); SC ScEnableAllExtensions (BOOL bEnable); // helper for CMMCSnapIn SC ScGetSnapinClsid(CLSID& clsid); static SC ScGetCMTSnapinNode(PSNAPIN pSnapIn, CMTSnapInNode **ppMTSnapInNode); public: // Attributes virtual BOOL IsStaticNode() const { return TRUE; } UINT GetResultImage(CNode* pNode, IImageListPrivate* pImageList); void SetResultImage(UINT index) { m_resultImage = index; } void SetPrimarySnapIn(CSnapIn * pSI); CNodeList& GetNodeList(void) { return m_NodeList; } virtual HRESULT IsExpandable(); // Operations // Initialize virtual HRESULT Init(void); // Create a node for this master node. virtual CNode * GetNode(CViewData* pViewData, BOOL fRootNode = FALSE); virtual tstring GetDisplayName(); virtual void SetDisplayName(LPCTSTR pszName); void AddNode(CNode * pNode); void RemoveNode(CNode * pNode); virtual CSnapInNode* FindNode(int nViewID); int GetNumberOfComponentDatas() { return m_ComponentDataArray.size(); } COMPONENTID AddComponentDataToArray(CComponentData* pCCD); CComponentData* GetComponentData(const CLSID& clsid); CComponentData* GetComponentData(COMPONENTID nID); CComponent* GetComponent(UINT nViewID, COMPONENTID nID, CSnapIn* pSnapIn); virtual HRESULT CloseView(int viewID); virtual HRESULT DeleteView(int viewID); // Loads from existing stream/storage or initializes with the new one SC ScInitIComponentData( CComponentData* pCD ); SC ScInitIComponent(CComponent* pComponent, int viewID); virtual void Reset(); void CompressComponentDataArray(); BOOL IsPreloadRequired () const; void SetPreloadRequired (bool bPreload) { m_ePreloadState = (bPreload) ? ePreload_True : ePreload_False;} SC ScConvertLegacyNode(const CLSID &clsid); // Implementation protected: // virtual HRESULT InitNew(); virtual HRESULT IsDirty(); virtual SC ScLoad(); virtual void Persist(CPersistor& persistor); private: SC ScInitProperties(); SC ScCreateSnapinProperties(CSnapinProperties** ppSIProps); SC ScAddImagesToImageList(); SC ScReadStreamsAndStoragesFromConsole(); // Loads from existing sream/storage of initializes with the new one. SC ScInitComponentOrComponentData( IUnknown *pSnapin, CMTSnapinNodeStreamsAndStorages *pStreamsAndStorages, int idView , const CLSID& clsid ); private: enum PersistType { PT_None, PT_IStream, PT_IStreamInit, PT_IStorage }; enum PreloadState { ePreload_Unknown = -1, // don't know if MMCN_PRELOAD is required yet ePreload_False = 0, // MMCN_PRELOAD not required ePreload_True = 1, // MMCN_PRELOAD required }; SC ScQueryPreloadRequired (PreloadState& ePreload) const; SC ScHandleCustomImages (const CLSID& clsidSnapin); SC ScHandleCustomImages (HBITMAP hbmSmall, HBITMAP hbmSmallOpen, HBITMAP hbmLarge, COLORREF crMask); HRESULT AreIComponentDatasDirty(); HRESULT AreIComponentsDirty(); HRESULT IsIUnknownDirty(IUnknown* pUnk); SC ScSaveIComponentDatas(); SC ScSaveIComponentData( CComponentData* pCD ); SC ScSaveIComponents(); SC ScSaveIComponent( CComponent* pCComponent, int viewID ); SC ScAskSnapinToSaveData( IUnknown *pSnapin, CMTSnapinNodeStreamsAndStorages *pStreamsAndStorages, int idView , const CLSID& clsid, CSnapIn *pCSnapin ); private: PropertiesPtr m_spProps; SnapInPtr m_spSnapIn; CComponentDataArray m_ComponentDataArray; CNodeList m_NodeList; ViewRootStorage m_ComponentStorage; CXMLImageList m_imlSmall; // small, open images CXMLImageList m_imlLarge; // large image UINT m_resultImage; CDPersistor m_CDPersistor; CComponentPersistor m_ComponentPersistor; mutable PreloadState m_ePreloadState; BOOL m_bHasBitmaps; bool m_fCallbackForDisplayName; // snap-in gave us MMC_TEXTCALLBACK for node name? }; // class CMTSnapInNode #include "mtnode.inl" #endif // _MTNODE_H_