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

461 lines
11 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
dlgrecon.cpp
Reconcile dialog
FILE HISTORY:
*/
#include "stdafx.h"
#include "dlgrecon.h"
#include "server.h"
#include "scope.h"
#include "mscope.h"
#include "busydlg.h"
/*---------------------------------------------------------------------------
CReconcileWorker
---------------------------------------------------------------------------*/
CReconcileWorker::CReconcileWorker(CDhcpServer * pServer, CScopeReconArray * pScopeReconArray)
: m_pServer(pServer),
m_pScopeReconArray(pScopeReconArray)
{
}
CReconcileWorker::~CReconcileWorker()
{
}
void
CReconcileWorker::OnDoAction()
{
// are we fixing or checking?
if (m_pScopeReconArray->GetSize() > 0)
{
// walk the scope list looking for scopes with inconsistencies
for (int i = 0; i < m_pScopeReconArray->GetSize(); i++)
{
CScopeReconInfo ScopeReconInfo = m_pScopeReconArray->GetAt(i);
// does this scope have an inconsistencies?
if (ScopeReconInfo.m_pScanList->NumScanItems > 0)
{
if (ScopeReconInfo.m_strName.IsEmpty())
{
// normal scope
m_dwErr = m_pServer->ScanDatabase(TRUE, &ScopeReconInfo.m_pScanList, ScopeReconInfo.m_dwScopeId);
}
else
{
// multicast scope
m_dwErr = m_pServer->ScanDatabase(TRUE, &ScopeReconInfo.m_pScanList, (LPWSTR) (LPCTSTR) ScopeReconInfo.m_strName);
}
}
}
}
else
{
// are we checking all of the scopes?
if (m_fReconcileAll)
{
// get list of all scopes, mscopes and check each one.
CheckAllScopes();
}
else
{
// we are only checking one scope, info is provided
m_dwErr = ScanScope(m_strName, m_dwScopeId);
}
}
}
void
CReconcileWorker::CheckAllScopes()
{
LARGE_INTEGER liVersion;
m_pServer->GetVersion(liVersion);
if (liVersion.QuadPart >= DHCP_NT5_VERSION)
{
CheckMScopes();
}
// now check all other scopes
CheckScopes();
}
void
CReconcileWorker::CheckMScopes()
{
DWORD dwError = ERROR_MORE_DATA;
DWORD dwElementsRead = 0, dwElementsTotal = 0;
LPDHCP_MSCOPE_TABLE pMScopeTable = NULL;
DHCP_RESUME_HANDLE resumeHandle;
//
// for this server, enumerate all of it's subnets
//
while (dwError == ERROR_MORE_DATA)
{
dwError = ::DhcpEnumMScopes((LPWSTR) m_pServer->GetIpAddress(),
&resumeHandle,
-1,
&pMScopeTable,
&dwElementsRead,
&dwElementsTotal);
if (dwElementsRead && dwElementsTotal && pMScopeTable)
{
//
// loop through all of the subnets that were returned
//
for (DWORD i = 0; i < pMScopeTable->NumElements; i++)
{
CString strName = pMScopeTable->pMScopeNames[i];
DWORD err = ScanScope(strName, 0);
if (err != ERROR_SUCCESS)
{
dwError = err;
break;
}
}
//
// Free up the RPC memory
//
::DhcpRpcFreeMemory(pMScopeTable);
dwElementsRead = 0;
dwElementsTotal = 0;
pMScopeTable = NULL;
}
}
if (dwError != ERROR_NO_MORE_ITEMS &&
dwError != ERROR_SUCCESS &&
dwError != ERROR_MORE_DATA)
{
m_dwErr = dwError;
}
else
{
m_dwErr = ERROR_SUCCESS;
}
}
void
CReconcileWorker::CheckScopes()
{
DWORD dwError = ERROR_MORE_DATA;
DWORD dwElementsRead = 0, dwElementsTotal = 0;
LPDHCP_IP_ARRAY pdhcpIpArray = NULL;
DHCP_RESUME_HANDLE resumeHandle;
//
// for this server, enumerate all of it's subnets
//
while (dwError == ERROR_MORE_DATA)
{
dwError = ::DhcpEnumSubnets((LPWSTR) m_pServer->GetIpAddress(),
&resumeHandle,
-1,
&pdhcpIpArray,
&dwElementsRead,
&dwElementsTotal);
if (dwElementsRead && dwElementsTotal && pdhcpIpArray)
{
for (DWORD i = 0; i < pdhcpIpArray->NumElements; i++)
{
// check this scope
CString strEmpty;
DWORD err = ScanScope(strEmpty, pdhcpIpArray->Elements[i]);
if (err != ERROR_SUCCESS)
{
dwError = err;
break;
}
}
//
// Free up the RPC memory
//
::DhcpRpcFreeMemory(pdhcpIpArray);
dwElementsRead = 0;
dwElementsTotal = 0;
pdhcpIpArray = NULL;
}
}
if (dwError != ERROR_NO_MORE_ITEMS &&
dwError != ERROR_SUCCESS &&
dwError != ERROR_MORE_DATA)
{
m_dwErr = dwError;
}
else
{
m_dwErr = ERROR_SUCCESS;
}
}
DWORD
CReconcileWorker::ScanScope(CString & strName, DWORD dwScopeId)
{
DWORD err = 0;
CScopeReconInfo ScopeReconInfo;
ScopeReconInfo.m_dwScopeId = dwScopeId;
ScopeReconInfo.m_strName = strName;
// check the scope. If the name is empty then is is a normal scope
// otherwise it is a multicast scope
err = (strName.IsEmpty()) ? m_pServer->ScanDatabase(FALSE, &ScopeReconInfo.m_pScanList, ScopeReconInfo.m_dwScopeId) :
m_pServer->ScanDatabase(FALSE, &ScopeReconInfo.m_pScanList, (LPWSTR) (LPCTSTR) ScopeReconInfo.m_strName);
if (err == ERROR_SUCCESS)
{
m_pScopeReconArray->Add(ScopeReconInfo);
}
return err;
}
/////////////////////////////////////////////////////////////////////////////
// CReconcileDlg dialog
CReconcileDlg::CReconcileDlg
(
ITFSNode * pServerNode,
BOOL fReconcileAll,
CWnd* pParent /*=NULL*/
)
: CBaseDialog(CReconcileDlg::IDD, pParent),
m_bListBuilt(FALSE),
m_bMulticast(FALSE),
m_fReconcileAll(fReconcileAll)
{
//{{AFX_DATA_INIT(CReconcileDlg)
//}}AFX_DATA_INIT
m_spNode.Set(pServerNode);
}
void
CReconcileDlg::DoDataExchange(CDataExchange* pDX)
{
CBaseDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CReconcileDlg)
DDX_Control(pDX, IDC_LIST_RECONCILE_IP_ADDRESSES, m_listctrlAddresses);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CReconcileDlg, CBaseDialog)
//{{AFX_MSG_MAP(CReconcileDlg)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CReconcileDlg message handlers
BOOL
CReconcileDlg::OnInitDialog()
{
CBaseDialog::OnInitDialog();
if (m_fReconcileAll)
{
CString strText;
// set the dialog title
strText.LoadString(IDS_RECONCILE_ALL_SCOPES_TITLE);
SetWindowText(strText);
}
// setup the listctrl
CString strTemp;
// add the scope column
strTemp.LoadString(IDS_SCOPE_FOLDER);
m_listctrlAddresses.InsertColumn(0, strTemp, LVCFMT_LEFT, 150);
// add the address column
strTemp.LoadString(IDS_IP_ADDRESS);
m_listctrlAddresses.InsertColumn(1, strTemp, LVCFMT_LEFT, 150);
SetOkButton(m_bListBuilt);
return TRUE; // return TRUE unless you set the focus to a control
}
void CReconcileDlg::SetOkButton(BOOL bListBuilt)
{
CWnd * pWnd = GetDlgItem(IDOK);
CString strButton;
if (bListBuilt)
{
strButton.LoadString(IDS_RECONCILE_DATABASE);
}
else
{
strButton.LoadString(IDS_CHECK_DATABASE);
}
pWnd->SetWindowText(strButton);
}
void CReconcileDlg::OnOK()
{
DWORD err = 0;
CDhcpScope * pScope;
CDhcpMScope * pMScope;
CDhcpServer * pServer;
if (m_fReconcileAll)
{
pServer = GETHANDLER(CDhcpServer, m_spNode);
}
else
{
if (m_bMulticast)
{
pMScope = GETHANDLER(CDhcpMScope, m_spNode);
pServer = pMScope->GetServerObject();
}
else
{
pScope = GETHANDLER(CDhcpScope, m_spNode);
pServer = pScope->GetServerObject();
}
}
if (m_bListBuilt)
{
// we've built a list of inconsistencies. Tell the
// dhcp server to reconcile them.
//
CReconcileWorker * pWorker = new CReconcileWorker(pServer, &m_ScopeReconArray);
CLongOperationDialog dlgBusy(pWorker, IDR_SEARCH_AVI);
dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
dlgBusy.LoadDescriptionString(IDS_FIXING_SCOPES);
dlgBusy.DoModal();
if (pWorker->GetError() != ERROR_SUCCESS)
{
::DhcpMessageBox(pWorker->GetError());
}
else
{
m_bListBuilt = FALSE;
m_listctrlAddresses.DeleteAllItems();
SetOkButton(m_bListBuilt);
}
}
else
{
//
// First we scan the whole database to see if
// there are IP addresses that need to be resolved.
//
m_listctrlAddresses.DeleteAllItems();
m_ScopeReconArray.RemoveAll();
CReconcileWorker * pWorker = new CReconcileWorker(pServer, &m_ScopeReconArray);
CLongOperationDialog dlgBusy(pWorker, IDR_SEARCH_AVI);
dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
dlgBusy.LoadDescriptionString(IDS_CHECKING_SCOPES);
pWorker->m_fReconcileAll = m_fReconcileAll;
pWorker->m_fMulticast = m_bMulticast;
if (!m_fReconcileAll)
{
if (m_bMulticast)
{
pWorker->m_strName = pMScope->GetName();
}
else
{
pWorker->m_dwScopeId = pScope->GetAddress();
}
}
dlgBusy.DoModal();
if (pWorker->GetError() != ERROR_SUCCESS)
{
::DhcpMessageBox(pWorker->GetError());
return;
}
// walk the list and build the display
for (int i = 0; i < m_ScopeReconArray.GetSize(); i++)
{
if (m_ScopeReconArray[i].m_pScanList->NumScanItems > 0)
{
//
// There are items to be reconciled.
// Present the list of ip addresses
// that didn't match, and let
// the user decide to add them
// or not.
//
AddItemToList(m_ScopeReconArray[i]);
m_bListBuilt = TRUE;
SetOkButton(m_bListBuilt);
}
}
if (!m_bListBuilt)
{
AfxMessageBox(IDS_MSG_NO_RECONCILE, MB_ICONINFORMATION);
}
}
//CBaseDialog::OnOK();
}
void
CReconcileDlg::AddItemToList(CScopeReconInfo & scopeReconInfo)
{
CString strScope;
CString strAddress;
int nItem = 0;
// get the scope string
if (scopeReconInfo.m_strName.IsEmpty())
{
// normal scope
::UtilCvtIpAddrToWstr(scopeReconInfo.m_dwScopeId, &strScope);
}
else
{
// multicast scope
strScope = scopeReconInfo.m_strName;
}
// convert the inconsistent address
for (DWORD j = 0; j < scopeReconInfo.m_pScanList->NumScanItems; j++)
{
::UtilCvtIpAddrToWstr(scopeReconInfo.m_pScanList->ScanItems[j].IpAddress, &strAddress);
nItem = m_listctrlAddresses.InsertItem(nItem, strScope);
m_listctrlAddresses.SetItemText(nItem, 1, strAddress);
}
}