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

2363 lines
56 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: uiutil.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 "zone.h"
#include "serverui.h"
#include "uiutil.h"
#ifdef DEBUG_ALLOCATOR
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
////////////////////////////////////////////////////////////////////////////
// CDNSNameTokenizer
CDNSNameTokenizer::CDNSNameTokenizer(PCWSTR pszDNSName)
{
ASSERT(pszDNSName != NULL);
m_szDNSName = pszDNSName;
}
CDNSNameTokenizer::~CDNSNameTokenizer()
{
}
BOOL CDNSNameTokenizer::Tokenize(const wchar_t* wcToken)
{
BOOL bRet = TRUE;
PWSTR pszToken = new WCHAR[m_szDNSName.GetLength() + 1];
if (pszToken != NULL)
{
wcscpy(pszToken, m_szDNSName);
PWSTR pszNextToken = wcstok(pszToken, wcToken);
while (pszNextToken != NULL)
{
AddTail(pszNextToken);
pszNextToken = wcstok(NULL, wcToken);
}
delete[] pszToken;
pszToken = NULL;
}
else
{
bRet = FALSE;
}
return bRet;
}
void CDNSNameTokenizer::RemoveMatchingFromTail(CDNSNameTokenizer& refTokenizer)
{
//
// Removes matching tokens from the tail until one of the tokenizers is empty
// or we come across mismatched tokens
//
while (GetCount() > 0 && refTokenizer.GetCount() > 0)
{
if (GetTail() == refTokenizer.GetTail())
{
RemoveTail();
refTokenizer.RemoveTail();
}
else
{
break;
}
}
}
void CDNSNameTokenizer::GetRemaining(CString& strrefRemaining, const wchar_t* wcToken)
{
//
// Copies the remaining tokens into a string delimited by the token passed in
//
strrefRemaining.Empty();
POSITION pos = GetHeadPosition();
while (pos != NULL)
{
strrefRemaining += GetNext(pos);
if (pos != NULL)
{
strrefRemaining += wcToken;
}
}
}
////////////////////////////////////////////////////////////////////////////
// Global functions
BOOL LoadStringsToComboBox(HINSTANCE hInstance, CComboBox* pCombo,
UINT nStringID, UINT nMaxLen, UINT nMaxAddCount)
{
pCombo->ResetContent();
ASSERT(hInstance != NULL);
WCHAR* szBuf = (WCHAR*)malloc(sizeof(WCHAR)*nMaxLen);
if (!szBuf)
{
return FALSE;
}
BOOL bRet = TRUE;
LPWSTR* lpszArr = 0;
do // false loop
{
if ( ::LoadString(hInstance, nStringID, szBuf, nMaxLen) == 0)
{
bRet = FALSE;
break;
}
lpszArr = (LPWSTR*)malloc(sizeof(LPWSTR*)*nMaxLen);
if (!lpszArr)
{
bRet = FALSE;
break;
}
UINT nArrEntries;
ParseNewLineSeparatedString(szBuf,lpszArr, &nArrEntries);
if (nMaxAddCount < nArrEntries) nArrEntries = nMaxAddCount;
for (UINT k=0; k<nArrEntries; k++)
pCombo->AddString(lpszArr[k]);
} while (false);
if (szBuf)
{
free(szBuf);
szBuf = 0;
}
if (lpszArr)
{
free(lpszArr);
lpszArr = 0;
}
return bRet;
}
void ParseNewLineSeparatedString(LPWSTR lpsz,
LPWSTR* lpszArr,
UINT* pnArrEntries)
{
static WCHAR lpszSep[] = L"\n";
*pnArrEntries = 0;
int k = 0;
lpszArr[k] = wcstok(lpsz, lpszSep);
if (lpszArr[k] == NULL)
return;
while (TRUE)
{
WCHAR* lpszToken = wcstok(NULL, lpszSep);
if (lpszToken != NULL)
lpszArr[++k] = lpszToken;
else
break;
}
*pnArrEntries = k+1;
}
void LoadStringArrayFromResource(LPWSTR* lpszArr,
UINT* nStringIDs,
int nArrEntries,
int* pnSuccessEntries)
{
CString szTemp;
*pnSuccessEntries = 0;
for (int k = 0;k < nArrEntries; k++)
{
if (!szTemp.LoadString(nStringIDs[k]))
{
lpszArr[k] = NULL;
continue;
}
int iLength = szTemp.GetLength() + 1;
lpszArr[k] = (LPWSTR)malloc(sizeof(WCHAR)*iLength);
if (lpszArr[k] != NULL)
{
wcscpy(lpszArr[k], (LPWSTR)(LPCWSTR)szTemp);
(*pnSuccessEntries)++;
}
}
}
void EnumerateMTNodeHelper(CMTContainerNode* pNode,
CComponentDataObject* pComponentData)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//TRACE(_T("before CLongOperationDialog::DoModal()\n"));
HWND hWnd = NULL;
HRESULT hr = pComponentData->GetConsole()->GetMainWindow(&hWnd);
ASSERT(SUCCEEDED(hr));
CWnd* pParentWnd = CWnd::FromHandle(hWnd);
CLongOperationDialog dlg(
new CNodeEnumerationThread(pComponentData,pNode),
pParentWnd,
IDR_SEARCH_AVI);
dlg.DoModal();
//TRACE(_T("after CLongOperationDialog::DoModal()\n"));
}
void _EnableEditableControlHelper(HWND hWnd, BOOL bEnable)
{
WCHAR szBuf[256];
::GetClassName(hWnd, szBuf, 256);
if (wcscmp(szBuf, TEXT("Static")) != 0)
::EnableWindow(hWnd, bEnable);
}
void EnableDialogControls(HWND hWnd, BOOL bEnable)
{
HWND hWndCurr = ::GetWindow(hWnd, GW_CHILD);
if (hWndCurr != NULL)
{
_EnableEditableControlHelper(hWndCurr, bEnable);
hWndCurr = ::GetNextWindow(hWndCurr, GW_HWNDNEXT);
while (hWndCurr)
{
_EnableEditableControlHelper(hWndCurr, bEnable);
hWndCurr = ::GetNextWindow(hWndCurr, GW_HWNDNEXT);
}
}
}
BOOL LoadFontInfoFromResource(IN UINT nFontNameID,
IN UINT nFontSizeID,
OUT LPWSTR lpFontName, IN int nFontNameMaxchar,
OUT int& nFontSize,
IN LPCWSTR lpszDefaultFont, IN int nDefaultFontSize)
{
BOOL bRes = FALSE;
if (0 == ::LoadString(_Module.GetResourceInstance(), nFontNameID,
lpFontName, nFontNameMaxchar))
{
wcscpy(lpFontName, lpszDefaultFont);
}
else
{
bRes = TRUE;
}
WCHAR szFontSize[128];
if (0 != ::LoadString(_Module.GetResourceInstance(), nFontSizeID,
szFontSize, sizeof(szFontSize)/sizeof(WCHAR)))
{
nFontSize = _wtoi(szFontSize);
if (nFontSize == 0)
nFontSize = nDefaultFontSize;
else
bRes = TRUE;
}
else
{
nFontSize = nDefaultFontSize;
}
return bRes;
}
void InitBigBoldFont(HWND hWnd, HFONT& hFont)
{
ASSERT(::IsWindow(hWnd));
NONCLIENTMETRICS ncm;
memset(&ncm, 0, sizeof(ncm));
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
LOGFONT boldLogFont = ncm.lfMessageFont;
boldLogFont.lfWeight = FW_BOLD;
int nFontSize = 0;
VERIFY(LoadFontInfoFromResource(IDS_BIG_BOLD_FONT_NAME,
IDS_BIG_BOLD_FONT_SIZE,
boldLogFont.lfFaceName, LF_FACESIZE,
nFontSize,
L"Verdana Bold", 12 // default if something goes wrong
));
HDC hdc = ::GetDC(hWnd);
if (hdc != NULL)
{
boldLogFont.lfHeight = 0 - (::GetDeviceCaps(hdc, LOGPIXELSY) * nFontSize / 72);
hFont = ::CreateFontIndirect((const LOGFONT*)(&boldLogFont));
::ReleaseDC(hWnd, hdc);
}
}
void SetBigBoldFont(HWND hWndDialog, int nControlID)
{
ASSERT(::IsWindow(hWndDialog));
ASSERT(nControlID);
static HFONT boldLogFont = 0;
if (boldLogFont == 0)
{
InitBigBoldFont(hWndDialog, boldLogFont);
}
HWND hWndControl = ::GetDlgItem(hWndDialog, nControlID);
if (hWndControl)
{
::SendMessage(hWndControl, WM_SETFONT, (WPARAM)boldLogFont, MAKELPARAM(TRUE, 0));
}
}
int GetCheckedRadioButtonHelper(HWND hDlg, int nCount, int* nRadioArr, int nRadioDefault)
{
ASSERT(::IsWindow(hDlg));
ASSERT(nCount > 0);
for (int k=0; k<nCount; k++)
{
HWND hRadio = ::GetDlgItem(hDlg, nRadioArr[k]);
ASSERT(hRadio != NULL);
if ((hRadio != NULL) && (BST_CHECKED == ::SendMessage(hRadio, BM_GETCHECK, 0, 0)))
return nRadioArr[k];
}
ASSERT(FALSE);
return nRadioDefault;
}
////////////////////////////////////////////////////////////////////////////
// CMultiselectErrorDialog
BEGIN_MESSAGE_MAP(CMultiselectErrorDialog, CDialog)
END_MESSAGE_MAP()
HRESULT CMultiselectErrorDialog::Initialize(CNodeList* pNodeList,
DNS_STATUS* pErrorArray,
UINT nErrorCount,
PCWSTR pszTitle,
PCWSTR pszCaption,
PCWSTR pszColumnHeader)
{
ASSERT(pNodeList != NULL);
ASSERT(pErrorArray != NULL);
ASSERT(pszTitle != NULL);
ASSERT(pszCaption != NULL);
ASSERT(pszColumnHeader != NULL);
if (pNodeList == NULL ||
pErrorArray == NULL ||
pszTitle == NULL ||
pszCaption == NULL ||
pszColumnHeader == NULL)
{
return E_POINTER;
}
m_pNodeList = pNodeList;
m_pErrorArray = pErrorArray;
m_nErrorCount = nErrorCount;
m_szTitle = pszTitle;
m_szCaption = pszCaption;
m_szColumnHeader = pszColumnHeader;
return S_OK;
}
const int OBJ_LIST_NAME_COL_WIDTH = 100;
const int IDX_NAME_COL = 0;
const int IDX_ERR_COL = 1;
BOOL CMultiselectErrorDialog::OnInitDialog()
{
CDialog::OnInitDialog();
SetWindowText(m_szTitle);
SetDlgItemText(IDC_STATIC_MESSAGE, m_szCaption);
HWND hList = GetDlgItem(IDC_ERROR_LIST)->GetSafeHwnd();
ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
//
// Set the column headings.
//
RECT rect;
::GetClientRect(hList, &rect);
LV_COLUMN lvc = {0};
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = OBJ_LIST_NAME_COL_WIDTH;
lvc.pszText = (PWSTR)(PCWSTR)m_szColumnHeader;
lvc.iSubItem = IDX_NAME_COL;
ListView_InsertColumn(hList, IDX_NAME_COL, &lvc);
CString szError;
VERIFY(szError.LoadString(IDS_ERROR));
lvc.cx = rect.right - OBJ_LIST_NAME_COL_WIDTH;
lvc.pszText = (PWSTR)(PCWSTR)szError;
lvc.iSubItem = IDX_ERR_COL;
ListView_InsertColumn(hList, IDX_ERR_COL, &lvc);
//
// Insert the errors
//
ASSERT(m_pErrorArray != NULL && m_pNodeList != NULL);
UINT nIdx = 0;
POSITION pos = m_pNodeList->GetHeadPosition();
while (pos != NULL)
{
CTreeNode* pNode = m_pNodeList->GetNext(pos);
if (pNode != NULL)
{
if (nIdx < m_nErrorCount && m_pErrorArray[nIdx] != 0)
{
//
// Create the list view item
//
LV_ITEM lvi = {0};
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iSubItem = IDX_NAME_COL;
lvi.lParam = (LPARAM)pNode->GetDisplayName();
lvi.pszText = (PWSTR)pNode->GetDisplayName();
lvi.iItem = nIdx;
//
// Insert the new item
//
int NewIndex = ListView_InsertItem(hList, &lvi);
ASSERT(NewIndex != -1);
if (NewIndex == -1)
{
continue;
}
//
// Get the error message
//
CString szErrorMessage;
if (CDNSErrorInfo::GetErrorString(m_pErrorArray[nIdx],szErrorMessage))
{
ListView_SetItemText(hList, NewIndex, IDX_ERR_COL, (PWSTR)(PCWSTR)szErrorMessage);
}
}
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
// CDNSMaskCtrl
// static alert function
int CDNSMaskCtrl::AlertFunc(HWND, DWORD dwCurrent, DWORD dwLow, DWORD dwHigh)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString szFormat;
szFormat.LoadString(IDS_MASK_ALERT);
CString s;
s.Format((LPCWSTR)szFormat, dwCurrent, dwLow, dwHigh);
AfxMessageBox(s);
return 0;
}
BOOL CDNSMaskCtrl::IsBlank()
{
return static_cast<BOOL>(SendMessage(DNS_MASK_CTRL_ISBLANK, 0, 0));
}
void CDNSMaskCtrl::SetFocusField(DWORD dwField)
{
SendMessage(DNS_MASK_CTRL_SETFOCUS, dwField, 0);
}
void CDNSMaskCtrl::SetFieldRange(DWORD dwField, DWORD dwMin, DWORD dwMax)
{
SendMessage(DNS_MASK_CTRL_SET_LOW_RANGE, dwField, dwMin);
SendMessage(DNS_MASK_CTRL_SET_HI_RANGE, dwField, dwMax);
}
void CDNSMaskCtrl::SetArray(DWORD* pArray, UINT nFields)
{
SendMessage(DNS_MASK_CTRL_SET, (WPARAM)pArray, (LPARAM)nFields);
}
void CDNSMaskCtrl::GetArray(DWORD* pArray, UINT nFields)
{
SendMessage(DNS_MASK_CTRL_GET, (WPARAM)pArray, (LPARAM)nFields);
}
void CDNSMaskCtrl::Clear(int nField)
{
SendMessage(DNS_MASK_CTRL_CLEAR, (WPARAM)nField, 0);
}
void CDNSMaskCtrl::SetAlertFunction( int (*lpfnAlert)(HWND, DWORD, DWORD, DWORD) )
{
SendMessage(DNS_MASK_CTRL_SET_ALERT, (WPARAM)lpfnAlert, 0);
}
void CDNSMaskCtrl::EnableField(int nField, BOOL bEnable)
{
SendMessage(DNS_MASK_CTRL_ENABLE_FIELD, (WPARAM)nField, (LPARAM)bEnable);
}
////////////////////////////////////////////////////////////////////////////
// CDNSIPv4Control
void CDNSIPv4Control::SetIPv4Val(DWORD x)
{
DWORD dwArr[4];
dwArr[3] = FIRST_IPADDRESS(x);
dwArr[2] = SECOND_IPADDRESS(x);
dwArr[1] = THIRD_IPADDRESS(x);
dwArr[0] = FOURTH_IPADDRESS(x);
SetArray(dwArr,4);
}
#define IP_FIELD_VALUE(x) ((x == FIELD_EMPTY) ? 0 : x)
void CDNSIPv4Control::GetIPv4Val(DWORD* pX)
{
DWORD dwArr[4];
GetArray(dwArr,4);
// got an array of DWORDS, if a field has value FIELD_EMPTY,
// need to assign a value of 0
*pX = static_cast<DWORD>(MAKEIPADDRESS(IP_FIELD_VALUE(dwArr[3]),
IP_FIELD_VALUE(dwArr[2]),
IP_FIELD_VALUE(dwArr[1]),
IP_FIELD_VALUE(dwArr[0])));
}
BOOL CDNSIPv4Control::IsEmpty()
{
DWORD dwArr[4];
GetArray(dwArr,4);
return ((dwArr[0] == FIELD_EMPTY) && (dwArr[1] == FIELD_EMPTY) &&
(dwArr[2] == FIELD_EMPTY) && (dwArr[3] == FIELD_EMPTY));
}
////////////////////////////////////////////////////////////////////////////
// CDNSIPv6Control
// REVIEW_MARCOC: need to do the same as the IPv4, with FIELD_EMPTY ==> zero
void CDNSIPv6Control::SetIPv6Val(IPV6_ADDRESS* pIpv6Address)
{
// assume the format is a WORD[8] array
DWORD dwArr[8]; // internal format, unpack
for(int k=0; k<8; k++)
{
dwArr[k] = 0x0000FFFF & REVERSE_WORD_BYTES(pIpv6Address->IP6Word[k]);
}
SetArray(dwArr,8);
}
void CDNSIPv6Control::GetIPv6Val(IPV6_ADDRESS* pIpv6Address)
{
// assume the format is a WORD[8] array
DWORD dwArr[8]; // internal format
GetArray(dwArr,8);
// got an array of DWORDS, to move into WORD[8]
// if a field has value FIELD_EMPTY, need to assign a value of 0
for(int k=0; k<8; k++)
{
if (dwArr[k] == FIELD_EMPTY)
pIpv6Address->IP6Word[k] = (WORD)0;
else
{
ASSERT(HIWORD(dwArr[k]) == 0x0);
pIpv6Address->IP6Word[k] = REVERSE_WORD_BYTES(LOWORD(dwArr[k]));
}
}
}
////////////////////////////////////////////////////////////////////////////
// CDNSTTLControl
void CDNSTTLControl::SetTTL(DWORD x)
{
DWORD dwArr[4];
// have to change from seconds into DDD:HH:MM:SS
DWORD dwMin = x/60;
dwArr[3] = x - dwMin*60; // # of seconds left
DWORD dwHours = dwMin/60;
dwArr[2] = dwMin - dwHours*60; // # of minutes left
DWORD dwDays = dwHours/24;
dwArr[1] = dwHours - dwDays*24; // # of hours left
dwArr[0] = dwDays; // # of days left
SetArray(dwArr,4);
}
void CDNSTTLControl::GetTTL(DWORD* pX)
{
// REVIEW_MARCOC: how do we deal with an empty field?
// do we force zero on it? Should we do it in the UI when exiting a field?
DWORD dwArr[4];
GetArray(dwArr,4);
// treat empty field as zero
for(int j=0; j<4;j++)
if (dwArr[j] == FIELD_EMPTY)
dwArr[j] = 0;
// have to convert back into seconds from DDD:HH:MM:SS
*pX = dwArr[0]*3600*24 // days
+ dwArr[1]*3600 // hours
+ dwArr[2]*60 // minutes
+ dwArr[3]; // seconds
// the max value is FFFFFFFF, that is 49710 days, 6 hours, 28 minutes and 15 seconds
// field validation allows to get to 49710 days, 23 hours, 59 minutes and 59 seconds
// causing wraparound
if (*pX < dwArr[0]*3600*24) // wrapped around
*pX = 0xFFFFFFFF; // max value
}
///////////////////////////////////////////////////////////////////////
// CDNSUnsignedIntEdit
BEGIN_MESSAGE_MAP(CDNSUnsignedIntEdit, CEdit)
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillFocus)
END_MESSAGE_MAP()
UINT _StrToUint(LPCTSTR sz)
{
LONG n = 0;
while (*sz != NULL)
{
LONG nPrev = n;
n = n*10 + (TCHAR)(*sz - TEXT('0') ); // assume it is a digit
if (nPrev > n || n > UINT_MAX)
return (UINT)-1; // wrapped
sz++;
}
return (UINT)n;
}
UINT _ForceToRange(UINT nVal, UINT nMin, UINT nMax)
{
if (nVal < nMin)
nVal = nMin;
else if( nVal > nMax)
nVal = nMax;
return nVal;
}
BOOL CDNSUnsignedIntEdit::SetVal(UINT nVal)
{
UINT n = _ForceToRange(nVal, m_nMin, m_nMax);
TCHAR szBuf[128];
wsprintf(szBuf, _T("%u"), n);
SetWindowText(szBuf);
return (nVal == n);
}
UINT CDNSUnsignedIntEdit::GetVal()
{
TCHAR szBuf[128] = {0};
GetWindowText(szBuf,128);
return _StrToUint(szBuf);
}
void CDNSUnsignedIntEdit::OnKillFocus()
{
UINT nVal = GetVal();
UINT n = _ForceToRange(nVal, m_nMin, m_nMax);
if ( (n != nVal) || (nVal == (UINT)-1) )
SetVal(n);
}
///////////////////////////////////////////////////////////////////////
// CDNSUpDownUnsignedIntEdit
BEGIN_MESSAGE_MAP(CDNSUpDownUnsignedIntEdit, CDNSUnsignedIntEdit)
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillFocus)
ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
END_MESSAGE_MAP()
void CDNSUpDownUnsignedIntEdit::OnKillFocus()
{
CDNSUnsignedIntEdit::OnKillFocus();
m_pEditGroup->SetButtonsState();
}
void CDNSUpDownUnsignedIntEdit::OnChange()
{
m_pEditGroup->OnEditChange();
}
///////////////////////////////////////////////////////////////////////
// CDNSUpDownButton
BEGIN_MESSAGE_MAP(CDNSUpDownButton, CButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
END_MESSAGE_MAP()
void CDNSUpDownButton::OnClicked()
{
m_pEditGroup->OnClicked(m_bUp);
}
///////////////////////////////////////////////////////////////////////
// CDNSUpDownUnsignedIntEditGroup
void CDNSUpDownUnsignedIntEditGroup::SetVal(UINT nVal)
{
m_edit.SetVal(nVal);
SetButtonsState();
}
UINT CDNSUpDownUnsignedIntEditGroup::GetVal()
{
return m_edit.GetVal();
}
void CDNSUpDownUnsignedIntEditGroup::OnClicked(BOOL bUp)
{
UINT n = m_edit.GetVal();
if (bUp)
{
m_edit.SetVal(++n);
}
else
{
m_edit.SetVal(--n);
}
SetButtonsState();
}
BOOL CDNSUpDownUnsignedIntEditGroup::Initialize(CWnd* pParentWnd, UINT nIDEdit,
UINT nIDBtnUp, UINT nIDBtnDown)
{
ASSERT(pParentWnd != NULL);
if (pParentWnd == NULL)
return FALSE;
m_edit.Set(this);
m_upBtn.Set(this,TRUE);
m_downBtn.Set(this,FALSE);
BOOL bRes = m_upBtn.SubclassDlgItem(nIDBtnUp, pParentWnd);
ASSERT(bRes);
bRes = m_downBtn.SubclassDlgItem(nIDBtnDown, pParentWnd);
ASSERT(bRes);
if (!bRes) return FALSE;
bRes = m_edit.SubclassDlgItem(nIDEdit, pParentWnd);
ASSERT(bRes);
return bRes;
}
void CDNSUpDownUnsignedIntEditGroup::SetButtonsState()
{
UINT n = m_edit.GetVal();
BOOL bUpEnabled = n < m_edit.GetMax();
BOOL bDownEnabled = n > m_edit.GetMin();
// have to see if buttos get disabled and move the focus accordingly
CWnd* pFocus = CWnd::GetFocus();
CWnd* pNewFocus = pFocus;
if ( (pFocus == &m_upBtn) && !bUpEnabled )
{
pNewFocus = &m_downBtn;
}
if ( (pFocus == &m_downBtn) && !bDownEnabled )
{
pNewFocus = &m_upBtn;
}
if ( ((pFocus == &m_downBtn) || (pFocus == &m_upBtn)) &&
!bDownEnabled && !bUpEnabled )
{
pNewFocus = &m_edit;
}
if (pNewFocus != pFocus)
pNewFocus->SetFocus();
m_upBtn.EnableWindow(bUpEnabled);
m_downBtn.EnableWindow(bDownEnabled);
}
/////////////////////////////////////////////////////////////////////////
// CDNSTimeIntervalEdit
BEGIN_MESSAGE_MAP(CDNSTimeIntervalEdit, CDNSUnsignedIntEdit)
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillFocus)
ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
END_MESSAGE_MAP()
void CDNSTimeIntervalEdit::OnKillFocus()
{
m_pEditGroup->OnEditKillFocus();
}
void CDNSTimeIntervalEdit::OnChange()
{
m_pEditGroup->OnEditChange();
}
/////////////////////////////////////////////////////////////////////////
// CDNSTimeUnitComboBox
BEGIN_MESSAGE_MAP(CDNSTimeUnitComboBox, CComboBox)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
END_MESSAGE_MAP()
void CDNSTimeUnitComboBox::OnSelChange()
{
m_pEditGroup->OnComboSelChange();
}
void CDNSTimeUnitComboBox::SetUnit(unitType u)
{
ASSERT((u >= sec) || (u <= days));
if (GetCount() - 1 < u)
SetCurSel(u - 2);
else
SetCurSel(u);
}
CDNSTimeUnitComboBox::unitType CDNSTimeUnitComboBox::GetUnit()
{
int n = GetCurSel();
unitType u = (unitType)n;
ASSERT((u >= sec) || (u <= days));
return u;
}
BOOL CDNSTimeUnitComboBox::LoadStrings(UINT nIDUnitsString, UINT nMaxAddCount)
{
return LoadStringsToComboBox(_Module.GetModuleInstance(),
this, nIDUnitsString, 256, nMaxAddCount);
}
//////////////////////////////////////////////////////////////////////////
// CDNSTimeIntervalEditGroup
CDNSTimeIntervalEditGroup::CDNSTimeIntervalEditGroup(UINT nMinVal, UINT nMaxVal)
{
m_nMinVal = nMinVal;
m_nMaxVal = nMaxVal;
InitRangeInfo();
}
void CDNSTimeIntervalEditGroup::InitRangeInfo()
{
static UINT _secondsCount[4] =
{ 1, 60, 3600, 3600*24 }; // # of secods in a sec, min, hour, day
for (UINT k=0; k<4; k++)
{
if (m_nMinVal == 0)
{
m_rangeInfoArr[k].m_nMinVal = 0;
}
else
{
m_rangeInfoArr[k].m_nMinVal = m_nMinVal/_secondsCount[k];
if (k > 0)
m_rangeInfoArr[k].m_nMinVal++;
}
m_rangeInfoArr[k].m_nMaxVal = m_nMaxVal/_secondsCount[k];
if (m_rangeInfoArr[k].m_nMaxVal >= m_rangeInfoArr[k].m_nMinVal)
m_nRangeCount = k + 1;
}
}
BOOL CDNSTimeIntervalEditGroup::Initialize(CWnd* pParentWnd, UINT nIDEdit,
UINT nIDCombo, UINT nIDComboUnitsString)
{
ASSERT(pParentWnd != NULL);
if (pParentWnd == NULL)
return FALSE;
m_edit.Set(this);
m_timeUnitCombo.Set(this);
BOOL bRes = m_edit.SubclassDlgItem(nIDEdit, pParentWnd);
ASSERT(bRes);
if (!bRes) return FALSE;
bRes = m_timeUnitCombo.SubclassDlgItem(nIDCombo, pParentWnd);
ASSERT(bRes);
if (!bRes) return FALSE;
bRes = m_timeUnitCombo.LoadStrings(nIDComboUnitsString, m_nRangeCount);
return bRes;
}
void CDNSTimeIntervalEditGroup::SetVal(UINT nVal)
{
// set default values
nVal = _ForceToRange(nVal, m_nMinVal, m_nMaxVal);
UINT nMax = (UINT)-1;
CDNSTimeUnitComboBox::unitType u = CDNSTimeUnitComboBox::sec;
// select the best unit of measurement (i.e. no truncation)
if ((nVal/60)*60 == nVal)
{
// can promote to minutes
u = CDNSTimeUnitComboBox::min;
nMax = nMax/60;
nVal = nVal/60;
if ((nVal/60)*60 == nVal)
{
// can promote to hours
u = CDNSTimeUnitComboBox::hrs;
nMax = nMax/60;
nVal = nVal/60;
if ((nVal/24)*24 == nVal)
{
// can promote to days
u = CDNSTimeUnitComboBox::days;
nMax = nMax/24;
nVal = nVal/24;
}
}
}
m_timeUnitCombo.SetUnit(u);
m_edit.SetRange(0,nMax);
m_edit.SetVal(nVal);
}
UINT CDNSTimeIntervalEditGroup::GetVal()
{
UINT nVal = m_edit.GetVal();
CDNSTimeUnitComboBox::unitType u = m_timeUnitCombo.GetUnit();
//
// the value must always to be in seconds
//
if (u != CDNSTimeUnitComboBox::sec)
{
switch(u)
{
case CDNSTimeUnitComboBox::min:
nVal *= 60;
break;
case CDNSTimeUnitComboBox::hrs:
nVal *= 3600;
break;
case CDNSTimeUnitComboBox::days:
nVal *= (3600*24);
break;
default:
ASSERT(FALSE);
}
}
if (nVal < m_nMinVal ||
nVal > m_nMaxVal)
{
UINT nRangeVal = _ForceToRange(nVal, m_nMinVal, m_nMaxVal);
SetVal(nRangeVal);
nVal = nRangeVal;
}
ASSERT(nVal >= m_nMinVal && nVal <= m_nMaxVal);
return nVal;
}
void CDNSTimeIntervalEditGroup::OnEditKillFocus()
{
UINT nVal = m_edit.GetVal();
CDNSTimeUnitComboBox::unitType u = m_timeUnitCombo.GetUnit();
//
// the value must always to be in seconds
//
if (u != CDNSTimeUnitComboBox::sec)
{
switch(u)
{
case CDNSTimeUnitComboBox::min:
nVal *= 60;
break;
case CDNSTimeUnitComboBox::hrs:
nVal *= 3600;
break;
case CDNSTimeUnitComboBox::days:
nVal *= (3600*24);
break;
default:
ASSERT(FALSE);
}
}
UINT nRangeVal = _ForceToRange(nVal, m_nMinVal, m_nMaxVal);
if (nRangeVal != nVal)
{
SetVal(nRangeVal);
}
}
void CDNSTimeIntervalEditGroup::OnComboSelChange()
{
CDNSTimeUnitComboBox::unitType u = m_timeUnitCombo.GetUnit();
// have to adjust the range
UINT nVal = m_edit.GetVal();
UINT nMax = (UINT)-1;
// have to adjust the range
switch(u)
{
case CDNSTimeUnitComboBox::sec:
break;
case CDNSTimeUnitComboBox::min:
nMax /= 60;
break;
case CDNSTimeUnitComboBox::hrs:
nMax /= 3600;
break;
case CDNSTimeUnitComboBox::days:
nMax /= (3600*24);
break;
default:
ASSERT(FALSE);
}
//m_edit.SetRange(0,nMax);
UINT k = (UINT)u;
m_edit.SetRange(m_rangeInfoArr[k].m_nMinVal, m_rangeInfoArr[k].m_nMaxVal);
nVal = _ForceToRange(nVal, m_rangeInfoArr[k].m_nMinVal, m_rangeInfoArr[k].m_nMaxVal);
m_edit.SetVal(nVal);
OnEditChange();
}
void CDNSTimeIntervalEditGroup::EnableUI(BOOL bEnable)
{
m_edit.EnableWindow(bEnable);
m_timeUnitCombo.EnableWindow(bEnable);
}
//////////////////////////////////////////////////////////////////////////
// CDNSManageControlTextHelper
CDNSManageControlTextHelper::CDNSManageControlTextHelper(int nStates)
{
m_nID = 0;
m_pParentWnd = NULL;
ASSERT(nStates > 1);
m_nStates = nStates;
m_lpszText = NULL;
m_lpszArr = (LPWSTR*)malloc(sizeof(LPWSTR*)*m_nStates);
if (m_lpszArr != NULL)
{
memset(m_lpszArr, 0x0, sizeof(LPWSTR*)*m_nStates);
}
}
CDNSManageControlTextHelper::~CDNSManageControlTextHelper()
{
free(m_lpszArr);
if (m_lpszText != NULL)
free(m_lpszText);
}
BOOL CDNSManageControlTextHelper::Init(CWnd* pParentWnd, UINT nID, UINT* nStrArray)
{
ASSERT(m_pParentWnd == NULL);
ASSERT(pParentWnd != NULL);
m_pParentWnd = pParentWnd;
m_nID = nID;
CWnd* pWnd = m_pParentWnd->GetDlgItem(m_nID);
if (pWnd == NULL)
return FALSE;
// get the text out of the window
int nLen = pWnd->GetWindowTextLength();
ASSERT(m_lpszText == NULL);
m_lpszText = (WCHAR*)malloc(sizeof(WCHAR)*(nLen+1));
if (m_lpszText != NULL)
{
pWnd->GetWindowText(m_lpszText, nLen+1);
}
else
{
return FALSE;
}
ASSERT(m_lpszText != NULL);
//
// get the text for the window
//
int nSuccessEntries;
LoadStringArrayFromResource(m_lpszArr, nStrArray, m_nStates, &nSuccessEntries);
ASSERT(nSuccessEntries == m_nStates);
return TRUE;
}
BOOL CDNSManageControlTextHelper::Init(CWnd* pParentWnd, UINT nID)
{
ASSERT(m_pParentWnd == NULL);
ASSERT(pParentWnd != NULL);
m_pParentWnd = pParentWnd;
m_nID = nID;
CWnd* pWnd = m_pParentWnd->GetDlgItem(m_nID);
if (pWnd == NULL)
return FALSE;
//
// get the text out of the window
//
int nLen = pWnd->GetWindowTextLength();
ASSERT(m_lpszText == NULL);
m_lpszText = (WCHAR*)malloc(sizeof(WCHAR)*(nLen+1));
if (m_lpszText != NULL)
{
pWnd->GetWindowText(m_lpszText, nLen+1);
}
else
{
return FALSE;
}
ASSERT(m_lpszText != NULL);
//
// get the text for the window
//
UINT nSuccessEntries;
ParseNewLineSeparatedString(m_lpszText, m_lpszArr, &nSuccessEntries);
ASSERT(nSuccessEntries == (UINT)m_nStates);
return TRUE;
}
void CDNSManageControlTextHelper::SetStateX(int nIndex)
{
CWnd* pWnd = m_pParentWnd->GetDlgItem(m_nID);
ASSERT(pWnd != NULL);
ASSERT( (nIndex >0) || (nIndex < m_nStates));
pWnd->SetWindowText(m_lpszArr[nIndex]);
}
//////////////////////////////////////////////////////////////////////////
// CDNSToggleTextControlHelper
CDNSToggleTextControlHelper::CDNSToggleTextControlHelper()
: CDNSManageControlTextHelper(2)
{
}
///////////////////////////////////////////////////////////////////////////
// CDNSManageButtonTextHelper
CDNSManageButtonTextHelper::CDNSManageButtonTextHelper(int nStates)
{
m_nID = 0;
m_pParentWnd = NULL;
m_nStates = nStates;
m_lpszText = NULL;
m_lpszArr = (LPWSTR*)malloc(sizeof(LPWSTR*)*m_nStates);
if (m_lpszArr != NULL)
{
memset(m_lpszArr, 0x0, sizeof(LPWSTR*)*m_nStates);
}
}
CDNSManageButtonTextHelper::~CDNSManageButtonTextHelper()
{
for (int k = 0; k < m_nStates; k++)
{
if (m_lpszArr[k] != NULL)
free(m_lpszArr[k]);
}
free(m_lpszArr);
}
void CDNSManageButtonTextHelper::SetStateX(int nIndex)
{
CWnd* pWnd = m_pParentWnd->GetDlgItem(m_nID);
ASSERT(pWnd != NULL);
ASSERT( (nIndex >0) || (nIndex < m_nStates));
pWnd->SetWindowText(m_lpszArr[nIndex]);
}
BOOL CDNSManageButtonTextHelper::Init(CWnd* pParentWnd, UINT nButtonID, UINT* nStrArray)
{
ASSERT(m_pParentWnd == NULL);
ASSERT(pParentWnd != NULL);
m_pParentWnd = pParentWnd;
m_nID = nButtonID;
CWnd* pWnd = m_pParentWnd->GetDlgItem(m_nID);
if (pWnd == NULL)
return FALSE;
// get the text for the window
int nSuccessEntries;
LoadStringArrayFromResource(m_lpszArr, nStrArray, m_nStates, &nSuccessEntries);
ASSERT(nSuccessEntries == m_nStates);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
// CDNSButtonToggleTextHelper
CDNSButtonToggleTextHelper::CDNSButtonToggleTextHelper()
: CDNSManageButtonTextHelper(2)
{
}
/////////////////////////////////////////////////////////////////////////////
// CDlgWorkerThread
CDlgWorkerThread::CDlgWorkerThread()
{
m_dwErr = 0x0;
}
BOOL CDlgWorkerThread::Start(CLongOperationDialog* pDlg)
{
ASSERT(pDlg != NULL);
HWND hWnd = pDlg->GetSafeHwnd();
return CWorkerThread::Start(hWnd);
}
BOOL CDlgWorkerThread::PostMessageToDlg()
{
return PostMessageToWnd(CLongOperationDialog::s_nNotificationMessage,
(WPARAM)0, (LPARAM)0);
}
int CDlgWorkerThread::Run()
{
// do the stuff
OnDoAction();
VERIFY(PostMessageToDlg());
WaitForExitAcknowledge();
//TRACE(_T("exiting\n"));
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CLongOperationDialog dialog
UINT CLongOperationDialog::s_nNotificationMessage = WM_USER + 100;
CLongOperationDialog::CLongOperationDialog(CDlgWorkerThread* pThreadObj,
CWnd* pParentWnd,
UINT nAviID)
: CDialog(IDD_SEARCHING_DIALOG, pParentWnd)
{
ASSERT(pThreadObj != NULL);
m_bAbandoned = TRUE;
m_pThreadObj = pThreadObj;
m_nAviID = nAviID;
m_bExecuteNoUI = FALSE;
}
CLongOperationDialog::~CLongOperationDialog()
{
if(m_pThreadObj != NULL)
{
delete m_pThreadObj;
m_pThreadObj = NULL;
}
}
BOOL CLongOperationDialog::LoadTitleString(UINT nID)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return m_szTitle.LoadString(nID);
}
BEGIN_MESSAGE_MAP(CLongOperationDialog, CDialog)
ON_MESSAGE( CLongOperationDialog::s_nNotificationMessage, OnNotificationMessage )
END_MESSAGE_MAP()
afx_msg LONG CLongOperationDialog::OnNotificationMessage( WPARAM, LPARAM)
{
TRACE(_T("CLongOperationDialog::OnNotificationMessage()\n"));
ASSERT(m_pThreadObj != NULL);
if (m_pThreadObj != NULL)
{
m_pThreadObj->AcknowledgeExiting();
VERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(m_pThreadObj->m_hThread,INFINITE));
m_bAbandoned = FALSE;
PostMessage(WM_CLOSE,0,0);
}
return 0;
}
BOOL CLongOperationDialog::OnInitDialog()
{
TRACE(_T("CLongOperationDialog::OnInitDialog()\n"));
CDialog::OnInitDialog();
if (!m_szTitle.IsEmpty())
SetWindowText(m_szTitle);
// load auto play AVI file if needed
if (m_nAviID != -1)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CAnimateCtrl* pAnimate = (CAnimateCtrl*)GetDlgItem(IDC_SEARCH_ANIMATE);
VERIFY(pAnimate->Open(m_nAviID));
}
// spawn worker thread
GetThreadObj()->Start(this);
return TRUE;
}
void CLongOperationDialog::OnCancel()
{
TRACE(_T("CLongOperationDialog::OnCancel()\n"));
if (m_bAbandoned)
{
m_pThreadObj->Abandon();
m_pThreadObj = NULL;
}
CDialog::OnCancel();
}
//////////////////////////////////////////////////////////
// CNodeEnumerationThread
CNodeEnumerationThread::CNodeEnumerationThread(CComponentDataObject* pComponentDataObject,
CMTContainerNode* pNode)
{
m_pSink = new CNotificationSinkEvent;
ASSERT(m_pSink != NULL);
m_pNode = pNode;
m_pComponentDataObject = pComponentDataObject;
m_pComponentDataObject->GetNotificationSinkTable()->Advise(m_pSink);
}
CNodeEnumerationThread::~CNodeEnumerationThread()
{
if (m_pComponentDataObject != NULL)
m_pComponentDataObject->GetNotificationSinkTable()->Unadvise(m_pSink);
delete m_pSink;
}
void CNodeEnumerationThread::OnDoAction()
{
TRACE(_T("CNodeEnumerationThread::OnDoAction() before Wait\n"));
ASSERT(m_pSink != NULL);
VERIFY(m_pComponentDataObject->PostForceEnumeration(m_pNode));
m_pSink->Wait();
TRACE(_T("CNodeEnumerationThread::OnDoAction() after Wait\n"));
}
void CNodeEnumerationThread::OnAbandon()
{
ASSERT(m_pComponentDataObject != NULL);
m_pComponentDataObject->GetNotificationSinkTable()->Unadvise(m_pSink);
m_pComponentDataObject = NULL;
}
//////////////////////////////////////////////////////////
// CArrayCheckListBox
BOOL CArrayCheckListBox::Initialize(UINT nCtrlID, UINT nStringID, CWnd* pParentWnd)
{
if (!SubclassDlgItem(nCtrlID, pParentWnd))
return FALSE;
SetCheckStyle(BS_AUTOCHECKBOX);
CString szBuf;
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!szBuf.LoadString(nStringID))
return FALSE;
}
LPWSTR* lpszArr = (LPWSTR*)malloc(sizeof(LPWSTR*)*m_nArrSize);
if (!lpszArr)
{
return FALSE;
}
UINT nArrEntries;
ParseNewLineSeparatedString(szBuf.GetBuffer(1),lpszArr, &nArrEntries);
szBuf.ReleaseBuffer();
ASSERT(nArrEntries == m_nArrSize);
for (UINT k=0; k<nArrEntries; k++)
AddString(lpszArr[k]);
if (lpszArr)
{
free(lpszArr);
lpszArr = 0;
}
return TRUE;
}
void CArrayCheckListBox::SetValue(DWORD dw)
{
for (UINT i=0; i< m_nArrSize; i++)
SetCheck(i, (dw & m_dwMaskArr[i]) != 0);
}
DWORD CArrayCheckListBox::GetValue()
{
DWORD dw = 0;
for (UINT i=0; i< m_nArrSize; i++)
dw |= GetCheck(i) ? m_dwMaskArr[i] : 0;
return dw;
}
void CArrayCheckListBox::SetArrValue(DWORD* dwArr, UINT nArrSize)
{
ASSERT(nArrSize <= m_nArrSize);
for (UINT i=0; i< nArrSize; i++)
SetCheck(i, dwArr[i] != 0);
}
void CArrayCheckListBox::GetArrValue(DWORD* dwArr, UINT nArrSize)
{
ASSERT(nArrSize <= m_nArrSize);
for (UINT i=0; i< m_nArrSize; i++)
dwArr[i] = GetCheck(i) != 0;
}
/*
//////////////////////////////////////////////////////////
// CDNSNameEditField
void CDNSNameEditField::SetReadOnly(BOOL bReadOnly)
{
// toggle the tabstop flag
LONG currStyle = ::GetWindowLong(m_edit.m_hWnd, GWL_STYLE);
LONG newStyle = currStyle;
if (bReadOnly)
newStyle &= ~WS_TABSTOP;
else
newStyle |= WS_TABSTOP;
if (newStyle != currStyle) {
::SetWindowLong(m_edit.m_hWnd, GWL_STYLE, newStyle);
}
// toggle the read only state
m_edit.SetReadOnly(bReadOnly);
}
//////////////////////////////////////////////////////////
// CDNSNameEditField::CDNSNameEditBox
BEGIN_MESSAGE_MAP(CDNSNameEditField::CDNSNameEditBox, CEdit)
ON_CONTROL_REFLECT(EN_UPDATE, CDNSNameEditField::CDNSNameEditBox::OnUpdate)
END_MESSAGE_MAP()
void CDNSNameEditField::CDNSNameEditBox::OnUpdate()
{
if (m_bUpdatePending)
return; // avoid infinite loop
GetWindowText(m_szScratchBuffer);
TRACE(_T("OnUpdate() Text = <%s>\n"), (LPCWSTR)m_szScratchBuffer);
DNS_STATUS errName = 0;
int nScratchBufferLen = m_szScratchBuffer.GetLength();
int nScratchBufferUTF8Len = UTF8StringLen(m_szScratchBuffer);
// validate max length
if ((m_nTextLimit >= 0) && (nScratchBufferUTF8Len > m_nTextLimit))
{
errName = -1;
}
// validate no dots
if ((errName == 0) && (m_dwFlags & DNS_NAME_EDIT_FIELD_NODOTS))
{
errName = m_szScratchBuffer.Find(L'.') != -1;
}
if ((errName == 0) && ((m_dwFlags & DNS_NAME_EDIT_FIELD_NOVALIDATE) == 0))
{
errName = Validate(nScratchBufferLen);
}
if (errName != 0)
{
// bad stuff
m_bUpdatePending = TRUE;
int nStartChar, nEndChar;
GetSel(nStartChar,nEndChar);
SetWindowText(m_szCurrText);
SetSel(nStartChar-1,nEndChar-1);
m_bUpdatePending = FALSE;
}
else
{
// good stuff
m_szCurrText = m_szScratchBuffer;
m_nCurrTextLen = nScratchBufferLen;
m_nCurrUTF8TextLen = nScratchBufferUTF8Len;
}
}
DNS_STATUS CDNSNameEditField::CDNSNameEditBox::Validate(int nScratchBufferLen)
{
DNS_STATUS errName = 0;
if ((errName == 0) && (nScratchBufferLen > 0))
{
// check for wildcards records
int nFirstAsterisk = m_szScratchBuffer.Find(L'*');
if (m_dwFlags & DNS_NAME_EDIT_FIELD_NOWILDCARDS)
{
// wildcards not accepted
errName = (nFirstAsterisk != -1);
}
else
{
if (nFirstAsterisk >= 0) // found at least one
{
// string must be "*"
errName = !((nScratchBufferLen == 1) && (nFirstAsterisk == 0));
}
}
// validate name against RFC
LPCWSTR lpszName = (LPCWSTR)m_szScratchBuffer;
if ( (errName == 0) && (m_dwFlags & (DNS_NAME_EDIT_FIELD_NORFC | DNS_NAME_EDIT_FIELD_RFC)) )
{
errName = ::DnsValidateName_W(lpszName, DnsNameDomain);
TRACE(_T("::DnsValidateName_W(%ws) return %d.\n"), lpszName, errName);
if ((m_dwFlags & DNS_NAME_EDIT_FIELD_NORFC) && (errName == DNS_ERROR_NON_RFC_NAME))
{
// we relax RFC compliance
errName = 0;
}
else if ( (m_dwFlags & DNS_NAME_EDIT_FIELD_ALLOWNUMBERS) )
{
// Assume the name failed because it is all digits
BOOL bAllDigits = TRUE;
LPWSTR lpszBuf = (LPWSTR)(LPCWSTR)m_szScratchBuffer;
for (int idx = 0; idx < nScratchBufferLen; idx++)
{
if (!iswdigit(lpszBuf[idx]))
{
// If we run across something that isn't a digit then thats not why we failed.
bAllDigits = FALSE;
TRACE(_T("Not all the characters are digits but something is still wrong.\n"));
}
}
if (bAllDigits)
{
errName = 0;
}
}
}
}
TRACE(_T("CDNSNameEditField::CDNSNameEditBox::Validate returns %d.\n"), errName);
return errName;
}
*/
////////////////////////////////////////////////////////////////////////////
// CDNSZone_AgingDialog
BEGIN_MESSAGE_MAP(CDNSZone_AgingDialog, CHelpDialog)
ON_BN_CLICKED(IDC_SCAVENGING_ENABLED, OnCheckScavenge)
END_MESSAGE_MAP()
CDNSZone_AgingDialog::CDNSZone_AgingDialog(CPropertyPageHolderBase* pHolder, UINT nID, CComponentDataObject* pComponentData)
: CHelpDialog(nID, pComponentData)
{
m_pHolder = pHolder;
m_bDirty = FALSE;
m_bAdvancedView = FALSE;
m_bScavengeDirty = FALSE;
m_bNoRefreshDirty = FALSE;
m_bRefreshDirty = FALSE;
// m_bApplyAll = FALSE;
m_bADApplyAll = FALSE;
// m_bStandardApplyAll = FALSE;
m_dwDefaultRefreshInterval = 0;
m_dwDefaultNoRefreshInterval = 0;
m_bDefaultScavengingState = FALSE;
if (pComponentData != NULL)
{
m_pComponentData = pComponentData;
}
else
{
m_pComponentData = pHolder->GetComponentData();
}
}
BOOL CDNSZone_AgingDialog::OnInitDialog()
{
CHelpDialog::OnInitDialog();
if (m_pHolder != NULL)
m_pHolder->PushDialogHWnd(GetSafeHwnd());
m_refreshIntervalEditGroup.m_pPage = this;
m_norefreshIntervalEditGroup.m_pPage = this;
VERIFY(m_refreshIntervalEditGroup.Initialize(this,
IDC_REFR_INT_EDIT1, IDC_REFR_INT_COMBO1,IDS_TIME_AGING_INTERVAL_UNITS));
VERIFY(m_norefreshIntervalEditGroup.Initialize(this,
IDC_REFR_INT_EDIT2, IDC_REFR_INT_COMBO2,IDS_TIME_AGING_INTERVAL_UNITS));
SendDlgItemMessage(IDC_REFR_INT_EDIT1, EM_SETLIMITTEXT, (WPARAM)10, 0);
SendDlgItemMessage(IDC_REFR_INT_EDIT2, EM_SETLIMITTEXT, (WPARAM)10, 0);
SetUIData();
return TRUE;
}
void CDNSZone_AgingDialog::SetUIData()
{
m_refreshIntervalEditGroup.SetVal(m_dwRefreshInterval);
m_norefreshIntervalEditGroup.SetVal(m_dwNoRefreshInterval);
((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->SetCheck(m_fScavengingEnabled);
// Enable the time stamp if we are in advanced view and got here through the zone property pages
if (m_bAdvancedView && m_pHolder != NULL)
{
GetDlgItem(IDC_TIME_STAMP_STATIC1)->EnableWindow(TRUE);
GetDlgItem(IDC_TIME_STAMP_STATIC2)->EnableWindow(TRUE);
GetDlgItem(IDC_TIME_STAMP)->EnableWindow(TRUE);
GetDlgItem(IDC_TIME_STAMP_STATIC1)->ShowWindow(TRUE);
GetDlgItem(IDC_TIME_STAMP_STATIC2)->ShowWindow(TRUE);
GetDlgItem(IDC_TIME_STAMP)->ShowWindow(TRUE);
CString cstrDate;
GetTimeStampString(cstrDate);
GetDlgItem(IDC_TIME_STAMP)->SetWindowText(cstrDate);
}
else if (!m_bAdvancedView && m_pHolder != NULL)
{
GetDlgItem(IDC_TIME_STAMP_STATIC1)->EnableWindow(FALSE);
GetDlgItem(IDC_TIME_STAMP_STATIC2)->EnableWindow(FALSE);
GetDlgItem(IDC_TIME_STAMP)->EnableWindow(FALSE);
GetDlgItem(IDC_TIME_STAMP_STATIC1)->ShowWindow(FALSE);
GetDlgItem(IDC_TIME_STAMP_STATIC2)->ShowWindow(FALSE);
GetDlgItem(IDC_TIME_STAMP)->ShowWindow(FALSE);
((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->SetCheck(m_fScavengingEnabled);
}
}
void CDNSZone_AgingDialog::OnCheckScavenge()
{
m_bScavengeDirty = TRUE;
GetDlgItem(IDOK)->EnableWindow(TRUE);
}
void CDNSZone_AgingDialog::SetDirty()
{
m_bDirty = TRUE;
GetDlgItem(IDOK)->EnableWindow(TRUE);
}
void CDNSZone_AgingDialog::GetTimeStampString(CString& strref)
{
SYSTEMTIME sysUTimeStamp, sysLTimeStamp;
VERIFY(SUCCEEDED(Dns_SystemHrToSystemTime(m_dwScavengingStart, &sysUTimeStamp)));
if (!::SystemTimeToTzSpecificLocalTime(NULL, &sysUTimeStamp, &sysLTimeStamp))
return;
// Format the string with respect to locale
PTSTR ptszDate = NULL;
int cchDate = 0;
cchDate = GetDateFormat(LOCALE_USER_DEFAULT, 0 ,
&sysLTimeStamp, NULL,
ptszDate, 0);
ptszDate = (PTSTR)malloc(sizeof(TCHAR) * cchDate);
if (ptszDate == NULL)
{
strref = L"";
return;
}
if (GetDateFormat(LOCALE_USER_DEFAULT, 0,
&sysLTimeStamp, NULL,
ptszDate, cchDate))
{
strref = ptszDate;
}
else
{
strref = L"";
}
free(ptszDate);
PTSTR ptszTime = NULL;
cchDate = GetTimeFormat(LOCALE_USER_DEFAULT, 0 ,
&sysLTimeStamp, NULL,
ptszTime, 0);
ptszTime = (PTSTR)malloc(sizeof(TCHAR) * cchDate);
if (GetTimeFormat(LOCALE_USER_DEFAULT, 0,
&sysLTimeStamp, NULL,
ptszTime, cchDate))
{
strref += _T(" ") + CString(ptszTime);
}
else
{
strref += _T("");
}
free(ptszTime);
}
void CDNSZone_AgingDialog::OnOK()
{
if (m_pHolder != NULL)
m_pHolder->PopDialogHWnd();
if (m_pHolder == NULL)
{
if (0 != m_refreshIntervalEditGroup.GetVal())
{
if (m_dwRefreshInterval != m_refreshIntervalEditGroup.GetVal())
{
m_dwRefreshInterval = m_refreshIntervalEditGroup.GetVal();
m_bRefreshDirty = TRUE;
}
else
{
m_bRefreshDirty = FALSE;
}
}
else
{
DNSMessageBox(IDS_MSG_INVALID_REFRESH_INTERVAL);
return;
}
if (0 != m_norefreshIntervalEditGroup.GetVal())
{
if (m_dwNoRefreshInterval != m_norefreshIntervalEditGroup.GetVal())
{
m_dwNoRefreshInterval = m_norefreshIntervalEditGroup.GetVal();
m_bNoRefreshDirty = TRUE;
}
else
{
m_bNoRefreshDirty = FALSE;
}
}
else
{
DNSMessageBox(IDS_MSG_INVALID_NOREFRESH_INTERVAL);
return;
}
if (m_fScavengingEnabled != static_cast<DWORD>(((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->GetCheck()))
{
m_fScavengingEnabled = ((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->GetCheck();
m_bScavengeDirty = TRUE;
}
else
{
m_bScavengeDirty = FALSE;
}
CDNSServer_AgingConfirm dlg(this);
if (IDOK == dlg.DoModal())
{
CHelpDialog::OnOK();
}
else
{
m_bRefreshDirty = FALSE;
m_bNoRefreshDirty = FALSE;
m_bScavengeDirty = FALSE;
m_dwRefreshInterval = m_dwDefaultRefreshInterval;
m_dwNoRefreshInterval = m_dwDefaultNoRefreshInterval;
m_fScavengingEnabled = m_bDefaultScavengingState;
SetUIData();
}
}
else
{
BOOL bContinue = TRUE;
if (!((CDNSZoneNode*)m_pHolder->GetTreeNode())->IsDSIntegrated() &&
((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->GetCheck() &&
!m_fScavengingEnabled)
{
if (DNSMessageBox(IDS_MSG_FILE_WARNING_ZONE, MB_YESNO) == IDNO)
{
bContinue = FALSE;
}
}
if (bContinue)
{
if (0 != m_refreshIntervalEditGroup.GetVal())
{
if (m_dwRefreshInterval != m_refreshIntervalEditGroup.GetVal())
{
m_dwRefreshInterval = m_refreshIntervalEditGroup.GetVal();
m_bRefreshDirty = TRUE;
}
else
{
m_bRefreshDirty = FALSE;
}
}
else
{
DNSMessageBox(IDS_MSG_INVALID_REFRESH_INTERVAL);
return;
}
if (0 != m_norefreshIntervalEditGroup.GetVal())
{
if (m_dwNoRefreshInterval != m_norefreshIntervalEditGroup.GetVal())
{
m_dwNoRefreshInterval = m_norefreshIntervalEditGroup.GetVal();
m_bNoRefreshDirty = TRUE;
}
else
{
m_bNoRefreshDirty = FALSE;
}
}
else
{
DNSMessageBox(IDS_MSG_INVALID_NOREFRESH_INTERVAL);
return;
}
if (m_fScavengingEnabled != static_cast<DWORD>(((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->GetCheck()))
{
m_fScavengingEnabled = ((CButton*)GetDlgItem(IDC_SCAVENGING_ENABLED))->GetCheck();
m_bScavengeDirty = TRUE;
}
else
{
m_bScavengeDirty = FALSE;
}
}
CHelpDialog::OnOK();
}
}
void CDNSZone_AgingDialog::OnCancel()
{
if (m_pHolder != NULL)
m_pHolder->PopDialogHWnd();
CHelpDialog::OnCancel();
}
////////////////////////////////////////////////////////////////////////////
// CDNS_AGING_TimeIntervalEditGroup
void CDNS_AGING_TimeIntervalEditGroup::OnEditChange()
{
if (m_pPage != NULL)
m_pPage->SetDirty();
}
// REVIEW_JEFFJON : Both of these functions are some serious hacks and need to be fixed
// These hacks were put in to deal with a combo box that only has hours
// and days, instead of seconds, minutes, hours, and days.
void CDNS_AGING_TimeIntervalEditGroup::SetVal(UINT nVal)
{
// set default values
nVal = _ForceToRange(nVal, m_nMinVal, m_nMaxVal);
UINT nMax = (UINT)-1;
CDNSTimeUnitComboBox::unitType u = CDNSTimeUnitComboBox::hrs;
if ((nVal/24)*24 == nVal)
{
// can promote to days
u = CDNSTimeUnitComboBox::days;
nMax = nMax/24;
nVal = nVal/24;
}
m_timeUnitCombo.SetUnit(u);
m_edit.SetRange(0,nMax);
m_edit.SetVal(nVal);
}
UINT CDNS_AGING_TimeIntervalEditGroup::GetVal()
{
CDNSTimeUnitComboBox::unitType u = m_timeUnitCombo.GetUnit();
UINT nVal = m_edit.GetVal();
// the value must always to be in hours
if (u != CDNSTimeUnitComboBox::sec)
{
switch(u)
{
case CDNSTimeUnitComboBox::min:
nVal *= 24;
break;
default:
ASSERT(FALSE);
}
}
ASSERT(nVal >= m_nMinVal && nVal <= m_nMaxVal);
return nVal;
}
void CDNS_AGING_TimeIntervalEditGroup::InitRangeInfo()
{
static UINT _secondsCount[2] =
{ 1, 24 }; // # of hours in a hour, day
for (UINT k=0; k<2; k++)
{
if (m_nMinVal == 0)
{
m_rangeInfoArr[k].m_nMinVal = 0;
}
else
{
m_rangeInfoArr[k].m_nMinVal = m_nMinVal/_secondsCount[k];
if (k > 0)
m_rangeInfoArr[k].m_nMinVal++;
}
m_rangeInfoArr[k].m_nMaxVal = m_nMaxVal/_secondsCount[k];
if (m_rangeInfoArr[k].m_nMaxVal >= m_rangeInfoArr[k].m_nMinVal)
m_nRangeCount = k + 1;
}
}
void CDNS_SERVER_AGING_TimeIntervalEditGroup::OnEditChange()
{
if (m_pPage2 != NULL)
m_pPage2->SetDirty(TRUE);
}
////////////////////////////////////////////////////////////////////////////////////
// CDNSServer_AgingConfirm
BOOL CDNSServer_AgingConfirm::OnInitDialog()
{
CHelpDialog::OnInitDialog();
// Removed because we didn't want to expose the defaults for file based zones
// ((CButton*)GetDlgItem(IDC_CHECK_AD))->SetCheck(TRUE);
// ((CButton*)GetDlgItem(IDC_CHECK_AD))->EnableWindow(FALSE);
SetAgingUpdateValues();
return FALSE;
}
void CDNSServer_AgingConfirm::SetAgingUpdateValues()
{
CEdit* pcAgingProps = (CEdit*)GetDlgItem(IDC_EDIT_NEW_DEFAULTS);
ASSERT(pcAgingProps != NULL);
CString szScavengeFormat, szScavengeValue,
szRefreshFormat, szRefreshValue,
szNoRefreshFormat, szNoRefreshValue,
szTotalString;
if (m_pAgingDialog->m_bScavengeDirty)
{
CString szEnabled;
VERIFY(szScavengeFormat.LoadString(IDS_SERVER_SCAVENGE_FORMAT));
if (m_pAgingDialog->m_fScavengingEnabled)
{
VERIFY(szEnabled.LoadString(IDS_ENABLED));
}
else
{
VERIFY(szEnabled.LoadString(IDS_DISABLED));
}
szScavengeValue.Format(szScavengeFormat, szEnabled);
szTotalString += szScavengeValue + _T("\r\n");
}
if (m_pAgingDialog->m_bNoRefreshDirty)
{
CString szUnit;
VERIFY(szNoRefreshFormat.LoadString(IDS_SERVER_NO_REFRESH_FORMAT));
DWORD nVal = 0;
if (m_pAgingDialog->m_dwNoRefreshInterval % 24 == 0)
{
szUnit.LoadString(IDS_DAYS);
nVal = m_pAgingDialog->m_dwNoRefreshInterval / 24;
}
else
{
szUnit.LoadString(IDS_HOURS);
nVal = m_pAgingDialog->m_dwNoRefreshInterval;
}
szNoRefreshValue.Format(szNoRefreshFormat, nVal, szUnit);
szTotalString += szNoRefreshValue + _T("\r\n");
}
if (m_pAgingDialog->m_bRefreshDirty)
{
CString szUnit;
VERIFY(szRefreshFormat.LoadString(IDS_SERVER_REFRESH_FORMAT));
DWORD nVal = 0;
if (m_pAgingDialog->m_dwRefreshInterval % 24 == 0)
{
szUnit.LoadString(IDS_DAYS);
nVal = m_pAgingDialog->m_dwRefreshInterval / 24;
}
else
{
szUnit.LoadString(IDS_HOURS);
nVal = m_pAgingDialog->m_dwRefreshInterval;
}
szRefreshValue.Format(szRefreshFormat, nVal, szUnit);
szTotalString += szRefreshValue;
}
pcAgingProps->SetWindowText(szTotalString);
}
void CDNSServer_AgingConfirm::OnOK()
{
// Removed because we didn't want to expose the defaults for file based zones
/* if (((CButton*)GetDlgItem(IDC_CHECK_STANDARD))->GetCheck() && m_pAgingDialog->m_fScavengingEnabled)
{
if (DNSMessageBox(IDS_MSG_FILE_WARNING, MB_YESNO) == IDNO)
{
return;
}
}
*/
m_pAgingDialog->m_bADApplyAll = ((CButton*)GetDlgItem(IDC_CHECK_AD_APPLY_ALL))->GetCheck();
// Removed because we didn't want to expose the defaults for file based zones
// m_pAgingDialog->m_bADApplyAll = ((CButton*)GetDlgItem(IDC_CHECK_AD))->GetCheck();
// m_pAgingDialog->m_bStandardApplyAll = ((CButton*)GetDlgItem(IDC_CHECK_STANDARD))->GetCheck();
CHelpDialog::OnOK();
}
///////////////////////////////////////////////////////////////////////////////
BOOL
WINAPI
DNSTzSpecificLocalTimeToSystemTime(
LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
LPSYSTEMTIME lpLocalTime,
LPSYSTEMTIME lpUniversalTime
)
{
TIME_ZONE_INFORMATION TziData;
LPTIME_ZONE_INFORMATION Tzi;
RTL_TIME_ZONE_INFORMATION tzi;
LARGE_INTEGER TimeZoneBias;
LARGE_INTEGER NewTimeZoneBias;
LARGE_INTEGER LocalCustomBias;
LARGE_INTEGER StandardTime;
LARGE_INTEGER DaylightTime;
LARGE_INTEGER CurrentLocalTime;
LARGE_INTEGER ComputedUniversalTime;
ULONG CurrentTimeZoneId = 0xffffffff;
//
// Get the timezone information into a useful format
//
if ( !ARGUMENT_PRESENT(lpTimeZoneInformation) ) {
//
// Convert universal time to local time using current timezone info
//
if (GetTimeZoneInformation(&TziData) == TIME_ZONE_ID_INVALID) {
return FALSE;
}
Tzi = &TziData;
}
else {
Tzi = lpTimeZoneInformation;
}
tzi.Bias = Tzi->Bias;
tzi.StandardBias = Tzi->StandardBias;
tzi.DaylightBias = Tzi->DaylightBias;
RtlMoveMemory(&tzi.StandardName,&Tzi->StandardName,sizeof(tzi.StandardName));
RtlMoveMemory(&tzi.DaylightName,&Tzi->DaylightName,sizeof(tzi.DaylightName));
tzi.StandardStart.Year = Tzi->StandardDate.wYear ;
tzi.StandardStart.Month = Tzi->StandardDate.wMonth ;
tzi.StandardStart.Weekday = Tzi->StandardDate.wDayOfWeek ;
tzi.StandardStart.Day = Tzi->StandardDate.wDay ;
tzi.StandardStart.Hour = Tzi->StandardDate.wHour ;
tzi.StandardStart.Minute = Tzi->StandardDate.wMinute ;
tzi.StandardStart.Second = Tzi->StandardDate.wSecond ;
tzi.StandardStart.Milliseconds = Tzi->StandardDate.wMilliseconds;
tzi.DaylightStart.Year = Tzi->DaylightDate.wYear ;
tzi.DaylightStart.Month = Tzi->DaylightDate.wMonth ;
tzi.DaylightStart.Weekday = Tzi->DaylightDate.wDayOfWeek ;
tzi.DaylightStart.Day = Tzi->DaylightDate.wDay ;
tzi.DaylightStart.Hour = Tzi->DaylightDate.wHour ;
tzi.DaylightStart.Minute = Tzi->DaylightDate.wMinute ;
tzi.DaylightStart.Second = Tzi->DaylightDate.wSecond ;
tzi.DaylightStart.Milliseconds = Tzi->DaylightDate.wMilliseconds;
//
// convert the input local time to NT style time
//
if ( !SystemTimeToFileTime(lpLocalTime,(LPFILETIME)&CurrentLocalTime) ) {
return FALSE;
}
//
// Get the new timezone bias
//
NewTimeZoneBias.QuadPart = Int32x32To64(tzi.Bias*60, 10000000);
//
// Now see if we have stored cutover times
//
if ( tzi.StandardStart.Month && tzi.DaylightStart.Month ) {
//
// We have timezone cutover information. Compute the
// cutover dates and compute what our current bias
// is
//
if ( !RtlCutoverTimeToSystemTime(
&tzi.StandardStart,
&StandardTime,
&CurrentLocalTime,
TRUE
) ) {
return FALSE;
}
if ( !RtlCutoverTimeToSystemTime(
&tzi.DaylightStart,
&DaylightTime,
&CurrentLocalTime,
TRUE
) ) {
return FALSE;
}
//
// If daylight < standard, then time >= daylight and
// less than standard is daylight
//
if ( DaylightTime.QuadPart < StandardTime.QuadPart ) {
//
// If today is >= DaylightTime and < StandardTime, then
// We are in daylight savings time
//
if ( (CurrentLocalTime.QuadPart >= DaylightTime.QuadPart) &&
(CurrentLocalTime.QuadPart < StandardTime.QuadPart) ) {
CurrentTimeZoneId = TIME_ZONE_ID_DAYLIGHT;
}
else {
CurrentTimeZoneId = TIME_ZONE_ID_STANDARD;
}
}
else {
//
// If today is >= StandardTime and < DaylightTime, then
// We are in standard time
//
if ( (CurrentLocalTime.QuadPart >= StandardTime.QuadPart ) &&
(CurrentLocalTime.QuadPart < DaylightTime.QuadPart ) ) {
CurrentTimeZoneId = TIME_ZONE_ID_STANDARD;
}
else {
CurrentTimeZoneId = TIME_ZONE_ID_DAYLIGHT;
}
}
//
// At this point, we know our current timezone and the
// local time of the next cutover.
//
LocalCustomBias.QuadPart = Int32x32To64(
CurrentTimeZoneId == TIME_ZONE_ID_DAYLIGHT ?
tzi.DaylightBias*60 :
tzi.StandardBias*60, // Bias in seconds
10000000
);
TimeZoneBias.QuadPart = NewTimeZoneBias.QuadPart + LocalCustomBias.QuadPart;
}
else {
TimeZoneBias = NewTimeZoneBias;
}
ComputedUniversalTime.QuadPart = CurrentLocalTime.QuadPart + TimeZoneBias.QuadPart;
if ( !FileTimeToSystemTime((LPFILETIME)&ComputedUniversalTime,lpUniversalTime) ) {
return FALSE;
}
return TRUE;
}
LONGLONG
GetSystemTime64(
SYSTEMTIME* pSysTime
)
/*++
Function : GetLongSystemTime
Description:
Parameters :
Return : 0 on error, GetLastError for more
Remarks :
--*/
{
LONGLONG llTime=0;
LONGLONG llHigh=0;
FILETIME fileTime;
//
// No return checking cause we return 0 on error
//
SystemTimeToFileTime( pSysTime, &fileTime );
llTime = (LONGLONG) fileTime.dwLowDateTime;
llHigh = (LONGLONG) fileTime.dwHighDateTime;
llTime |= (llHigh << 32);
// this is 100ns blocks since 1601. Now convert to seconds
llTime = llTime / (10*1000*1000L);
return llTime;
}
/////////////////////////////////////////////////////////////////////////
BOOL LoadComboBoxFromTable(CComboBox* pComboBox, PCOMBOBOX_TABLE_ENTRY pTable)
{
BOOL bRet = TRUE;
if (pComboBox == NULL ||
pTable == NULL)
{
return FALSE;
}
PCOMBOBOX_TABLE_ENTRY pTableEntry = pTable;
while (pTableEntry->nComboStringID != 0)
{
CString szComboString;
if (!szComboString.LoadString(pTableEntry->nComboStringID))
{
bRet = FALSE;
break;
}
int idx = pComboBox->AddString(szComboString);
if (idx != CB_ERR)
{
pComboBox->SetItemData(idx, pTableEntry->dwComboData);
}
else
{
bRet = FALSE;
break;
}
pTableEntry++;
}
return bRet;
}
BOOL SetComboSelByData(CComboBox* pComboBox, DWORD dwData)
{
BOOL bRet = FALSE;
int iCount = pComboBox->GetCount();
for (int idx = 0; idx < iCount; idx++)
{
if (pComboBox->GetItemData(idx) == dwData)
{
pComboBox->SetCurSel(idx);
bRet = TRUE;
break;
}
}
return bRet;
}