windows-nt/Source/XPSP1/NT/admin/snapin/dsadmin/uinode.cpp
2020-09-26 16:20:57 +08:00

812 lines
17 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: DSCookie.cpp
//
// Contents: TBD
//
// History: 02-Oct-96 WayneSc Created
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "resource.h"
#include "uinode.h"
#include "dscmn.h" // CrackName()
#include "ContextMenu.h"
#include "dsfilter.h"
#include "xmlutil.h"
#include <notify.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////
// CUIFolderInfo
const UINT CUIFolderInfo::nSerialNomberNotTouched = 0x7fffffff;
CUIFolderInfo::CUIFolderInfo(CUINode* pUINode)
{
ASSERT(pUINode != NULL);
m_pUINode = pUINode;
m_hScopeItem = NULL;
m_bExpandedOnce = FALSE;
m_cObjectsContained = 0;
m_SerialNumber = SERIALNUM_NOT_TOUCHED;
m_pColumnSet = NULL;
m_bTooMuchData = FALSE;
m_nApproximateTotalContained = 0;
m_bSortOnNextSelect = FALSE;
}
CUIFolderInfo::CUIFolderInfo(const CUIFolderInfo&)
{
//
// The node is probably still being created so don't copy it
//
m_pUINode = NULL;
//
// Don't copy the scope item
//
m_hScopeItem = 0;
//
// Don't mark as expanded
//
m_bExpandedOnce = FALSE;
//
// Shouldn't contain any object either
//
m_cObjectsContained = 0;
m_SerialNumber = SERIALNUM_NOT_TOUCHED;
m_pColumnSet = NULL;
m_bTooMuchData = FALSE;
m_nApproximateTotalContained = 0;
m_bSortOnNextSelect = FALSE;
}
CDSColumnSet* CUIFolderInfo::GetColumnSet(PCWSTR pszClass, CDSComponentData* pCD)
{
if (m_pColumnSet == NULL)
{
ASSERT(pCD != NULL);
if (_wcsicmp(m_pUINode->GetName(), L"ForeignSecurityPrincipals") == 0)
{
m_pColumnSet = pCD->FindColumnSet(L"ForeignSecurityPrincipals");
}
else
{
m_pColumnSet = pCD->FindColumnSet(pszClass);
}
ASSERT(m_pColumnSet != NULL);
}
return m_pColumnSet;
}
void CUIFolderInfo::UpdateSerialNumber(CDSComponentData * pCD)
{
m_SerialNumber = pCD->GetSerialNumber();
// TRACE(_T("cookie (%s)serial number updated: %d.\n"),
// m_strName, m_SerialNumber);
CUINode* pParentNode = GetParentNode();
if (pParentNode != NULL)
pParentNode->GetFolderInfo()->UpdateSerialNumber(pCD);
}
void CUIFolderInfo::AddToCount(UINT increment)
{
m_cObjectsContained += increment;
// TRACE(_T("cookie (%s) count increased to: %d.\n"),
// m_strName, m_cObjectsContained);
CUINode* pParentNode = GetParentNode();
if (pParentNode != NULL)
pParentNode->GetFolderInfo()->AddToCount(increment);
}
void CUIFolderInfo::SubtractFromCount(UINT decrement)
{
if (m_cObjectsContained == 0)
return;
m_cObjectsContained -= decrement;
// TRACE(_T("cookie (%s) count decreased to: %d.\n"),
// m_strName, m_cObjectsContained);
CUINode* pParentNode = GetParentNode();
if (pParentNode != NULL)
pParentNode->GetFolderInfo()->SubtractFromCount(decrement);
}
CUINode* CUIFolderInfo::GetParentNode()
{
ASSERT(m_pUINode != NULL);
return m_pUINode->GetParent();
}
void CUIFolderInfo::DeleteAllLeafNodes(void)
{
SubtractFromCount ((UINT)m_LeafNodes.GetCount());
while (!m_LeafNodes.IsEmpty())
delete m_LeafNodes.RemoveTail();
}
void CUIFolderInfo::DeleteAllContainerNodes(void)
{
SubtractFromCount ((UINT)m_ContainerNodes.GetCount());
while (!m_ContainerNodes.IsEmpty())
delete m_ContainerNodes.RemoveTail();
}
HRESULT CUIFolderInfo::AddNode(CUINode* pUINode)
{
if (pUINode==NULL)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
if (pUINode->IsContainer())
m_ContainerNodes.AddTail(pUINode);
else
m_LeafNodes.AddTail(pUINode);
AddToCount(1);
pUINode->SetParent(m_pUINode);
return S_OK;
}
HRESULT CUIFolderInfo::AddListofNodes(CUINodeList* pNodeList)
{
HRESULT hr = S_OK;
if (pNodeList == NULL)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
POSITION pos = pNodeList->GetHeadPosition();
while (pos != NULL)
{
CUINode* pUINode = pNodeList->GetNext(pos);
if (pUINode != NULL)
{
AddNode(pUINode);
}
else
{
hr = E_POINTER;
}
}
return hr;
}
HRESULT CUIFolderInfo::DeleteNode(CUINode* pUINode)
{
if (pUINode==NULL)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
HRESULT hr = RemoveNode(pUINode);
if (SUCCEEDED(hr))
{
delete pUINode;
}
return hr;
}
HRESULT CUIFolderInfo::RemoveNode(CUINode* pUINode)
{
if (pUINode==NULL)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
HRESULT hr=E_FAIL;
POSITION pos;
CUINodeList* pList=NULL;
if (pUINode->IsContainer())
{
pList=&m_ContainerNodes;
}
else
{
pList=&m_LeafNodes;
}
pos = pList->Find(pUINode);
if (pos != NULL)
{
pList->RemoveAt(pos);
hr = S_OK;
}
SubtractFromCount(1);
return hr;
}
void CUIFolderInfo::SetTooMuchData(BOOL bSet, UINT nApproximateTotal)
{
m_bTooMuchData = bSet;
if (!bSet)
{
m_nApproximateTotalContained = 0;
}
else
{
m_nApproximateTotalContained = nApproximateTotal;
}
}
////////////////////////////////////////////////////////////////////
// CUINode
CUINode::CUINode(CUINode* pParentNode)
{
m_pParentNode = pParentNode;
m_pNodeData = NULL;
m_pFolderInfo = NULL;
m_nSheetLockCount = 0;
m_extension_op = 0;
m_pMenuVerbs = NULL;
}
CUINode::CUINode(const CUINode& copyNode)
{
m_pParentNode = copyNode.m_pParentNode;
if (copyNode.m_pNodeData != NULL)
{
m_pNodeData = new CNodeData(*(copyNode.m_pNodeData));
}
else
{
m_pNodeData = NULL;
}
if (copyNode.m_pFolderInfo != NULL)
{
m_pFolderInfo = new CUIFolderInfo(*(copyNode.m_pFolderInfo));
m_pFolderInfo->SetNode(this);
}
else
{
m_pFolderInfo = NULL;
}
m_nSheetLockCount = copyNode.m_nSheetLockCount;
m_extension_op = copyNode.m_extension_op;
m_pMenuVerbs = NULL;
}
CUINode::~CUINode()
{
ASSERT(m_nSheetLockCount == 0);
if (m_pNodeData != NULL)
{
delete m_pNodeData;
}
if (m_pFolderInfo != NULL)
{
delete m_pFolderInfo;
}
if (m_pMenuVerbs != NULL)
{
delete m_pMenuVerbs;
}
}
BOOL CUINode::IsRelative(CUINode* pUINode)
{
BOOL bRet = FALSE;
if (pUINode == this)
{
bRet = TRUE;
}
else
{
if (!IsSnapinRoot())
{
bRet = GetParent()->IsRelative(pUINode);
}
}
return bRet;
}
void CUINode::IncrementSheetLockCount()
{
++m_nSheetLockCount;
if (m_pParentNode != NULL)
m_pParentNode->IncrementSheetLockCount();
}
void CUINode::DecrementSheetLockCount()
{
ASSERT(m_nSheetLockCount > 0);
--m_nSheetLockCount;
if (m_pParentNode != NULL)
m_pParentNode->DecrementSheetLockCount();
}
BOOL CUINode::IsDeleteAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsRenameAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsRefreshAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::ArePropertiesAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsCutAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsCopyAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsPasteAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
BOOL CUINode::IsPrintAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = TRUE;
return FALSE;
}
CDSColumnSet* CUINode::GetColumnSet(CDSComponentData* pComponentData)
{
CDSColumnSet* pColumnSet = NULL;
if (IsContainer())
{
pColumnSet = m_pFolderInfo->GetColumnSet(DEFAULT_COLUMN_SET, pComponentData);
}
return pColumnSet;
}
CContextMenuVerbs* CUINode::GetContextMenuVerbsObject(CDSComponentData* pComponentData)
{
if (m_pMenuVerbs == NULL)
{
if (pComponentData->QuerySnapinType() == SNAPINTYPE_SITE)
{
m_pMenuVerbs = new CSARContextMenuVerbs(pComponentData);
}
else
{
m_pMenuVerbs = new CDSAdminContextMenuVerbs(pComponentData);
}
}
return m_pMenuVerbs;
}
HRESULT CUINode::Delete(CDSComponentData* pComponentData)
{
HRESULT hr = S_OK;
if (IsContainer())
{
hr = pComponentData->RemoveContainerFromUI(this);
delete this;
}
else
{
CUINode* pParentNode = GetParent();
ASSERT(pParentNode->IsContainer());
pParentNode->GetFolderInfo()->RemoveNode(this);
//
// The CDSEvent::_DeleteSingleSel() handles removing the node from the UI
//
}
return hr;
}
HRESULT CUINode::DeleteMultiselect(CDSComponentData* pComponentData, CInternalFormatCracker* pObjCracker)
{
HRESULT hr = S_OK;
//
// Multiselection should always delegate to the container
//
ASSERT(IsContainer());
if (IsContainer())
{
for (UINT nIdx = 0; nIdx < pObjCracker->GetCookieCount(); nIdx++)
{
CUINode* pUINode = pObjCracker->GetCookie(nIdx);
if (pUINode != NULL)
{
if (pUINode->IsContainer())
{
hr = pComponentData->RemoveContainerFromUI(pUINode);
delete pUINode;
}
else
{
GetFolderInfo()->RemoveNode(pUINode);
}
}
}
}
else
{
hr = S_FALSE;
}
return hr;
}
HRESULT CUINode::Rename(LPCWSTR lpszNewName, CDSComponentData* pComponentData)
{
HRESULT hr = S_OK;
SetName(lpszNewName);
hr = pComponentData->UpdateItem(this);
return hr;
}
////////////////////////////////////////////////////////////////////
// CUINodeTableBase
#define NUMBER_OF_COOKIE_TABLE_ENTRIES 4 // default count, expandable at run time
CUINodeTableBase::CUINodeTableBase()
{
m_nEntries = NUMBER_OF_COOKIE_TABLE_ENTRIES;
m_pCookieArr =(CUINode**)malloc(m_nEntries*sizeof(CUINode*));
if (m_pCookieArr != NULL)
{
ZeroMemory(m_pCookieArr, m_nEntries*sizeof(CUINode*));
}
}
CUINodeTableBase::~CUINodeTableBase()
{
free(m_pCookieArr);
}
void CUINodeTableBase::Add(CUINode* pNode)
{
ASSERT(!IsPresent(pNode));
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] == NULL)
{
m_pCookieArr[k] = pNode;
return;
}
}
// not space left, need to allocate
int nAlloc = m_nEntries*2;
m_pCookieArr = (CUINode**)realloc(m_pCookieArr, sizeof(CUINode*)*nAlloc);
::ZeroMemory(&m_pCookieArr[m_nEntries], sizeof(CDSCookie*)*m_nEntries);
m_pCookieArr[m_nEntries] = pNode;
m_nEntries = nAlloc;
}
BOOL CUINodeTableBase::Remove(CUINode* pNode)
{
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] == pNode)
{
m_pCookieArr[k] = NULL;
return TRUE; // found
}
}
return FALSE; // not found
}
BOOL CUINodeTableBase::IsPresent(CUINode* pNode)
{
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] == pNode)
return TRUE;
}
return FALSE;
}
void CUINodeTableBase::Reset()
{
for (UINT k=0; k<m_nEntries; k++)
{
m_pCookieArr[k] = NULL;
}
}
UINT CUINodeTableBase::GetCount()
{
UINT nCount = 0;
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] != NULL)
nCount++;
}
return nCount;
}
////////////////////////////////////////////////////////////////////
// CUINodeQueryTable
void CUINodeQueryTable::RemoveDescendants(CUINode* pNode)
{
// cannot do this while the cookie has a pending operation
ASSERT(!IsPresent(pNode));
// remove all the cookies that have the given cookie as parent
// or ancestor,
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] != NULL)
{
CUINode* pAncestorNode = m_pCookieArr[k]->GetParent();
while (pAncestorNode != NULL)
{
if (pAncestorNode == pNode)
{
m_pCookieArr[k] = NULL;
}
pAncestorNode = pAncestorNode->GetParent();
}
}
}
}
BOOL CUINodeQueryTable::IsLocked(CUINode* pNode)
{
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] != NULL)
{
// found the cookie itself?
if (pNode == m_pCookieArr[k])
return TRUE;
// look if the cookie is an ancestor of the current cookie
CUINode* pAncestorNode = m_pCookieArr[k]->GetParent();
while (pAncestorNode != NULL)
{
if (pAncestorNode == pNode)
return TRUE;
pAncestorNode = pAncestorNode->GetParent();
}
}
}
return FALSE;
}
////////////////////////////////////////////////////////////////////
// CUINodeSheetTable
void CUINodeSheetTable::BringToForeground(CUINode* pNode, CDSComponentData* pCD, BOOL bActivate)
{
ASSERT(pCD != NULL);
ASSERT(pNode != NULL);
//
// look for the cookie itself and for all the cookies that have the
// given cookie as parent or ancestor
//
for (UINT k=0; k<m_nEntries; k++)
{
if (m_pCookieArr[k] != NULL)
{
CUINode* pAncestorNode = m_pCookieArr[k];
while (pAncestorNode != NULL)
{
if (pAncestorNode == pNode)
{
CString szADSIPath;
if (IS_CLASS(*pNode, CDSUINode))
{
CDSCookie* pCookie = GetDSCookieFromUINode(pNode);
if (pCookie != NULL)
{
pCD->GetBasePathsInfo()->ComposeADsIPath(szADSIPath, pCookie->GetPath());
//
// the first one will be also activated
//
TRACE(L"BringSheetToForeground(%s, %d)\n", (LPCWSTR)szADSIPath, bActivate);
VERIFY(BringSheetToForeground((LPWSTR)(LPCWSTR)szADSIPath, bActivate));
if (bActivate)
{
bActivate = FALSE;
}
}
}
}
pAncestorNode = pAncestorNode->GetParent();
}
} // if
} // for
}
/////////////////////////////////////////////////////////////////////////////
// CGenericUINode
CGenericUINode::CGenericUINode(CUINode* pParentNode) : CUINode(pParentNode)
{
m_nImage = 0;
}
CGenericUINode::CGenericUINode(const CGenericUINode& copyNode) : CUINode(copyNode)
{
m_nImage = copyNode.m_nImage;
m_strName = copyNode.m_strName;
m_strDesc = copyNode.m_strDesc;
}
LPCWSTR CGenericUINode::g_szNameXMLTag = L"NAME";
LPCWSTR CGenericUINode::g_szDecriptionXMLTag = L"DESCRIPTION";
HRESULT CGenericUINode::XMLSaveBase(IXMLDOMDocument* pXMLDoc,
IXMLDOMNode* pXMLDOMNode)
{
HRESULT hr = XML_AppendTextDataNode(pXMLDoc, pXMLDOMNode, CGenericUINode::g_szNameXMLTag, GetName());
RETURN_IF_FAILED(hr);
hr = XML_AppendTextDataNode(pXMLDoc, pXMLDOMNode, CGenericUINode::g_szDecriptionXMLTag, GetDesc());
return hr;
}
//////////////////////////////////////////////////////////////////////////////
// CRootNode
BOOL CRootNode::IsRefreshAllowed(CDSComponentData*, BOOL* pbHide)
{
*pbHide = FALSE;
return TRUE;
}
CContextMenuVerbs* CRootNode::GetContextMenuVerbsObject(CDSComponentData* pComponentData)
{
if (m_pMenuVerbs == NULL)
{
m_pMenuVerbs = new CSnapinRootMenuVerbs(pComponentData);
}
return m_pMenuVerbs;
}
HRESULT CRootNode::OnCommand(long lCommandID, CDSComponentData* pComponentData)
{
HRESULT hr = S_OK;
switch (lCommandID)
{
case IDM_GEN_TASK_SELECT_DOMAIN:
case IDM_GEN_TASK_SELECT_FOREST:
if (pComponentData->CanRefreshAll())
{
pComponentData->GetDomain();
}
break;
case IDM_GEN_TASK_SELECT_DC:
if (pComponentData->CanRefreshAll())
{
pComponentData->GetDC();
}
break;
case IDM_VIEW_SERVICES_NODE:
{
if (pComponentData->CanRefreshAll())
{
ASSERT( SNAPINTYPE_SITE == pComponentData->QuerySnapinType() );
pComponentData->GetQueryFilter()->ToggleViewServicesNode();
pComponentData->SetDirty();
if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
{
pComponentData->Refresh(pComponentData->GetRootNode(), FALSE /*bFlushCache*/ );
}
}
}
break;
case IDM_GEN_TASK_EDIT_FSMO:
{
pComponentData->EditFSMO();
}
break;
case IDM_GEN_TASK_RAISE_VERSION:
pComponentData->RaiseVersion();
break;
case IDM_VIEW_ADVANCED:
{
if (pComponentData->CanRefreshAll())
{
ASSERT( SNAPINTYPE_SITE != pComponentData->QuerySnapinType() );
pComponentData->GetQueryFilter()->ToggleAdvancedView();
pComponentData->SetDirty();
if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
{
pComponentData->Refresh(pComponentData->GetRootNode(), TRUE /*bFlushCache*/ );
}
}
}
break;
case IDM_VIEW_COMPUTER_HACK:
if (pComponentData->CanRefreshAll())
{
pComponentData->Lock();
pComponentData->GetQueryFilter()->ToggleExpandComputers();
pComponentData->Unlock();
BOOL fDoRefresh = pComponentData->GetClassCache()->ToggleExpandSpecialClasses(pComponentData->GetQueryFilter()->ExpandComputers());
pComponentData->SetDirty();
if (fDoRefresh)
{
if (pComponentData->GetRootNode()->GetFolderInfo()->IsExpanded())
{
pComponentData->Refresh(pComponentData->GetRootNode(), TRUE /*bFlushCache*/ );
}
}
}
break;
default:
ASSERT(FALSE);
break;
}
return hr;
}