Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1905 lines
72 KiB

// RRECORD.CPP
#include "common.h"
#define mskTraceLocalDebug 0x00010000
// Review: SIZE: use pointer * g_pResourceRecordDlgHandler
CResourceRecordDlgHandler g_ResourceRecordDlgHandler;
const char szArpa[] = ".in-addr.arpa";
/////////////////////////////////////////////////////////////////////////////
// CDnsRpcRecord()
//
// Construct a CDnsRpcRecord object from existing data.
// - NOTE: The object does not free none of the data; it simply
// make a copy of the pointers. The parent is therefore responsible
// of storing the data as well as freeing it when done.
//
CDnsRpcRecord::CDnsRpcRecord(
CDomainNode * pParentDomain, // Parent node of the record
const DNS_RPC_RECORD * pDnsRecord, // Actual record data
const char pszShortName[]) // Short name version of the record
{
Assert(pParentDomain != NULL);
Assert(pDnsRecord != NULL);
Assert(pszShortName != NULL);
IRRT iRRT = IrrtFromWrrt(pDnsRecord->wType);
Assert(iRRT != iRRT_Nil);
if (iRRT > iRRT_Generic && iRRT < iRRT_Max)
{
m_pszRecordType = IRRT_PchGetName(iRRT);
}
else
{
Trace1(mskTraceAlways, "\nResourceRecord - Unknown type [pDnsRecord->wType=0x%x].", pDnsRecord->wType);
m_pszRecordType = szNull; // Point to an empty string
}
m_pNextRecord = NULL;
m_pDnsRecord = pDnsRecord;
m_pszShortName = pszShortName;
DebugCode( m_pParentDomain = NULL; )
Attach(pParentDomain);
Assert(m_pParentDomain == pParentDomain);
} // CDnsRpcRecord::CDnsRpcRecord
/////////////////////////////////////////////////////////////////////////////
void CDnsRpcRecord::Attach(CDomainNode * pParentDomain)
{
CDnsRpcRecord * p;
CDnsRpcRecord * pPrev = NULL;
Assert(pParentDomain != NULL);
AssertSz(m_pParentDomain == NULL, "Record should not have a parent yet");
m_pParentDomain = pParentDomain;
p = m_pParentDomain->m_pDRR;
while (p) {
pPrev = p;
p = p->m_pNextRecord;
}
if (pPrev == NULL)
{
m_pParentDomain->m_pDRR = this;
}
else
{
pPrev->m_pNextRecord = this;
}
m_pNextRecord = NULL;
} // CDnsRpcRecord::Attach
/////////////////////////////////////////////////////////////////////////////
void CDnsRpcRecord::Detach()
{
Assert(m_pParentDomain != NULL);
Assert(m_pParentDomain->m_pDRR != NULL);
CDnsRpcRecord * p = m_pParentDomain->m_pDRR;
if (p == this)
{
m_pParentDomain->m_pDRR = m_pNextRecord;
}
else
{
CDnsRpcRecord * pPrev;
do
{
pPrev = p;
p = p->m_pNextRecord;
AssertSz(p != NULL, "End of list reached - p is not valid a child");
}
while (p != this);
Assert(pPrev->m_pNextRecord == this);
pPrev->m_pNextRecord = m_pNextRecord;
} // if...else
m_pNextRecord = NULL;
m_pParentDomain = NULL;
} // CDnsRpcRecord::Detach
/////////////////////////////////////////////////////////////////////////////
// GetFullNameA()
//
// Build the full DNS name of a record.
// The name is truncated to 255 characters
//
void CDnsRpcRecord::GetFullNameA(OUT char szFullName[], UINT cchBuffer) const
{
char szTemp[cchDnsNameMax2];
char szTemp2[cchDnsNameMax2];
int cch;
Assert(szFullName != NULL);
AssertSz(cchBuffer > DNS_MAX_NAME_LENGTH, "Buffer is too small for a full DNS name");
AssertSz(cchBuffer > DNS_MAX_NAME_LENGTH * 2, "Long name may overflow the buffer. Set buffer length to cchDnsNameMax2");
Assert(m_pParentDomain != NULL);
Assert(m_pszShortName != NULL);
if (m_pszShortName[0])
{
if(m_pDnsRecord->wType == DNS_RECORDTYPE_PTR) {
strcpy(szFullName, m_pszShortName);
} else {
if (m_pParentDomain->m_dwFlags & CDomainNode::mskfReverseMode ) {
strcpy(szTemp, m_pParentDomain->PchGetFullNameA());
::RevIpAddrOrder(m_pszShortName,szTemp2);
char * pchCount = szTemp2;
char * pchTemp;
while ((*pchCount != '.') && (pchCount - szTemp2 < 4)){
pchCount++;
}
if (*pchCount == '.') { //found the first octet
strncpy (szFullName, szTemp2,
pchCount - szTemp2 + 1);
pchTemp = szFullName + (pchCount - szTemp2 + 1);
strcpy (pchTemp, szTemp);
cch = strlen(szFullName) + 1;
} else { //this is a root reverse lookup zone
cch = 1 + wsprintfA(szFullName, "%s.%s", m_pszShortName,
szTemp);
}
} else {
const char * pszName = m_pParentDomain->PchGetFullNameA();
if ((m_pszShortName[strlen(m_pszShortName) - 1] == '.') ||
(pszName[0] == '.')){
wsprintfA(szFullName, "%s%s", m_pszShortName, pszName);
} else {
wsprintfA(szFullName, "%s.%s", m_pszShortName, pszName);
}
}
}
}
else
{
strcpy(szFullName, m_pParentDomain->PchGetFullNameA());
}
AssertSz(strlen(szFullName) < cchBuffer, "Buffer too small for DNS name");
ReportFSz3(strlen(szFullName) < DNS_MAX_NAME_LENGTH,
"DNS name '%s' is %d characters long. Name will be truncated to %d characters.",
szFullName, strlen(szFullName), DNS_MAX_NAME_LENGTH);
// Append a null terminator at the end of string
szFullName[DNS_MAX_NAME_LENGTH] = 0;
} // CDnsRpcRecord::GetFullNameA
const char * CDnsRpcRecord::PchGetSzData(INOUT char * pszInOutBuffer) const
{
Assert(m_pDnsRecord != NULL);
switch (m_pDnsRecord->wType)
{
case DNS_RECORDTYPE_A:
ConvertIpAddrToString(m_pDnsRecord->Data.A.ipAddress, OUT pszInOutBuffer);
return pszInOutBuffer;
case DNS_RECORDTYPE_SOA:
return m_pDnsRecord->Data.SOA.namePrimaryServer.achName;
case DNS_RECORDTYPE_MX:
case DNS_RECORDTYPE_AFSDB:
case DNS_RECORDTYPE_RT:
return m_pDnsRecord->Data.MX.nameExchange.achName;
case DNS_RECORDTYPE_TXT:
memcpy(pszInOutBuffer, &m_pDnsRecord->Data, m_pDnsRecord->Data.TXT.stringData.cchNameLength);
pszInOutBuffer[m_pDnsRecord->Data.TXT.stringData.cchNameLength] = 0;
return pszInOutBuffer;
case DNS_RECORDTYPE_PTR:
case DNS_RECORDTYPE_NS:
case DNS_RECORDTYPE_CNAME:
case DNS_RECORDTYPE_MB:
case DNS_RECORDTYPE_MD:
case DNS_RECORDTYPE_MF:
case DNS_RECORDTYPE_MG:
case DNS_RECORDTYPE_MR:
case DNS_RECORDTYPE_MINFO:
case DNS_RECORDTYPE_RP:
case DNS_RECORDTYPE_HINFO:
case DNS_RECORDTYPE_ISDN:
case DNS_RECORDTYPE_X25:
case DNS_RECORDTYPE_AAAA:
// This should include all the other single string records such as
// PTR, NS, CNAME, MB, MD, MF, MG, MR, MINFO, RP, HINFO, ISDN, X25, NULL
Assert(&m_pDnsRecord->Data.PTR.nameNode == &m_pDnsRecord->Data.MINFO.nameMailBox);
Assert(&m_pDnsRecord->Data.PTR.nameNode == &m_pDnsRecord->Data.HINFO.stringData);
return m_pDnsRecord->Data.PTR.nameNode.achName;
default:
return szNull; // Empty string
} // switch
} // CDnsRpcRecord::PchGetSzData
/////////////////////////////////////////////////////////////////////////////
// FRpcSetRecordData()
//
// Create and/or update record data with pDnsRecordNew.
// - Function check if content of pDnsRecordNew is different
// than original one. If so, do not update
// - If pDnsRecordNew points to a different location than
// the current resource record, the function will allocate
// memory and make its own copy of the record.
// Return FALSE if OOM or record could not be created.
//
BOOL CDnsRpcRecord::FRpcSetRecordData(IN const DNS_RPC_RECORD * pDnsRecordNew)
{
char szFullName[cchDnsNameMax2];
DNS_HANDLE hRecord;
BOOL OnlyTtlChanged = FALSE;
Assert(pDnsRecordNew != NULL);
Assert(m_pDnsRecord != NULL);
Assert(m_pParentDomain != NULL);
GetFullNameA(OUT szFullName, LENGTH(szFullName));
Trace3(m_pDnsRecord->wType != pDnsRecordNew->wType ? (mskTraceDNS | mskTraceInfo) : mskTraceNone,
"\nINFO: Record %s is changing its type from 0x%X to 0x%X",
szFullName, m_pDnsRecord->wType, pDnsRecordNew->wType);
if (m_pDnsRecord->hRecord != NULL &&
pDnsRecordNew->wDataLength == m_pDnsRecord->wDataLength &&
pDnsRecordNew->wType == m_pDnsRecord->wType)
{
// Check if both records have the same content
if (memcmp(&pDnsRecordNew->Data, &m_pDnsRecord->Data,
m_pDnsRecord->wDataLength) == sgnEqual)
{
if (pDnsRecordNew->dwTtlSeconds != m_pDnsRecord->dwTtlSeconds) {
// Ttl is the only difference, set the flag, and jump out
OnlyTtlChanged = TRUE;
goto TtlOnly;
}
DebugCode( IRRT iRRT = IrrtFromWrrt(m_pDnsRecord->wType); )
Trace2(mskTraceDNS,
"\nINFO: New %s record \"%s\" is identical to previous one. "
"No need to update record.",
iRRT == iRRT_Nil ? "???" : IRRT_PchGetName(iRRT), szFullName);
DbgPrintDnsRecord(mskTraceDNSDebug, m_pDnsRecord);
return TRUE;
}
} // if
TtlOnly:
hRecord = m_pDnsRecord->hRecord;
if (pDnsRecordNew != m_pDnsRecord)
{
// New record, so allocate memory to store it
BYTE * pbData = m_pParentDomain->PbAllocateRawNode(pDnsRecordNew->wRecordLength);
ReportFSz(pbData != NULL, "Out of memory");
if (pbData == NULL)
return FALSE;
// Make a copy of the content of the new record into the parent's memory
memcpy(pbData, pDnsRecordNew, pDnsRecordNew->wRecordLength);
((DNS_RPC_RECORD *)pbData)->hRecord = hRecord;
m_pDnsRecord = (DNS_RPC_RECORD *)pbData;
}
DNS_STATUS err;
CWaitCursor wait;
CWaitTimer sleep;
char szTemp[cchDnsNameMax2];
if (m_pDnsRecord->wType == DNS_TYPE_PTR) {
if ((m_pParentDomain) &&
(m_pParentDomain->m_dwFlags & CDomainNode::mskfReverseMode)) {
UINT cch = RevIpAddrOrder (szFullName, szTemp);
strcat (szTemp, szArpa);
} else {
strcpy (szTemp, szFullName);
}
} else {
strcpy (szTemp, szFullName);
}
if (OnlyTtlChanged) {
DNS_RPC_RECORD * pRecord;
pRecord = (DNS_RPC_RECORD *)m_pDnsRecord;
pRecord->dwFlags |= DNS_RPC_RECORD_FLAG_TTL_CHANGE;
}
StatusBar.SetTextPrintf(hRecord ?
IDS_STATUS_s_UPDATE_RECORD : IDS_STATUS_s_CREATE_RECORD, szFullName);
StatusBar.UpdateWindow();
Trace1(mskTraceDNS, "\nDnsUpdateRecord(%"_aS_")...", szFullName);
DbgPrintDnsRecord(mskTraceDNSDebug, m_pDnsRecord);
err = ::DnsUpdateRecord(
m_pParentDomain->PchGetServerNameA(), // Server name
NULL, // Zone handle (not used)
szTemp, // Node name
INOUT &hRecord, // Existing record handle (if any)
m_pDnsRecord->wRecordLength, // Record length
(BYTE *)m_pDnsRecord); // Record data
sleep.DoWait(1000);
if (err)
{
Trace3(mskTraceDNS, "\nERR: DnsUpdateRecord(%"_aS_") error code = 0x%08X (%d)",
szFullName, err, err);
DnsReportError(err);
if (err == DNS_WARNING_PTR_CREATE_FAILED) {
MsgBox (IDS_PTR_CREATE_FAILED, szCaptionApp, MB_OK);
} else {
if (err == DNS_ERROR_NODE_IS_CNAME) {
MsgBox (IDS_ERROR_NAME_IN_USE_CNAME, szCaptionApp, MB_OK);
} else if (err == DNS_ERROR_CNAME_COLLISION) {
MsgBox (IDS_ERROR_ALIAS_ALREADY_IN_USE, szCaptionApp, MB_OK);
} else if (err == DNS_ERROR_RECORD_ALREADY_EXISTS) {
MsgBox (IDS_ERROR_DUPLICATE, szCaptionApp, MB_OK);
} else {
MsgBoxPrintf (IDS_ERR_s_UNABLE_TO_REGISTER_RECORD, szCaptionApp, MB_OK, (UINT) szFullName);
}
StatusBar.SetText(IDS_READY);
return FALSE;
}
}
Assert(m_pDnsRecord != NULL);
AssertSz1(hRecord != NULL, "DnsUpdateRecord(%"_aS_") cannot return "
"err=ERROR_SUCCESS and hRecord=NULL", szFullName);
((DNS_RPC_RECORD *)m_pDnsRecord)->hRecord = hRecord;
StatusBar.SetText(IDS_READY);
return TRUE;
} // CDnsRpcRecord::FRpcSetRecordData
/////////////////////////////////////////////////////////////////////////////
// RpcDeleteRecord()
//
// Delete a resource record from its domain
// - Remove the item on the record listbox
//
void CDnsRpcRecord::RpcDeleteRecord()
{
char szFullName[cchDnsNameMax2];
Assert(m_pParentDomain != NULL);
Assert(m_pDnsRecord != NULL);
Assert(m_pDnsRecord->hRecord != NULL);
GetFullNameA(OUT szFullName, LENGTH(szFullName));
if (IDYES == MsgBoxPrintf(
IDS_MSG_s_DELETE_RECORD,
szCaptionApp,
MB_ICONQUESTION | MB_YESNOCANCEL,
szFullName))
{
DNS_STATUS err;
CWaitCursor wait;
StatusBar.SetTextPrintf(IDS_STATUS_s_DELETE_RECORD, szFullName);
StatusBar.UpdateWindow();
if (m_pDnsRecord->wType == DNS_TYPE_PTR) {
CZoneRootDomain * pRootZone = m_pParentDomain->PFindZoneRootDomainParent();
if (pRootZone->m_dwFlags & CDomainNode::mskfReverseMode) {
char szTemp[cchDnsNameMax];
RevIpAddrOrder (szFullName, szTemp);
strcpy (szFullName, szTemp);
strcat (szFullName, szArpa);
}
}
Trace1(mskTraceDNSVerbose, "\n - DnsDeleteRecord(%"_aS_")...", szFullName);
err = ::DnsDeleteRecord(
m_pParentDomain->PchGetServerNameA(), // Server name
szFullName, // Node name
m_pDnsRecord->hRecord); // Record handle
if (err)
{
Trace3(mskTraceDNS, "\nERR: DnsDeleteRecord(%"_aS_") error code = 0x%08X (%d)",
szFullName, err, err);
DnsReportError(err);
}
else
{
int iRecord = ListBox_FindItemData(DlgZoneHelper.m_hwndListBoxRecord, (LPARAM)this);
ReportFSz1(iRecord >= 0, "Unable to find item %s in listbox", szFullName);
LSendMessage(DlgZoneHelper.m_hwndListBoxRecord, LB_DELETESTRING, iRecord, 0);
Detach();
delete this;
}
StatusBar.SetText(IDS_READY);
} // if
} // CDnsRpcRecord::RpcDeleteRecord
/////////////////////////////////////////////////////////////////////////////
void CDnsRpcRecord::DlgProperties()
{
Assert(m_pParentDomain != NULL);
Assert(m_pDnsRecord != NULL);
Assert(m_pDnsRecord->hRecord != NULL);
CRecordWiz dlgRecordWiz;
dlgRecordWiz.DoProperties(this);
} // CDnsRpcRecord::DlgProperties
/////////////////////////////////////////////////////////////////////////////
void CDnsRpcRecord::DrawItem(DRAWITEMSTRUCT * pDIS)
{
char szT[cchDnsNameMax2];
const char * pch;
int cch;
RECT rcItem;
int x, cx;
int type;
char szSubtype[SHORT_STRING_LEN];
char szIPAddr [IP_ADDR_LEN];
const CDnsRpcRecord * pDRR;
const DNS_RPC_RECORD * pDnsRecord;
const HEADERITEMINFO * pHII;
Assert(pDIS);
Assert(IsWindow(pDIS->hwndItem));
rcItem = pDIS->rcItem;
if (pDIS->itemID < 0)
{
// Listbox is empty
Report(pDIS->itemID == -1);
goto DrawFocus;
}
if (pDIS->itemState & ODS_SELECTED)
{
SetBkColor(pDIS->hDC, clrHighlight);
SetTextColor(pDIS->hDC, clrHighlightText);
FillRect(pDIS->hDC, &rcItem, hbrHighlight);
}
else
{
SetBkColor(pDIS->hDC, clrWindow);
SetTextColor(pDIS->hDC, clrWindowText);
FillRect(pDIS->hDC, &rcItem, hbrWindow);
}
pDRR = (CDnsRpcRecord *)pDIS->itemData;
if ((pDRR == NULL) || (pDRR == (CDnsRpcRecord *)-1)) {
// This happens when the listbox is empty or
// when there is no selection
goto DrawFocus;
}
Assert(pDRR->m_pDnsRecord != NULL);
Assert(pDRR->m_pParentDomain != NULL);
Assert(pDRR->m_pszShortName != NULL);
Assert(pDRR->m_pszRecordType != NULL);
pDnsRecord = pDRR->m_pDnsRecord;
pHII = (HEADERITEMINFO *)GetWindowLong(pDIS->hwndItem, GWL_USERDATA);
AssertSz(pHII != NULL, "You must attach HEADERITEMINFO structure in GWL_USERDATA");
// Print Record Name
pch = pDRR->m_pszShortName;
if ((!*pch) || (pDnsRecord->wType == DNS_TYPE_NS))
{
// Empty Name, therefore use full name
// removed 5/15/96: pch = pDRR->m_pParentDomain->PchGetFullNameA();
pDRR->GetFullNameA (szT, cchDnsNameMax2);
pch = &szT[0];
}
#define cxLeftMargin 2
#define cxRightMargin 3
x = cxLeftMargin;
cx = pHII[0].cxItemCurrent;
rcItem.left = x;
rcItem.right = x + cx - (cxLeftMargin + cxRightMargin);
ExtTextOut(pDIS->hDC, rcItem.left, rcItem.top, ETO_CLIPPED, &rcItem,
pch, strlen(pch), NULL);
// Print the record type
pch = pDRR->m_pszRecordType;
if (!*pch)
{
// Empty Record Type, so print the type number instead
wsprintf(szT, _W"%u", pDnsRecord->wType);
pch = szT;
}
x += cx;
cx = pHII[1].cxItemCurrent;
rcItem.left = x;
rcItem.right = x + cx - (cxLeftMargin + cxRightMargin);
ExtTextOut(pDIS->hDC, rcItem.left, rcItem.top, ETO_CLIPPED, &rcItem,
pch, strlen(pch), NULL);
// Print the record data
x += cx;
cx = pHII[2].cxItemCurrent;
rcItem.left = x;
rcItem.right = x + cx - (cxLeftMargin + cxRightMargin);
switch (pDnsRecord->wType)
{
case DNS_RECORDTYPE_WINS: // print the IP Address
cch = ConvertIpAddrToString(pDnsRecord->Data.WINS.aipWinsServers[0],
OUT szT);
Assert(cch < LENGTH(szT));
pch = szT;
break;
case DNS_RECORDTYPE_NBSTAT:
pch = pDnsRecord->Data.NBSTAT.nameResultDomain.achName;
cch = pDnsRecord->Data.NBSTAT.nameResultDomain.cchNameLength - 1u;
break;
case DNS_RECORDTYPE_A: // IP Address
cch = ConvertIpAddrToString(pDnsRecord->Data.A.ipAddress, OUT szT);
Assert(cch < LENGTH(szT));
pch = szT;
break;
case DNS_RECORDTYPE_WKS:
cch = ConvertIpAddrToString(pDnsRecord->Data.WKS.ipAddress, OUT szIPAddr);
Assert(cch < LENGTH(szIPAddr));
cch = wsprintf(szT, _W"%"_aS_", %"_aS_"", szIPAddr,
(CHAR *)pDnsRecord->Data.WKS.bBitMask + 1u);
pch = szT;
break;
case DNS_RECORDTYPE_SOA:
pch = pDnsRecord->Data.SOA.namePrimaryServer.achName +
pDnsRecord->Data.SOA.namePrimaryServer.cchNameLength + 1;
Assert(*(pch - 1) == (int)strlen(pch) + 1);
cch = wsprintf(szT, _W"%"_aS_", %"_aS_"", pDnsRecord->Data.SOA.namePrimaryServer.achName, pch);
AssertSz(cch < LENGTH(szT), "Buffer overflow");
pch = szT;
break;
case DNS_RECORDTYPE_TXT:
{
UCHAR cChars = 0;
cch = 0;
pch = (char *)&pDnsRecord->Data;
while (pch - (char *)&pDnsRecord->Data < pDnsRecord->wDataLength)
{
if (pch != (char *)&pDnsRecord->Data) {
szT[cch++] = ',';
}
cChars = (UCHAR)*pch;
if (cch + cChars > cchDnsNameMax2) {
*(szT + cch) = '\0';
break;
}
memcpy(szT + cch, pch + 1, cChars);
cch += cChars;
pch += 1 + cChars;
} // while
pch = szT;
cch--;
break;
}
case DNS_RECORDTYPE_MR:
case DNS_RECORDTYPE_MB:
case DNS_RECORDTYPE_RP:
case DNS_RECORDTYPE_MINFO:
case DNS_RECORDTYPE_HINFO:
case DNS_RECORDTYPE_ISDN:
case DNS_RECORDTYPE_X25:
case DNS_RECORDTYPE_AAAA:
case DNS_RECORDTYPE_MG:
case DNS_RECORDTYPE_MD:
case DNS_RECORDTYPE_MF:
case DNS_RECORDTYPE_NS: // Name Server
case DNS_RECORDTYPE_PTR: // Pointer
case DNS_RECORDTYPE_CNAME: // Canonical Name
pch = pDnsRecord->Data.NS.nameNode.achName;
cch = pDnsRecord->Data.NS.nameNode.cchNameLength - 1u;
break;
case DNS_RECORDTYPE_RT:
case DNS_RECORDTYPE_MX:
cch = wsprintf(szT, _W"[%u]", pDnsRecord->Data.MX.wPreference);
TextOut(pDIS->hDC, rcItem.left, rcItem.top, szT, cch);
if (pDnsRecord->Data.MX.wPreference < 1000)
rcItem.left += 30;
else
rcItem.left += 40;
pch = pDnsRecord->Data.Mx.nameExchange.achName;
cch = pDnsRecord->Data.Mx.nameExchange.cchNameLength - 1u;
break;
case DNS_RECORDTYPE_AFSDB:
type = pDnsRecord->Data.AFSDB.wPreference;
if (type == 1) {
CchLoadString (IDS_AFSDB_AFS, szSubtype, sizeof (szSubtype));
}
else {
CchLoadString (IDS_AFSDB_DCE, szSubtype, sizeof (szSubtype));
}
cch = wsprintf(szT, _W"[%s]", szSubtype);
TextOut(pDIS->hDC, rcItem.left, rcItem.top, szT, cch);
rcItem.left += 30;
pch = pDnsRecord->Data.AFSDB.nameExchange.achName;
cch = pDnsRecord->Data.AFSDB.nameExchange.cchNameLength - 1u;
break;
default:
cch = RawDataToString((const BYTE *)&pDnsRecord->Data, pDnsRecord->wDataLength,
OUT szT, LENGTH(szT));
pch = szT;
} // switch
ExtTextOut(pDIS->hDC, rcItem.left, rcItem.top, ETO_CLIPPED, &rcItem,
pch, cch, NULL);
DrawFocus:
if (pDIS->itemState & ODS_FOCUS) {
DrawFocusRect(pDIS->hDC, &pDIS->rcItem);
}
} // CDnsRpcRecord::DrawItem
/////////////////////////////////////////////////////////////////////////////
// OnInitDialog()
//
// Initialize the dialog with either a specific record or a list of records.
// Array rgIrrtListBox must have iRRT_Nil as its last entry.
//
void CResourceRecordDlgHandler::OnInitDialog(
IN HWND hdlg,
IN const IRRT rgIrrtListBox[], // OPTIONAL: may be NULL
IN const DNS_RPC_RECORD * pDnsRecord) // OPTIONAL: may be NULL
{
TCHAR szT[64]; // Must be large enough for "%s Record"
RECT rc;
int i, j;
int cy, small_cy;
BOOL fSOAFound = FALSE;
Assert(IsWindow(hdlg));
AssertSz(rgIrrtListBox || pDnsRecord, "Only one of them can be NULL. Not both.");
// Check if more than one dialog share the same handler
Trace0(m_fInit ? mskTraceAlways : mskTraceNone,
"\nCResourceRecordDlgHandler seems to be already in use. Call Destroy() when done.");
DebugCode( m_fInit = TRUE; )
m_fSkipBugInEditControl = TRUE;
m_hdlg = hdlg;
m_hwndList = HGetDlgItem(hdlg, IDC_LIST_RECORDTYPE);
m_hwndStatic0 = HGetDlgItem(hdlg, IDC_STATIC0);
m_hwndStatic1 = HGetDlgItem(hdlg, IDC_STATIC1);
m_hwndStatic2 = HGetDlgItem(hdlg, IDC_STATIC_SERIALNUMBER);
m_hwndStatic3 = HGetDlgItem(hdlg, IDC_STATIC_REFRESHTIME);
m_hwndStatic4 = HGetDlgItem(hdlg, IDC_STATIC_RETRYTIME);
m_hwndEdit0 = HGetDlgItem(hdlg, IDC_EDIT0);
m_hwndEdit1 = HGetDlgItem(hdlg, IDC_EDIT1);
m_hwndEdit2 = HGetDlgItem(hdlg, IDC_EDIT_SERIALNUMBER);
m_hwndEdit3 = HGetDlgItem(hdlg, IDC_EDIT3);
m_hwndIpEdit1 = HGetDlgItem(hdlg, IDC_IPEDIT1);
m_hwndIpEdit2 = HGetDlgItem(hdlg, IDC_IPEDIT2);
m_hwndRadio1 = HGetDlgItem(hdlg, IDC_RADIO1);
m_hwndRadio2 = HGetDlgItem(hdlg, IDC_RADIO2);
m_hwndStaticTTL = HGetDlgItem(hdlg, IDC_STATIC_TTL);
m_hwndEditTTL = HGetDlgItem(hdlg, IDC_EDIT_TTL);
m_hwndSpinTTL = HGetDlgItem(hdlg, IDC_SPIN_TTL);
m_hwndComboTTL = HGetDlgItem(hdlg, IDC_COMBO_TTL);
GetChildRect(m_hwndEdit0, OUT &m_rcEdit0);
GetChildRect(m_hwndEdit1, OUT &m_rcEdit1);
GetChildRect(m_hwndEdit2, OUT &m_rcEdit2);
GetChildRect(m_hwndEdit3, OUT &m_rcEdit3);
GetChildRect(m_hwndStatic0, OUT &m_rcStatic0);
GetChildRect(m_hwndStatic1, OUT &m_rcStatic1);
GetChildRect(m_hwndStatic2, OUT &m_rcStatic2);
GetWindowRect(m_hwndIpEdit1, OUT &rc);
m_sizeStatic.cx = m_rcStatic0.right - m_rcStatic0.left;
m_sizeStatic.cy = m_rcStatic0.bottom - m_rcStatic0.top;
m_sizeEdit.cx = m_rcEdit0.right - m_rcEdit0.left;
m_sizeEdit.cy = m_rcEdit0.bottom - m_rcEdit0.top;
m_sizeIpEdit.cx = rc.right - rc.left;
m_sizeIpEdit.cy = rc.bottom - rc.top;
small_cy = (m_rcEdit1.top - m_rcEdit0.top);
cy = small_cy * 2;
MoveWindow(m_hwndIpEdit1, m_rcEdit0.left, m_rcEdit0.top,
m_sizeIpEdit.cx, m_sizeIpEdit.cy, FALSE);
MoveWindow(m_hwndIpEdit2, m_rcEdit0.left, m_rcEdit0.top + cy,
m_sizeIpEdit.cx, m_sizeIpEdit.cy, FALSE);
CheckDlgButton(m_hdlg, IDC_CHECK_CREATE_PTR_RECORD, TRUE);
m_wFlagsPrev = RRT_mskfShowEdit0 | RRT_mskfShowEdit1 | RRT_mskfShowEdit2;
m_wIdStringDescriptionPrev = 0;
m_iRRT = iRRT_Nil;
m_pCurrentDRR = NULL;
m_pParentDRR = NULL;
m_pParentDomain = NULL;;
m_fHostParent = FALSE;
m_hwndAutoFillPrev = NULL;
if (rgIrrtListBox == NULL)
{
//
// Existing record
//
Assert(pDnsRecord != NULL);
IRRT iRRT = IrrtFromWrrt(pDnsRecord->wType);
AssertSz(iRRT != iRRT_Nil, "Unknown record type [pDnsRecord->wType=0x%X] - Using generic record");
if (iRRT == iRRT_Nil) {
iRRT = iRRT_Generic;
}
if (rgRRTInfo[iRRT].wFlags == 0) {
iRRT = iRRT_Generic; // No flags, then treat this one as generic
}
wsprintf(szT, szRecordTypeFmt, IRRT_PchGetName(iRRT));
Assert(lstrlen(szT) < LENGTH(szT));
i = SendMessage(m_hwndList, LB_ADDSTRING, 0, (LPARAM)szT);
Report(i >= 0);
SendMessage(m_hwndList, LB_SETITEMDATA, i, iRRT);
if (iRRT == iRRT_SOA)
{
fSOAFound = TRUE;
for (i = IDC_EDIT_REFRESHTIME; i <= IDC_EDIT_MINIMUMTTL; i += 4)
SpinBox_SetSpinRange(HGetDlgItem(hdlg, i + 1), 0, SpinBox_wUpperRangeMax);
}
}
else
{
Assert(rgIrrtListBox != NULL);
for (const IRRT * piRRT = rgIrrtListBox; *piRRT != iRRT_Nil; piRRT++)
{
Assert(*piRRT < iRRT_Max);
wsprintf(szT, szRecordTypeFmt, IRRT_PchGetName(*piRRT));
Assert(lstrlen(szT) < LENGTH(szT));
i = SendMessage(m_hwndList, LB_ADDSTRING, 0, (LPARAM)szT);
Report(i >= 0);
SendMessage(m_hwndList, LB_SETITEMDATA, i, *piRRT);
if (*piRRT == iRRT_SOA)
{
fSOAFound = TRUE;
SetCtrlDWordValue(HGetDlgItem(m_hdlg, IDC_EDIT_SERIALNUMBER), 1);
const DWORD rgdwTimeValueDefaultSOA[] =
{
3 * dwTimeValueHours, // Refresh Time
1 * dwTimeValueHours, // Retry Time
3 * dwTimeValueDays, // Expire Time
1 * dwTimeValueDays, // Minimum TTL
};
for (i = IDC_EDIT_REFRESHTIME, j = 0; i <= IDC_EDIT_MINIMUMTTL; i += 4, j++)
{
EditCombo_SetTime(hdlg, i, i + 2, rgdwTimeValueDefaultSOA[j]);
SpinBox_SetSpinRange(HGetDlgItem(hdlg, i + 1), 0, SpinBox_wUpperRangeMax);
} // for
} // if
} // for
} // if...else
SpinBox_SetSpinRange(m_hwndSpinTTL, 0, SpinBox_wUpperRangeMax);
SendMessage(m_hwndList, LB_SETCURSEL, 0, 0);
if (!fSOAFound)
{
// Move the last static and edit controls
MoveWindow(m_hwndStatic2,
m_rcStatic0.left, m_rcStatic0.top + cy,
m_sizeStatic.cx, m_sizeStatic.cy, FALSE);
MoveWindow(m_hwndEdit2,
m_rcEdit0.left, m_rcEdit0.top + cy,
m_sizeEdit.cx, m_sizeEdit.cy, FALSE);
MoveWindow(m_hwndStatic3,
m_rcStatic1.left, m_rcStatic1.top + cy,
m_sizeStatic.cx, m_sizeStatic.cy, FALSE);
MoveWindow(m_hwndEdit3,
m_rcEdit1.left, m_rcEdit1.top + cy,
m_sizeEdit.cx, m_sizeEdit.cy, FALSE);
GetChildRect(m_hwndStatic2, OUT &m_rcStatic2);
MoveWindow(m_hwndStatic4,
m_rcStatic2.left, m_rcStatic2.top + cy,
m_sizeStatic.cx, m_sizeStatic.cy, FALSE);
// Clear the SS_RIGHT style
SetWindowLong(m_hwndStatic2, GWL_STYLE,
GetWindowLong(m_hwndStatic2, GWL_STYLE) & ~SS_RIGHT);
SetWindowLong(m_hwndStatic4, GWL_STYLE,
GetWindowLong(m_hwndStatic4, GWL_STYLE) & ~SS_RIGHT);
// move the radio buttons
GetChildRect(m_hwndEdit2, OUT &m_rcEdit2);
GetChildRect(m_hwndEdit3, OUT &m_rcEdit3);
MoveWindow(m_hwndRadio1,
m_rcEdit3.left, m_rcEdit3.top + small_cy,
m_sizeEdit.cx, m_sizeEdit.cy, FALSE);
MoveWindow(m_hwndRadio2,
m_rcEdit3.left, m_rcEdit3.top + (small_cy * 3)/2,
m_sizeEdit.cx, m_sizeEdit.cy, FALSE);
} // if
if (pDnsRecord != NULL) {
InitRecordData(pDnsRecord);
}
m_fSkipBugInEditControl = FALSE;
} // CResourceRecordDlgHandler::OnInitDialog
/////////////////////////////////////////////////////////////////////////////
// SetCurrentRecord()
//
// Initialize the handler for displaying the properties of a RR
//
void CResourceRecordDlgHandler::SetCurrentRecord(
CDnsRpcRecord * pCurrentDRR, // Current Resource Record
UINT idsCaptionExtra) // Optional String Id to concatenate to the caption (0 == no caption)
{
char szFullName[cchDnsNameMax2];
char szCaption[cchDnsNameMax2];
Assert(pCurrentDRR != NULL);
Assert(pCurrentDRR->m_pDnsRecord != NULL);
Assert(pCurrentDRR->m_pParentDomain != NULL);
Assert(pCurrentDRR->m_pParentDomain->m_pParentServer->FIsLocked());
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling SetCurrentRecord()");
m_fHostParent = TRUE;
m_pCurrentDRR = pCurrentDRR;
Assert(m_pParentDomain == NULL);
Assert(m_pParentDRR == NULL);
if (idsCaptionExtra != 0)
{
pCurrentDRR->GetFullNameA(OUT szFullName, LENGTH(szFullName));
LoadStringPrintf(IDS_s_PROPERTIES, OUT szCaption, LENGTH(szCaption), szFullName);
if (idsCaptionExtra != IDS_NONE)
{
CchLoadString(idsCaptionExtra, OUT szFullName, LENGTH(szFullName));
strcat(szCaption, szFullName);
}
Assert(strlen(szCaption) < LENGTH(szCaption));
FSetWindowText(m_hdlg, szCaption);
// if this is a PRT record, fill in the address, since it is
// not available at InitDialog time. it ugly, but it works :-)
if (m_pCurrentDRR->m_pDnsRecord->wType == DNS_RECORDTYPE_PTR) {
m_pCurrentDRR->GetFullNameA(szFullName,
LENGTH(szFullName));
Assert (strlen(szFullName) <= IP_ADDR_LEN);
strcpy (m_ipPTR_IpAddr, szFullName);
IpEdit_SetAddress(m_hwndIpEdit1,
ConvertStringToIpAddr(m_ipPTR_IpAddr));
}
} // if
} // CResourceRecordDlgHandler::SetCurrentRecord
/////////////////////////////////////////////////////////////////////////////
// SetParentDomain()
//
// Initialize the handler using a ResourceRecord as the DomainName.
//
void CResourceRecordDlgHandler::SetParentDomain(CDnsRpcRecord * pParentDRR)
{
Assert(pParentDRR != NULL);
Assert(pParentDRR->m_pDnsRecord != NULL);
Assert(pParentDRR->m_pParentDomain != NULL);
Assert(pParentDRR->m_pParentDomain->m_pParentServer->FIsLocked());
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling SetParentDomain()");
m_fHostParent = TRUE;
m_pParentDRR = pParentDRR;
Assert(m_pParentDomain == NULL);
Assert(m_pCurrentDRR == NULL);
SetWindowString(m_hdlg, IDS_NEWRESOURCERECORD);
EditCombo_SetTime(m_hdlg,
IDC_EDIT_TTL,
IDC_COMBO_TTL,
DNS_DEFAULT_TTL);
} // CResourceRecordDlgHandler::SetParentDomain
/////////////////////////////////////////////////////////////////////////////
// SetParentDomain()
//
// Initialize the handler using a DomainNode as the DomainName.
//
void CResourceRecordDlgHandler::SetParentDomain(CDomainNode * pParentDomain)
{
Assert(pParentDomain != NULL);
DebugCode( pParentDomain->AssertNodeValid(); )
Assert(pParentDomain->m_pParentServer->FIsLocked());
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling SetParentDomain()");
m_fHostParent = FALSE;
m_pParentDomain = pParentDomain;
Assert(m_pParentDRR == NULL);
Assert(m_pCurrentDRR == NULL);
SetWindowString(m_hdlg, IDS_NEWRESOURCERECORD);
CZoneRootDomain * pRootZone = m_pParentDomain->PFindZoneRootDomainParent();
if (pRootZone->m_pSOA != NULL) {
EditCombo_SetTime(m_hdlg,
IDC_EDIT_TTL,
IDC_COMBO_TTL,
pRootZone->m_pSOA->m_pDnsRecord->Data.SOA.dwMinimumTtl);
} else {
EditCombo_SetTime(m_hdlg,
IDC_EDIT_TTL,
IDC_COMBO_TTL,
DNS_DEFAULT_TTL);
}
} // CResourceRecordDlgHandler::SetParentDomain
/////////////////////////////////////////////////////////////////////////////
// OnUpdateControls()
//
// Show/hide controls according to the listbox selection.
// This function also set the text of the static controls.
//
//
void CResourceRecordDlgHandler::OnUpdateControls()
{
UINT iRRT;
WORD wFlags;
int i;
UINT wIdStringBase;
UINT wIdStringDescription;
UINT wIdStringStatic0;
UINT wIdStringStatic1;
UINT wIdStringStatic2;
UINT wIdStringStatic3;
UINT wIdStringStatic4;
UINT wIdStringRadio1;
UINT wIdStringRadio2;
if (m_fSkipBugInEditControl)
return;
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling OnUpdateControls()");
Assert(IsWindow(m_hwndList));
m_fSkipBugInEditControl = TRUE;
iRRT = ListBox_GetSelectedItemData(m_hwndList);
AssertSz(iRRT >= 0 && iRRT < iRRT_Max, "Possible mismatch/misuse of iRRT and wRRT");
wFlags = rgRRTInfo[iRRT].wFlags;
wIdStringBase = rgRRTInfo[iRRT].wIdString;
if (iRRT != m_iRRT && iRRT != iRRT_SOA)
{
// Find out which window will be auto filled
char * pch;
const char * pszAutoFill = NULL;
char szAutoFill[cchDnsNameMax2];
BOOL fAllowNameToShrink = FALSE;
HWND hwndAutoFill = m_hwndEdit0;
GarbageInit(szAutoFill, sizeof(szAutoFill));
if (m_iRRT != iRRT_Nil)
{
FSetWindowText(m_hwndEdit0, szNull);
FSetWindowText(m_hwndEdit1, szNull);
FSetWindowText(m_hwndEdit2, szNull);
FSetWindowText(m_hwndEdit3, szNull);
}
if (m_pCurrentDRR != NULL)
{
m_pCurrentDRR->GetFullNameA(szAutoFill, LENGTH(szAutoFill));
pszAutoFill = szAutoFill;
fAllowNameToShrink = TRUE;
}
else if (m_pParentDRR != NULL)
{
m_pParentDRR->GetFullNameA(szAutoFill, LENGTH(szAutoFill));
pszAutoFill = szAutoFill;
fAllowNameToShrink = TRUE;
}
else if (m_pParentDomain != NULL)
{
strcpy(szAutoFill, m_pParentDomain->PchGetFullNameA());
pszAutoFill = szAutoFill;
}
if (pszAutoFill != NULL)
{
if ((wFlags & RRT_mskfHasShortName) & fAllowNameToShrink)
{
pch = strchr(szAutoFill, '.');
ReportFSz1(pch != NULL, "Unable to find character '.' into %s", szAutoFill);
if (pch != NULL)
{
*pch++ = 0;
FSetWindowText(m_hwndEdit0, pch);
LSendMessage(m_hwndEdit0, EM_SETREADONLY, TRUE, 0);
hwndAutoFill = m_hwndEdit1;
}
} // if
FSetWindowText(hwndAutoFill, pszAutoFill);
if (m_hwndAutoFillPrev)
LSendMessage(m_hwndAutoFillPrev, EM_SETREADONLY, FALSE, 0);
LSendMessage(hwndAutoFill, EM_SETREADONLY, TRUE, 0);
m_hwndAutoFillPrev = hwndAutoFill;
} // if
// Find out which controls must be shown/hidden
#define FFlagChanged(mskf) (((wFlags) & (mskf)) != ((m_wFlagsPrev) & (mskf)))
if (FFlagChanged(RRT_mskfShowEdit0))
ShowWindow(m_hwndEdit0, (wFlags & RRT_mskfShowEdit0) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowEdit1))
ShowWindow(m_hwndEdit1, (wFlags & RRT_mskfShowEdit1) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowEdit2))
ShowWindow(m_hwndEdit2, (wFlags & RRT_mskfShowEdit2) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowIpEdit1))
ShowWindow(m_hwndIpEdit1, (wFlags & RRT_mskfShowIpEdit1) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowIpEdit2))
ShowWindow(m_hwndIpEdit2, (wFlags & RRT_mskfShowIpEdit2) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowEdit2 | RRT_mskfShowIpEdit2))
ShowWindow(m_hwndStatic2, (wFlags & (RRT_mskfShowEdit2 | RRT_mskfShowIpEdit2)) ? SW_SHOW : SW_HIDE);
if (FFlagChanged(RRT_mskfShowButtons)) {
ShowWindow(m_hwndRadio1, (wFlags & RRT_mskfShowButtons) ? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndRadio2, (wFlags & RRT_mskfShowButtons) ? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndStatic4, (wFlags & RRT_mskfShowButtons) ? SW_SHOW : SW_HIDE);
}
#define SetEditWidth(hwnd, cxWidth) \
SetWindowPos(hwnd, NULL, 0, 0, cxWidth, m_sizeEdit.cy, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER)
#define SetEditHeight(hwnd, cyHeight) \
SetWindowPos(hwnd, NULL, 0, 0, m_sizeEdit.cx, cyHeight, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER)
// Special cases
if ((iRRT != iRRT_SOA) && (m_iRRT != iRRT_SOA))
{
const int nCmdShowSOABulk = (iRRT == iRRT_SOA) ? SW_SHOW : SW_HIDE;
for (i = IDC_STATIC_REFRESHTIME; i <= IDC_COMBO_MINIMUMTTL; i++)
ShowWindow(HGetDlgItem(m_hdlg, i), nCmdShowSOABulk);
}
#define FRecordChange(iRRT_TEST) (iRRT == iRRT_TEST || m_iRRT == iRRT_TEST)
ShowWindow(m_hwndEdit3,
(wFlags & RRT_mskfShowEdit3) ? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndStatic3,
(wFlags & RRT_mskfShowEdit3) ? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndStatic4,
(wFlags & RRT_mskfShowButtons) ? SW_SHOW : SW_HIDE);
// fix static control alignment
DWORD style = GetWindowLong (HGetDlgItem (m_hdlg,
IDC_STATIC_REFRESHTIME), GWL_STYLE);
SetWindowLong (HGetDlgItem (m_hdlg, IDC_STATIC_REFRESHTIME),
GWL_STYLE, style & ~SS_RIGHT);
if (FRecordChange(iRRT_A))
{
ShowWindow(HGetDlgItem(m_hdlg, IDC_CHECK_CREATE_PTR_RECORD), (iRRT == iRRT_A) ? SW_SHOW : SW_HIDE);
if (m_pCurrentDRR != NULL)
SetDlgItemString(m_hdlg, IDC_CHECK_CREATE_PTR_RECORD, IDS_UPDATE_PTR_RECORD);
}
if (FRecordChange(iRRT_TXT))
{
i = GetWindowLong(m_hwndEdit2, GWL_STYLE);
if (iRRT == iRRT_TXT)
{
i |= ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL;
SetWindowLong(m_hwndEdit2, GWL_STYLE, i);
SetEditHeight(m_hwndEdit2, m_sizeEdit.cy * 5);
}
else
{
Report(i & ES_MULTILINE);
i &= ~(ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL);
SetWindowLong(m_hwndEdit2, GWL_STYLE, i);
SetEditHeight(m_hwndEdit2, m_sizeEdit.cy);
}
}
if (FFlagChanged(RRT_mskfShrinkEdit1))
SetEditWidth(m_hwndEdit1, (wFlags & RRT_mskfShrinkEdit1) ? m_sizeEdit.cx / 3 : m_sizeEdit.cx);
if (FFlagChanged(RRT_mskfShrinkEdit2))
SetEditWidth(m_hwndEdit2, (wFlags & RRT_mskfShrinkEdit2) ? m_sizeEdit.cx / 3 : m_sizeEdit.cx);
if (FFlagChanged(RRT_mskfShrinkEdit3))
SetEditWidth(m_hwndEdit3, (wFlags & RRT_mskfShrinkEdit3) ? m_sizeEdit.cx / 3 : m_sizeEdit.cx);
SetWindowPos(m_hwndStatic2, NULL, 0, 0, m_sizeEdit.cx, m_sizeStatic.cy, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
} // if
// handle TTL display
ShowWindow(m_hwndStaticTTL, dnsoptions.fExposeTTL? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndEditTTL, dnsoptions.fExposeTTL? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndComboTTL, dnsoptions.fExposeTTL? SW_SHOW : SW_HIDE);
ShowWindow(m_hwndSpinTTL, dnsoptions.fExposeTTL? SW_SHOW : SW_HIDE);
m_wFlagsPrev = wFlags;
m_iRRT = iRRT;
// Set the strings
// wIdStringDescription = wIdStringBase+0
// wIdStringStatic0 = [Auto]
// wIdStringDescriptionEdit0 = [Auto]
// wIdStringStatic1 = wIdStringBase+1
// wIdStringDescriptionEdit1 = wIdStringBase+2
// wIdStringStatic2 = wIdStringBase+3
// wIdStringDescriptionEdit2 = wIdStringBase+4
UINT uIdStringShift = 0;
if (wFlags & RRT_mskfNoAutoPrefix)
{
wIdStringStatic0 = wIdStringBase + 1;
uIdStringShift = 2;
}
else
{
wIdStringStatic0 = IDS_DOMAIN;
if (wFlags & RRT_mskfHasForPrefix) {
wIdStringStatic0 += 2;
}
}
wIdStringStatic1 = (wIdStringBase + 1) + uIdStringShift;
wIdStringStatic2 = 0;
if (wFlags & (RRT_mskfShowEdit2 | RRT_mskfShowIpEdit2)) {
wIdStringStatic2 = (wIdStringBase + 3) + uIdStringShift;
}
wIdStringStatic3 = 0;
if (wFlags & RRT_mskfShowEdit3) {
wIdStringStatic3 = (wIdStringBase + 5) + uIdStringShift;
}
wIdStringStatic4 = 0;
wIdStringRadio1 = 0;
wIdStringRadio2 = 0;
if (wFlags & RRT_mskfShowButtons) {
wIdStringStatic4 = (wIdStringBase + 7) + uIdStringShift;
wIdStringRadio1 = (wIdStringBase + 9) + uIdStringShift;
wIdStringRadio2 = (wIdStringBase + 11) + uIdStringShift;
}
SetWindowString(m_hwndStatic0, wIdStringStatic0);
SetWindowString(m_hwndStatic1, wIdStringStatic1);
if (wIdStringStatic2 != 0)
SetWindowString(m_hwndStatic2, wIdStringStatic2);
if (wIdStringStatic3 != 0)
SetWindowString(m_hwndStatic3, wIdStringStatic3);
if (wIdStringStatic4 != 0)
SetWindowString(m_hwndStatic4, wIdStringStatic4);
if (wIdStringRadio1 != 0)
SetWindowString(m_hwndRadio1, wIdStringRadio1);
if (wIdStringRadio2 != 0)
SetWindowString(m_hwndRadio2, wIdStringRadio2);
//-----------------------------------------------------------------------
// this code fragment is a step towards providing some help for the
// user in entering a valid IP address for a PTR record. i.e. take the
// reverse IP address part of the zone name, and partially fill in the
// ip edit box. i've isolated the addr part of the name here, but it looks
// like mods to the IpEdit control are needed to make this work. jdh
/*
if (FRecordChange(iRRT_PTR)) {
char szTemp[cchDnsNameMax2];
char * pc;
strcpy (szTemp, m_pParentDomain->m_pszFullName);
pc = strrchr (szTemp, '.');
*pc = '\0';
pc = strrchr (szTemp, '.');
*pc = '\0';
}
-------------------------------------------------------------------------*/
wIdStringDescription = wIdStringBase;
if (wIdStringDescription != m_wIdStringDescriptionPrev)
{
SetDlgItemString(m_hdlg, IDC_STATIC_DESCRIPTION, wIdStringDescription);
m_wIdStringDescriptionPrev = wIdStringDescription;
}
m_fSkipBugInEditControl = FALSE;
} // CResourceRecordDlgHandler::OnUpdateControls
/////////////////////////////////////////////////////////////////////////////
// InitRecordData()
//
// Initialize the dialog with data from pDnsRecord. The content of pDnsRecord
// is not cached.
//
void CResourceRecordDlgHandler::InitRecordData(IN const DNS_RPC_RECORD * pDnsRecord)
{
const char * pch;
char szRawData[512];
IP_ADDRESS ipTemp;
unsigned int uIdControl;
Assert(pDnsRecord);
Assert(IsWindow(m_hdlg));
AssertSz2(IrrtFromWrrt(pDnsRecord->wType) != iRRT_Nil,
"Unknown record type: pDnsRecord->wType=%u (0x%X).", pDnsRecord->wType, pDnsRecord->wType);
GarbageInit(szRawData, sizeof(szRawData));
EditCombo_SetTime(m_hdlg, IDC_EDIT_TTL, IDC_COMBO_TTL, pDnsRecord->dwTtlSeconds);
switch (pDnsRecord->wType)
{
case DNS_RECORDTYPE_GENERIC:
SetCtrlDWordValue(m_hwndEdit1, pDnsRecord->wType);
RawDataToString(IN (const BYTE *)&pDnsRecord->Data, pDnsRecord->wDataLength,
OUT szRawData, LENGTH(szRawData));
FSetWindowText(m_hwndEdit2, szRawData);
break;
case DNS_RECORDTYPE_A: // IP Address
IpEdit_SetAddress(m_hwndIpEdit2, pDnsRecord->Data.A.ipAddress);
break;
case DNS_RECORDTYPE_PTR:
FSetWindowText(m_hwndEdit1, pDnsRecord->Data.PTR.nameNode.achName);
break;
case DNS_RECORDTYPE_SOA:
SetCtrlDWordValue(HGetDlgItem(m_hdlg, IDC_EDIT_SERIALNUMBER),
pDnsRecord->Data.SOA.dwSerialNo);
EditCombo_SetTime(m_hdlg, IDC_EDIT_REFRESHTIME, IDC_COMBO_REFRESHTIME,
pDnsRecord->Data.SOA.dwRefresh);
EditCombo_SetTime(m_hdlg, IDC_EDIT_RETRYTIME, IDC_COMBO_RETRYTIME,
pDnsRecord->Data.SOA.dwRetry);
EditCombo_SetTime(m_hdlg, IDC_EDIT_EXPIRETIME, IDC_COMBO_EXPIRETIME,
pDnsRecord->Data.SOA.dwExpire);
EditCombo_SetTime(m_hdlg, IDC_EDIT_MINIMUMTTL, IDC_COMBO_MINIMUMTTL,
pDnsRecord->Data.SOA.dwMinimumTtl);
Assert(pDnsRecord->Data.SOA.namePrimaryServer.cchNameLength == strlen(pDnsRecord->Data.SOA.namePrimaryServer.achName) + 1);
FSetWindowText(m_hwndEdit0, pDnsRecord->Data.SOA.namePrimaryServer.achName);
pch = pDnsRecord->Data.SOA.namePrimaryServer.achName +
pDnsRecord->Data.SOA.namePrimaryServer.cchNameLength + 1;
Assert(*(pch - 1) == (int)strlen(pch) + 1);
FSetWindowText(m_hwndEdit1, pch);
break;
case DNS_RECORDTYPE_WINS:
case DNS_RECORDTYPE_NBSTAT:
AssertSz(FALSE, "Those records should be found in the PropertySheet of the CZoneRootDomain object");
break;
case DNS_RECORDTYPE_WKS:
IpEdit_SetAddress(m_hwndIpEdit2, pDnsRecord->Data.WKS.ipAddress);
Assert((pDnsRecord->Data.WKS.chProtocol == DNS_PROTOCOL_TCP) ||
(pDnsRecord->Data.WKS.chProtocol == DNS_PROTOCOL_UDP));
uIdControl = (pDnsRecord->Data.WKS.chProtocol == DNS_PROTOCOL_TCP)? IDC_RADIO1 : IDC_RADIO2;
CheckDlgButton (m_hdlg, uIdControl, BST_CHECKED);
FSetWindowText (m_hwndEdit3, (char *)pDnsRecord->Data.WKS.bBitMask + 1u);
break;
case DNS_RECORDTYPE_TXT:
SetWindowLong(m_hwndEdit2, GWL_STYLE, GetWindowLong(m_hwndEdit1, GWL_STYLE) |
(ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL));
pch = (char *)&pDnsRecord->Data;
while (pch - (char *)&pDnsRecord->Data < pDnsRecord->wDataLength)
{
UCHAR cchLine = *pch;
char * pchLine = szRawData;
if (pch != (char *)&pDnsRecord->Data)
{
strcpy(pchLine, "\r\n");
pchLine += 2;
}
memcpy(pchLine, pch + 1, cchLine);
*(pchLine + cchLine) = 0;
LSendMessage(m_hwndEdit2, EM_SETSEL, (WPARAM)2000000, (LPARAM)2000000); // Move the cursor to the end
LSendMessage(m_hwndEdit2, EM_REPLACESEL, 0, (LPARAM)szRawData); // Set the text
pch += 1 + cchLine;
} // while
break;
case DNS_RECORDTYPE_AFSDB:
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.MX.nameExchange.achName);
Assert(pDnsRecord->Data.MX.wPreference > 0);
Assert(pDnsRecord->Data.MX.wPreference < 3);
uIdControl = (pDnsRecord->Data.MX.wPreference == 1)? IDC_RADIO1 : IDC_RADIO2;
CheckDlgButton (m_hdlg, uIdControl, BST_CHECKED);
break;
case DNS_RECORDTYPE_MX:
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.MX.nameExchange.achName);
SetCtrlDWordValue(m_hwndEdit3, pDnsRecord->Data.MX.wPreference);
break;
case DNS_RECORDTYPE_RT:
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.MX.nameExchange.achName);
SetCtrlDWordValue(m_hwndEdit3, pDnsRecord->Data.MX.wPreference);
break;
case DNS_RECORDTYPE_RP:
case DNS_RECORDTYPE_MINFO:
case DNS_RECORDTYPE_HINFO:
case DNS_RECORDTYPE_ISDN:
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.HINFO.stringData.achName);
FSetWindowText(m_hwndEdit3, pDnsRecord->Data.HINFO.stringData.achName + 1 +
pDnsRecord->Data.HINFO.stringData.cchNameLength );
break;
case DNS_RECORDTYPE_MR:
case DNS_RECORDTYPE_MB:
case DNS_RECORDTYPE_X25:
case DNS_RECORDTYPE_AAAA:
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.MB.nameNode.achName);
break;
default:
Assert(&pDnsRecord->Data.PTR.nameNode == &pDnsRecord->Data.MINFO.nameMailBox);
Assert(&pDnsRecord->Data.PTR.nameNode == &pDnsRecord->Data.HINFO.stringData);
if ((pDnsRecord->wType == DNS_RECORDTYPE_CNAME) ||
(pDnsRecord->wType == DNS_RECORDTYPE_MB))
{
FSetWindowText(m_hwndEdit2, pDnsRecord->Data.PTR.nameNode.achName);
}
else
{
FSetWindowText(m_hwndEdit1, pDnsRecord->Data.PTR.nameNode.achName);
}
break;
} // switch
} // CResourceRecordDlgHandler::InitRecordData
/////////////////////////////////////////////////////////////////////////////
// FGetRecordData()
//
// Build a resource record and put the data into pDnsRecord.
// The function does not allocate any memory.
// Return TRUE if data is valid, othwerwise return FALSE and set
// the focus to the faulty control.
//
BOOL CResourceRecordDlgHandler::FGetRecordData(
OUT DNS_RPC_RECORD * pDnsRecordData, // Pointer of a buffer to store the record data
UINT cbBufferSize) // Size of the buffer (in bytes)
{
char * pch;
union
{
char szRawData[512];
struct
{
char stzEdit0[cchDnsNameMax];
char stzEdit1[cchDnsNameMax];
};
};
char stzEdit2[cchDnsNameMax];
char stzEdit3[cchDnsNameMax];
char szEdit1Tmp[cchDnsNameMax];
UINT cbEdit0;
UINT cbEdit1;
UINT cbEdit2;
UINT cbEdit3;
DWORD dwNumber;
Assert(pDnsRecordData != NULL);
Assert(IsWindow(m_hdlg));
AssertSz(m_iRRT != iRRT_Nil, "No item selected in the listbox");
Assert(m_iRRT >= 0 && m_iRRT < iRRT_Max);
Assert(rgRRTInfo[m_iRRT].wType == WrrtFromIrrt(m_iRRT));
Assert(DNS_MAX_NAME_LENGTH < LENGTH(stzEdit1));
GarbageInit(szRawData, sizeof(szRawData));
GarbageInit(stzEdit0, sizeof(stzEdit0));
GarbageInit(stzEdit1, sizeof(stzEdit1));
GarbageInit(stzEdit2, sizeof(stzEdit2));
GarbageInit(stzEdit3, sizeof(stzEdit3));
Assert(cbBufferSize > SIZEOF_DNS_RPC_RECORD_HEADER);
InitDnsRecord(pDnsRecordData, cbBufferSize);
pDnsRecordData->wType = rgRRTInfo[m_iRRT].wType;
const WORD wFlags = rgRRTInfo[m_iRRT].wFlags;
UINT cbDataLength = 0;
UINT cbDataLengthAvailable = cbBufferSize - SIZEOF_DNS_RPC_RECORD_HEADER;
// REVIEW: Unicode WCHAR => char conversion
if (m_iRRT == iRRT_Generic)
{
// Generic Record
// Empty string would not be considered valid
gGI_dwFlags &= ~GI_mskfEmptyStringValid;
if (!FGetCtrlDWordValue(m_hwndEdit1, OUT &dwNumber, 0, 0xFFFF))
return FALSE;
CchGetWindowText(m_hwndEdit2, szRawData, LENGTH(szRawData));
int cb = sizeof(stzEdit2);
if (!FStringToRawData(IN szRawData, OUT (BYTE *)stzEdit2, INOUT &cb))
{
MsgBox(IDS_ERR_INVALID_STRING);
SetFocus(m_hwndEdit2);
LSendMessage(m_hwndEdit2, EM_SETSEL, cb, cb + 1);
return FALSE;
}
Assert(cb < sizeof(stzEdit2));
cbDataLength = cb;
if (stzEdit2[cbDataLength] != 0)
{
// Null-terminator not found in last character
cbDataLength++; // So, add it to the string
Assert(stzEdit2[cbDataLength] == 0); // Here is the proof the string is null-terminated
}
if (cbDataLength > cbDataLengthAvailable)
{
ReportSz1("String too long. String will be truncated to %d characters", cbDataLengthAvailable);
cbDataLength = cbDataLengthAvailable;
}
pDnsRecordData->wType = (WORD)dwNumber;
memcpy((void *)&pDnsRecordData->Data, stzEdit2, cbDataLength);
}
else if (m_iRRT == iRRT_TXT)
{
int cLine = LSendMessage(m_hwndEdit2, EM_GETLINECOUNT, 0, 0);
pch = (char *)&pDnsRecordData->Data;
for (int i = 0; i < cLine; i++)
{
CHAR szTemp[DNS_MAX_NAME_LENGTH];
*(WORD *)&szTemp[0] = DNS_MAX_NAME_LENGTH;
cbEdit2 = LSendMessage(m_hwndEdit2, EM_GETLINE, i, OUT (LPARAM)szTemp);
Assert(cbEdit2 <= DNS_MAX_NAME_LENGTH);
memcpy (pch + 1, szTemp, cbEdit2);
if (cbDataLength + cbEdit2 >= cbDataLengthAvailable)
{
ReportSz1("Text too long. Text will be truncated to %d characters", pch - (char *)&pDnsRecordData->Data);
break;
}
pch[++cbEdit2] = '\0';
*pch = (BYTE)cbEdit2;
cbDataLength += cbEdit2 + 1;
pch += cbEdit2;
} // for
}
else
{
cbEdit0 = CchGetWindowText(m_hwndEdit0, &stzEdit0[1], cchDnsCompMax);
stzEdit0[0] = (BYTE)++cbEdit0;
cbEdit0++;
*(WORD *)&szEdit1Tmp[0] = cchDnsCompMax;
cbEdit1 = LSendMessage(m_hwndEdit1, EM_GETLINE, 0, OUT (LPARAM)szEdit1Tmp);
memcpy (&stzEdit1[1], szEdit1Tmp, cbEdit1);
stzEdit1[1+cbEdit1] = 0; // Manually put the null-terminator
stzEdit1[0] = (BYTE)++cbEdit1;
cbEdit1++;
if (rgRRTInfo[m_iRRT].wFlags & RRT_mskfHasShortName)
{ // i.e. edit1 is host name
if (strchr (stzEdit1, '.')) {
switch (pDnsRecordData->wType)
{
case DNS_RECORDTYPE_CNAME:
MsgBox (IDS_ERROR_NODOTSINALIASNAME);
break;
case DNS_RECORDTYPE_MB:
case DNS_RECORDTYPE_MINFO:
case DNS_RECORDTYPE_MR:
MsgBox (IDS_ERROR_NODOTSINMAILBOXNAME);
break;
default:
MsgBox (IDS_ERROR_NODOTSINHOSTNAME);
break;
}
return FALSE;
}
}
cbEdit2 = CchGetWindowText(m_hwndEdit2, &stzEdit2[1], cchDnsCompMax);
stzEdit2[0] = (BYTE)++cbEdit2;
cbEdit2++;
cbEdit3 = CchGetWindowText(m_hwndEdit3, &stzEdit3[1], cchDnsCompMax);
stzEdit3[0] = (BYTE)++cbEdit3;
cbEdit3++;
EditCombo_FGetTime (m_hdlg, IDC_EDIT_TTL, IDC_COMBO_TTL,
OUT &pDnsRecordData->dwTtlSeconds);
switch (pDnsRecordData->wType)
{
case DNS_RECORDTYPE_A: // IP Address
pDnsRecordData->Data.A.ipAddress = IpEdit_GetAddress(m_hwndIpEdit2);
cbDataLength = sizeof(pDnsRecordData->Data.A);
if (IsDlgButtonChecked (m_hdlg, IDC_CHECK_CREATE_PTR_RECORD)) {
pDnsRecordData->dwFlags |= DNS_RPC_RECORD_FLAG_CREATE_PTR;
}
break;
case DNS_RECORDTYPE_SOA:
if (!FGetCtrlDWordValue(HGetDlgItem(m_hdlg, IDC_EDIT_SERIALNUMBER),
OUT &pDnsRecordData->Data.SOA.dwSerialNo, 0, (DWORD)-1) ||
!EditCombo_FGetTime(m_hdlg, IDC_EDIT_REFRESHTIME, IDC_COMBO_REFRESHTIME,
OUT &pDnsRecordData->Data.SOA.dwRefresh) ||
!EditCombo_FGetTime(m_hdlg, IDC_EDIT_RETRYTIME, IDC_COMBO_RETRYTIME,
OUT &pDnsRecordData->Data.SOA.dwRetry) ||
!EditCombo_FGetTime(m_hdlg, IDC_EDIT_EXPIRETIME, IDC_COMBO_EXPIRETIME,
OUT &pDnsRecordData->Data.SOA.dwExpire) ||
!EditCombo_FGetTime(m_hdlg, IDC_EDIT_MINIMUMTTL, IDC_COMBO_MINIMUMTTL,
OUT &pDnsRecordData->Data.SOA.dwMinimumTtl))
{
return FALSE;
}
memcpy(&pDnsRecordData->Data.SOA.namePrimaryServer, stzEdit0, cbEdit0);
pch = (char *)&pDnsRecordData->Data.SOA.namePrimaryServer + cbEdit0;
memcpy(pch, stzEdit1, cbEdit1);
cbDataLength = (BYTE *)&pDnsRecordData->Data.SOA.namePrimaryServer -
(BYTE *)&pDnsRecordData->Data.SOA + cbEdit0 + cbEdit1;
break;
case DNS_RECORDTYPE_WINS:
case DNS_RECORDTYPE_NBSTAT:
AssertSz(FALSE, "Those records should be found in the PropertySheet of the CZoneRootDomain object");
break;
case DNS_RECORDTYPE_WKS:
pDnsRecordData->Data.WKS.ipAddress = IpEdit_GetAddress(m_hwndIpEdit2);
cbDataLength = sizeof(pDnsRecordData->Data.WKS);
// figure out type
if (!FGetRadioSelection(m_hdlg, IDC_RADIO1, IDC_RADIO2, OUT &dwNumber)) {
return FALSE;
}
pDnsRecordData->Data.WKS.chProtocol =
(BYTE)((dwNumber == 1) ? DNS_PROTOCOL_TCP : DNS_PROTOCOL_UDP);
cbDataLength += sizeof(pDnsRecordData->Data.WKS.chProtocol);
memcpy(&pDnsRecordData->Data.WKS.bBitMask, stzEdit3, cbEdit3);
cbDataLength += cbEdit3;
break;
case DNS_RECORDTYPE_MX:
if (!FGetCtrlDWordValue(m_hwndEdit3, OUT &dwNumber, 0, 0xFFFF)) {
return FALSE;
}
pDnsRecordData->Data.MX.wPreference = (WORD)dwNumber;
memcpy(&pDnsRecordData->Data.MX.nameExchange, stzEdit2, cbEdit2);
cbDataLength = (BYTE *)&pDnsRecordData->Data.MX.nameExchange -
(BYTE *)&pDnsRecordData->Data.MX + cbEdit2;
break;
case DNS_RECORDTYPE_AFSDB:
// figure out type
if (!FGetRadioSelection(m_hdlg, IDC_RADIO1, IDC_RADIO2, OUT &dwNumber)) {
return FALSE;
}
pDnsRecordData->Data.AFSDB.wPreference = (WORD)dwNumber;
memcpy(&pDnsRecordData->Data.AFSDB.nameExchange, stzEdit2, cbEdit2);
cbDataLength = (BYTE *)&pDnsRecordData->Data.AFSDB.nameExchange -
(BYTE *)&pDnsRecordData->Data.AFSDB + cbEdit2;
break;
case DNS_RECORDTYPE_RT:
if (!FGetCtrlDWordValue(m_hwndEdit3, OUT &dwNumber, 0, 0xFFFF)) {
return FALSE;
}
pDnsRecordData->Data.RT.wPreference = (WORD)dwNumber;
memcpy(&pDnsRecordData->Data.RT.nameExchange, stzEdit2, cbEdit2);
cbDataLength = (BYTE *)&pDnsRecordData->Data.RT.nameExchange -
(BYTE *)&pDnsRecordData->Data.RT + cbEdit2;
break;
case DNS_RECORDTYPE_MINFO:
case DNS_RECORDTYPE_HINFO:
case DNS_RECORDTYPE_ISDN:
case DNS_RECORDTYPE_RP:
Assert(&pDnsRecordData->Data.PTR.nameNode == &pDnsRecordData->Data.HINFO.stringData);
memcpy(&pDnsRecordData->Data.HINFO.stringData, stzEdit2, cbEdit2);
memcpy(&pDnsRecordData->Data.HINFO.stringData + cbEdit2, stzEdit3, cbEdit3);
cbDataLength = cbEdit2 + cbEdit3;
break;
case DNS_RECORDTYPE_MR:
case DNS_RECORDTYPE_MB:
case DNS_RECORDTYPE_X25:
case DNS_RECORDTYPE_AAAA:
memcpy(&pDnsRecordData->Data.MB.nameNode, stzEdit2, cbEdit2);
cbDataLength = cbEdit2;
break;
default:
// This should include all the other single string records such as
// PTR, NS, CNAME, MB, MD, MF, MG, MR, MINFO, RP, HINFO, ISDN, X25, NULL
Assert(&pDnsRecordData->Data.PTR.nameNode == &pDnsRecordData->Data.MINFO.nameMailBox);
Assert(&pDnsRecordData->Data.PTR.nameNode == &pDnsRecordData->Data.HINFO.stringData);
if ((pDnsRecordData->wType == DNS_RECORDTYPE_CNAME) ||
(pDnsRecordData->wType == DNS_RECORDTYPE_MB))
{
memcpy(&pDnsRecordData->Data.PTR.nameNode, stzEdit2, cbEdit2);
cbDataLength = cbEdit2;
}
else
{
memcpy(&pDnsRecordData->Data.PTR.nameNode, stzEdit1, cbEdit1);
cbDataLength = cbEdit1;
}
break;
} // switch
} // if...else
Assert(cbDataLength + SIZEOF_DNS_RPC_RECORD_HEADER < cbBufferSize);
pDnsRecordData->wDataLength = cbDataLength;
pDnsRecordData->wRecordLength = SIZEOF_DNS_RPC_RECORD_HEADER + NEXT_DWORD(cbDataLength);
return TRUE;
} // CResourceRecordDlgHandler::FGetRecordData
/////////////////////////////////////////////////////////////////////////////
// FIsRecordValid()
//
// Return FALSE if the data inside is not valid.
// Return TRUE if the data inside a record seems to be valid or if not sure.
//
BOOL CResourceRecordDlgHandler::FIsRecordValid()
{
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling FIsRecordValid()");
AssertSz(m_iRRT != iRRT_Nil, "Invalid Record Type Index - No record type selected");
switch (rgRRTInfo[m_iRRT].wType)
{
case 0:
break;
}
return TRUE;
} // CResourceRecordDlgHandler::FIsRecordValid
/////////////////////////////////////////////////////////////////////////////
// FIsRecordDirty()
//
// Return FALSE if none of the controls have been modified.
// Return TRUE if the record has been modified or don't know if it has been modified
BOOL CResourceRecordDlgHandler::FIsRecordDirty()
{
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling FIsRecordDirty()");
AssertSz(m_iRRT != iRRT_Nil, "Invalid Record Type Index - No record type selected");
return TRUE;
} // CResourceRecordDlgHandler::FIsRecordDirty
/////////////////////////////////////////////////////////////////////////////
// FOnOK()
//
// Create/update resource record.
// Return TRUE if successfull indicating the dialog should be dismissed.
// Return FALSE if data was not valid
//
BOOL CResourceRecordDlgHandler::FOnOK()
{
BYTE rgbRecordData[CDnsRpcRecord::cbDNS_RPC_RECORD_MAX];
AssertSz(m_fInit == TRUE, "You must call OnInitDialog() before calling FOnOK()");
AssertSz(m_iRRT != iRRT_Nil, "Invalid Record Type Index - No record type selected");
if (!FGetRecordData(OUT (DNS_RPC_RECORD *)rgbRecordData, sizeof(rgbRecordData))) {
return FALSE;
}
if (m_pCurrentDRR != NULL)
{
//
// Existing Resource Record
//
(void)m_pCurrentDRR->FRpcSetRecordData(IN (const DNS_RPC_RECORD *)rgbRecordData);
// Force a repait of the listbox to update the changes
InvalidateRect(DlgZoneHelper.m_hwndListBoxRecord, NULL, TRUE);
return TRUE;
}
//
// New Resource Record
//
char szShortNameT[cchDnsNameMax];
char szTemp[cchDnsNameMax];
CDomainNode * pParentDomain = m_pParentDomain;
BOOL fIpFieldEmpty = FALSE;
char * pch = NULL;
AssertSz(m_pParentDomain || m_pParentDRR, "You must at least initialize one of them via SetParentDomain()");
if (m_pParentDRR != NULL) {
pParentDomain = m_pParentDRR->m_pParentDomain;
}
Assert(pParentDomain != NULL);
DebugCode( pParentDomain->AssertNodeValid(); )
Assert(m_iRRT >= 0 && m_iRRT < iRRT_Max);
// Find out which records may have a short name
szShortNameT[0] = 0;
if (m_pParentDRR != NULL)
{
// Get the short name from pParentDRR
strcpy(szShortNameT, m_pParentDRR->m_pszShortName);
}
else
{
// Otherwise get it from the edit control
if (rgRRTInfo[m_iRRT].wFlags & RRT_mskfHasShortName) {
CchGetWindowText(m_hwndEdit1, OUT szShortNameT, LENGTH(szShortNameT));
}
// if a PTR record, get it from the IP edit control
if (m_iRRT == iRRT_PTR) {
ConvertIpAddrToString(IpEdit_GetAddressEx (m_hwndIpEdit1, &fIpFieldEmpty),
szShortNameT);
if (fIpFieldEmpty) { // if so, we assume doing gateway. this means that
// an addr of 123.45.0.0 should be converted to
// 123.45.
pch = strstr (szShortNameT, ".0");
AssertSz (pch != NULL, "got fIpFieldEmpty, but couldn't find a 0");
if (pch != NULL) { //found a 0, if not, oopser!
*pch = '\0';
}
}
}
}
if (pParentDomain->PRpcCreateDnsRecord(szShortNameT, IN (const DNS_RPC_RECORD *)rgbRecordData)) {
return TRUE;
} else {
return FALSE;
}
} // CResourceRecordDlgHandler::FOnOK
/////////////////////////////////////////////////////////////////////////////
// IrrtFromWrrt()
//
// Get the iRRT from a given wRRT
//
IRRT IrrtFromWrrt(WRRT wRRT)
{
// Check of we get a 1:1 mapping from a iRRT to a wRRT
if (wRRT <= iRRT_1To1Last)
{
Assert(rgRRTInfo[wRRT].wType == wRRT);
return wRRT;
}
// Check the end of the list for a match
for (IRRT iRRT = iRRT_1To1Last; iRRT < iRRT_Max; iRRT++)
{
if (rgRRTInfo[iRRT].wType == wRRT)
return iRRT;
}
Trace1(mskTraceDNS | mskTraceDNSVerbose, "\nUnknown Resource Record Type (wRRT=0x%X)", wRRT);
return iRRT_Nil;
} // IrrtFromWrrt
/////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG
void DbgPrintDnsRecord(DWORD dwTraceFlags, const DNS_RPC_RECORD * pDnsRecord)
{
char szT[cchDnsNameMax2];
const char * pch;
#define szTrace_DNS_RPC_RECORD "\n \t\t -> "
Assert(pDnsRecord != NULL);
IRRT iRRT = IrrtFromWrrt(pDnsRecord->wType);
if (iRRT == iRRT_Nil)
{
Trace2(dwTraceFlags, szTrace_DNS_RPC_RECORD "wType=%d (Unknown) \t(hRecord=0x%08X)",
pDnsRecord->wType, pDnsRecord->hRecord);
return;
}
switch (pDnsRecord->wType)
{
case DNS_RECORDTYPE_A: // IP Address
ConvertIpAddrToString(pDnsRecord->Data.A.ipAddress, OUT szT);
break;
case DNS_RECORDTYPE_SOA: // SOA Record
AssertDnsName(&pDnsRecord->Data.SOA.namePrimaryServer);
pch = pDnsRecord->Data.SOA.namePrimaryServer.achName +
pDnsRecord->Data.SOA.namePrimaryServer.cchNameLength + 1;
Assert(*(pch - 1) == (int)strlen(pch) + 1);
wsprintfA(szT, "%"_aS_", %"_aS_, pDnsRecord->Data.SOA.namePrimaryServer.achName, pch);
AssertSz(strlen(szT) < LENGTH(szT), "Buffer overflow");
break;
case DNS_RECORDTYPE_NS: // Name Server
case DNS_RECORDTYPE_PTR: // Pointer
case DNS_RECORDTYPE_CNAME: // Canonical Name
AssertDnsName(&pDnsRecord->Data.NS.nameNode);
strcpy(szT, pDnsRecord->Data.NS.nameNode.achName);
break;
case DNS_RECORDTYPE_MX:
AssertDnsName(&pDnsRecord->Data.Mx.nameExchange);
wsprintfA(szT, "[%u] %s", pDnsRecord->Data.MX.wPreference, pDnsRecord->Data.Mx.nameExchange.achName);
break;
default:
RawDataToString((const BYTE *)&pDnsRecord->Data, pDnsRecord->wDataLength, OUT szT, LENGTH(szT));
} // switch
Trace3(dwTraceFlags, szTrace_DNS_RPC_RECORD "%s Record : %"_aS_" \t(hRecord=0x%08X)",
IRRT_PchGetName(iRRT), szT, pDnsRecord->hRecord);
} // DbgPrintDnsRecord
#endif // DEBUG
/////////////////////////////////////////////////////////////////////////////
// DoNewRecord()
//
// Create a new resource record from scratch.
// This is the generic way of creating a resource record.
//
void CRecordWiz::DoNewRecord(CDomainNode * pParentDomain)
{
// Default Record Types for different type of domains
const IRRT rgIrrtZoneRootDomainFowardDefault[] =
{ iRRT_A, iRRT_AAAA, iRRT_AFSDB, iRRT_CNAME, iRRT_HINFO, iRRT_ISDN, iRRT_MB,
iRRT_MG, iRRT_MINFO, iRRT_MR, iRRT_MX, iRRT_NS,
iRRT_RP, iRRT_RT, iRRT_TXT, iRRT_WKS, iRRT_X25, iRRT_Nil };
const IRRT rgIrrtZoneDomainFowardDefault[] =
{ iRRT_A, iRRT_AAAA, iRRT_AFSDB, iRRT_CNAME, iRRT_HINFO, iRRT_ISDN, iRRT_MB,
iRRT_MG, iRRT_MINFO, iRRT_MR, iRRT_MX, iRRT_NS, iRRT_PTR,
iRRT_RP, iRRT_RT, iRRT_TXT, iRRT_WKS, iRRT_X25, iRRT_Nil };
const IRRT rgIrrtZoneRootDomainReverseDefault[] =
{ iRRT_NS, iRRT_PTR, iRRT_TXT, iRRT_Nil };
const IRRT rgIrrtZoneDomainReverseDefault[] =
{ iRRT_NS, iRRT_PTR, iRRT_TXT, iRRT_Nil };
Assert(pParentDomain != NULL);
Assert(s_pThis == NULL);
ZeroInit(this, sizeof(*this));
m_pParentDomain = pParentDomain;
m_fNewRecord = TRUE;
if (pParentDomain->m_dwFlags & CDomainNode::mskfIsZoneRootDomain)
{
Assert(pParentDomain->m_pThisTreeItem != NULL);
Assert(pParentDomain->m_pThisTreeItem->QueryInterface() == ITreeItem::IID_CZoneRootDomain);
if (pParentDomain->m_dwFlags & CDomainNode::mskfReverseMode)
m_pIrrtInit = rgIrrtZoneRootDomainReverseDefault;
else
m_pIrrtInit = rgIrrtZoneRootDomainFowardDefault;
}
else
{
if (pParentDomain->m_dwFlags & CDomainNode::mskfReverseMode)
m_pIrrtInit = rgIrrtZoneDomainReverseDefault;
else
m_pIrrtInit = rgIrrtZoneDomainFowardDefault;
}
s_pThis = this;
(void)DoDialogBox(IDD_RESOURCERECORDv2, hwndMain, DlgProcRecordProperties);
s_pThis = NULL;
} // CRecordWiz::DoNewRecord
/////////////////////////////////////////////////////////////////////////////
// DoNewRecord()
//
// Create a new resource record based on an existing Address record
//
void CRecordWiz::DoNewRecord(CDnsRpcRecord * pDRRHost)
{
const IRRT rgIrrtAddressRecord[] =
{ iRRT_MX, iRRT_TXT, iRRT_PTR, iRRT_Generic, iRRT_Nil };
Assert(pDRRHost != NULL);
Assert(pDRRHost->m_pDnsRecord != NULL);
Assert(pDRRHost->m_pDnsRecord->wType == DNS_RECORDTYPE_A);
Assert(s_pThis == NULL);
ZeroInit(this, sizeof(*this));
m_pParentDomain = pDRRHost->m_pParentDomain;
m_pDRRCurrent = pDRRHost;
m_fNewRecord = TRUE;
m_pIrrtInit = rgIrrtAddressRecord;
m_pDnsRecordInit = pDRRHost->m_pDnsRecord;
s_pThis = this;
(void)DoDialogBox(IDD_RESOURCERECORDv2, hwndMain, DlgProcRecordProperties);
s_pThis = NULL;
} // CRecordWiz::DoNewRecord
/////////////////////////////////////////////////////////////////////////////
void CRecordWiz::DoNewDomain(CDomainNode * pParentDomain)
{
Assert(pParentDomain != NULL);
Assert(s_pThis == NULL);
ZeroInit(this, sizeof(*this));
m_pParentDomain = pParentDomain;
m_ids = IDS_s_CREATEDOMAINFOR;
s_pThis = this;
(void)DoDialogBox(IDD_RESOURCERECORD_CREATEDOMAIN, hwndMain, DlgProcNewDomain);
s_pThis = NULL;
} // CRecordWiz::DoNewDomain
/////////////////////////////////////////////////////////////////////////////
void CRecordWiz::DoNewHost(CDomainNode * pParentDomain)
{
Assert(pParentDomain != NULL);
Assert(s_pThis == NULL);
ZeroInit(this, sizeof(*this));
m_pParentDomain = pParentDomain;
m_ids = IDS_s_CREATEHOSTFOR;
s_pThis = this;
(void)DoDialogBox(IDD_RESOURCERECORD_CREATEHOST, hwndMain, DlgProcNewDomain);
s_pThis = NULL;
} // CRecordWiz::DoNewHost
/////////////////////////////////////////////////////////////////////////////
void CRecordWiz::DoProperties(CDnsRpcRecord * pDRR)
{
Assert(pDRR != NULL);
Assert(pDRR->m_pParentDomain != NULL);
Assert(pDRR->m_pDnsRecord != NULL);
Assert(s_pThis == NULL);
ZeroInit(this, sizeof(*this));
m_pDRRCurrent = pDRR;
m_pParentDomain = pDRR->m_pParentDomain;
m_pDnsRecordInit = pDRR->m_pDnsRecord;
switch (pDRR->m_pDnsRecord->wType)
{
case DNS_RECORDTYPE_WINS:
case DNS_RECORDTYPE_NBSTAT:
Assert(m_pParentDomain->m_pThisTreeItem != NULL);
Assert(m_pParentDomain->m_pThisTreeItem->QueryInterface() == ITreeItem::IID_CZoneRootDomain);
((CZoneRootDomain *)m_pParentDomain)->DlgProperties(pDRR);
return;
}
if (m_pParentDomain->m_dwFlags & CDomainNode::mskfReadOnly) {
m_fReadOnly = TRUE;
}
s_pThis = this;
(void)DoDialogBox(IDD_RESOURCERECORDv2, hwndMain, DlgProcRecordProperties);
s_pThis = NULL;
} // CRecordWiz::DoProperties