//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1998 - 1999 // // File: record.cpp // //-------------------------------------------------------------------------- #include "preDNSsn.h" #include #include "resource.h" #include "dnsutil.h" #include "DNSSnap.h" #include "snapdata.h" #include "server.h" #include "domain.h" #include "record.h" #include "zone.h" #ifdef DEBUG_ALLOCATOR #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #endif #define DNS_RECORD_CLASS_DEFAULT (0x1) // we support only class one records #ifdef _USE_BLANK #else const WCHAR* g_szAtTheNodeInput = L"@"; // string to mark the "At the node RR" #endif extern COMBOBOX_TABLE_ENTRY g_Algorithms[]; extern COMBOBOX_TABLE_ENTRY g_Protocols[]; //////////////////////////////////////////////////////////////////////////// // CDNSRecord : base class for all the DNS record types CDNSRecord::CDNSRecord() { m_wType = 0x0; m_dwFlags = DNS_RPC_RECORD_FLAG_DEFAULT; m_dwTtlSeconds = 60; m_dwScavengeStart = 0; } //////////////////////////////////////////////////////////////////// //////////////// RPC SPECIFIC ////////////////////////////////////// // // sizes of data sections for records: some of them have strings // after the constant size part // #define SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER (sizeof(IP_ADDRESS)) #define SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER (sizeof(UCHAR)) #define SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER (sizeof(IPV6_ADDRESS)) #define SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER (5*sizeof(DWORD)) // then string #define SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER (sizeof(WORD)) // thsn string #define SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER (sizeof(IP_ADDRESS)+sizeof(UCHAR)) #define SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER (4*sizeof(DWORD)) #define SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER (3*sizeof(DWORD)) #define SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER (3*sizeof(WORD)) #define SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER \ (sizeof(WORD)+2*sizeof(BYTE)+3*sizeof(DWORD)+sizeof(WORD)) // then string then blob #define SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER (sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE)) #define SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER (sizeof(WORD)) DNS_STATUS CDNSRecord::Update(LPCTSTR lpszServerName, LPCTSTR lpszZoneName, LPCTSTR lpszNodeName, CDNSRecord* pDNSRecordOld, BOOL bUseDefaultTTL) { USES_CONVERSION; WORD nBytesLen = GetRPCRecordLength(); BYTE* pMem = (BYTE*)malloc(nBytesLen); if (!pMem) { return ERROR_OUTOFMEMORY; } memset(pMem, 0x0, nBytesLen); DNS_STATUS err = 0; BYTE* pMemOld = 0; do // false loop { DNS_RPC_RECORD* pDnsRpcRecord = NULL; WriteRPCData(pMem, &pDnsRpcRecord); ASSERT(pDnsRpcRecord != NULL); DNS_RPC_RECORD* pDnsRpcRecordOld = NULL; if (pDNSRecordOld != NULL) // doing an update of existing record { WORD nOldBytesLen = pDNSRecordOld->GetRPCRecordLength(); pMemOld = (BYTE*)malloc(nOldBytesLen); if (!pMemOld) { err = ERROR_OUTOFMEMORY; break; } memset(pMemOld, 0x0, nOldBytesLen); pDNSRecordOld->WriteRPCData(pMemOld, &pDnsRpcRecordOld); ASSERT(pDnsRpcRecordOld != NULL); // // figure out if it is TTL only or full update // if (pDnsRpcRecordOld->wDataLength == pDnsRpcRecord->wDataLength) { // // mask the flags // DWORD dwFlagSave = pDnsRpcRecord->dwFlags; pDnsRpcRecord->dwFlags = 0; // // mask the TTL // DWORD dwTtlSave = pDnsRpcRecord->dwTtlSeconds; // // mask the StartRefreshHr // DWORD dwStartRefreshHrSave = pDnsRpcRecord->dwTimeStamp; pDnsRpcRecord->dwTtlSeconds = pDnsRpcRecordOld->dwTtlSeconds; BOOL bEqual = memcmp( pDnsRpcRecord, pDnsRpcRecordOld, min( pDnsRpcRecord->wDataLength + SIZEOF_DNS_RPC_RECORD_HEADER, pDnsRpcRecordOld->wDataLength + SIZEOF_DNS_RPC_RECORD_HEADER)) == 0; // // restore masked fields // pDnsRpcRecord->dwTimeStamp = dwStartRefreshHrSave; pDnsRpcRecord->dwTtlSeconds = dwTtlSave; pDnsRpcRecord->dwFlags = dwFlagSave; // // check if TTL only // if (bEqual && (pDnsRpcRecord->dwTtlSeconds != pDnsRpcRecordOld->dwTtlSeconds)) { pDnsRpcRecord->dwFlags |= DNS_RPC_RECORD_FLAG_TTL_CHANGE; } } } if (bUseDefaultTTL) { pDnsRpcRecord->dwFlags |= DNS_RPC_RECORD_FLAG_DEFAULT_TTL; } ASSERT(pDnsRpcRecord->wType != 0); err = ::DnssrvUpdateRecord( lpszServerName, W_TO_UTF8(lpszZoneName), W_TO_UTF8(lpszNodeName), pDnsRpcRecord, pDnsRpcRecordOld); // // if we get DNS_ERROR_ALREADY_EXISTS and it is an existing record, // we are actually OK, ignore the error code // // NTRAID#Windows Bugs-251410-2001/01/17-jeffjon // The DNS_ERROR_RECORD_ALREADY_EXISTS was taken out due to bug 251410. I // am leaving it here in case we run into problems after removing it since // I don't know why it was here in the first place. // /*if ((err == DNS_ERROR_RECORD_ALREADY_EXISTS) && (pDNSRecordOld != NULL)) { err = 0; }*/ } while (false); if (pMem) { free(pMem); pMem = 0; } if (pMemOld) { free(pMemOld); pMemOld = 0; } return err; } DNS_STATUS CDNSRecord::Delete(LPCTSTR lpszServerName, LPCTSTR lpszZoneName, LPCTSTR lpszNodeName) { USES_CONVERSION; WORD nBytesLen = GetRPCRecordLength(); BYTE* pMem = (BYTE*)malloc(nBytesLen); if (!pMem) { return ERROR_OUTOFMEMORY; } memset(pMem, 0x0, nBytesLen); DNS_RPC_RECORD* pDnsRpcRecord = NULL; WriteRPCData(pMem, &pDnsRpcRecord); ASSERT(pDnsRpcRecord != NULL); DNS_STATUS err = ::DnssrvUpdateRecord(lpszServerName, W_TO_UTF8(lpszZoneName), W_TO_UTF8(lpszNodeName), NULL, pDnsRpcRecord); if (pMem) { free(pMem); pMem = 0; } return err; } // helper function void CDNSRecord::CopyDNSRecordData(CDNSRecord* pDest, CDNSRecord* pSource) { ASSERT(pDest != NULL); ASSERT(pSource != NULL); // allocate buffer on the stack WORD nBytesLen = pSource->GetRPCRecordLength(); BYTE* pMem = (BYTE*)malloc(nBytesLen); if (!pMem) { return; } memset(pMem, 0x0, nBytesLen); DNS_RPC_RECORD* pDnsRPCRecord = NULL; pSource->WriteRPCData(pMem, &pDnsRPCRecord); // write source to memory ASSERT(pDnsRPCRecord != NULL); pDest->ReadRPCData(pDnsRPCRecord); // read destination from memory // got to test if it is the same ASSERT(pDest->GetType() == pSource->GetType()); if (pMem) { free(pMem); pMem = 0; } } void CDNSRecord::CloneValue(CDNSRecord* pClone) { ASSERT(pClone != NULL); CopyDNSRecordData(pClone,this); } void CDNSRecord::SetValue(CDNSRecord* pRecord) { ASSERT(pRecord != NULL); CopyDNSRecordData(this,pRecord); } void CDNSRecord::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { ASSERT(pDnsRecord != NULL); // base class: just read common attributes // either we know the type, or we are an unk/null record type ASSERT(( m_wType == DNS_TYPE_NULL) || (m_wType == pDnsRecord->wType) ); m_wType = pDnsRecord->wType; m_dwFlags = pDnsRecord->dwFlags; m_dwTtlSeconds = pDnsRecord->dwTtlSeconds; m_dwScavengeStart = pDnsRecord->dwTimeStamp; } void CDNSRecord::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { ASSERT(pDnsQueryRecord != NULL); // base class: just read common attributes // either we know the type, or we are an unk/null record type ASSERT(( m_wType == DNS_TYPE_NULL) || (m_wType == pDnsQueryRecord->wType) ); m_wType = pDnsQueryRecord->wType; m_dwFlags = 0x0; // pDnsQueryRecord->Flags.W; m_dwTtlSeconds = pDnsQueryRecord->dwTtl; } void CDNSRecord::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { ASSERT(pMem != NULL); ASSERT(ppDnsRecord != NULL); *ppDnsRecord = (DNS_RPC_RECORD*)pMem; // fill in the common fields (*ppDnsRecord)->wType = m_wType; (*ppDnsRecord)->dwFlags = m_dwFlags; (*ppDnsRecord)->dwTtlSeconds = m_dwTtlSeconds; (*ppDnsRecord)->dwTimeStamp = m_dwScavengeStart; // fill in the length info: derived classes will ad to it (*ppDnsRecord)->wDataLength = 0x0; } WORD CDNSRecord::RPCBufferStringLen(LPCWSTR lpsz) { // returns the size of a DNS_RPC_STRING written to the buffer USES_CONVERSION; LPCSTR lpszAnsi = W_TO_UTF8(lpsz); // do not count NULL, // add size of cchNameLength (UCHAR) string length WORD wLen = 0; if (lpszAnsi != NULL && lpszAnsi[0] != L'\0') { wLen = static_cast(UTF8_LEN(lpszAnsi) + sizeof(UCHAR)); } else { wLen = sizeof(UCHAR) + sizeof(CHAR); } return wLen; } void CDNSRecord::ReadRPCString(CString& sz, DNS_RPC_NAME* pDnsRPCName) { // the input string is not NULL terminated DnsUtf8ToWCStringHelper(sz, pDnsRPCName->achName, pDnsRPCName->cchNameLength); } WORD CDNSRecord::WriteString(DNS_RPC_NAME* pDnsRPCName, LPCTSTR lpsz) { USES_CONVERSION; ASSERT(pDnsRPCName != NULL); LPCSTR lpszAnsi = W_TO_UTF8(lpsz); if (lpszAnsi != NULL && lpszAnsi[0] != '\0') { // IMPORTANT: string in the RPC BUFFER are NOT NULL terminated pDnsRPCName->cchNameLength = (BYTE)UTF8_LEN(lpszAnsi); // don't count NULL memcpy(pDnsRPCName->achName, lpszAnsi, pDnsRPCName->cchNameLength); } else { // // NTRAID#Windows Bugs-305034-2001/02/05-jeffjon : // According to JWesth a null string should be passed with cchNameLength = 1 // and the string a single NULL UTF8 character // pDnsRPCName->cchNameLength = 1; // We don't want the null terminator here so just copy the one byte. memcpy(pDnsRPCName->achName, "\0", 1); } // return length of the struct // (add size of cchNameLength (UCHAR) string length) return static_cast(pDnsRPCName->cchNameLength + 1); } #ifdef _DEBUG void CDNSRecord::TestRPCStuff(DNS_RPC_RECORD* pDnsRecord) { // // TEST ONLY!!!! // WORD nBytesLen = GetRPCRecordLength(); BYTE* pMem = (BYTE*)malloc(nBytesLen); if (!pMem) { return; } memset(pMem, 0x0, nBytesLen); DNS_RPC_RECORD* pDnsRecordTest = NULL; WriteRPCData(pMem, &pDnsRecordTest); ASSERT(pDnsRecordTest != NULL); // // got to test if it is the same // ASSERT(pDnsRecord->wDataLength == pDnsRecordTest->wDataLength); ASSERT(memcmp(pDnsRecord, pDnsRecordTest, SIZEOF_DNS_RPC_RECORD_HEADER + pDnsRecordTest->wDataLength) == 0); if (pMem) { free(pMem); pMem = 0; } } #endif //////////////////////////////////////////////////////////////////////////// // CDNSRecordNodeBase // {720132BB-44B2-11d1-B92F-00A0C9A06D2D} const GUID CDNSRecordNodeBase::NodeTypeGUID = { 0x720132bb, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } }; CDNSRecordNodeBase::~CDNSRecordNodeBase() { if (m_pDNSRecord != NULL) { delete m_pDNSRecord; m_pDNSRecord = NULL; } } void CDNSRecordNodeBase::SetViewOptions(DWORD dwRecordViewOptions) { // we do not own the upper WORD of the flags dwRecordViewOptions &= 0x0000ffff; // clear high WORD to be sure m_dwNodeFlags &= 0xffff0000; // clear all the flags m_dwNodeFlags |= dwRecordViewOptions; } HRESULT CDNSRecordNodeBase::OnSetToolbarVerbState(IToolbar* pToolbar, CNodeList*) { // // Set the button state for each button on the toolbar // VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE))); VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE))); VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE))); return S_OK; } BOOL CDNSRecordNodeBase::OnAddMenuItem(LPCONTEXTMENUITEM2, long*) { ASSERT(FALSE); // never called return FALSE; } BOOL CDNSRecordNodeBase::OnSetDeleteVerbState(DATA_OBJECT_TYPES, BOOL* pbHide, CNodeList* pNodeList) { if (pNodeList->GetCount() > 1) // multiple selection { *pbHide = TRUE; return FALSE; } *pbHide = FALSE; CDNSZoneNode* pZoneNode = GetDomainNode()->GetZoneNode(); if (pZoneNode->IsAutocreated() || (pZoneNode->GetZoneType() == DNS_ZONE_TYPE_SECONDARY) || (pZoneNode->GetZoneType() == DNS_ZONE_TYPE_STUB)) { return FALSE; } if (!CanDelete()) { return FALSE; } WORD wType = GetType(); if ((wType == DNS_TYPE_WINS) || (wType == DNS_TYPE_NBSTAT) || (wType == DNS_TYPE_NS) || (wType == DNS_TYPE_SOA)) { return FALSE; } return TRUE; } HRESULT CDNSRecordNodeBase::OnCommand(long, DATA_OBJECT_TYPES, CComponentDataObject*, CNodeList*) { ASSERT(FALSE); // never called!!! return E_FAIL; } LPCWSTR CDNSRecordNodeBase::GetString(int nCol) { switch (nCol) { case 0: return GetDisplayName(); case 1: { return CDNSRecordInfo::GetTypeString(m_pDNSRecord->GetType(), CDNSRecordInfo::fullName); } case 2: return (LPCWSTR)m_szDisplayData; } return g_lpszNullString; } int CDNSRecordNodeBase::GetImageIndex(BOOL) { return RECORD_IMAGE_BASE; } void CDNSRecordNodeBase::SetRecordName(LPCTSTR lpszName, BOOL bAtTheNode) { m_bAtTheNode = bAtTheNode; m_szDisplayName = m_bAtTheNode ? CDNSRecordInfo::GetAtTheNodeDisplayString() : lpszName; } BOOL CDNSRecordNodeBase::ZoneIsCache() { CDNSDomainNode* pDomainNode = GetDomainNode(); return (pDomainNode->GetZoneNode()->GetZoneType() == DNS_ZONE_TYPE_CACHE); } void CDNSRecordNodeBase::GetFullName(CString& szFullName) { CDNSDomainNode* pDomainNode = GetDomainNode(); ASSERT(pDomainNode != NULL); if (IsAtTheNode()) { szFullName = pDomainNode->GetFullName(); } else { CString szTrueName = GetTrueRecordName(); ASSERT(szTrueName.GetLength() > 0); LPCWSTR lpszDomainName = pDomainNode->GetFullName(); if ((lpszDomainName == NULL) || (lpszDomainName[0] == NULL)) { // domain with no name, use the RR display name as FQDN // this should be only with a temporary (fake) domain ASSERT(szTrueName[szTrueName.GetLength()-1] == TEXT('.')); szFullName = szTrueName; } else if ((lpszDomainName[0] == TEXT('.')) && (lpszDomainName[1] == NULL)) { // the "." domain could be the Root or Root Hints if ( IS_CLASS(*pDomainNode, CDNSRootHintsNode) && (szTrueName[szTrueName.GetLength()-1] == TEXT('.')) ) { // special case A records in Root Hints, they might // have "." at the end, e.g. "A.ROOT-SERVERS.NET." szFullName = szTrueName; } else { // no need for dot in the format string // e.g. "myhost" and "." gives "myhost." szFullName.Format(_T("%s%s"), (LPCWSTR)szTrueName, lpszDomainName); } } else { // standard case, e.g. "myhost" and "banana.com." // to get "myhost.banana.com." szFullName.Format(_T("%s.%s"), (LPCWSTR)szTrueName, lpszDomainName); } } TRACE(_T("\nCDNSRecordNodeBase::GetFullName(%s)\n"), (LPCTSTR)szFullName); } void CDNSRecordNodeBase::CreateFromRPCRecord(DNS_RPC_RECORD* pDnsRecord) { ASSERT(m_pDNSRecord == NULL); m_pDNSRecord = CreateRecord(); if (m_pDNSRecord) { m_pDNSRecord->ReadRPCData(pDnsRecord); m_pDNSRecord->UpdateDisplayData(m_szDisplayData); #ifdef _DEBUG // // TEST ONLY!!!! // m_pDNSRecord->TestRPCStuff(pDnsRecord); #endif } } void CDNSRecordNodeBase::CreateFromDnsQueryRecord(DNS_RECORD* pDnsQueryRecord, DWORD dwFlags) { ASSERT(m_pDNSRecord == NULL); m_pDNSRecord = CreateRecord(); if (m_pDNSRecord) { m_pDNSRecord->ReadDnsQueryData(pDnsQueryRecord); m_pDNSRecord->UpdateDisplayData(m_szDisplayData); m_pDNSRecord->m_dwFlags = dwFlags; } } CDNSRecord* CDNSRecordNodeBase::CreateCloneRecord() { ASSERT(m_pDNSRecord != NULL); CDNSRecord* pClone = CreateRecord(); if (pClone) { m_pDNSRecord->CloneValue(pClone); } return pClone; } BOOL CDNSRecordNodeBase::CanCloseSheets() { return (IDCANCEL != DNSMessageBox(IDS_MSG_RECORD_CLOSE_SHEET, MB_OKCANCEL)); } void CDNSRecordNodeBase::OnDelete(CComponentDataObject* pComponentData, CNodeList* pNodeList) { if (pNodeList->GetCount() > 1) // multiple selection { return; } UINT nRet = DNSConfirmOperation(IDS_MSG_RECORD_DELETE, this); if (IDCANCEL == nRet || IDNO == nRet) { return; } if (IsSheetLocked()) { if (!CanCloseSheets()) return; pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this); } ASSERT(!IsSheetLocked()); // try first to delete the record in the server DNS_STATUS err = DeleteOnServerAndUI(pComponentData); if (err != 0) { DNSErrorDialog(err, IDS_MSG_RECORD_FAIL_DELETE); return; } delete this; // gone } DNS_STATUS CDNSRecordNodeBase::DeleteOnServer() { ASSERT(m_pDNSRecord != NULL); CDNSDomainNode* pDomainNode = GetDomainNode(); ASSERT(pDomainNode != NULL); CDNSServerNode* pServerNode = pDomainNode->GetServerNode(); ASSERT(pServerNode != NULL); CString szFullName; GetFullName(szFullName); LPCTSTR lpszZoneNode = NULL; CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode(); if (pZoneNode != NULL) { if (pZoneNode->GetZoneType() != DNS_ZONE_TYPE_CACHE) { lpszZoneNode = pZoneNode->GetFullName(); if ((lpszZoneNode != NULL) && (lpszZoneNode[0] == NULL)) lpszZoneNode = NULL; } } return m_pDNSRecord->Delete(pServerNode->GetRPCName(), lpszZoneNode, szFullName); } DNS_STATUS CDNSRecordNodeBase::DeleteOnServerAndUI(CComponentDataObject* pComponentData) { ASSERT(pComponentData != NULL); DNS_STATUS err = DeleteOnServer(); if (err == 0) DeleteHelper(pComponentData); // delete in the UI and list of children return err; } BOOL CDNSRecordNodeBase::HasPropertyPages(DATA_OBJECT_TYPES, BOOL* pbHideVerb, CNodeList* pNodeList) { if (pNodeList->GetCount() > 1) // multiple selection { *pbHideVerb = TRUE; return FALSE; } *pbHideVerb = FALSE; // always show the verb return !GetDomainNode()->GetZoneNode()->IsAutocreated(); } HRESULT CDNSRecordNodeBase::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, CNodeList* pNodeList) { ASSERT(pNodeList->GetCount() == 1); // multi-select not supported CComponentDataObject* pComponentDataObject = ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject(); ASSERT(pComponentDataObject != NULL); HRESULT hr = S_OK; CDNSRecordPropertyPageHolder* pHolder = new CDNSRecordPropertyPageHolder((CDNSDomainNode*)GetContainer(), this, pComponentDataObject); if (pHolder) { if (IsAtTheNode()) { pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, GetContainer()); } else { pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this); } hr = pHolder->CreateModelessSheet(lpProvider, handle); } else { hr = E_OUTOFMEMORY; } return hr; } DNS_STATUS CDNSRecordNodeBase::Update(CDNSRecord* pDNSRecordNew, BOOL bUseDefaultTTL, BOOL bIgnoreAlreadyExists) { // get a new record, write to server, if successful copy it and substitute it in place of the old // passing pDNSRecordNew == NULL meand we are creating a new record BOOL bNew = (pDNSRecordNew == NULL); if (bNew) { pDNSRecordNew = m_pDNSRecord; m_pDNSRecord = NULL; } ASSERT(pDNSRecordNew != NULL); // try to write new record to the server, passing the old as comparison CDNSDomainNode* pDomainNode = GetDomainNode(); CString szFullName; LPCTSTR lpszServerName = pDomainNode->GetServerNode()->GetRPCName(); LPCTSTR lpszRecordName; if (IsAtTheNode()) { lpszRecordName = pDomainNode->GetFullName(); // e.g. "myzone.com" } else { GetFullName(szFullName); lpszRecordName = szFullName; // e.g. "myrec.myzone.com" } LPCTSTR lpszZoneNode = NULL; CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode(); if (pZoneNode != NULL) { if (pZoneNode->GetZoneType() != DNS_ZONE_TYPE_CACHE) { lpszZoneNode = pZoneNode->GetFullName(); if ((lpszZoneNode != NULL) && (lpszZoneNode[0] == NULL)) lpszZoneNode = NULL; } } DNS_STATUS err = pDNSRecordNew->Update(lpszServerName, lpszZoneNode, lpszRecordName, m_pDNSRecord, bUseDefaultTTL); if (bIgnoreAlreadyExists && (err == DNS_ERROR_RECORD_ALREADY_EXISTS) ) err = 0; // tried to write, but it was already there, so it is fine. if (err != 0 && err != DNS_WARNING_PTR_CREATE_FAILED) return err; // failed, no update to the record if (bNew) { // put back the existing DNSRecord, no need to create a new one ASSERT(pDNSRecordNew != NULL); m_pDNSRecord = pDNSRecordNew; } // update the record with the new one if (m_pDNSRecord == NULL) // we are creating a new record { m_pDNSRecord = CreateRecord(); } if (m_pDNSRecord) { m_pDNSRecord->SetValue(pDNSRecordNew); //Update the scavenging time on both the temporary and the node's CDNSRecord SetScavengingTime(m_pDNSRecord); SetScavengingTime(pDNSRecordNew); m_pDNSRecord->UpdateDisplayData(m_szDisplayData); } else { err = ERROR_OUTOFMEMORY; } return err; } void CDNSRecordNodeBase::SetScavengingTime(CDNSRecord* pRecord) { if (pRecord->m_dwFlags & DNS_RPC_RECORD_FLAG_AGING_ON) { pRecord->m_dwScavengeStart = CalculateScavengingTime(); } else { pRecord->m_dwScavengeStart = 0; } } DWORD CDNSRecordNodeBase::CalculateScavengingTime() { CDNSZoneNode* pZoneNode = GetDomainNode()->GetZoneNode(); ASSERT(pZoneNode != NULL); if (pZoneNode == NULL) return 0; SYSTEMTIME currentSysTime; ::GetSystemTime(¤tSysTime); LONGLONG llResult = GetSystemTime64(¤tSysTime); return static_cast(llResult / 3600L); } void CDNSRecordNodeBase::CreateDsRecordLdapPath(CString& sz) { CDNSDomainNode* pDomainNode = GetDomainNode(); CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode(); CDNSServerNode* pServerNode = pZoneNode->GetServerNode(); pServerNode->CreateDsZoneName(pZoneNode, sz); if (sz.IsEmpty()) return; // no LDAP path at all CString szTmp; // need to figure out the additional "DC = <>" part if (pDomainNode->IsZone() && IsAtTheNode()) { szTmp = L"DC=@,"; } else { CString szRecordFullName; if (IsAtTheNode()) { szRecordFullName = GetDomainNode()->GetFullName(); // e.g. "mydom.myzone.com" } else { GetFullName(szRecordFullName); // e.g. "myrec.mydom.myzone.com" } LPCTSTR lpszZoneName = pZoneNode->GetFullName(); // remove zone part (e.g. "myzone.com") from record name, // to get e.g. "mydom" or "myrec.mydom" int nZoneLen = static_cast(wcslen(lpszZoneName)); int nRecordLen = szRecordFullName.GetLength(); ASSERT(nRecordLen > nZoneLen); szTmp.Format(_T("DC=%s,"),(LPCTSTR)szRecordFullName.Left(nRecordLen-nZoneLen-1)); } szTmp += sz; pServerNode->CreateLdapPathFromX500Name(szTmp, sz); } /////////////////////////////////////////////////////////////////// // CDNS_Null_Record CDNS_Null_Record::CDNS_Null_Record() { m_wType = DNS_TYPE_NULL; } WORD CDNS_Null_Record::GetRPCDataLength() { return (WORD)m_blob.GetSize(); } void CDNS_Null_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); m_blob.Set(pDnsRecord->Data.Null.bData , pDnsRecord->wDataLength); } void CDNS_Null_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_Null_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); UINT nBytes = m_blob.GetSize(); memcpy((*ppDnsRecord)->Data.Null.bData, m_blob.GetData(), sizeof(BYTE)*nBytes); (*ppDnsRecord)->wDataLength = static_cast((((*ppDnsRecord)->wDataLength) + nBytes) & 0xffff); } void CDNS_Null_Record::UpdateDisplayData(CString& szDisplayData) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); szDisplayData.LoadString(IDS_RECORD_DATA_UNK); } /////////////////////////////////////////////////////////////////// // CDNS_A_Record CDNS_A_Record::CDNS_A_Record() { m_wType = DNS_TYPE_A; m_ipAddress = 0x0; } WORD CDNS_A_Record::GetRPCDataLength() { return (WORD)SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER; } void CDNS_A_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_A); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER); m_ipAddress = pDnsRecord->Data.A.ipAddress; } void CDNS_A_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(pDnsQueryRecord->wType == DNS_TYPE_A); m_ipAddress = pDnsQueryRecord->Data.A.IpAddress; } void CDNS_A_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.A.ipAddress = m_ipAddress; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER; } void CDNS_A_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Format(g_szIpStringFmt, IP_STRING_FMT_ARGS(m_ipAddress)); } /////////////////////////////////////////////////////////////////// // CDNS_ATMA_Record void _ATMA_BCD_ToString(CString& s, BYTE* pBuf) { const int nHexChars = 2*DNS_ATMA_MAX_ADDR_LENGTH+1; LPWSTR lpszBuf = s.GetBuffer(nHexChars); ZeroMemory(lpszBuf, nHexChars*sizeof(WCHAR)); for (int i=0; i(*(pBuf+i) >> 4); BYTE low = static_cast(*(pBuf+i) & 0x0f); // just offset out of the ASCII table *(lpszBuf+2*i) = static_cast((high <= 9) ? (high + TEXT('0')) : ( high - 10 + TEXT('a'))); *(lpszBuf+2*i+1) = static_cast((low <= 9) ? (low + TEXT('0')) : ( low - 10 + TEXT('a'))); } s.ReleaseBuffer(); } BOOL _ATMA_StringTo_BCD(BYTE* pBuf, LPCWSTR lpsz) { // verify the string is the right length size_t nLen = wcslen(lpsz); if (nLen != 2*DNS_ATMA_MAX_ADDR_LENGTH) return FALSE; ZeroMemory(pBuf, DNS_ATMA_MAX_ADDR_LENGTH); for (int i=0; i((high << 4) | (low & 0x0f)); } return TRUE; } CDNS_ATMA_Record::CDNS_ATMA_Record() { m_wType = DNS_TYPE_ATMA; m_chFormat = DNS_ATMA_FORMAT_E164; } WORD CDNS_ATMA_Record::GetRPCDataLength() { DWORD dwLen = SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER; ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA)); if (m_chFormat == DNS_ATMA_FORMAT_E164) { USES_CONVERSION; // it is a null terminated string dwLen += UTF8_LEN(W_TO_UTF8(m_szAddress)); // do not count NULL at the end } else { // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH dwLen += DNS_ATMA_MAX_ADDR_LENGTH; } return static_cast(dwLen); } void CDNS_ATMA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_ATMA); m_chFormat = pDnsRecord->Data.ATMA.chFormat; ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA)); if (m_chFormat == DNS_ATMA_FORMAT_E164) { // non NULL terminated string int nBytes = pDnsRecord->wDataLength - SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER; DnsUtf8ToWCStringHelper(m_szAddress, (LPSTR)pDnsRecord->Data.ATMA.bAddress, nBytes); } else { // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH ASSERT(pDnsRecord->wDataLength == (SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER+DNS_ATMA_MAX_ADDR_LENGTH)); _ATMA_BCD_ToString(m_szAddress, pDnsRecord->Data.ATMA.bAddress); } } void CDNS_ATMA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(pDnsQueryRecord->wType == DNS_TYPE_ATMA); ASSERT(FALSE); // TODO } void CDNS_ATMA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.ATMA.chFormat = m_chFormat; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER; ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA)); if (m_chFormat == DNS_ATMA_FORMAT_E164) { // it is a non null terminated string USES_CONVERSION; LPCSTR lpszAnsi = W_TO_UTF8(m_szAddress); if (lpszAnsi != NULL) { DWORD nAnsiLen = UTF8_LEN(lpszAnsi); if (nAnsiLen > DNS_ATMA_MAX_ADDR_LENGTH) nAnsiLen = DNS_ATMA_MAX_ADDR_LENGTH; UCHAR* pU = ((*ppDnsRecord)->Data.ATMA.bAddress); memcpy(pU, lpszAnsi, nAnsiLen); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + nAnsiLen) & 0xffff); } } else { // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH VERIFY(_ATMA_StringTo_BCD((*ppDnsRecord)->Data.ATMA.bAddress, m_szAddress)); (*ppDnsRecord)->wDataLength += DNS_ATMA_MAX_ADDR_LENGTH; } } void CDNS_ATMA_Record::UpdateDisplayData(CString& szDisplayData) { ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA)); if (m_chFormat == DNS_ATMA_FORMAT_E164) { szDisplayData.Format(L"(E164) %s", (LPCWSTR)m_szAddress); } else { szDisplayData.Format(L"(NSAP) %s", (LPCWSTR)m_szAddress); } } /////////////////////////////////////////////////////////////////// // CDNS_SOA_Record CDNS_SOA_Record::CDNS_SOA_Record() { m_wType = DNS_TYPE_SOA; m_dwSerialNo = 0x0; m_dwRefresh = 0x0; m_dwRetry = 0x0; m_dwExpire = 0x0; m_dwMinimumTtl = 0x0; } WORD CDNS_SOA_Record::GetRPCDataLength() { return static_cast(SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER + RPCBufferStringLen(m_szNamePrimaryServer) + RPCBufferStringLen(m_szResponsibleParty)); } void CDNS_SOA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_SOA); ASSERT(pDnsRecord->wDataLength >= (SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER +4)); // read header data m_dwSerialNo = pDnsRecord->Data.SOA.dwSerialNo; m_dwRefresh = pDnsRecord->Data.SOA.dwRefresh; m_dwRetry = pDnsRecord->Data.SOA.dwRetry; m_dwExpire = pDnsRecord->Data.SOA.dwExpire; m_dwMinimumTtl = pDnsRecord->Data.SOA.dwMinimumTtl; // read primary server name DNS_RPC_NAME* pRPCName1 = &(pDnsRecord->Data.SOA.namePrimaryServer); ReadRPCString(m_szNamePrimaryServer, pRPCName1); // read primary server name DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1); ASSERT(DNS_IS_NAME_IN_RECORD(pDnsRecord,pRPCName2)); ReadRPCString(m_szResponsibleParty, pRPCName2); ASSERT(pDnsRecord->wDataLength == (SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER + pRPCName1->cchNameLength + pRPCName2->cchNameLength + 2) ); } void CDNS_SOA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_SOA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // write header data (*ppDnsRecord)->Data.SOA.dwSerialNo = m_dwSerialNo; (*ppDnsRecord)->Data.SOA.dwRefresh = m_dwRefresh; (*ppDnsRecord)->Data.SOA.dwRetry = m_dwRetry; (*ppDnsRecord)->Data.SOA.dwExpire = m_dwExpire; (*ppDnsRecord)->Data.SOA.dwMinimumTtl = m_dwMinimumTtl; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER; // write primary server name DNS_RPC_NAME* pRPCName1 = &((*ppDnsRecord)->Data.SOA.namePrimaryServer); ASSERT(DNS_IS_DWORD_ALIGNED(pRPCName1)); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName1, m_szNamePrimaryServer)) & 0xffff); // write the responsible party DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName2, m_szResponsibleParty)) & 0xffff); ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName1)); ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName2)); } void CDNS_SOA_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Format(_T("[%u], %s, %s"), m_dwSerialNo, (LPCTSTR)m_szNamePrimaryServer,(LPCTSTR)m_szResponsibleParty); } /////////////////////////////////////////////////////////////////// // CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record:: CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record() { } WORD CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::GetRPCDataLength() { return RPCBufferStringLen(m_szNameNode); } void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record:: ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT( (pDnsRecord->wType == DNS_TYPE_PTR) || (pDnsRecord->wType == DNS_TYPE_NS) || (pDnsRecord->wType == DNS_TYPE_CNAME) || (pDnsRecord->wType == DNS_TYPE_MB) || (pDnsRecord->wType == DNS_TYPE_MD) || (pDnsRecord->wType == DNS_TYPE_MF) || (pDnsRecord->wType == DNS_TYPE_MG) || (pDnsRecord->wType == DNS_TYPE_MR) ); DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.NS.nameNode); ASSERT(pDnsRecord->wDataLength == pRPCName->cchNameLength +1); // read name node ReadRPCString(m_szNameNode, pRPCName); } void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT( (pDnsQueryRecord->wType == DNS_TYPE_PTR) || (pDnsQueryRecord->wType == DNS_TYPE_NS) || (pDnsQueryRecord->wType == DNS_TYPE_CNAME) || (pDnsQueryRecord->wType == DNS_TYPE_MB) || (pDnsQueryRecord->wType == DNS_TYPE_MD) || (pDnsQueryRecord->wType == DNS_TYPE_MF) || (pDnsQueryRecord->wType == DNS_TYPE_MG) || (pDnsQueryRecord->wType == DNS_TYPE_MR) ); m_szNameNode = pDnsQueryRecord->Data.NS.pNameHost; } void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record ::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // write name node DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.NS.nameNode); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName,m_szNameNode)) & 0xffff); } void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData = m_szNameNode; } /////////////////////////////////////////////////////////////////// // CDNS_MINFO_RP_Record CDNS_MINFO_RP_Record::CDNS_MINFO_RP_Record() { } WORD CDNS_MINFO_RP_Record::GetRPCDataLength() { return static_cast(RPCBufferStringLen(m_szNameMailBox) + RPCBufferStringLen(m_szErrorToMailbox)); } void CDNS_MINFO_RP_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT( (pDnsRecord->wType == DNS_TYPE_MINFO) || (pDnsRecord->wType == DNS_TYPE_RP)); // read mailbox name DNS_RPC_NAME* pRPCName1 = &(pDnsRecord->Data.MINFO.nameMailBox); ReadRPCString(m_szNameMailBox, pRPCName1); // read errors to mailbox DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1); ASSERT(DNS_IS_NAME_IN_RECORD(pDnsRecord,pRPCName2)); ReadRPCString(m_szErrorToMailbox, pRPCName2); ASSERT(pDnsRecord->wDataLength == (pRPCName1->cchNameLength + pRPCName2->cchNameLength + 2) ); } void CDNS_MINFO_RP_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_MINFO_RP_Record:: WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // write mailbox name DNS_RPC_NAME* pRPCName1 = &((*ppDnsRecord)->Data.MINFO.nameMailBox); ASSERT(DNS_IS_DWORD_ALIGNED(pRPCName1)); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName1, m_szNameMailBox)) & 0xffff); // write errors to mailbox DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName2, m_szErrorToMailbox)) & 0xffff); ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName1)); ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName2)); } void CDNS_MINFO_RP_Record::UpdateDisplayData(CString& szDisplayData) { if ((GetType() == DNS_TYPE_RP) && (m_szErrorToMailbox.IsEmpty())) { szDisplayData.Format(_T("%s"),(LPCTSTR)m_szNameMailBox); } else { szDisplayData.Format(_T("%s, %s"), (LPCTSTR)m_szNameMailBox,(LPCTSTR)m_szErrorToMailbox); } } /////////////////////////////////////////////////////////////////// // CDNS_MX_AFSDB_RT_Record CDNS_MX_AFSDB_RT_Record::CDNS_MX_AFSDB_RT_Record() { m_wPreference = 0x0; } WORD CDNS_MX_AFSDB_RT_Record::GetRPCDataLength() { return static_cast(SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER + RPCBufferStringLen(m_szNameExchange)); } void CDNS_MX_AFSDB_RT_Record:: ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT( (pDnsRecord->wType == DNS_TYPE_MX) || (pDnsRecord->wType == DNS_TYPE_AFSDB) || (pDnsRecord->wType == DNS_TYPE_RT)); // read header data m_wPreference = pDnsRecord->Data.MX.wPreference; // read name exchange DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.MX.nameExchange); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER + pRPCName->cchNameLength +1); ReadRPCString(m_szNameExchange, pRPCName); } void CDNS_MX_AFSDB_RT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_MX_AFSDB_RT_Record:: WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // write header data (*ppDnsRecord)->Data.MX.wPreference = m_wPreference; (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER) & 0xffff); // write name exchange DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.MX.nameExchange); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName,m_szNameExchange)) & 0xffff); } void CDNS_MX_AFSDB_RT_Record::UpdateDisplayData(CString& szDisplayData) { TCHAR szBuf[32]; szBuf[0] = NULL; LPCTSTR lpsz; if ( (m_wType == DNS_TYPE_AFSDB) && ((m_wPreference == AFSDB_PREF_AFS_CELL_DB_SERV) || (m_wPreference == AFSDB_PREF_DCE_AUTH_NAME_SERV)) ) { if (m_wPreference == AFSDB_PREF_AFS_CELL_DB_SERV) lpsz = _T("AFS"); else lpsz = _T("DCE"); } else { wsprintf(szBuf,_T("%d"), m_wPreference); lpsz = szBuf; } szDisplayData.Format(_T("[%s] %s"), lpsz,(LPCTSTR)m_szNameExchange); } /////////////////////////////////////////////////////////////////// // CDNS_AAAA_Record CDNS_AAAA_Record::CDNS_AAAA_Record() { m_wType = DNS_TYPE_AAAA; memset(&m_ipv6Address, 0x0,sizeof(IPV6_ADDRESS)); } WORD CDNS_AAAA_Record::GetRPCDataLength() { return (WORD)SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER; } void CDNS_AAAA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_AAAA); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER); memcpy(&m_ipv6Address, (UNALIGNED IPV6_ADDRESS*)(&(pDnsRecord->Data.AAAA.ipv6Address)), sizeof(IPV6_ADDRESS)); } void CDNS_AAAA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_AAAA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); memcpy(&((*ppDnsRecord)->Data.AAAA.ipv6Address), &m_ipv6Address, sizeof(IPV6_ADDRESS)); (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER; } void CDNS_AAAA_Record::UpdateDisplayData(CString& szDisplayData) { FormatIPv6Addr(szDisplayData, &m_ipv6Address); } /////////////////////////////////////////////////////////////////// // CDNS_HINFO_ISDN_TXT_X25_Record CDNS_HINFO_ISDN_TXT_X25_Record:: CDNS_HINFO_ISDN_TXT_X25_Record() { } WORD CDNS_HINFO_ISDN_TXT_X25_Record::GetRPCDataLength() { ASSERT(FALSE); // intermediate class return 0; } void CDNS_HINFO_ISDN_TXT_X25_Record:: ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT( (pDnsRecord->wType == DNS_TYPE_HINFO) || (pDnsRecord->wType == DNS_TYPE_ISDN) || (pDnsRecord->wType == DNS_TYPE_TEXT) || (pDnsRecord->wType == DNS_TYPE_X25) ); // loop to the end of the buffer and copy into array of strings DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.HINFO.stringData); int k = 0; WORD wDataLength = 0x0; CString szTemp; while ((PCHAR)pRPCName < DNS_GET_END_OF_RPC_RECORD_DATA(pDnsRecord)) { ReadRPCString(szTemp, pRPCName); OnReadRPCString(szTemp, k++); wDataLength = wDataLength + static_cast(pRPCName->cchNameLength + 1); pRPCName = DNS_GET_NEXT_NAME(pRPCName); } SetStringCount(k); ASSERT(pDnsRecord->wDataLength == wDataLength); } void CDNS_HINFO_ISDN_TXT_X25_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_HINFO_ISDN_TXT_X25_Record:: WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // loop through the list of strings DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.HINFO.stringData); int nCount = GetStringCount(); for (int j=0; j < nCount; j++) { //(*ppDnsRecord)->wDataLength += WriteString(pRPCName,m_stringDataArray[j]); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + OnWriteString(pRPCName,j)) & 0xffff); pRPCName = DNS_GET_NEXT_NAME(pRPCName); } } void CDNS_HINFO_ISDN_TXT_X25_Record::UpdateDisplayData(CString& szDisplayData) { ASSERT(FALSE); szDisplayData = _T("ERROR, should never happen"); } /////////////////////////////////////////////////////////////////// // CDNS_HINFO_Record WORD CDNS_HINFO_Record::GetRPCDataLength() { return static_cast(RPCBufferStringLen(m_szCPUType) + RPCBufferStringLen(m_szOperatingSystem)); } void CDNS_HINFO_Record::OnReadRPCString(LPCTSTR lpszStr, int k) { switch (k) { case 0: m_szCPUType = lpszStr; break; case 1: m_szOperatingSystem = lpszStr; break; default: ASSERT(FALSE); } } WORD CDNS_HINFO_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k) { switch (k) { case 0: return WriteString(pDnsRPCName,m_szCPUType); case 1: return WriteString(pDnsRPCName,m_szOperatingSystem); default: ASSERT(FALSE); } return 0; } void CDNS_HINFO_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Format(_T("%s, %s"),(LPCTSTR)m_szCPUType, (LPCTSTR)m_szOperatingSystem); } /////////////////////////////////////////////////////////////////// // CDNS_ISDN_Record WORD CDNS_ISDN_Record::GetRPCDataLength() { return static_cast(RPCBufferStringLen(m_szPhoneNumberAndDDI) + RPCBufferStringLen(m_szSubAddress)); } CDNS_ISDN_Record::CDNS_ISDN_Record() { m_wType = DNS_TYPE_ISDN; } void CDNS_ISDN_Record::OnReadRPCString(LPCTSTR lpszStr, int k) { switch (k) { case 0: m_szPhoneNumberAndDDI = lpszStr; m_szSubAddress.Empty(); // copy from 2 to 1 strings might not execute case 1: break; case 1: m_szSubAddress = lpszStr; break; default: ASSERT(FALSE); } } WORD CDNS_ISDN_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k) { switch (k) { case 0: return WriteString(pDnsRPCName,m_szPhoneNumberAndDDI); case 1: { ASSERT(!m_szSubAddress.IsEmpty()); if (m_szSubAddress.IsEmpty()) return 0; return WriteString(pDnsRPCName,m_szSubAddress); } default: ASSERT(FALSE); } return 0; } void CDNS_ISDN_Record::UpdateDisplayData(CString& szDisplayData) { if(m_szSubAddress.IsEmpty()) szDisplayData = m_szPhoneNumberAndDDI; else szDisplayData.Format(_T("%s, %s"),(LPCTSTR)m_szPhoneNumberAndDDI, (LPCTSTR)m_szSubAddress); } /////////////////////////////////////////////////////////////////// // CDNS_TXT_Record CDNS_TXT_Record::CDNS_TXT_Record() { m_wType = DNS_TYPE_TEXT; m_stringDataArray.SetSize(2,2); // SetSize(size, grow by) m_nStringDataCount = 0; // empty } WORD CDNS_TXT_Record::GetRPCDataLength() { WORD wLen = 0; for (int j=0; j((wLen + (RPCBufferStringLen(m_stringDataArray[j])) & 0xffff)); } return wLen; } void CDNS_TXT_Record::OnReadRPCString(LPCTSTR lpszStr, int k) { m_stringDataArray.SetAtGrow(k,lpszStr); } WORD CDNS_TXT_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k) { return WriteString(pDnsRPCName,m_stringDataArray[k]); } #define MAX_TXT_DISPLAYLEN 80 // arbitrary width void CDNS_TXT_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Empty(); if (m_nStringDataCount == 0) return; szDisplayData = m_stringDataArray[0]; if (szDisplayData.GetLength() > MAX_TXT_DISPLAYLEN) { szDisplayData.Left(MAX_TXT_DISPLAYLEN); szDisplayData += _T(" ..."); return; } for (int j=1; j MAX_TXT_DISPLAYLEN) { szDisplayData.Left(MAX_TXT_DISPLAYLEN); szDisplayData += _T(" ..."); break; } } } /////////////////////////////////////////////////////////////////// // CDNS_X25_Record WORD CDNS_X25_Record::GetRPCDataLength() { return RPCBufferStringLen(m_szX121PSDNAddress); } void CDNS_X25_Record::OnReadRPCString(LPCTSTR lpszStr, int k) { ASSERT(k == 0); m_szX121PSDNAddress = lpszStr; } WORD CDNS_X25_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k) { ASSERT(k == 0); return WriteString(pDnsRPCName,m_szX121PSDNAddress); } void CDNS_X25_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData = m_szX121PSDNAddress; } /////////////////////////////////////////////////////////////////// // CDNS_WKS_Record CDNS_WKS_Record::CDNS_WKS_Record() { m_wType = DNS_TYPE_WKS; m_ipAddress = 0x0; m_chProtocol = DNS_WKS_PROTOCOL_TCP; //m_bBitMask[0] = 0x0; } WORD CDNS_WKS_Record::GetRPCDataLength() { return static_cast(SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER + RPCBufferStringLen(m_szServiceList)); } void CDNS_WKS_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_WKS); m_ipAddress = pDnsRecord->Data.WKS.ipAddress; m_chProtocol = pDnsRecord->Data.WKS.chProtocol; DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)(pDnsRecord->Data.WKS.bBitMask); ReadRPCString(m_szServiceList, pRPCName); //ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER); //m_ipAddress = pDnsRecord->Data.WKS.ipAddress; //m_chProtocol = pDnsRecord->Data.WKS.chProtocol; //m_bBitMask[0] = pDnsRecord->Data.WKS.bBitMask[0]; } void CDNS_WKS_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_WKS_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.WKS.ipAddress = m_ipAddress; (*ppDnsRecord)->Data.WKS.chProtocol = m_chProtocol; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER; DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)((*ppDnsRecord)->Data.WKS.bBitMask); ASSERT(!DNS_IS_DWORD_ALIGNED(pRPCName)); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName, m_szServiceList)) & 0xffff); // (*ppDnsRecord)->Data.WKS.ipAddress = m_ipAddress; // (*ppDnsRecord)->Data.WKS.chProtocol = m_chProtocol; // (*ppDnsRecord)->Data.WKS.bBitMask[0] = m_bBitMask[0]; } void CDNS_WKS_Record::UpdateDisplayData(CString& szDisplayData) { TCHAR szBuf[32]; szBuf[0] = NULL; LPCTSTR lpsz; if (m_chProtocol == DNS_WKS_PROTOCOL_TCP) lpsz = _T("TCP"); else if (m_chProtocol == DNS_WKS_PROTOCOL_UDP) lpsz = _T("UDP"); else { wsprintf(szBuf,_T("%d"), m_chProtocol); lpsz = szBuf; } szDisplayData.Format(_T("[%s] %s"), lpsz,(LPCTSTR)m_szServiceList); } /////////////////////////////////////////////////////////////////// // CDNS_WINS_Record CDNS_WINS_Record::CDNS_WINS_Record() { m_wType = DNS_TYPE_WINS; m_dwMappingFlag = 0x0; m_dwLookupTimeout = DNS_RR_WINS_LOOKUP_DEFAULT_TIMEOUT; m_dwCacheTimeout = DNS_RR_WINS_CACHE_DEFAULT_TIMEOUT; m_ipWinsServersArray.SetSize(4,4); // SetSize(size, grow by) m_nWinsServerCount = 0; // empty } WORD CDNS_WINS_Record::GetRPCDataLength() { return static_cast((SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER + m_nWinsServerCount*sizeof(IP_ADDRESS)) & 0xff); } void CDNS_WINS_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_WINS); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER + pDnsRecord->Data.WINS.cWinsServerCount*sizeof(IP_ADDRESS)); m_dwMappingFlag = pDnsRecord->Data.WINS.dwMappingFlag; m_dwLookupTimeout = pDnsRecord->Data.WINS.dwLookupTimeout; m_dwCacheTimeout = pDnsRecord->Data.WINS.dwCacheTimeout; m_nWinsServerCount = pDnsRecord->Data.WINS.cWinsServerCount; for (DWORD k=0; kData.WINS.cWinsServerCount; k++) m_ipWinsServersArray.SetAtGrow(k, pDnsRecord->Data.WINS.aipWinsServers[k]); } void CDNS_WINS_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_WINS_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.WINS.dwMappingFlag = m_dwMappingFlag; (*ppDnsRecord)->Data.WINS.dwLookupTimeout = m_dwLookupTimeout; (*ppDnsRecord)->Data.WINS.dwCacheTimeout = m_dwCacheTimeout; (*ppDnsRecord)->Data.WINS.cWinsServerCount = m_nWinsServerCount; for (DWORD k=0; k<(*ppDnsRecord)->Data.WINS.cWinsServerCount; k++) (*ppDnsRecord)->Data.WINS.aipWinsServers[k] = m_ipWinsServersArray[k]; (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER + (*ppDnsRecord)->Data.WINS.cWinsServerCount*sizeof(IP_ADDRESS)) & 0xffff); } void CDNS_WINS_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Empty(); if (m_nWinsServerCount == 0) return; // need to chain the IP addresses in a single string CString szTemp; szTemp.GetBuffer(20); // length of an IP string szTemp.ReleaseBuffer(); szDisplayData.GetBuffer(20*m_nWinsServerCount); szDisplayData.ReleaseBuffer(); for (int k=0; k(SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER + RPCBufferStringLen(m_szNameResultDomain)); } void CDNS_NBSTAT_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_NBSTAT); m_dwMappingFlag = pDnsRecord->Data.NBSTAT.dwMappingFlag; m_dwLookupTimeout = pDnsRecord->Data.NBSTAT.dwLookupTimeout; m_dwCacheTimeout = pDnsRecord->Data.NBSTAT.dwCacheTimeout; DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.NBSTAT.nameResultDomain); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER + pRPCName->cchNameLength +1); ReadRPCString(m_szNameResultDomain, pRPCName); } void CDNS_NBSTAT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_NBSTAT_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.NBSTAT.dwMappingFlag = m_dwMappingFlag; (*ppDnsRecord)->Data.NBSTAT.dwLookupTimeout = m_dwLookupTimeout; (*ppDnsRecord)->Data.NBSTAT.dwCacheTimeout= m_dwCacheTimeout; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER; DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.NBSTAT.nameResultDomain); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName,m_szNameResultDomain)) & 0xffff); } void CDNS_NBSTAT_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData = m_szNameResultDomain; } /////////////////////////////////////////////////////////////////// // CDNS_SRV_Record CDNS_SRV_Record::CDNS_SRV_Record() { m_wType = DNS_TYPE_SRV; m_wPriority = 0x0; m_wWeight = 0x0; m_wPort = 0x0; } WORD CDNS_SRV_Record::GetRPCDataLength() { return static_cast(SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER + RPCBufferStringLen(m_szNameTarget)); } void CDNS_SRV_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_SRV); m_wPriority = pDnsRecord->Data.SRV.wPriority; m_wWeight = pDnsRecord->Data.SRV.wWeight; m_wPort= pDnsRecord->Data.SRV.wPort; DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.SRV.nameTarget); ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER + pRPCName->cchNameLength +1); ReadRPCString(m_szNameTarget, pRPCName); } void CDNS_SRV_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(FALSE); // TODO } void CDNS_SRV_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.SRV.wPriority = m_wPriority; (*ppDnsRecord)->Data.SRV.wWeight = m_wWeight; (*ppDnsRecord)->Data.SRV.wPort = m_wPort; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER; DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.SRV.nameTarget); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName,m_szNameTarget)) & 0xffff); } void CDNS_SRV_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Format(_T("[%d][%d][%d] %s"), m_wPriority, m_wWeight, m_wPort, m_szNameTarget); } /////////////////////////////////////////////////////////////////// // CDNS_SIG_Record CDNS_SIG_Record::CDNS_SIG_Record() { m_wType = DNS_TYPE_SIG; m_wTypeCovered = 0; m_chAlgorithm = 0; m_chLabels = 0; m_dwOriginalTtl = 0; m_dwExpiration = 0; m_dwTimeSigned = 0; m_wKeyFootprint = 0; m_szSignerName = L""; } WORD CDNS_SIG_Record::GetRPCDataLength() { WORD wSize = static_cast(SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER); wSize = static_cast(wSize + RPCBufferStringLen(m_szSignerName)); wSize = static_cast(wSize + m_Signature.GetSize()); return wSize; } void CDNS_SIG_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_SIG); ASSERT(pDnsRecord->wDataLength >= (SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER)); // constant length data m_wTypeCovered = pDnsRecord->Data.SIG.wTypeCovered; m_chAlgorithm = pDnsRecord->Data.SIG.chAlgorithm; m_chLabels = pDnsRecord->Data.SIG.chLabelCount; m_dwOriginalTtl = pDnsRecord->Data.SIG.dwOriginalTtl; m_dwExpiration = pDnsRecord->Data.SIG.dwSigExpiration; m_dwTimeSigned = pDnsRecord->Data.SIG.dwSigInception; m_wKeyFootprint = pDnsRecord->Data.SIG.wKeyTag; ReadRPCString(m_szSignerName, &(pDnsRecord->Data.SIG.nameSigner)); BYTE* pBlob = (BYTE*)DNS_GET_NEXT_NAME(&(pDnsRecord->Data.SIG.nameSigner)); UINT blobSize = pDnsRecord->wDataLength - SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER; // Due to DNS server bug 716362 we must special case the length of the // nameSigner. The server is returning a cchNameLength of 0 with no achString // data. We are expecting a cchNameLength of 1 and an achString of '\0' when // the string is empty. This only seems to happen for SIG records if (pDnsRecord->Data.SIG.nameSigner.cchNameLength == 0) { blobSize -= sizeof(UCHAR); } else { blobSize -= RPCBufferStringLen(m_szSignerName); } m_Signature.Set(pBlob, blobSize); } void CDNS_SIG_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(pDnsQueryRecord->wType == DNS_TYPE_SIG); ASSERT(FALSE); // TODO } void CDNS_SIG_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); // constant length data (*ppDnsRecord)->Data.SIG.wTypeCovered = m_wTypeCovered; (*ppDnsRecord)->Data.SIG.chAlgorithm = m_chAlgorithm; (*ppDnsRecord)->Data.SIG.chLabelCount = m_chLabels; (*ppDnsRecord)->Data.SIG.dwOriginalTtl = m_dwOriginalTtl; (*ppDnsRecord)->Data.SIG.dwSigExpiration = m_dwExpiration; (*ppDnsRecord)->Data.SIG.dwSigInception = m_dwTimeSigned; (*ppDnsRecord)->Data.SIG.wKeyTag = m_wKeyFootprint; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER; DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.SIG.nameSigner); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName, m_szSignerName)) & 0xffff); BYTE* pSignature = (BYTE*)DNS_GET_NEXT_NAME(&((*ppDnsRecord)->Data.SIG.nameSigner)); memcpy(pSignature, m_Signature.GetData(), m_Signature.GetSize()); (*ppDnsRecord)->wDataLength = static_cast((*ppDnsRecord)->wDataLength + m_Signature.GetSize()); } void CDNS_SIG_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Empty(); // // Load the type covered // PCWSTR pszDisplay = NULL; DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable(); while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { if (pTable->wType == m_wTypeCovered) { pszDisplay = pTable->lpszShortName; break; } pTable++; } szDisplayData += L"["; szDisplayData += pszDisplay; szDisplayData += L"]"; // // Show the inception date // CString szInceptionTime; if (::ConvertTTLToLocalTimeString(m_dwTimeSigned, szInceptionTime)) { szDisplayData += L"[Inception:"; szDisplayData += szInceptionTime; szDisplayData += L"]"; } // // Show the expiration date // CString szExpirationTime; if (::ConvertTTLToLocalTimeString(m_dwExpiration, szExpirationTime)) { szDisplayData += L"[Expiration:"; szDisplayData += szExpirationTime; szDisplayData += L"]"; } // // Show the signer's name // szDisplayData += L"["; szDisplayData += m_szSignerName; szDisplayData += L"]"; // // Show the algorithms // PCOMBOBOX_TABLE_ENTRY pTableEntry = g_Algorithms; while (pTableEntry->nComboStringID != 0) { if (static_cast(pTableEntry->dwComboData) == m_chAlgorithm) { CString szAlgorithm; VERIFY(szAlgorithm.LoadString(pTableEntry->nComboStringID)); szDisplayData += L"["; szDisplayData += szAlgorithm; szDisplayData += L"]"; break; } pTableEntry++; } // // Show the label count // szDisplayData.Format(L"%s[%d]", szDisplayData, m_chLabels); // // Show the key footprint // szDisplayData.Format(L"%s[%d]", szDisplayData, m_wKeyFootprint); // // Show the key as base64 // szDisplayData += L"["; szDisplayData += Base64BLOBToString(m_Signature); szDisplayData += L"]"; } /////////////////////////////////////////////////////////////////// // CDNS_KEY_Record CDNS_KEY_Record::CDNS_KEY_Record() { m_wType = DNS_TYPE_KEY; m_wFlags = 0; m_chProtocol = 0; m_chAlgorithm = 0; } WORD CDNS_KEY_Record::GetRPCDataLength() { WORD wKeySize = static_cast(m_Key.GetSize()); WORD wSize = static_cast(SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER + wKeySize); return wSize; } void CDNS_KEY_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_KEY); m_wFlags = pDnsRecord->Data.KEY.wFlags; m_chProtocol = pDnsRecord->Data.KEY.chProtocol; m_chAlgorithm = pDnsRecord->Data.KEY.chAlgorithm; // // set the blob // m_Key.Set(pDnsRecord->Data.KEY.bKey, pDnsRecord->wDataLength - SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER); } void CDNS_KEY_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(pDnsQueryRecord->wType == DNS_TYPE_KEY); ASSERT(FALSE); // TODO } void CDNS_KEY_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->Data.KEY.wFlags = m_wFlags; (*ppDnsRecord)->Data.KEY.chProtocol = m_chProtocol; (*ppDnsRecord)->Data.KEY.chAlgorithm = m_chAlgorithm; (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER; BYTE* pKey = (*ppDnsRecord)->Data.KEY.bKey; (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + m_Key.Get(pKey)) & 0xffff); } void CDNS_KEY_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData.Empty(); // // Turn the bitfield into a binary string // CString szTempField; WORD wTemp = m_wFlags; for (size_t idx = 0; idx < sizeof(WORD) * 8; idx++) { if ((wTemp & (0x1 << idx)) == 0) { szTempField = L'0' + szTempField; } else { szTempField = L'1' + szTempField; } } szDisplayData += _T("[") + szTempField + _T("]"); // // Load the protocols // PCOMBOBOX_TABLE_ENTRY pTableEntry = g_Protocols; while (pTableEntry->nComboStringID != 0) { if (static_cast(pTableEntry->dwComboData) == m_chProtocol) { CString szProtocol; VERIFY(szProtocol.LoadString(pTableEntry->nComboStringID)); szDisplayData += L"["; szDisplayData += szProtocol; szDisplayData += L"]"; break; } pTableEntry++; } // // Load the algorithms // pTableEntry = g_Algorithms; while (pTableEntry->nComboStringID != 0) { if (static_cast(pTableEntry->dwComboData) == m_chAlgorithm) { CString szAlgorithm; VERIFY(szAlgorithm.LoadString(pTableEntry->nComboStringID)); szDisplayData += L"["; szDisplayData += szAlgorithm; szDisplayData += L"]"; break; } pTableEntry++; } // // Show the key as base64 // szDisplayData += L"["; szDisplayData += Base64BLOBToString(m_Key); szDisplayData += L"]"; } /////////////////////////////////////////////////////////////////// // CDNS_NXT_Record CDNS_NXT_Record::CDNS_NXT_Record() { m_wType = DNS_TYPE_NXT; m_wNumTypesCovered = 0; m_pwTypesCovered = NULL; } CDNS_NXT_Record::~CDNS_NXT_Record() { if (m_pwTypesCovered != NULL) { delete[] m_pwTypesCovered; m_pwTypesCovered = NULL; } m_wNumTypesCovered = 0; } WORD CDNS_NXT_Record::GetRPCDataLength() { WORD wSize = RPCBufferStringLen(m_szNextDomain); wSize = wSize + static_cast(m_wNumTypesCovered * sizeof(WORD)); wSize += static_cast(SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER); return wSize; } void CDNS_NXT_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord) { CDNSRecord::ReadRPCData(pDnsRecord); ASSERT(pDnsRecord->wType == DNS_TYPE_NXT); m_wNumTypesCovered = pDnsRecord->Data.NXT.wNumTypeWords; m_pwTypesCovered = new WORD[m_wNumTypesCovered]; if (m_pwTypesCovered != NULL) { for (DWORD dwIdx = 0; dwIdx < m_wNumTypesCovered; dwIdx++) { m_pwTypesCovered[dwIdx] = pDnsRecord->Data.NXT.wTypeWords[dwIdx]; } } ReadRPCString(m_szNextDomain, (DNS_RPC_STRING*)(pDnsRecord->Data.NXT.wTypeWords + m_wNumTypesCovered)); } void CDNS_NXT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord) { CDNSRecord::ReadDnsQueryData(pDnsQueryRecord); ASSERT(pDnsQueryRecord->wType == DNS_TYPE_NXT); ASSERT(FALSE); // TODO } void CDNS_NXT_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord) { CDNSRecord::WriteRPCData(pMem, ppDnsRecord); (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER; (*ppDnsRecord)->Data.NXT.wNumTypeWords = m_wNumTypesCovered; WORD* pTypesCovered = (*ppDnsRecord)->Data.NXT.wTypeWords; if (pTypesCovered != NULL) { memcpy(pTypesCovered, m_pwTypesCovered, m_wNumTypesCovered * sizeof(WORD)); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + m_wNumTypesCovered * sizeof(WORD)) & 0xffff); } DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)(pTypesCovered + m_wNumTypesCovered); (*ppDnsRecord)->wDataLength = static_cast(((*ppDnsRecord)->wDataLength + WriteString(pRPCName,m_szNextDomain)) & 0xffff); } void CDNS_NXT_Record::UpdateDisplayData(CString& szDisplayData) { szDisplayData = m_szNextDomain; if (m_wNumTypesCovered > 0) { szDisplayData += L"["; UINT nCount = 0; for (DWORD dwIdx = 0; dwIdx < m_wNumTypesCovered; dwIdx++) { DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable(); while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { if (pTable->dwFlags & DNS_RECORD_INFO_FLAG_SHOW_NXT) { if (pTable->wType == m_pwTypesCovered[dwIdx]) { if (nCount > 0) { szDisplayData += L","; } szDisplayData += pTable->lpszShortName; nCount++; } } pTable++; } } szDisplayData += L"]"; } } /////////////////////////////////////////////////////////////////// // CDNS_PTR_RecordNode LPCWSTR CDNS_PTR_RecordNode::GetTrueRecordName() { return m_szLastOctectName; } void CDNS_PTR_RecordNode::SetRecordName(LPCTSTR lpszName, BOOL bAtTheNode) { // ASSERT(!bAtTheNode); // must have a non null name all the time m_bAtTheNode = bAtTheNode; #ifdef _DEBUG int nDots = 0; LPWSTR p = (LPWSTR)lpszName; while (*p) { if (*p == TEXT('.')) nDots++; p++; } ASSERT(nDots == 0); #endif // _DEBUG m_szDisplayName = m_bAtTheNode ? CDNSRecordInfo::GetAtTheNodeDisplayString() : lpszName; // m_szDisplayName = lpszName; m_szLastOctectName = lpszName; } void CDNS_PTR_RecordNode::ChangeDisplayName(CDNSDomainNode* pDomainNode, BOOL bAdvancedView) { if (IsAtTheNode()) { return; } if ((!pDomainNode->GetZoneNode()->IsReverse()) || bAdvancedView) { // for fwd lookup or advanced view, do not change the name m_szDisplayName = m_szLastOctectName; } else { ASSERT(pDomainNode != NULL); LPCWSTR lpszFullName = pDomainNode->GetFullName(); // e.g. "80.55.157.in-addr.arpa" m_szDisplayName.Format(_T("%s.%s"), (LPCTSTR)m_szLastOctectName, lpszFullName); // now got "77.80.55.157.in-addr.arpa" BOOL bArpa = RemoveInAddrArpaSuffix(m_szDisplayName.GetBuffer(1)); m_szDisplayName.ReleaseBuffer(); // got "77.80.55.157" if (!bArpa) { // failed to detect the arpa suffix, just restore the advanced name m_szDisplayName = m_szLastOctectName; } else { ReverseIPString(m_szDisplayName.GetBuffer(1)); m_szDisplayName.ReleaseBuffer(); // finally got "157.55.80.77" } } } //////////////////////////////////////////////////////////////////////////// // special data structures and definitions to handle NS record editing //////////////////////////////////////////////////////////////////////////// // CDNSRecordNodeEditInfo CDNSRecordNodeEditInfo::CDNSRecordNodeEditInfo() { m_pRecordNode = NULL; m_pRecord = NULL; m_pEditInfoList = new CDNSRecordNodeEditInfoList; m_bExisting = TRUE; m_bUpdateUI = TRUE; m_bOwnMemory = FALSE; m_bFromDnsQuery = FALSE; m_action = unchanged; m_dwErr = 0x0; } CDNSRecordNodeEditInfo::~CDNSRecordNodeEditInfo() { Cleanup(); delete m_pEditInfoList; ASSERT(m_pRecordNode == NULL); ASSERT(m_pRecord == NULL); } void CDNSRecordNodeEditInfo::CreateFromExistingRecord(CDNSRecordNodeBase* pNode, BOOL bOwnMemory, BOOL bUpdateUI) { // copy the pointer to record node, and possibli assume ownership of memory // but clone the record for editing ASSERT(pNode != NULL); m_bExisting = TRUE; m_bUpdateUI = bUpdateUI; m_bOwnMemory = bOwnMemory; m_pRecordNode = pNode; m_pRecord = pNode->CreateCloneRecord(); m_action = unchanged; } void CDNSRecordNodeEditInfo::CreateFromNewRecord(CDNSRecordNodeBase* pNode) { // this is a new record, so we own the memory ASSERT(pNode != NULL); m_bExisting = FALSE; m_bOwnMemory = TRUE; m_pRecordNode = pNode; m_pRecord = pNode->CreateRecord(); m_action = add; } void CDNSRecordNodeEditInfo::Cleanup() { if (m_bOwnMemory && (m_pRecordNode != NULL)) delete m_pRecordNode; m_pRecordNode = NULL; if (m_pRecord != NULL) { delete m_pRecord; // if here, always to be discarded m_pRecord = NULL; } m_pEditInfoList->RemoveAllNodes(); } DNS_STATUS CDNSRecordNodeEditInfo::Update(CDNSDomainNode* pDomainNode, CComponentDataObject* pComponentData) { ASSERT((m_action == add) || (m_action == edit) || (m_action == unchanged)); if (m_action == add) { // new record // hook up container and set name of node (same as the zone) m_pRecordNode->SetContainer(pDomainNode); } else if (m_action == edit) { // preexisting, might have touched the TTL // just in case domain node was not set when reading the RR m_pRecordNode->SetContainer(pDomainNode); } // force a write, ignoring error if the record already exists BOOL bUseDefaultTTL = (m_pRecord->m_dwTtlSeconds == pDomainNode->GetDefaultTTL()); m_dwErr = m_pRecordNode->Update(m_pRecord, bUseDefaultTTL, /*bIgnoreAlreadyExists*/ TRUE); if (m_dwErr == 0 && m_bUpdateUI) { // update the UI if (m_action == add) { VERIFY(pDomainNode->AddChildToListAndUI(m_pRecordNode, pComponentData)); pComponentData->SetDescriptionBarText(pDomainNode); } else // edit { if (pDomainNode->IsVisible()) { long changeMask = CHANGE_RESULT_ITEM; VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pRecordNode, changeMask))); } } } return m_dwErr; } DNS_STATUS CDNSRecordNodeEditInfo::Remove(CDNSDomainNode* pDomainNode, CComponentDataObject* pComponentData) { if (m_bUpdateUI) { ASSERT(m_pRecordNode->GetDomainNode() == pDomainNode); m_dwErr = m_pRecordNode->DeleteOnServerAndUI(pComponentData); } else { // temporarily attach the provided domain if (m_pRecordNode->GetContainer() == NULL) m_pRecordNode->SetContainer(pDomainNode); m_pRecordNode->DeleteOnServer(); } if (m_dwErr == 0) { // own memory from now on m_bOwnMemory = TRUE; } return m_dwErr; } //////////////////////////////////////////////////////////////////////////// // CDNSRecordInfo : table driven info for record types CDNSRecordNodeBase* CDNSRecordInfo::CreateRecordNodeFromRPCData(LPCTSTR lpszName, DNS_RPC_RECORD* pDnsRecord, BOOL bAtTheNode) { ASSERT(pDnsRecord != NULL); // // construct an object of the right type // CDNSRecordNodeBase* pNode = CreateRecordNode(pDnsRecord->wType); if (pNode == NULL) { return NULL; } // // set the object from RPC buffer // pNode->SetRecordName(lpszName, bAtTheNode); pNode->CreateFromRPCRecord(pDnsRecord); return pNode; } #define SWITCH_ENTRY(x) \ case DNS_TYPE_##x : \ pNode = new CDNS_##x_RecordNode; \ break; CDNSRecordNodeBase* CDNSRecordInfo::CreateRecordNode(WORD wType) { CDNSRecordNodeBase* pNode = NULL; // construct an object of the right type switch (wType) { case DNS_TYPE_A: pNode = new CDNS_A_RecordNode; break; case DNS_TYPE_ATMA: pNode = new CDNS_ATMA_RecordNode; break; case DNS_TYPE_SOA: { pNode = new CDNS_SOA_RecordNode; if (pNode) { pNode->SetFlagsDown(TN_FLAG_NO_DELETE, TRUE /*bSet*/); } } break; case DNS_TYPE_PTR: pNode = new CDNS_PTR_RecordNode; break; case DNS_TYPE_NS: pNode = new CDNS_NS_RecordNode; break; case DNS_TYPE_CNAME: pNode = new CDNS_CNAME_RecordNode; break; case DNS_TYPE_MB: pNode = new CDNS_MB_RecordNode; break; case DNS_TYPE_MD: pNode = new CDNS_MD_RecordNode; break; case DNS_TYPE_MF: pNode = new CDNS_MF_RecordNode; break; case DNS_TYPE_MG: pNode = new CDNS_MG_RecordNode; break; case DNS_TYPE_MR: pNode = new CDNS_MR_RecordNode; break; case DNS_TYPE_MINFO: pNode = new CDNS_MINFO_RecordNode; break; case DNS_TYPE_RP: pNode = new CDNS_RP_RecordNode; break; case DNS_TYPE_MX: pNode = new CDNS_MX_RecordNode; break; case DNS_TYPE_AFSDB: pNode = new CDNS_AFSDB_RecordNode; break; case DNS_TYPE_RT: pNode = new CDNS_RT_RecordNode; break; case DNS_TYPE_AAAA: pNode = new CDNS_AAAA_RecordNode; break; case DNS_TYPE_HINFO: pNode = new CDNS_HINFO_RecordNode; break; case DNS_TYPE_ISDN: pNode = new CDNS_ISDN_RecordNode; break; case DNS_TYPE_TEXT: pNode = new CDNS_TXT_RecordNode; break; case DNS_TYPE_X25: pNode = new CDNS_X25_RecordNode; break; case DNS_TYPE_WKS: pNode = new CDNS_WKS_RecordNode; break; case DNS_TYPE_WINS: pNode = new CDNS_WINS_RecordNode; break; case DNS_TYPE_NBSTAT: pNode = new CDNS_NBSTAT_RecordNode; break; case DNS_TYPE_SRV: pNode = new CDNS_SRV_RecordNode; break; case DNS_TYPE_KEY: pNode = new CDNS_KEY_RecordNode; break; case DNS_TYPE_SIG: pNode = new CDNS_SIG_RecordNode; break; case DNS_TYPE_NXT: pNode = new CDNS_NXT_RecordNode; break; case DNS_TYPE_NULL: pNode = new CDNS_Null_RecordNode; break; default: { pNode = new CDNS_Null_RecordNode; // unknown type of record } } ASSERT(pNode != NULL); return pNode; } #define INFO_ENTRY(x) \ {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", 0x0}, #define INFO_ENTRY_SHOWNXT(x) \ {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define INFO_ENTRY_UI_CREATE(x) \ {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE | DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define INFO_ENTRY_UI_CREATE_AT_NODE(x) \ {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE_AT_NODE | DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(x) \ {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE | DNS_RECORD_INFO_FLAG_SHOW_NXT | DNS_RECORD_INFO_FLAG_WHISTLER_OR_LATER}, #define INFO_ENTRY_NAME(x, namestr) \ {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", 0x0}, #define INFO_ENTRY_NAME_SHOWNXT(x, namestr) \ {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define INFO_ENTRY_NAME_UI_CREATE(x, namestr) \ {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE | DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define INFO_ENTRY_NAME_UI_CREATE_AT_NODE(x, namestr) \ {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE_AT_NODE | DNS_RECORD_INFO_FLAG_SHOW_NXT}, #define END_OF_TABLE_INFO_ENTRY { 0 , NULL , NULL , NULL , (UINT)-1 , L"", 0x0} const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetInfoEntryTable() { static DNS_RECORD_INFO_ENTRY info[] = { // createble record types (at the node also) INFO_ENTRY_UI_CREATE_AT_NODE(A) INFO_ENTRY_UI_CREATE_AT_NODE(ATMA) INFO_ENTRY_UI_CREATE_AT_NODE(AAAA) INFO_ENTRY_NAME_UI_CREATE_AT_NODE(TEXT, L"TXT" ) // createble record types (never at the node) INFO_ENTRY_UI_CREATE(CNAME) INFO_ENTRY_UI_CREATE(MB) INFO_ENTRY_UI_CREATE(MG) INFO_ENTRY_UI_CREATE(MR) INFO_ENTRY_UI_CREATE(PTR) INFO_ENTRY_UI_CREATE(WKS) INFO_ENTRY_UI_CREATE(HINFO) INFO_ENTRY_UI_CREATE(MINFO) INFO_ENTRY_UI_CREATE(MX) INFO_ENTRY_UI_CREATE(RP) INFO_ENTRY_UI_CREATE(AFSDB) INFO_ENTRY_UI_CREATE(X25) INFO_ENTRY_UI_CREATE(ISDN) INFO_ENTRY_UI_CREATE(RT) INFO_ENTRY_UI_CREATE(SRV) INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(SIG) INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(KEY) INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(NXT) // non createble record types INFO_ENTRY_SHOWNXT(SOA) // cannot create an SOA record!!! INFO_ENTRY(WINS) // cannot create a WINS record from the Wizard INFO_ENTRY_NAME(NBSTAT, L"WINS-R" ) //cannot create a NBSTAT(WINS-R) record from the Wizard INFO_ENTRY(NBSTAT) INFO_ENTRY_SHOWNXT(NS) // use the Name Servers property page INFO_ENTRY_SHOWNXT(MD) // obsolete, should use MX INFO_ENTRY_SHOWNXT(MF) // obsolete, should use MX INFO_ENTRY_SHOWNXT(NSAP) INFO_ENTRY_SHOWNXT(NSAPPTR) INFO_ENTRY_SHOWNXT(PX) INFO_ENTRY_SHOWNXT(GPOS) INFO_ENTRY(NULL) // Null/Unk records can only be viewed INFO_ENTRY(UNK) END_OF_TABLE_INFO_ENTRY }; return (const DNS_RECORD_INFO_ENTRY*)&info; } const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetEntry(int nIndex) { DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable(); int k = 0; while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { if (k == nIndex) return pTable; pTable++; k++; } return NULL; } const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetEntryFromName(LPCWSTR lpszName) { DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable(); while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { LPCWSTR lpszTableName = pTable->lpszFullName; if (_wcsicmp(lpszTableName,lpszName) == 0) return pTable; pTable++; } return NULL; } const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetTypeEntry(WORD wType) { DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable(); while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { if (pTable->wType == wType) { return pTable; } pTable++; } return NULL; } LPCWSTR CDNSRecordInfo::GetTypeString(WORD wType, stringType type) { const DNS_RECORD_INFO_ENTRY* pTableEntry = GetTypeEntry(wType); if (pTableEntry != NULL) { switch(type) { case shortName: return pTableEntry->lpszShortName; case fullName: return pTableEntry->lpszFullName; case description: return pTableEntry->lpszDescription; } } return g_lpszNullString; } CString CDNSRecordInfo::m_szAtTheNodeDisplayString; BOOL CDNSRecordInfo::LoadResources() { HINSTANCE hInstance = _Module.GetModuleInstance(); ASSERT(hInstance != NULL); DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable(); while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE) { if (0 == ::LoadString(hInstance, pTable->nResourceID, pTable->cStringData, MAX_RECORD_RESOURCE_STRLEN)) return FALSE; // mmissing resource string? // parse and replace \n with NULL pTable->lpszFullName = pTable->cStringData; for (WCHAR* pCh = pTable->cStringData; (*pCh) != NULL; pCh++) { if ( (*pCh) == L'\n') { pTable->lpszDescription = (pCh+1); (*pCh) = NULL; break; } } pTable++; } AFX_MANAGE_STATE(AfxGetStaticModuleState()); return m_szAtTheNodeDisplayString.LoadString(IDS_RECORD_AT_THE_NODE); }