672 lines
16 KiB
C++
672 lines
16 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
root.cpp
|
|
Root node information (the root node is not displayed
|
|
in the MMC framework but contains information such as
|
|
all of the subnodes in this snapin).
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "util.h"
|
|
#include "root.h"
|
|
#include "reg.h"
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
RootHandler implementation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
IMPLEMENT_ADDREF_RELEASE(RootHandler)
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(RootHandler)
|
|
|
|
HRESULT RootHandler::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// Is the pointer bad?
|
|
if (ppv == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// Place NULL in *ppv in case of failure
|
|
*ppv = NULL;
|
|
|
|
// This is the non-delegating IUnknown implementation
|
|
if (riid == IID_IUnknown)
|
|
*ppv = (LPVOID) this;
|
|
else if (riid == IID_IPersistStreamInit)
|
|
*ppv = (IPersistStreamInit *) this;
|
|
|
|
// If we're going to return an interface, AddRef it first
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN) *ppv)->AddRef();
|
|
return hrOK;
|
|
}
|
|
else
|
|
return BaseRouterHandler::QueryInterface(riid, ppv);
|
|
}
|
|
|
|
RootHandler::RootHandler(ITFSComponentData *pCompData)
|
|
: BaseRouterHandler(pCompData)
|
|
{
|
|
m_spTFSCompData.Set(pCompData);
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(RootHandler)
|
|
}
|
|
|
|
HRESULT RootHandler::Init()
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::ConstructNode
|
|
Initializes the root node (sets it up).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::ConstructNode(ITFSNode *pNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (pNode == NULL)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Need to initialize the data for the root node
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_FOLDER_CLOSED);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_FOLDER_OPEN);
|
|
pNode->SetData(TFS_DATA_SCOPEID, 0);
|
|
|
|
pNode->SetData(TFS_DATA_COOKIE, 0);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//// IPersistStream interface members
|
|
|
|
STDMETHODIMP RootHandler::GetClassID
|
|
(
|
|
CLSID *pClassID
|
|
)
|
|
{
|
|
ASSERT(pClassID != NULL);
|
|
|
|
// Copy the CLSID for this snapin
|
|
*pClassID = CLSID_IPXAdminExtension;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
STDMETHODIMP RootHandler::IsDirty()
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
m_spTFSCompData->GetRootNode(&spNode);
|
|
return (spNode->GetData(TFS_DATA_DIRTY) || GetConfigStream()->GetDirty()) ? hrOK : hrFalse;
|
|
}
|
|
|
|
STDMETHODIMP RootHandler::Load
|
|
(
|
|
IStream *pStm
|
|
)
|
|
{
|
|
Assert(pStm);
|
|
HRESULT hr = hrOK;
|
|
CString st;
|
|
BOOL fServer;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
hr = GetConfigStream()->LoadFrom(pStm);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP RootHandler::Save
|
|
(
|
|
IStream *pStm,
|
|
BOOL fClearDirty
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SPITFSNode spNode;
|
|
|
|
Assert(pStm);
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (fClearDirty)
|
|
{
|
|
m_spTFSCompData->GetRootNode(&spNode);
|
|
spNode->SetData(TFS_DATA_DIRTY, FALSE);
|
|
}
|
|
|
|
hr = GetConfigStream()->SaveTo(pStm);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP RootHandler::GetSizeMax
|
|
(
|
|
ULARGE_INTEGER *pcbSize
|
|
)
|
|
{
|
|
ULONG cbSize;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
hr = GetConfigStream()->GetSize(&cbSize);
|
|
if (FHrSucceeded(hr))
|
|
{
|
|
pcbSize->HighPart = 0;
|
|
pcbSize->LowPart = cbSize;
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP RootHandler::InitNew()
|
|
{
|
|
HRESULT hr = hrOK;
|
|
COM_PROTECT_TRY
|
|
{
|
|
hr = GetConfigStream()->InitNew();
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
// for RtrMgrInfo access
|
|
HRESULT RootHandler::AddRtrObj(LONG_PTR ulConnId, REFIID riid, IUnknown * pRtrObj)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj))
|
|
{
|
|
// connection id already in the list.
|
|
Trace1("RootHandler::AddRtrObj - %lx already in the list!", ulConnId);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
rtrObj.m_riid = riid;
|
|
rtrObj.m_spUnk.Set(pRtrObj);
|
|
|
|
m_mapRtrObj.SetAt(ulConnId, rtrObj);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT RootHandler::RemoveRtrObj(LONG_PTR ulConnId)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.RemoveKey(ulConnId) == 0)
|
|
{
|
|
// element not in the list
|
|
Trace1("RootHandler::RemoveRtrObj - %lx not in the list!", ulConnId);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT RootHandler::GetRtrObj(LONG_PTR ulConnId, IUnknown ** ppRtrObj)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj) == 0)
|
|
{
|
|
// entry not in the list
|
|
Trace1("RootHandler::GetRtrObj - %lx not in the list!", ulConnId);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (ppRtrObj)
|
|
{
|
|
*ppRtrObj = rtrObj.m_spUnk;
|
|
(*ppRtrObj)->AddRef();
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT RootHandler::SetProtocolAdded(LONG_PTR ulConnId, BOOL fProtocolAdded)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj) == 0)
|
|
{
|
|
// entry not in the list
|
|
Trace1("RootHandler::SetProtocolAdded - %lx not in the list!", ulConnId);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
rtrObj.m_fAddedProtocolNode = fProtocolAdded;
|
|
|
|
m_mapRtrObj.SetAt(ulConnId, rtrObj);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL RootHandler::IsProtocolAdded(LONG_PTR ulConnId)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
BOOL bAdded = FALSE;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj) == 0)
|
|
{
|
|
// entry not in the list
|
|
Trace1("RootHandler::IsProtocolAdded - %lx not in the list!", ulConnId);
|
|
return bAdded;
|
|
}
|
|
|
|
bAdded = rtrObj.m_fAddedProtocolNode;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return bAdded;
|
|
}
|
|
|
|
HRESULT RootHandler::RemoveAllRtrObj()
|
|
{
|
|
HRESULT hr = hrOK;
|
|
POSITION pos;
|
|
RtrObjRecord rtrObj;
|
|
LONG_PTR ulKey;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pos = m_mapRtrObj.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
m_mapRtrObj.GetNextAssoc(pos, ulKey, rtrObj);
|
|
|
|
if (rtrObj.m_riid == IID_IRtrMgrInfo)
|
|
{
|
|
SPIRtrMgrInfo spRm;
|
|
|
|
Verify( FHrOK(spRm.HrQuery(rtrObj.m_spUnk)) );
|
|
spRm->RtrUnadvise(ulKey);
|
|
}
|
|
else if (rtrObj.m_riid == IID_IRouterInfo)
|
|
{
|
|
SPIRouterInfo spRouter;
|
|
Verify( FHrOK(spRouter.HrQuery(rtrObj.m_spUnk)) );
|
|
spRouter->RtrUnadvise(ulKey);
|
|
}
|
|
else if (rtrObj.m_riid == IID_IRouterRefresh)
|
|
{
|
|
SPIRouterInfo spRouter;
|
|
SPIRouterRefresh spRefresh;
|
|
|
|
Verify( FHrOK(spRouter.HrQuery(rtrObj.m_spUnk)) );
|
|
|
|
Verify( FHrOK(spRouter->GetRefreshObject(&spRefresh)) );
|
|
|
|
if (ulKey)
|
|
spRefresh->UnadviseRefresh(ulKey);
|
|
}
|
|
else
|
|
{
|
|
Panic0("Unknown type in RtrObjMap!");
|
|
}
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::AddScopeItem
|
|
This will add the hScopeItem into the map (using the pszMachineName
|
|
as the key).
|
|
If the machine name already exists, then the hScopeItem entry is
|
|
overwritten.
|
|
|
|
This is added so that we can differentiate between the various
|
|
nodes (in the mulitple instance case).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::AddScopeItem(LPCTSTR pszMachineName, HSCOPEITEM hScopeItem)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
Assert(pszMachineName);
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
m_mapScopeItem.SetAt(pszMachineName, (LPVOID) hScopeItem);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::GetScopeItem
|
|
Looks up the scope item associated with this machine name.
|
|
|
|
Returns hrOK if a scope item is found.
|
|
Returns hrFalse if there is no scope item for this name.
|
|
Returns else otherwise.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::GetScopeItem(LPCTSTR pszMachineName, HSCOPEITEM *phScopeItem)
|
|
{
|
|
HRESULT hr = hrFalse;
|
|
LPVOID pv;
|
|
|
|
Assert(phScopeItem);
|
|
|
|
*phScopeItem = NULL;
|
|
|
|
if (m_mapScopeItem.Lookup(pszMachineName, pv))
|
|
{
|
|
*phScopeItem = (HSCOPEITEM) pv;
|
|
hr = hrOK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::RemoveScopeItem
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::RemoveScopeItem(HSCOPEITEM hScopeItem)
|
|
{
|
|
HRESULT hr = hrFalse;
|
|
CString stKey;
|
|
POSITION pos = NULL;
|
|
LPVOID pv = NULL;
|
|
|
|
for (pos = m_mapScopeItem.GetStartPosition(); pos != NULL; )
|
|
{
|
|
stKey.Empty();
|
|
pv = NULL;
|
|
|
|
m_mapScopeItem.GetNextAssoc(pos, stKey, pv);
|
|
|
|
if ((HSCOPEITEM) pv == hScopeItem)
|
|
{
|
|
Trace2("Removing (%s,%x)\n", (LPCTSTR) stKey, hScopeItem);
|
|
m_mapScopeItem.RemoveKey(stKey);
|
|
hr = hrOK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT RootHandler::SetComputerAddedAsLocal(LONG_PTR ulConnId, BOOL fComputerAddedAsLocal)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj) == 0)
|
|
{
|
|
// entry not in the list
|
|
Trace1("RootHandler::SetComputerAddedAsLocal - %lx not in the list!", ulConnId);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
rtrObj.m_fComputerAddedAsLocal = fComputerAddedAsLocal;
|
|
|
|
m_mapRtrObj.SetAt(ulConnId, rtrObj);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL RootHandler::IsComputerAddedAsLocal(LONG_PTR ulConnId)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
RtrObjRecord rtrObj;
|
|
BOOL bAdded = FALSE;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_mapRtrObj.Lookup(ulConnId, rtrObj) == 0)
|
|
{
|
|
// entry not in the list
|
|
Trace1("RootHandler::IsComputerAddedAsLocal - %lx not in the list!", ulConnId);
|
|
return bAdded;
|
|
}
|
|
|
|
bAdded = rtrObj.m_fComputerAddedAsLocal;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return bAdded;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::AddCookie
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::AddCookie(HSCOPEITEM hScopeItem, MMC_COOKIE cookie)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
m_mapNode.SetAt((LPVOID) hScopeItem, (LPVOID) cookie);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::GetCookie
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::GetCookie(HSCOPEITEM hScopeItem, MMC_COOKIE *pCookie)
|
|
{
|
|
HRESULT hr = hrFalse;
|
|
LPVOID pv;
|
|
|
|
*pCookie = NULL;
|
|
|
|
if (m_mapNode.Lookup((LPVOID) hScopeItem, pv))
|
|
{
|
|
*pCookie = (MMC_COOKIE) pv;
|
|
hr = hrOK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::RemoveCookie
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::RemoveCookie(HSCOPEITEM hScopeItem)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (m_mapNode.RemoveKey((LPVOID) hScopeItem) == 0)
|
|
hr = hrFalse;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::CompareNodeToMachineName
|
|
Dummy function.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::CompareNodeToMachineName(ITFSNode *pNode,
|
|
LPCTSTR pszMachineName)
|
|
{
|
|
Panic0("This should be overriden!");
|
|
return hrFalse;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::RemoveNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::RemoveNode(ITFSNode *pNode,
|
|
LPCTSTR pszMachineName)
|
|
{
|
|
Assert(pNode);
|
|
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
|
|
// Windows NT Bug : 246822
|
|
// Due to the server list programming model, we need to setup
|
|
// the proper scopeitem (so that MMC adds this to the proper
|
|
// node).
|
|
// Get the proper scope item for this node.
|
|
// ----------------------------------------------------------------
|
|
HSCOPEITEM hScopeItem = 0;
|
|
HSCOPEITEM hOldScopeItem = 0;
|
|
|
|
Verify( GetScopeItem(pszMachineName, &hScopeItem) == hrOK);
|
|
|
|
// Get the old one and save it. place the new one in the node.
|
|
// ----------------------------------------------------
|
|
hOldScopeItem = pNode->GetData(TFS_DATA_SCOPEID);
|
|
pNode->SetData(TFS_DATA_SCOPEID, hScopeItem);
|
|
|
|
CORg( pNode->GetEnum(&spNodeEnum) );
|
|
|
|
for (; spNodeEnum->Next(1, &spNode, NULL) == hrOK; spNode.Release())
|
|
{
|
|
if (CompareNodeToMachineName(spNode, pszMachineName) == hrOK)
|
|
{
|
|
pNode->RemoveChild(spNode);
|
|
spNode->Destroy();
|
|
break;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
pNode->SetData(TFS_DATA_SCOPEID, hOldScopeItem);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::RemoveAllNodes
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::RemoveAllNodes(ITFSNode *pNode)
|
|
{
|
|
Assert(pNode);
|
|
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
|
|
CORg( pNode->GetEnum(&spNodeEnum) );
|
|
|
|
for (; spNodeEnum->Next(1, &spNode, NULL) == hrOK; spNode.Release())
|
|
{
|
|
pNode->RemoveChild(spNode);
|
|
spNode->Destroy();
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RootHandler::OnRemoveChildren
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RootHandler::OnRemoveChildren(ITFSNode *pNode,
|
|
LPDATAOBJECT pdo,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
MMC_COOKIE cookie;
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spChild;
|
|
|
|
// Map the scopeitem to the cookie
|
|
// ----------------------------------------------------------------
|
|
if ( FHrOK(GetCookie((HSCOPEITEM) arg, &cookie)) )
|
|
{
|
|
// Remove this node
|
|
// --------------------------------------------------------
|
|
m_spNodeMgr->FindNode(cookie, &spChild);
|
|
|
|
Assert(spChild);
|
|
if (spChild)
|
|
{
|
|
pNode->RemoveChild(spChild);
|
|
spChild->Destroy();
|
|
spChild.Release();
|
|
|
|
RemoveScopeItem((HSCOPEITEM) arg);
|
|
RemoveCookie((HSCOPEITEM) arg);
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|