/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/ /* croot.cpp WINS root node information (the root node is not displayed in the MMC framework but contains information such as all of the servers in this snapin). FILE HISTORY: */ #include "stdafx.h" #include "root.h" // definition for this file #include "snappp.h" // property pages for this node #include "server.h" // server node definitions #include "service.h" // Service routings #include "ncglobal.h" // network console global defines #include "status.h" // status node stuff #include "ipadddlg.h" // for adding WINS servers #include #include "..\tfscore\cluster.h" unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME"); #define WINS_MESSAGE_SIZE 576 #define ANSWER_TIMEOUT 20000 #define ROOT_MESSAGE_MAX_STRING 6 typedef enum _ROOT_MESSAGES { ROOT_MESSAGE_NO_SERVERS, ROOT_MESSAGE_MAX }; UINT g_uRootMessages[ROOT_MESSAGE_MAX][ROOT_MESSAGE_MAX_STRING] = { {IDS_ROOT_MESSAGE_TITLE, Icon_Information, IDS_ROOT_MESSAGE_BODY1, IDS_ROOT_MESSAGE_BODY2, IDS_ROOT_MESSAGE_BODY3, 0}, }; /*--------------------------------------------------------------------------- CWinsRootHandler::CWinsRootHandler Description Author: EricDav ---------------------------------------------------------------------------*/ CWinsRootHandler::CWinsRootHandler(ITFSComponentData *pCompData) : CWinsHandler(pCompData), m_dwFlags(0), m_dwUpdateInterval(5*60*1000) { m_nState = loaded; m_bMachineAdded = FALSE; } /*--------------------------------------------------------------------------- CWinsRootHandler::~CWinsRootHandler Cleanup function Author: EricDav ---------------------------------------------------------------------------*/ CWinsRootHandler::~CWinsRootHandler() { } /*-------------------------------------------------------------------------- CWinsRootHandler::InitializeNode Initializes node specific data Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::InitializeNode ( ITFSNode * pNode ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CString strDisp; strDisp.LoadString(IDS_ROOT_NODENAME); SetDisplayName(strDisp); m_fValidate = m_dwFlags & FLAG_VALIDATE_CACHE ? TRUE : FALSE; pNode->SetVisibilityState(TFS_VIS_SHOW); pNode->SetData(TFS_DATA_COOKIE, 0); pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_WINS_PRODUCT); pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_WINS_PRODUCT); pNode->SetData(TFS_DATA_USER, (LPARAM) this); pNode->SetData(TFS_DATA_TYPE, WINSSNAP_ROOT); SetColumnStringIDs(&aColumns[WINSSNAP_ROOT][0]); SetColumnWidths(&aColumnWidths[WINSSNAP_ROOT][0]); return hrOK; } /*--------------------------------------------------------------------------- Overridden base handler functions ---------------------------------------------------------------------------*/ /*!-------------------------------------------------------------------------- CWinsRootHandler::GetString Implementation of ITFSNodeHandler::GetString Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(LPCTSTR) CWinsRootHandler::GetString ( ITFSNode * pNode, int nCol ) { if (nCol == 0 || nCol == -1) return GetDisplayName(); else return NULL; } HRESULT CWinsRootHandler::SetGroupName(LPCTSTR pszGroupName) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strSnapinBaseName; strSnapinBaseName.LoadString(IDS_ROOT_NODENAME); CString szBuf; szBuf.Format(_T("%s %s"), (LPCWSTR)strSnapinBaseName, (LPCWSTR)pszGroupName); SetDisplayName(strSnapinBaseName); return hrOK; } HRESULT CWinsRootHandler::GetGroupName(CString * pstrGroupName) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strSnapinBaseName, strDisplayName; strSnapinBaseName.LoadString(IDS_ROOT_NODENAME); int nBaseLength = strSnapinBaseName.GetLength() + 1; // For the space strDisplayName = GetDisplayName(); if (strDisplayName.GetLength() == nBaseLength) pstrGroupName->Empty(); else *pstrGroupName = strDisplayName.Right(strDisplayName.GetLength() - nBaseLength); return hrOK; } /*--------------------------------------------------------------------------- CWinsRootHandler::OnExpand Handles enumeration of a scope item Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::OnExpand ( ITFSNode * pNode, LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg, LPARAM param ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = hrOK; CWinsStatusHandler *pStatus = NULL; SPITFSNodeHandler spHandler; SPITFSNode spRootNode; DWORD err = ERROR_SUCCESS; CString strServerName; DWORD dwIPVerified; BOOL fValidate; CVerifyWins *pDlg = NULL; if (m_bExpanded) return hr; // do the default handling hr = CWinsHandler::OnExpand(pNode, pDataObject, dwType, arg, param); if (dwType & TFS_COMPDATA_EXTENSION) { // we are extending somebody. Get the computer name // and check that machine hr = CheckMachine(pNode, pDataObject); } else { // only possibly add the local machine if the list is currently empty if (IsServerListEmpty(pNode)) { // check to see if we need to add the local machine to the list hr = CheckMachine(pNode, NULL); } // Create a handler for the node try { pStatus = new CWinsStatusHandler(m_spTFSCompData, m_dwUpdateInterval); // Do this so that it will get released correctly spHandler = pStatus; } catch(...) { hr = E_OUTOFMEMORY; } CORg( hr ); // Create the server container information CreateContainerTFSNode(&m_spStatusNode, &GUID_WinsServerStatusNodeType, pStatus, pStatus, m_spNodeMgr); // Tell the handler to initialize any specific data pStatus->InitializeNode((ITFSNode *) m_spStatusNode); pNode->AddChild(m_spStatusNode); } Error: return hr; } /*--------------------------------------------------------------------------- CWinsRootHandler::OnAddMenuItems Description Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CWinsRootHandler::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_ADD_SERVER); hr = LoadAndAddMenuItem( pContextMenuCallback, strMenuItem, IDS_ADD_SERVER, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0 ); ASSERT( SUCCEEDED(hr) ); } } return hr; } /*--------------------------------------------------------------------------- CWinsRootHandler::OnCommand Description Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CWinsRootHandler::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_ADD_SERVER: hr = OnCreateNewServer(pNode); break; default: break; } return hr; } /*!-------------------------------------------------------------------------- CWinsRootHandler::AddMenuItems Over-ride this to add our view menu item Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CWinsRootHandler::AddMenuItems ( ITFSComponent * pComponent, MMC_COOKIE cookie, LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long * pInsertionAllowed ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = S_OK; // figure out if we need to pass this to the scope pane menu handler hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed); return hr; } /*!-------------------------------------------------------------------------- CWinsRootHandler::Command Handles commands for the current view Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CWinsRootHandler::Command ( ITFSComponent * pComponent, MMC_COOKIE cookie, int nCommandID, LPDATAOBJECT pDataObject ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; switch (nCommandID) { case MMCC_STANDARD_VIEW_SELECT: break; // this may have come from the scope pane handler, so pass it up default: hr = HandleScopeCommand(cookie, nCommandID, pDataObject); break; } return hr; } /*!-------------------------------------------------------------------------- CWinsRootHandler::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 CWinsRootHandler::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 = hrFalse; } else { // we have property pages in the normal case hr = hrOK; } return hr; } /*--------------------------------------------------------------------------- CWinsRootHandler::CreatePropertyPages Description Author: EricDav ---------------------------------------------------------------------------*/ STDMETHODIMP CWinsRootHandler::CreatePropertyPages ( ITFSNode * pNode, LPPROPERTYSHEETCALLBACK lpProvider, LPDATAOBJECT pDataObject, LONG_PTR handle, DWORD dwType ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = hrOK; HPROPSHEETPAGE hPage; Assert(pNode->GetData(TFS_DATA_COOKIE) == 0); if (dwType & TFS_COMPDATA_CREATE) { // // We are loading this snapin for the first time, put up a property // page to allow them to name this thing. // //CSnapinWizName *pPage = new CSnapinWizName (this); //VERIFY(SUCCEEDED(MMCPropPageCallback(&pPage->m_psp))); //hPage = CreatePropertySheetPage(&pPage->m_psp); //if (hPage == NULL) // return E_UNEXPECTED; //Assert(lpProvider != NULL); //CORg ( lpProvider->AddPage(hPage) ); } else { // // Object gets deleted when the page is destroyed // SPIComponentData spComponentData; m_spNodeMgr->GetComponentData(&spComponentData); CSnapinProperties * pSnapinProp = new CSnapinProperties(pNode, spComponentData, m_spTFSCompData, NULL); Assert(lpProvider != NULL); return pSnapinProp->CreateModelessSheet(lpProvider, handle); } return hr; } /*--------------------------------------------------------------------------- CWinsRootHandler::OnPropertyChange Description Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::OnPropertyChange ( ITFSNode * pNode, LPDATAOBJECT pDataobject, DWORD dwType, LPARAM arg, LPARAM lParam ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CSnapinProperties * pSnapinProp = reinterpret_cast(lParam); // tell the property page to do whatever now that we are back on the // main thread LONG_PTR changeMask = 0; pSnapinProp->OnPropertyChange(TRUE, &changeMask); pSnapinProp->AcknowledgeNotify(); pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA); return hrOK; } /*--------------------------------------------------------------------------- CWinsRootHandler::OnRemoveChildren Description Author: FlorinT ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::OnRemoveChildren( ITFSNode * pNode, LPDATAOBJECT pDataObject, LPARAM arg, LPARAM param ) { HRESULT hr = hrOK; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; if (!m_bExpanded) return hr; m_bExpanded = FALSE; // do the default handling hr = CWinsHandler::OnRemoveChildren(pNode, pDataObject, arg, param); // get the enumerator for this node CORg(pNode->GetEnum(&spNodeEnum)); CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned)); // walk the list of child nodes and remove each node while (nNumReturned) { CORg (pNode->RemoveChild(spCurrentNode)); spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } Error: return hr; } /*!-------------------------------------------------------------------------- CWinsRootHandler::OnResultSelect For nodes with task pads, we override the select message to set the selected node. Nodes with taskpads do not get the MMCN_SHOW message which is where we normall set the selected node Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::OnResultSelect(ITFSComponent *pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = hrOK; SPIConsoleVerb spConsoleVerb; SPITFSNode spNode; CORg(CWinsHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam)); CORg (pComponent->GetConsoleVerb(&spConsoleVerb)); spConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, FALSE); spConsoleVerb->SetVerbState(MMC_VERB_RENAME, HIDDEN, TRUE); m_spNodeMgr->GetRootNode(&spNode); UpdateResultMessage(spNode); Error: return hr; } /*!-------------------------------------------------------------------------- CWinsRootHandler::UpdateResultMessage Determines what to display (if anything) in the result pane. Author: EricDav ---------------------------------------------------------------------------*/ void CWinsRootHandler::UpdateResultMessage(ITFSNode * pNode) { HRESULT hr = hrOK; int nMessage = ROOT_MESSAGE_NO_SERVERS; // default int i; CString strTitle, strBody, strTemp; if (!IsServerListEmpty(pNode)) { ClearMessage(pNode); } else { nMessage = ROOT_MESSAGE_NO_SERVERS; // now build the text strings // first entry is the title strTitle.LoadString(g_uRootMessages[nMessage][0]); // second entry is the icon // third ... n entries are the body strings for (i = 2; g_uRootMessages[nMessage][i] != 0; i++) { strTemp.LoadString(g_uRootMessages[nMessage][i]); strBody += strTemp; } ShowMessage(pNode, strTitle, strBody, (IconIdentifier) g_uRootMessages[nMessage][1]); } } /*--------------------------------------------------------------------------- Command handlers ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- CWinsRootHandler::OnCreateNewServer Description Author: EricDav Date Modified: 08/14/97 ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::OnCreateNewServer ( ITFSNode * pNode ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CNewWinsServer dlg; CThemeContextActivator themeActivator; dlg.m_spRootNode.Set(pNode); dlg.m_pRootHandler = this; if (dlg.DoModal() == IDOK) { AddServer(dlg.m_strServerName, TRUE, dlg.m_dwServerIp, FALSE, WINS_SERVER_FLAGS_DEFAULT, WINS_SERVER_REFRESH_DEFAULT, FALSE); UpdateResultMessage(pNode); } return hrOK; } /*--------------------------------------------------------------------------- CWinsRootHandler::AddServerSortedIp Description Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::AddServerSortedIp ( ITFSNode * pNewNode, BOOL bNewServer ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = hrOK; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; SPITFSNode spPrevNode; SPITFSNode spRootNode; ULONG nNumReturned = 0; CString strCurrent; CString strTarget; DWORD dwTarIP; DWORD dwCurIP; CWinsServerHandler * pServer; // get our target address pServer = GETHANDLER(CWinsServerHandler, pNewNode); strTarget = pServer->GetServerAddress(); dwTarIP = pServer->GetServerIP(); // need to get our node descriptor CORg(m_spNodeMgr->GetRootNode(&spRootNode)); // get the enumerator for this node CORg(spRootNode->GetEnum(&spNodeEnum)); CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned)); while (nNumReturned) { const GUID *pGuid ; pGuid = spCurrentNode->GetNodeType(); if(*pGuid == GUID_WinsServerStatusNodeType) { spPrevNode.Set(spCurrentNode); spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); continue; } // walk the list of servers and see if it exists pServer = GETHANDLER(CWinsServerHandler, spCurrentNode); strCurrent = pServer->GetServerAddress(); dwCurIP = pServer->GetServerIP(); // in case of servers being ordered by the name if (GetOrderByName()) { //if (strTarget.Compare(strCurrent) < 0) if (lstrcmp(strTarget, strCurrent) < 0) { // Found where we need to put it, break out break; } } // in case of servers being ordered by the IP else { // case where the server name not resolved if (dwTarIP == 0) break; if (dwCurIP > dwTarIP) { // Found where we need to put it, break out break; } } // get the next Server in the list spPrevNode.Set(spCurrentNode); spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } // Add the node in based on the PrevNode pointer if (spPrevNode) { if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL) { pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS); pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID)); } CORg(spRootNode->InsertChild(spPrevNode, pNewNode)); } else { CORg(spRootNode->AddChild(pNewNode)); } Error: return hr; } /*--------------------------------------------------------------------------- CWinsRootHandler::IsServerInList(ITFSNode *pRootNode, CString strNewAddr) Checks if a particular servers name already exists ---------------------------------------------------------------------------*/ BOOL CWinsRootHandler::IsServerInList(ITFSNode *pRootNode, CString strNewAddr) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // enumerate thro' all the nodes HRESULT hr = hrOK; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; BOOL bFound = FALSE; // get the enumerator for this node pRootNode->GetEnum(&spNodeEnum); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); while (nNumReturned) { // if the status node encountered, just iterate const GUID *pGuid; pGuid = spCurrentNode->GetNodeType(); if(*pGuid == GUID_WinsServerStatusNodeType) { // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); continue; } // walk the list of servers and see if it already exists CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spCurrentNode); CString strCurAddr = pServer->GetServerAddress(); if (strNewAddr.CompareNoCase(strCurAddr) == 0) { bFound = TRUE; break; } // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } return bFound; } /*--------------------------------------------------------------------------- CWinsRootHandler::IsIPInList(ITFSNode *pRootNode, DWORD dwNewAddr) Checks if a partiular IP address is alreay listed ---------------------------------------------------------------------------*/ BOOL CWinsRootHandler::IsIPInList(ITFSNode *pRootNode, DWORD dwNewAddr) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // enumerate thro' all the nodes HRESULT hr = hrOK; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; BOOL bFound = FALSE; // get the enumerator for this node pRootNode->GetEnum(&spNodeEnum); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); while (nNumReturned) { // just iterate if the status node enountered const GUID *pGuid; pGuid = spCurrentNode->GetNodeType(); if(*pGuid == GUID_WinsServerStatusNodeType) { // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); continue; } // walk the list of servers and see if it already exists CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spCurrentNode); DWORD dwIPCur = pServer->GetServerIP(); if (dwNewAddr == dwIPCur) { bFound = TRUE; break; } // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } return bFound; } /*--------------------------------------------------------------------------- CWinsRootHandler::AddServer Description Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::AddServer ( LPCWSTR pServerName, BOOL bNewServer, DWORD dwIP, BOOL fConnected, DWORD dwFlags, DWORD dwRefreshInterval, BOOL fValidateNow ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = hrOK; CWinsServerHandler *pWinsServer = NULL; SPITFSNodeHandler spHandler; SPITFSNode spNode, spRootNode; DWORD err = ERROR_SUCCESS; CString strServerName; DWORD dwIPVerified; BOOL fValidate; CVerifyWins *pDlg = NULL; // if the validate servers caption is on, validate the server // before adding it if ((m_dwFlags & FLAG_VALIDATE_CACHE) && m_fValidate && fValidateNow) { CString strServerNameIP(pServerName); if (m_dlgVerify.GetSafeHwnd() == NULL) { m_dlgVerify.Create(IDD_VERIFY_WINS); } // check the current server CString strDisp; strDisp = _T("\\\\") + strServerNameIP; m_dlgVerify.SetServerName(strDisp); BEGIN_WAIT_CURSOR err = ::VerifyWinsServer(strServerNameIP, strServerName, dwIPVerified); END_WAIT_CURSOR if (err == ERROR_SUCCESS) { pServerName = strServerName; dwIP = dwIPVerified; } // process some messages since we were dead while verifying MSG msg; while (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if (m_dlgVerify.IsCancelPressed()) { m_fValidate = FALSE; m_dlgVerify.Dismiss(); } } if (err) { // display a message Box asking if the node is to be removed CString strMessage; AfxFormatString1(strMessage, IDS_MSG_VALIDATE, pServerName); CThemeContextActivator themeActivator; int nRet = AfxMessageBox(strMessage, MB_YESNOCANCEL); if (nRet == IDYES) { return hrOK; } else if (nRet == IDCANCEL) { m_dlgVerify.Dismiss(); m_fValidate = FALSE; } } // Create a handler for the node try { pWinsServer = new CWinsServerHandler(m_spTFSCompData, pServerName, FALSE, dwIP, dwFlags, dwRefreshInterval); // Do this so that it will get released correctly spHandler = pWinsServer; } catch(...) { hr = E_OUTOFMEMORY; } CORg( hr ); // Create the server container information CreateContainerTFSNode(&spNode, &GUID_WinsServerNodeType, pWinsServer, pWinsServer, m_spNodeMgr); // Tell the handler to initialize any specific data pWinsServer->InitializeNode((ITFSNode *) spNode); // tell the server how to display it's name if (dwFlags & FLAG_EXTENSION) { m_bMachineAdded = TRUE; pWinsServer->SetExtensionName(); } else { pWinsServer->SetDisplay(NULL, GetShowLongName()); } AddServerSortedIp(spNode, bNewServer); if (bNewServer) { // need to get our node descriptor CORg(m_spNodeMgr->GetRootNode(&spRootNode)); spRootNode->SetData(TFS_DATA_DIRTY, TRUE); // add a node to the status list AddStatusNode(spRootNode, pWinsServer); } Error: return hr; } /*!-------------------------------------------------------------------------- CBaseResultHandler::LoadColumns - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::LoadColumns(ITFSComponent * pComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); SPIHeaderCtrl spHeaderCtrl; pComponent->GetHeaderCtrl(&spHeaderCtrl); CString str; int i = 0; CString strDisp, strTemp; GetGroupName(&strDisp); int nPos = strDisp.Find(_T("[")); strTemp = strDisp.Right(strDisp.GetLength() - nPos -1); strTemp = strTemp.Left(strTemp.GetLength() - 1); while (i < ARRAYLEN(aColumnWidths[WINSSNAP_ROOT])) { if (i == 0) { if(nPos != -1) { AfxFormatString1(str, IDS_ROOT_NAME, strTemp); } else { str.LoadString(IDS_ROOT_NODENAME); } int nTest = spHeaderCtrl->InsertColumn(i, const_cast((LPCWSTR)str), LVCFMT_LEFT, aColumnWidths[WINSSNAP_ROOT][0]); i++; } else if (i == 1) { str.LoadString(IDS_STATUS); int nTest = spHeaderCtrl->InsertColumn(1, const_cast((LPCWSTR)str), LVCFMT_LEFT, aColumnWidths[WINSSNAP_ROOT][1]); i++; } if (aColumns[WINSSNAP_ROOT][i] == 0) break; } return hrOK; } /*--------------------------------------------------------------------------- CWinsRootHandler::CheckMachine Checks to see if the WINS server service is running on the local machine. If it is, it adds it to the list of servers. Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CWinsRootHandler::CheckMachine ( ITFSNode * pRootNode, LPDATAOBJECT pDataObject ) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); HRESULT hr = hrOK; // Get the local machine name and check to see if the service // is installed. CString strMachineName; CString strIp; LPTSTR pBuf; DWORD dwLength = MAX_COMPUTERNAME_LENGTH + 1; BOOL bExtension = (pDataObject != NULL); if (!bExtension) { // just check the local machine pBuf = strMachineName.GetBuffer(dwLength); GetComputerName(pBuf, &dwLength); strMachineName.ReleaseBuffer(); } else { // get the machine name from the data object strMachineName = Extract(pDataObject, (CLIPFORMAT) g_cfMachineName, COMPUTERNAME_LEN_MAX); } if (strMachineName.IsEmpty()) { DWORD dwSize = 256; LPTSTR pBuf = strMachineName.GetBuffer(dwSize); GetComputerName(pBuf, &dwSize); strMachineName.ReleaseBuffer(); } if (bExtension) RemoveOldEntries(pRootNode, strMachineName); // // if the local machine is part of a cluster, get the WINS resource // IP to use instead of the local machine. // if (::FIsComputerInRunningCluster(strMachineName)) { if (GetClusterResourceIp(strMachineName, _T("WINS Service"), strIp) == ERROR_SUCCESS) { strMachineName = strIp; } } BOOL bServiceRunning; DWORD dwError = ::TFSIsServiceRunning(strMachineName, _T("WINS"), &bServiceRunning); if (dwError != ERROR_SUCCESS || !bServiceRunning) { // The following condition could happen to get here: // o The service is not installed. // o Couldn't access for some reason. // o The service isn't running. // Don't add to the list. return hrOK; } // OK. The service is installed, so lets get the IP address for the machine // and add it to the list. DWORD dwIp; SPITFSNodeHandler spHandler; SPITFSNodeMgr spNodeMgr; CWinsServerHandler * pServer = NULL; SPITFSNode spNode; CString strName; if (::VerifyWinsServer(strMachineName, strName, dwIp) == ERROR_SUCCESS) { strIp.Empty(); MakeIPAddress(dwIp, strIp); if (IsServerInList(pRootNode, strName)) return hr; // looks good, add to list try { pServer = new CWinsServerHandler(m_spTFSCompData, (LPCTSTR) strName, FALSE, dwIp ); // Do this so that it will get released correctly spHandler = pServer; } catch(...) { hr = E_OUTOFMEMORY; } CORg(hr); pRootNode->GetNodeMgr(&spNodeMgr); // // Store the server object in the holder // CreateContainerTFSNode(&spNode, &GUID_WinsServerNodeType, pServer, pServer, spNodeMgr); // Tell the handler to initialize any specific data pServer->InitializeNode((ITFSNode *) spNode); if (bExtension) { pServer->m_dwFlags |= FLAG_EXTENSION; pServer->SetExtensionName(); } AddServerSortedIp(spNode, TRUE); // mark the data as dirty so that we'll ask the user to save. pRootNode->SetData(TFS_DATA_DIRTY, TRUE); m_bMachineAdded = TRUE; } Error: return hr; } // when running as an extension, it is possible that we were saved as "local machine" // which means that if the saved console file was moved to another machine we need to remove // the old entry that was saved HRESULT CWinsRootHandler::RemoveOldEntries(ITFSNode * pNode, LPCTSTR pszAddr) { HRESULT hr = hrOK; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; CWinsServerHandler * pServer; CString strCurAddr; // get the enumerator for this node CORg(pNode->GetEnum(&spNodeEnum)); CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned)); while (nNumReturned) { // walk the list of servers and see if it already exists pServer = GETHANDLER(CWinsServerHandler, spCurrentNode); strCurAddr = pServer->GetServerAddress(); //if (strCurAddr.CompareNoCase(pszAddr) != 0) { CORg (pNode->RemoveChild(spCurrentNode)); } spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } Error: return hr; } void CWinsRootHandler::AddStatusNode(ITFSNode * pRoot, CWinsServerHandler * pServer) { SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; // get the enumerator for this node pRoot->GetEnum(&spNodeEnum); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); while (nNumReturned) { // iterate to teh next node, if the status handler node is seen const GUID* pGuid; pGuid = spCurrentNode->GetNodeType(); if (*pGuid == GUID_WinsServerStatusNodeType) { CWinsStatusHandler * pStatus = GETHANDLER(CWinsStatusHandler, spCurrentNode); pStatus->AddNode(spCurrentNode, pServer); break; } // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } } BOOL CWinsRootHandler::IsServerListEmpty(ITFSNode * pRoot) { BOOL fEmpty = TRUE; SPITFSNodeEnum spNodeEnum; SPITFSNode spCurrentNode; ULONG nNumReturned = 0; // get the enumerator for this node pRoot->GetEnum(&spNodeEnum); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); while (nNumReturned) { const GUID* pGuid; pGuid = spCurrentNode->GetNodeType(); if (*pGuid != GUID_WinsServerStatusNodeType) { fEmpty = FALSE; break; } // get the next Server in the list spCurrentNode.Release(); spNodeEnum->Next(1, &spCurrentNode, &nNumReturned); } return fEmpty; }