WindowsXP-SP1/admin/snapin/dnsmgr/server.cpp
2020-09-30 16:53:49 +02:00

3620 lines
102 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: server.cpp
//
//--------------------------------------------------------------------------
#include "preDNSsn.h"
#include <SnapBase.h>
#include "resource.h"
#include "dnsutil.h"
#include "DNSSnap.h"
#include "snapdata.h"
#include "server.h"
#include "serverui.h"
#include "servmon.h"
#include "servwiz.h"
#include "domain.h"
#include "record.h"
#include "zone.h"
#include "ZoneWiz.h"
#ifdef DEBUG_ALLOCATOR
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
// GLOBAL FUNCTIONS
LPCWSTR DNS_EVT_COMMAND_LINE = L"\\system32\\msdssevt.msc /computer=";
LPCWSTR MMC_APP = L"\\system32\\mmc.exe";
DNS_STATUS ServerHasCache(LPCWSTR lpszServerName, BOOL* pbRes)
{
USES_CONVERSION;
*pbRes = FALSE;
DWORD dwFilter = ZONE_REQUEST_CACHE;
PDNS_RPC_ZONE_LIST pZoneList = NULL;
DNS_STATUS err = ::DnssrvEnumZones(lpszServerName,
dwFilter,
NULL /*pszLastZone, unused for the moment */,
&pZoneList);
if (err == 0 &&
pZoneList)
{
*pbRes = (pZoneList->dwZoneCount > 0);
::DnssrvFreeZoneList(pZoneList);
}
else
{
ASSERT(pZoneList);
}
return err;
}
DNS_STATUS ServerHasRootZone(LPCWSTR lpszServerName, BOOL* pbRes)
{
USES_CONVERSION;
*pbRes = FALSE;
DWORD dwFilter = ZONE_REQUEST_FORWARD | ZONE_REQUEST_PRIMARY | ZONE_REQUEST_SECONDARY;
PDNS_RPC_ZONE_LIST pZoneList = NULL;
DNS_STATUS err = ::DnssrvEnumZones(lpszServerName,
dwFilter,
NULL /*pszLastZone, unused for the moment */,
&pZoneList);
if (err == 0 && pZoneList)
{
for (DWORD iZone = 0; iZone < pZoneList->dwZoneCount; iZone++)
{
if (pZoneList->ZoneArray[iZone]->pszZoneName)
{
if (wcscmp(L".", pZoneList->ZoneArray[iZone]->pszZoneName) == 0)
{
*pbRes = TRUE;
break;
}
}
}
}
if (pZoneList != NULL)
::DnssrvFreeZoneList(pZoneList);
return err;
}
///////////////////////////////////////////////////////////////////////////////
// CZoneInfoHolder : simple memory manager for arrays of zone info handles
#define DEFAULT_ZONE_INFO_ARRAY_SIZE (128)
#define MAX_ZONE_INFO_ARRAY_SIZE (0xffff)
CZoneInfoHolder::CZoneInfoHolder()
{
AllocateMemory(DEFAULT_ZONE_INFO_ARRAY_SIZE);
}
CZoneInfoHolder::~CZoneInfoHolder()
{
FreeMemory();
}
void CZoneInfoHolder::AllocateMemory(DWORD dwArrSize)
{
TRACE(_T("CZoneInfoHolder::AllocateMemory(dwArrSize = %d)\n"), dwArrSize);
m_dwArrSize = dwArrSize;
DWORD dwMemSize = 2*m_dwArrSize*sizeof(PDNS_ZONE_INFO);
m_zoneInfoArray = (PDNS_ZONE_INFO*)malloc(dwMemSize);
if (m_zoneInfoArray != NULL)
{
ASSERT(m_zoneInfoArray != NULL);
memset(m_zoneInfoArray, 0x0, dwMemSize);
m_dwZoneCount = 0;
#ifdef _DEBUG
for (DWORD k=0; k< dwArrSize; k++)
ASSERT(m_zoneInfoArray[k] == NULL);
#endif
}
}
void CZoneInfoHolder::FreeMemory()
{
if (m_zoneInfoArray != NULL)
{
TRACE(_T("CZoneInfoHolder::FreeMemory() m_dwArrSize = %d\n"), m_dwArrSize);
ASSERT(m_dwArrSize > 0);
//ASSERT(m_dwZoneCount <= m_dwArrSize);
for (DWORD k=0; k < m_dwArrSize; k++)
{
if (m_zoneInfoArray[k] != NULL)
{
TRACE(_T("CZoneInfoHolder::FreeMemory() DnsFreeZoneInfo(m_zoneInfoArray[%d])\n"), k);
::DnssrvFreeZoneInfo(m_zoneInfoArray[k]);
}
}
free(m_zoneInfoArray);
m_zoneInfoArray = NULL;
m_dwZoneCount = 0;
m_dwArrSize = 0;
}
}
BOOL CZoneInfoHolder::Grow()
{
TRACE(_T("CZoneInfoHolder::Grow()\n"));
if (m_dwArrSize >= MAX_ZONE_INFO_ARRAY_SIZE)
return FALSE;
ASSERT(m_dwArrSize > 0);
ASSERT(m_dwZoneCount > m_dwArrSize);
DWORD dwNewSize = m_dwZoneCount;
FreeMemory();
AllocateMemory(dwNewSize);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
// CDNSMTContainerNode
CDNSMTContainerNode::CDNSMTContainerNode()
{
m_pServerNode = NULL;
m_nState = notLoaded;
m_szDescriptionBar = _T("");
m_pColumnSet = NULL;
}
HRESULT CDNSMTContainerNode::OnSetToolbarVerbState(IToolbar* pToolbar,
CNodeList*)
{
HRESULT hr = S_OK;
//
// Set the button state for each button on the toolbar
//
hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
return hr;
}
LPWSTR CDNSMTContainerNode::GetDescriptionBarText()
{
static CString szFilterEnabled;
if(((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
{
if (szFilterEnabled.IsEmpty())
{
szFilterEnabled.LoadString(IDS_FILTER_ENABLED);
}
m_szDescriptionBar = szFilterEnabled;
}
else
{
m_szDescriptionBar = _T("");
}
return (LPWSTR)(LPCWSTR)m_szDescriptionBar;
}
int CDNSMTContainerNode::GetImageIndex(BOOL)
{
int nIndex = 0;
switch (m_nState)
{
case notLoaded:
nIndex = FOLDER_IMAGE_NOT_LOADED;
break;
case loading:
nIndex = FOLDER_IMAGE_LOADING;
break;
case loaded:
nIndex = FOLDER_IMAGE_LOADED;
break;
case unableToLoad:
nIndex = FOLDER_IMAGE_UNABLE_TO_LOAD;
break;
case accessDenied:
nIndex = FOLDER_IMAGE_ACCESS_DENIED;
break;
default:
ASSERT(FALSE);
}
return nIndex;
}
void CDNSMTContainerNode::OnChangeState(CComponentDataObject* pComponentDataObject)
{
switch (m_nState)
{
case notLoaded:
case loaded:
case unableToLoad:
case accessDenied:
{
m_nState = loading;
m_dwErr = 0;
}
break;
case loading:
{
if (m_dwErr == 0)
m_nState = loaded;
else if (m_dwErr == ERROR_ACCESS_DENIED)
m_nState = accessDenied;
else
m_nState = unableToLoad;
}
break;
default:
ASSERT(FALSE);
}
VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
VERIFY(SUCCEEDED(pComponentDataObject->UpdateVerbState(this)));
if (m_nState != loading)
{
pComponentDataObject->UpdateResultPaneView(this);
}
}
BOOL CDNSMTContainerNode::CanCloseSheets()
{
return (IDCANCEL != DNSMessageBox(IDS_MSG_CONT_CLOSE_SHEET, MB_OKCANCEL));
}
void CDNSMTContainerNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
{
CDNSMTContainerNode* p = dynamic_cast<CDNSMTContainerNode*>(pObj);
ASSERT(p != NULL);
if (p != NULL)
{
p->SetServerNode(GetServerNode());
}
AddChildToListAndUI(p, pComponentDataObject);
pComponentDataObject->SetDescriptionBarText(this);
}
void CDNSMTContainerNode::OnError(DWORD dwErr)
{
if (dwErr == ERROR_MORE_DATA)
{
// need to pop message
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString szFmt;
szFmt.LoadString(IDS_MSG_QUERY_TOO_MANY_ITEMS);
CString szMsg;
szMsg.Format(szFmt, GetDisplayName());
AfxMessageBox(szMsg);
// this is actually a warning, need to reset
dwErr = 0;
}
m_dwErr = dwErr;
}
///////////////////////////////////////////////////////////////////////////////
// CDNSQueryObj : general purpose base class
void CDNSQueryObj::SetFilterOptions(CDNSQueryFilter* pFilter)
{
// limits
m_bGetAll = pFilter->GetAll();
m_nMaxObjectCount = pFilter->GetMaxObjectCount();
// filtering
m_nFilterOption = pFilter->GetFilterOption();
m_szFilterString1 = pFilter->GetFilterString();
m_nFilterStringLen1 = m_szFilterString1.GetLength();
m_szFilterString2 = pFilter->GetFilterStringRange();
m_nFilterStringLen2 = m_szFilterString2.GetLength();
if ((m_nFilterStringLen1 == 0) && (m_nFilterStringLen2 == 0))
m_nFilterOption = DNS_QUERY_FILTER_NONE;
}
BOOL CDNSQueryObj::MatchName(LPCWSTR lpszName)
{
if (m_nFilterOption == DNS_QUERY_FILTER_CONTAINS)
{
//
// wcsstr is case sensitive so make the strings lower
// case before trying to find the substring
//
CString szName = lpszName;
CString szFilterString = m_szFilterString1;
szName.MakeLower();
szFilterString.MakeLower();
LPWSTR lpsz = wcsstr((LPCWSTR)szName, (LPCWSTR)szFilterString);
return (lpsz != NULL);
}
if (m_nFilterOption == DNS_QUERY_FILTER_STARTS)
{
// match at the beginning
size_t nLen = wcslen(lpszName);
if (static_cast<int>(nLen) < m_nFilterStringLen1)
return FALSE; // too short
return (_wcsnicmp(lpszName, (LPCWSTR)m_szFilterString1, m_nFilterStringLen1) == 0);
}
if (m_nFilterOption == DNS_QUERY_FILTER_RANGE)
{
// test lower limit
if (m_nFilterStringLen1 > 0)
{
if (_wcsicmp(lpszName, (LPCWSTR)m_szFilterString1) < 0)
return FALSE; // below range, no need to continue
}
// test upper limit
if (m_nFilterStringLen2 > 0)
{
return _wcsnicmp(lpszName, (LPCWSTR)m_szFilterString2, m_nFilterStringLen2) <= 0;
}
return TRUE;
}
return TRUE;
}
BOOL CDNSQueryObj::TooMuchData()
{
if (m_bGetAll || (m_nObjectCount <= m_nMaxObjectCount))
return FALSE;
TRACE(_T("TooMuchData() m_nObjectCount = %d "), m_nObjectCount);
/*
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString szFmt;
szFmt.LoadString(IDS_MSG_QUERY_TOO_MANY_ITEMS);
CString szMsg;
szMsg.Format(szFmt, lpszFolderName);
AfxMessageBox(szMsg);
*/
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
// CCathegoryFolderNode
BOOL CCathegoryFolderQueryObj::CanAddZone(PDNS_RPC_ZONE pZoneInfo)
{
// no filtering if cache is selected
if (m_type == cache)
return TRUE;
// no filtering on reverse lookup autocreated zones
if ( (m_type == revAuthoritated) && (pZoneInfo->Flags.AutoCreated))
return TRUE;
// filter on name
return MatchName(pZoneInfo->pszZoneName);
}
BOOL CCathegoryFolderQueryObj::Enumerate()
{
USES_CONVERSION;
DWORD dwFilter = 0;
switch(m_type)
{
case cache:
dwFilter = ZONE_REQUEST_CACHE;
m_bGetAll = TRUE; // no limit on #, to be safe
break;
case fwdAuthoritated:
dwFilter = ZONE_REQUEST_FORWARD |
ZONE_REQUEST_PRIMARY |
ZONE_REQUEST_SECONDARY |
ZONE_REQUEST_STUB;
break;
case revAuthoritated:
dwFilter = ZONE_REQUEST_REVERSE |
ZONE_REQUEST_PRIMARY |
ZONE_REQUEST_SECONDARY |
ZONE_REQUEST_STUB |
ZONE_REQUEST_AUTO;
break;
case domainForwarders:
dwFilter = ZONE_REQUEST_FORWARDER;
break;
}
PDNS_RPC_ZONE_LIST pZoneList = NULL;
DNS_STATUS err = ::DnssrvEnumZones(m_szServerName,
dwFilter,
NULL /*pszLastZone, unused for the moment */,
&pZoneList);
if (err != 0)
{
if (pZoneList != NULL)
::DnssrvFreeZoneList(pZoneList);
OnError(err);
return FALSE;
}
if (!pZoneList)
{
ASSERT(pZoneList);
return FALSE;
}
for (DWORD iZone = 0; iZone < pZoneList->dwZoneCount; iZone++)
{
if (pZoneList->ZoneArray[iZone]->Flags.AutoCreated)
{
// if the zone is autocreated, we cannot count it in the
// filtering limit, because we need it anyway
m_nMaxObjectCount++;
}
else
{
if (TooMuchData())
break;
}
//
// Don't filter the domain forwarders
//
if (m_type != domainForwarders)
{
if (CanAddZone(pZoneList->ZoneArray[iZone]))
{
TRACE(_T("%s\n"),pZoneList->ZoneArray[iZone]->pszZoneName);
CDNSZoneNode* pZoneNode = new CDNSZoneNode();
if (pZoneNode != NULL)
{
pZoneNode->InitializeFromRPCZoneInfo(pZoneList->ZoneArray[iZone], m_bAdvancedView);
VERIFY(AddQueryResult(pZoneNode));
}
}
}
else
{
TRACE(_T("%s\n"),pZoneList->ZoneArray[iZone]->pszZoneName);
CDNSZoneNode* pZoneNode = new CDNSZoneNode();
if (pZoneNode != NULL)
{
pZoneNode->InitializeFromRPCZoneInfo(pZoneList->ZoneArray[iZone], m_bAdvancedView);
VERIFY(AddQueryResult(pZoneNode));
}
}
}
::DnssrvFreeZoneList(pZoneList);
return FALSE;
}
CQueryObj* CCathegoryFolderNode::OnCreateQuery()
{
CDNSRootData* pRootData = (CDNSRootData*)GetRootContainer();
ASSERT(pRootData != NULL);
ASSERT(m_type != CCathegoryFolderQueryObj::unk);
CCathegoryFolderQueryObj* pQuery =
new CCathegoryFolderQueryObj(pRootData->IsAdvancedView(),
GetServerNode()->GetVersion());
pQuery->m_szServerName = GetServerNode()->GetRPCName();
pQuery->SetType(m_type);
return pQuery;
}
HRESULT CCathegoryFolderNode::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return E_FAIL;
}
if (nCommandID == IDM_SNAPIN_ADVANCED_VIEW)
{
((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
pComponentData->UpdateResultPaneView(this);
return S_OK;
}
if (nCommandID == IDM_SNAPIN_FILTERING)
{
if(((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
{
pComponentData->SetDescriptionBarText(this);
}
return S_OK;
}
return E_FAIL;
}
BOOL CCathegoryFolderNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long*)
{
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
{
pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
}
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
{
if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
{
pContextMenuItem2->fFlags = MF_CHECKED;
}
return TRUE;
}
return FALSE;
}
BOOL CCathegoryFolderNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList*)
{
*pbHide = FALSE;
return !IsThreadLocked();
}
LPWSTR CCathegoryFolderNode::GetDescriptionBarText()
{
static CString szFilterEnabled;
static CString szZonesFormat;
INT_PTR nContainerCount = GetContainerChildList()->GetCount();
INT_PTR nLeafCount = GetLeafChildList()->GetCount();
//
// If not already loaded, then load the format string L"%d record(s)"
//
if (szZonesFormat.IsEmpty())
{
szZonesFormat.LoadString(IDS_FORMAT_ZONES);
}
//
// Format the child count into the description bar text
//
m_szDescriptionBar.Format(szZonesFormat, nContainerCount + nLeafCount);
//
// Add L"[Filter Activated]" if the filter is on
//
if(((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
{
//
// If not already loaded, then load the L"[Filter Activated]" string
//
if (szFilterEnabled.IsEmpty())
{
szFilterEnabled.LoadString(IDS_FILTER_ENABLED);
}
m_szDescriptionBar += szFilterEnabled;
}
return (LPWSTR)(LPCWSTR)m_szDescriptionBar;
}
/////////////////////////////////////////////////////////////////////////
// CDNSCacheNode
CDNSCacheNode::CDNSCacheNode()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_type = CCathegoryFolderQueryObj::cache;
m_dwNodeFlags |= TN_FLAG_NO_WRITE;
m_szDisplayName.LoadString(IDS_CATHEGORY_FOLDER_CACHE);
}
BOOL CDNSCacheNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long*)
{
//we have only one menu item, so no checks
if (IsThreadLocked())
{
pContextMenuItem2->fFlags |= MF_GRAYED;
}
return TRUE;
}
HRESULT CDNSCacheNode::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return E_FAIL;
}
switch (nCommandID)
{
case IDM_CACHE_FOLDER_CLEAR_CACHE:
OnClearCache(pComponentData);
break;
default:
ASSERT(FALSE); // Unknown command!
return E_FAIL;
}
return S_OK;
}
void CDNSCacheNode::OnClearCache(CComponentDataObject* pComponentData)
{
ASSERT((GetFlags() & TN_FLAG_HIDDEN) == 0); // must not be hidden
// if there are sheets up, ask to close them down, because
// we will need a refresh
if (IsSheetLocked())
{
if (!CanCloseSheets())
return;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
DNS_STATUS err;
{ // scope for the wait cursor
CWaitCursor wait;
err = GetServerNode()->ClearCache();
}
if (err != 0)
{
// need to let the user know the operation failed
DNSErrorDialog(err, IDS_MSG_SERVER_FAIL_CLEAR_CACHE);
return;
}
CNodeList nodeList;
nodeList.AddTail(this);
// the cache has been cleared, cause a refresh to get new data
VERIFY(OnRefresh(pComponentData, &nodeList));
}
/////////////////////////////////////////////////////////////////////////
// CDNSDomainForwardersNode
//
CDNSDomainForwardersNode::CDNSDomainForwardersNode()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_type = CCathegoryFolderQueryObj::domainForwarders;
//
// Always hide the domain forwarders node
//
m_dwNodeFlags |= TN_FLAG_HIDDEN;
m_szDisplayName.LoadString(IDS_CATHEGORY_FOLDER_DOMAIN_FORWARDERS);
}
BOOL CDNSDomainForwardersNode::OnEnumerate(CComponentDataObject* pComponentData, BOOL)
{
OnChangeState(pComponentData);
VERIFY(StartBackgroundThread(pComponentData, FALSE));
//
// Now enumerate all the children
//
CNodeList* pContList = GetContainerChildList();
if (pContList != NULL)
{
POSITION pos = pContList->GetHeadPosition();
while (pos != NULL)
{
CDNSZoneNode* pZoneNode = reinterpret_cast<CDNSZoneNode*>(pContList->GetNext(pos));
if (pZoneNode != NULL)
{
//
// Enumerate the zone asynchronously
//
pZoneNode->OnEnumerate(pComponentData);
}
}
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////
// CDNSAuthoritatedZonesNode
BEGIN_TOOLBAR_MAP(CDNSAuthoritatedZonesNode)
TOOLBAR_EVENT(toolbarNewZone, OnNewZone)
END_TOOLBAR_MAP()
CDNSAuthoritatedZonesNode::CDNSAuthoritatedZonesNode(BOOL bReverse, UINT nStringID)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_szDisplayName.LoadString(nStringID);
m_bReverse = bReverse;
m_type = bReverse ? CCathegoryFolderQueryObj::revAuthoritated :
CCathegoryFolderQueryObj::fwdAuthoritated;
}
HRESULT CDNSAuthoritatedZonesNode::OnSetToolbarVerbState(IToolbar* pToolbar,
CNodeList* pNodeList)
{
HRESULT hr = S_OK;
//
// Set the button state for each button on the toolbar
//
hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
if (pNodeList->GetCount() > 1) // multiple selection
{
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
}
else if (pNodeList->GetCount() == 1) // single selection
{
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, (m_nState == loaded));
ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT CDNSAuthoritatedZonesNode::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
HRESULT hr = S_OK;
if (pNodeList->GetCount() > 1) // multiple selection
{
return E_FAIL;
}
switch (nCommandID)
{
case IDM_SERVER_NEW_ZONE:
hr = OnNewZone(pComponentData, pNodeList);
pComponentData->UpdateResultPaneView(this);
break;
case IDM_SNAPIN_ADVANCED_VIEW:
((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
pComponentData->UpdateResultPaneView(this);
break;
case IDM_SNAPIN_FILTERING:
{
if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
{
pComponentData->SetDescriptionBarText(this);
}
}
break;
default:
ASSERT(FALSE); // Unknown command!
return E_FAIL;
}
return hr;
};
HRESULT CDNSAuthoritatedZonesNode::OnNewZone(CComponentDataObject* pComponentData, CNodeList*)
{
ASSERT(pComponentData != NULL);
CDNSServerNode* pServerNode = GetServerNode();
ASSERT(pServerNode != NULL);
CDNSZoneWizardHolder holder(pComponentData);
holder.Initialize(pServerNode);
holder.PreSetZoneLookupType(!m_bReverse);
holder.DoModalWizard();
return S_OK;
}
BOOL CDNSAuthoritatedZonesNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long*)
{
// gray out commands that need data from the server
if ((m_nState != loaded) && (pContextMenuItem2->lCommandID == IDM_SERVER_NEW_ZONE))
{
pContextMenuItem2->fFlags |= MF_GRAYED;
}
// add toggle menu item for advanced view
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
{
pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
}
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
{
if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
{
pContextMenuItem2->fFlags = MF_CHECKED;
}
return TRUE;
}
return TRUE;
};
BOOL CDNSAuthoritatedZonesNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList*)
{
*pbHide = FALSE;
return !IsThreadLocked();
}
/////////////////////////////////////////////////////////////////////////
// CDNSForwardZonesNode
CDNSForwardZonesNode::CDNSForwardZonesNode() :
CDNSAuthoritatedZonesNode(FALSE, IDS_CATHEGORY_FOLDER_FWD)
{
}
HRESULT CDNSForwardZonesNode::GetResultViewType(CComponentDataObject*,
LPOLESTR *ppViewType,
long *pViewOptions)
{
HRESULT hr = S_FALSE;
if ((m_containerChildList.IsEmpty() &&
m_leafChildList.IsEmpty()) ||
m_nState == accessDenied ||
m_nState == unableToLoad &&
m_nState != loading &&
m_nState != notLoaded)
{
*pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
LPOLESTR psz = NULL;
StringFromCLSID(CLSID_MessageView, &psz);
USES_CONVERSION;
if (psz != NULL)
{
*ppViewType = psz;
hr = S_OK;
}
}
else
{
*pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
*ppViewType = NULL;
hr = S_FALSE;
}
return hr;
}
HRESULT CDNSForwardZonesNode::OnShow(LPCONSOLE lpConsole)
{
CComPtr<IUnknown> spUnknown;
CComPtr<IMessageView> spMessageView;
HRESULT hr = lpConsole->QueryResultView(&spUnknown);
if (FAILED(hr))
return S_OK;
hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
if (SUCCEEDED(hr))
{
CString szTitle, szMessage;
IconIdentifier iconID;
if (m_nState == accessDenied)
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
iconID = Icon_Error;
}
else if (m_nState == unableToLoad)
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
iconID = Icon_Error;
}
else
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_MESSAGE));
iconID = Icon_Information;
}
spMessageView->SetTitleText(szTitle);
spMessageView->SetBodyText(szMessage);
spMessageView->SetIcon(iconID);
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////
// CDNSReverseZonesNode
CDNSReverseZonesNode::CDNSReverseZonesNode() :
CDNSAuthoritatedZonesNode(TRUE, IDS_CATHEGORY_FOLDER_REV)
{
m_p0ZoneNode = NULL;
m_p127ZoneNode = NULL;
m_p255ZoneNode = NULL;
}
BOOL CDNSReverseZonesNode::OnRefresh(CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return FALSE;
}
if (CDNSAuthoritatedZonesNode::OnRefresh(pComponentData, pNodeList))
{
m_p0ZoneNode = NULL;
m_p127ZoneNode = NULL;
m_p255ZoneNode = NULL;
return TRUE;
}
return FALSE;
}
void CDNSReverseZonesNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
{
// the autocreated zone nodes can be shown or not, depending on the view options
if ( (m_p0ZoneNode == NULL) || (m_p127ZoneNode == NULL) || (m_p255ZoneNode == NULL) &&
IS_CLASS(*pObj, CDNSZoneNode))
{
CDNSZoneNode* pZoneNode = dynamic_cast<CDNSZoneNode*>(pObj);
ASSERT(pZoneNode != NULL); // should never have anything below but zones!!!
if (pZoneNode != NULL)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentDataObject->GetRootData();
if (pZoneNode->IsAutocreated())
{
BOOL bCachedPointer = FALSE;
if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_0) == 0)
{
ASSERT(m_p0ZoneNode == NULL);
m_p0ZoneNode = pZoneNode;
bCachedPointer = TRUE;
}
else if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_127) == 0)
{
ASSERT(m_p127ZoneNode == NULL);
m_p127ZoneNode = pZoneNode;
bCachedPointer = TRUE;
}
else if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_255) == 0)
{
ASSERT(m_p255ZoneNode == NULL);
m_p255ZoneNode = pZoneNode;
bCachedPointer = TRUE;
}
if (bCachedPointer && !pRootData->IsAdvancedView())
{
pZoneNode->SetFlagsDown(TN_FLAG_HIDDEN,TRUE); // mark it hidden, will not be added to UI
}
}
}
}
CDNSMTContainerNode::OnHaveData(pObj,pComponentDataObject);
}
void CDNSReverseZonesNode::ChangeViewOption(BOOL bAdvanced,
CComponentDataObject* pComponentDataObject)
{
POSITION pos;
for( pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pCurrentChild = m_containerChildList.GetNext(pos);
CDNSZoneNode* pZoneNode = dynamic_cast<CDNSZoneNode*>(pCurrentChild);
ASSERT(pZoneNode != NULL);
pZoneNode->ChangeViewOption(bAdvanced, pComponentDataObject);
}
if (m_p0ZoneNode != NULL)
m_p0ZoneNode->Show(bAdvanced,pComponentDataObject);
if (m_p127ZoneNode != NULL)
m_p127ZoneNode->Show(bAdvanced,pComponentDataObject);
if (m_p255ZoneNode != NULL)
m_p255ZoneNode->Show(bAdvanced,pComponentDataObject);
}
HRESULT CDNSReverseZonesNode::GetResultViewType(CComponentDataObject*,
LPOLESTR *ppViewType,
long *pViewOptions)
{
HRESULT hr = S_FALSE;
// the 3 refers to the auto-created reverse lookup zones
if ((m_containerChildList.IsEmpty() &&
m_leafChildList.IsEmpty()) ||
(!((CDNSRootData*)GetRootContainer())->IsAdvancedView() && m_containerChildList.GetCount() == 3) ||
m_nState == accessDenied ||
m_nState == unableToLoad &&
m_nState != loading &&
m_nState != notLoaded)
{
*pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
LPOLESTR psz = NULL;
StringFromCLSID(CLSID_MessageView, &psz);
USES_CONVERSION;
if (psz != NULL)
{
*ppViewType = psz;
hr = S_OK;
}
}
else
{
*pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
*ppViewType = NULL;
hr = S_FALSE;
}
return hr;
}
HRESULT CDNSReverseZonesNode::OnShow(LPCONSOLE lpConsole)
{
CComPtr<IUnknown> spUnknown;
CComPtr<IMessageView> spMessageView;
HRESULT hr = lpConsole->QueryResultView(&spUnknown);
if (FAILED(hr))
return S_OK;
hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
if (SUCCEEDED(hr))
{
CString szTitle, szMessage;
IconIdentifier iconID;
if (m_nState == accessDenied)
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
iconID = Icon_Error;
}
else if (m_nState == unableToLoad)
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
iconID = Icon_Error;
}
else
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_MESSAGE));
iconID = Icon_Information;
}
spMessageView->SetTitleText(szTitle);
spMessageView->SetBodyText(szMessage);
spMessageView->SetIcon(iconID);
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////
// CDNSServerTestOptions
CDNSServerTestOptions::CDNSServerTestOptions()
{
m_bEnabled = FALSE;
m_dwInterval = DEFAULT_SERVER_TEST_INTERVAL;
m_bSimpleQuery = FALSE;
m_bRecursiveQuery = FALSE;
}
HRESULT CDNSServerTestOptions::Save(IStream* pStm)
{
ULONG cbWrite;
VERIFY(SUCCEEDED(pStm->Write((void*)&m_bEnabled, sizeof(BOOL),&cbWrite)));
ASSERT(cbWrite == sizeof(BOOL));
VERIFY(SUCCEEDED(pStm->Write((void*)&m_dwInterval, sizeof(DWORD),&cbWrite)));
ASSERT(cbWrite == sizeof(DWORD));
VERIFY(SUCCEEDED(pStm->Write((void*)&m_bSimpleQuery, sizeof(BOOL),&cbWrite)));
ASSERT(cbWrite == sizeof(BOOL));
VERIFY(SUCCEEDED(pStm->Write((void*)&m_bRecursiveQuery, sizeof(BOOL),&cbWrite)));
ASSERT(cbWrite == sizeof(BOOL));
return S_OK;
}
HRESULT CDNSServerTestOptions::Load(IStream* pStm)
{
ULONG cbRead;
VERIFY(SUCCEEDED(pStm->Read((void*)&m_bEnabled,sizeof(BOOL), &cbRead)));
ASSERT(cbRead == sizeof(BOOL));
VERIFY(SUCCEEDED(pStm->Read((void*)&m_dwInterval,sizeof(DWORD), &cbRead)));
ASSERT(cbRead == sizeof(DWORD));
VERIFY(SUCCEEDED(pStm->Read((void*)&m_bSimpleQuery,sizeof(BOOL), &cbRead)));
ASSERT(cbRead == sizeof(BOOL));
VERIFY(SUCCEEDED(pStm->Read((void*)&m_bRecursiveQuery,sizeof(BOOL), &cbRead)));
ASSERT(cbRead == sizeof(BOOL));
// force range on test interval
if (m_dwInterval < MIN_SERVER_TEST_INTERVAL)
m_dwInterval = MIN_SERVER_TEST_INTERVAL;
else if (m_dwInterval > MAX_SERVER_TEST_INTERVAL)
m_dwInterval = MAX_SERVER_TEST_INTERVAL;
return S_OK;
}
const CDNSServerTestOptions&
CDNSServerTestOptions::operator=(const CDNSServerTestOptions& x)
{
m_bEnabled = x.m_bEnabled;
m_dwInterval = x.m_dwInterval;
m_bSimpleQuery = x.m_bSimpleQuery;
m_bRecursiveQuery = x.m_bRecursiveQuery;
return *this;
}
BOOL CDNSServerTestOptions::operator==(const CDNSServerTestOptions& x) const
{
if (m_bEnabled != x.m_bEnabled) return FALSE;
if (m_dwInterval != x.m_dwInterval) return FALSE;
if (m_bSimpleQuery != x.m_bSimpleQuery) return FALSE;
if (m_bRecursiveQuery != x.m_bRecursiveQuery) return FALSE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
// CDNSServerNode
BEGIN_TOOLBAR_MAP(CDNSServerNode)
TOOLBAR_EVENT(toolbarNewZone, OnNewZone)
END_TOOLBAR_MAP()
// {720132B8-44B2-11d1-B92F-00A0C9A06D2D}
const GUID CDNSServerNode::NodeTypeGUID =
{ 0x720132b8, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } };
CDNSServerNode::CDNSServerNode(LPCTSTR lpszName, BOOL bIsLocalServer)
{
SetServerNode(this);
m_szDisplayName = lpszName;
m_pServInfoEx = new CDNSServerInfoEx;
m_pRootHintsNode = NULL;
m_pCacheFolderNode = NULL;
m_pFwdZonesFolderNode = NULL;
m_pRevZonesFolderNode = NULL;
m_pDomainForwardersFolderNode = NULL;
m_dwTestTime = 0x0;
m_bTestQueryPending = FALSE;
m_bShowMessages = TRUE;
m_bPrevQuerySuccess = TRUE;
m_nStartProppage = -1;
m_bLocalServer = bIsLocalServer;
}
CDNSServerNode::~CDNSServerNode()
{
ASSERT(m_pServInfoEx != NULL);
delete m_pServInfoEx;
FreeRootHints();
//TRACE(_T("~CDNSServerNode(), name <%s>\n"),GetDisplayName());
}
void CDNSServerNode::SetDisplayName(LPCWSTR lpszDisplayName)
{
m_szDisplayName = lpszDisplayName;
}
LPCWSTR CDNSServerNode::GetRPCName()
{
return GetDisplayName();
}
CLIPFORMAT g_cfMachineName = (CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
CLIPFORMAT g_cfServiceName = (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_NAME");
CLIPFORMAT g_cfServiceDisplayName = (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME");
CLIPFORMAT g_cfFramewrkDataObjectType = (CLIPFORMAT)RegisterClipboardFormat(L"FRAMEWRK_DATA_OBJECT_TYPE");
CLIPFORMAT g_cfEventViewer = (CLIPFORMAT)RegisterClipboardFormat(L"CF_EV_VIEWS");
HRESULT CDNSServerNode::GetDataHere(CLIPFORMAT cf, LPSTGMEDIUM lpMedium,
CDataObject* pDataObject)
{
ASSERT(pDataObject != NULL);
HRESULT hr = DV_E_CLIPFORMAT;
if (cf == g_cfMachineName)
{
LPCWSTR pwszMachineName = GetDisplayName();
hr = pDataObject->Create(pwszMachineName, BYTE_MEM_LEN_W(pwszMachineName), lpMedium);
}
else if (cf == g_cfServiceName)
{
LPCWSTR pwszServiceName = _T("DNS");
hr = pDataObject->Create(pwszServiceName, BYTE_MEM_LEN_W(pwszServiceName), lpMedium);
}
else if (cf == g_cfServiceDisplayName)
{
LPCWSTR pwszServiceDisplayName = _T("Microsoft DNS Server");
hr = pDataObject->Create(pwszServiceDisplayName, BYTE_MEM_LEN_W(pwszServiceDisplayName), lpMedium);
}
else if (cf == g_cfFramewrkDataObjectType)
{
DATA_OBJECT_TYPES type = pDataObject->GetType();
hr = pDataObject->Create(&type, sizeof(DATA_OBJECT_TYPES), lpMedium);
}
return hr;
}
HRESULT CDNSServerNode::GetData(CLIPFORMAT cf, LPSTGMEDIUM lpMedium, CDataObject* pDataObject)
{
ASSERT(pDataObject != NULL);
HRESULT hr = DV_E_CLIPFORMAT;
if (cf == g_cfEventViewer)
{
hr = RetrieveEventViewerLogs(lpMedium, pDataObject);
}
return hr;
}
//
// Macros and #defines for event viewer clipformats
//
#define ELT_SYSTEM 101
#define ELT_SECURITY 102
#define ELT_APPLICATION 103
#define ELT_CUSTOM 104
#define VIEWINFO_BACKUP 0x0001
#define VIEWINFO_FILTERED 0x0002
#define VIEWINFO_LOW_SPEED 0x0004
#define VIEWINFO_USER_CREATED 0x0008
#define VIEWINFO_ALLOW_DELETE 0x0100
#define VIEWINFO_DISABLED 0x0200
#define VIEWINFO_READ_ONLY 0x0400
#define VIEWINFO_DONT_PERSIST 0x0800
#define VIEWINFO_CUSTOM ( VIEWINFO_FILTERED | VIEWINFO_DONT_PERSIST | \
VIEWINFO_ALLOW_DELETE | VIEWINFO_USER_CREATED)
#define EV_ALL_ERRORS (EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | \
EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS | \
EVENTLOG_AUDIT_FAILURE)
// Make sure that the data is processor aligned
#if defined(_X86_)
#define _RNDUP(p,m) (p)
#else
#define _RNDUP(p,m) (BYTE *)(((ULONG_PTR)(p) + (m) - 1) & ~((m) - 1))
#endif
#define ADD_TYPE(data, type) \
pPos = _RNDUP(pPos, (ULONG_PTR) __alignof(type)); \
*((type*)pPos) = (type)(data); \
pPos += sizeof(type)
#define ADD_USHORT(us) ADD_TYPE(us, USHORT)
#define ADD_BOOL(b) ADD_TYPE(b, BOOL)
#define ADD_ULONG(ul) ADD_TYPE(ul, ULONG)
#define ADD_STRING(str) \
strLength = wcslen((LPCWSTR)(str)) + 1; \
ADD_USHORT(strLength); \
wcsncpy((LPWSTR)pPos, (LPCWSTR)(str), strLength); \
pPos += strLength * sizeof(WCHAR);
HRESULT CDNSServerNode::RetrieveEventViewerLogs(LPSTGMEDIUM lpMedium, CDataObject*)
{
HRESULT hr = S_OK;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, 1024 );
if( NULL == hMem )
{
return STG_E_MEDIUMFULL;
}
//
// Get a pointer to our data
//
BYTE* pPos = reinterpret_cast<BYTE*>(::GlobalLock(hMem));
if (!pPos)
{
return HRESULT_FROM_WIN32(GetLastError());
}
size_t strLength = 0;
//
// Build the path to the event log
//
CString szDNSEventPath;
CString szConfigPath;
CString szServerName = L"\\\\";
szServerName += GetDisplayName();
szConfigPath += szServerName;
szConfigPath += L"\\Admin$\\System32\\config\\";
szDNSEventPath = szConfigPath;
szDNSEventPath += L"DNSEvent.Evt";
//
// Add header info
//
ADD_BOOL( TRUE ); // fOnlyTheseViews
ADD_USHORT( 1 ); // cViews
//
// Add application log filtered for our services
//
ADD_ULONG( ELT_CUSTOM ); // Type; ELT_CUSTOM
ADD_USHORT( VIEWINFO_CUSTOM ); // flViewFlags: VIEWINFO_FILTERED
ADD_STRING( GetDisplayName() ); // ServerName
ADD_STRING( L"DNS Server" ); // SourceName
ADD_STRING( szDNSEventPath ); // FileName
ADD_STRING( L"DNS Events" ); // DisplayName REVIEW_JEFFJON : this needs to be put in the rc file
ADD_ULONG( EV_ALL_ERRORS );// flRecType (could filter warning, error, etc.)
ADD_USHORT( 0 ); // usCategory
ADD_BOOL( FALSE ); // fEventID
ADD_ULONG( 0 ); // ulEventID
ADD_STRING( L"" ); // szSourceName
ADD_STRING( L"" ); // szUser
ADD_STRING( L"" ); // szComputer
ADD_ULONG( 0 ); // ulFrom
ADD_ULONG( 0 ); // ulTo
::GlobalUnlock( hMem ); // Unlock and set the rest of the
lpMedium->hGlobal = hMem; // StgMedium variables
lpMedium->tymed = TYMED_HGLOBAL;
lpMedium->pUnkForRelease = NULL;
return hr;
}
void CDNSServerNode::ChangeViewOption(BOOL bAdvanced, CComponentDataObject* pComponentData)
{
//
// changes in record options
//
SetFlagsOnNonContainers(TN_FLAG_DNS_RECORD_FULL_NAME , !bAdvanced);
//
//pComponentData->RepaintResultPane(this);
//
pComponentData->RepaintSelectedFolderInResultPane();
//
// Cached Lookup Folder
//
if (m_pCacheFolderNode != NULL)
{
m_pCacheFolderNode->Show(bAdvanced,pComponentData);
}
//
// Auto Created Zones
//
if (m_pRevZonesFolderNode != NULL)
{
m_pRevZonesFolderNode->ChangeViewOption(bAdvanced, pComponentData);
}
}
CDNSAuthoritatedZonesNode* CDNSServerNode::GetAuthoritatedZoneFolder(BOOL bFwd)
{
return bFwd ? (CDNSAuthoritatedZonesNode*)m_pFwdZonesFolderNode :
(CDNSAuthoritatedZonesNode*)m_pRevZonesFolderNode;
}
HRESULT CDNSServerNode::OnSetToolbarVerbState(IToolbar* pToolbar,
CNodeList* pNodeList)
{
HRESULT hr = S_OK;
//
// Set the button state for each button on the toolbar
//
hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
if (pNodeList->GetCount() > 1) // multiple selection
{
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
}
else if (pNodeList->GetCount() == 1) // single selection
{
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, (m_nState == loaded));
}
return hr;
}
HRESULT CDNSServerNode::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
HRESULT hr = S_OK;
if (pNodeList->GetCount() == 1) // single selection
{
switch (nCommandID)
{
case IDM_SERVER_NEW_ZONE:
hr = OnNewZone(pComponentData, pNodeList);
break;
case IDM_SERVER_UPDATE_DATA_FILES:
OnUpdateDataFiles(pComponentData);
break;
case IDM_SERVER_CLEAR_CACHE:
OnClearCache(pComponentData);
break;
case IDM_SNAPIN_ADVANCED_VIEW:
((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
break;
case IDM_SNAPIN_MESSAGE:
m_bShowMessages = !m_bShowMessages;
pComponentData->UpdateResultPaneView(this);
break;
case IDM_SNAPIN_FILTERING:
{
if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
{
pComponentData->SetDescriptionBarText(this);
}
}
break;
case IDM_SERVER_SET_AGING:
SetRecordAging();
break;
case IDM_SERVER_SCAVENGE:
ScavengeRecords();
break;
case IDM_SERVER_CONFIGURE:
OnConfigureServer(pComponentData);
break;
#ifdef USE_NDNC
case IDM_SERVER_CREATE_NDNC:
OnCreateNDNC();
break;
#endif
default:
ASSERT(FALSE); // Unknown command!
hr = E_FAIL;
}
}
else
{
hr = E_FAIL;
}
return hr;
}
#ifdef USE_NDNC
void CDNSServerNode::OnCreateNDNC()
{
// First ask if they want to create the domain NDNC
USES_CONVERSION;
do
{
DNS_STATUS err = 0;
CString szDomainNDNC;
szDomainNDNC.Format(IDS_SERVER_CREATE_DOMAIN_NDNC_FORMAT, UTF8_TO_W(GetDomainName()));
UINT nResult = DNSMessageBox(szDomainNDNC, MB_YESNOCANCEL | MB_ICONWARNING);
if (IDCANCEL == nResult)
{
// don't do anything more
break;
}
else if (IDYES == nResult)
{
// create the domain partition
err = ::DnssrvSetupDefaultDirectoryPartitions(
GetRPCName(),
DNS_DP_OP_CREATE_DOMAIN);
if (err != 0)
{
DNSErrorDialog(err, IDS_ERRMSG_CREATE_DOMAIN_NDNC);
break;
}
}
CString szForestNDNC;
szForestNDNC.Format(IDS_SERVER_CREATE_FOREST_NDNC_FORMAT, UTF8_TO_W(GetForestName()));
nResult = DNSMessageBox(szForestNDNC, MB_YESNO | MB_ICONWARNING);
if (IDYES == nResult)
{
// create the forest partition
err = ::DnssrvSetupDefaultDirectoryPartitions(
GetRPCName(),
DNS_DP_OP_CREATE_FOREST);
if (err != 0)
{
DNSErrorDialog(err, IDS_ERRMSG_CREATE_FOREST_NDNC);
break;
}
}
} while (false);
}
#endif // USE_NDNC
void CDNSServerNode::OnConfigureServer(CComponentDataObject* pComponentData)
{
CDNSServerWizardHolder holder((CDNSRootData*)GetRootContainer(), pComponentData, this);
holder.DoModalWizard();
pComponentData->UpdateResultPaneView(this);
}
void CDNSServerNode::SetRecordAging()
{
CDNSZone_AgingDialog dlg(NULL, IDD_SERVER_AGING_DIALOG, ((CDNSRootData*)GetRootContainer())->GetComponentDataObject());
dlg.m_dwRefreshInterval = GetDefaultRefreshInterval();
dlg.m_dwNoRefreshInterval = GetDefaultNoRefreshInterval();
dlg.m_fScavengingEnabled = GetDefaultScavengingState();
dlg.m_dwDefaultRefreshInterval = GetDefaultRefreshInterval();
dlg.m_dwDefaultNoRefreshInterval = GetDefaultNoRefreshInterval();
dlg.m_bDefaultScavengingState = GetDefaultScavengingState();
if (IDCANCEL == dlg.DoModal())
{
return;
}
DNS_STATUS dwErr;
if (dlg.m_dwRefreshInterval != GetDefaultRefreshInterval())
{
dwErr = ResetDefaultRefreshInterval(dlg.m_dwRefreshInterval);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
if (dlg.m_dwNoRefreshInterval != GetDefaultNoRefreshInterval())
{
dwErr = ResetDefaultNoRefreshInterval(dlg.m_dwNoRefreshInterval);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
if (dlg.m_fScavengingEnabled != GetDefaultScavengingState())
{
DWORD dwScavengingState = DNS_AGING_OFF;
if (dlg.m_fScavengingEnabled)
{
dwScavengingState = DNS_AGING_DS_ZONES;
}
dwErr = ResetDefaultScavengingState(dwScavengingState);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
BOOL bApplyAll = dlg.m_bADApplyAll;
if (bApplyAll)
{
DWORD dwContextFlags = ZONE_REQUEST_PRIMARY;
dwContextFlags = dlg.m_bADApplyAll ? dwContextFlags | ZONE_REQUEST_DS : dwContextFlags;
if (dlg.m_bNoRefreshDirty)
{
dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
DNS_ZONE_ALL,
dwContextFlags,
DNS_REGKEY_ZONE_NOREFRESH_INTERVAL,
dlg.m_dwNoRefreshInterval);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
if (dlg.m_bRefreshDirty)
{
dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
DNS_ZONE_ALL,
dwContextFlags,
DNS_REGKEY_ZONE_REFRESH_INTERVAL,
dlg.m_dwRefreshInterval);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
if (dlg.m_bScavengeDirty)
{
dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
DNS_ZONE_ALL,
dwContextFlags,
DNS_REGKEY_ZONE_AGING,
dlg.m_fScavengingEnabled);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
return;
}
}
}
}
void CDNSServerNode::ScavengeRecords()
{
UINT nRet = DNSConfirmOperation(IDS_MSG_SERVER_CONFIRM_SCAVENGE, this);
if(IDCANCEL == nRet ||
IDNO == nRet)
{
return;
}
DNS_STATUS dwErr = ::DnssrvOperation(GetRPCName(),
NULL,
DNSSRV_OP_START_SCAVENGING,
DNSSRV_TYPEID_NULL,
NULL);
if (dwErr != 0)
{
DNSErrorDialog(dwErr, IDS_MSG_ERROR_SCAVENGE_RECORDS);
return;
}
}
int CDNSServerNode::GetImageIndex(BOOL)
{
BOOL bSuccess = m_testResultList.LastQuerySuceeded();
int nIndex = 0;
switch (m_nState)
{
case notLoaded:
nIndex = bSuccess ? SERVER_IMAGE_NOT_LOADED : SERVER_IMAGE_NOT_LOADED_TEST_FAIL;
break;
case loading:
nIndex = bSuccess ? SERVER_IMAGE_LOADING : SERVER_IMAGE_LOADING_TEST_FAIL;
break;
case loaded:
nIndex = bSuccess ? SERVER_IMAGE_LOADED : SERVER_IMAGE_LOADED_TEST_FAIL;
break;
case unableToLoad:
nIndex = bSuccess ? SERVER_IMAGE_UNABLE_TO_LOAD : SERVER_IMAGE_UNABLE_TO_LOAD_TEST_FAIL;
break;
case accessDenied:
nIndex = bSuccess ? SERVER_IMAGE_ACCESS_DENIED : SERVER_IMAGE_ACCESS_DENIED_TEST_FAIL;
break;
default:
ASSERT(FALSE);
}
return nIndex;
}
void CDNSServerNode::OnDelete(CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return;
}
UINT nRet = DNSConfirmOperation(IDS_MSG_SERVER_DELETE, this);
if (IDCANCEL == nRet ||
IDNO == nRet)
{
return;
}
if (IsSheetLocked())
{
if (!CanCloseSheets())
return;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
ASSERT(!IsSheetLocked());
// now remove from the UI and from the cache
DeleteHelper(pComponentData);
CDNSRootData* pSnapinData = (CDNSRootData*)GetRootContainer();
pSnapinData->SetDirtyFlag(TRUE);
pSnapinData->RemoveServerFromThreadList(this, pComponentData);
pComponentData->UpdateResultPaneView(GetContainer());
delete this; // gone
}
#define MAX_COMPUTER_DISPLAYNAME_LENGTH 256
HRESULT CDNSServerNode::CreateFromStream(IStream* pStm, CDNSServerNode** ppServerNode)
{
WCHAR szBuffer[MAX_COMPUTER_DISPLAYNAME_LENGTH];
ULONG nLen; // WCHAR counting NULL
ULONG cbRead;
VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
ASSERT(cbRead == sizeof(UINT));
VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
ASSERT(cbRead == sizeof(WCHAR)*nLen);
BOOL bIsLocalHost = (_wcsicmp(szBuffer, L"localhost.") == 0);
if (bIsLocalHost)
{
//
// Retrieve the local computer name
//
DWORD dwLen = MAX_COMPUTER_DISPLAYNAME_LENGTH;
BOOL bRes = ::GetComputerName(szBuffer, &dwLen);
ASSERT(bRes);
}
*ppServerNode = new CDNSServerNode(szBuffer, bIsLocalHost);
ASSERT(*ppServerNode != NULL);
VERIFY(SUCCEEDED((*ppServerNode)->m_testOptions.Load(pStm)));
return S_OK;
}
HRESULT CDNSServerNode::SaveToStream(IStream* pStm)
{
// for each server name, write # of chars+NULL, and then the name
ULONG cbWrite = 0;
ULONG nLen = 0;
static PCWSTR pszLocalHost = L"localhost.";
if (IsLocalServer())
{
nLen = static_cast<ULONG>(wcslen(pszLocalHost) + 1);
VERIFY(SUCCEEDED(pStm->Write((void*)&nLen, sizeof(UINT),&cbWrite)));
ASSERT(cbWrite == sizeof(UINT));
VERIFY(SUCCEEDED(pStm->Write((void*)(pszLocalHost), sizeof(WCHAR)*nLen,&cbWrite)));
ASSERT(cbWrite == sizeof(WCHAR)*nLen);
}
else
{
nLen = static_cast<ULONG>(wcslen(GetDisplayName())+1); // WCHAR including NULL
VERIFY(SUCCEEDED(pStm->Write((void*)&nLen, sizeof(UINT),&cbWrite)));
ASSERT(cbWrite == sizeof(UINT));
VERIFY(SUCCEEDED(pStm->Write((void*)(GetDisplayName()), sizeof(WCHAR)*nLen,&cbWrite)));
ASSERT(cbWrite == sizeof(WCHAR)*nLen);
}
VERIFY(SUCCEEDED(m_testOptions.Save(pStm)));
return S_OK;
}
HRESULT CDNSServerNode::OnNewZone(CComponentDataObject* pComponentData, CNodeList*)
{
ASSERT(pComponentData != NULL);
ASSERT(pComponentData != NULL);
CDNSZoneWizardHolder holder(pComponentData);
holder.Initialize(this);
holder.DoModalWizard();
return S_OK;
}
void CDNSServerNode::OnUpdateDataFiles(CComponentDataObject* pComponentData)
{
// if there are sheets up, ask to close them down, because a
// failure would "Red X" the server and remove all the children
if (IsSheetLocked())
{
if (!CanCloseSheets())
return;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
OnChangeState(pComponentData); // move to loading
m_dwErr = WriteDirtyZones();
// if there is a failure, remove all children,
// will need a refresh to get them back
if (m_dwErr != 0)
{
RemoveAllChildrenHelper(pComponentData);
ASSERT(!HasChildren());
}
OnChangeState(pComponentData); // move to loaded or unableToLoad
}
void CDNSServerNode::OnClearCache(CComponentDataObject* pComponentData)
{
// if there is a cache folder and it is not hidden, delegate to it
if ((m_pCacheFolderNode != NULL) && ((m_pCacheFolderNode->GetFlags() & TN_FLAG_HIDDEN) == 0))
{
m_pCacheFolderNode->OnClearCache(pComponentData);
return;
}
// directly call into the server
DNS_STATUS err;
{ // scope for wait cursor
CWaitCursor wait;
err = ClearCache();
}
if (err != 0)
{
// need to let the user know the operation failed
DNSErrorDialog(err, IDS_MSG_SERVER_FAIL_CLEAR_CACHE);
return;
}
if (m_pCacheFolderNode != NULL)
{
ASSERT(m_pCacheFolderNode->GetFlags() & TN_FLAG_HIDDEN);
// the cache folder is there, but hidden, so we just have
// to call the API and remove its children
m_pCacheFolderNode->RemoveAllChildrenFromList();
}
}
BOOL CDNSServerNode::HasPropertyPages(DATA_OBJECT_TYPES,
BOOL* pbHideVerb,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return FALSE;
}
*pbHideVerb = FALSE; // always show the verb
// cannot have property pages when in loading, notLoaded, or the thread lock state
return (!IsThreadLocked() && (m_nState != notLoaded) && (m_nState != loading));
}
HRESULT CDNSServerNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
CNodeList* pNodeList)
{
CWaitCursor wait;
ASSERT(pNodeList->GetCount() == 1); // multi-select not support
ASSERT(m_nState != loading);
CComponentDataObject* pComponentDataObject =
((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
ASSERT(pComponentDataObject != NULL);
//
// Refresh the domain forwarders node under the server so that it has current data,
// but do it manually since we have to enumerate synchronously
//
CDNSDomainForwardersNode* pDomainForwardersNode = GetDomainForwardersNode();
if (pDomainForwardersNode != NULL)
{
pDomainForwardersNode->RemoveAllChildrenHelper(pComponentDataObject);
pDomainForwardersNode->OnEnumerate(pComponentDataObject, FALSE);
}
if (m_pServInfoEx != NULL)
{
VERIFY(m_pServInfoEx->Query(GetRPCName()) == 0);
}
CDNSServerPropertyPageHolder* pHolder =
new CDNSServerPropertyPageHolder((CDNSRootData*)GetContainer(), this, pComponentDataObject);
ASSERT(pHolder != NULL);
pHolder->SetStartPageCode(m_nStartProppage);
pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this);
return pHolder->CreateModelessSheet(lpProvider, handle);
}
void CDNSServerNode::DecrementSheetLockCount()
{
CTreeNode::DecrementSheetLockCount();
m_nStartProppage = -1;
}
BOOL CDNSServerQueryObj::Enumerate()
{
// query the server to find out if it has a cache
BOOL bHasRootZone = FALSE;
DNS_STATUS err = ::ServerHasRootZone(m_szServerName, &bHasRootZone);
if (err != 0)
{
OnError(err);
return FALSE; // failed to get answer
}
CDNSRootHintsNode* pRootHintsNode = NULL;
// if there is not a root zone, the server is not authoritated for the root
// so create the root hints folder and ask it to query for NS and A records
if (!bHasRootZone)
{
pRootHintsNode = new CDNSRootHintsNode;
err = pRootHintsNode->QueryForRootHints(m_szServerName, m_dwServerVersion);
if (err != 0)
{
//
// NOTE: permissions are different for the Root Hints so we will
// fail this silently
//
// OnError(err);
delete pRootHintsNode;
pRootHintsNode = NULL;
// return FALSE; // failed in the query, exit without putting folders
}
}
// get server info
CDNSServerInfoEx* pServerInfoEx = new CDNSServerInfoEx;
err = pServerInfoEx->Query(m_szServerName);
if (err != 0)
{
OnError(err);
delete pServerInfoEx;
pServerInfoEx = NULL;
if (pRootHintsNode != NULL)
{
delete pRootHintsNode;
pRootHintsNode = NULL;
}
return FALSE; // stop if could not get server info
}
// all went well, finally send data
VERIFY(AddQueryResult(pServerInfoEx)); // server info data
if (!bHasRootZone)
{
ASSERT(pRootHintsNode != NULL);
VERIFY(AddQueryResult(pRootHintsNode));
}
//
// create cache data folder
//
VERIFY(AddQueryResult(new CDNSCacheNode));
//
// create the fwd/rev lookup zones folders
//
VERIFY(AddQueryResult(new CDNSForwardZonesNode));
VERIFY(AddQueryResult(new CDNSReverseZonesNode));
//
// Always add the domain forwarders folder here so that it can be enumerated immediately
//
VERIFY(AddQueryResult(new CDNSDomainForwardersNode));
return FALSE; // end thread
}
HRESULT CDNSServerNode::GetResultViewType(CComponentDataObject*,
LPOLESTR *ppViewType,
long *pViewOptions)
{
HRESULT hr = S_FALSE;
if ((!IsServerConfigured() ||
m_nState == accessDenied ||
m_nState == unableToLoad ||
!m_testResultList.LastQuerySuceeded()) &&
m_bShowMessages)
{
*pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
LPOLESTR psz = NULL;
StringFromCLSID(CLSID_MessageView, &psz);
USES_CONVERSION;
if (psz != NULL)
{
*ppViewType = psz;
hr = S_OK;
}
}
else
{
*pViewOptions = MMC_VIEW_OPTIONS_NONE;
*ppViewType = NULL;
hr = S_FALSE;
}
return hr;
}
HRESULT CDNSServerNode::OnShow(LPCONSOLE lpConsole)
{
CComPtr<IUnknown> spUnknown;
CComPtr<IMessageView> spMessageView;
HRESULT hr = lpConsole->QueryResultView(&spUnknown);
if (FAILED(hr))
return S_OK;
hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
if (SUCCEEDED(hr))
{
CString szTitle, szMessage;
IconIdentifier iconID;
if (!IsServerConfigured())
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_CONFIG_SERVER_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_CONFIG_SERVER_MESSAGE));
iconID = Icon_Information;
}
else if (m_testResultList.LastQuerySuceeded())
{
if (m_nState == accessDenied)
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
iconID = Icon_Error;
}
else // Unable to load and other unknown errors
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
iconID = Icon_Error;
}
}
else
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_QUERY_FAILED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_QUERY_FAILED_MESSAGE));
iconID = Icon_Error;
}
spMessageView->SetTitleText(szTitle);
spMessageView->SetBodyText(szMessage);
spMessageView->SetIcon(iconID);
}
return S_OK;
}
CQueryObj* CDNSServerNode::OnCreateQuery()
{
CDNSRootData* pRootData = (CDNSRootData*)GetRootContainer();
ASSERT(pRootData != NULL);
CDNSServerQueryObj* pQuery =
new CDNSServerQueryObj(pRootData->IsAdvancedView(), 0x0 /*version not known yet*/);
pQuery->m_szServerName = m_szDisplayName;
return pQuery;
}
BOOL CDNSServerNode::OnRefresh(CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
BOOL bRet = TRUE;
POSITION pos = pNodeList->GetHeadPosition();
while (pos != NULL)
{
CTreeNode* pNode = pNodeList->GetNext(pos);
ASSERT(pNode != NULL);
CNodeList nodeList;
nodeList.AddTail(pNode);
if (!pNode->OnRefresh(pComponentData, &nodeList))
{
bRet = FALSE;
}
}
return bRet;
}
//
// Single selections
//
if (CMTContainerNode::OnRefresh(pComponentData, pNodeList))
{
m_pCacheFolderNode = NULL;
m_pFwdZonesFolderNode = NULL;
m_pRevZonesFolderNode = NULL;
m_pDomainForwardersFolderNode = NULL;
FreeRootHints();
FreeServInfo();
return TRUE;
}
return FALSE;
}
void CDNSServerNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
{
// the first message coming should be server info struct, not kept in the list of children
if (IS_CLASS(*pObj, CDNSServerInfoEx))
{
AttachServerInfo(dynamic_cast<CDNSServerInfoEx*>(pObj));
return;
}
// the root hints node is special and not kept in the list of children
if (IS_CLASS(*pObj, CDNSRootHintsNode))
{
CDNSRootHintsNode* pNewRootHints = dynamic_cast<CDNSRootHintsNode*>(pObj);
if (pNewRootHints != NULL)
{
AttachRootHints(pNewRootHints);
}
ASSERT(m_pRootHintsNode != NULL);
return;
}
// set cached pointers for fdw/rev zones folders
if (IS_CLASS(*pObj, CDNSForwardZonesNode))
{
ASSERT(m_pFwdZonesFolderNode == NULL);
m_pFwdZonesFolderNode = dynamic_cast<CDNSForwardZonesNode*>(pObj);
ASSERT(m_pFwdZonesFolderNode != NULL);
}
else if (IS_CLASS(*pObj, CDNSReverseZonesNode))
{
ASSERT(m_pRevZonesFolderNode == NULL);
m_pRevZonesFolderNode = dynamic_cast<CDNSReverseZonesNode*>(pObj);
ASSERT(m_pRevZonesFolderNode != NULL);
}
else if (IS_CLASS(*pObj, CDNSCacheNode))
{
//
// the cache folder node can be shown or not, depending on the view options
//
ASSERT(m_pCacheFolderNode == NULL);
m_pCacheFolderNode = dynamic_cast<CDNSCacheNode*>(pObj);
ASSERT(m_pCacheFolderNode != NULL);
CDNSRootData* pRootData = (CDNSRootData*)pComponentDataObject->GetRootData();
if (!pRootData->IsAdvancedView())
{
m_pCacheFolderNode->SetFlagsDown(TN_FLAG_HIDDEN,TRUE); // mark it hidden, will not be added to UI
}
}
else if (IS_CLASS(*pObj, CDNSDomainForwardersNode))
{
//
// The domain forwarders node should never be shown
//
ASSERT(m_pDomainForwardersFolderNode == NULL);
m_pDomainForwardersFolderNode = dynamic_cast<CDNSDomainForwardersNode*>(pObj);
ASSERT(m_pDomainForwardersFolderNode != NULL);
//
// Make sure its hidden in the UI
//
m_pDomainForwardersFolderNode->SetFlagsDown(TN_FLAG_HIDDEN, TRUE);
}
CDNSMTContainerNode::OnHaveData(pObj,pComponentDataObject);
}
BOOL CDNSServerNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long*)
{
// gray out commands that need data from the server
if ((m_nState != loaded) && ( (pContextMenuItem2->lCommandID == IDM_SERVER_NEW_ZONE) ||
(pContextMenuItem2->lCommandID == IDM_SERVER_UPDATE_DATA_FILES) ||
(pContextMenuItem2->lCommandID == IDM_SERVER_CLEAR_CACHE) ||
(pContextMenuItem2->lCommandID == IDM_SERVER_SET_AGING) ||
(pContextMenuItem2->lCommandID == IDM_SERVER_SCAVENGE)
#ifdef USE_NDNC
||(pContextMenuItem2->lCommandID == IDM_SERVER_CREATE_NDNC)
#endif
) )
{
pContextMenuItem2->fFlags |= MF_GRAYED;
}
if ((pContextMenuItem2->lCommandID == IDM_SERVER_CONFIGURE) && IsServerConfigured())
{
return FALSE;
}
#ifdef USE_NDNC
if ((pContextMenuItem2->lCommandID == IDM_SERVER_CREATE_NDNC) &&
(m_nState != loaded ||
GetBuildNumber() < DNS_SRV_BUILD_NUMBER_WHISTLER ||
(GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_5 &&
GetMinorVersion() < DNS_SRV_MINOR_VERSION_WHISTLER) ||
ContainsDefaultNDNCs()))
{
return FALSE;
}
#endif
// this command might cause a refresh
if ( IsThreadLocked() && (pContextMenuItem2->lCommandID == IDM_SERVER_CLEAR_CACHE))
{
pContextMenuItem2->fFlags |= MF_GRAYED;
}
// add toggle menu item for advanced view
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
{
pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
return TRUE;
}
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
{
if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
{
pContextMenuItem2->fFlags = MF_CHECKED;
}
return TRUE;
}
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_MESSAGE)
{
if (m_bShowMessages)
{
pContextMenuItem2->fFlags = MF_CHECKED;
}
}
return TRUE;
}
BOOL CDNSServerNode::OnSetDeleteVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
*pbHide = TRUE;
return FALSE;
}
if (((CDNSRootData*)GetRootContainer())->GetComponentDataObject()->IsExtensionSnapin())
{
// for extensions, remove the delete verb
*pbHide = TRUE;
return FALSE; // disable
}
*pbHide = FALSE;
TRACE(_T("CDNSServerNode::OnSetDeleteVerbState() IsThreadLocked() == %d\n"),
IsThreadLocked());
return !IsThreadLocked();
}
BOOL CDNSServerNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList*)
{
*pbHide = FALSE;
return !IsThreadLocked();
}
CDNSZoneNode* CDNSServerNode::GetNewZoneNode()
{
CDNSZoneNode* pZoneNode = new CDNSZoneNode();
ASSERT(pZoneNode != NULL);
pZoneNode->SetServerNode(this);
return pZoneNode;
}
#ifdef USE_NDNC
DNS_STATUS CDNSServerNode::CreatePrimaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
BOOL bLoadExisting,
BOOL bFwd,
BOOL bDSIntegrated,
UINT nDynamicUpdate,
CComponentDataObject* pComponentData,
ReplicationType replType,
PCWSTR pszPartitionName)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
lpszName, lpszName);
DNS_STATUS err = 0;
if (bDSIntegrated && !(replType == none || replType == w2k))
{
err = pZoneNode->CreatePrimaryInDirectoryPartition(bLoadExisting,
nDynamicUpdate,
replType,
pszPartitionName);
}
else
{
err = pZoneNode->CreatePrimary(lpszFileName, bLoadExisting, bDSIntegrated, nDynamicUpdate);
}
if (err != 0)
{
// fail
delete pZoneNode;
return err;
}
// succeeded, need to add to the UI, if possible
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
return err;
}
#else
DNS_STATUS CDNSServerNode::CreatePrimaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
BOOL bLoadExisting,
BOOL bFwd,
BOOL bDSIntegrated,
UINT nDynamicUpdate,
CComponentDataObject* pComponentData)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
lpszName, lpszName);
DNS_STATUS err = pZoneNode->CreatePrimary(lpszFileName, bLoadExisting, bDSIntegrated, nDynamicUpdate);
if (err != 0)
{
// fail
delete pZoneNode;
return err;
}
// succeeded, need to add to the UI, if possible
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
return err;
}
#endif //USE_NDNC
DNS_STATUS CDNSServerNode::CreateSecondaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
BOOL bLoadExisting, BOOL bFwd,
DWORD* ipMastersArray, int nIPMastersCount, CComponentDataObject* pComponentData)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
lpszName, lpszName);
DNS_STATUS err = pZoneNode->CreateSecondary(ipMastersArray, nIPMastersCount,
lpszFileName, bLoadExisting);
if (err != 0)
{
// fail
delete pZoneNode;
return err;
}
// succeeded, need to add to the UI, if possible
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
return err;
}
#ifdef USE_NDNC
DNS_STATUS CDNSServerNode::CreateStubZone(LPCTSTR lpszName,
LPCTSTR lpszFileName,
BOOL bLoadExisting,
BOOL bDSIntegrated,
BOOL bFwd,
DWORD* ipMastersArray,
int nIPMastersCount,
BOOL bLocalListOfMasters,
CComponentDataObject* pComponentData,
ReplicationType replType,
PCWSTR pszPartitionName)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
lpszName, lpszName);
USES_CONVERSION;
DNS_STATUS err = 0;
if (bDSIntegrated && !(replType == none || replType == w2k))
{
err = pZoneNode->CreateStubInDirectoryPartition(ipMastersArray,
nIPMastersCount,
bLoadExisting,
replType,
pszPartitionName);
}
else
{
err = pZoneNode->CreateStub(ipMastersArray,
nIPMastersCount,
lpszFileName,
bLoadExisting,
bDSIntegrated);
}
if (err != 0)
{
// fail
delete pZoneNode;
return err;
}
// succeeded, need to add to the UI, if possible
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
//
// Change to the local list of masters after the zone has been created
//
if (bLocalListOfMasters)
{
err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
nIPMastersCount,
ipMastersArray,
TRUE); // LocalListOfMasters
if (err != 0)
return err;
}
else
{
/*
err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
0,
NULL,
TRUE); // LocalListOfMasters
if (err != 0)
return err;
*/
}
return err;
}
#else
DNS_STATUS CDNSServerNode::CreateStubZone(LPCTSTR lpszName,
LPCTSTR lpszFileName,
BOOL bLoadExisting,
BOOL bDSIntegrated,
BOOL bFwd,
DWORD* ipMastersArray,
int nIPMastersCount,
BOOL bLocalListOfMasters,
CComponentDataObject* pComponentData)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
lpszName, lpszName);
USES_CONVERSION;
DNS_STATUS err = pZoneNode->CreateStub(ipMastersArray,
nIPMastersCount,
lpszFileName,
bLoadExisting,
bDSIntegrated);
if (err != 0)
{
// fail
delete pZoneNode;
return err;
}
// succeeded, need to add to the UI, if possible
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
//
// Change to the local list of masters after the zone has been created
//
if (bLocalListOfMasters)
{
err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
nIPMastersCount,
ipMastersArray,
TRUE); // LocalListOfMasters
if (err != 0)
return err;
}
else
{
/*
err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
0,
NULL,
TRUE); // LocalListOfMasters
if (err != 0)
return err;
*/
}
return err;
}
#endif // USE_NDNC
DNS_STATUS CDNSServerNode::CreateForwarderZone(LPCTSTR lpszName,
DWORD* ipMastersArray,
int nIPMastersCount,
DWORD dwTimeout,
DWORD fSlave,
CComponentDataObject* pComponentData)
{
CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
ASSERT(pRootData != NULL);
CDNSZoneNode* pZoneNode = GetNewZoneNode();
pZoneNode->SetNames(TRUE /* isZone*/,
TRUE,
pRootData->IsAdvancedView(),
lpszName,
lpszName);
DNS_STATUS err = pZoneNode->CreateForwarder(ipMastersArray,
nIPMastersCount,
dwTimeout,
fSlave);
if (err != 0)
{
//
// fail
//
delete pZoneNode;
return err;
}
//
// succeeded, need to add to the UI, if possible
//
if (IsExpanded())
{
CCathegoryFolderNode* pCathegoryFolder = GetDomainForwardersNode();
if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
{
VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
pComponentData->SetDescriptionBarText(pCathegoryFolder);
}
else
{
delete pZoneNode; // the enumeration will add it
}
}
else
{
delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
}
return err;
}
DNS_STATUS CDNSServerNode::WriteDirtyZones()
{
USES_CONVERSION;
return ::DnssrvWriteDirtyZones(GetServerNode()->GetRPCName());
}
BOOL CDNSServerNode::CanUseADS()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_4)
return FALSE;
return m_pServInfoEx->m_pServInfo->fDsAvailable;
}
DWORD CDNSServerNode::GetVersion()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
return m_pServInfoEx->m_pServInfo->dwVersion;
}
return (DWORD)-1;
}
void _CopyStringAndFree(CString& sz, LPWSTR lpsz)
{
sz = lpsz;
if (lpsz)
::DnssrvFreeRpcBuffer((PDNS_RPC_BUFFER)lpsz);
}
void _LdapPathFromX500(CString& szLdap, PDNS_RPC_SERVER_INFO pInfo, LPCWSTR lpszX500Name)
{
ASSERT(pInfo != NULL);
ASSERT(pInfo->pszServerName != NULL);
USES_CONVERSION;
LPCWSTR lpszServerName = UTF8_TO_W(pInfo->pszServerName);
szLdap.Format(L"LDAP://%s/%s", lpszServerName, lpszX500Name);
}
void CDNSServerNode::CreateDsServerLdapPath(CString& sz)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
CString szX500;
_CopyStringAndFree(szX500,::DnssrvCreateDsServerName(m_pServInfoEx->m_pServInfo));
CreateLdapPathFromX500Name(szX500, sz);
}
else
sz.Empty();
}
void CDNSServerNode::CreateDsZoneLdapPath(CDNSZoneNode* pZoneNode, CString& sz)
{
PCWSTR pszDN = pZoneNode->GetDN();
if (!pszDN)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
CString szX500;
_CopyStringAndFree(szX500, ::DnssrvCreateDsZoneName(m_pServInfoEx->m_pServInfo,
(LPWSTR)pZoneNode->GetFullName()));
CreateLdapPathFromX500Name( szX500, sz);
}
else
{
sz.Empty();
}
}
else
{
CreateLdapPathFromX500Name(pszDN, sz);
}
}
void CDNSServerNode::CreateDsZoneName(CDNSZoneNode* pZoneNode, CString& sz)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
_CopyStringAndFree(sz, ::DnssrvCreateDsZoneName(m_pServInfoEx->m_pServInfo,
(LPWSTR)pZoneNode->GetFullName()));
}
else
sz.Empty();
}
void CDNSServerNode::CreateDsNodeLdapPath(CDNSZoneNode* pZoneNode, CDNSDomainNode* pDomainNode, CString& sz)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
// need to get the relative path of the node wrt the zone
size_t nZoneLen = wcslen(pZoneNode->GetFullName());
size_t nDomainLen = wcslen(pDomainNode->GetFullName());
size_t nRelativeNameLen = nDomainLen - nZoneLen - 1; // remove a dot
CString szRelativeName(pDomainNode->GetFullName(), static_cast<int>(nRelativeNameLen));
CString szX500;
_CopyStringAndFree(szX500, ::DnssrvCreateDsNodeName(m_pServInfoEx->m_pServInfo,
(LPWSTR)pZoneNode->GetFullName(),
(LPWSTR)(LPCWSTR)szRelativeName));
CreateLdapPathFromX500Name(szX500, sz);
}
else
sz.Empty();
}
void CDNSServerNode::CreateLdapPathFromX500Name(LPCWSTR lpszX500Name, CString& szLdapPath)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
if (m_pServInfoEx->m_pServInfo != NULL)
{
_LdapPathFromX500(szLdapPath, m_pServInfoEx->m_pServInfo, lpszX500Name);
}
else
szLdapPath.Empty();
}
BOOL CDNSServerNode::DoesRecursion()
{
if (m_pServInfoEx == NULL || m_pServInfoEx->m_pServInfo == NULL)
{
ASSERT(FALSE);
return TRUE;
}
return !m_pServInfoEx->m_pServInfo->fNoRecursion;
}
void CDNSServerNode::GetAdvancedOptions(BOOL* bOptionsArray)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
bOptionsArray[SERVER_REGKEY_ARR_INDEX_NO_RECURSION] = m_pServInfoEx->m_pServInfo->fNoRecursion;
bOptionsArray[SERVER_REGKEY_ARR_INDEX_BIND_SECONDARIES] = m_pServInfoEx->m_pServInfo->fBindSecondaries;
bOptionsArray[SERVER_REGKEY_ARR_INDEX_STRICT_FILE_PARSING] = m_pServInfoEx->m_pServInfo->fStrictFileParsing;
bOptionsArray[SERVER_REGKEY_ARR_INDEX_ROUND_ROBIN] = m_pServInfoEx->m_pServInfo->fRoundRobin;
bOptionsArray[SERVER_REGKEY_ARR_LOCAL_NET_PRIORITY] = m_pServInfoEx->m_pServInfo->fLocalNetPriority;
bOptionsArray[SERVER_REGKEY_ARR_CACHE_POLLUTION] = m_pServInfoEx->m_pServInfo->fSecureResponses;
}
DNS_STATUS CDNSServerNode::ResetAdvancedOptions(BOOL* bOptionsArray, DNS_STATUS* dwRegKeyOptionsErrorArr)
{
ASSERT(m_pServInfoEx != NULL);
DNS_STATUS err = 0;
BOOL bChanged = FALSE;
ZeroMemory(dwRegKeyOptionsErrorArr, sizeof(DNS_STATUS )*SERVER_REGKEY_ARR_SIZE);
for (UINT iKey=0; iKey < SERVER_REGKEY_ARR_SIZE; iKey++)
{
BOOL bDirty = FALSE;
switch (iKey)
{
case SERVER_REGKEY_ARR_INDEX_NO_RECURSION:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fNoRecursion);
break;
case SERVER_REGKEY_ARR_INDEX_BIND_SECONDARIES:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fBindSecondaries);
break;
case SERVER_REGKEY_ARR_INDEX_STRICT_FILE_PARSING:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fStrictFileParsing);
break;
case SERVER_REGKEY_ARR_INDEX_ROUND_ROBIN:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fRoundRobin);
break;
case SERVER_REGKEY_ARR_LOCAL_NET_PRIORITY:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fLocalNetPriority);
break;
case SERVER_REGKEY_ARR_CACHE_POLLUTION:
bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fSecureResponses);
break;
default:
ASSERT(FALSE);
}
if (bDirty)
{
dwRegKeyOptionsErrorArr[iKey] = ::DnssrvResetDwordProperty(
GetServerNode()->GetRPCName(), // server name
NULL,
_DnsServerRegkeyStringArr[iKey],
bOptionsArray[iKey]);
if (dwRegKeyOptionsErrorArr[iKey] == 0)
bChanged = TRUE;
}
}
if (bChanged)
err = GetServInfo(); // update the info
return err;
}
UCHAR CDNSServerNode::GetBootMethod()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->fBootMethod;
}
DNS_STATUS CDNSServerNode::ResetBootMethod(UCHAR fBootMethod)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if(fBootMethod != m_pServInfoEx->m_pServInfo->fBootMethod)
{
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_BOOT_METHOD,
fBootMethod);
if (err != 0)
return err;
// all fine, update the info
err = GetServInfo();
}
return err;
}
BOOL CDNSServerNode::ContainsDefaultNDNCs()
{
//
// Enumerate the available directory partitions
//
BOOL result = FALSE;
PDNS_RPC_DP_LIST pDirectoryPartitions = NULL;
DWORD dwErr = ::DnssrvEnumDirectoryPartitions(GetRPCName(),
DNS_DP_ENLISTED,
&pDirectoryPartitions);
//
// Don't show an error if we are not able to get the available directory partitions
// We can still continue on and the user can type in the directory partition they need
//
if (dwErr == 0 && pDirectoryPartitions)
{
for (DWORD dwIdx = 0; dwIdx < pDirectoryPartitions->dwDpCount; dwIdx++)
{
PDNS_RPC_DP_INFO pDirectoryPartition = 0;
dwErr = ::DnssrvDirectoryPartitionInfo(GetRPCName(),
pDirectoryPartitions->DpArray[dwIdx]->pszDpFqdn,
&pDirectoryPartition);
if (dwErr == 0 &&
pDirectoryPartition)
{
//
// Check to see if it was an autocreated partition
//
if (pDirectoryPartition->dwFlags & DNS_DP_AUTOCREATED)
{
result = TRUE;
::DnssrvFreeDirectoryPartitionInfo(pDirectoryPartition);
break;
}
::DnssrvFreeDirectoryPartitionInfo(pDirectoryPartition);
}
}
::DnssrvFreeDirectoryPartitionList(pDirectoryPartitions);
}
return result;
}
BOOL CDNSServerNode::IsServerConfigured()
{
ASSERT(m_pServInfoEx != NULL);
if (m_pServInfoEx != NULL && m_pServInfoEx->m_pServInfo != NULL)
{
return m_pServInfoEx->m_pServInfo->fAdminConfigured;
}
return TRUE;
}
DNS_STATUS CDNSServerNode::SetServerConfigured()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if (TRUE != m_pServInfoEx->m_pServInfo->fAdminConfigured)
{
err = ::DnssrvResetDwordProperty(GetRPCName(),
NULL,
DNS_REGKEY_ADMIN_CONFIGURED,
TRUE);
if (err != 0)
return err;
err = GetServInfo();
}
return err;
}
BOOL CDNSServerNode::GetScavengingState()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwScavengingInterval > 0;
}
DWORD CDNSServerNode::GetScavengingInterval()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwScavengingInterval;
}
DNS_STATUS CDNSServerNode::ResetScavengingInterval(DWORD dwScavengingInterval)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if (dwScavengingInterval != m_pServInfoEx->m_pServInfo->dwScavengingInterval)
{
DNS_RPC_NAME_AND_PARAM param;
param.dwParam = dwScavengingInterval;
param.pszNodeName = DNS_REGKEY_SCAVENGING_INTERVAL;
err = ::DnssrvOperation(
GetRPCName(),
NULL,
DNSSRV_OP_RESET_DWORD_PROPERTY,
DNSSRV_TYPEID_NAME_AND_PARAM,
& param
);
if (err != 0)
return err;
err = GetServInfo();
}
return err;
}
DWORD CDNSServerNode::GetDefaultRefreshInterval()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwDefaultRefreshInterval;
}
DNS_STATUS CDNSServerNode::ResetDefaultRefreshInterval(DWORD dwRefreshInterval)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if (dwRefreshInterval != m_pServInfoEx->m_pServInfo->dwDefaultRefreshInterval)
{
DNS_RPC_NAME_AND_PARAM param;
param.dwParam = dwRefreshInterval;
param.pszNodeName = DNS_REGKEY_DEFAULT_REFRESH_INTERVAL;
err = ::DnssrvOperation(
GetRPCName(),
NULL,
DNSSRV_OP_RESET_DWORD_PROPERTY,
DNSSRV_TYPEID_NAME_AND_PARAM,
& param
);
if (err != 0)
return err;
err = GetServInfo();
}
return err;
}
DWORD CDNSServerNode::GetDefaultNoRefreshInterval()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwDefaultNoRefreshInterval;
}
DNS_STATUS CDNSServerNode::ResetDefaultNoRefreshInterval(DWORD dwNoRefreshInterval)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if (dwNoRefreshInterval != m_pServInfoEx->m_pServInfo->dwDefaultNoRefreshInterval)
{
DNS_RPC_NAME_AND_PARAM param;
param.dwParam = dwNoRefreshInterval;
param.pszNodeName = DNS_REGKEY_DEFAULT_NOREFRESH_INTERVAL;
err = ::DnssrvOperation(
GetRPCName(),
NULL,
DNSSRV_OP_RESET_DWORD_PROPERTY,
DNSSRV_TYPEID_NAME_AND_PARAM,
& param
);
if (err != 0)
return err;
err = GetServInfo();
}
return err;
}
#ifdef USE_NDNC
PCSTR CDNSServerNode::GetDomainName()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo);
return m_pServInfoEx->m_pServInfo->pszDomainName;
}
PCSTR CDNSServerNode::GetForestName()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo);
return m_pServInfoEx->m_pServInfo->pszForestName;
}
#endif
DWORD CDNSServerNode::GetDefaultScavengingState()
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->fDefaultAgingState;
}
DNS_STATUS CDNSServerNode::ResetDefaultScavengingState(DWORD dwScavengingState)
{
ASSERT(m_pServInfoEx != NULL);
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DWORD err = 0;
if (dwScavengingState != m_pServInfoEx->m_pServInfo->fDefaultAgingState)
{
DNS_RPC_NAME_AND_PARAM param;
param.dwParam = dwScavengingState;
param.pszNodeName = DNS_REGKEY_DEFAULT_AGING_STATE;
err = ::DnssrvOperation(
GetRPCName(),
NULL,
DNSSRV_OP_RESET_DWORD_PROPERTY,
DNSSRV_TYPEID_NAME_AND_PARAM,
& param
);
if (err != 0)
return err;
err = GetServInfo();
}
return err;
}
DWORD CDNSServerNode::GetNameCheckFlag()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwNameCheckFlag;
}
DNS_STATUS CDNSServerNode::ResetNameCheckFlag(DWORD dwNameCheckFlag)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DNS_STATUS err = 0;
// call only if the info is dirty
if (m_pServInfoEx->m_pServInfo->dwNameCheckFlag != dwNameCheckFlag)
{
USES_CONVERSION;
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_NAME_CHECK_FLAG,
dwNameCheckFlag);
if (err != 0)
return err;
err = GetServInfo(); // update the info
}
return err;
}
PIP_ARRAY CDNSServerNode::GetDebugLogFilterList()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->aipLogFilter;
}
DNS_STATUS CDNSServerNode::ResetDebugLogFilterList(PIP_ARRAY pIPArray)
{
DNS_STATUS err = 0;
err = ::DnssrvResetIPListProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_LOG_IP_FILTER_LIST,
pIPArray,
0); // dwFlags
if (err != 0)
return err;
err = GetServInfo(); // update the info
return err;
}
PCWSTR CDNSServerNode::GetDebugLogFileName()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->pwszLogFilePath;
}
DNS_STATUS CDNSServerNode::ResetDebugLogFileName(PCWSTR pszLogFileName)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DNS_STATUS err = 0;
if (m_pServInfoEx->m_pServInfo->pwszLogFilePath == NULL ||
_wcsicmp(m_pServInfoEx->m_pServInfo->pwszLogFilePath, pszLogFileName) != 0)
{
err = ::DnssrvResetStringProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_LOG_FILE_PATH,
pszLogFileName,
0); // dwFlags
if (err != 0)
return err;
err = GetServInfo(); // update the info
}
return err;
}
DWORD CDNSServerNode::GetDebugLogFileMaxSize()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwLogFileMaxSize;
}
DNS_STATUS CDNSServerNode::ResetDebugLogFileMaxSize(DWORD dwMaxSize)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DNS_STATUS err = 0;
if (m_pServInfoEx->m_pServInfo->dwLogFileMaxSize != dwMaxSize)
{
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_LOG_FILE_MAX_SIZE,
dwMaxSize);
if (err != 0)
return err;
err = GetServInfo(); // update the info
}
return err;
}
DWORD CDNSServerNode::GetLogLevelFlag()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwLogLevel;
}
DNS_STATUS CDNSServerNode::ResetLogLevelFlag(DWORD dwLogLevel)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DNS_STATUS err = 0;
// call only if the info is dirty
if (m_pServInfoEx->m_pServInfo->dwLogLevel != dwLogLevel)
{
USES_CONVERSION;
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_LOG_LEVEL,
dwLogLevel);
if (err != 0)
return err;
err = GetServInfo(); // update the info
}
return err;
}
DWORD CDNSServerNode::GetEventLogLevelFlag()
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
return m_pServInfoEx->m_pServInfo->dwEventLogLevel;
}
DNS_STATUS CDNSServerNode::ResetEventLogLevelFlag(DWORD dwEventLogLevel)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
DNS_STATUS err = 0;
if (m_pServInfoEx->m_pServInfo->dwEventLogLevel != dwEventLogLevel)
{
USES_CONVERSION;
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
NULL,
DNS_REGKEY_EVENTLOG_LEVEL,
dwEventLogLevel);
if (err != 0)
return err;
err = GetServInfo(); // update the info
}
return err;
}
DNS_STATUS CDNSServerNode::ResetListenAddresses(DWORD cAddrCount, PIP_ADDRESS pipAddrs)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
USES_CONVERSION;
// make the call only if the data is dirty
DNS_STATUS err = 0;
if (!(m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL && cAddrCount == 0) && // if still no addresses, skip
((m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL && cAddrCount > 0) || // no addr --> more than one
(m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrCount != cAddrCount) || // change the # of addresses
(memcmp(pipAddrs, m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrArray, sizeof(IP_ADDRESS)*cAddrCount) != 0)
)
)
{
IP_ADDRESS dummy;
if (pipAddrs == NULL)
{
ASSERT(cAddrCount == 0);
pipAddrs = &dummy; // RPC wants non null ip array
}
err = ::DnssrvResetServerListenAddresses(GetRPCName(), cAddrCount, pipAddrs);
}
if (err != 0)
return err;
return GetServInfo(); // update the info
}
void CDNSServerNode::GetListenAddressesInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
ASSERT(pcAddrCount != NULL);
ASSERT(ppipAddrs != NULL);
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL)
{
*pcAddrCount = 0;
*ppipAddrs = NULL;
}
else
{
*pcAddrCount = m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrCount;
*ppipAddrs = m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrArray;
}
}
void CDNSServerNode::GetServerAddressesInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
{
//
// Validate parameters
//
ASSERT(pcAddrCount != NULL);
ASSERT(ppipAddrs != NULL);
if (pcAddrCount == NULL ||
ppipAddrs == NULL)
{
return;
}
if (!m_pServInfoEx->HasData())
{
DNS_STATUS err = GetServInfo();
if (err != 0)
{
*pcAddrCount = 0;
*ppipAddrs = NULL;
return;
}
}
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pServInfoEx->m_pServInfo->aipServerAddrs == NULL)
{
*pcAddrCount = 0;
*ppipAddrs = NULL;
}
else
{
*pcAddrCount = m_pServInfoEx->m_pServInfo->aipServerAddrs->AddrCount;
*ppipAddrs = m_pServInfoEx->m_pServInfo->aipServerAddrs->AddrArray;
}
}
DNS_STATUS CDNSServerNode::ResetForwarders(DWORD cForwardersCount, PIP_ADDRESS aipForwarders,
DWORD dwForwardTimeout, DWORD fSlave)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
// make the call only if the data is dirty
DNS_STATUS err = 0;
if (m_pServInfoEx->m_pServInfo->aipForwarders == NULL && cForwardersCount == 0)
return err; // there are no addresses
BOOL bDirty = (m_pServInfoEx->m_pServInfo->fSlave != fSlave) || (m_pServInfoEx->m_pServInfo->dwForwardTimeout != dwForwardTimeout) ||
(m_pServInfoEx->m_pServInfo->aipForwarders == NULL && cForwardersCount > 0) || // no addr --> more than one
(m_pServInfoEx->m_pServInfo->aipForwarders != NULL && cForwardersCount == 0) || // some addr --> no addr
(m_pServInfoEx->m_pServInfo->aipForwarders->AddrCount != cForwardersCount) || // change the # of addresses
(memcmp(aipForwarders, m_pServInfoEx->m_pServInfo->aipForwarders->AddrArray, sizeof(IP_ADDRESS)*cForwardersCount) != 0);
if (bDirty)
{
IP_ADDRESS dummy;
if (aipForwarders == NULL)
{
ASSERT(cForwardersCount == 0);
aipForwarders = &dummy; // RPC wants non null ip array
}
USES_CONVERSION;
err = ::DnssrvResetForwarders(GetRPCName(),
cForwardersCount, aipForwarders, dwForwardTimeout, fSlave);
if (err == 0)
err = GetServInfo(); // update the info
}
return err;
}
void CDNSServerNode::GetForwardersInfo(DWORD* pcForwardersCount, PIP_ADDRESS* paipForwarders,
DWORD* pdwForwardTimeout, DWORD* pfSlave)
{
ASSERT(m_pServInfoEx->m_pServInfo != NULL);
// return pointers to struct fields, caller has to copy data elsewhere
*pdwForwardTimeout = m_pServInfoEx->m_pServInfo->dwForwardTimeout;
*pfSlave = m_pServInfoEx->m_pServInfo->fSlave;
if (m_pServInfoEx->m_pServInfo->aipForwarders == NULL)
{
*pcForwardersCount = 0;
*paipForwarders = NULL;
}
else
{
*pcForwardersCount = m_pServInfoEx->m_pServInfo->aipForwarders->AddrCount;
*paipForwarders = m_pServInfoEx->m_pServInfo->aipForwarders->AddrArray;
}
}
CDNSRootHintsNode* CDNSServerNode::GetRootHints()
{
if (m_pRootHintsNode == NULL)
{
m_pRootHintsNode = new CDNSRootHintsNode;
ASSERT(m_pRootHintsNode != NULL);
m_pRootHintsNode->SetServerNode(GetServerNode());
}
return m_pRootHintsNode;
}
void CDNSServerNode::GetTestOptions(CDNSServerTestOptions* pOptions)
{
ASSERT(pOptions != NULL);
*pOptions = m_testOptions;
}
void CDNSServerNode::ResetTestOptions(CDNSServerTestOptions* pOptions)
{
ASSERT(pOptions != NULL);
m_testOptions = *pOptions;
CDNSRootData* pSnapinData = (CDNSRootData*)GetRootContainer();
pSnapinData->SetDirtyFlag(TRUE);
}
void CDNSServerNode::AddTestQueryResult(CDNSServerTestQueryResult* pTestResult,
CComponentDataObject* pComponentData)
{
// TRACE(_T("m_testResultList.GetCount() == %d\n"), m_testResultList.GetCount());
if (!pTestResult->m_bAsyncQuery)
m_bTestQueryPending = FALSE;
CDNSServerTestQueryResultList::addAction action =
m_testResultList.AddTestQueryResult(pTestResult);
// change icon, if necessary (GetImageIndex() will switch from/to alternative server icon set
if (action == CDNSServerTestQueryResultList::added ||
action == CDNSServerTestQueryResultList::addedAndRemoved)
{
ASSERT(IsVisible());
VERIFY(SUCCEEDED(pComponentData->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
if (m_bPrevQuerySuccess != m_testResultList.LastQuerySuceeded())
{
pComponentData->UpdateResultPaneView(this);
}
m_bPrevQuerySuccess = m_testResultList.LastQuerySuceeded();
}
pComponentData->GetPropertyPageHolderTable()->BroadcastMessageToSheets(
this, SHEET_MSG_SERVER_TEST_DATA,
(LPARAM)action);
}
/////////////////////////////////////////////////////////////////////////////
///////// LOW LEVEL DNS UTILITIES ///////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
DNS_STATUS CDNSServerNode::EnumZoneInfo(CZoneInfoHolder* pZoneInfoHolder)
{
return EnumZoneInfo(m_szDisplayName, pZoneInfoHolder);
}
DNS_STATUS CDNSServerNode::EnumZoneInfo(LPCTSTR, CZoneInfoHolder* pZoneInfoHolder)
{
ASSERT(pZoneInfoHolder != NULL);
USES_CONVERSION;
DNS_STATUS err = 0;
do
{
ASSERT(pZoneInfoHolder->m_dwArrSize > 0);
ASSERT(pZoneInfoHolder->m_dwZoneCount == 0);
ASSERT(pZoneInfoHolder->m_zoneInfoArray != NULL);
if ((err == 0) || (err != ERROR_MORE_DATA))
{
break; // success or no need to retry
}
if (!pZoneInfoHolder->Grow())
{
break; // reached the limit for growth
}
} while (TRUE);
return err;
}
DNS_STATUS CDNSServerNode::ClearCache()
{
USES_CONVERSION;
return ::DnssrvOperation(GetRPCName(), // server name
NULL, // zone name, just pass null
DNSSRV_OP_CLEAR_CACHE,
DNSSRV_TYPEID_NULL,
NULL);
}
void CDNSServerNode::FreeServInfo()
{
ASSERT(m_pServInfoEx != NULL);
m_pServInfoEx->FreeInfo();
}
DNS_STATUS CDNSServerNode::GetServInfo()
{
ASSERT(m_pServInfoEx != NULL);
return m_pServInfoEx->Query(GetDisplayName());
}
void CDNSServerNode::AttachServerInfo(CDNSServerInfoEx* pNewInfo)
{
ASSERT(pNewInfo != NULL);
ASSERT(m_pServInfoEx != NULL);
delete m_pServInfoEx;
m_pServInfoEx = pNewInfo;
}
void CDNSServerNode::FreeRootHints()
{
if (m_pRootHintsNode != NULL)
{
//CNodeList* pChildList = m_pRootHintsNode->GetChildList();
//int n = pChildList->GetCount();
delete m_pRootHintsNode;
m_pRootHintsNode = NULL;
}
}
void CDNSServerNode::AttachRootHints(CDNSRootHintsNode* pNewRootHints)
{
ASSERT(pNewRootHints != NULL);
FreeRootHints();
m_pRootHintsNode = pNewRootHints;
// the display and full names were set already in the constructor
m_pRootHintsNode->SetServerNode(GetServerNode());
}