//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 2000 // // File: nopin.h // //-------------------------------------------------------------------------- #ifndef __CSCUI_NOPIN_H #define __CSCUI_NOPIN_H const HRESULT NOPIN_E_BADPATH = HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME); // // This class contains a tree of nodes, each node representing a file or // directory. The tree structure mirrors the directory/file structure // being represented. Each leaf node in the tree specifies a particular file // or directory for which pinning is disallowed. The tree is initialized // from the registry using the Initialize() method. Once initialized, // the tree is queried using the IsPinAllowed() method. This method // searches the tree given a particular UNC path. If a matching // traversal ending in a leaf node is found, pinning of that path is // not allowed. // // Since this code is to be used by the Offline Files context menu // handler, speed is critical. The tree structure was chosen for // it's fast lookup characteristics for filesystem paths. // class CNoPinList { public: CNoPinList(void); ~CNoPinList(void); // // Determines if pinning of a particular path is allowed. // S_OK == Pinning is allowed. // S_FALSE == Pinning is not allowed. // HRESULT IsPinAllowed(LPCTSTR pszPath); // // Determines if there is any pin that would be disallowed. // Basically, is the tree not empty? // HRESULT IsAnyPinDisallowed(void); #if DBG // // Dump tree contents to debugger. // void Dump(void); #endif private: // // Prevent copy. // CNoPinList(const CNoPinList& rhs); // not implemented. CNoPinList& operator = (const CNoPinList& rhs); // not implemented. #if DBG // // This "inspector" class is a trivial thing to allow us to // see inside a CNode object for debugging purposes. It is a friend // of CNode. This lets us keep the CNode private information private // for all bug debugging purposes. See the method CNoPinList::DumpNode // for it's usage. // class CNode; // fwd decl class CNodeInspector { public: CNodeInspector(const CNode *pNode) : m_pNode(pNode) { } LPCTSTR NodeName(void) const { return m_pNode->m_pszName; } const CNode *ChildList(void) const { return m_pNode->m_pChildren; } const CNode *NextSibling(void) const { return m_pNode->m_pNext; } private: const CNode *m_pNode; }; #endif // // A node in the tree. // class CNode { public: CNode(void); ~CNode(void); HRESULT Initialize(LPCTSTR pszName); HRESULT AddPath(LPTSTR pszPath); HRESULT SubPathExists(LPTSTR pszPath) const; bool HasChildren(void) const { return NULL != m_pChildren; } private: LPTSTR m_pszName; // Node's name CNode *m_pChildren; // List of children. NULL for leaf nodes. CNode *m_pNext; // Next in list of siblings // // Prevent copy. // CNode(const CNode& rhs); // Not implemented. CNode& operator = (const CNode& rhs); // Not implemented. CNode *_FindChild(LPCTSTR pszName) const; void _AddChild(CNode *pChild); static LPCTSTR _FindNextPathComponent(LPCTSTR pszPath, int *pcchComponent); static void _SwapChars(LPTSTR pszA, LPTSTR pszB); #if DBG friend class CNodeInspector; #endif }; CNode *m_pRoot; // The root of the tree. HRESULT _Initialize(void); HRESULT _InitPathFromRegistry(LPCTSTR pszPath); HRESULT _AddPath(LPCTSTR pszPath); #if DBG void _DumpNode(const CNode *pNode, int iIndent); #endif }; inline CNoPinList::CNode::CNode( void ) : m_pszName(NULL), m_pChildren(NULL), m_pNext(NULL) { } inline void CNoPinList::CNode::_SwapChars( LPTSTR pszA, LPTSTR pszB ) { const TCHAR chTemp = *pszA; *pszA = *pszB; *pszB = chTemp; } #endif // __CSCUI_NOPIN_H