windows-nt/Source/XPSP1/NT/admin/snapin/dnsmgr/zone.cpp

2004 lines
52 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: zone.cpp
//
//--------------------------------------------------------------------------
#include "preDNSsn.h"
#include <SnapBase.h>
#include "resource.h"
#include "dnsutil.h"
#include "DNSSnap.h"
#include "snapdata.h"
#include "server.h"
#include "domain.h"
#include "record.h"
#include "zone.h"
#ifdef DEBUG_ALLOCATOR
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
////////////////////////////////////////////////////////////////////////////
// CDNSZoneNode
// {720132B9-44B2-11d1-B92F-00A0C9A06D2D}
const GUID CDNSZoneNode::NodeTypeGUID =
{ 0x720132b9, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } };
extern ZONE_TYPE_MAP _ZoneTypeStrings[];
CDNSZoneNode::CDNSZoneNode()
{
ASSERT(!IsDelegation());
m_pZoneNode = this; // the zone is us
m_pZoneInfoEx = new CDNSZoneInfoEx; // empty object with no data inside
// data valid when zone info not available
m_dwZoneFlags = 0x0;
m_wZoneType = 0x0;
NullCachedPointers();
}
CDNSZoneNode::~CDNSZoneNode()
{
TRACE(_T("~CDNSZoneNode(), name <%s>\n"),GetDisplayName());
if (m_pZoneInfoEx != NULL)
delete m_pZoneInfoEx;
}
#ifdef USE_NDNC
ReplicationType CDNSZoneNode::GetDirectoryPartitionFlagsAsReplType()
{
ReplicationType replReturn = w2k;
DWORD dwFlags = GetDirectoryPartitionFlags();
if (dwFlags & DNS_DP_DOMAIN_DEFAULT)
{
replReturn = domain;
}
else if (dwFlags & DNS_DP_FOREST_DEFAULT)
{
replReturn = forest;
}
else
{
if (dwFlags & DNS_DP_LEGACY)
{
replReturn = w2k;
}
else
{
replReturn = custom;
}
}
return replReturn;
}
PCWSTR CDNSZoneNode::GetCustomPartitionName()
{
USES_CONVERSION;
ASSERT(m_pZoneInfoEx != NULL);
if (m_szPartitionName.IsEmpty() && m_pZoneInfoEx->HasData())
{
m_szPartitionName = UTF8_TO_W(m_pZoneInfoEx->m_pZoneInfo->pszDpFqdn);
}
return m_szPartitionName;
}
DNS_STATUS CDNSZoneNode::ChangeDirectoryPartitionType(ReplicationType type, PCWSTR pszCustomPartition)
{
USES_CONVERSION;
PSTR pszReplScope = 0;
switch (type)
{
case domain :
pszReplScope = DNS_DP_DOMAIN_STR;
break;
case forest :
pszReplScope = DNS_DP_FOREST_STR;
break;
case w2k :
pszReplScope = DNS_DP_LEGACY_STR;
break;
default :
pszReplScope = W_TO_UTF8(pszCustomPartition);
break;
}
DNS_STATUS dwErr = ::DnssrvChangeZoneDirectoryPartition(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
pszReplScope);
if (dwErr == 0)
{
GetZoneInfo();
}
return dwErr;
}
#endif // USE_NDNC
LPCWSTR CDNSZoneNode::GetString(int nCol)
{
switch (nCol)
{
case 0:
//
// Zone name
//
return GetDisplayName();
case 1:
//
// Zone type
//
{
if (GetZoneType() == DNS_ZONE_TYPE_PRIMARY && IsDSIntegrated())
{
return _ZoneTypeStrings[0].szBuffer;
}
if (GetZoneType() == DNS_ZONE_TYPE_SECONDARY)
{
return _ZoneTypeStrings[2].szBuffer;
}
if (GetZoneType() == DNS_ZONE_TYPE_STUB)
{
if (IsDSIntegrated())
{
return _ZoneTypeStrings[6].szBuffer;
}
else
{
return _ZoneTypeStrings[5].szBuffer;
}
}
//
// Standard primary
//
return _ZoneTypeStrings[1].szBuffer;
}
/* case 2:
//
// Directory Partition Name
//
{
CDNSServerNode* pServerNode = GetServerNode();
if (!IsDSIntegrated() ||
pServerNode->GetBuildNumber() < DNS_SRV_BUILD_NUMBER_WHISTLER ||
(pServerNode->GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_5 &&
pServerNode->GetMinorVersion() < DNS_SRV_MINOR_VERSION_WHISTLER))
{
//
// The zone is not DS integrated
// or
// this is a pre-Whistler server, no Application Directory Partition support
//
return g_lpszNullString;
}
DWORD dwDpFlags = GetDirectoryPartitionFlags();
if (dwDpFlags == 0 ||
dwDpFlags & DNS_DP_LEGACY)
{
//
// To all DCs in the domain
//
// REVIEW_JEFFJON : todo!!!
return g_lpszNullString;
}
else if (dwDpFlags & DNS_DP_DOMAIN_DEFAULT)
{
//
// To all DNS servers in the domain
//
// REVIEW_JEFFJON : todo!!!
return g_lpszNullString;
}
else if (dwDpFlags & DNS_DP_ENTERPRISE_DEFAULT)
{
//
// To all DNS servers in the forest
//
// REVIEW_JEFFJON : todo!!!
return g_lpszNullString;
}
else if (dwDpFlags & DNS_DP_ENLISTED)
{
//
// To all DCs in the application directory partition
//
return GetCustomPartitionName();
}
}
break;
*/
case 2:
//
// Status
//
{
if (IsPaused())
{
return _ZoneTypeStrings[4].szBuffer;
}
return _ZoneTypeStrings[3].szBuffer;
}
}
return g_lpszNullString;
}
void CDNSZoneNode::InitializeFromRPCZoneInfo(PDNS_RPC_ZONE pZoneInfo, BOOL bAdvancedView)
{
USES_CONVERSION;
ASSERT(m_pZoneInfoEx != NULL);
ASSERT(!m_pZoneInfoEx->HasData());
ASSERT(pZoneInfo != NULL);
m_dwZoneFlags = 0x0;
if (pZoneInfo->Flags.Paused) m_dwZoneFlags |= DNS_ZONE_Paused;
if (pZoneInfo->Flags.Shutdown) m_dwZoneFlags |= DNS_ZONE_Shutdown;
if (pZoneInfo->Flags.Reverse) m_dwZoneFlags |= DNS_ZONE_Reverse;
if (pZoneInfo->Flags.AutoCreated) m_dwZoneFlags |= DNS_ZONE_AutoCreated;
if (pZoneInfo->Flags.DsIntegrated) m_dwZoneFlags |= DNS_ZONE_DsIntegrated;
m_wZoneType = pZoneInfo->ZoneType;
SetNames(IsZone(), pZoneInfo->Flags.Reverse, bAdvancedView,
pZoneInfo->pszZoneName, pZoneInfo->pszZoneName);
}
void CDNSZoneNode::FreeZoneInfo()
{
ASSERT(m_pZoneInfoEx != NULL);
m_pZoneInfoEx->FreeInfo();
}
DNS_STATUS CDNSZoneNode::GetZoneInfo()
{
ASSERT(m_pZoneInfoEx != NULL);
CDNSServerNode* pServerNode = GetServerNode();
ASSERT(pServerNode != NULL);
return m_pZoneInfoEx->Query(pServerNode->GetRPCName(),
GetFullName(),
pServerNode->GetVersion());
}
void CDNSZoneNode::AttachZoneInfo(CDNSZoneInfoEx* pNewInfo)
{
ASSERT(pNewInfo != NULL);
if (m_pZoneInfoEx != NULL)
delete m_pZoneInfoEx;
m_pZoneInfoEx = pNewInfo;
}
void CDNSZoneNode::SetZoneNormalViewHelper(CString& szDisplayName)
{
// the display name is stripped of the "in-addr.arpa" suffix
// e.g. from "127.in-addr.arpa" to "127"
// e.g. from "55.157.in-addr.arpa" to "55.157"
BOOL bArpa = RemoveInAddrArpaSuffix(szDisplayName.GetBuffer(1));
szDisplayName.ReleaseBuffer();
if (!bArpa)
return;
LPWSTR lpsz1 = szDisplayName.GetBuffer(1);
int nOctects = ReverseIPString(lpsz1);
//ASSERT(nOctects > 0 && nOctects < 4);
szDisplayName.ReleaseBuffer(); // got "157.80"
switch(nOctects)
{
case 1:
szDisplayName += _T(".x.x.x Subnet");
break;
case 2:
szDisplayName += _T(".x.x Subnet");
break;
case 3:
szDisplayName += _T(".x Subnet");
break;
}
}
void CDNSZoneNode::ChangeViewOption(BOOL bAdvanced,
CComponentDataObject* pComponentDataObject)
{
ASSERT(IsReverse());
if (!IsReverse())
return;
// change the display name
m_szDisplayName = GetFullName();
if (!bAdvanced)
{
SetZoneNormalViewHelper(m_szDisplayName);
}
if(IsVisible())
VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_DATA)));
// change the display name for all PTR records in the tree
ChangePTRRecordsViewOption(bAdvanced, pComponentDataObject);
}
BOOL CDNSZoneNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long *pInsertionAllowed)
{
DWORD dwType = GetZoneType();
//
// call this before the base class because it filters it out
//
if (pContextMenuItem2->lCommandID == IDM_ZONE_TRANSFER ||
pContextMenuItem2->lCommandID == IDM_ZONE_RELOAD_FROM_MASTER)
{
//
// if it is not a secondary, just bail out
//
if ( (dwType != DNS_ZONE_TYPE_SECONDARY) && (dwType != DNS_ZONE_TYPE_STUB))
{
return FALSE;
}
//
// have the menu item added. but it might be grayed out...
//
if (IsThreadLocked() || (m_nState == notLoaded) || (m_nState == loading))
{
//
// thread locked or not loaded state
//
pContextMenuItem2->fFlags |= MF_GRAYED;
}
return TRUE;
}
if (pContextMenuItem2->lCommandID == IDM_ZONE_UPDATE_DATA_FILE)
{
//
// cannot update data file on secondary zones, the cache or autocreated zones
//
if ( (dwType != DNS_ZONE_TYPE_PRIMARY) || IsAutocreated() )
{
return FALSE;
}
//
// have the menu item added. but it might be grayed out...
//
if (m_nState != loaded)
{
//
// not loaded state
//
pContextMenuItem2->fFlags |= MF_GRAYED;
}
else if ( (dwType == DNS_ZONE_TYPE_PRIMARY) && IsDSIntegrated() )
{
//
// primaries DS integrated
//
pContextMenuItem2->fFlags |= MF_GRAYED;
}
return TRUE;
}
if (pContextMenuItem2->lCommandID == IDM_ZONE_RELOAD)
{
//
// cannot reload the cache or autocreated zones
//
if ( (dwType == DNS_ZONE_TYPE_CACHE) || IsAutocreated() )
{
return FALSE;
}
//
// have the menu item added. but it might be grayed out...
//
if (IsThreadLocked() || (m_nState != loaded))
{
// not loaded state
pContextMenuItem2->fFlags |= MF_GRAYED;
}
return TRUE;
}
//
// NOTE: the base class knows about the derived class, so must call like this
//
if (!CDNSDomainNode::OnAddMenuItem(pContextMenuItem2,pInsertionAllowed))
{
return FALSE;
}
return TRUE;
}
BOOL CDNSZoneNode::OnSetRenameVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList*)
{
// REVIEW_JEFFJON : removed from Whistler release
//*pbHide = FALSE;
//return TRUE;
*pbHide = TRUE;
return FALSE;
}
HRESULT CDNSZoneNode::OnRename(CComponentDataObject*,
LPWSTR lpszNewName)
{
TRACE(_T("CDNSZoneNode::OnRename() : new name = %ws\n"), lpszNewName);
return S_FALSE;
}
HRESULT CDNSZoneNode::GetResultViewType(CComponentDataObject*,
LPOLESTR *ppViewType,
long *pViewOptions)
{
HRESULT hr = S_FALSE;
BOOL bUseMessageView = FALSE;
DWORD dwType = GetZoneType();
// special case for paused/expired zones
switch (m_nState)
{
case loaded:
{
if (dwType == DNS_ZONE_TYPE_CACHE)
{
bUseMessageView = FALSE;
}
else // authoritated zone
{
if (IsPaused())
bUseMessageView = FALSE;
else if (IsExpired())
bUseMessageView = TRUE;
else
bUseMessageView = FALSE;
}
}
break;
case unableToLoad:
case accessDenied:
bUseMessageView = TRUE;
break;
default:
bUseMessageView = FALSE;
}
if (bUseMessageView)
{
*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 CDNSZoneNode::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;
DWORD dwType = GetZoneType();
if ((dwType == DNS_ZONE_TYPE_PRIMARY) && IsDSIntegrated())
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_DS_MESSAGE));
iconID = Icon_Error;
}
else if ((dwType == DNS_ZONE_TYPE_PRIMARY) && !IsDSIntegrated())
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_PRIMARY_MESSAGE));
iconID = Icon_Error;
}
else
{
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_SECONDARY_MESSAGE));
iconID = Icon_Error;
}
spMessageView->SetTitleText(szTitle);
spMessageView->SetBodyText(szMessage);
spMessageView->SetIcon(iconID);
}
return S_OK;
}
int CDNSZoneNode::GetImageIndex(BOOL)
{
DWORD dwType = GetZoneType();
BOOL bPrimary = (dwType == DNS_ZONE_TYPE_PRIMARY);
// special case for paused/expired zones
int nIndex = -1;
switch (m_nState)
{
case notLoaded:
nIndex = (bPrimary) ? ZONE_IMAGE_NOT_LOADED_1 : ZONE_IMAGE_NOT_LOADED_2;
break;
case loading:
nIndex = (bPrimary) ? ZONE_IMAGE_LOADING_1 : ZONE_IMAGE_LOADING_2;
break;
case loaded:
{
if (dwType == DNS_ZONE_TYPE_CACHE)
{
nIndex = (bPrimary) ? ZONE_IMAGE_LOADED_1 : ZONE_IMAGE_LOADED_2;
}
else // authoritated zone
{
if (IsPaused())
nIndex = (bPrimary) ? ZONE_IMAGE_PAUSED_1 : ZONE_IMAGE_PAUSED_2;
else if (IsExpired())
nIndex = (bPrimary) ? ZONE_IMAGE_EXPIRED_1 : ZONE_IMAGE_EXPIRED_2;
else
nIndex = (bPrimary) ? ZONE_IMAGE_LOADED_1 : ZONE_IMAGE_LOADED_2;
}
}
break;
case unableToLoad:
nIndex = (bPrimary) ? ZONE_IMAGE_UNABLE_TO_LOAD_1 : ZONE_IMAGE_UNABLE_TO_LOAD_2;
break;
case accessDenied:
nIndex = (bPrimary) ? ZONE_IMAGE_ACCESS_DENIED_1 : ZONE_IMAGE_ACCESS_DENIED_2;
break;
default:
ASSERT(FALSE);
}
ASSERT(nIndex > 0);
return nIndex;
}
HRESULT CDNSZoneNode::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return E_FAIL;
}
switch (nCommandID)
{
case IDM_DOMAIN_NEW_DOMAIN:
OnNewDomain(pComponentData);
break;
case IDM_DOMAIN_NEW_DELEGATION:
OnNewDelegation(pComponentData);
break;
case IDM_DOMAIN_NEW_RECORD:
OnNewRecord(pComponentData, pNodeList);
break;
case IDM_DOMAIN_NEW_HOST:
OnNewHost(pComponentData);
break;
case IDM_DOMAIN_NEW_ALIAS:
OnNewAlias(pComponentData);
break;
case IDM_DOMAIN_NEW_MX:
OnNewMailExchanger(pComponentData);
break;
case IDM_DOMAIN_NEW_PTR:
OnNewPointer(pComponentData);
break;
case IDM_ZONE_UPDATE_DATA_FILE:
OnUpdateDataFile(pComponentData);
break;
case IDM_ZONE_RELOAD:
OnReload(pComponentData);
break;
case IDM_ZONE_TRANSFER:
OnTransferFromMaster(pComponentData);
break;
case IDM_ZONE_RELOAD_FROM_MASTER:
OnReloadFromMaster(pComponentData);
break;
case IDM_SNAPIN_ADVANCED_VIEW:
((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
break;
case IDM_SNAPIN_FILTERING:
{
if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
{
pComponentData->SetDescriptionBarText(this);
}
}
break;
default:
ASSERT(FALSE); // Unknown command!
return E_FAIL;
}
return S_OK;
}
void CDNSZoneNode::OnUpdateDataFile(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);
}
ASSERT(m_nState == loaded);
OnChangeState(pComponentData); // move to loading
{ // scope for the wait cursor
CWaitCursor wait;
m_dwErr = WriteToDatabase();
}
// 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 CDNSZoneNode::OnReload(CComponentDataObject* pComponentData)
{
UINT nRet = DNSConfirmOperation(IDS_MSG_ZONE_RELOAD, this);
if (IDCANCEL == nRet ||
IDNO == nRet)
{
return;
}
// 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);
}
ASSERT(m_nState == loaded);
DNS_STATUS err;
{ // scope for the wait cursor
CWaitCursor wait;
err = Reload();
}
if (err != 0)
{
// need to let the user know the operation failed
DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_RELOAD);
return;
}
CNodeList nodeList;
nodeList.AddTail(this);
// the zone has been reloaded cause a refresh to get new data
VERIFY(OnRefresh(pComponentData, &nodeList));
}
void CDNSZoneNode::OnTransferFromMaster(CComponentDataObject* pComponentData)
{
// 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);
}
ASSERT(m_nState != notLoaded);
ASSERT(m_nState != loading);
DNS_STATUS err;
{ // scope for the wait cursor
CWaitCursor wait;
err = TransferFromMaster();
}
if (err != 0)
{
// need to let the user know the operation failed
DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_TRANSFER);
return;
}
CNodeList nodeList;
nodeList.AddTail(this);
// the zone has been reloaded cause a refresh to get new data
VERIFY(OnRefresh(pComponentData, &nodeList));
}
void CDNSZoneNode::OnReloadFromMaster(CComponentDataObject* pComponentData)
{
// 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);
}
ASSERT(m_nState != notLoaded);
ASSERT(m_nState != loading);
DNS_STATUS err;
{ // scope for the wait cursor
CWaitCursor wait;
err = ReloadFromMaster();
}
if (err != 0)
{
// need to let the user know the operation failed
DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_RELOAD_FROM_MASTER);
return;
}
CNodeList nodeList;
nodeList.AddTail(this);
// the zone has been reloaded cause a refresh to get new data
VERIFY(OnRefresh(pComponentData, &nodeList));
}
void CDNSZoneNode::OnDelete(CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
OnMultiselectDelete(pComponentData, pNodeList);
return;
}
UINT nRet = DNSConfirmOperation(IDS_MSG_ZONE_DELETE, this);
if (IDCANCEL == nRet ||
IDNO == nRet)
{
return;
}
BOOL bDeleteFromDS = FALSE;
if (((GetZoneType() == DNS_ZONE_TYPE_PRIMARY) || (GetZoneType() == DNS_ZONE_TYPE_STUB)) &&
IsDSIntegrated())
{
if (GetServerNode()->GetBootMethod() == BOOT_METHOD_DIRECTORY)
{
// ask confirmation on delete from DS
int nRetVal = DNSMessageBox(IDS_MSG_ZONE_DELETE_FROM_DS_BOOT3,
MB_YESNO | MB_DEFBUTTON2);
if (IDNO == nRetVal)
return;
bDeleteFromDS = TRUE;
}
else
{
// ask confirmation on delete from DS
int nRetVal = DNSMessageBox(IDS_MSG_ZONE_DELETE_FROM_DS,
MB_YESNOCANCEL | MB_DEFBUTTON3);
if (IDCANCEL == nRetVal)
return;
bDeleteFromDS = (nRetVal == IDYES);
}
}
if (IsSheetLocked())
{
if (IDCANCEL == DNSMessageBox(IDS_ZONE_WARNING_SHEETS_UP, MB_OKCANCEL))
return;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
ASSERT(!IsSheetLocked());
DNS_STATUS err = Delete(bDeleteFromDS);
if (err != 0)
{
DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_DELETE);
return;
}
// now remove from the UI and from the cache
DeleteHelper(pComponentData);
pComponentData->UpdateResultPaneView(GetContainer());
if (IsRootZone())
{
if (DNSMessageBox(IDS_MSG_ZONE_DELETE_ROOT, MB_YESNO) == IDYES)
{
GetServerNode()->SetProppageStart(3); // 3 signifies the Root Hints page
pComponentData->CreatePropertySheet(GetServerNode(), NULL, L"My Title");
}
}
delete this; // gone
}
BOOL CDNSZoneNode::HasPropertyPages(DATA_OBJECT_TYPES,
BOOL* pbHideVerb,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return FALSE;
}
*pbHideVerb = FALSE; // always show the verb
if (!m_bHasDataForPropPages)
return FALSE;
// cannot have property pages only in loaded state
// if (m_nState != loaded)
// return FALSE;
ASSERT(m_pZoneInfoEx != NULL);
if ( (!m_pZoneInfoEx->HasData()) ||
( (GetZoneType() == DNS_ZONE_TYPE_CACHE) || IsAutocreated() ) )
{
return FALSE;
}
return TRUE;
}
HRESULT CDNSZoneNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
CNodeList* pNodeList)
{
ASSERT(pNodeList->GetCount() == 1); // multi-select not supported
ASSERT(m_bHasDataForPropPages);
if (GetSheetCount() > 0)
{
CComponentDataObject* pComponentDataObject =
((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
ASSERT(pComponentDataObject != NULL);
pComponentDataObject->GetPropertyPageHolderTable()->BroadcastSelectPage(this, ZONE_HOLDER_GEN);
return S_OK;
}
return CreatePropertyPagesHelper(lpProvider, handle, ZONE_HOLDER_GEN);
}
HRESULT CDNSZoneNode::CreatePropertyPagesHelper(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle, long nStartPageCode)
{
CComponentDataObject* pComponentDataObject =
((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
ASSERT(pComponentDataObject != NULL);
CDNSZonePropertyPageHolder* pHolder =
new CDNSZonePropertyPageHolder((CCathegoryFolderNode*)GetContainer(), this, pComponentDataObject);
ASSERT(pHolder != NULL);
pHolder->SetStartPageCode(nStartPageCode);
pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this);
return pHolder->CreateModelessSheet(lpProvider, handle);
}
void CDNSZoneNode::Show(BOOL bShow, CComponentDataObject* pComponentData)
{
CDNSDomainNode::Show(bShow, pComponentData);
if (!bShow)
NullCachedPointers();
}
void CDNSZoneNode::NullCachedPointers()
{
m_pSOARecordNode = NULL;
m_pWINSRecordNode = NULL;
}
BOOL CDNSZoneNode::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;
}
CNodeList nodeList;
nodeList.AddTail(this);
if (CDNSDomainNode::OnRefresh(pComponentData, &nodeList))
{
FreeZoneInfo();
NullCachedPointers();
return TRUE;
}
return FALSE;
}
void CDNSZoneNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
{
// if we get the zone info, just set it and bail out (no UI)
if (IS_CLASS(*pObj, CDNSZoneInfoEx))
{
ASSERT(!HasChildren()); // must be the first one coming from the thread
AttachZoneInfo(dynamic_cast<CDNSZoneInfoEx*>(pObj));
return;
}
CDNSDomainNode::OnHaveData(pObj, pComponentDataObject);
}
void CDNSZoneNode::OnHaveRecord(CDNSRecordNodeBase* pRecordNode,
CComponentDataObject* pComponentDataObject)
{
CDNSDomainNode::OnHaveRecord(pRecordNode, pComponentDataObject);
if ((pRecordNode->GetType() == DNS_TYPE_SOA) && pRecordNode->IsAtTheNode())
{
ASSERT(m_pSOARecordNode == NULL);
m_pSOARecordNode = (CDNS_SOA_RecordNode*)pRecordNode;
}
else if ( ( (pRecordNode->GetType() == DNS_TYPE_WINS) ||
(pRecordNode->GetType() == DNS_TYPE_NBSTAT) ) && pRecordNode->IsAtTheNode() )
{
ASSERT(m_pWINSRecordNode == NULL);
ASSERT( (IsReverse() && pRecordNode->GetType() == DNS_TYPE_NBSTAT) ||
(!IsReverse() && pRecordNode->GetType() == DNS_TYPE_WINS ) );
m_pWINSRecordNode = pRecordNode;
}
}
//////////////////////////////////////////////////////////////////////////////////
DNS_STATUS CDNSZoneNode::CreatePrimary(LPCTSTR lpszDBName,
BOOL bLoadExisting,
BOOL bDSIntegrated,
UINT nDynamicUpdate)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_PRIMARY;
IP_ADDRESS adwIpAddressDummy = 0;
LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
// create the zone
DNS_STATUS err = ::DnssrvCreateZone(
lpszServerName,
lpszAnsiZoneName,
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
0, // Number of masters, NA for primary
&adwIpAddressDummy, // Array of masters, dummy for primary
bLoadExisting,
bDSIntegrated,
bDSIntegrated ? NULL : W_TO_UTF8(lpszDBName), // Database file
0,
0);
if (err != 0)
return err;
// set the dynamic update flag
err = ::DnssrvResetDwordProperty(lpszServerName, lpszAnsiZoneName,
DNS_REGKEY_ZONE_ALLOW_UPDATE, nDynamicUpdate);
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
#ifdef USE_NDNC
DNS_STATUS CDNSZoneNode::CreatePrimaryInDirectoryPartition(BOOL bLoadExisting,
UINT nDynamicUpdate,
ReplicationType replType,
PCWSTR pszPartitionName)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_PRIMARY;
IP_ADDRESS adwIpAddressDummy = 0;
DWORD dwPartitionFlags = 0;
switch (replType)
{
case forest:
dwPartitionFlags |= DNS_DP_FOREST_DEFAULT;
break;
case domain:
dwPartitionFlags |= DNS_DP_DOMAIN_DEFAULT;
break;
case w2k:
dwPartitionFlags |= DNS_DP_LEGACY;
break;
case custom:
dwPartitionFlags = 0;
break;
case none:
default:
ASSERT(FALSE);
break;
}
LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
LPCSTR lpszUTF8PartitionName = W_TO_UTF8(pszPartitionName);
// create the zone
DNS_STATUS err = ::DnssrvCreateZoneInDirectoryPartition(
lpszServerName,
lpszAnsiZoneName,
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
0, // Number of masters, NA for primary
&adwIpAddressDummy, // Array of masters, dummy for primary
bLoadExisting,
0, // dwTimeout
0, // fSlave
dwPartitionFlags,
(replType == custom) ? lpszUTF8PartitionName : NULL);
if (err != 0)
return err;
// set the dynamic update flag
err = ::DnssrvResetDwordProperty(lpszServerName, lpszAnsiZoneName,
DNS_REGKEY_ZONE_ALLOW_UPDATE, nDynamicUpdate);
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
DNS_STATUS CDNSZoneNode::CreateStubInDirectoryPartition(DWORD* ipMastersArray,
int nIPMastersCount,
BOOL bLoadExisting,
ReplicationType replType,
PCWSTR pszPartitionName)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_STUB;
DWORD dwPartitionFlags = 0;
switch (replType)
{
case forest:
dwPartitionFlags |= DNS_DP_FOREST_DEFAULT;
break;
case domain:
dwPartitionFlags |= DNS_DP_DOMAIN_DEFAULT;
break;
case w2k:
dwPartitionFlags |= DNS_DP_LEGACY;
break;
case custom:
dwPartitionFlags = 0;
break;
case none:
default:
ASSERT(FALSE);
break;
}
ASSERT(ipMastersArray != NULL);
ASSERT(nIPMastersCount > 0);
LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
LPCSTR lpszUTF8PartitionName = W_TO_UTF8(pszPartitionName);
// create the zone
DNS_STATUS err = ::DnssrvCreateZoneInDirectoryPartition(
lpszServerName,
lpszAnsiZoneName,
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
nIPMastersCount, // Number of masters, NA for primary
ipMastersArray, // Array of masters, dummy for primary
bLoadExisting,
0, // dwTimeout
0, // fSlave
dwPartitionFlags,
(replType == custom) ? lpszUTF8PartitionName : NULL);
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
#endif // USE_NDNC
DNS_STATUS CDNSZoneNode::CreateSecondary(DWORD* ipMastersArray, int nIPMastersCount,
LPCTSTR lpszDBName, BOOL bLoadExisting)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_SECONDARY;
ASSERT(ipMastersArray != NULL);
ASSERT(nIPMastersCount > 0);
DNS_STATUS err = ::DnssrvCreateZone(
GetServerNode()->GetRPCName(), // Server name
W_TO_UTF8(GetFullName()), // Zone name
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
(DWORD)nIPMastersCount, // Number of masters
ipMastersArray, // Array of masters
bLoadExisting,
FALSE, // fDSIntegrated (secondaries are not in the DS)
W_TO_UTF8(lpszDBName), // Database file
0,
0);
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
DNS_STATUS CDNSZoneNode::CreateStub(DWORD* ipMastersArray,
int nIPMastersCount,
LPCTSTR lpszDBName,
BOOL bLoadExisting,
BOOL bDSIntegrated)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_STUB;
ASSERT(ipMastersArray != NULL);
ASSERT(nIPMastersCount > 0);
DNS_STATUS err = ::DnssrvCreateZone(
GetServerNode()->GetRPCName(), // Server name
W_TO_UTF8(GetFullName()), // Zone name
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
(DWORD)nIPMastersCount, // Number of masters
ipMastersArray, // Array of masters
bLoadExisting,
bDSIntegrated,
(bDSIntegrated) ? NULL : W_TO_UTF8(lpszDBName), // Database file
0,
0);
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
DNS_STATUS CDNSZoneNode::CreateForwarder(DWORD* ipMastersArray,
int nIPMastersCount,
DWORD dwTimeout,
DWORD fSlave)
{
USES_CONVERSION;
DWORD dwZoneType = DNS_ZONE_TYPE_FORWARDER;
DNS_STATUS err = ::DnssrvCreateZone(
GetServerNode()->GetRPCName(), // Server name
W_TO_UTF8(GetFullName()), // Zone name
dwZoneType, // Zone type
NULL, // RNAME field should be NULL according to bug 135245
(DWORD)nIPMastersCount, // Number of masters
ipMastersArray, // Array of masters
FALSE, // Load existing?
FALSE, // fDSIntegrated (secondaries are not in the DS)
NULL, // Database file
dwTimeout, // Time out
fSlave); // Slave?
if (err != 0)
return err;
ASSERT(m_pZoneInfoEx != NULL);
return GetZoneInfo();
}
DNS_STATUS CDNSZoneNode::SetSecondary(DWORD cMasters, PIP_ADDRESS aipMasters,
DWORD dwLoadOptions, LPCTSTR lpszDataFile)
{
USES_CONVERSION;
ASSERT_VALID_ZONE_INFO();
if (cMasters == 0)
return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
DNS_STATUS err = 0;
IP_ADDRESS dummy;
if (aipMasters == NULL)
{
ASSERT(cMasters == 0);
aipMasters = &dummy; // RPC wants non null ip array
}
err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
DNS_ZONE_TYPE_SECONDARY,
cMasters,
aipMasters,
dwLoadOptions,
FALSE, // bDSIntegrated
W_TO_UTF8(lpszDataFile));
if (err == 0)
err = GetZoneInfo();
return err;
}
DNS_STATUS CDNSZoneNode::SetStub(DWORD cMasters,
PIP_ADDRESS aipMasters,
DWORD dwLoadOptions,
BOOL bDSIntegrated,
LPCTSTR lpszDataFile,
BOOL bLocalListOfMasters)
{
USES_CONVERSION;
ASSERT_VALID_ZONE_INFO();
if (cMasters == 0)
return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
DNS_STATUS err = 0;
IP_ADDRESS dummy;
if (aipMasters == NULL)
{
ASSERT(cMasters == 0);
aipMasters = &dummy; // RPC wants non null ip array
}
err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
DNS_ZONE_TYPE_STUB,
cMasters,
aipMasters,
dwLoadOptions,
bDSIntegrated,
(bDSIntegrated) ? NULL : W_TO_UTF8(lpszDataFile));
if (err != 0)
return err;
if (bLocalListOfMasters)
{
err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
cMasters,
aipMasters,
TRUE); // LocalListOfMasters
}
else
{
err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
0,
NULL,
TRUE); // LocalListOfMasters
}
if (err == 0)
err = GetZoneInfo();
return err;
}
DNS_STATUS CDNSZoneNode::SetPrimary(DWORD dwLoadOptions, BOOL bDSIntegrated,
LPCTSTR lpszDataFile)
{
USES_CONVERSION;
ASSERT_VALID_ZONE_INFO();
DWORD cDummyMasters = 0; // dummy
DWORD dwDummyArr = 0;
DNS_STATUS err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
DNS_ZONE_TYPE_PRIMARY,
cDummyMasters, // not neeeded, but have to pass valid RPC val
&dwDummyArr,
dwLoadOptions,
bDSIntegrated,
bDSIntegrated ? "" : W_TO_UTF8(lpszDataFile));
if (err == 0)
err = GetZoneInfo();
return err;
}
DNS_STATUS CDNSZoneNode::SetAgingNoRefreshInterval(DWORD dwNoRefreshInterval)
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
DNS_REGKEY_ZONE_NOREFRESH_INTERVAL,
dwNoRefreshInterval);
if (dwErr == 0)
m_pZoneInfoEx->m_pZoneInfo->dwNoRefreshInterval = dwNoRefreshInterval;
return dwErr;
}
DNS_STATUS CDNSZoneNode::SetAgingRefreshInterval(DWORD dwRefreshInterval)
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
DNS_REGKEY_ZONE_REFRESH_INTERVAL,
dwRefreshInterval);
if (dwErr == 0)
m_pZoneInfoEx->m_pZoneInfo->dwRefreshInterval = dwRefreshInterval;
return dwErr;
}
DNS_STATUS CDNSZoneNode::SetScavengingEnabled(BOOL bEnable)
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()),
DNS_REGKEY_ZONE_AGING,
bEnable);
if (dwErr == 0)
m_pZoneInfoEx->m_pZoneInfo->fAging = bEnable;
return dwErr;
}
DNS_STATUS CDNSZoneNode::Delete(BOOL bDeleteFromDs)
{
ASSERT(m_pZoneInfoEx != NULL);
USES_CONVERSION;
if (((GetZoneType() == DNS_ZONE_TYPE_PRIMARY) ||
(GetZoneType() == DNS_ZONE_TYPE_STUB) ||
(GetZoneType() == DNS_ZONE_TYPE_FORWARDER)) &&
IsDSIntegrated() && bDeleteFromDs)
{
return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()),
DNSSRV_OP_ZONE_DELETE_FROM_DS,
DNSSRV_TYPEID_NULL,
NULL);
}
else
{
return ::DnssrvDeleteZone(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()));
}
}
DNS_STATUS CDNSZoneNode::IncrementVersion()
{
ASSERT(GetZoneType() == DNS_ZONE_TYPE_PRIMARY);
ASSERT(!IsAutocreated());
ASSERT(m_pZoneInfoEx != NULL);
USES_CONVERSION;
DNS_STATUS err = ::DnssrvIncrementZoneVersion(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()));
// refresh Zone Info if already present
if ((err == 0) && m_pZoneInfoEx->HasData())
err = GetZoneInfo();
return err;
}
DNS_STATUS CDNSZoneNode::Reload()
{
ASSERT(GetZoneType() == DNS_ZONE_TYPE_PRIMARY);
ASSERT(!IsAutocreated());
ASSERT(m_pZoneInfoEx != NULL);
USES_CONVERSION;
return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()),
DNSSRV_OP_ZONE_RELOAD,
DNSSRV_TYPEID_NULL,
NULL);
}
DNS_STATUS CDNSZoneNode::TransferFromMaster()
{
ASSERT(GetZoneType() == DNS_ZONE_TYPE_SECONDARY || GetZoneType() == DNS_ZONE_TYPE_STUB);
ASSERT(!IsAutocreated());
ASSERT(m_pZoneInfoEx != NULL);
USES_CONVERSION;
return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()),
DNSSRV_OP_ZONE_REFRESH,
DNSSRV_TYPEID_NULL,
NULL);
}
DNS_STATUS CDNSZoneNode::ReloadFromMaster()
{
ASSERT(GetZoneType() == DNS_ZONE_TYPE_SECONDARY || GetZoneType() == DNS_ZONE_TYPE_STUB);
ASSERT(!IsAutocreated());
ASSERT(m_pZoneInfoEx != NULL);
USES_CONVERSION;
return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()),
DNSSRV_OP_ZONE_EXPIRE,
DNSSRV_TYPEID_NULL,
NULL);
}
PCWSTR CDNSZoneNode::GetDN()
{
ASSERT(IsDSIntegrated());
ASSERT(m_pZoneInfoEx);
ASSERT(m_pZoneInfoEx->HasData());
return m_pZoneInfoEx->m_pZoneInfo->pwszZoneDn;
}
BOOL CDNSZoneNode::IsDSIntegrated()
{
if (GetZoneType() == DNS_ZONE_TYPE_CACHE)
return FALSE;
ASSERT(m_pZoneInfoEx != NULL);
return (m_pZoneInfoEx->HasData()) ?
(m_pZoneInfoEx->m_pZoneInfo->fUseDatabase ? TRUE : FALSE):
((m_dwZoneFlags & DNS_ZONE_DsIntegrated) != 0);
}
//sz = _T("LDAP://DC=uidev-one,DC=ntdev,DC=Microsoft,DC=Com,O=Internet");
void CDNSZoneNode::GetDataFile(CString& szName)
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
if (m_pZoneInfoEx == NULL || m_pZoneInfoEx->m_pZoneInfo == NULL)
{
szName = L"";
}
else
{
szName = UTF8_TO_W(m_pZoneInfoEx->m_pZoneInfo->pszDataFile);
}
}
LPCSTR CDNSZoneNode::GetDataFile()
{
ASSERT_VALID_ZONE_INFO();
if (m_pZoneInfoEx == NULL || m_pZoneInfoEx->m_pZoneInfo == NULL)
{
return "";
}
return m_pZoneInfoEx->m_pZoneInfo->pszDataFile;
}
DNS_STATUS CDNSZoneNode::ResetDatabase(BOOL bDSIntegrated, LPCTSTR lpszDataFile)
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
DNS_STATUS err = ::DnssrvResetZoneDatabase(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
bDSIntegrated,
W_TO_UTF8(lpszDataFile));
if (err == 0)
err = GetZoneInfo();
return err;
}
DNS_STATUS CDNSZoneNode::WriteToDatabase()
{
ASSERT_VALID_ZONE_INFO();
return CDNSZoneNode::WriteToDatabase(GetServerNode()->GetRPCName(), // server name
GetFullName()); // zone name
}
DNS_STATUS CDNSZoneNode::WriteToDatabase(LPCWSTR lpszServer, LPCWSTR lpszZone)
{
USES_CONVERSION;
return ::DnssrvOperation(lpszServer, W_TO_UTF8(lpszZone),
DNSSRV_OP_ZONE_WRITE_BACK_FILE,
DNSSRV_TYPEID_NULL,
NULL);
}
DNS_STATUS CDNSZoneNode::WriteToDatabase(LPCWSTR lpszServer, LPCSTR lpszZone)
{
return ::DnssrvOperation(lpszServer, lpszZone,
DNSSRV_OP_ZONE_WRITE_BACK_FILE,
DNSSRV_TYPEID_NULL,
NULL);
}
UINT CDNSZoneNode::GetDynamicUpdate()
{
ASSERT_VALID_ZONE_INFO();
return m_pZoneInfoEx->m_pZoneInfo->fAllowUpdate;
// return m_pZoneInfoEx->m_nAllowsDynamicUpdate;
}
DNS_STATUS CDNSZoneNode::SetDynamicUpdate(UINT nDynamic)
{
ASSERT_VALID_ZONE_INFO();
DNS_STATUS err = 0;
// call only if the info is dirty
if (GetDynamicUpdate() != nDynamic)
{
USES_CONVERSION;
err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
m_pZoneInfoEx->m_pZoneInfo->pszZoneName,
DNS_REGKEY_ZONE_ALLOW_UPDATE,
nDynamic);
if (err != 0)
return err;
err = GetZoneInfo();
}
return err;
}
DNS_STATUS CDNSZoneNode::ResetSecondaries(DWORD fSecureSecondaries,
DWORD cSecondaries, PIP_ADDRESS aipSecondaries,
DWORD fNotifyLevel,
DWORD cNotify, PIP_ADDRESS aipNotify)
{
ASSERT_VALID_ZONE_INFO();
DNS_STATUS err = 0;
BOOL bSecondariesDirty = (m_pZoneInfoEx->m_pZoneInfo->fSecureSecondaries != fSecureSecondaries) ||
(m_pZoneInfoEx->m_pZoneInfo->fNotifyLevel != fNotifyLevel) ||
(!(m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL && cSecondaries == 0) &&
(
(m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL && cSecondaries > 0) || // no addr --> more than one
(m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrCount != cSecondaries) || // change the # of addresses
(memcmp(aipSecondaries, m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrArray, sizeof(IP_ADDRESS)*cSecondaries) != 0)
)
);
BOOL bNotifyDirty =
(!(m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL && cNotify == 0) &&
(
(m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL && cNotify > 0) || // no addr --> more than one
(m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrCount != cNotify) || // change the # of addresses
(memcmp(aipNotify, m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrArray, sizeof(IP_ADDRESS)*cNotify) != 0)
)
);
if (bSecondariesDirty || bNotifyDirty)
{
USES_CONVERSION;
err = ::DnssrvResetZoneSecondaries(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
fSecureSecondaries,
cSecondaries,
aipSecondaries,
fNotifyLevel,
cNotify,
aipNotify
);
}
if (err == 0)
err = GetZoneInfo();
return err;
}
void CDNSZoneNode::GetSecondariesInfo(DWORD* pfSecureSecondaries,
DWORD* pcSecondaries, PIP_ADDRESS* paipSecondaries,
DWORD* pfNotifyLevel,
DWORD* pcNotify, PIP_ADDRESS* paipNotify)
{
ASSERT_VALID_ZONE_INFO();
ASSERT(pfSecureSecondaries != NULL);
ASSERT(pcSecondaries != NULL);
ASSERT(paipSecondaries != NULL);
ASSERT(pfNotifyLevel != NULL);
ASSERT(pcNotify != NULL);
ASSERT(paipNotify != NULL);
*pfSecureSecondaries = m_pZoneInfoEx->m_pZoneInfo->fSecureSecondaries;
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL)
{
*pcSecondaries = 0;
*paipSecondaries = NULL;
}
else
{
*pcSecondaries = m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrCount;
*paipSecondaries = m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrArray;
}
*pfNotifyLevel = m_pZoneInfoEx->m_pZoneInfo->fNotifyLevel;
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL)
{
*pcNotify = 0;
*paipNotify = NULL;
}
else
{
*pcNotify = m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrCount;
*paipNotify = m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrArray;
}
}
DNS_STATUS CDNSZoneNode::ResetMasters(DWORD cMasters, PIP_ADDRESS aipMasters, BOOL bLocalMasters)
{
ASSERT_VALID_ZONE_INFO();
if (cMasters == 0)
return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
USES_CONVERSION;
// make the call only if the data is dirty
DNS_STATUS err = 0;
if ((m_pZoneInfoEx->m_pZoneInfo->aipMasters == NULL && cMasters > 0) || // no addr --> more than one
(m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrCount != cMasters) || // change the # of addresses
(memcmp(aipMasters, m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrArray, sizeof(IP_ADDRESS)*cMasters) != 0) )
{
IP_ADDRESS dummy;
if (aipMasters == NULL)
{
ASSERT(cMasters == 0);
aipMasters = &dummy; // RPC wants non null ip array
}
err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
cMasters,
aipMasters,
bLocalMasters);
if (!bLocalMasters)
{
//
// Reset local list of masters
//
err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(), // server name
W_TO_UTF8(GetFullName()), // zone name
0,
NULL,
TRUE); // LocalListOfMasters
if (err != 0)
return err;
}
}
if (err == 0)
err = GetZoneInfo();
return err;
}
void CDNSZoneNode::GetMastersInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
{
ASSERT_VALID_ZONE_INFO();
ASSERT(pcAddrCount != NULL);
ASSERT(ppipAddrs != NULL);
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pZoneInfoEx->m_pZoneInfo->aipMasters == NULL)
{
*pcAddrCount = 0;
*ppipAddrs = NULL;
}
else
{
*pcAddrCount = m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrCount;
*ppipAddrs = m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrArray;
}
}
void CDNSZoneNode::GetLocalListOfMasters(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
{
ASSERT_VALID_ZONE_INFO();
ASSERT(pcAddrCount != NULL);
ASSERT(ppipAddrs != NULL);
// return pointers to struct fields, caller has to copy data elsewhere
if (m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters == NULL)
{
*pcAddrCount = 0;
*ppipAddrs = NULL;
}
else
{
*pcAddrCount = m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters->AddrCount;
*ppipAddrs = m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters->AddrArray;
}
}
DNS_STATUS CDNSZoneNode::TogglePauseHelper(CComponentDataObject* pComponentData)
{
ASSERT(m_nState == loaded);
OnChangeState(pComponentData); // move to loading
m_dwErr = TogglePause();
OnChangeState(pComponentData); // move to loaded or unableToLoad
return (DNS_STATUS)m_dwErr;
}
DNS_STATUS CDNSZoneNode::TogglePause()
{
ASSERT_VALID_ZONE_INFO();
USES_CONVERSION;
DNS_STATUS err;
if (IsPaused())
err = ::DnssrvResumeZone(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()) // zone name
);
else
err = ::DnssrvPauseZone(GetServerNode()->GetRPCName(),
W_TO_UTF8(GetFullName()) // zone name
);
if (err != 0)
return err;
err = GetZoneInfo();
ASSERT(err == 0);
return err;
}
BOOL CDNSZoneNode::IsPaused()
{
if (m_pZoneInfoEx != NULL && m_pZoneInfoEx->HasData())
{
ASSERT_VALID_ZONE_INFO();
return m_pZoneInfoEx->m_pZoneInfo->fPaused;
}
return ((m_dwZoneFlags & DNS_ZONE_Paused) != 0);
}
BOOL CDNSZoneNode::IsExpired()
{
ASSERT(m_pZoneInfoEx != NULL);
return (m_pZoneInfoEx->HasData()) ? m_pZoneInfoEx->m_pZoneInfo->fShutdown :
((m_dwZoneFlags & DNS_ZONE_Shutdown) != 0);
}
//////////////////////////////////////////////////////////////////////////
// editing API's for special record types
CDNS_SOA_Record* CDNSZoneNode::GetSOARecordCopy()
{
ASSERT(m_pSOARecordNode != NULL);
if (m_pSOARecordNode == NULL)
return NULL;
return (CDNS_SOA_Record*)m_pSOARecordNode->CreateCloneRecord();
}
DNS_STATUS CDNSZoneNode::UpdateSOARecord(CDNS_SOA_Record* pNewRecord,
CComponentDataObject* pComponentData)
{
ASSERT(m_pSOARecordNode != NULL);
if (m_pSOARecordNode == NULL)
{
return -1;
}
DNS_STATUS err = m_pSOARecordNode->Update(pNewRecord, FALSE /*bUseDefaultTTL*/);
if ( (err == 0) && (pComponentData != NULL) )
{
VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pSOARecordNode, CHANGE_RESULT_ITEM)));
}
return err;
}
CDNSRecord* CDNSZoneNode::GetWINSRecordCopy()
{
ASSERT(m_pWINSRecordNode != NULL);
if (m_pWINSRecordNode == NULL)
return NULL;
return m_pWINSRecordNode->CreateCloneRecord();
}
DNS_STATUS CDNSZoneNode::CreateWINSRecord(CDNSRecord* pNewWINSRecord,
CComponentDataObject* pComponentData)
{
TRACE(_T("CDNSZoneNode::CreateWINSRecord()\n"));
ASSERT(pNewWINSRecord != NULL);
if (m_pWINSRecordNode != NULL)
{
//
// should never happen
//
ASSERT(FALSE && m_pWINSRecordNode == NULL);
return -1;
}
//
// create a new record node object
//
if (IsReverse())
{
m_pWINSRecordNode = CDNSRecordInfo::CreateRecordNode(DNS_TYPE_NBSTAT);
}
else
{
m_pWINSRecordNode = CDNSRecordInfo::CreateRecordNode(DNS_TYPE_WINS);
}
//
// hook up container and set name of node (same as the zone)
//
m_pWINSRecordNode->SetContainer(this);
m_pWINSRecordNode->SetRecordName(GetDisplayName(), TRUE /*bAtTheNode */);
CDNSRootData* pRootData = (CDNSRootData*)(pComponentData->GetRootData());
ASSERT(pRootData != NULL);
m_pWINSRecordNode->SetFlagsDown(TN_FLAG_DNS_RECORD_FULL_NAME, !pRootData->IsAdvancedView());
//
// write on server
//
DNS_STATUS err = m_pWINSRecordNode->Update(pNewWINSRecord, TRUE /*bUseDefaultTTL*/);
if (err == 0)
{
VERIFY(AddChildToListAndUI(m_pWINSRecordNode, pComponentData));
pComponentData->SetDescriptionBarText(this);
}
else
{
delete m_pWINSRecordNode;
m_pWINSRecordNode = NULL;
}
TRACE(_T("EXIT\n"));
return err;
}
DNS_STATUS CDNSZoneNode::UpdateWINSRecord(CDNSRecord* pNewWINSRecord,
CComponentDataObject* pComponentData)
{
TRACE(_T("CDNSZoneNode::UpdateWINSRecord()\n"));
ASSERT(pNewWINSRecord != NULL);
ASSERT(m_pWINSRecordNode != NULL);
if (m_pWINSRecordNode == NULL)
{
return -1; // Bogus error code
}
ASSERT(
(IsReverse() && pNewWINSRecord->GetType() == DNS_TYPE_NBSTAT
&& m_pWINSRecordNode->GetType() == DNS_TYPE_NBSTAT) ||
(!IsReverse() && pNewWINSRecord->GetType() == DNS_TYPE_WINS
&& m_pWINSRecordNode->GetType() == DNS_TYPE_WINS)
);
DNS_STATUS err = m_pWINSRecordNode->Update(pNewWINSRecord, TRUE /*bUseDefaultTTL*/);
if (err == 0)
{
VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pWINSRecordNode, CHANGE_RESULT_ITEM)));
}
TRACE(_T("EXIT\n"));
return err;
}
DNS_STATUS CDNSZoneNode::DeleteWINSRecord(CComponentDataObject* pComponentData)
{
TRACE(_T("CDNSZoneNode::DeleteWINSRecord()\n"));
ASSERT(m_pWINSRecordNode != NULL);
if (m_pWINSRecordNode == NULL)
{
return -1; // bogus error code
}
DNS_STATUS err = m_pWINSRecordNode->DeleteOnServerAndUI(pComponentData);
if (err == 0)
{
delete m_pWINSRecordNode;
m_pWINSRecordNode = NULL;
}
TRACE(_T("EXIT\n"));
return err;
}