windows-nt/Source/XPSP1/NT/admin/snapin/dnsmgr/snapdata.cpp
2020-09-26 16:20:57 +08:00

1570 lines
41 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: snapdata.cpp
//
//--------------------------------------------------------------------------
#include "preDNSsn.h"
#include <SnapBase.h>
#include "resource.h"
#include "DNSSnap.h"
#include "dnsutil.h"
#include "snapdata.h"
#include "server.h"
#include "servwiz.h"
#include <prsht.h>
#include <svcguid.h>
#ifdef DEBUG_ALLOCATOR
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
// GLOBAL FUNCTIONS
HRESULT SaveStringHelper(LPCWSTR pwsz, IStream* pStm)
{
ASSERT(pStm);
ULONG nBytesWritten;
HRESULT hr;
DWORD nLen = static_cast<DWORD>(wcslen(pwsz)+1); // WCHAR including NULL
hr = pStm->Write((void*)&nLen, sizeof(DWORD),&nBytesWritten);
ASSERT(nBytesWritten == sizeof(DWORD));
if (FAILED(hr))
return hr;
hr = pStm->Write((void*)pwsz, sizeof(WCHAR)*nLen,&nBytesWritten);
ASSERT(nBytesWritten == sizeof(WCHAR)*nLen);
TRACE(_T("SaveStringHelper(<%s> nLen = %d\n"),pwsz,nLen);
return hr;
}
HRESULT LoadStringHelper(CString& sz, IStream* pStm)
{
ASSERT(pStm);
HRESULT hr;
ULONG nBytesRead;
DWORD nLen = 0;
hr = pStm->Read((void*)&nLen,sizeof(DWORD), &nBytesRead);
ASSERT(nBytesRead == sizeof(DWORD));
if (FAILED(hr) || (nBytesRead != sizeof(DWORD)))
return hr;
hr = pStm->Read((void*)sz.GetBuffer(nLen),sizeof(WCHAR)*nLen, &nBytesRead);
ASSERT(nBytesRead == sizeof(WCHAR)*nLen);
sz.ReleaseBuffer();
TRACE(_T("LoadStringHelper(<%s> nLen = %d\n"),(LPCTSTR)sz,nLen);
return hr;
}
HRESULT SaveDWordHelper(IStream* pStm, DWORD dw)
{
ULONG nBytesWritten;
HRESULT hr = pStm->Write((void*)&dw, sizeof(DWORD),&nBytesWritten);
if (nBytesWritten < sizeof(DWORD))
hr = STG_E_CANTSAVE;
return hr;
}
HRESULT LoadDWordHelper(IStream* pStm, DWORD* pdw)
{
ULONG nBytesRead;
HRESULT hr = pStm->Read((void*)pdw,sizeof(DWORD), &nBytesRead);
ASSERT(nBytesRead == sizeof(DWORD));
return hr;
}
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterPageBase
class CDNSQueryFilterSheet; // fwd decl
class CDNSQueryFilterPageBase : public CPropertyPage
{
public:
CDNSQueryFilterPageBase(UINT nIDD, CDNSQueryFilterSheet* pSheet)
: CPropertyPage(nIDD)
{
m_pSheet = pSheet;
m_bDirty = FALSE;
m_bInit = FALSE;
}
protected:
CDNSQueryFilterSheet* m_pSheet;
void SetDirty();
void Init();
BOOL IsDirty() { return m_bDirty;}
virtual BOOL OnInitDialog();
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnWhatsThis();
afx_msg BOOL OnHelp(WPARAM wParam, LPARAM lParam);
private:
BOOL m_bInit;
BOOL m_bDirty;
HWND m_hWndWhatsThis; // hwnd of right click "What's this" help
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterNamePage
class CDNSQueryFilterNamePage : public CDNSQueryFilterPageBase
{
public:
CDNSQueryFilterNamePage(CDNSQueryFilterSheet* pSheet)
: CDNSQueryFilterPageBase(IDD_FILTERING_NAME, pSheet)
{
}
protected:
virtual BOOL OnInitDialog();
virtual BOOL OnApply();
afx_msg void OnRadioClicked();
afx_msg void OnEditChange();
private:
CEdit* GetStartsStringEdit() { return (CEdit*)GetDlgItem(IDC_EDIT_FILTER_STARTS);}
CEdit* GetContainsStringEdit() { return (CEdit*)GetDlgItem(IDC_EDIT_FILTER_CONTAINS);}
CEdit* GetRangeFromStringEdit() { return (CEdit*)GetDlgItem(IDC_EDIT_FILTER_RANGE_FROM);}
CEdit* GetRangeToStringEdit() { return (CEdit*)GetDlgItem(IDC_EDIT_FILTER_RANGE_TO);}
CButton* GetRadioNone() { return (CButton*)GetDlgItem(IDC_RADIO_FILTER_NONE);}
CButton* GetRadioStarts() { return (CButton*)GetDlgItem(IDC_RADIO_FILTER_STARTS);}
CButton* GetRadioContains() { return (CButton*)GetDlgItem(IDC_RADIO_FILTER_CONTAINS);}
CButton* GetRadioRange() { return (CButton*)GetDlgItem(IDC_RADIO_FILTER_RANGE);}
// utility methods
UINT GetSelectedRadioButtonID();
void SyncControls(UINT nRadioID);
void GetEditText(UINT nID, CString& s);
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterAdvancedPage
class CDNSQueryFilterAdvancedPage : public CDNSQueryFilterPageBase
{
public:
CDNSQueryFilterAdvancedPage(CDNSQueryFilterSheet* pSheet)
: CDNSQueryFilterPageBase(IDD_FILTERING_LIMITS, pSheet)
{
}
protected:
virtual BOOL OnInitDialog();
virtual BOOL OnApply();
afx_msg void OnCountEditChange();
CDNSUnsignedIntEdit m_maxCountEdit;
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterSheet
class CDNSQueryFilterSheet : public CPropertySheet
{
public:
CDNSQueryFilterSheet(CDNSQueryFilter* pQueryFilter, CComponentDataObject* pComponentData)
: CPropertySheet(IDS_SNAPIN_FILTERING_TITLE),
m_namePage(this), m_advancedPage(this), m_pComponentData(pComponentData)
{
m_psh.dwFlags |= PSH_NOAPPLYNOW;
m_pQueryFilter = pQueryFilter;
AddPage(&m_namePage);
AddPage(&m_advancedPage);
m_bInit = FALSE;
}
CDNSQueryFilter* GetQueryFilter() { return m_pQueryFilter;}
CComponentDataObject* GetComponentData() { return m_pComponentData; }
void SetSheetStyle()
{
DWORD dwStyle = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
dwStyle |= WS_EX_CONTEXTHELP; // force the [?] button
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, dwStyle);
}
private:
void Init()
{
if (m_bInit)
return;
m_bInit = TRUE;
CWnd* p = GetDlgItem(IDOK);
if (p)
p->EnableWindow(FALSE);
}
void SetDirty()
{
if (!m_bInit)
return;
GetDlgItem(IDOK)->EnableWindow(TRUE);
}
BOOL m_bInit;
CComponentDataObject* m_pComponentData;
CDNSQueryFilter* m_pQueryFilter;
CDNSQueryFilterNamePage m_namePage;
CDNSQueryFilterAdvancedPage m_advancedPage;
friend class CDNSQueryFilterPageBase;
friend class CDNSQueryFilterNamePage;
friend class CDNSQueryFilterAdvancedPage;
};
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterPageBase IMPLEMENTATION
BOOL CDNSQueryFilterPageBase::OnInitDialog()
{
BOOL bRet = CPropertyPage::OnInitDialog();
m_pSheet->SetSheetStyle();
return bRet;
}
void CDNSQueryFilterPageBase::SetDirty()
{
if (!m_bInit)
return;
m_bDirty = TRUE;
m_pSheet->SetDirty();
}
void CDNSQueryFilterPageBase::Init()
{
m_bInit = TRUE;
m_pSheet->Init();
}
BEGIN_MESSAGE_MAP(CDNSQueryFilterPageBase, CPropertyPage)
ON_WM_CONTEXTMENU()
ON_MESSAGE(WM_HELP, OnHelp)
ON_COMMAND(IDM_WHATS_THIS, OnWhatsThis)
END_MESSAGE_MAP()
void CDNSQueryFilterPageBase::OnWhatsThis()
{
//
// Display context help for a control
//
if ( m_hWndWhatsThis )
{
//
// Build our own HELPINFO struct to pass to the underlying
// CS help functions built into the framework
//
int iCtrlID = ::GetDlgCtrlID(m_hWndWhatsThis);
HELPINFO helpInfo;
ZeroMemory(&helpInfo, sizeof(HELPINFO));
helpInfo.cbSize = sizeof(HELPINFO);
helpInfo.hItemHandle = m_hWndWhatsThis;
helpInfo.iCtrlId = iCtrlID;
m_pSheet->GetComponentData()->OnDialogContextHelp(m_nIDHelp, &helpInfo);
}
}
BOOL CDNSQueryFilterPageBase::OnHelp(WPARAM /*wParam*/, LPARAM lParam)
{
const LPHELPINFO pHelpInfo = (LPHELPINFO)lParam;
if (pHelpInfo && pHelpInfo->iContextType == HELPINFO_WINDOW)
{
//
// Display context help for a control
//
m_pSheet->GetComponentData()->OnDialogContextHelp(m_nIDHelp, pHelpInfo);
}
return TRUE;
}
void CDNSQueryFilterPageBase::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
//
// point is in screen coordinates
//
CMenu bar;
if ( bar.LoadMenu(IDR_WHATS_THIS_CONTEXT_MENU1) )
{
CMenu& popup = *bar.GetSubMenu (0);
ASSERT(popup.m_hMenu);
if ( popup.TrackPopupMenu (TPM_RIGHTBUTTON | TPM_LEFTBUTTON,
point.x, // in screen coordinates
point.y, // in screen coordinates
this) ) // route commands through main window
{
m_hWndWhatsThis = 0;
ScreenToClient (&point);
CWnd* pChild = ChildWindowFromPoint (point, // in client coordinates
CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
if ( pChild )
{
m_hWndWhatsThis = pChild->m_hWnd;
}
}
}
}
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterNamePage IMPLEMENTATION
BEGIN_MESSAGE_MAP(CDNSQueryFilterNamePage, CDNSQueryFilterPageBase)
ON_BN_CLICKED(IDC_RADIO_FILTER_NONE, OnRadioClicked)
ON_BN_CLICKED(IDC_RADIO_FILTER_STARTS, OnRadioClicked)
ON_BN_CLICKED(IDC_RADIO_FILTER_CONTAINS, OnRadioClicked)
ON_BN_CLICKED(IDC_RADIO_FILTER_RANGE, OnRadioClicked)
ON_EN_CHANGE(IDC_EDIT_FILTER_STARTS, OnEditChange)
ON_EN_CHANGE(IDC_EDIT_FILTER_CONTAINS, OnEditChange)
ON_EN_CHANGE(IDC_EDIT_FILTER_RANGE_FROM, OnEditChange)
ON_EN_CHANGE(IDC_EDIT_FILTER_RANGE_TO, OnEditChange)
END_MESSAGE_MAP()
UINT CDNSQueryFilterNamePage::GetSelectedRadioButtonID()
{
return GetCheckedRadioButton(IDC_RADIO_FILTER_NONE, IDC_RADIO_FILTER_RANGE);
}
void CDNSQueryFilterNamePage::OnRadioClicked()
{
UINT nRadioID = GetSelectedRadioButtonID();
SyncControls(nRadioID);
}
void CDNSQueryFilterNamePage::SyncControls(UINT nRadioID)
{
BOOL bStartsStringEditEnabled = FALSE;
BOOL bContainsStringEditEnabled = FALSE;
BOOL bRangeEnabled = FALSE;
if (nRadioID == IDC_RADIO_FILTER_STARTS)
{
bStartsStringEditEnabled = TRUE;
}
else if (nRadioID == IDC_RADIO_FILTER_CONTAINS)
{
bContainsStringEditEnabled = TRUE;
}
else if (nRadioID == IDC_RADIO_FILTER_RANGE)
{
bRangeEnabled = TRUE;
}
GetStartsStringEdit()->SetReadOnly(!bStartsStringEditEnabled);
GetContainsStringEdit()->SetReadOnly(!bContainsStringEditEnabled);
GetRangeFromStringEdit()->SetReadOnly(!bRangeEnabled);
GetRangeToStringEdit()->SetReadOnly(!bRangeEnabled);
SetDirty();
}
void CDNSQueryFilterNamePage::GetEditText(UINT nID, CString& s)
{
GetDlgItemText(nID, s);
s.TrimLeft();
s.TrimRight();
}
void CDNSQueryFilterNamePage::OnEditChange()
{
SetDirty();
}
BOOL CDNSQueryFilterNamePage::OnInitDialog()
{
CDNSQueryFilterPageBase::OnInitDialog();
// write data to edit fields
SetDlgItemText(IDC_EDIT_FILTER_STARTS, m_pSheet->m_pQueryFilter->m_szStartsString);
SetDlgItemText(IDC_EDIT_FILTER_CONTAINS, m_pSheet->m_pQueryFilter->m_szContainsString);
SetDlgItemText(IDC_EDIT_FILTER_RANGE_FROM, m_pSheet->m_pQueryFilter->m_szRangeFrom);
SetDlgItemText(IDC_EDIT_FILTER_RANGE_TO, m_pSheet->m_pQueryFilter->m_szRangeTo);
// set the radio buttons
UINT nRadioID = IDC_RADIO_FILTER_NONE;
switch(m_pSheet->m_pQueryFilter->m_nFilterOption)
{
case DNS_QUERY_FILTER_NONE:
{
GetRadioNone()->SetCheck(TRUE);
nRadioID = IDC_RADIO_FILTER_NONE;
}
break;
case DNS_QUERY_FILTER_STARTS:
{
GetRadioStarts()->SetCheck(TRUE);
nRadioID = IDC_RADIO_FILTER_STARTS;
}
break;
case DNS_QUERY_FILTER_CONTAINS:
{
GetRadioContains()->SetCheck(TRUE);
nRadioID = IDC_RADIO_FILTER_CONTAINS;
}
break;
case DNS_QUERY_FILTER_RANGE:
{
GetRadioRange()->SetCheck(TRUE);
nRadioID = IDC_RADIO_FILTER_RANGE;
}
break;
default:
ASSERT(FALSE);
}
// enable/disable the edit fields
SyncControls(nRadioID);
Init();
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CDNSQueryFilterNamePage::OnApply()
{
if (!IsDirty())
return TRUE;
UINT nRadioID = GetSelectedRadioButtonID();
// get data from edit controls
GetEditText(IDC_EDIT_FILTER_STARTS, m_pSheet->m_pQueryFilter->m_szStartsString);
GetEditText(IDC_EDIT_FILTER_CONTAINS, m_pSheet->m_pQueryFilter->m_szContainsString);
GetEditText(IDC_EDIT_FILTER_RANGE_FROM, m_pSheet->m_pQueryFilter->m_szRangeFrom);
GetEditText(IDC_EDIT_FILTER_RANGE_TO, m_pSheet->m_pQueryFilter->m_szRangeTo);
// get radio button selection
switch(nRadioID)
{
case IDC_RADIO_FILTER_NONE:
{
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_NONE;
}
break;
case IDC_RADIO_FILTER_STARTS:
{
if (m_pSheet->m_pQueryFilter->m_szStartsString.IsEmpty())
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_NONE;
else
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_STARTS;
}
break;
case IDC_RADIO_FILTER_CONTAINS:
{
if (m_pSheet->m_pQueryFilter->m_szContainsString.IsEmpty())
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_NONE;
else
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_CONTAINS;
}
break;
case IDC_RADIO_FILTER_RANGE:
{
if (m_pSheet->m_pQueryFilter->m_szRangeFrom.IsEmpty() &&
m_pSheet->m_pQueryFilter->m_szRangeTo.IsEmpty() )
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_NONE;
else
m_pSheet->m_pQueryFilter->m_nFilterOption = DNS_QUERY_FILTER_RANGE;
}
break;
default:
ASSERT(FALSE);
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilterAdvancedPage IMPLEMENTATION
BEGIN_MESSAGE_MAP(CDNSQueryFilterAdvancedPage, CDNSQueryFilterPageBase)
ON_EN_CHANGE(IDC_EDIT_COUNT, OnCountEditChange)
END_MESSAGE_MAP()
void CDNSQueryFilterAdvancedPage::OnCountEditChange()
{
SetDirty();
}
BOOL CDNSQueryFilterAdvancedPage::OnInitDialog()
{
CDNSQueryFilterPageBase::OnInitDialog();
// set the range of the edit control for range validation
VERIFY(m_maxCountEdit.SubclassDlgItem(IDC_EDIT_COUNT, this));
m_maxCountEdit.SetRange(DNS_QUERY_OBJ_COUNT_MIN, DNS_QUERY_OBJ_COUNT_MAX);
// Disable IME support on the control
ImmAssociateContext(m_maxCountEdit.GetSafeHwnd(), NULL);
// set limit on the # of digits based on the max value
CString s;
s.Format(_T("%u"), DNS_QUERY_OBJ_COUNT_MAX);
m_maxCountEdit.LimitText(s.GetLength());
// set the value
m_maxCountEdit.SetVal(m_pSheet->m_pQueryFilter->m_nMaxObjectCount);
Init();
return TRUE;
}
BOOL CDNSQueryFilterAdvancedPage::OnApply()
{
if (!IsDirty())
return TRUE;
m_pSheet->m_pQueryFilter->m_nMaxObjectCount = m_maxCountEdit.GetVal();
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CDNSQueryFilter
BOOL CDNSQueryFilter::EditFilteringOptions(CComponentDataObject* pComponentData)
{
CDNSQueryFilterSheet dlg(this, pComponentData);
return IDOK == dlg.DoModal();
}
HRESULT CDNSQueryFilter::Load(IStream* pStm)
{
HRESULT hr;
// name filtering
if (FAILED(hr = LoadDWordHelper(pStm, (DWORD*)(&m_nFilterOption))))
return hr;
if (FAILED(hr = LoadStringHelper(m_szStartsString, pStm)))
return hr;
if (FAILED(hr = LoadStringHelper(m_szContainsString, pStm)))
return hr;
if (FAILED(hr = LoadStringHelper(m_szRangeFrom, pStm)))
return hr;
if (FAILED(hr = LoadStringHelper(m_szRangeTo, pStm)))
return hr;
// query limit
if (FAILED(hr = LoadDWordHelper(pStm, (DWORD*)(&m_nMaxObjectCount))))
return hr;
return LoadDWordHelper(pStm, (DWORD*)(&m_bGetAll));
}
HRESULT CDNSQueryFilter::Save(IStream* pStm)
{
HRESULT hr;
// name filtering
if (FAILED(hr = SaveDWordHelper(pStm, (DWORD)m_nFilterOption)))
return hr;
if (FAILED(hr = SaveStringHelper(m_szStartsString, pStm)))
return hr;
if (FAILED(hr = SaveStringHelper(m_szContainsString, pStm)))
return hr;
if (FAILED(hr = SaveStringHelper(m_szRangeFrom, pStm)))
return hr;
if (FAILED(hr = SaveStringHelper(m_szRangeTo, pStm)))
return hr;
// query limit
if (FAILED(hr = SaveDWordHelper(pStm, (DWORD)(m_nMaxObjectCount))))
return hr;
return SaveDWordHelper(pStm, (DWORD)(m_bGetAll));
}
//////////////////////////////////////////////////////////////////////
// CDNSRootData
const GUID CDNSRootData::NodeTypeGUID =
{ 0x2faebfa3, 0x3f1a, 0x11d0, { 0x8c, 0x65, 0x0, 0xc0, 0x4f, 0xd8, 0xfe, 0xcb } };
BEGIN_TOOLBAR_MAP(CDNSRootData)
TOOLBAR_EVENT(toolbarNewServer, OnConnectToServer)
END_TOOLBAR_MAP()
CDNSRootData::CDNSRootData(CComponentDataObject* pComponentData) : CRootData(pComponentData)
{
m_bAdvancedView = FALSE;
m_pColumnSet = NULL;
m_szDescriptionBar = _T("");
m_bCreatePTRWithHost = FALSE;
}
CDNSRootData::~CDNSRootData()
{
TRACE(_T("~CDNSRootData(), name <%s>\n"),GetDisplayName());
}
STDAPI DnsSetup(LPCWSTR lpszFwdZoneName,
LPCWSTR lpszFwdZoneFileName,
LPCWSTR lpszRevZoneName,
LPCWSTR lpszRevZoneFileName,
DWORD dwFlags);
BOOL CDNSRootData::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
long*)
{
CComponentDataObject* pComponentData = GetComponentDataObject();
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_CONNECT_TO_SERVER)
{
ASSERT(pComponentData != NULL);
if (pComponentData->IsExtensionSnapin())
return FALSE; // extensions do not have this menu item
return TRUE;
}
// add toggle menu item for advanced view
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
{
pContextMenuItem2->fFlags = IsAdvancedView() ? MF_CHECKED : 0;
}
if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
{
if (IsFilteringEnabled())
{
pContextMenuItem2->fFlags = MF_CHECKED;
}
return TRUE;
}
return TRUE;
}
HRESULT CDNSRootData::GetResultViewType(CComponentDataObject*,
LPOLESTR *ppViewType,
long *pViewOptions)
{
HRESULT hr = S_FALSE;
if (m_containerChildList.IsEmpty() && m_leafChildList.IsEmpty())
{
*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 CDNSRootData::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))
{
// Load and set the title text of the message view
CString szTitle;
VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NO_SERVER_TITLE));
spMessageView->SetTitleText(szTitle);
// Load and set the body text of the message view
CString szMessage;
VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NO_SERVER_MESSAGE));
spMessageView->SetBodyText(szMessage);
// Use the standard information icon
spMessageView->SetIcon(Icon_Information);
}
return S_OK;
}
BOOL CDNSRootData::IsFilteringEnabled()
{
UINT nFilterOption = GetFilter()->GetFilterOption();
if (nFilterOption == DNS_QUERY_FILTER_DISABLED || nFilterOption == DNS_QUERY_FILTER_NONE)
{
return FALSE;
}
return TRUE;
}
BOOL CDNSRootData::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
BOOL* pbHide,
CNodeList*)
{
*pbHide = FALSE;
return !IsThreadLocked();
}
HRESULT CDNSRootData::OnSetToolbarVerbState(IToolbar* pToolbar,
CNodeList*)
{
HRESULT hr = S_OK;
//
// Set the button state for each button on the toolbar
//
hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, TRUE);
ASSERT(SUCCEEDED(hr));
hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
ASSERT(SUCCEEDED(hr));
return hr;
}
HRESULT CDNSRootData::OnCommand(long nCommandID,
DATA_OBJECT_TYPES,
CComponentDataObject* pComponentData,
CNodeList* pNodeList)
{
if (pNodeList->GetCount() > 1) // multiple selection
{
return E_FAIL;
}
switch (nCommandID)
{
case IDM_SNAPIN_CONNECT_TO_SERVER:
OnConnectToServer(pComponentData, pNodeList);
break;
case IDM_SNAPIN_ADVANCED_VIEW:
OnViewOptions(pComponentData);
break;
case IDM_SNAPIN_FILTERING:
{
if (OnFilteringOptions(pComponentData))
{
pComponentData->SetDescriptionBarText(this);
}
}
break;
default:
ASSERT(FALSE); // Unknown command!
return E_FAIL;
}
return S_OK;
}
BOOL CDNSRootData::OnEnumerate(CComponentDataObject* pComponentData, BOOL)
{
if (m_containerChildList.IsEmpty())
{
// the list is empty, need to add
ASSERT(pComponentData != NULL);
// create a modal dialog + possibly the wizard proper
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDNSServerWizardHolder holder(this, pComponentData, NULL);
holder.DoModalConnectOnLocalComputer();
return FALSE;
}
return TRUE; // there are already children, add them to the UI now
}
#define DNS_STREAM_VERSION_W2K ((DWORD)0x06)
#define DNS_STREAM_VERSION ((DWORD)0x07)
// IStream manipulation helpers overrides
HRESULT CDNSRootData::Load(IStream* pStm)
{
// assume never get multiple loads
if(!m_containerChildList.IsEmpty() || !m_leafChildList.IsEmpty())
return E_FAIL;
WCHAR szBuffer[256];
ULONG nLen; // WCHAR counting NULL
UINT nCount;
ULONG cbRead;
// read the version ##
DWORD dwVersion;
VERIFY(SUCCEEDED(pStm->Read((void*)&dwVersion,sizeof(DWORD), &cbRead)));
ASSERT(cbRead == sizeof(DWORD));
if (dwVersion != DNS_STREAM_VERSION && dwVersion != DNS_STREAM_VERSION_W2K)
return E_FAIL;
// load filtering options
VERIFY(SUCCEEDED(m_filterObj.Load(pStm)));
// load view option
VERIFY(SUCCEEDED(pStm->Read((void*)&m_bAdvancedView,sizeof(BOOL), &cbRead)));
ASSERT(cbRead == sizeof(BOOL));
//
// load the Create PTR record with host flag
//
if (dwVersion > DNS_STREAM_VERSION_W2K)
{
VERIFY(SUCCEEDED(pStm->Read((void*)&m_bCreatePTRWithHost,sizeof(BOOL), &cbRead)));
ASSERT(cbRead == sizeof(BOOL));
}
// load the name of the snapin root display string
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);
SetDisplayName(szBuffer);
// load the list of servers
VERIFY(SUCCEEDED(pStm->Read((void*)&nCount,sizeof(UINT), &cbRead)));
ASSERT(cbRead == sizeof(UINT));
CComponentDataObject* pComponentData = GetComponentDataObject();
for (int k=0; k< (int)nCount; k++)
{
CDNSServerNode* p = NULL;
VERIFY(SUCCEEDED(CDNSServerNode::CreateFromStream(pStm, &p)));
ASSERT(p != NULL);
VERIFY(AddChildToList(p));
AddServerToThreadList(p, pComponentData);
}
if (nCount > 0)
MarkEnumerated();
ASSERT(m_containerChildList.GetCount() == (int)nCount);
return S_OK;
}
HRESULT CDNSRootData::Save(IStream* pStm, BOOL fClearDirty)
{
UINT nCount;
ULONG cbWrite;
// write the version ##
DWORD dwVersion = DNS_STREAM_VERSION;
VERIFY(SUCCEEDED(pStm->Write((void*)&dwVersion, sizeof(DWORD),&cbWrite)));
ASSERT(cbWrite == sizeof(DWORD));
// save filtering options
VERIFY(SUCCEEDED(m_filterObj.Save(pStm)));
// save view options
VERIFY(SUCCEEDED(pStm->Write((void*)&m_bAdvancedView, sizeof(BOOL),&cbWrite)));
ASSERT(cbWrite == sizeof(BOOL));
//
// save the create PTR record with host flag
//
VERIFY(SUCCEEDED(pStm->Write((void*)&m_bCreatePTRWithHost, sizeof(BOOL),&cbWrite)));
ASSERT(cbWrite == sizeof(BOOL));
// save the name of the snapin root display string
ULONG 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);
// write # of servers
nCount = (UINT)m_containerChildList.GetCount();
VERIFY(SUCCEEDED(pStm->Write((void*)&nCount, sizeof(UINT),&cbWrite)));
ASSERT(cbWrite == sizeof(UINT));
// loop through the list of servers and serialize them
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CDNSServerNode* pServerNode = (CDNSServerNode*)m_containerChildList.GetNext(pos);
VERIFY(SUCCEEDED(pServerNode->SaveToStream(pStm)));
}
if (fClearDirty)
SetDirtyFlag(FALSE);
return S_OK;
}
HRESULT CDNSRootData::IsDirty()
{
return CRootData::IsDirty();
}
HRESULT CDNSRootData::OnConnectToServer(CComponentDataObject* pComponentData,
CNodeList*)
{
ASSERT(pComponentData != NULL);
// create a modal dialog + possibly the wizard proper
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDNSServerWizardHolder holder(this, pComponentData, NULL);
holder.DoModalConnect();
pComponentData->UpdateResultPaneView(this);
return S_OK;
}
void CDNSRootData::AddServer(CDNSServerNode* p, CComponentDataObject* pComponentData)
{
ASSERT(p != NULL);
AddChildToListAndUISorted(p, pComponentData);
AddServerToThreadList(p, pComponentData);
pComponentData->UpdateResultPaneView(this);
pComponentData->SetDescriptionBarText(this);
}
BOOL CDNSRootData::VerifyServerName(LPCTSTR lpszServerName)
{
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
//
// case insensitive compare
//
if (_wcsicmp(pNode->GetDisplayName(), lpszServerName) == 0)
{
return FALSE;
}
}
return TRUE;
}
BOOL CDNSRootData::OnViewOptions(CComponentDataObject* pComponentData)
{
// make sure there are not property sheets up: we do this because:
// a) some folders might be removed and might have sheets up
// b) some RR property pages (PTR) might not be switchable
// on the fly between view types
if (IsSheetLocked())
{
if (!CanCloseSheets())
return TRUE;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
ASSERT(!IsSheetLocked());
// toggle the view state
m_bAdvancedView = !m_bAdvancedView;
// loop through the servers
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
CDNSServerNode* pServerNode = (CDNSServerNode*)pNode;
// pass the new view option
pServerNode->ChangeViewOption(m_bAdvancedView, pComponentData);
}
// dirty the MMC document
SetDirtyFlag(TRUE);
return TRUE;
}
BOOL CDNSRootData::OnFilteringOptions(CComponentDataObject* pComponentData)
{
BOOL bRet = m_filterObj.EditFilteringOptions(pComponentData);
if (bRet)
{
SetDirtyFlag(TRUE);
}
return bRet;
}
BOOL CDNSRootData::CanCloseSheets()
{
return (IDCANCEL != DNSMessageBox(IDS_MSG_CONT_CLOSE_SHEET, MB_OKCANCEL));
}
BOOL CDNSRootData::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;
}
if (IsSheetLocked())
{
if (!CanCloseSheets())
return FALSE;
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
}
ASSERT(!IsSheetLocked());
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
CNodeList nodeList;
nodeList.AddTail(pNode);
((CDNSServerNode*)pNode)->OnRefresh(pComponentData, &nodeList);
}
return TRUE;
}
LPWSTR CDNSRootData::GetDescriptionBarText()
{
static CString szFilterEnabled;
static CString szServersFormat;
INT_PTR nContainerCount = GetContainerChildList()->GetCount();
INT_PTR nLeafCount = GetLeafChildList()->GetCount();
//
// If not already loaded, then load the format string L"%d record(s)"
//
if (szServersFormat.IsEmpty())
{
szServersFormat.LoadString(IDS_FORMAT_SERVERS);
}
//
// Format the child count into the description bar text
//
m_szDescriptionBar.Format(szServersFormat, nContainerCount + nLeafCount);
//
// Add L"[Filter Activated]" if the filter is on
//
if(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;
}
void CDNSRootData::TestServers(DWORD dwCurrTime, DWORD dwTimeInterval,
CComponentDataObject* pComponentData)
{
//TRACE(_T("CDNSRootData::TestServers()\n"));
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
CDNSServerNode* pServerNode = (CDNSServerNode*)pNode;
if (pServerNode->IsTestEnabled() && !pServerNode->m_bTestQueryPending
&& (pServerNode->m_dwTestTime <= dwCurrTime))
{
DWORD dwQueryFlags =
CDNSServerTestQueryResult::Pack(pServerNode->IsTestSimpleQueryEnabled(),
pServerNode->IsRecursiveQueryEnabled());
pComponentData->PostMessageToTimerThread(WM_TIMER_THREAD_SEND_QUERY,
(WPARAM)pServerNode,
(WPARAM)dwQueryFlags);
pServerNode->m_dwTestTime = dwCurrTime + pServerNode->GetTestInterval();
}
}
// check if the time counter has wrapped (it should be very unlikely, because
// the timeline is on a DWORD in seconds (about 47000 days) from the console startup.
if ((dwCurrTime + dwTimeInterval) < dwCurrTime)
{
// just reset the whole set of server times (not accurate, but acceptable)
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
CDNSServerNode* pServerNode = (CDNSServerNode*)pNode;
pServerNode->m_dwTestTime = 0;
}
}
}
void CDNSRootData::OnServerTestData(WPARAM wParam, LPARAM lParam, CComponentDataObject* pComponentData)
{
ASSERT(lParam == 0);
CDNSServerTestQueryResult* pTestResult = (CDNSServerTestQueryResult*)wParam;
ASSERT(pTestResult != NULL);
// loop through the list of servers to find where it belongs
POSITION pos;
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
{
CTreeNode* pNode = m_containerChildList.GetNext(pos);
ASSERT(pNode->IsContainer());
CDNSServerNode* pServerNode = (CDNSServerNode*)pNode;
if ( (CDNSServerNode*)(pTestResult->m_serverCookie) == pServerNode)
{
pServerNode->AddTestQueryResult(pTestResult, pComponentData);
return;
}
}
}
void CDNSRootData::AddServerToThreadList(CDNSServerNode* pServerNode,
CComponentDataObject* pComponentData)
{
CDNSServerTestQueryInfo* pInfo = new CDNSServerTestQueryInfo;
if (pInfo)
{
pInfo->m_szServerName = pServerNode->GetDisplayName();
pInfo->m_serverCookie = (MMC_COOKIE)pServerNode;
pComponentData->PostMessageToTimerThread(WM_TIMER_THREAD_ADD_SERVER, (WPARAM)pInfo,0);
}
}
void CDNSRootData::RemoveServerFromThreadList(CDNSServerNode* pServerNode,
CComponentDataObject* pComponentData)
{
WPARAM serverCookie = (WPARAM)pServerNode;
pComponentData->PostMessageToTimerThread(WM_TIMER_THREAD_REMOVE_SERVER, serverCookie,0);
}
///////////////////////////////////////////////////////////////////
// CDNSServerTestTimerThread
int CDNSServerTestTimerThread::Run()
{
MSG msg;
// initialize the message pump
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
// get let the main thread know we are entering the loop
// (0,0) means just acknowkedge
PostMessageToWnd(0,0);
while(::GetMessage(&msg, NULL, 0, 0))
{
switch(msg.message)
{
case WM_TIMER_THREAD_SEND_QUERY:
case WM_TIMER_THREAD_SEND_QUERY_TEST_NOW:
{
long serverCookie = (long)msg.wParam;
ASSERT(serverCookie != NULL);
POSITION pos;
for (pos = m_serverInfoList.GetHeadPosition(); pos != NULL; )
{
CDNSServerTestQueryInfo* pCurrInfo =
(CDNSServerTestQueryInfo*)m_serverInfoList.GetNext(pos);
if (serverCookie == pCurrInfo->m_serverCookie)
{
OnExecuteQuery(pCurrInfo, (DWORD)msg.lParam,
(msg.message == WM_TIMER_THREAD_SEND_QUERY_TEST_NOW));
break;
}
}
}
break;
case WM_TIMER_THREAD_ADD_SERVER:
{
CDNSServerTestQueryInfo* pInfo = (CDNSServerTestQueryInfo*)msg.wParam;
ASSERT(pInfo != NULL);
m_serverInfoList.AddTail(pInfo);
}
break;
case WM_TIMER_THREAD_REMOVE_SERVER:
{
long serverCookie = (long)msg.wParam;
ASSERT(serverCookie != NULL);
POSITION pos;
POSITION posDel = NULL;
CDNSServerTestQueryInfo* pInfo = NULL;
for (pos = m_serverInfoList.GetHeadPosition(); pos != NULL; )
{
posDel = pos;
CDNSServerTestQueryInfo* pCurrInfo =
(CDNSServerTestQueryInfo*)m_serverInfoList.GetNext(pos);
if (serverCookie == pCurrInfo->m_serverCookie)
{
pInfo = pCurrInfo;
break;
}
}
if (pInfo != NULL)
{
ASSERT(posDel != NULL);
m_serverInfoList.RemoveAt(posDel);
delete pInfo;
}
}
break;
//default:
//ASSERT(FALSE);
}
}
return 0;
}
void CDNSServerTestTimerThread::OnExecuteQuery(CDNSServerTestQueryInfo* pInfo,
DWORD dwQueryFlags,
BOOL bAsyncQuery)
{
// initialize a query result object
CDNSServerTestQueryResult* pTestResult = new CDNSServerTestQueryResult;
if (!pTestResult)
{
return;
}
pTestResult->m_serverCookie = pInfo->m_serverCookie;
pTestResult->m_dwQueryFlags = dwQueryFlags;
pTestResult->m_bAsyncQuery = bAsyncQuery;
::GetLocalTime(&(pTestResult->m_queryTime));
// execute query
BOOL bPlainQuery, bRecursiveQuery;
CDNSServerTestQueryResult::Unpack(dwQueryFlags, &bPlainQuery, &bRecursiveQuery);
IP_ADDRESS* ipArray;
int nIPCount;
pTestResult->m_dwAddressResolutionResult = FindIP(pInfo->m_szServerName, &ipArray, &nIPCount);
if (pTestResult->m_dwAddressResolutionResult == 0)
{
ASSERT(ipArray != NULL);
ASSERT(nIPCount > 0);
PIP_ARRAY pipArr = (PIP_ARRAY)malloc(sizeof(DWORD)+sizeof(IP_ADDRESS)*nIPCount);
if (pipArr && ipArray)
{
pipArr->AddrCount = nIPCount;
memcpy(pipArr->AddrArray, ipArray, sizeof(IP_ADDRESS)*nIPCount);
if (bPlainQuery)
{
pTestResult->m_dwPlainQueryResult = DoNothingQuery(pipArr, TRUE);
}
if (bRecursiveQuery)
{
pTestResult->m_dwRecursiveQueryResult = DoNothingQuery(pipArr, FALSE);
}
free(pipArr);
pipArr = 0;
}
}
if (!PostMessageToWnd((WPARAM)pTestResult, 0))
delete pTestResult; // could not deliver
if (ipArray != NULL)
free(ipArray);
}
DNS_STATUS CDNSServerTestTimerThread::FindIP(LPCTSTR lpszServerName, IP_ADDRESS** pipArray, int* pnIPCount)
{
DNS_STATUS dwErr = 0;
*pipArray = NULL;
*pnIPCount = 0;
// try to see if the name is already an IP address
IP_ADDRESS ipAddr = IPStringToAddr(lpszServerName);
if (ipAddr != INADDR_NONE)
{
*pnIPCount = 1;
*pipArray = (IP_ADDRESS*)malloc((*pnIPCount)*sizeof(IP_ADDRESS));
if (*pipArray != NULL)
{
*pipArray[0] = ipAddr;
}
}
else
{
//
// Originally we were doing a DnsQuery() to retrieve the IP address of the server so that we
// could perform a query to that server to monitor its response. The problem with this is that
// if the user enters a single label hostname as the server and they are administering remotely
// and the two machines have different domain suffixes, then the DnsQuery() to get the IP address
// of the server would fail. DnsQuery() appends the name of the Domain suffix to the single label
// host name and then tries to resolve the using that FQDN which is incorrect. So instead of
// performing a DnsQuery() to get the IP address, the following uses WSALookupServiceBegin(),
// Next(), and End() to get the IP address. This has a better chance of resolving the name because
// it uses DNS, WINS, etc. I am leaving in the old stuff just in case we run into some problems.
//
HANDLE hLookup;
WSAQUERYSET qsQuery;
DWORD dwBufLen = 0;
GUID gHostAddrByName = SVCID_INET_HOSTADDRBYNAME;
WSAQUERYSET* pBuffer = NULL;
//
// Initialize the query structure
//
memset(&qsQuery, 0, sizeof(WSAQUERYSET));
qsQuery.dwSize = sizeof(WSAQUERYSET); // the dwSize field has to be initialised like this
qsQuery.dwNameSpace = NS_ALL;
qsQuery.lpServiceClassId = &gHostAddrByName; // this is the GUID to perform forward name resolution (name to IP)
qsQuery.lpszServiceInstanceName = (LPWSTR)lpszServerName; // this is the name queried for.
hLookup = NULL;
//
// Get the handle for the query
//
int iStartupRet = 0;
int iResult = WSALookupServiceBegin(&qsQuery,LUP_RETURN_ALL,&hLookup);
if (iResult != 0)
{
//
// Find out what socket error it was
//
int iErrorRet = WSAGetLastError();
//
// If the service wasn't started try starting it
//
if (iErrorRet == WSANOTINITIALISED)
{
WSADATA wsaData;
WORD wVersion = MAKEWORD(2,0);
iStartupRet = WSAStartup(wVersion, &wsaData);
if (iStartupRet == 0)
{
//
// Startup succeeded, lets try to begin again
//
iResult = WSALookupServiceBegin(&qsQuery,LUP_RETURN_ALL,&hLookup);
}
}
//
// Clear the error
//
WSASetLastError(0);
}
if(0 == iResult)
{
//
// Get the size of the first data block from the query
//
iResult = WSALookupServiceNext(hLookup, LUP_RETURN_ALL | LUP_FLUSHCACHE, &dwBufLen,
pBuffer);
//
// Allocate the required space for the query data
//
pBuffer = (WSAQUERYSET*)malloc(dwBufLen);
ASSERT(pBuffer != NULL);
if (pBuffer == NULL)
{
return E_OUTOFMEMORY;
}
else
{
//
// Get the first data block from the query
//
iResult = WSALookupServiceNext(hLookup, LUP_RETURN_ALL | LUP_FLUSHCACHE, &dwBufLen,
pBuffer);
//
// Loop through all the data in the query but stop if we get a valid IP address
// for the remote machine.
//
while(0 == iResult)
{
if (pBuffer->lpcsaBuffer != NULL && pBuffer->lpcsaBuffer->RemoteAddr.lpSockaddr != NULL)
{
//
// We are only interested in the socket address so get a pointer to the sockaddr structure
//
sockaddr_in* pSockAddr = (sockaddr_in*)pBuffer->lpcsaBuffer->RemoteAddr.lpSockaddr;
ASSERT(pSockAddr != NULL);
//
// Pull the IP address of the remote machine and pack it into a DWORD
//
DWORD dwIP = 0;
dwIP = pSockAddr->sin_addr.S_un.S_un_b.s_b1;
dwIP |= pSockAddr->sin_addr.S_un.S_un_b.s_b2 << 8;
dwIP |= pSockAddr->sin_addr.S_un.S_un_b.s_b3 << 16;
dwIP |= pSockAddr->sin_addr.S_un.S_un_b.s_b4 << 24;
//
// Increment the IP count and allocate space for the address
//
(*pnIPCount)++;
*pipArray = (IP_ADDRESS*)malloc((*pnIPCount)*sizeof(IP_ADDRESS));
if (*pipArray != NULL)
{
//
// Copy the IP address into the IP array
//
PIP_ADDRESS pCurrAddr = *pipArray;
*pCurrAddr = dwIP;
}
//
// Break since we were able to obtain an IP address
//
break;
}
//
// Free the buffer if it is still there
//
if (pBuffer != NULL)
{
free(pBuffer);
pBuffer = NULL;
dwBufLen = 0;
}
//
// Get the size of the next data block from the query
//
iResult = WSALookupServiceNext(hLookup, LUP_RETURN_ALL | LUP_FLUSHCACHE, &dwBufLen,
pBuffer);
//
// Allocate enough space for the next data block from the query
//
pBuffer = (WSAQUERYSET*)malloc(dwBufLen);
ASSERT(pBuffer != NULL);
//
// Get the next data block from the query
//
iResult = WSALookupServiceNext(hLookup, LUP_RETURN_ALL, &dwBufLen,
pBuffer);
}
//
// Free the buffer if it hasn't already been freed
//
if (pBuffer != NULL)
{
free(pBuffer);
pBuffer = NULL;
}
}
//
// Close the handle to the query
//
iResult = WSALookupServiceEnd(hLookup);
ASSERT(iResult == 0);
//
// If we didn't get an IP address return an error
//
dwErr = (*pnIPCount < 1) ? -1 : 0;
}
}
return dwErr;
}
DNS_STATUS CDNSServerTestTimerThread::DoNothingQuery(PIP_ARRAY pipArr, BOOL bSimple)
{
PDNS_RECORD pRecordList = NULL;
DNS_STATUS dwErr = 0;
if (bSimple)
{
dwErr = ::DnsQuery(_T("1.0.0.127.in-addr.arpa"),
DNS_TYPE_PTR,
DNS_QUERY_NO_RECURSION | DNS_QUERY_BYPASS_CACHE | DNS_QUERY_ACCEPT_PARTIAL_UDP,
pipArr, &pRecordList, NULL);
}
else
{
dwErr = ::DnsQuery(_T("."),
DNS_TYPE_NS,
DNS_QUERY_STANDARD | DNS_QUERY_BYPASS_CACHE | DNS_QUERY_ACCEPT_PARTIAL_UDP,
pipArr, &pRecordList, NULL);
}
if (pRecordList != NULL)
::DnsRecordListFree(pRecordList, DnsFreeRecordListDeep);
return dwErr;
}