windows-nt/Source/XPSP1/NT/net/mmc/wins/reppart.cpp
2020-09-26 16:20:57 +08:00

1618 lines
39 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
reppart.cpp
WINS replication partners node information.
FILE HISTORY:
*/
#include "stdafx.h"
#include "reppart.h"
#include "server.h"
#include "nodes.h"
#include "repnodpp.h"
#include "ipadddlg.h"
UINT guReplicationPartnersMessageStrings[] =
{
IDS_REPLICATION_PARTNERS_MESSAGE_BODY1,
IDS_REPLICATION_PARTNERS_MESSAGE_BODY2,
IDS_REPLICATION_PARTNERS_MESSAGE_BODY3,
IDS_REPLICATION_PARTNERS_MESSAGE_BODY4,
-1
};
// various registry keys
const CReplicationPartnersHandler::REGKEYNAME CReplicationPartnersHandler::lpstrPullRoot = _T("SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Pull");
const CReplicationPartnersHandler::REGKEYNAME CReplicationPartnersHandler::lpstrPushRoot = _T("SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Push");
const CReplicationPartnersHandler::REGKEYNAME CReplicationPartnersHandler::lpstrNetBIOSName = _T("NetBIOSName");
const CReplicationPartnersHandler::REGKEYNAME CReplicationPartnersHandler::lpstrPersistence = _T("PersistentRplOn");
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::CReplicationPartnersHandler
Description
Author: EricDav
---------------------------------------------------------------------------*/
CReplicationPartnersHandler::CReplicationPartnersHandler(
ITFSComponentData *pCompData)
: CWinsHandler(pCompData)
{
m_bExpanded = FALSE;
//m_verbDefault = MMC_VERB_PROPERTIES;
m_nState = loaded;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CString strTemp;
strTemp.LoadString(IDS_REPLICATION);
SetDisplayName(strTemp);
m_strDescription.LoadString(IDS_REPLICATION_DISC);
// Make the node immediately visible
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_REP_PARTNERS_FOLDER_OPEN);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, WINSSNAP_REPLICATION_PARTNERS);
pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
SetColumnStringIDs(&aColumns[WINSSNAP_REPLICATION_PARTNERS][0]);
SetColumnWidths(&aColumnWidths[WINSSNAP_REPLICATION_PARTNERS][0]);
return hrOK;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnCreateNodeId2
Returns a unique string for this node
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CReplicationPartnersHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
{
const GUID * pGuid = pNode->GetNodeType();
CString strGuid;
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
strGuid.ReleaseBuffer();
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
strId = pServer->m_strServerAddress + strGuid;
return hrOK;
}
/*---------------------------------------------------------------------------
Overridden base handler functions
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::GetString
Implementation of ITFSNodeHandler::GetString
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CReplicationPartnersHandler::GetString
(
ITFSNode * pNode,
int nCol
)
{
if (nCol == 0 || nCol == -1)
return GetDisplayName();
else if(nCol == 1)
return m_strDescription;
else
return NULL;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnAddMenuItems
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CReplicationPartnersHandler::OnAddMenuItems
(
ITFSNode * pNode,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
LPDATAOBJECT lpDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = S_OK;
CString strMenuItem;
if (type == CCT_SCOPE)
{
// these menu items go in the new menu,
// only visible from scope pane
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
strMenuItem.LoadString(IDS_REP_NEW_REPLICATION_PARTNER);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_REP_NEW_REPLICATION_PARTNER,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
strMenuItem.LoadString(IDS_REP_REPLICATE_NOW);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_REP_REPLICATE_NOW,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
}
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnCommand
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CReplicationPartnersHandler::OnCommand
(
ITFSNode * pNode,
long nCommandId,
DATA_OBJECT_TYPES type,
LPDATAOBJECT pDataObject,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
switch(nCommandId)
{
case IDS_REP_REPLICATE_NOW:
hr = OnReplicateNow(pNode);
break;
case IDS_REP_NEW_REPLICATION_PARTNER:
hr = OnCreateRepPartner(pNode);
break;
default:
break;
}
return hr;
}
/*!--------------------------------------------------------------------------
CReplicationPartnersHandler::HasPropertyPages
Implementation of ITFSNodeHandler::HasPropertyPages
NOTE: the root node handler has to over-ride this function to
handle the snapin manager property page (wizard) case!!!
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CReplicationPartnersHandler::HasPropertyPages
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
if (dwType & TFS_COMPDATA_CREATE)
{
// This is the case where we are asked to bring up property
// pages when the user is adding a new snapin. These calls
// are forwarded to the root node to handle.
hr = hrOK;
}
else
{
// we have property pages in the normal case
hr = hrOK;
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::CreatePropertyPages
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CReplicationPartnersHandler::CreatePropertyPages
(
ITFSNode * pNode,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
Assert(pNode->GetData(TFS_DATA_COOKIE) != 0);
// get the server info
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
// Object gets deleted when the page is destroyed
SPIComponentData spComponentData;
m_spNodeMgr->GetComponentData(&spComponentData);
CRepNodeProperties * pRepProp =
new CRepNodeProperties( pNode,
spComponentData,
m_spTFSCompData,
NULL);
pRepProp->m_pageGeneral.m_uImage = (UINT) pNode->GetData(TFS_DATA_IMAGEINDEX);
pRepProp->SetConfig(&pServer->GetConfig());
Assert(lpProvider != NULL);
return pRepProp->CreateModelessSheet(lpProvider, handle);
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnPropertyChange
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnPropertyChange
(
ITFSNode * pNode,
LPDATAOBJECT pDataobject,
DWORD dwType,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CRepNodeProperties * pProp
= reinterpret_cast<CRepNodeProperties *>(lParam);
LONG_PTR changeMask = 0;
// tell the property page to do whatever now that we are back on the
// main thread
pProp->OnPropertyChange(TRUE, &changeMask);
pProp->AcknowledgeNotify();
if (changeMask)
pNode->ChangeNode(changeMask);
return hrOK;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::CompareItems
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(int)
CReplicationPartnersHandler::CompareItems
(
ITFSComponent * pComponent,
MMC_COOKIE cookieA,
MMC_COOKIE cookieB,
int nCol
)
{
SPITFSNode spNode1, spNode2;
m_spNodeMgr->FindNode(cookieA, &spNode1);
m_spNodeMgr->FindNode(cookieB, &spNode2);
int nCompare = 0;
CReplicationPartner *pRepPart1 = GETHANDLER(CReplicationPartner, spNode1);
CReplicationPartner *pRepPart2 = GETHANDLER(CReplicationPartner, spNode2);
switch (nCol)
{
case 0:
{
//
// Name compare
//
CString strName1 = pRepPart1->GetServerName();
nCompare = strName1.CompareNoCase(pRepPart2->GetServerName());
}
break;
case 1:
{
// compare the IP Addresses
CString strIp1, strIp2;
strIp1 = pRepPart1->GetIPAddress();
strIp2 = pRepPart2->GetIPAddress();
CIpAddress ipa1(strIp1);
CIpAddress ipa2(strIp2);
if ((LONG) ipa1 < (LONG) ipa2)
nCompare = -1;
else
if ((LONG) ipa1 > (LONG) ipa2)
nCompare = 1;
// default is equal
}
break;
case 2:
{
// compare the types
CString str1;
str1 = pRepPart1->GetType();
nCompare = str1.CompareNoCase(pRepPart2->GetType());
}
break;
}
return nCompare;
}
/*---------------------------------------------------------------------------
Command handlers
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnExpand
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject,
DWORD dwType,
LPARAM arg,
LPARAM param
)
{
HRESULT hr = hrOK;
if (m_bExpanded)
return hr;
BEGIN_WAIT_CURSOR
// read the values from the registry
hr = Load(pNode);
if (SUCCEEDED(hr))
{
// remove any nodes that may have been created before we were expanded.
pNode->DeleteAllChildren(FALSE);
hr = CreateNodes(pNode);
}
else
{
WinsMessageBox(WIN32_FROM_HRESULT(hr));
}
END_WAIT_CURSOR
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::CreateNodes(ITFSNode *pNode)
Adds the replication partnes to the result pane
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::CreateNodes
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
for (int i = 0; i < m_RepPartnersArray.GetSize(); i++)
{
SPITFSNode spRepNode;
CReplicationPartner * pRep =
new CReplicationPartner(m_spTFSCompData,
&m_RepPartnersArray.GetAt(i) );
CreateLeafTFSNode(&spRepNode,
&GUID_WinsReplicationPartnerLeafNodeType,
pRep,
pRep,
m_spNodeMgr);
// Tell the handler to initialize any specific data
pRep->InitializeNode((ITFSNode *) spRepNode);
// Add the node as a child to the Active Leases container
pNode->AddChild(spRepNode);
pRep->Release();
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::Load(ITFSNode *pNode)
Loads the rpelication partners by reading from the registry
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::Load
(
ITFSNode *pNode
)
{
DWORD err = ERROR_SUCCESS;
HRESULT hr = hrOK;
CString strServerName;
GetServerName(pNode, strServerName);
CString strTemp =_T("\\\\");
strServerName = strTemp + strServerName;
RegKey rkPull;
err = rkPull.Open(HKEY_LOCAL_MACHINE, (LPCTSTR) lpstrPullRoot, KEY_READ, strServerName);
if (err)
{
// might not be there, try to create
err = rkPull.Create(HKEY_LOCAL_MACHINE,
(LPCTSTR)lpstrPullRoot,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
strServerName);
}
RegKey rkPush;
err = rkPush.Open(HKEY_LOCAL_MACHINE, (LPCTSTR) lpstrPushRoot, KEY_READ, strServerName);
if (err)
{
err = rkPush.Create(HKEY_LOCAL_MACHINE,
(LPCTSTR)lpstrPushRoot,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
strServerName);
}
if (err)
return HRESULT_FROM_WIN32(err);
RegKeyIterator iterPushkey;
RegKeyIterator iterPullkey;
hr = iterPushkey.Init(&rkPush);
if (FAILED(hr))
return hr;
hr = iterPullkey.Init(&rkPull);
if (FAILED(hr))
return hr;
m_RepPartnersArray.RemoveAll();
CWinsServerObj ws;
CString strName;
// Read in push partners
hr = iterPushkey.Next(&strName, NULL);
while (hr != S_FALSE && SUCCEEDED(hr))
{
// Key name is the IP address.
ws.SetIpAddress(strName);
ws.SetstrIPAddress(strName);
CString strKey = (CString)lpstrPushRoot + _T("\\") + strName;
RegKey rk;
err = rk.Open(HKEY_LOCAL_MACHINE, strKey, KEY_READ, strServerName);
if (err)
{
hr = HRESULT_FROM_WIN32(err);
break;
}
if (err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
{
// This replication partner is does not have a netbios
// name listed with it. This is not a major problem,
// as the name is for display purposes only.
CString strTemp;
strTemp.LoadString(IDS_NAME_UNKNOWN);
ws.GetNetBIOSName() = strTemp;
}
DWORD dwTest;
if (rk.QueryValue(WINSCNF_UPDATE_COUNT_NM, (DWORD&) dwTest)
!= ERROR_SUCCESS)
{
ws.GetPushUpdateCount() = 0;
}
else
{
ws.GetPushUpdateCount() = dwTest;
}
ws.SetPush(TRUE, TRUE);
// check for the persistence stuff
dwTest = (rk.QueryValue(lpstrPersistence, dwTest) == ERROR_SUCCESS) ? dwTest : 0;
ws.SetPushPersistence(dwTest);
// Make sure the Pull intervals are reset.
ws.SetPull(FALSE, TRUE);
ws.GetPullReplicationInterval() = 0;
ws.GetPullStartTime() = (time_t)0;
m_RepPartnersArray.Add(ws);
hr = iterPushkey.Next(&strName, NULL);
}
if (FAILED(hr))
return hr;
// Read in pull partners
hr = iterPullkey.Next(&strName, NULL);
while (hr != S_FALSE && SUCCEEDED(hr))
{
// Key name is the IP address.
ws.SetIpAddress(strName);
ws.SetstrIPAddress(strName);
CString strKey = (CString)lpstrPullRoot + _T("\\") + strName;
RegKey rk;
err = rk.Open(HKEY_LOCAL_MACHINE, strKey, KEY_READ, strServerName);
if (err)
{
hr = HRESULT_FROM_WIN32(err);
break;
}
err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName());
if (err)
{
// No netbios name given.
CString strTemp;
strTemp.LoadString(IDS_NAME_UNKNOWN);
ws.GetNetBIOSName() = strTemp;
}
DWORD dwPullInt;
err = rk.QueryValue(WINSCNF_RPL_INTERVAL_NM, (DWORD &)dwPullInt);
if (err != ERROR_SUCCESS)
{
ws.GetPullReplicationInterval() = 0;
}
else
{
ws.GetPullReplicationInterval() = dwPullInt;
}
CString strSpTime;
err = rk.QueryValue(WINSCNF_SP_TIME_NM, strSpTime);
if (err != ERROR_SUCCESS)
{
ws.GetPullStartTime() = (time_t)0;
}
else
{
CIntlTime spTime(strSpTime);
ws.GetPullStartTime() = spTime;
}
DWORD dwTest = 0;
// check for the persistence stuff
dwTest = (rk.QueryValue(lpstrPersistence, dwTest) == ERROR_SUCCESS) ? dwTest : 0;
ws.SetPullPersistence(dwTest);
int pos;
CWinsServerObj wsTarget;
// If it's already in the list as a push partner,
// then simply set the push flag, as this replication
// partner is both a push and a pull partner.
if ((pos = IsInList(ws))!= -1)
{
wsTarget = (CWinsServerObj)m_RepPartnersArray.GetAt(pos);
ASSERT(wsTarget != NULL);
wsTarget.SetPull(TRUE, TRUE);
wsTarget.GetPullReplicationInterval() = ws.GetPullReplicationInterval();
wsTarget.GetPullStartTime() = ws.GetPullStartTime();
wsTarget.SetPullPersistence(ws.GetPullPersistence());
m_RepPartnersArray.SetAt(pos, wsTarget);
}
else
{
ws.SetPull(TRUE, TRUE);
ws.SetPullPersistence(dwTest);
// Reset push flags
ws.SetPush(FALSE, TRUE);
ws.GetPushUpdateCount() = 0;
m_RepPartnersArray.Add(ws);
}
hr = iterPullkey.Next(&strName, NULL);
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::IsInList
Checks if the given server is present in the list of
replication partners, returns a valid value if found
else returns -1
Author: v-shubk
---------------------------------------------------------------------------*/
int
CReplicationPartnersHandler::IsInList
(
const CIpNamePair& inpTarget,
BOOL bBoth
) const
{
CIpNamePair Current;
int pos1;
for (pos1 = 0;pos1 <m_RepPartnersArray.GetSize(); pos1++)
{
Current = (CIpNamePair)m_RepPartnersArray.GetAt(pos1);
if (Current.Compare(inpTarget, bBoth) == 0)
{
return pos1;
}
}
return -1;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::GetServerName
Gets the server name from the server node
Suthor:v-shubk
---------------------------------------------------------------------------*/
void
CReplicationPartnersHandler::GetServerName
(
ITFSNode * pNode,
CString & strName
)
{
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
strName = pServer->GetServerAddress();
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnReplicateNow(ITFSNode* pNode)
Send the replication triger to all it's partners
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnReplicateNow
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
if (IDYES != AfxMessageBox(IDS_REP_START_CONFIRM, MB_YESNO))
return hrOK;
int nItems = (int)m_RepPartnersArray.GetSize();
DWORD err;
for (int n = 0; n < nItems; n++)
{
CWinsServerObj ws;
ws = m_RepPartnersArray.GetAt(n);
BEGIN_WAIT_CURSOR
if (ws.IsPull())
{
if ((err = ::SendTrigger(pServer->GetBinding(), (LONG) ws.GetIpAddress(), FALSE, FALSE)) != ERROR_SUCCESS)
{
::WinsMessageBox(WIN32_FROM_HRESULT(err));
continue;
}
}
if (ws.IsPush())
{
if ((err = ::SendTrigger(pServer->GetBinding(), (LONG) ws.GetIpAddress(), TRUE, TRUE)) != ERROR_SUCCESS)
{
::WinsMessageBox(WIN32_FROM_HRESULT(err));
continue;
}
}
END_WAIT_CURSOR
}
if (err == ERROR_SUCCESS)
{
AfxMessageBox(IDS_REPL_QUEUED, MB_ICONINFORMATION);
}
return HRESULT_FROM_WIN32(err);
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnCreateRepPartner
Invokes new replication partner Wizard
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnCreateRepPartner
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// check to see if the user has access
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
if (!pServer->GetConfig().IsAdmin())
{
// access denied
WinsMessageBox(ERROR_ACCESS_DENIED);
return hr;
}
// the user has access. ask for the partner info
CNewReplicationPartner dlg;
dlg.m_spRepPartNode.Set(pNode);
dlg.m_pRepPartHandler = this;
if (dlg.DoModal() == IDOK)
{
// create the new replication partner
CWinsServerObj ws;
// grab the name and ip from the dlg
ws.SetstrIPAddress(dlg.m_strServerIp);
ws.SetIpAddress(dlg.m_strServerIp);
ws.SetNetBIOSName(dlg.m_strServerName);
// default is push/pull partner
ws.SetPush(TRUE, TRUE);
ws.SetPull(TRUE, TRUE);
ws.SetPullClean(TRUE);
ws.SetPushClean(TRUE);
DWORD dwErr = AddRegEntry(pNode, ws);
if (dwErr != ERROR_SUCCESS)
{
WinsMessageBox(dwErr);
}
else
{
HandleResultMessage(pNode);
}
}
return hrOK;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::Store(ITFSNode *pNode)
Adds the new replication partner info to the registry
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::Store
(
ITFSNode * pNode
)
{
DWORD err = ERROR_SUCCESS;
CString strServerName;
GetServerName(pNode, strServerName);
CString strTemp =_T("\\\\");
strServerName = strTemp + strServerName;
RegKey rkPull;
err = rkPull.Create(HKEY_LOCAL_MACHINE,
(LPCTSTR)lpstrPullRoot,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
strServerName);
RegKey rkPush;
err = rkPush.Create(HKEY_LOCAL_MACHINE,
(LPCTSTR)lpstrPushRoot,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
strServerName);
if (err)
return HRESULT_FROM_WIN32(err);
RegKeyIterator iterPushkey;
RegKeyIterator iterPullkey;
err = iterPushkey.Init(&rkPush);
err = iterPullkey.Init(&rkPull);
if (err)
return HRESULT_FROM_WIN32(err);
CWinsServerObj ws;
CString strName;
// Read in push partners
while ((err = iterPushkey.Next(&strName, NULL)) == ERROR_SUCCESS )
{
// Key name is the IP address.
ws.SetIpAddress(strName);
ws.SetstrIPAddress(strName);
CString strKey = (CString)lpstrPushRoot + _T("\\") + strName;
RegKey rk;
err = rk.Create(HKEY_LOCAL_MACHINE,
strKey,
0,
KEY_ALL_ACCESS,
NULL,
strServerName);
if (err)
{
return HRESULT_FROM_WIN32(err);
}
if (err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
{
// This replication partner is does not have a netbios
// name listed with it. This is not a major problem,
// as the name is for display purposes only.
CString strTemp;
strTemp.LoadString(IDS_NAME_UNKNOWN);
ws.GetNetBIOSName() = strTemp;
}
DWORD dwTest;
if (rk.QueryValue(WINSCNF_UPDATE_COUNT_NM, (DWORD&) dwTest) != ERROR_SUCCESS)
{
ws.GetPushUpdateCount() = 0;
}
ws.SetPush(TRUE, TRUE);
// Make sure the Pull intervals are reset.
ws.SetPull(FALSE, TRUE);
ws.GetPullReplicationInterval() = 0;
ws.GetPullStartTime() = (time_t)0;
m_RepPartnersArray.Add(ws);
}
// Read in pull partners
while ((err = iterPullkey.Next(&strName, NULL)) == ERROR_SUCCESS)
{
// Key name is the IP address.
ws.SetIpAddress(strName);
ws.SetstrIPAddress(strName);
CString strKey = (CString)lpstrPullRoot + _T("\\") + strName;
RegKey rk;
err = rk.Create(HKEY_LOCAL_MACHINE, strKey, 0, KEY_ALL_ACCESS, NULL, strServerName);
if (err)
{
return HRESULT_FROM_WIN32(err);
}
if (err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
{
// No netbios name given.
CString strTemp;
strTemp.LoadString(IDS_NAME_UNKNOWN);
ws.GetNetBIOSName() = strTemp;
}
DWORD dwPullInt;
if (rk.QueryValue(WINSCNF_RPL_INTERVAL_NM, (DWORD &)dwPullInt) != ERROR_SUCCESS)
{
ws.GetPullReplicationInterval() = 0;
}
else
{
ws.GetPullReplicationInterval() = dwPullInt;
}
if (rk.QueryValue(WINSCNF_SP_TIME_NM, (DWORD &)dwPullInt) != ERROR_SUCCESS)
{
ws.GetPullStartTime() = (time_t)0;
}
else
{
ws.GetPullStartTime() = (time_t)dwPullInt;
}
int pos;
CWinsServerObj wsTarget;
// If it's already in the list as a push partner,
// then simply set the push flag, as this replication
// partner is both a push and a pull partner.
if ((pos = IsInList(ws))!= -1)
{
wsTarget = (CWinsServerObj)m_RepPartnersArray.GetAt(pos);
ASSERT(wsTarget != NULL);
wsTarget.SetPull(TRUE, TRUE);
wsTarget.GetPullReplicationInterval() = ws.GetPullReplicationInterval();
wsTarget.GetPullStartTime() = ws.GetPullStartTime();
m_RepPartnersArray.SetAt(pos, wsTarget);
}
else
{
ws.SetPull(TRUE, TRUE);
// Reset push flags
ws.SetPush(FALSE, TRUE);
ws.GetPushUpdateCount() = 0;
m_RepPartnersArray.Add(ws);
}
}
return hrOK;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnResultDelete
Deletes replication partner
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnResultDelete
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM param
)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// translate the cookie into a node pointer
SPITFSNode spReplicationPartnersHandler, spSelectedNode;
m_spNodeMgr->FindNode(cookie, &spReplicationPartnersHandler);
pComponent->GetSelectedNode(&spSelectedNode);
Assert(spSelectedNode == spReplicationPartnersHandler);
if (spSelectedNode != spReplicationPartnersHandler)
return hr;
SPITFSNode spServerNode ;
spReplicationPartnersHandler->GetParent(&spServerNode);
CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spServerNode);
// build the list of selected nodes
CTFSNodeList listNodesToDelete;
hr = BuildSelectedItemList(pComponent, &listNodesToDelete);
// Confirm with the user
CString strMessage, strTemp;
int nNodes = (int)listNodesToDelete.GetCount();
if (nNodes > 1)
{
strTemp.Format(_T("%d"), nNodes);
AfxFormatString1(strMessage, IDS_DELETE_ITEMS, (LPCTSTR) strTemp);
}
else
{
strMessage.LoadString(IDS_DELETE_ITEM);
}
if (AfxMessageBox(strMessage, MB_YESNO) == IDNO)
{
return NOERROR;
}
BOOL fAskedPurge = FALSE;
BOOL fPurge = FALSE;
while (listNodesToDelete.GetCount() > 0)
{
SPITFSNode spRepNode;
spRepNode = listNodesToDelete.RemoveHead();
CReplicationPartner * pItem = GETHANDLER(CReplicationPartner , spRepNode);
CString str = pItem->GetServerName();
// Do we also need to remove all references to this
// WINS server from the database?
if (!fAskedPurge)
{
int nReturn = AfxMessageBox(IDS_MSG_PURGE_WINS, MB_YESNOCANCEL | MB_DEFBUTTON2 | MB_ICONQUESTION);
fAskedPurge = TRUE;
if (nReturn == IDYES)
{
fPurge = TRUE;
}
else if (nReturn == IDCANCEL)
{
//
// Forget the whole thing
//
return NOERROR;
}
}
CWinsServerObj pws = pItem->m_Server;
if (pws.IsPush() || pws.IsPull())
{
pws.SetPush(FALSE);
pws.SetPushClean(FALSE);
pws.SetPull(FALSE);
pws.SetPullClean(FALSE);
err = UpdateReg(spReplicationPartnersHandler, &pws);
}
if (err == ERROR_SUCCESS && fPurge)
{
BEGIN_WAIT_CURSOR
err = pServer->DeleteWinsServer((LONG) pws.GetIpAddress());
END_WAIT_CURSOR
}
if (err == ERROR_SUCCESS)
{
int pos = IsInList(pws);
m_RepPartnersArray.RemoveAt(pos,pws);
//
// Remove from UI now
//
spReplicationPartnersHandler->RemoveChild(spRepNode);
spRepNode.Release();
}
if (err != ERROR_SUCCESS)
{
if (::WinsMessageBox(err, MB_OKCANCEL) == IDCANCEL)
break;
}
}
HandleResultMessage(spReplicationPartnersHandler);
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnResultRefresh
Base handler override
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnResultRefresh
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
HRESULT hr = hrOK;
SPITFSNode spNode;
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
BEGIN_WAIT_CURSOR
OnRefreshNode(spNode, pDataObject);
END_WAIT_CURSOR
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CReplicationPartnersHandler::OnResultSelect
Handles the MMCN_SELECT notifcation
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnResultSelect
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
SPITFSNode spNode;
CORg(CWinsHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam));
m_spResultNodeMgr->FindNode(cookie, &spNode);
HandleResultMessage(spNode);
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CReplicationPartnersHandler::HandleResultMessage
Displays the message in the result pane
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::HandleResultMessage(ITFSNode * pNode)
{
HRESULT hr = hrOK;
if (m_RepPartnersArray.GetSize() == 0)
{
CString strTitle, strBody, strTemp;
int i;
strTitle.LoadString(IDS_REPLICATION_PARTNERS_MESSAGE_TITLE);
for (i = 0; ; i++)
{
if (guReplicationPartnersMessageStrings[i] == -1)
break;
strTemp.LoadString(guReplicationPartnersMessageStrings[i]);
strBody += strTemp;
}
ShowMessage(pNode, strTitle, strBody, Icon_Information);
}
else
{
ClearMessage(pNode);
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnRefreshNode
refreshes the list of replication partners
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnRefreshNode
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject
)
{
HRESULT hr = hrOK;
// remove the nodes first
hr = RemoveChildren(pNode);
hr = Load(pNode);
if (SUCCEEDED(hr))
{
DWORD err = CreateNodes(pNode);
HandleResultMessage(pNode);
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler:: RemoveChildren
Deletes the child nodes
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler:: RemoveChildren
(
ITFSNode* pNode
)
{
// enumerate thro' all the nodes
HRESULT hr = hrOK;
SPITFSNodeEnum spNodeEnum;
SPITFSNode spCurrentNode;
ULONG nNumReturned = 0;
// get the enumerator for this node
pNode->GetEnum(&spNodeEnum);
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
while (nNumReturned)
{
// walk the list of replication servers
pNode->RemoveChild(spCurrentNode);
spCurrentNode.Release();
// get the next Server in the list
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::OnGetResultViewType
Overridden for multiple selection
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CReplicationPartnersHandler::OnGetResultViewType
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPOLESTR * ppViewType,
long * pViewOptions
)
{
HRESULT hr = hrOK;
// call the base class to see if it is handling this
if (CWinsHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions) != S_OK)
{
*pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
hr = S_FALSE;
}
return hr;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::UpdateReg()
Updates the regisrty, called from OnApply()
---------------------------------------------------------------------------*/
DWORD
CReplicationPartnersHandler::UpdateReg(ITFSNode *pNode, CWinsServerObj* pws)
{
DWORD err = ERROR_SUCCESS;
HRESULT hr = hrOK;
CString strServerName;
GetServerName(pNode, strServerName);
const DWORD dwZero = 0;
CString strTemp =_T("\\\\");
strServerName = strTemp + strServerName;
RegKey rkPush;
RegKey rkPull;
CString strKey = lpstrPushRoot + _T("\\") + (CString)pws->GetstrIPAddress();
err = rkPush.Create(HKEY_LOCAL_MACHINE,
(CString)lpstrPushRoot,
0,
KEY_ALL_ACCESS,
NULL,
strServerName);
if (err)
return err;
strKey = lpstrPullRoot + _T("\\") + (CString)pws->GetstrIPAddress();
err = rkPull.Create(HKEY_LOCAL_MACHINE,
(CString)lpstrPullRoot,
0,
KEY_ALL_ACCESS,
NULL,
strServerName);
if (err)
return err;
RegKeyIterator iterPushkey;
RegKeyIterator iterPullkey;
hr = iterPushkey.Init(&rkPush);
if (FAILED(hr))
return WIN32_FROM_HRESULT(hr);
hr = iterPullkey.Init(&rkPull);
if (FAILED(hr))
return WIN32_FROM_HRESULT(hr);
DWORD errDel;
CString csKeyName;
// if none, delete the key from registry
if (!pws->IsPush() && !pws->IsPull())
{
// cleanup push partners list
hr = iterPushkey.Next (&csKeyName, NULL);
while (hr != S_FALSE && SUCCEEDED(hr))
{
if (csKeyName == pws->GetstrIPAddress())
{
errDel = RegDeleteKey (HKEY(rkPush), csKeyName);
iterPushkey.Reset();
}
hr = iterPushkey.Next (&csKeyName, NULL);
}
if (FAILED(hr))
err = WIN32_FROM_HRESULT(hr);
hr = iterPullkey.Next (&csKeyName, NULL);
while (hr != S_FALSE && SUCCEEDED(hr))
{
if (csKeyName == pws->GetstrIPAddress())
{
errDel = RegDeleteKey (HKEY(rkPull), csKeyName);
iterPullkey.Reset();
}
hr = iterPullkey.Next (&csKeyName, NULL);
}
if (FAILED(hr))
err = WIN32_FROM_HRESULT(hr);
}
return err;
}
/*---------------------------------------------------------------------------
CReplicationPartnersHandler::UpdateReg(ITFSNode *pNode,
CWinsServerObj* pws)
Creates a new replication partner entry
---------------------------------------------------------------------------*/
DWORD
CReplicationPartnersHandler::AddRegEntry(ITFSNode * pNode, CWinsServerObj & ws)
{
// get the server handler for default values
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
// Set the defaults
ws.SetPushUpdateCount(pServer->GetConfig().m_dwPushUpdateCount);
ws.SetPullReplicationInterval(pServer->GetConfig().m_dwPullTimeInterval);
ws.SetPullStartTime(pServer->GetConfig().m_dwPullSpTime);
ws.SetPullPersistence(pServer->GetConfig().m_dwPullPersistence);
ws.SetPushPersistence(pServer->GetConfig().m_dwPushPersistence);
// write the information to the registry
CString strTemp =_T("\\\\");
CString strServerName;
GetServerName(pNode, strServerName);
strServerName = strTemp + strServerName;
DWORD err;
DWORD dwZero = 0;
RegKey rk;
if (ws.IsPush())
{
CString strKey = lpstrPushRoot + _T("\\") + (CString)ws.GetstrIPAddress();
err = rk.Create(HKEY_LOCAL_MACHINE, strKey, 0, KEY_ALL_ACCESS, NULL, strServerName);
DWORD dwResult;
if (!err)
{
err = rk.SetValue(lpstrNetBIOSName, ws.GetNetBIOSName());
if (!err)
err = rk.QueryValue(WINSCNF_SELF_FND_NM, (DWORD&)dwResult);
if (err)
err = rk.SetValue(WINSCNF_SELF_FND_NM,(DWORD&) dwZero);
DWORD dwPushUpdateCount = (LONG) ws.GetPushUpdateCount();
if (dwPushUpdateCount > 0)
err = rk.SetValue(WINSCNF_UPDATE_COUNT_NM, (DWORD&)dwPushUpdateCount);
DWORD dwPersistence = ws.GetPushPersistence();
err = rk.SetValue(lpstrPersistence, dwPersistence);
}
}
if (ws.IsPull())
{
CString strKey = lpstrPullRoot + _T("\\") + (CString)ws.GetstrIPAddress();
err = rk.Create(HKEY_LOCAL_MACHINE, strKey, 0, KEY_ALL_ACCESS, NULL, strServerName);
DWORD dwResult;
if (!err)
{
err = rk.SetValue(lpstrNetBIOSName, ws.GetNetBIOSName());
if (!err)
err = rk.QueryValue(WINSCNF_SELF_FND_NM, dwResult);
if (err)
err = rk.SetValue(WINSCNF_SELF_FND_NM, (DWORD) dwZero);
DWORD dwPullTimeInterval = (LONG) ws.GetPullReplicationInterval();
if (dwPullTimeInterval > 0)
{
err = rk.SetValue(WINSCNF_RPL_INTERVAL_NM, dwPullTimeInterval);
}
DWORD dwSpTime = (DWORD) ws.GetPullStartTime();
if (!err)
{
if (dwSpTime > (time_t)0)
err = rk.SetValue(WINSCNF_SP_TIME_NM, ws.GetPullStartTime().IntlFormat(CIntlTime::TFRQ_MILITARY_TIME));
}
DWORD dwPersistence = ws.GetPullPersistence();
err = rk.SetValue(lpstrPersistence, dwPersistence);
}
}
if (err == ERROR_SUCCESS)
{
// add to the list of replication partners
m_RepPartnersArray.Add(ws);
SPITFSNode spNode;
SPITFSNodeMgr spNodeMgr;
pNode->GetNodeMgr(&spNodeMgr);
// Create a new node for this partner
CReplicationPartner *pRepNew = new CReplicationPartner(m_spTFSCompData, &ws);
CreateLeafTFSNode(&spNode,
&GUID_WinsReplicationPartnerLeafNodeType,
pRepNew,
pRepNew,
spNodeMgr);
// Tell the handler to initialize any specific data
pRepNew->InitializeNode((ITFSNode *) spNode);
pNode->AddChild(spNode);
pRepNew->Release();
}
return err;
}