Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

784 lines
18 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corp., 1995 **/
/**********************************************************************/
/*
mainfrm.cpp
Main frame window
FILE HISTORY:
*/
#include "stdafx.h"
#include "winsadmn.h"
#include "mainfrm.h"
#include "winsadoc.h"
#include "statisti.h"
#include "selectwi.h"
#include "preferen.h"
#include "connecti.h"
#include "confirmd.h"
#include "configur.h"
#include "replicat.h"
#include "staticma.h"
#include "viewmapp.h"
#include "winsfile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
#define new DEBUG_NEW
UINT
_cdecl
RefreshStatsThread(
LPVOID pParam
)
{
CThreadInfo * lpThreadInfo = (CThreadInfo *)pParam;
HANDLE hmutStatistics = NULL;
#ifndef WIN32S
//
// Open the existing mutex
//
while (hmutStatistics == NULL)
{
if ((hmutStatistics = ::OpenMutex(SYNCHRONIZE, FALSE, STATMUTEXNAME)) == NULL)
{
TRACEEOLID("(thread) Failed to open the mutex, trying again in 2 seconds");
::Sleep(2000L);
}
}
#endif // WIN32S
if (hmutStatistics == NULL)
{
TRACEEOLID("Unable to obtain mutex");
return 0;
}
#ifndef WIN32S
//
// This is where the work gets done
//
for (;;)
{
::Sleep(lpThreadInfo->dwInterval);
//::MessageBeep(MB_ICONEXCLAMATION);
CMainFrame * pWnd = lpThreadInfo->pMainWnd;
ASSERT(pWnd != NULL);
if (pWnd != NULL)
{
//
// Wait until we get the go ahead
//
DWORD dw = ::WaitForSingleObject(hmutStatistics, INFINITE);
if (dw == WAIT_OBJECT_0)
{
pWnd->m_wrResults.WinsStat.NoOfPnrs = 0;
pWnd->m_wrResults.WinsStat.pRplPnrs = 0;
pWnd->m_wrResults.NoOfWorkerThds = 1;
APIERR err = ::WinsStatus(WINSINTF_E_STAT, &pWnd->m_wrResults);
::PostMessage(lpThreadInfo->hwndNotifyWnd, WM_USER_STAT_REFRESH, 0, 0);
if (pWnd->m_wrResults.WinsStat.NoOfPnrs)
{
::WinsFreeMem(pWnd->m_wrResults.WinsStat.pRplPnrs);
}
::ReleaseMutex(hmutStatistics);
if (err == ERROR_ACCESS_DENIED)
{
//
// Quit the thread in this case, as there's no
// point in filling their error log.
//
theApp.MessageBox(err);
TRACEEOLID("Stat thread terminating due to access denied");
return err;
}
}
}
}
#else
//
// No threads in WIN32S
//
return 0;
#endif // WIN32S
return 0;
}
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_WININICHANGE()
ON_WM_CLOSE()
ON_COMMAND(ID_WINS_ADD_SERVER, OnWinsAddServer)
ON_COMMAND(ID_WINS_REMOVE_SERVER, OnWinsRemoveServer)
ON_UPDATE_COMMAND_UI(ID_WINS_REMOVE_SERVER, OnUpdateWinsRemoveServer)
ON_COMMAND(ID_OPTIONS_PREFERENCES, OnOptionsPreferences)
ON_COMMAND(ID_WINS_CLEARSTATISTICS, OnWinsClearstatistics)
ON_UPDATE_COMMAND_UI(ID_WINS_CLEARSTATISTICS, OnUpdateWinsClearstatistics)
ON_COMMAND(ID_WINS_REFRESHSTATISTICS, OnWinsRefreshstatistics)
ON_UPDATE_COMMAND_UI(ID_WINS_REFRESHSTATISTICS, OnUpdateWinsRefreshstatistics)
ON_COMMAND(ID_WINS_CONNECTIONINFO, OnWinsConnectioninfo)
ON_COMMAND(ID_WINS_DOSCAVENGING, OnWinsDoscavenging)
ON_COMMAND(ID_WINS_DATABASE_BACKUP, OnWinsDatabaseBackup)
ON_COMMAND(ID_WINS_DATABASE_RESTORE, OnWinsDatabaseRestore)
ON_COMMAND(ID_WINS_CONFIGURATION, OnWinsConfiguration)
ON_COMMAND(ID_WINS_REPLICATIONPARTNERS, OnWinsReplicationpartners)
ON_COMMAND(ID_WINS_DATABASE_DOREPORT, OnWinsDatabaseDoreport)
ON_COMMAND(ID_WINS_STATICMAPPINGS, OnWinsStaticmappings)
ON_UPDATE_COMMAND_UI(ID_WINS_CONNECTIONINFO, OnUpdateWinsConnectioninfo)
ON_UPDATE_COMMAND_UI(ID_WINS_STATICMAPPINGS, OnUpdateWinsStaticmappings)
ON_UPDATE_COMMAND_UI(ID_WINS_CONFIGURATION, OnUpdateWinsConfiguration)
ON_UPDATE_COMMAND_UI(ID_WINS_REPLICATIONPARTNERS, OnUpdateWinsReplicationpartners)
ON_UPDATE_COMMAND_UI(ID_WINS_DATABASE_BACKUP, OnUpdateWinsDatabaseBackup)
ON_UPDATE_COMMAND_UI(ID_WINS_DATABASE_RESTORE, OnUpdateWinsDatabaseRestore)
ON_UPDATE_COMMAND_UI(ID_WINS_DATABASE_DOREPORT, OnUpdateWinsDatabaseDoreport)
ON_UPDATE_COMMAND_UI(ID_WINS_DOSCAVENGING, OnUpdateWinsDoscavenging)
ON_COMMAND(ID_HELP_SEARCHFORHELPON, OnHelpSearchforhelpon)
ON_COMMAND(ID_HELP, OnHelp)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// CMainFrame construction/destruction
//
CMainFrame::CMainFrame()
: m_fStatsAvailable(FALSE),
m_pRefreshThread(NULL)
{
}
CMainFrame::~CMainFrame()
{
KillRefresherThread();
}
static UINT BASED_CODE indicators[] =
{
0, // Message bar only (no indicators)
IDS_INFO,
};
//
// Split the main window into two panes
//
BOOL
CMainFrame::OnCreateClient(
LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext
)
{
m_wndSplitter.CreateStatic(this, 1, 2);
CRect rect;
GetClientRect(&rect);
m_wndSplitter.CreateView(0, 0,
RUNTIME_CLASS(CSelectWinsServersDlg),
CSize(rect.right/4,
rect.bottom),
pContext);
m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CStatistics),
CSize(0,0),
pContext);
SetActiveView((CView *)m_wndSplitter.GetPane(0,0));
return TRUE;
}
BOOL
CMainFrame::PreCreateWindow(
CREATESTRUCT &cs
)
{
//
// Insert our own class name, since we want to check
// for previous instances.
//
//cs.lpszClass = WINSADMIN_CLASS_NAME;
// Window will initially be invisible until it is resized
// and positioned.
//
// BUGBUG: For some reason, the app refuses to start minimized
//
cs.style &= ~(WS_MAXIMIZEBOX | (LONG)FWS_ADDTOTITLE | WS_VISIBLE);
return CFrameWnd::PreCreateWindow(cs);
}
int
CMainFrame::OnCreate(
LPCREATESTRUCT lpCreateStruct
)
{
int cxWidth ;
UINT nId, nStyle ;
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators) / sizeof(UINT))
)
{
TRACEEOLID("Failed to create status bar.");
return -1;
}
m_wndStatusBar.GetPaneInfo( 0, nId, nStyle, cxWidth ) ;
nStyle &= ~ SBPS_NOBORDERS;
m_wndStatusBar.SetPaneInfo( 0, nId, nStyle | SBPS_STRETCH, cxWidth ) ;
m_wndStatusBar.SetPaneText( 1, "");
return 0;
}
void
CMainFrame::CloseCurrentConnection()
{
if (IsThreadRunning())
{
KillRefresherThread();
}
theApp.DisconnectFromWinsServer();
//
// Tell the views to clear all the data, then to disable
// the view screen, and lastly, clear the title.
//
GetStatView()->ClearView();
m_fStatsAvailable = FALSE;
GetStatView()->Refresh();
theApp.SetTitle();
}
void
CMainFrame::GetStatistics()
{
APIERR err;
TRY
{
err = theApp.GetStatistics(&m_wrResults);
if (err == ERROR_SUCCESS)
{
m_fStatsAvailable = TRUE;
GetStatView()->Refresh();
}
else if (err == ERROR_SEM_TIMEOUT)
{
TRACEEOLID("Stat refresh timeout -- on screen stats not altered");
}
//
// If we failed to get the stats, but did manage to get them
// last time, then we need to inform the user of a change in
// condition, and disable the statistics screen. Otherwise, he
// presumably knows already.
//
else if (m_fStatsAvailable)
{
m_fStatsAvailable = FALSE;
GetStatView()->Refresh();
theApp.MessageBox(err);
return;
}
}
CATCH_ALL(e)
{
TRACEEOLID("exception get statistics");
}
END_CATCH_ALL
}
void
CMainFrame::DoBackupRestore(BOOL fBackup)
{
CWinsBackupDlg dlgFile(
fBackup,
fBackup ? IDS_SELECT_BACKUP_DIRECTORY : IDS_SELECT_RESTORE_DIRECTORY,
this);
if (dlgFile.DoModal() != IDOK)
return;
theApp.SetStatusBarText(fBackup ?
IDS_STATUS_BACKING_UP :
IDS_STATUS_RESTORING);
theApp.BeginWaitCursor();
APIERR err = fBackup
? theApp.BackupDatabase(dlgFile.m_szFullPath, dlgFile.m_fIncremental)
: theApp.RestoreDatabase(dlgFile.m_szFullPath);
theApp.EndWaitCursor();
theApp.SetStatusBarText();
if (err != ERROR_SUCCESS)
{
theApp.MessageBox(err);
}
else
{
theApp.MessageBox(fBackup
? IDS_MSG_BACKUP
: IDS_MSG_RESTORE, MB_ICONINFORMATION);
}
}
void
CMainFrame::StartRefresherThread(
DWORD dwInterval
)
{
//
// Fire off a new thread
//
m_ThreadInfo.dwInterval = dwInterval;
m_ThreadInfo.pMainWnd = this;
m_ThreadInfo.hwndNotifyWnd = GetStatView()->m_hWnd;
m_pRefreshThread = ::AfxBeginThread(RefreshStatsThread, &m_ThreadInfo);
if (m_pRefreshThread == NULL)
{
TRACEEOLID("Failed to create thread");
theApp.MessageBox(IDS_ERR_CANT_CREATE_THREAD);
m_pRefreshThread = NULL;
return;
}
TRACEEOLID("Auto refresh thread succesfully started");
}
void
CMainFrame::KillRefresherThread()
{
//
// Kill refresher thread if necessary.
//
if (m_pRefreshThread == NULL)
{
//
// No thread running
//
return;
}
::TerminateThread(m_pRefreshThread->m_hThread, 0);
::CloseHandle(m_pRefreshThread->m_hThread);
m_pRefreshThread = NULL;
}
//
// CMainFrame diagnostics
//
#ifdef _DEBUG
void
CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void
CMainFrame::Dump(
CDumpContext& dc
) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
//
// CMainFrame message handlers
//
void
CMainFrame::OnWinIniChange(
LPCSTR lpszSection
)
{
CFrameWnd::OnWinIniChange(lpszSection);
//
// International settings may have changed, so update
// international-related classes, and change on-screen
// numbers
//
if (!::lstrcmpi(lpszSection, "intl"))
{
TRACEEOLID("International settings have changed. Changing values on the fly");
CIntlTime::Reset();
CIntlNumber::Reset();
//
// Update the statistics view
//
GetStatView()->Refresh();
}
}
void
CMainFrame::OnClose()
{
ASSERT(theApp.m_pMainWnd != NULL);
//
// Remember the current screen location for the
// future.
//
if (!theApp.m_pMainWnd->GetWindowPlacement(
&theApp.m_wpPreferences.m_wpPosition))
{
//
// Constructed with default
//
CPreferences prefDefault;
theApp.m_wpPreferences.m_wpPosition = prefDefault.m_wpPosition;
}
if (theApp.IsConnected())
{
theApp.SetStatusBarText(IDS_STATUS_DISCONNECTING);
CloseCurrentConnection();
theApp.SetStatusBarText();
}
CFrameWnd::OnClose();
}
//
// This routine adds a server to the list of known wins servers
//
void
CMainFrame::OnWinsAddServer()
{
GetSelectionView()->AddServer();
}
void
CMainFrame::Connect(
LPCSTR lpAddress
)
{
GetSelectionView()->TryToConnect(lpAddress);
}
void
CMainFrame::OnWinsRemoveServer()
{
GetSelectionView()->RemoveServer();
}
void
CMainFrame::OnUpdateWinsRemoveServer(
CCmdUI* pCmdUI
)
{
CIpNamePair inpAddress;
pCmdUI->Enable(theApp.m_wcWinssCache.GetFirst(inpAddress) &&
GetSelectionView()->m_list_KnownWinsServers.GetCurSel() != LB_ERR);
}
void
CMainFrame::OnOptionsPreferences()
{
CPreferencesDlg dlgPref(&theApp.m_wpPreferences);
if (dlgPref.DoModal() == IDOK)
{
dlgPref.Save();
//
// Now update the listbox of WINS servers to reflect a change in
// order and the like.
//
GetSelectionView()->Refresh();
//
// Refresh interval may have changed, so kill the currently
// running refresh thread, and start a new one with the newly
// set interval, provided of course that we're
// currently connected.
//
if (theApp.IsConnected())
{
if (IsThreadRunning())
{
KillRefresherThread();
}
if ((theApp.m_wpPreferences.IsAutoRefresh()) &&
((LONG)theApp.m_wpPreferences.m_inStatRefreshInterval > 0))
{
StartRefresherThread((LONG)theApp.m_wpPreferences.m_inStatRefreshInterval * A_SECOND);
}
}
}
}
void
CMainFrame::OnWinsClearstatistics()
{
ASSERT(theApp.IsServiceRunning());
if (theApp.MessageBox(IDS_MSG_CLEAR_STATISTICS,
MB_YESNO | MB_ICONQUESTION) == IDYES)
{
theApp.SetStatusBarText(IDS_STATUS_CLEARING_STATS);
APIERR err = theApp.ClearStatistics();
theApp.SetStatusBarText();
if (err != ERROR_SUCCESS)
{
theApp.MessageBox(err);
}
else
{
OnWinsRefreshstatistics();
}
}
}
void
CMainFrame::OnUpdateWinsClearstatistics(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnWinsRefreshstatistics()
{
ASSERT(theApp.IsConnected());
theApp.SetStatusBarText(IDS_STATUS_GETTING_STATS);
theApp.BeginWaitCursor();
GetStatistics();
theApp.EndWaitCursor();
theApp.SetStatusBarText();
}
void
CMainFrame::OnUpdateWinsRefreshstatistics(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnWinsConnectioninfo()
{
ASSERT(theApp.IsConnected());
CConnectionInfoDlg dlgInfo;
dlgInfo.DoModal();
}
void
CMainFrame::OnWinsDoscavenging()
{
ASSERT(theApp.IsServiceRunning());
theApp.SetStatusBarText(IDS_STATUS_SCAVENGING);
APIERR err = theApp.DoScavenging();
theApp.SetStatusBarText();
if (err == ERROR_SUCCESS)
{
theApp.MessageBox(IDS_MSG_SCAVENGING, MB_ICONINFORMATION);
OnWinsRefreshstatistics();
}
else
{
theApp.MessageBox(err);
}
}
void
CMainFrame::OnWinsDatabaseBackup()
{
ASSERT(theApp.IsServiceRunning());
DoBackupRestore(TRUE);
}
void
CMainFrame::OnWinsDatabaseRestore()
{
ASSERT(!theApp.IsServiceRunning());
// REVIEW: IsLocalConnection() asserts when service not started
ASSERT(theApp.IsLocalConnection());
DoBackupRestore(FALSE);
}
void
CMainFrame::OnWinsConfiguration()
{
ASSERT(theApp.IsConnected());
ASSERT(theApp.m_cConfig.IsReady());
APIERR err;
theApp.SetStatusBarText(IDS_STATUS_GET_CONFIG);
theApp.BeginWaitCursor();
err = theApp.m_cConfig.Load();
theApp.EndWaitCursor();
theApp.SetStatusBarText();
if (err != ERROR_SUCCESS)
{
theApp.MessageBox(err);
return;
}
CConfigurationDlg dlgConfig(&theApp.m_cConfig);
if (dlgConfig.DoModal() == IDOK)
{
dlgConfig.Save();
theApp.SetStatusBarText(IDS_STATUS_SET_CONFIG);
theApp.BeginWaitCursor();
err = theApp.m_cConfig.Store();
theApp.EndWaitCursor();
theApp.SetStatusBarText();
if (err != ERROR_SUCCESS)
{
theApp.MessageBox(err);
}
}
}
void
CMainFrame::OnWinsReplicationpartners()
{
ASSERT(theApp.IsConnected());
CReplicationPartnersDlg dlgPartners;
if (dlgPartners.DoModal() == IDOK)
{
//
// Our cache of WINS servers is now invalid.
// Refresh it now.
//
GetSelectionView()->Refresh();
}
}
void
CMainFrame::OnWinsDatabaseDoreport()
{
ASSERT(theApp.IsConnected());
ASSERT(theApp.IsServiceRunning());
CViewMappingsDlg dlgView;
dlgView.DoModal();
}
void
CMainFrame::OnWinsStaticmappings()
{
ASSERT(theApp.IsConnected());
ASSERT(theApp.IsServiceRunning());
CStaticMappingsDlg dlgStaticMappings;
dlgStaticMappings.DoModal();
OnWinsRefreshstatistics();
}
void
CMainFrame::OnUpdateWinsConnectioninfo(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnUpdateWinsStaticmappings(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnUpdateWinsConfiguration(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected() && theApp.IsAdmin());
}
void
CMainFrame::OnUpdateWinsReplicationpartners(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected() && theApp.IsAdmin());
}
void
CMainFrame::OnUpdateWinsDatabaseBackup(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected() && theApp.IsLocalConnection());
}
void
CMainFrame::OnUpdateWinsDatabaseRestore(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable((!theApp.IsConnected() || theApp.IsLocalConnection())
&& theApp.HasStoppedWins());
}
void
CMainFrame::OnUpdateWinsDatabaseDoreport(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnUpdateWinsDoscavenging(
CCmdUI* pCmdUI
)
{
pCmdUI->Enable(theApp.IsConnected());
}
void
CMainFrame::OnHelpSearchforhelpon()
{
//
// Use an empty string to ensure no-match,
// and bring up the "search for help on"
// dialog.
//
theApp.WinHelp((ULONG)"", HELP_PARTIALKEY);
}
void CMainFrame::OnHelp()
{
//
// If we are tracking a menu selection then don't display help
//
if (!IsTracking())
CFrameWnd::OnHelp();
}