/**********************************************************************/ /** 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(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 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; CThemeContextActivator themeActivator; 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; CThemeContextActivator themeActivator; 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; CThemeContextActivator themeActivator; 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; }