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

2419 lines
60 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
server.cpp
WINS server node information.
FILE HISTORY:
*/
#include "stdafx.h"
#include "winssnap.h"
#include "root.h"
#include "Srvlatpp.h"
#include "actreg.h"
#include "reppart.h"
#include "server.h"
#include "svrstats.h"
#include "shlobj.h"
#include "cprogdlg.h"
#include "status.h"
#include "tregkey.h"
#include "verify.h"
#include "pushtrig.h"
#include "ipadddlg.h"
#include <service.h>
#define NB_NAME_MAX_LENGTH 16 // Max length for NetBIOS names
#define LM_NAME_MAX_LENGTH 15 // Maximum length for Lanman-compatible
// NetBIOS Name.
#define DOMAINNAME_LENGTH 255
#define HOSTNAME_LENGTH 16
CNameCache g_NameCache;
int BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
int i;
switch (uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
break;
}
return 0;
}
/*---------------------------------------------------------------------------
CNameThread
Background thread that resolves names
Author: EricDav
---------------------------------------------------------------------------*/
CNameThread::CNameThread()
{
m_bAutoDelete = FALSE;
m_hEventHandle = NULL;
m_pServerInfoArray = NULL;
}
CNameThread::~CNameThread()
{
if (m_hEventHandle != NULL)
{
VERIFY(::CloseHandle(m_hEventHandle));
m_hEventHandle = NULL;
}
}
void CNameThread::Init(CServerInfoArray * pServerInfoArray)
{
m_pServerInfoArray = pServerInfoArray;
}
BOOL CNameThread::Start()
{
ASSERT(m_hEventHandle == NULL); // cannot call start twice or reuse the same C++ object
m_hEventHandle = ::CreateEvent(NULL,TRUE /*bManualReset*/,FALSE /*signalled*/, NULL);
if (m_hEventHandle == NULL)
return FALSE;
return CreateThread();
}
void CNameThread::Abort(BOOL fAutoDelete)
{
if (!IsRunning() && fAutoDelete)
{
delete this;
}
else
{
m_bAutoDelete = fAutoDelete;
SetEvent(m_hEventHandle);
}
}
void CNameThread::AbortAndWait()
{
Abort(FALSE);
WaitForSingleObject(m_hThread, INFINITE);
}
BOOL CNameThread::IsRunning()
{
if (WaitForSingleObject(m_hThread, 0) == WAIT_OBJECT_0)
{
return FALSE;
}
else
{
return TRUE;
}
}
int CNameThread::Run()
{
Assert(m_pServerInfoArray);
//
// fill in the host names for each owner in the list
//
UpdateNameCache();
if (FCheckForAbort())
return 29;
for (int i = 0; i < m_pServerInfoArray->GetSize(); i++)
{
if (FCheckForAbort())
break;
DWORD dwIp = m_pServerInfoArray->GetAt(i).m_dwIp;
if (dwIp != 0)
{
CString strName;
if (!GetNameFromCache(dwIp, strName))
{
GetHostName(dwIp, strName);
CNameCacheEntry cacheEntry;
cacheEntry.m_dwIp = dwIp;
cacheEntry.m_strName = strName;
cacheEntry.m_timeLastUpdate.GetCurrentTime();
g_NameCache.Add(cacheEntry);
Trace2("CNameThread::Run - GetHostName for %lx returned %s\n", dwIp, strName);
}
if (FCheckForAbort())
break;
(*m_pServerInfoArray)[i].m_strName = strName;
}
}
return 29; // exit code so I can tell when the thread goes away
}
BOOL CNameThread::FCheckForAbort()
{
if (WaitForSingleObject(m_hEventHandle, 0) == WAIT_OBJECT_0)
{
Trace0("CNameThread::Run - abort detected, exiting...\n");
return TRUE;
}
else
{
return FALSE;
}
}
void CNameThread::UpdateNameCache()
{
CTime time;
time = CTime::GetCurrentTime();
CTimeSpan timespan(0, 1, 0, 0); // 1 hour
for (int i = 0; i < g_NameCache.GetSize(); i++)
{
if (g_NameCache[i].m_timeLastUpdate < (time - timespan))
{
CString strName;
GetHostName(g_NameCache[i].m_dwIp, strName);
g_NameCache[i].m_strName = strName;
if (FCheckForAbort())
break;
}
}
}
BOOL CNameThread::GetNameFromCache(DWORD dwIp, CString & strName)
{
BOOL fFound = FALSE;
for (int i = 0; i < g_NameCache.GetSize(); i++)
{
if (g_NameCache[i].m_dwIp == dwIp)
{
strName = g_NameCache[i].m_strName;
fFound = TRUE;
break;
}
}
return fFound;
}
/*---------------------------------------------------------------------------
Constructor and destructor
Description
Author: EricDav
---------------------------------------------------------------------------*/
CWinsServerHandler::CWinsServerHandler
(
ITFSComponentData * pComponentData,
LPCWSTR pServerName,
BOOL fConnected,
DWORD dwIp,
DWORD dwFlags,
DWORD dwRefreshInterval
) : CMTWinsHandler(pComponentData),
m_dwFlags(dwFlags),
m_dwRefreshInterval(dwRefreshInterval),
m_hBinding(NULL)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_strServerAddress = pServerName;
m_fConnected = fConnected;
m_dwIPAdd = dwIp;
m_hBinding = NULL;
m_bExtension = FALSE;
m_pNameThread = NULL;
strcpy(szIPMon, "");
}
/*---------------------------------------------------------------------------
Constructor and destructor
Description
Author: EricDav
---------------------------------------------------------------------------*/
CWinsServerHandler::~CWinsServerHandler()
{
HWND hStatsWnd;
// Check to see if this node has a stats sheet up.
hStatsWnd = m_dlgStats.GetSafeHwnd();
if (hStatsWnd != NULL)
{
m_dlgStats.KillRefresherThread();
}
// diconnect from server and make the handle invalid
DisConnectFromWinsServer();
// kill the name query thread if exists
if (m_pNameThread)
{
m_pNameThread->AbortAndWait();
delete m_pNameThread;
}
}
/*!--------------------------------------------------------------------------
CWinsServerHandler::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CString IPAdd;
CString strDisp;
if (m_dwIPAdd != 0)
{
MakeIPAddress(m_dwIPAdd, IPAdd);
strDisp.Format(IDS_SERVER_NAME_FORMAT, m_strServerAddress, IPAdd);
}
else
{
strDisp = m_strServerAddress;
}
SetDisplayName(strDisp);
if (m_fConnected)
{
m_nState = loaded;
}
else
{
m_nState = notLoaded;
}
pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, WINSSNAP_SERVER);
SetColumnStringIDs(&aColumns[WINSSNAP_SERVER][0]);
SetColumnWidths(&aColumnWidths[WINSSNAP_SERVER][0]);
return hrOK;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnCreateNodeId2
Returns a unique string for this node
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CWinsServerHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
{
const GUID * pGuid = pNode->GetNodeType();
CString strGuid;
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
strGuid.ReleaseBuffer();
strId = m_strServerAddress + strGuid;
return hrOK;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::GetImageIndex
Description
Author: EricDav
---------------------------------------------------------------------------*/
int
CWinsServerHandler::GetImageIndex(BOOL bOpenImage)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
int nIndex = 0;
switch (m_nState)
{
case notLoaded:
nIndex = ICON_IDX_SERVER;
break;
case loaded:
nIndex = ICON_IDX_SERVER_CONNECTED;
m_strConnected.LoadString(IDS_SERVER_CONNECTED);
break;
case unableToLoad:
if (m_dwErr == ERROR_ACCESS_DENIED)
{
nIndex = ICON_IDX_SERVER_NO_ACCESS;
}
else
{
nIndex = ICON_IDX_SERVER_LOST_CONNECTION;
}
m_strConnected.LoadString(IDS_SERVER_NOTCONNECTED);
break;
case loading:
nIndex = ICON_IDX_SERVER_BUSY;
break;
default:
ASSERT(FALSE);
}
return nIndex;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnHaveData
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CWinsServerHandler::OnHaveData
(
ITFSNode * pParentNode,
ITFSNode * pNewNode
)
{
// expand the node so that child nodes appear correctly
LONG_PTR dwType = pNewNode->GetData(TFS_DATA_TYPE);
switch (dwType)
{
case WINSSNAP_ACTIVE_REGISTRATIONS:
{
CActiveRegistrationsHandler * pActReg = GETHANDLER(CActiveRegistrationsHandler, pNewNode);
pActReg->SetServer(pParentNode);
m_spActiveReg.Set(pNewNode);
}
break;
case WINSSNAP_REPLICATION_PARTNERS:
m_spReplicationPartner.Set(pNewNode);
break;
default:
Assert("Invalid node types passed back to server handler!");
break;
}
pParentNode->AddChild(pNewNode);
// now tell the view to update themselves
ExpandNode(pParentNode, TRUE);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnHaveData
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CWinsServerHandler::OnHaveData
(
ITFSNode * pParentNode,
LPARAM Data,
LPARAM Type
)
{
// This is how we get non-node data back from the background thread.
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
switch (Type)
{
case WINS_QDATA_SERVER_INFO:
{
CServerData * pServerInfo = (CServerData *) Data;
DisConnectFromWinsServer();
m_hBinding = pServerInfo->m_hBinding;
m_dwIPAdd = pServerInfo->m_dwServerIp;
m_strServerAddress = pServerInfo->m_strServerName;
m_cConfig = pServerInfo->m_config;
// update the name string
if (!m_bExtension)
{
SPITFSNode spRoot;
CWinsRootHandler * pRoot;
m_spNodeMgr->GetRootNode(&spRoot);
pRoot = GETHANDLER(CWinsRootHandler, spRoot);
SetDisplay(pParentNode, pRoot->GetShowLongName());
}
delete pServerInfo;
}
break;
}
}
/*---------------------------------------------------------------------------
Overridden base handler functions
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
CWinsServerHandler::OnAddMenuItems
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerHandler::OnAddMenuItems
(
ITFSNode * pNode,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
LPDATAOBJECT lpDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
LONG fFlags = 0, fLoadingFlags = 0, f351Flags = 0, fAdminFlags = 0;
HRESULT hr = S_OK;
CString strMenuItem;
BOOL b351 = FALSE;
if ( m_nState != loaded )
{
fFlags |= MF_GRAYED;
}
if ( m_nState == loading)
{
fLoadingFlags = MF_GRAYED;
}
if (!m_cConfig.IsAdmin())
{
fAdminFlags = MF_GRAYED;
}
if (type == CCT_SCOPE)
{
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
strMenuItem.LoadString(IDS_SHOW_SERVER_STATS);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SHOW_SERVER_STATS,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
// separator
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
0,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
MF_SEPARATOR);
ASSERT( SUCCEEDED(hr) );
// scavenge
strMenuItem.LoadString(IDS_SERVER_SCAVENGE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_SCAVENGE,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
// check if 351 server is being managed
if ( m_nState == loaded )
b351 = CheckIfNT351Server();
// yes? grey out the consistency check items
if(b351)
f351Flags |= MF_GRAYED;
else
f351Flags &= ~MF_GRAYED;
// only available to admins
strMenuItem.LoadString(IDS_DO_CONSISTENCY_CHECK);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_DO_CONSISTENCY_CHECK,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
f351Flags | fFlags | fAdminFlags);
ASSERT( SUCCEEDED(hr) );
// only available to admins
strMenuItem.LoadString(IDS_CHECK_VERSION_CONSISTENCY);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_CHECK_VERSION_CONSISTENCY,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
f351Flags | fFlags | fAdminFlags);
ASSERT( SUCCEEDED(hr) );
// separator
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
0,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
MF_SEPARATOR);
ASSERT( SUCCEEDED(hr) );
// replication triggers
strMenuItem.LoadString(IDS_REP_SEND_PUSH_TRIGGER);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_REP_SEND_PUSH_TRIGGER,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
strMenuItem.LoadString(IDS_REP_SEND_PULL_TRIGGER);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_REP_SEND_PULL_TRIGGER,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
// separator
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
0,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
MF_SEPARATOR);
ASSERT( SUCCEEDED(hr) );
// enable backp and restore database only for local servers
if(IsLocalConnection() && m_nState == loaded)
fFlags &= ~MF_GRAYED;
else
fFlags |= MF_GRAYED;
strMenuItem.LoadString(IDS_SERVER_BACKUP);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_BACKUP,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
// default is to not show this item
fFlags |= MF_GRAYED;
BOOL fServiceRunning = TRUE;
::TFSIsServiceRunning(m_strServerAddress, _T("WINS"), &fServiceRunning);
if (IsLocalConnection() && m_cConfig.IsAdmin())
{
// the service call can be costly if doing it remotely, so only do it
// when we really need to.
if (!fServiceRunning)
fFlags &= ~MF_GRAYED;
}
strMenuItem.LoadString(IDS_SERVER_RESTORE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_RESTORE,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
fFlags );
ASSERT( SUCCEEDED(hr) );
}
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
{
// start/stop service menu items
if ( m_nState == notLoaded ||
m_nState == loading)
{
fFlags = MF_GRAYED;
}
else
{
fFlags = 0;
}
DWORD dwServiceStatus, dwErrorCode, dwErr;
dwErr = ::TFSGetServiceStatus(m_strServerAddress, _T("wins"), &dwServiceStatus, &dwErrorCode);
if (dwErr != ERROR_SUCCESS)
fFlags |= MF_GRAYED;
// determining the restart state is the same as the stop flag
LONG lStartFlag = (dwServiceStatus == SERVICE_STOPPED) ? 0 : MF_GRAYED;
LONG lStopFlag = ( (dwServiceStatus == SERVICE_RUNNING) ||
(dwServiceStatus == SERVICE_PAUSED) ) ? 0 : MF_GRAYED;
LONG lPauseFlag = ( (dwServiceStatus == SERVICE_RUNNING) ||
( (dwServiceStatus != SERVICE_PAUSED) &&
(dwServiceStatus != SERVICE_STOPPED) ) ) ? 0 : MF_GRAYED;
LONG lResumeFlag = (dwServiceStatus == SERVICE_PAUSED) ? 0 : MF_GRAYED;
strMenuItem.LoadString(IDS_SERVER_START_SERVICE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_START_SERVICE,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags | lStartFlag);
strMenuItem.LoadString(IDS_SERVER_STOP_SERVICE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_STOP_SERVICE,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags | lStopFlag);
strMenuItem.LoadString(IDS_SERVER_PAUSE_SERVICE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_PAUSE_SERVICE,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags | lPauseFlag);
strMenuItem.LoadString(IDS_SERVER_RESUME_SERVICE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_RESUME_SERVICE,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags | lResumeFlag);
strMenuItem.LoadString(IDS_SERVER_RESTART_SERVICE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_RESTART_SERVICE,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags | lStopFlag);
/* Don't do this in the snapin, go back to the old command prompt way
strMenuItem.LoadString(IDS_SERVER_COMPACT);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_SERVER_COMPACT,
CCM_INSERTIONPOINTID_PRIMARY_TASK,
fFlags );
ASSERT( SUCCEEDED(hr) );
*/
}
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnCommand
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerHandler::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_SHOW_SERVER_STATS:
ShowServerStatDialog(pNode);
break;
case IDS_SERVER_BACKUP:
DoDBBackup(pNode);
break;
case IDS_SERVER_SCAVENGE:
DoDBScavenge(pNode);
break;
case IDS_SERVER_COMPACT:
DoDBCompact(pNode);
break;
case IDS_SERVER_RESTORE:
DoDBRestore(pNode);
break;
case IDS_DO_CONSISTENCY_CHECK:
OnDoConsistencyCheck(pNode);
break;
case IDS_CHECK_VERSION_CONSISTENCY:
OnDoVersionConsistencyCheck(pNode);
break;
case IDS_REP_SEND_PUSH_TRIGGER:
hr = OnSendPushTrigger(pNode);
break;
case IDS_REP_SEND_PULL_TRIGGER:
hr = OnSendPullTrigger(pNode);
break;
case IDS_SERVER_STOP_SERVICE:
hr = OnControlService(pNode, FALSE);
break;
case IDS_SERVER_START_SERVICE:
hr = OnControlService(pNode, TRUE);
break;
case IDS_SERVER_PAUSE_SERVICE:
hr = OnPauseResumeService(pNode, TRUE);
break;
case IDS_SERVER_RESUME_SERVICE:
hr = OnPauseResumeService(pNode, FALSE);
break;
case IDS_SERVER_RESTART_SERVICE:
hr = OnRestartService(pNode);
break;
default:
break;
}
return hr;
}
/*!--------------------------------------------------------------------------
CWinsServerHandler::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
CWinsServerHandler::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;
Assert(FALSE); // should never get here
}
else
{
// we have property pages in the normal case, but don't put the
// menu up if we are not loaded yet
if ( m_nState != loaded )
{
hr = hrFalse;
}
else
{
hr = hrOK;
}
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::CreatePropertyPages
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerHandler::CreatePropertyPages
(
ITFSNode * pNode,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
HPROPSHEETPAGE hPage;
SPIComponentData spComponentData;
Assert(pNode->GetData(TFS_DATA_COOKIE) != 0);
//
// Object gets deleted when the page is destroyed
//
m_spNodeMgr->GetComponentData(&spComponentData);
ConnectToWinsServer(pNode);
// to read the values from the registry
DWORD err = m_cConfig.Load(GetBinding());
// unable to read the registry
if (err != ERROR_SUCCESS)
{
::WinsMessageBox(WIN32_FROM_HRESULT(err));
return hrOK;
}
CServerProperties * pServerProp =
new CServerProperties(pNode, spComponentData, m_spTFSCompData, NULL);
pServerProp->m_pageGeneral.m_uImage = GetImageIndex(FALSE);
pServerProp->SetConfig(&m_cConfig);
Assert(lpProvider != NULL);
return pServerProp->CreateModelessSheet(lpProvider, handle);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnPropertyChange
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnPropertyChange
(
ITFSNode * pNode,
LPDATAOBJECT pDataobject,
DWORD dwType,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CServerProperties * pServerProp
= reinterpret_cast<CServerProperties *>(lParam);
LONG_PTR changeMask = 0;
// tell the property page to do whatever now that we are back on the
// main thread
pServerProp->OnPropertyChange(TRUE, &changeMask);
pServerProp->AcknowledgeNotify();
if (changeMask)
pNode->ChangeNode(changeMask);
return hrOK;
}
/*!--------------------------------------------------------------------------
CWinsServer::Command
Handles commands for the current view
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerHandler::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;
}
/*!--------------------------------------------------------------------------
CWinsServer::AddMenuItems
Over-ride this to add our view menu item
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerHandler::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;
}
/*---------------------------------------------------------------------------
Command handlers
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
CWinsServerHandler::ShowServerStatDialog(ITFSNode* pNode)
Displays the ServerStatistics Window
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::ShowServerStatDialog(ITFSNode* pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
m_dlgStats.SetNode(pNode);
m_dlgStats.SetServer(m_strServerAddress);
CreateNewStatisticsWindow(&m_dlgStats,
::FindMMCMainWindow(),
IDD_STATS_NARROW);
HRESULT hr = hrOK;
return hr;
}
/*!--------------------------------------------------------------------------
CWinsServerHandler::OnDelete
The base handler calls this when MMC sends a MMCN_DELETE for a
scope pane item. We just call our delete command handler.
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnDelete
(
ITFSNode * pNode,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
LONG err = 0 ;
CString strMessage, strTemp;
SPITFSNode spParent;
CWinsStatusHandler *pStat = NULL;
CWinsRootHandler *pRoot = NULL;
strTemp = m_strServerAddress;
AfxFormatString1(strMessage,
IDS_DELETE_SERVER,
m_strServerAddress);
if (AfxMessageBox(strMessage, MB_YESNO) != IDYES)
return NOERROR;
pNode->GetParent(&spParent);
pRoot = GETHANDLER(CWinsRootHandler, spParent);
// remove the node from the status node as well
pStat = GETHANDLER(CWinsStatusHandler, pRoot->m_spStatusNode);
pStat->DeleteNode(pRoot->m_spStatusNode, this);
// remove this node from the list, there's nothing we need to tell
// the server, it's just our local list of servers
spParent->RemoveChild(pNode);
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::LoadColumns()
Description
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::LoadColumns(ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam)
{
HRESULT hr = hrOK;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SPIHeaderCtrl spHeaderCtrl;
pComponent->GetHeaderCtrl(&spHeaderCtrl);
CString str;
int i = 0;
CString strTemp;
strTemp = m_strServerAddress;
while( i< ARRAYLEN(aColumnWidths[1]))
{
if (i == 0)
{
AfxFormatString1(str, IDS_WINSSERVER_NAME, strTemp);
int nTest = spHeaderCtrl->InsertColumn(i,
const_cast<LPTSTR>((LPCWSTR)str),
LVCFMT_LEFT,
aColumnWidths[1][0]);
i++;
}
else
{
str.LoadString(IDS_DESCRIPTION);
int nTest = spHeaderCtrl->InsertColumn(1,
const_cast<LPTSTR>((LPCWSTR)str),
LVCFMT_LEFT,
aColumnWidths[1][1]);
i++;
}
if(aColumns[0][i] == 0)
break;
}
return hrOK;
}
/*!--------------------------------------------------------------------------
CWinsServerHandler::GetStatistics()
Gets the statistics from the server
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler::GetStatistics(ITFSNode * pNode, PWINSINTF_RESULTS_T * ppStats)
{
DWORD dwStatus = ERROR_SUCCESS;
CString strName, strIP;
if (ppStats)
*ppStats = NULL;
if (m_dwStatus != ERROR_SUCCESS)
m_dwStatus = ConnectToWinsServer(pNode);
if (m_dwStatus == ERROR_SUCCESS)
{
m_wrResults.WinsStat.NoOfPnrs = 0;
m_wrResults.WinsStat.pRplPnrs = 0;
m_wrResults.NoOfWorkerThds = 1;
#ifdef WINS_CLIENT_APIS
dwStatus = ::WinsStatus(m_hBinding, WINSINTF_E_STAT, &m_wrResults);
#else
dwStatus = ::WinsStatus(WINSINTF_E_STAT, &m_wrResults);
#endif WINS_CLIENT_APIS
if (dwStatus == ERROR_SUCCESS)
{
if (ppStats)
*ppStats = &m_wrResults;
}
}
else
{
dwStatus = m_dwStatus;
}
return dwStatus;
}
/*!--------------------------------------------------------------------------
CWinsServerHandler::ClearStatistics()
Clears the statistics from the server
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler::ClearStatistics(ITFSNode *pNode)
{
DWORD dwStatus = ERROR_SUCCESS;
CString strName, strIP;
if (m_dwStatus != ERROR_SUCCESS)
m_dwStatus = ConnectToWinsServer(pNode);
if (m_dwStatus == ERROR_SUCCESS)
{
#ifdef WINS_CLIENT_APIS
dwStatus = ::WinsResetCounters(m_hBinding);
#else
dwStatus = ::WinsResetCounters();
#endif WINS_CLIENT_APIS
}
else
{
dwStatus = m_dwStatus;
}
return dwStatus;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::ConnectToWinsServer()
Connects to the wins server
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler::ConnectToWinsServer(ITFSNode *pNode)
{
HRESULT hr = hrOK;
CString strServerName, strIP;
DWORD dwStatus = ERROR_SUCCESS;
WINSINTF_ADD_T waWinsAddress;
WINSINTF_BIND_DATA_T wbdBindData;
// build some information about the server
strServerName = GetServerAddress();
DWORD dwIP = GetServerIP();
MakeIPAddress(dwIP, strIP);
DisConnectFromWinsServer();
// now that the server name and ip are valid, call
// WINSBind function directly.
do
{
char szNetBIOSName[128] = {0};
// call WinsBind function with the IP address
wbdBindData.fTcpIp = 1;
wbdBindData.pPipeName = NULL;
wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIP;
BEGIN_WAIT_CURSOR
if ((m_hBinding = ::WinsBind(&wbdBindData)) == NULL)
{
m_dwStatus = ::GetLastError();
break;
}
#ifdef WINS_CLIENT_APIS
m_dwStatus = ::WinsGetNameAndAdd(m_hBinding, &waWinsAddress, (LPBYTE) szNetBIOSName);
#else
m_dwStatus = ::WinsGetNameAndAdd(&waWinsAddress, (LPBYTE) szNetBIOSName);
#endif WINS_CLIENT_APIS
END_WAIT_CURSOR
} while (FALSE);
return m_dwStatus;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::DoDBBackup()
backs up the database
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::DoDBBackup(ITFSNode *pNode)
{
HRESULT hr = hrOK;
DWORD dwStatus = ConnectToWinsServer(pNode);
CString strBackupPath;
CString strHelpText;
strHelpText.LoadString(IDS_SELECT_BACKUP_FOLDER);
if (GetFolderName(strBackupPath, strHelpText))
{
dwStatus = BackupDatabase(strBackupPath);
if (dwStatus == ERROR_SUCCESS)
{
AfxMessageBox(IDS_DB_BACKUP_SUCCESS, MB_ICONINFORMATION | MB_OK);
// don't update the default path just because they selected a path here
//if (m_cConfig.m_strBackupPath.CompareNoCase(strBackupPath) != 0)
//{
// m_cConfig.m_strBackupPath = strBackupPath;
// m_cConfig.Store();
//}
}
else
{
::WinsMessageBox(dwStatus, MB_OK);
}
}
return HRESULT_FROM_WIN32(dwStatus);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::BackupDatabase(CString strBackupPath)
Calls WINS API for backing the database
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler::BackupDatabase(CString strBackupPath)
{
BOOL fIncremental = FALSE;
BOOL fDefaultCharUsed = FALSE;
DWORD dwStatus = ERROR_SUCCESS;
char szTemp[MAX_PATH] = {0};
// INTL$ Should this be ACP or OEMCP?
WideToMBCS(strBackupPath, szTemp, CP_ACP, 0, &fDefaultCharUsed);
if (fDefaultCharUsed)
{
// could not convert this string... error out
dwStatus = IDS_ERR_CANT_CONVERT_STRING;
}
else
{
BEGIN_WAIT_CURSOR
#ifdef WINS_CLIENT_APIS
dwStatus = ::WinsBackup(m_hBinding, (unsigned char *)szTemp, (short)fIncremental);
#else
dwStatus = ::WinsBackup((unsigned char *)szTemp, (short)fIncremental);
#endif WINS_CLIENT_APIS
END_WAIT_CURSOR
}
return dwStatus;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::DoDBCompact()
backs up the database
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::DoDBCompact(ITFSNode *pNode)
{
HRESULT hr = hrOK;
// tell the user that we need to stop WINS in order to do this
if (AfxMessageBox(IDS_WARN_SERVICE_STOP, MB_YESNO) == IDNO)
return hr;
CDBCompactProgress dlgCompactProgress;
dlgCompactProgress.m_dwIpAddress = m_dwIPAdd;
dlgCompactProgress.m_strServerName = m_strServerAddress;
dlgCompactProgress.m_hBinding = GetBinding();
dlgCompactProgress.m_pConfig = &m_cConfig;
dlgCompactProgress.DoModal();
// since the service gets restarted, the new binding handle is in the object
m_hBinding = dlgCompactProgress.m_hBinding;
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::DoDBRestore()
Restores the database
Author:v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::DoDBRestore(ITFSNode *pNode)
{
DWORD dwStatus = 0;
DWORD err = ERROR_SUCCESS;
HRESULT hr = hrOK;
CString strRestorePath;
CString strHelpText;
strHelpText.LoadString(IDS_SELECT_RESTORE_FOLDER);
if (GetFolderName(strRestorePath, strHelpText))
{
BOOL fOldBackup = m_cConfig.m_fBackupOnTermination;
if (!strRestorePath.IsEmpty())
{
BEGIN_WAIT_CURSOR
// need to disable backup on shutdown since we need to shutdown
// the server to do this and we don't want it to backup and stomp
// over what we may want to restore.
if (fOldBackup)
{
m_cConfig.m_fBackupOnTermination = FALSE;
m_cConfig.Store();
}
DisConnectFromWinsServer();
// convert the string from unicode to DBCS for the WINS API
char szTemp[MAX_PATH * 2] = {0};
BOOL fDefaultCharUsed = FALSE;
// INTL$ should this be ACP or OEMCP?
WideToMBCS(strRestorePath, szTemp, CP_ACP, 0, &fDefaultCharUsed);
// if there is no code page available for conversion, error out
if (fDefaultCharUsed)
{
dwStatus = IDS_ERR_CANT_CONVERT_STRING;
}
else
{
dwStatus = ::WinsRestore((LPBYTE) szTemp);
}
END_WAIT_CURSOR
if (dwStatus == ERROR_SUCCESS)
{
// re-start the WINS service that was stopped
CString strServiceDesc;
strServiceDesc.LoadString(IDS_SERVICE_NAME);
err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
// connect to the server again
ConnectToWinsServer(pNode);
// let the user know everything went OK.
AfxMessageBox(IDS_DB_RESTORE_SUCCESS, MB_ICONINFORMATION | MB_OK);
}
else
{
::WinsMessageBox(dwStatus, MB_OK);
}
hr = HRESULT_FROM_WIN32(dwStatus);
// restore the backup on shutdown flag if necessary
if (fOldBackup)
{
m_cConfig.m_fBackupOnTermination = TRUE;
m_cConfig.Store();
}
if (SUCCEEDED(hr))
{
// need to refresh the server node because this can only be triggered
// if the service wasn't running
if (m_pNameThread)
{
m_pNameThread->Abort();
m_pNameThread = NULL;
}
OnRefresh(pNode, NULL, 0, 0, 0);
}
}
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnControlService
-
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnControlService
(
ITFSNode * pNode,
BOOL fStart
)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
CString strServiceDesc;
strServiceDesc.LoadString(IDS_SERVICE_NAME);
if (fStart)
{
err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
}
else
{
err = TFSStopServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
}
if (err == ERROR_SUCCESS)
{
// need to refresh the server node because this can only be triggered
// if the service wasn't running
if (m_pNameThread)
{
m_pNameThread->Abort();
m_pNameThread = NULL;
}
if (!fStart)
m_fSilent = TRUE;
OnRefresh(pNode, NULL, 0, 0, 0);
}
else
{
WinsMessageBox(err);
hr = HRESULT_FROM_WIN32(err);
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnPauseResumeService
-
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnPauseResumeService
(
ITFSNode * pNode,
BOOL fPause
)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
CString strServiceDesc;
strServiceDesc.LoadString(IDS_SERVICE_NAME);
if (fPause)
{
err = TFSPauseService(m_strServerAddress, _T("wins"), strServiceDesc);
}
else
{
err = TFSResumeService(m_strServerAddress, _T("wins"), strServiceDesc);
}
if (err != ERROR_SUCCESS)
{
WinsMessageBox(err);
hr = HRESULT_FROM_WIN32(err);
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnRestartService
-
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnRestartService
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
CString strServiceDesc;
strServiceDesc.LoadString(IDS_SERVICE_NAME);
err = TFSStopServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
if (err != ERROR_SUCCESS)
{
WinsMessageBox(err);
hr = HRESULT_FROM_WIN32(err);
}
if (SUCCEEDED(hr))
{
err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
if (err != ERROR_SUCCESS)
{
WinsMessageBox(err);
hr = HRESULT_FROM_WIN32(err);
}
}
// refresh
OnRefresh(pNode, NULL, 0, 0, 0);
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::UpdateStatistics
Notification that stats are now available. Update stats for the
server node and give all subnodes a chance to update.
Author: EricDav
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler::UpdateStatistics
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
SPITFSNodeEnum spNodeEnum;
SPITFSNode spCurrentNode;
ULONG nNumReturned;
HWND hStatsWnd;
BOOL bChangeIcon = FALSE;
// Check to see if this node has a stats sheet up.
hStatsWnd = m_dlgStats.GetSafeHwnd();
if (hStatsWnd != NULL)
{
PostMessage(hStatsWnd, WM_NEW_STATS_AVAILABLE, 0, 0);
}
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::DoDBScavenge()
Scavenges the database
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::DoDBScavenge(ITFSNode *pNode)
{
HRESULT hr = hrOK;
DWORD dwStatus;
if (m_dwStatus != ERROR_SUCCESS)
{
dwStatus = ConnectToWinsServer(pNode);
}
#ifdef WINS_CLIENT_APIS
dwStatus = ::WinsDoScavenging(m_hBinding);
#else
dwStatus = ::WinsDoScavenging();
#endif WINS_CLIENT_APIS
if (dwStatus == ERROR_SUCCESS)
{
CString strDisp;
CString strTemp;
strTemp.LoadString(IDS_SCAVENGE_COMMAND);
AfxFormatString1(strDisp, IDS_QUEUED_MESSAGE, strTemp);
AfxMessageBox(strDisp, MB_ICONINFORMATION|MB_OK);
BEGIN_WAIT_CURSOR
// refresh the stats
m_wrResults.WinsStat.NoOfPnrs = 0;
m_wrResults.WinsStat.pRplPnrs = 0;
m_wrResults.NoOfWorkerThds = 1;
#ifdef WINS_CLIENT_APIS
dwStatus = ::WinsStatus(m_hBinding, WINSINTF_E_CONFIG, &m_wrResults);
#else
dwStatus = ::WinsStatus(WINSINTF_E_CONFIG, &m_wrResults);
#endif WINS_CLIENT_APIS
UpdateStatistics(pNode);
END_WAIT_CURSOR
}
else
{
::WinsMessageBox(dwStatus, MB_OK);
}
return HRESULT_FROM_WIN32(dwStatus);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::IsValidNetBIOSName
Determine if the given netbios is valid, and pre-pend
a double backslash if not already present (and the address
is otherwise valid).
---------------------------------------------------------------------------*/
BOOL
CWinsServerHandler::IsValidNetBIOSName
(
CString & strAddress,
BOOL fLanmanCompatible,
BOOL fWackwack // expand slashes if not present
)
{
TCHAR szWacks[] = _T("\\\\");
if (strAddress.IsEmpty())
{
return FALSE;
}
if (strAddress[0] == _T('\\'))
{
if (strAddress.GetLength() < 3)
{
return FALSE;
}
if (strAddress[1] != _T('\\'))
{
// One slash only? Not valid
return FALSE;
}
}
else
{
if (fWackwack)
{
// Add the backslashes
strAddress = szWacks + strAddress;
}
}
int nMaxAllowedLength = fLanmanCompatible
? LM_NAME_MAX_LENGTH
: NB_NAME_MAX_LENGTH;
if (fLanmanCompatible)
{
strAddress.MakeUpper();
}
return strAddress.GetLength() <= nMaxAllowedLength + 2;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnResultRefresh
Refreshes the data relating to the server
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnResultRefresh
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
HRESULT hr = hrOK;
SPITFSNode spNode;
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
if (m_pNameThread)
{
m_pNameThread->Abort();
m_pNameThread = NULL;
}
OnRefresh(spNode, pDataObject, 0, arg, lParam);
Error:
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnDoConsistencyCheck(ITFSNode *pNode)
Consisntency Check for WINS
Author - v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnDoConsistencyCheck(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
if(IDYES != AfxMessageBox(IDS_CONSISTENCY_CONFIRM, MB_YESNO))
return hrFalse;
WINSINTF_SCV_REQ_T ScvReq;
ScvReq.Age = 0; // check all the replicas
ScvReq.fForce = FALSE;
ScvReq.Opcode_e = WINSINTF_E_SCV_VERIFY;
#ifdef WINS_CLIENT_APIS
DWORD dwStatus = ::WinsDoScavengingNew(m_hBinding, &ScvReq);
#else
DWORD dwStatus = ::WinsDoScavengingNew(&ScvReq);
#endif WINS_CLIENT_APIS
if(dwStatus == ERROR_SUCCESS)
{
CString strDisp, strJob;
strJob.Format(IDS_DO_CONSISTENCY_CHECK_STR);
AfxFormatString1(strDisp,IDS_QUEUED_MESSAGE, strJob);
AfxMessageBox(strDisp, MB_OK);
}
else
{
::WinsMessageBox(dwStatus, MB_OK);
}
return hr;
}
/*---------------------------------------------------------------------------
CWInsServerHandler::OnDoVersionConsistencyCheck(ITFSNode *pNode)
Performs the version number consistency check
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnDoVersionConsistencyCheck(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
if (IDYES != AfxMessageBox(IDS_VERSION_CONSIS_CHECK_WARNING, MB_YESNO))
return hrOK;
CCheckVersionProgress dlgCheckVersions;
dlgCheckVersions.m_dwIpAddress = m_dwIPAdd;
dlgCheckVersions.m_hBinding = GetBinding();
dlgCheckVersions.DoModal();
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnSendPushTrigger()
Sends Push replication trigger
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnSendPushTrigger(ITFSNode * pNode)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
CPushTrig dlgPushTrig;
CGetTriggerPartner dlgTrigPartner;
if (dlgTrigPartner.DoModal() != IDOK)
return hr;
if (dlgPushTrig.DoModal() != IDOK)
return hr;
err = ::SendTrigger(GetBinding(),
(LONG) dlgTrigPartner.m_dwServerIp,
TRUE,
dlgPushTrig.GetPropagate());
if (err == ERROR_SUCCESS)
{
AfxMessageBox(IDS_REPL_QUEUED, MB_ICONINFORMATION);
}
else
{
WinsMessageBox(err);
}
return HRESULT_FROM_WIN32(err);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnSendPullTrigger()
Sends Pull replication trigger
---------------------------------------------------------------------------*/
HRESULT
CWinsServerHandler::OnSendPullTrigger(ITFSNode * pNode)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
CPullTrig dlgPullTrig;
CGetTriggerPartner dlgTrigPartner;
if (dlgTrigPartner.DoModal() != IDOK)
return hr;
if (dlgPullTrig.DoModal() != IDOK)
return hr;
err = ::SendTrigger(GetBinding(),
(LONG) dlgTrigPartner.m_dwServerIp,
FALSE,
FALSE);
if (err == ERROR_SUCCESS)
{
AfxMessageBox(IDS_REPL_QUEUED, MB_ICONINFORMATION);
}
else
{
::WinsMessageBox(err);
}
return HRESULT_FROM_WIN32(err);
}
/*---------------------------------------------------------------------------
CWinsServerHandler::GetFolderName(CString& strPath)
Returns the folder name after displaying the
File Dialog
---------------------------------------------------------------------------*/
BOOL
CWinsServerHandler::GetFolderName(CString& strPath, CString& strHelpText)
{
BOOL fOk = FALSE;
TCHAR szBuffer[MAX_PATH];
TCHAR szExpandedPath[MAX_PATH * 2];
CString strStartingPath = m_cConfig.m_strBackupPath;
if (strStartingPath.IsEmpty())
{
strStartingPath = _T("%SystemDrive%\\");
}
ExpandEnvironmentStrings(strStartingPath, szExpandedPath, sizeof(szExpandedPath) / sizeof(TCHAR));
LPITEMIDLIST pidlPrograms = NULL;
SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlPrograms);
BROWSEINFO browseInfo;
browseInfo.hwndOwner = ::FindMMCMainWindow();
browseInfo.pidlRoot = pidlPrograms;
browseInfo.pszDisplayName = szBuffer;
browseInfo.lpszTitle = strHelpText;
browseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS ;
browseInfo.lpfn = BrowseCallbackProc;
browseInfo.lParam = (LPARAM) szExpandedPath;
LPITEMIDLIST pidlBrowse = SHBrowseForFolder(&browseInfo);
fOk = SHGetPathFromIDList(pidlBrowse, szBuffer);
CString strBackupPath(szBuffer);
strPath = strBackupPath;
LPMALLOC pMalloc = NULL;
if (pidlPrograms && SUCCEEDED(SHGetMalloc(&pMalloc)))
{
if (pMalloc)
pMalloc->Free(pidlPrograms);
}
return fOk;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::SetExtensionName()
-
Author: EricDav
---------------------------------------------------------------------------*/
void
CWinsServerHandler::SetExtensionName()
{
SetDisplayName(_T("WINS"));
m_bExtension = TRUE;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::IsLocalConnection()
Checks if the local server is being managed
Author: v-shubk
---------------------------------------------------------------------------*/
BOOL
CWinsServerHandler::IsLocalConnection()
{
// get the server netbios name
CString strServerName = m_strServerAddress;
TCHAR lpBuffer[MAX_COMPUTERNAME_LENGTH + 1]; // address of name buffer
DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1;
::GetComputerName(lpBuffer,&nSize);
CString strCompName(lpBuffer);
if(strCompName.CompareNoCase(strServerName) == 0)
return TRUE;
return FALSE;
}
/*---------------------------------------------------------------------------
CWinsServerHandler:: DeleteWinsServer(CWinsServerObj* pws)
Calls WinsAPI to delete the server
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CWinsServerHandler:: DeleteWinsServer
(
DWORD dwIpAddress
)
{
DWORD err = ERROR_SUCCESS;
WINSINTF_ADD_T WinsAdd;
WinsAdd.Len = 4;
WinsAdd.Type = 0;
WinsAdd.IPAdd = dwIpAddress;
#ifdef WINS_CLIENT_APIS
err = ::WinsDeleteWins(GetBinding(), &WinsAdd);
#else
err = ::WinsDeleteWins(&WinsAdd);
#endif WINS_CLIENT_APIS
return err;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::DisConnectFromWinsServer()
Calls WinsUnbind and makes the binding handle invalid
---------------------------------------------------------------------------*/
void
CWinsServerHandler::DisConnectFromWinsServer()
{
if (m_hBinding)
{
CString strIP;
WINSINTF_BIND_DATA_T wbdBindData;
DWORD dwIP = GetServerIP();
MakeIPAddress(dwIP, strIP);
wbdBindData.fTcpIp = 1;
wbdBindData.pPipeName = NULL;
wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIP;
::WinsUnbind(&wbdBindData, m_hBinding);
m_hBinding = NULL;
}
}
/*---------------------------------------------------------------------------
CWinsServerHandler::CheckIfNT351Server()
Checks if a 351 server is being managed
---------------------------------------------------------------------------*/
BOOL
CWinsServerHandler::CheckIfNT351Server()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DWORD err = ERROR_SUCCESS;
CString lpstrRoot;
CString lpstrVersion;
CString strVersion;
BOOL f351 = FALSE;
// don't go to the registry each time -- we have the info in our config object
// 7/8/98 - EricDav
/*
// connect to the registry of the server to find if
// it's a 351 server
lpstrRoot = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
lpstrVersion = _T("CurrentVersion");
RegKey rk;
err = rk.Open(HKEY_LOCAL_MACHINE, lpstrRoot, KEY_READ, m_strServerAddress);
// Get the count of items
if (!err)
err = rk.QueryValue(lpstrVersion,strVersion) ;
if(strVersion.CompareNoCase(_T("3.51")) == 0 )
return TRUE;
return FALSE;
*/
if (m_cConfig.m_dwMajorVersion < 4)
{
f351 = TRUE;
}
return f351;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::SetDisplay()
Sets the node name to either the host name or FQDN
---------------------------------------------------------------------------*/
void
CWinsServerHandler::SetDisplay(ITFSNode * pNode, BOOL fFQDN)
{
CHAR szHostName[MAX_PATH] = {0};
CString strIPAdd, strDisplay;
::MakeIPAddress(m_dwIPAdd, strIPAdd);
if (fFQDN)
{
// check if the server name was resolved and added
if (m_dwIPAdd != 0)
{
// default is ACP. This should use ACP because winsock uses ACP
WideToMBCS(m_strServerAddress, szHostName);
HOSTENT * pHostent = ::gethostbyname((CHAR *) szHostName);
if (pHostent)
{
CString strFQDN;
MBCSToWide(pHostent->h_name, strFQDN);
strFQDN.MakeLower();
strDisplay.Format(IDS_SERVER_NAME_FORMAT, strFQDN, strIPAdd);
SetDisplayName(strDisplay);
if (pNode)
pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
}
}
}
// if not FQDN
else
{
if (m_dwIPAdd != 0)
{
strDisplay.Format(IDS_SERVER_NAME_FORMAT, m_strServerAddress, strIPAdd);
}
else
{
strDisplay = m_strServerAddress;
}
SetDisplayName(strDisplay);
if (pNode)
pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
}
}
void
CWinsServerHandler::GetErrorInfo(CString & strTitle, CString & strBody, IconIdentifier * pIcon)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
TCHAR szBuffer[MAX_PATH * 2];
// build the body text
LoadMessage(m_dwErr, szBuffer, sizeof(szBuffer) / sizeof(TCHAR));
AfxFormatString1(strBody, IDS_SERVER_MESSAGE_BODY, szBuffer);
CString strTemp;
strTemp.LoadString(IDS_SERVER_MESSAGE_BODY_REFRESH);
strBody += strTemp;
// get the title
strTitle.LoadString(IDS_SERVER_MESSAGE_TITLE);
// and the icon
if (pIcon)
{
*pIcon = Icon_Error;
}
}
/*---------------------------------------------------------------------------
Background thread functionality
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
CWinsServerHandler::OnCreateQuery
Description
Author: EricDav
---------------------------------------------------------------------------*/
ITFSQueryObject*
CWinsServerHandler::OnCreateQuery(ITFSNode * pNode)
{
CWinsServerQueryObj* pQuery = NULL;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
m_pNameThread = new CNameThread();
pQuery = new CWinsServerQueryObj(m_spTFSCompData, m_spNodeMgr);
pQuery->m_strServer = GetServerAddress();
pQuery->m_dwIPAdd = m_dwIPAdd;
pQuery->m_pNameThread = m_pNameThread;
pQuery->m_pServerInfoArray = &m_ServerInfoArray;
}
COM_PROTECT_CATCH
return pQuery;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnEventAbort
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CWinsServerQueryObj::OnEventAbort
(
DWORD dwData,
DWORD dwType
)
{
if (dwType == WINS_QDATA_SERVER_INFO)
{
Trace0("CWinsServerHandler::OnEventAbort - deleting version");
delete ULongToPtr(dwData);
}
}
/*---------------------------------------------------------------------------
CWinsServerQueryObj::Execute()
Enumerates everything about a server
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsServerQueryObj::Execute()
{
HRESULT hr = hrOK;
WINSINTF_BIND_DATA_T wbdBindData;
CString strName, strIp;
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwIp;
CServerData * pServerInfo;
// need to get the server name and IP address if the server is added
// with Do not connect option
dwStatus = ::VerifyWinsServer(m_strServer, strName, dwIp);
if (dwStatus != ERROR_SUCCESS)
{
Trace1("CWinsServerQueryObj::Execute() - VerifyWinsServer failed! %d\n", dwStatus);
// Use the existing information we have to try and connect
if (m_dwIPAdd)
{
// we couldn't resolve the name so just use what we have and try to connect
strName = m_strServer;
dwIp = m_dwIPAdd;
}
else
{
// we don't have an IP for this and we can't resolve the name, so error out
PostError(dwStatus);
return hrFalse;
}
}
pServerInfo = new CServerData;
::MakeIPAddress(dwIp, strIp);
pServerInfo->m_strServerName = strName;
pServerInfo->m_dwServerIp = dwIp;
pServerInfo->m_hBinding = NULL;
// get a binding for this server
wbdBindData.fTcpIp = 1;
wbdBindData.pPipeName = NULL;
wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIp;
if ((pServerInfo->m_hBinding = ::WinsBind(&wbdBindData)) == NULL)
{
dwStatus = ::GetLastError();
// send what info we have back to the main thread
AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
Trace1("CWinsServerQueryObj::Execute() - WinsBind failed! %d\n", dwStatus);
PostError(dwStatus);
return hrFalse;
}
// load the configuration object
//pServerInfo->m_config.SetOwner(strName);
pServerInfo->m_config.SetOwner(strIp);
dwStatus = pServerInfo->m_config.Load(pServerInfo->m_hBinding);
if (dwStatus != ERROR_SUCCESS)
{
// send what info we have back to the main thread
AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
Trace1("CWinsServerQueryObj::Execute() - Load configuration failed! %d\n", dwStatus);
PostError(dwStatus);
return hrFalse;
}
// send all of the information back to the main thread here
handle_t hBinding = pServerInfo->m_hBinding;
AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
// build the child nodes
AddNodes(hBinding);
return hrFalse;
}
/*---------------------------------------------------------------------------
CWinsServerQueryObj::AddNodes
Creates the active registrations and replication partners nodes
Author: EricDav
---------------------------------------------------------------------------*/
void
CWinsServerQueryObj::AddNodes(handle_t hBinding)
{
HRESULT hr = hrOK;
SPITFSNode spActReg, spRepPart;
CServerInfoArray * pServerInfoArray;
//
// active registrations node
//
CActiveRegistrationsHandler *pActRegHand = NULL;
try
{
pActRegHand = new CActiveRegistrationsHandler(m_spTFSCompData);
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
//
// Create the actreg container information
//
CreateContainerTFSNode(&spActReg,
&GUID_WinsActiveRegNodeType,
pActRegHand,
pActRegHand,
m_spNodeMgr);
// Tell the handler to initialize any specific data
pActRegHand->InitializeNode((ITFSNode *) spActReg);
// load the name type mapping from the registry
pActRegHand->m_NameTypeMap.SetMachineName(m_strServer);
pActRegHand->m_NameTypeMap.Load();
// build the owner mapping
pActRegHand->m_pServerInfoArray = m_pServerInfoArray;
pActRegHand->BuildOwnerArray(hBinding);
// Post this node back to the main thread
AddToQueue(spActReg);
pActRegHand->Release();
//
// replication partners node
//
CReplicationPartnersHandler *pReplicationHand = NULL;
try
{
pReplicationHand = new CReplicationPartnersHandler (m_spTFSCompData);
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
// Create the actreg container information
CreateContainerTFSNode(&spRepPart,
&GUID_WinsReplicationNodeType,
pReplicationHand,
pReplicationHand,
m_spNodeMgr);
// Tell the handler to initialize any specific data
pReplicationHand->InitializeNode((ITFSNode *) spRepPart);
// Post this node back to the main thread
AddToQueue(spRepPart);
pReplicationHand->Release();
// kick off the name query thread
m_pNameThread->Init(m_pServerInfoArray);
m_pNameThread->Start();
}