2419 lines
60 KiB
C++
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();
|
|
}
|