Leaked source code of windows server 2003
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.

2928 lines
82 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: record.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "preDNSsn.h"
  11. #include <SnapBase.h>
  12. #include "resource.h"
  13. #include "dnsutil.h"
  14. #include "DNSSnap.h"
  15. #include "snapdata.h"
  16. #include "server.h"
  17. #include "domain.h"
  18. #include "record.h"
  19. #include "zone.h"
  20. #ifdef DEBUG_ALLOCATOR
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #endif
  27. #define DNS_RECORD_CLASS_DEFAULT (0x1) // we support only class one records
  28. #ifdef _USE_BLANK
  29. #else
  30. const WCHAR* g_szAtTheNodeInput = L"@"; // string to mark the "At the node RR"
  31. #endif
  32. extern COMBOBOX_TABLE_ENTRY g_Algorithms[];
  33. extern COMBOBOX_TABLE_ENTRY g_Protocols[];
  34. ////////////////////////////////////////////////////////////////////////////
  35. // CDNSRecord : base class for all the DNS record types
  36. CDNSRecord::CDNSRecord()
  37. {
  38. m_wType = 0x0;
  39. m_dwFlags = DNS_RPC_RECORD_FLAG_DEFAULT;
  40. m_dwTtlSeconds = 60;
  41. m_dwScavengeStart = 0;
  42. }
  43. ////////////////////////////////////////////////////////////////////
  44. //////////////// RPC SPECIFIC //////////////////////////////////////
  45. //
  46. // sizes of data sections for records: some of them have strings
  47. // after the constant size part
  48. //
  49. #define SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER (sizeof(IP_ADDRESS))
  50. #define SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER (sizeof(UCHAR))
  51. #define SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER (sizeof(IPV6_ADDRESS))
  52. #define SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER (5*sizeof(DWORD)) // then string
  53. #define SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER (sizeof(WORD)) // thsn string
  54. #define SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER (sizeof(IP_ADDRESS)+sizeof(UCHAR))
  55. #define SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER (4*sizeof(DWORD))
  56. #define SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER (3*sizeof(DWORD))
  57. #define SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER (3*sizeof(WORD))
  58. #define SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER \
  59. (sizeof(WORD)+2*sizeof(BYTE)+3*sizeof(DWORD)+sizeof(WORD)) // then string then blob
  60. #define SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER (sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE))
  61. #define SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER (sizeof(WORD))
  62. DNS_STATUS CDNSRecord::Update(LPCTSTR lpszServerName, LPCTSTR lpszZoneName, LPCTSTR lpszNodeName,
  63. CDNSRecord* pDNSRecordOld, BOOL bUseDefaultTTL)
  64. {
  65. USES_CONVERSION;
  66. WORD nBytesLen = GetRPCRecordLength();
  67. BYTE* pMem = (BYTE*)malloc(nBytesLen);
  68. if (!pMem)
  69. {
  70. return ERROR_OUTOFMEMORY;
  71. }
  72. memset(pMem, 0x0, nBytesLen);
  73. DNS_STATUS err = 0;
  74. BYTE* pMemOld = 0;
  75. do // false loop
  76. {
  77. DNS_RPC_RECORD* pDnsRpcRecord = NULL;
  78. WriteRPCData(pMem, &pDnsRpcRecord);
  79. ASSERT(pDnsRpcRecord != NULL);
  80. DNS_RPC_RECORD* pDnsRpcRecordOld = NULL;
  81. if (pDNSRecordOld != NULL) // doing an update of existing record
  82. {
  83. WORD nOldBytesLen = pDNSRecordOld->GetRPCRecordLength();
  84. pMemOld = (BYTE*)malloc(nOldBytesLen);
  85. if (!pMemOld)
  86. {
  87. err = ERROR_OUTOFMEMORY;
  88. break;
  89. }
  90. memset(pMemOld, 0x0, nOldBytesLen);
  91. pDNSRecordOld->WriteRPCData(pMemOld, &pDnsRpcRecordOld);
  92. ASSERT(pDnsRpcRecordOld != NULL);
  93. //
  94. // figure out if it is TTL only or full update
  95. //
  96. if (pDnsRpcRecordOld->wDataLength == pDnsRpcRecord->wDataLength)
  97. {
  98. //
  99. // mask the flags
  100. //
  101. DWORD dwFlagSave = pDnsRpcRecord->dwFlags;
  102. pDnsRpcRecord->dwFlags = 0;
  103. //
  104. // mask the TTL
  105. //
  106. DWORD dwTtlSave = pDnsRpcRecord->dwTtlSeconds;
  107. //
  108. // mask the StartRefreshHr
  109. //
  110. DWORD dwStartRefreshHrSave = pDnsRpcRecord->dwTimeStamp;
  111. pDnsRpcRecord->dwTtlSeconds = pDnsRpcRecordOld->dwTtlSeconds;
  112. BOOL bEqual =
  113. memcmp(
  114. pDnsRpcRecord,
  115. pDnsRpcRecordOld,
  116. min(
  117. pDnsRpcRecord->wDataLength + SIZEOF_DNS_RPC_RECORD_HEADER,
  118. pDnsRpcRecordOld->wDataLength + SIZEOF_DNS_RPC_RECORD_HEADER)) == 0;
  119. //
  120. // restore masked fields
  121. //
  122. pDnsRpcRecord->dwTimeStamp = dwStartRefreshHrSave;
  123. pDnsRpcRecord->dwTtlSeconds = dwTtlSave;
  124. pDnsRpcRecord->dwFlags = dwFlagSave;
  125. //
  126. // check if TTL only
  127. //
  128. if (bEqual && (pDnsRpcRecord->dwTtlSeconds != pDnsRpcRecordOld->dwTtlSeconds))
  129. {
  130. pDnsRpcRecord->dwFlags |= DNS_RPC_RECORD_FLAG_TTL_CHANGE;
  131. }
  132. }
  133. }
  134. if (bUseDefaultTTL)
  135. {
  136. pDnsRpcRecord->dwFlags |= DNS_RPC_RECORD_FLAG_DEFAULT_TTL;
  137. }
  138. ASSERT(pDnsRpcRecord->wType != 0);
  139. err =
  140. ::DnssrvUpdateRecord(
  141. lpszServerName,
  142. W_TO_UTF8(lpszZoneName),
  143. W_TO_UTF8(lpszNodeName),
  144. pDnsRpcRecord, pDnsRpcRecordOld);
  145. //
  146. // if we get DNS_ERROR_ALREADY_EXISTS and it is an existing record,
  147. // we are actually OK, ignore the error code
  148. //
  149. // NTRAID#Windows Bugs-251410-2001/01/17-jeffjon
  150. // The DNS_ERROR_RECORD_ALREADY_EXISTS was taken out due to bug 251410. I
  151. // am leaving it here in case we run into problems after removing it since
  152. // I don't know why it was here in the first place.
  153. //
  154. /*if ((err == DNS_ERROR_RECORD_ALREADY_EXISTS) && (pDNSRecordOld != NULL))
  155. {
  156. err = 0;
  157. }*/
  158. } while (false);
  159. if (pMem)
  160. {
  161. free(pMem);
  162. pMem = 0;
  163. }
  164. if (pMemOld)
  165. {
  166. free(pMemOld);
  167. pMemOld = 0;
  168. }
  169. return err;
  170. }
  171. DNS_STATUS CDNSRecord::Delete(LPCTSTR lpszServerName,
  172. LPCTSTR lpszZoneName,
  173. LPCTSTR lpszNodeName)
  174. {
  175. USES_CONVERSION;
  176. WORD nBytesLen = GetRPCRecordLength();
  177. BYTE* pMem = (BYTE*)malloc(nBytesLen);
  178. if (!pMem)
  179. {
  180. return ERROR_OUTOFMEMORY;
  181. }
  182. memset(pMem, 0x0, nBytesLen);
  183. DNS_RPC_RECORD* pDnsRpcRecord = NULL;
  184. WriteRPCData(pMem, &pDnsRpcRecord);
  185. ASSERT(pDnsRpcRecord != NULL);
  186. DNS_STATUS err = ::DnssrvUpdateRecord(lpszServerName,
  187. W_TO_UTF8(lpszZoneName),
  188. W_TO_UTF8(lpszNodeName),
  189. NULL, pDnsRpcRecord);
  190. if (pMem)
  191. {
  192. free(pMem);
  193. pMem = 0;
  194. }
  195. return err;
  196. }
  197. // helper function
  198. void CDNSRecord::CopyDNSRecordData(CDNSRecord* pDest, CDNSRecord* pSource)
  199. {
  200. ASSERT(pDest != NULL);
  201. ASSERT(pSource != NULL);
  202. // allocate buffer on the stack
  203. WORD nBytesLen = pSource->GetRPCRecordLength();
  204. BYTE* pMem = (BYTE*)malloc(nBytesLen);
  205. if (!pMem)
  206. {
  207. return;
  208. }
  209. memset(pMem, 0x0, nBytesLen);
  210. DNS_RPC_RECORD* pDnsRPCRecord = NULL;
  211. pSource->WriteRPCData(pMem, &pDnsRPCRecord); // write source to memory
  212. ASSERT(pDnsRPCRecord != NULL);
  213. pDest->ReadRPCData(pDnsRPCRecord); // read destination from memory
  214. // got to test if it is the same
  215. ASSERT(pDest->GetType() == pSource->GetType());
  216. if (pMem)
  217. {
  218. free(pMem);
  219. pMem = 0;
  220. }
  221. }
  222. void CDNSRecord::CloneValue(CDNSRecord* pClone)
  223. {
  224. ASSERT(pClone != NULL);
  225. CopyDNSRecordData(pClone,this);
  226. }
  227. void CDNSRecord::SetValue(CDNSRecord* pRecord)
  228. {
  229. ASSERT(pRecord != NULL);
  230. CopyDNSRecordData(this,pRecord);
  231. }
  232. void CDNSRecord::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  233. {
  234. ASSERT(pDnsRecord != NULL);
  235. // base class: just read common attributes
  236. // either we know the type, or we are an unk/null record type
  237. ASSERT(( m_wType == DNS_TYPE_NULL) || (m_wType == pDnsRecord->wType) );
  238. m_wType = pDnsRecord->wType;
  239. m_dwFlags = pDnsRecord->dwFlags;
  240. m_dwTtlSeconds = pDnsRecord->dwTtlSeconds;
  241. m_dwScavengeStart = pDnsRecord->dwTimeStamp;
  242. }
  243. void CDNSRecord::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  244. {
  245. ASSERT(pDnsQueryRecord != NULL);
  246. // base class: just read common attributes
  247. // either we know the type, or we are an unk/null record type
  248. ASSERT(( m_wType == DNS_TYPE_NULL) || (m_wType == pDnsQueryRecord->wType) );
  249. m_wType = pDnsQueryRecord->wType;
  250. m_dwFlags = 0x0; // pDnsQueryRecord->Flags.W;
  251. m_dwTtlSeconds = pDnsQueryRecord->dwTtl;
  252. }
  253. void CDNSRecord::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  254. {
  255. ASSERT(pMem != NULL);
  256. ASSERT(ppDnsRecord != NULL);
  257. *ppDnsRecord = (DNS_RPC_RECORD*)pMem;
  258. // fill in the common fields
  259. (*ppDnsRecord)->wType = m_wType;
  260. (*ppDnsRecord)->dwFlags = m_dwFlags;
  261. (*ppDnsRecord)->dwTtlSeconds = m_dwTtlSeconds;
  262. (*ppDnsRecord)->dwTimeStamp = m_dwScavengeStart;
  263. // fill in the length info: derived classes will ad to it
  264. (*ppDnsRecord)->wDataLength = 0x0;
  265. }
  266. WORD CDNSRecord::RPCBufferStringLen(LPCWSTR lpsz)
  267. {
  268. // returns the size of a DNS_RPC_STRING written to the buffer
  269. USES_CONVERSION;
  270. LPCSTR lpszAnsi = W_TO_UTF8(lpsz);
  271. // do not count NULL,
  272. // add size of cchNameLength (UCHAR) string length
  273. WORD wLen = 0;
  274. if (lpszAnsi != NULL && lpszAnsi[0] != L'\0')
  275. {
  276. wLen = static_cast<WORD>(UTF8_LEN(lpszAnsi) + sizeof(UCHAR));
  277. }
  278. else
  279. {
  280. wLen = sizeof(UCHAR) + sizeof(CHAR);
  281. }
  282. return wLen;
  283. }
  284. void CDNSRecord::ReadRPCString(CString& sz, DNS_RPC_NAME* pDnsRPCName)
  285. {
  286. // the input string is not NULL terminated
  287. DnsUtf8ToWCStringHelper(sz, pDnsRPCName->achName, pDnsRPCName->cchNameLength);
  288. }
  289. WORD CDNSRecord::WriteString(DNS_RPC_NAME* pDnsRPCName, LPCTSTR lpsz)
  290. {
  291. USES_CONVERSION;
  292. ASSERT(pDnsRPCName != NULL);
  293. LPCSTR lpszAnsi = W_TO_UTF8(lpsz);
  294. if (lpszAnsi != NULL &&
  295. lpszAnsi[0] != '\0')
  296. {
  297. // IMPORTANT: string in the RPC BUFFER are NOT NULL terminated
  298. pDnsRPCName->cchNameLength = (BYTE)UTF8_LEN(lpszAnsi); // don't count NULL
  299. memcpy(pDnsRPCName->achName, lpszAnsi, pDnsRPCName->cchNameLength);
  300. }
  301. else
  302. {
  303. //
  304. // NTRAID#Windows Bugs-305034-2001/02/05-jeffjon :
  305. // According to JWesth a null string should be passed with cchNameLength = 1
  306. // and the string a single NULL UTF8 character
  307. //
  308. pDnsRPCName->cchNameLength = 1;
  309. // We don't want the null terminator here so just copy the one byte.
  310. memcpy(pDnsRPCName->achName, "\0", 1);
  311. }
  312. // return length of the struct
  313. // (add size of cchNameLength (UCHAR) string length)
  314. return static_cast<WORD>(pDnsRPCName->cchNameLength + 1);
  315. }
  316. #ifdef _DEBUG
  317. void CDNSRecord::TestRPCStuff(DNS_RPC_RECORD* pDnsRecord)
  318. {
  319. //
  320. // TEST ONLY!!!!
  321. //
  322. WORD nBytesLen = GetRPCRecordLength();
  323. BYTE* pMem = (BYTE*)malloc(nBytesLen);
  324. if (!pMem)
  325. {
  326. return;
  327. }
  328. memset(pMem, 0x0, nBytesLen);
  329. DNS_RPC_RECORD* pDnsRecordTest = NULL;
  330. WriteRPCData(pMem, &pDnsRecordTest);
  331. ASSERT(pDnsRecordTest != NULL);
  332. //
  333. // got to test if it is the same
  334. //
  335. ASSERT(pDnsRecord->wDataLength == pDnsRecordTest->wDataLength);
  336. ASSERT(memcmp(pDnsRecord, pDnsRecordTest,
  337. SIZEOF_DNS_RPC_RECORD_HEADER + pDnsRecordTest->wDataLength) == 0);
  338. if (pMem)
  339. {
  340. free(pMem);
  341. pMem = 0;
  342. }
  343. }
  344. #endif
  345. ////////////////////////////////////////////////////////////////////////////
  346. // CDNSRecordNodeBase
  347. // {720132BB-44B2-11d1-B92F-00A0C9A06D2D}
  348. const GUID CDNSRecordNodeBase::NodeTypeGUID =
  349. { 0x720132bb, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } };
  350. CDNSRecordNodeBase::~CDNSRecordNodeBase()
  351. {
  352. if (m_pDNSRecord != NULL)
  353. {
  354. delete m_pDNSRecord;
  355. m_pDNSRecord = NULL;
  356. }
  357. }
  358. void CDNSRecordNodeBase::SetViewOptions(DWORD dwRecordViewOptions)
  359. {
  360. // we do not own the upper WORD of the flags
  361. dwRecordViewOptions &= 0x0000ffff; // clear high WORD to be sure
  362. m_dwNodeFlags &= 0xffff0000; // clear all the flags
  363. m_dwNodeFlags |= dwRecordViewOptions;
  364. }
  365. HRESULT CDNSRecordNodeBase::OnSetToolbarVerbState(IToolbar* pToolbar,
  366. CNodeList*)
  367. {
  368. //
  369. // Set the button state for each button on the toolbar
  370. //
  371. VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE)));
  372. VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE)));
  373. VERIFY(SUCCEEDED(pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE)));
  374. return S_OK;
  375. }
  376. BOOL CDNSRecordNodeBase::OnAddMenuItem(LPCONTEXTMENUITEM2,
  377. long*)
  378. {
  379. ASSERT(FALSE); // never called
  380. return FALSE;
  381. }
  382. BOOL CDNSRecordNodeBase::OnSetDeleteVerbState(DATA_OBJECT_TYPES,
  383. BOOL* pbHide,
  384. CNodeList* pNodeList)
  385. {
  386. if (pNodeList->GetCount() > 1) // multiple selection
  387. {
  388. *pbHide = TRUE;
  389. return FALSE;
  390. }
  391. *pbHide = FALSE;
  392. CDNSZoneNode* pZoneNode = GetDomainNode()->GetZoneNode();
  393. if (pZoneNode->IsAutocreated() ||
  394. (pZoneNode->GetZoneType() == DNS_ZONE_TYPE_SECONDARY) ||
  395. (pZoneNode->GetZoneType() == DNS_ZONE_TYPE_STUB))
  396. {
  397. return FALSE;
  398. }
  399. if (!CanDelete())
  400. {
  401. return FALSE;
  402. }
  403. WORD wType = GetType();
  404. if ((wType == DNS_TYPE_WINS) ||
  405. (wType == DNS_TYPE_NBSTAT) ||
  406. (wType == DNS_TYPE_NS) ||
  407. (wType == DNS_TYPE_SOA))
  408. {
  409. return FALSE;
  410. }
  411. return TRUE;
  412. }
  413. HRESULT CDNSRecordNodeBase::OnCommand(long,
  414. DATA_OBJECT_TYPES,
  415. CComponentDataObject*,
  416. CNodeList*)
  417. {
  418. ASSERT(FALSE); // never called!!!
  419. return E_FAIL;
  420. }
  421. LPCWSTR CDNSRecordNodeBase::GetString(int nCol)
  422. {
  423. switch (nCol)
  424. {
  425. case 0:
  426. return GetDisplayName();
  427. case 1:
  428. {
  429. return CDNSRecordInfo::GetTypeString(m_pDNSRecord->GetType(), CDNSRecordInfo::fullName);
  430. }
  431. case 2:
  432. return (LPCWSTR)m_szDisplayData;
  433. }
  434. return g_lpszNullString;
  435. }
  436. int CDNSRecordNodeBase::GetImageIndex(BOOL)
  437. {
  438. return RECORD_IMAGE_BASE;
  439. }
  440. void CDNSRecordNodeBase::SetRecordName(LPCTSTR lpszName, BOOL bAtTheNode)
  441. {
  442. m_bAtTheNode = bAtTheNode;
  443. m_szDisplayName = m_bAtTheNode ? CDNSRecordInfo::GetAtTheNodeDisplayString() : lpszName;
  444. }
  445. BOOL CDNSRecordNodeBase::ZoneIsCache()
  446. {
  447. CDNSDomainNode* pDomainNode = GetDomainNode();
  448. return (pDomainNode->GetZoneNode()->GetZoneType() == DNS_ZONE_TYPE_CACHE);
  449. }
  450. void CDNSRecordNodeBase::GetFullName(CString& szFullName)
  451. {
  452. CDNSDomainNode* pDomainNode = GetDomainNode();
  453. ASSERT(pDomainNode != NULL);
  454. if (IsAtTheNode())
  455. {
  456. szFullName = pDomainNode->GetFullName();
  457. }
  458. else
  459. {
  460. CString szTrueName = GetTrueRecordName();
  461. ASSERT(szTrueName.GetLength() > 0);
  462. LPCWSTR lpszDomainName = pDomainNode->GetFullName();
  463. if ((lpszDomainName == NULL) || (lpszDomainName[0] == NULL))
  464. {
  465. // domain with no name, use the RR display name as FQDN
  466. // this should be only with a temporary (fake) domain
  467. ASSERT(szTrueName[szTrueName.GetLength()-1] == TEXT('.'));
  468. szFullName = szTrueName;
  469. }
  470. else if ((lpszDomainName[0] == TEXT('.')) && (lpszDomainName[1] == NULL))
  471. {
  472. // the "." domain could be the Root or Root Hints
  473. if ( IS_CLASS(*pDomainNode, CDNSRootHintsNode) &&
  474. (szTrueName[szTrueName.GetLength()-1] == TEXT('.')) )
  475. {
  476. // special case A records in Root Hints, they might
  477. // have "." at the end, e.g. "A.ROOT-SERVERS.NET."
  478. szFullName = szTrueName;
  479. }
  480. else
  481. {
  482. // no need for dot in the format string
  483. // e.g. "myhost" and "." gives "myhost."
  484. szFullName.Format(_T("%s%s"), (LPCWSTR)szTrueName,
  485. lpszDomainName);
  486. }
  487. }
  488. else
  489. {
  490. // standard case, e.g. "myhost" and "banana.com."
  491. // to get "myhost.banana.com."
  492. szFullName.Format(_T("%s.%s"), (LPCWSTR)szTrueName,
  493. lpszDomainName);
  494. }
  495. }
  496. TRACE(_T("\nCDNSRecordNodeBase::GetFullName(%s)\n"), (LPCTSTR)szFullName);
  497. }
  498. void CDNSRecordNodeBase::CreateFromRPCRecord(DNS_RPC_RECORD* pDnsRecord)
  499. {
  500. ASSERT(m_pDNSRecord == NULL);
  501. m_pDNSRecord = CreateRecord();
  502. if (m_pDNSRecord)
  503. {
  504. m_pDNSRecord->ReadRPCData(pDnsRecord);
  505. m_pDNSRecord->UpdateDisplayData(m_szDisplayData);
  506. #ifdef _DEBUG
  507. //
  508. // TEST ONLY!!!!
  509. //
  510. m_pDNSRecord->TestRPCStuff(pDnsRecord);
  511. #endif
  512. }
  513. }
  514. void CDNSRecordNodeBase::CreateFromDnsQueryRecord(DNS_RECORD* pDnsQueryRecord, DWORD dwFlags)
  515. {
  516. ASSERT(m_pDNSRecord == NULL);
  517. m_pDNSRecord = CreateRecord();
  518. if (m_pDNSRecord)
  519. {
  520. m_pDNSRecord->ReadDnsQueryData(pDnsQueryRecord);
  521. m_pDNSRecord->UpdateDisplayData(m_szDisplayData);
  522. m_pDNSRecord->m_dwFlags = dwFlags;
  523. }
  524. }
  525. CDNSRecord* CDNSRecordNodeBase::CreateCloneRecord()
  526. {
  527. ASSERT(m_pDNSRecord != NULL);
  528. CDNSRecord* pClone = CreateRecord();
  529. if (pClone)
  530. {
  531. m_pDNSRecord->CloneValue(pClone);
  532. }
  533. return pClone;
  534. }
  535. BOOL CDNSRecordNodeBase::CanCloseSheets()
  536. {
  537. return (IDCANCEL != DNSMessageBox(IDS_MSG_RECORD_CLOSE_SHEET, MB_OKCANCEL));
  538. }
  539. void CDNSRecordNodeBase::OnDelete(CComponentDataObject* pComponentData,
  540. CNodeList* pNodeList)
  541. {
  542. if (pNodeList->GetCount() > 1) // multiple selection
  543. {
  544. return;
  545. }
  546. UINT nRet = DNSConfirmOperation(IDS_MSG_RECORD_DELETE, this);
  547. if (IDCANCEL == nRet ||
  548. IDNO == nRet)
  549. {
  550. return;
  551. }
  552. if (IsSheetLocked())
  553. {
  554. if (!CanCloseSheets())
  555. return;
  556. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  557. }
  558. ASSERT(!IsSheetLocked());
  559. // try first to delete the record in the server
  560. DNS_STATUS err = DeleteOnServerAndUI(pComponentData);
  561. if (err != 0)
  562. {
  563. DNSErrorDialog(err, IDS_MSG_RECORD_FAIL_DELETE);
  564. return;
  565. }
  566. delete this; // gone
  567. }
  568. DNS_STATUS CDNSRecordNodeBase::DeleteOnServer()
  569. {
  570. ASSERT(m_pDNSRecord != NULL);
  571. CDNSDomainNode* pDomainNode = GetDomainNode();
  572. ASSERT(pDomainNode != NULL);
  573. CDNSServerNode* pServerNode = pDomainNode->GetServerNode();
  574. ASSERT(pServerNode != NULL);
  575. CString szFullName;
  576. GetFullName(szFullName);
  577. LPCTSTR lpszZoneNode = NULL;
  578. CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode();
  579. if (pZoneNode != NULL)
  580. {
  581. if (pZoneNode->GetZoneType() != DNS_ZONE_TYPE_CACHE)
  582. {
  583. lpszZoneNode = pZoneNode->GetFullName();
  584. if ((lpszZoneNode != NULL) && (lpszZoneNode[0] == NULL))
  585. lpszZoneNode = NULL;
  586. }
  587. }
  588. return m_pDNSRecord->Delete(pServerNode->GetRPCName(), lpszZoneNode, szFullName);
  589. }
  590. DNS_STATUS CDNSRecordNodeBase::DeleteOnServerAndUI(CComponentDataObject* pComponentData)
  591. {
  592. ASSERT(pComponentData != NULL);
  593. DNS_STATUS err = DeleteOnServer();
  594. if (err == 0)
  595. DeleteHelper(pComponentData); // delete in the UI and list of children
  596. return err;
  597. }
  598. BOOL CDNSRecordNodeBase::HasPropertyPages(DATA_OBJECT_TYPES,
  599. BOOL* pbHideVerb,
  600. CNodeList* pNodeList)
  601. {
  602. if (pNodeList->GetCount() > 1) // multiple selection
  603. {
  604. *pbHideVerb = TRUE;
  605. return FALSE;
  606. }
  607. *pbHideVerb = FALSE; // always show the verb
  608. return !GetDomainNode()->GetZoneNode()->IsAutocreated();
  609. }
  610. HRESULT CDNSRecordNodeBase::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  611. LONG_PTR handle,
  612. CNodeList* pNodeList)
  613. {
  614. ASSERT(pNodeList->GetCount() == 1); // multi-select not supported
  615. CComponentDataObject* pComponentDataObject = ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  616. ASSERT(pComponentDataObject != NULL);
  617. HRESULT hr = S_OK;
  618. CDNSRecordPropertyPageHolder* pHolder = new CDNSRecordPropertyPageHolder((CDNSDomainNode*)GetContainer(), this, pComponentDataObject);
  619. if (pHolder)
  620. {
  621. if (IsAtTheNode())
  622. {
  623. pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, GetContainer());
  624. }
  625. else
  626. {
  627. pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this);
  628. }
  629. hr = pHolder->CreateModelessSheet(lpProvider, handle);
  630. }
  631. else
  632. {
  633. hr = E_OUTOFMEMORY;
  634. }
  635. return hr;
  636. }
  637. DNS_STATUS CDNSRecordNodeBase::Update(CDNSRecord* pDNSRecordNew, BOOL bUseDefaultTTL,
  638. BOOL bIgnoreAlreadyExists)
  639. {
  640. // get a new record, write to server, if successful copy it and substitute it in place of the old
  641. // passing pDNSRecordNew == NULL meand we are creating a new record
  642. BOOL bNew = (pDNSRecordNew == NULL);
  643. if (bNew)
  644. {
  645. pDNSRecordNew = m_pDNSRecord;
  646. m_pDNSRecord = NULL;
  647. }
  648. ASSERT(pDNSRecordNew != NULL);
  649. // try to write new record to the server, passing the old as comparison
  650. CDNSDomainNode* pDomainNode = GetDomainNode();
  651. CString szFullName;
  652. LPCTSTR lpszServerName = pDomainNode->GetServerNode()->GetRPCName();
  653. LPCTSTR lpszRecordName;
  654. if (IsAtTheNode())
  655. {
  656. lpszRecordName = pDomainNode->GetFullName(); // e.g. "myzone.com"
  657. }
  658. else
  659. {
  660. GetFullName(szFullName);
  661. lpszRecordName = szFullName; // e.g. "myrec.myzone.com"
  662. }
  663. LPCTSTR lpszZoneNode = NULL;
  664. CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode();
  665. if (pZoneNode != NULL)
  666. {
  667. if (pZoneNode->GetZoneType() != DNS_ZONE_TYPE_CACHE)
  668. {
  669. lpszZoneNode = pZoneNode->GetFullName();
  670. if ((lpszZoneNode != NULL) && (lpszZoneNode[0] == NULL))
  671. lpszZoneNode = NULL;
  672. }
  673. }
  674. DNS_STATUS err = pDNSRecordNew->Update(lpszServerName, lpszZoneNode, lpszRecordName,
  675. m_pDNSRecord, bUseDefaultTTL);
  676. if (bIgnoreAlreadyExists && (err == DNS_ERROR_RECORD_ALREADY_EXISTS) )
  677. err = 0; // tried to write, but it was already there, so it is fine.
  678. if (err != 0 && err != DNS_WARNING_PTR_CREATE_FAILED)
  679. return err; // failed, no update to the record
  680. if (bNew)
  681. {
  682. // put back the existing DNSRecord, no need to create a new one
  683. ASSERT(pDNSRecordNew != NULL);
  684. m_pDNSRecord = pDNSRecordNew;
  685. }
  686. // update the record with the new one
  687. if (m_pDNSRecord == NULL) // we are creating a new record
  688. {
  689. m_pDNSRecord = CreateRecord();
  690. }
  691. if (m_pDNSRecord)
  692. {
  693. m_pDNSRecord->SetValue(pDNSRecordNew);
  694. //Update the scavenging time on both the temporary and the node's CDNSRecord
  695. SetScavengingTime(m_pDNSRecord);
  696. SetScavengingTime(pDNSRecordNew);
  697. m_pDNSRecord->UpdateDisplayData(m_szDisplayData);
  698. }
  699. else
  700. {
  701. err = ERROR_OUTOFMEMORY;
  702. }
  703. return err;
  704. }
  705. void CDNSRecordNodeBase::SetScavengingTime(CDNSRecord* pRecord)
  706. {
  707. if (pRecord->m_dwFlags & DNS_RPC_RECORD_FLAG_AGING_ON)
  708. {
  709. pRecord->m_dwScavengeStart = CalculateScavengingTime();
  710. }
  711. else
  712. {
  713. pRecord->m_dwScavengeStart = 0;
  714. }
  715. }
  716. DWORD CDNSRecordNodeBase::CalculateScavengingTime()
  717. {
  718. CDNSZoneNode* pZoneNode = GetDomainNode()->GetZoneNode();
  719. ASSERT(pZoneNode != NULL);
  720. if (pZoneNode == NULL)
  721. return 0;
  722. SYSTEMTIME currentSysTime;
  723. ::GetSystemTime(&currentSysTime);
  724. LONGLONG llResult = GetSystemTime64(&currentSysTime);
  725. return static_cast<DWORD>(llResult / 3600L);
  726. }
  727. void CDNSRecordNodeBase::CreateDsRecordLdapPath(CString& sz)
  728. {
  729. CDNSDomainNode* pDomainNode = GetDomainNode();
  730. CDNSZoneNode* pZoneNode = pDomainNode->GetZoneNode();
  731. CDNSServerNode* pServerNode = pZoneNode->GetServerNode();
  732. pServerNode->CreateDsZoneName(pZoneNode, sz);
  733. if (sz.IsEmpty())
  734. return; // no LDAP path at all
  735. CString szTmp;
  736. // need to figure out the additional "DC = <>" part
  737. if (pDomainNode->IsZone() && IsAtTheNode())
  738. {
  739. szTmp = L"DC=@,";
  740. }
  741. else
  742. {
  743. CString szRecordFullName;
  744. if (IsAtTheNode())
  745. {
  746. szRecordFullName = GetDomainNode()->GetFullName(); // e.g. "mydom.myzone.com"
  747. }
  748. else
  749. {
  750. GetFullName(szRecordFullName); // e.g. "myrec.mydom.myzone.com"
  751. }
  752. LPCTSTR lpszZoneName = pZoneNode->GetFullName();
  753. // remove zone part (e.g. "myzone.com") from record name,
  754. // to get e.g. "mydom" or "myrec.mydom"
  755. int nZoneLen = static_cast<int>(wcslen(lpszZoneName));
  756. int nRecordLen = szRecordFullName.GetLength();
  757. ASSERT(nRecordLen > nZoneLen);
  758. szTmp.Format(_T("DC=%s,"),(LPCTSTR)szRecordFullName.Left(nRecordLen-nZoneLen-1));
  759. }
  760. szTmp += sz;
  761. pServerNode->CreateLdapPathFromX500Name(szTmp, sz);
  762. }
  763. ///////////////////////////////////////////////////////////////////
  764. // CDNS_Null_Record
  765. CDNS_Null_Record::CDNS_Null_Record()
  766. {
  767. m_wType = DNS_TYPE_NULL;
  768. }
  769. WORD CDNS_Null_Record::GetRPCDataLength()
  770. {
  771. return (WORD)m_blob.GetSize();
  772. }
  773. void CDNS_Null_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  774. {
  775. CDNSRecord::ReadRPCData(pDnsRecord);
  776. m_blob.Set(pDnsRecord->Data.Null.bData , pDnsRecord->wDataLength);
  777. }
  778. void CDNS_Null_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  779. {
  780. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  781. ASSERT(FALSE); // TODO
  782. }
  783. void CDNS_Null_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  784. {
  785. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  786. UINT nBytes = m_blob.GetSize();
  787. memcpy((*ppDnsRecord)->Data.Null.bData, m_blob.GetData(), sizeof(BYTE)*nBytes);
  788. (*ppDnsRecord)->wDataLength = static_cast<WORD>((((*ppDnsRecord)->wDataLength) + nBytes) & 0xffff);
  789. }
  790. void CDNS_Null_Record::UpdateDisplayData(CString& szDisplayData)
  791. {
  792. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  793. szDisplayData.LoadString(IDS_RECORD_DATA_UNK);
  794. }
  795. ///////////////////////////////////////////////////////////////////
  796. // CDNS_A_Record
  797. CDNS_A_Record::CDNS_A_Record()
  798. {
  799. m_wType = DNS_TYPE_A;
  800. m_ipAddress = 0x0;
  801. }
  802. WORD CDNS_A_Record::GetRPCDataLength()
  803. {
  804. return (WORD)SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER;
  805. }
  806. void CDNS_A_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  807. {
  808. CDNSRecord::ReadRPCData(pDnsRecord);
  809. ASSERT(pDnsRecord->wType == DNS_TYPE_A);
  810. ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER);
  811. m_ipAddress = pDnsRecord->Data.A.ipAddress;
  812. }
  813. void CDNS_A_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  814. {
  815. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  816. ASSERT(pDnsQueryRecord->wType == DNS_TYPE_A);
  817. m_ipAddress = pDnsQueryRecord->Data.A.IpAddress;
  818. }
  819. void CDNS_A_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  820. {
  821. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  822. (*ppDnsRecord)->Data.A.ipAddress = m_ipAddress;
  823. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_A_RECORD_DATA_HEADER;
  824. }
  825. void CDNS_A_Record::UpdateDisplayData(CString& szDisplayData)
  826. {
  827. szDisplayData.Format(g_szIpStringFmt, IP_STRING_FMT_ARGS(m_ipAddress));
  828. }
  829. ///////////////////////////////////////////////////////////////////
  830. // CDNS_ATMA_Record
  831. void _ATMA_BCD_ToString(CString& s, BYTE* pBuf)
  832. {
  833. const int nHexChars = 2*DNS_ATMA_MAX_ADDR_LENGTH+1;
  834. LPWSTR lpszBuf = s.GetBuffer(nHexChars);
  835. ZeroMemory(lpszBuf, nHexChars*sizeof(WCHAR));
  836. for (int i=0; i<DNS_ATMA_MAX_ADDR_LENGTH; i++)
  837. {
  838. BYTE high = static_cast<BYTE>(*(pBuf+i) >> 4);
  839. BYTE low = static_cast<BYTE>(*(pBuf+i) & 0x0f);
  840. // just offset out of the ASCII table
  841. *(lpszBuf+2*i) = static_cast<WCHAR>((high <= 9) ? (high + TEXT('0')) : ( high - 10 + TEXT('a')));
  842. *(lpszBuf+2*i+1) = static_cast<WCHAR>((low <= 9) ? (low + TEXT('0')) : ( low - 10 + TEXT('a')));
  843. }
  844. s.ReleaseBuffer();
  845. }
  846. BOOL _ATMA_StringTo_BCD(BYTE* pBuf, LPCWSTR lpsz)
  847. {
  848. // verify the string is the right length
  849. size_t nLen = wcslen(lpsz);
  850. if (nLen != 2*DNS_ATMA_MAX_ADDR_LENGTH)
  851. return FALSE;
  852. ZeroMemory(pBuf, DNS_ATMA_MAX_ADDR_LENGTH);
  853. for (int i=0; i<DNS_ATMA_MAX_ADDR_LENGTH; i++)
  854. {
  855. BYTE high = HexCharToByte(lpsz[2*i]);
  856. if (high == 0xFF)
  857. return FALSE;
  858. BYTE low = HexCharToByte(lpsz[2*i+1]);
  859. if (low == 0xFF)
  860. return FALSE;
  861. pBuf[i] = static_cast<BYTE>((high << 4) | (low & 0x0f));
  862. }
  863. return TRUE;
  864. }
  865. CDNS_ATMA_Record::CDNS_ATMA_Record()
  866. {
  867. m_wType = DNS_TYPE_ATMA;
  868. m_chFormat = DNS_ATMA_FORMAT_E164;
  869. }
  870. WORD CDNS_ATMA_Record::GetRPCDataLength()
  871. {
  872. DWORD dwLen = SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER;
  873. ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA));
  874. if (m_chFormat == DNS_ATMA_FORMAT_E164)
  875. {
  876. USES_CONVERSION;
  877. // it is a null terminated string
  878. dwLen += UTF8_LEN(W_TO_UTF8(m_szAddress)); // do not count NULL at the end
  879. }
  880. else
  881. {
  882. // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH
  883. dwLen += DNS_ATMA_MAX_ADDR_LENGTH;
  884. }
  885. return static_cast<WORD>(dwLen);
  886. }
  887. void CDNS_ATMA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  888. {
  889. CDNSRecord::ReadRPCData(pDnsRecord);
  890. ASSERT(pDnsRecord->wType == DNS_TYPE_ATMA);
  891. m_chFormat = pDnsRecord->Data.ATMA.chFormat;
  892. ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA));
  893. if (m_chFormat == DNS_ATMA_FORMAT_E164)
  894. {
  895. // non NULL terminated string
  896. int nBytes = pDnsRecord->wDataLength - SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER;
  897. DnsUtf8ToWCStringHelper(m_szAddress, (LPSTR)pDnsRecord->Data.ATMA.bAddress, nBytes);
  898. }
  899. else
  900. {
  901. // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH
  902. ASSERT(pDnsRecord->wDataLength == (SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER+DNS_ATMA_MAX_ADDR_LENGTH));
  903. _ATMA_BCD_ToString(m_szAddress, pDnsRecord->Data.ATMA.bAddress);
  904. }
  905. }
  906. void CDNS_ATMA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  907. {
  908. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  909. ASSERT(pDnsQueryRecord->wType == DNS_TYPE_ATMA);
  910. ASSERT(FALSE); // TODO
  911. }
  912. void CDNS_ATMA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  913. {
  914. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  915. (*ppDnsRecord)->Data.ATMA.chFormat = m_chFormat;
  916. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_ATMA_RECORD_DATA_HEADER;
  917. ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA));
  918. if (m_chFormat == DNS_ATMA_FORMAT_E164)
  919. {
  920. // it is a non null terminated string
  921. USES_CONVERSION;
  922. LPCSTR lpszAnsi = W_TO_UTF8(m_szAddress);
  923. if (lpszAnsi != NULL)
  924. {
  925. DWORD nAnsiLen = UTF8_LEN(lpszAnsi);
  926. if (nAnsiLen > DNS_ATMA_MAX_ADDR_LENGTH)
  927. nAnsiLen = DNS_ATMA_MAX_ADDR_LENGTH;
  928. UCHAR* pU = ((*ppDnsRecord)->Data.ATMA.bAddress);
  929. memcpy(pU, lpszAnsi, nAnsiLen);
  930. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength + nAnsiLen) & 0xffff);
  931. }
  932. }
  933. else
  934. {
  935. // it is BCD encoding of DNS_ATMA_MAX_ADDR_LENGTH
  936. VERIFY(_ATMA_StringTo_BCD((*ppDnsRecord)->Data.ATMA.bAddress, m_szAddress));
  937. (*ppDnsRecord)->wDataLength += DNS_ATMA_MAX_ADDR_LENGTH;
  938. }
  939. }
  940. void CDNS_ATMA_Record::UpdateDisplayData(CString& szDisplayData)
  941. {
  942. ASSERT((m_chFormat == DNS_ATMA_FORMAT_E164) || (m_chFormat == DNS_ATMA_FORMAT_AESA));
  943. if (m_chFormat == DNS_ATMA_FORMAT_E164)
  944. {
  945. szDisplayData.Format(L"(E164) %s", (LPCWSTR)m_szAddress);
  946. }
  947. else
  948. {
  949. szDisplayData.Format(L"(NSAP) %s", (LPCWSTR)m_szAddress);
  950. }
  951. }
  952. ///////////////////////////////////////////////////////////////////
  953. // CDNS_SOA_Record
  954. CDNS_SOA_Record::CDNS_SOA_Record()
  955. {
  956. m_wType = DNS_TYPE_SOA;
  957. m_dwSerialNo = 0x0;
  958. m_dwRefresh = 0x0;
  959. m_dwRetry = 0x0;
  960. m_dwExpire = 0x0;
  961. m_dwMinimumTtl = 0x0;
  962. }
  963. WORD CDNS_SOA_Record::GetRPCDataLength()
  964. {
  965. return static_cast<WORD>(SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER +
  966. RPCBufferStringLen(m_szNamePrimaryServer) +
  967. RPCBufferStringLen(m_szResponsibleParty));
  968. }
  969. void CDNS_SOA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  970. {
  971. CDNSRecord::ReadRPCData(pDnsRecord);
  972. ASSERT(pDnsRecord->wType == DNS_TYPE_SOA);
  973. ASSERT(pDnsRecord->wDataLength >= (SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER +4));
  974. // read header data
  975. m_dwSerialNo = pDnsRecord->Data.SOA.dwSerialNo;
  976. m_dwRefresh = pDnsRecord->Data.SOA.dwRefresh;
  977. m_dwRetry = pDnsRecord->Data.SOA.dwRetry;
  978. m_dwExpire = pDnsRecord->Data.SOA.dwExpire;
  979. m_dwMinimumTtl = pDnsRecord->Data.SOA.dwMinimumTtl;
  980. // read primary server name
  981. DNS_RPC_NAME* pRPCName1 = &(pDnsRecord->Data.SOA.namePrimaryServer);
  982. ReadRPCString(m_szNamePrimaryServer, pRPCName1);
  983. // read primary server name
  984. DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1);
  985. ASSERT(DNS_IS_NAME_IN_RECORD(pDnsRecord,pRPCName2));
  986. ReadRPCString(m_szResponsibleParty, pRPCName2);
  987. ASSERT(pDnsRecord->wDataLength == (SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER +
  988. pRPCName1->cchNameLength + pRPCName2->cchNameLength + 2) );
  989. }
  990. void CDNS_SOA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  991. {
  992. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  993. ASSERT(FALSE); // TODO
  994. }
  995. void CDNS_SOA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  996. {
  997. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  998. // write header data
  999. (*ppDnsRecord)->Data.SOA.dwSerialNo = m_dwSerialNo;
  1000. (*ppDnsRecord)->Data.SOA.dwRefresh = m_dwRefresh;
  1001. (*ppDnsRecord)->Data.SOA.dwRetry = m_dwRetry;
  1002. (*ppDnsRecord)->Data.SOA.dwExpire = m_dwExpire;
  1003. (*ppDnsRecord)->Data.SOA.dwMinimumTtl = m_dwMinimumTtl;
  1004. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SOA_RECORD_DATA_HEADER;
  1005. // write primary server name
  1006. DNS_RPC_NAME* pRPCName1 = &((*ppDnsRecord)->Data.SOA.namePrimaryServer);
  1007. ASSERT(DNS_IS_DWORD_ALIGNED(pRPCName1));
  1008. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1009. WriteString(pRPCName1, m_szNamePrimaryServer)) & 0xffff);
  1010. // write the responsible party
  1011. DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1);
  1012. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1013. WriteString(pRPCName2, m_szResponsibleParty)) & 0xffff);
  1014. ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName1));
  1015. ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName2));
  1016. }
  1017. void CDNS_SOA_Record::UpdateDisplayData(CString& szDisplayData)
  1018. {
  1019. szDisplayData.Format(_T("[%u], %s, %s"), m_dwSerialNo,
  1020. (LPCTSTR)m_szNamePrimaryServer,(LPCTSTR)m_szResponsibleParty);
  1021. }
  1022. ///////////////////////////////////////////////////////////////////
  1023. // CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record
  1024. CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::
  1025. CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record()
  1026. {
  1027. }
  1028. WORD CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::GetRPCDataLength()
  1029. {
  1030. return RPCBufferStringLen(m_szNameNode);
  1031. }
  1032. void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::
  1033. ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1034. {
  1035. CDNSRecord::ReadRPCData(pDnsRecord);
  1036. ASSERT( (pDnsRecord->wType == DNS_TYPE_PTR) ||
  1037. (pDnsRecord->wType == DNS_TYPE_NS) ||
  1038. (pDnsRecord->wType == DNS_TYPE_CNAME) ||
  1039. (pDnsRecord->wType == DNS_TYPE_MB) ||
  1040. (pDnsRecord->wType == DNS_TYPE_MD) ||
  1041. (pDnsRecord->wType == DNS_TYPE_MF) ||
  1042. (pDnsRecord->wType == DNS_TYPE_MG) ||
  1043. (pDnsRecord->wType == DNS_TYPE_MR) );
  1044. DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.NS.nameNode);
  1045. ASSERT(pDnsRecord->wDataLength == pRPCName->cchNameLength +1);
  1046. // read name node
  1047. ReadRPCString(m_szNameNode, pRPCName);
  1048. }
  1049. void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1050. {
  1051. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1052. ASSERT( (pDnsQueryRecord->wType == DNS_TYPE_PTR) ||
  1053. (pDnsQueryRecord->wType == DNS_TYPE_NS) ||
  1054. (pDnsQueryRecord->wType == DNS_TYPE_CNAME) ||
  1055. (pDnsQueryRecord->wType == DNS_TYPE_MB) ||
  1056. (pDnsQueryRecord->wType == DNS_TYPE_MD) ||
  1057. (pDnsQueryRecord->wType == DNS_TYPE_MF) ||
  1058. (pDnsQueryRecord->wType == DNS_TYPE_MG) ||
  1059. (pDnsQueryRecord->wType == DNS_TYPE_MR) );
  1060. m_szNameNode = pDnsQueryRecord->Data.NS.pNameHost;
  1061. }
  1062. void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record
  1063. ::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1064. {
  1065. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1066. // write name node
  1067. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.NS.nameNode);
  1068. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1069. WriteString(pRPCName,m_szNameNode)) & 0xffff);
  1070. }
  1071. void CDNS_PTR_NS_CNAME_MB_MD_MF_MG_MR_Record::UpdateDisplayData(CString& szDisplayData)
  1072. {
  1073. szDisplayData = m_szNameNode;
  1074. }
  1075. ///////////////////////////////////////////////////////////////////
  1076. // CDNS_MINFO_RP_Record
  1077. CDNS_MINFO_RP_Record::CDNS_MINFO_RP_Record()
  1078. {
  1079. }
  1080. WORD CDNS_MINFO_RP_Record::GetRPCDataLength()
  1081. {
  1082. return static_cast<WORD>(RPCBufferStringLen(m_szNameMailBox) +
  1083. RPCBufferStringLen(m_szErrorToMailbox));
  1084. }
  1085. void CDNS_MINFO_RP_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1086. {
  1087. CDNSRecord::ReadRPCData(pDnsRecord);
  1088. ASSERT( (pDnsRecord->wType == DNS_TYPE_MINFO) ||
  1089. (pDnsRecord->wType == DNS_TYPE_RP));
  1090. // read mailbox name
  1091. DNS_RPC_NAME* pRPCName1 = &(pDnsRecord->Data.MINFO.nameMailBox);
  1092. ReadRPCString(m_szNameMailBox, pRPCName1);
  1093. // read errors to mailbox
  1094. DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1);
  1095. ASSERT(DNS_IS_NAME_IN_RECORD(pDnsRecord,pRPCName2));
  1096. ReadRPCString(m_szErrorToMailbox, pRPCName2);
  1097. ASSERT(pDnsRecord->wDataLength ==
  1098. (pRPCName1->cchNameLength + pRPCName2->cchNameLength + 2) );
  1099. }
  1100. void CDNS_MINFO_RP_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1101. {
  1102. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1103. ASSERT(FALSE); // TODO
  1104. }
  1105. void CDNS_MINFO_RP_Record::
  1106. WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1107. {
  1108. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1109. // write mailbox name
  1110. DNS_RPC_NAME* pRPCName1 = &((*ppDnsRecord)->Data.MINFO.nameMailBox);
  1111. ASSERT(DNS_IS_DWORD_ALIGNED(pRPCName1));
  1112. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1113. WriteString(pRPCName1, m_szNameMailBox)) & 0xffff);
  1114. // write errors to mailbox
  1115. DNS_RPC_NAME* pRPCName2 = DNS_GET_NEXT_NAME(pRPCName1);
  1116. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1117. WriteString(pRPCName2, m_szErrorToMailbox)) & 0xffff);
  1118. ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName1));
  1119. ASSERT(DNS_IS_NAME_IN_RECORD((*ppDnsRecord),pRPCName2));
  1120. }
  1121. void CDNS_MINFO_RP_Record::UpdateDisplayData(CString& szDisplayData)
  1122. {
  1123. if ((GetType() == DNS_TYPE_RP) && (m_szErrorToMailbox.IsEmpty()))
  1124. {
  1125. szDisplayData.Format(_T("%s"),(LPCTSTR)m_szNameMailBox);
  1126. }
  1127. else
  1128. {
  1129. szDisplayData.Format(_T("%s, %s"),
  1130. (LPCTSTR)m_szNameMailBox,(LPCTSTR)m_szErrorToMailbox);
  1131. }
  1132. }
  1133. ///////////////////////////////////////////////////////////////////
  1134. // CDNS_MX_AFSDB_RT_Record
  1135. CDNS_MX_AFSDB_RT_Record::CDNS_MX_AFSDB_RT_Record()
  1136. {
  1137. m_wPreference = 0x0;
  1138. }
  1139. WORD CDNS_MX_AFSDB_RT_Record::GetRPCDataLength()
  1140. {
  1141. return static_cast<WORD>(SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER +
  1142. RPCBufferStringLen(m_szNameExchange));
  1143. }
  1144. void CDNS_MX_AFSDB_RT_Record::
  1145. ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1146. {
  1147. CDNSRecord::ReadRPCData(pDnsRecord);
  1148. ASSERT( (pDnsRecord->wType == DNS_TYPE_MX) ||
  1149. (pDnsRecord->wType == DNS_TYPE_AFSDB) ||
  1150. (pDnsRecord->wType == DNS_TYPE_RT));
  1151. // read header data
  1152. m_wPreference = pDnsRecord->Data.MX.wPreference;
  1153. // read name exchange
  1154. DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.MX.nameExchange);
  1155. ASSERT(pDnsRecord->wDataLength ==
  1156. SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER + pRPCName->cchNameLength +1);
  1157. ReadRPCString(m_szNameExchange, pRPCName);
  1158. }
  1159. void CDNS_MX_AFSDB_RT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1160. {
  1161. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1162. ASSERT(FALSE); // TODO
  1163. }
  1164. void CDNS_MX_AFSDB_RT_Record::
  1165. WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1166. {
  1167. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1168. // write header data
  1169. (*ppDnsRecord)->Data.MX.wPreference = m_wPreference;
  1170. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1171. SIZEOF_DNS_RPC_MXAFSBD_RT_RECORD_DATA_HEADER) & 0xffff);
  1172. // write name exchange
  1173. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.MX.nameExchange);
  1174. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1175. WriteString(pRPCName,m_szNameExchange)) & 0xffff);
  1176. }
  1177. void CDNS_MX_AFSDB_RT_Record::UpdateDisplayData(CString& szDisplayData)
  1178. {
  1179. TCHAR szBuf[32];
  1180. szBuf[0] = NULL;
  1181. LPCTSTR lpsz;
  1182. if ( (m_wType == DNS_TYPE_AFSDB) &&
  1183. ((m_wPreference == AFSDB_PREF_AFS_CELL_DB_SERV) ||
  1184. (m_wPreference == AFSDB_PREF_DCE_AUTH_NAME_SERV)) )
  1185. {
  1186. if (m_wPreference == AFSDB_PREF_AFS_CELL_DB_SERV)
  1187. lpsz = _T("AFS");
  1188. else
  1189. lpsz = _T("DCE");
  1190. }
  1191. else
  1192. {
  1193. wsprintf(szBuf,_T("%d"), m_wPreference);
  1194. lpsz = szBuf;
  1195. }
  1196. szDisplayData.Format(_T("[%s] %s"), lpsz,(LPCTSTR)m_szNameExchange);
  1197. }
  1198. ///////////////////////////////////////////////////////////////////
  1199. // CDNS_AAAA_Record
  1200. CDNS_AAAA_Record::CDNS_AAAA_Record()
  1201. {
  1202. m_wType = DNS_TYPE_AAAA;
  1203. memset(&m_ipv6Address, 0x0,sizeof(IPV6_ADDRESS));
  1204. }
  1205. WORD CDNS_AAAA_Record::GetRPCDataLength()
  1206. {
  1207. return (WORD)SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER;
  1208. }
  1209. void CDNS_AAAA_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1210. {
  1211. CDNSRecord::ReadRPCData(pDnsRecord);
  1212. ASSERT(pDnsRecord->wType == DNS_TYPE_AAAA);
  1213. ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER);
  1214. memcpy(&m_ipv6Address, (UNALIGNED IPV6_ADDRESS*)(&(pDnsRecord->Data.AAAA.ipv6Address)), sizeof(IPV6_ADDRESS));
  1215. }
  1216. void CDNS_AAAA_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1217. {
  1218. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1219. ASSERT(FALSE); // TODO
  1220. }
  1221. void CDNS_AAAA_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1222. {
  1223. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1224. memcpy(&((*ppDnsRecord)->Data.AAAA.ipv6Address), &m_ipv6Address, sizeof(IPV6_ADDRESS));
  1225. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_AAAA_RECORD_DATA_HEADER;
  1226. }
  1227. void CDNS_AAAA_Record::UpdateDisplayData(CString& szDisplayData)
  1228. {
  1229. FormatIPv6Addr(szDisplayData, &m_ipv6Address);
  1230. }
  1231. ///////////////////////////////////////////////////////////////////
  1232. // CDNS_HINFO_ISDN_TXT_X25_Record
  1233. CDNS_HINFO_ISDN_TXT_X25_Record::
  1234. CDNS_HINFO_ISDN_TXT_X25_Record()
  1235. {
  1236. }
  1237. WORD CDNS_HINFO_ISDN_TXT_X25_Record::GetRPCDataLength()
  1238. {
  1239. ASSERT(FALSE); // intermediate class
  1240. return 0;
  1241. }
  1242. void CDNS_HINFO_ISDN_TXT_X25_Record::
  1243. ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1244. {
  1245. CDNSRecord::ReadRPCData(pDnsRecord);
  1246. ASSERT( (pDnsRecord->wType == DNS_TYPE_HINFO) ||
  1247. (pDnsRecord->wType == DNS_TYPE_ISDN) ||
  1248. (pDnsRecord->wType == DNS_TYPE_TEXT) ||
  1249. (pDnsRecord->wType == DNS_TYPE_X25) );
  1250. // loop to the end of the buffer and copy into array of strings
  1251. DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.HINFO.stringData);
  1252. int k = 0;
  1253. WORD wDataLength = 0x0;
  1254. CString szTemp;
  1255. while ((PCHAR)pRPCName < DNS_GET_END_OF_RPC_RECORD_DATA(pDnsRecord))
  1256. {
  1257. ReadRPCString(szTemp, pRPCName);
  1258. OnReadRPCString(szTemp, k++);
  1259. wDataLength = wDataLength + static_cast<WORD>(pRPCName->cchNameLength + 1);
  1260. pRPCName = DNS_GET_NEXT_NAME(pRPCName);
  1261. }
  1262. SetStringCount(k);
  1263. ASSERT(pDnsRecord->wDataLength == wDataLength);
  1264. }
  1265. void CDNS_HINFO_ISDN_TXT_X25_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1266. {
  1267. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1268. ASSERT(FALSE); // TODO
  1269. }
  1270. void CDNS_HINFO_ISDN_TXT_X25_Record::
  1271. WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1272. {
  1273. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1274. // loop through the list of strings
  1275. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.HINFO.stringData);
  1276. int nCount = GetStringCount();
  1277. for (int j=0; j < nCount; j++)
  1278. {
  1279. //(*ppDnsRecord)->wDataLength += WriteString(pRPCName,m_stringDataArray[j]);
  1280. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1281. OnWriteString(pRPCName,j)) & 0xffff);
  1282. pRPCName = DNS_GET_NEXT_NAME(pRPCName);
  1283. }
  1284. }
  1285. void CDNS_HINFO_ISDN_TXT_X25_Record::UpdateDisplayData(CString& szDisplayData)
  1286. {
  1287. ASSERT(FALSE);
  1288. szDisplayData = _T("ERROR, should never happen");
  1289. }
  1290. ///////////////////////////////////////////////////////////////////
  1291. // CDNS_HINFO_Record
  1292. WORD CDNS_HINFO_Record::GetRPCDataLength()
  1293. {
  1294. return static_cast<WORD>(RPCBufferStringLen(m_szCPUType) +
  1295. RPCBufferStringLen(m_szOperatingSystem));
  1296. }
  1297. void CDNS_HINFO_Record::OnReadRPCString(LPCTSTR lpszStr, int k)
  1298. {
  1299. switch (k)
  1300. {
  1301. case 0:
  1302. m_szCPUType = lpszStr;
  1303. break;
  1304. case 1:
  1305. m_szOperatingSystem = lpszStr;
  1306. break;
  1307. default:
  1308. ASSERT(FALSE);
  1309. }
  1310. }
  1311. WORD CDNS_HINFO_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k)
  1312. {
  1313. switch (k)
  1314. {
  1315. case 0:
  1316. return WriteString(pDnsRPCName,m_szCPUType);
  1317. case 1:
  1318. return WriteString(pDnsRPCName,m_szOperatingSystem);
  1319. default:
  1320. ASSERT(FALSE);
  1321. }
  1322. return 0;
  1323. }
  1324. void CDNS_HINFO_Record::UpdateDisplayData(CString& szDisplayData)
  1325. {
  1326. szDisplayData.Format(_T("%s, %s"),(LPCTSTR)m_szCPUType, (LPCTSTR)m_szOperatingSystem);
  1327. }
  1328. ///////////////////////////////////////////////////////////////////
  1329. // CDNS_ISDN_Record
  1330. WORD CDNS_ISDN_Record::GetRPCDataLength()
  1331. {
  1332. return static_cast<WORD>(RPCBufferStringLen(m_szPhoneNumberAndDDI) +
  1333. RPCBufferStringLen(m_szSubAddress));
  1334. }
  1335. CDNS_ISDN_Record::CDNS_ISDN_Record()
  1336. {
  1337. m_wType = DNS_TYPE_ISDN;
  1338. }
  1339. void CDNS_ISDN_Record::OnReadRPCString(LPCTSTR lpszStr, int k)
  1340. {
  1341. switch (k)
  1342. {
  1343. case 0:
  1344. m_szPhoneNumberAndDDI = lpszStr;
  1345. m_szSubAddress.Empty(); // copy from 2 to 1 strings might not execute case 1:
  1346. break;
  1347. case 1:
  1348. m_szSubAddress = lpszStr;
  1349. break;
  1350. default:
  1351. ASSERT(FALSE);
  1352. }
  1353. }
  1354. WORD CDNS_ISDN_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k)
  1355. {
  1356. switch (k)
  1357. {
  1358. case 0:
  1359. return WriteString(pDnsRPCName,m_szPhoneNumberAndDDI);
  1360. case 1:
  1361. {
  1362. ASSERT(!m_szSubAddress.IsEmpty());
  1363. if (m_szSubAddress.IsEmpty())
  1364. return 0;
  1365. return WriteString(pDnsRPCName,m_szSubAddress);
  1366. }
  1367. default:
  1368. ASSERT(FALSE);
  1369. }
  1370. return 0;
  1371. }
  1372. void CDNS_ISDN_Record::UpdateDisplayData(CString& szDisplayData)
  1373. {
  1374. if(m_szSubAddress.IsEmpty())
  1375. szDisplayData = m_szPhoneNumberAndDDI;
  1376. else
  1377. szDisplayData.Format(_T("%s, %s"),(LPCTSTR)m_szPhoneNumberAndDDI, (LPCTSTR)m_szSubAddress);
  1378. }
  1379. ///////////////////////////////////////////////////////////////////
  1380. // CDNS_TXT_Record
  1381. CDNS_TXT_Record::CDNS_TXT_Record()
  1382. {
  1383. m_wType = DNS_TYPE_TEXT;
  1384. m_stringDataArray.SetSize(2,2); // SetSize(size, grow by)
  1385. m_nStringDataCount = 0; // empty
  1386. }
  1387. WORD CDNS_TXT_Record::GetRPCDataLength()
  1388. {
  1389. WORD wLen = 0;
  1390. for (int j=0; j<m_nStringDataCount; j++)
  1391. {
  1392. wLen = static_cast<WORD>((wLen + (RPCBufferStringLen(m_stringDataArray[j])) & 0xffff));
  1393. }
  1394. return wLen;
  1395. }
  1396. void CDNS_TXT_Record::OnReadRPCString(LPCTSTR lpszStr, int k)
  1397. {
  1398. m_stringDataArray.SetAtGrow(k,lpszStr);
  1399. }
  1400. WORD CDNS_TXT_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k)
  1401. {
  1402. return WriteString(pDnsRPCName,m_stringDataArray[k]);
  1403. }
  1404. #define MAX_TXT_DISPLAYLEN 80 // arbitrary width
  1405. void CDNS_TXT_Record::UpdateDisplayData(CString& szDisplayData)
  1406. {
  1407. szDisplayData.Empty();
  1408. if (m_nStringDataCount == 0)
  1409. return;
  1410. szDisplayData = m_stringDataArray[0];
  1411. if (szDisplayData.GetLength() > MAX_TXT_DISPLAYLEN)
  1412. {
  1413. szDisplayData.Left(MAX_TXT_DISPLAYLEN);
  1414. szDisplayData += _T(" ...");
  1415. return;
  1416. }
  1417. for (int j=1; j<m_nStringDataCount; j++)
  1418. {
  1419. szDisplayData += _T(", ");
  1420. szDisplayData += m_stringDataArray[j];
  1421. if (szDisplayData.GetLength() > MAX_TXT_DISPLAYLEN)
  1422. {
  1423. szDisplayData.Left(MAX_TXT_DISPLAYLEN);
  1424. szDisplayData += _T(" ...");
  1425. break;
  1426. }
  1427. }
  1428. }
  1429. ///////////////////////////////////////////////////////////////////
  1430. // CDNS_X25_Record
  1431. WORD CDNS_X25_Record::GetRPCDataLength()
  1432. {
  1433. return RPCBufferStringLen(m_szX121PSDNAddress);
  1434. }
  1435. void CDNS_X25_Record::OnReadRPCString(LPCTSTR lpszStr, int k)
  1436. {
  1437. ASSERT(k == 0);
  1438. m_szX121PSDNAddress = lpszStr;
  1439. }
  1440. WORD CDNS_X25_Record::OnWriteString(DNS_RPC_NAME* pDnsRPCName, int k)
  1441. {
  1442. ASSERT(k == 0);
  1443. return WriteString(pDnsRPCName,m_szX121PSDNAddress);
  1444. }
  1445. void CDNS_X25_Record::UpdateDisplayData(CString& szDisplayData)
  1446. {
  1447. szDisplayData = m_szX121PSDNAddress;
  1448. }
  1449. ///////////////////////////////////////////////////////////////////
  1450. // CDNS_WKS_Record
  1451. CDNS_WKS_Record::CDNS_WKS_Record()
  1452. {
  1453. m_wType = DNS_TYPE_WKS;
  1454. m_ipAddress = 0x0;
  1455. m_chProtocol = DNS_WKS_PROTOCOL_TCP;
  1456. //m_bBitMask[0] = 0x0;
  1457. }
  1458. WORD CDNS_WKS_Record::GetRPCDataLength()
  1459. {
  1460. return static_cast<WORD>(SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER +
  1461. RPCBufferStringLen(m_szServiceList));
  1462. }
  1463. void CDNS_WKS_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1464. {
  1465. CDNSRecord::ReadRPCData(pDnsRecord);
  1466. ASSERT(pDnsRecord->wType == DNS_TYPE_WKS);
  1467. m_ipAddress = pDnsRecord->Data.WKS.ipAddress;
  1468. m_chProtocol = pDnsRecord->Data.WKS.chProtocol;
  1469. DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)(pDnsRecord->Data.WKS.bBitMask);
  1470. ReadRPCString(m_szServiceList, pRPCName);
  1471. //ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER);
  1472. //m_ipAddress = pDnsRecord->Data.WKS.ipAddress;
  1473. //m_chProtocol = pDnsRecord->Data.WKS.chProtocol;
  1474. //m_bBitMask[0] = pDnsRecord->Data.WKS.bBitMask[0];
  1475. }
  1476. void CDNS_WKS_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1477. {
  1478. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1479. ASSERT(FALSE); // TODO
  1480. }
  1481. void CDNS_WKS_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1482. {
  1483. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1484. (*ppDnsRecord)->Data.WKS.ipAddress = m_ipAddress;
  1485. (*ppDnsRecord)->Data.WKS.chProtocol = m_chProtocol;
  1486. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_WKS_RECORD_DATA_HEADER;
  1487. DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)((*ppDnsRecord)->Data.WKS.bBitMask);
  1488. ASSERT(!DNS_IS_DWORD_ALIGNED(pRPCName));
  1489. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1490. WriteString(pRPCName, m_szServiceList)) & 0xffff);
  1491. // (*ppDnsRecord)->Data.WKS.ipAddress = m_ipAddress;
  1492. // (*ppDnsRecord)->Data.WKS.chProtocol = m_chProtocol;
  1493. // (*ppDnsRecord)->Data.WKS.bBitMask[0] = m_bBitMask[0];
  1494. }
  1495. void CDNS_WKS_Record::UpdateDisplayData(CString& szDisplayData)
  1496. {
  1497. TCHAR szBuf[32];
  1498. szBuf[0] = NULL;
  1499. LPCTSTR lpsz;
  1500. if (m_chProtocol == DNS_WKS_PROTOCOL_TCP)
  1501. lpsz = _T("TCP");
  1502. else if (m_chProtocol == DNS_WKS_PROTOCOL_UDP)
  1503. lpsz = _T("UDP");
  1504. else
  1505. {
  1506. wsprintf(szBuf,_T("%d"), m_chProtocol);
  1507. lpsz = szBuf;
  1508. }
  1509. szDisplayData.Format(_T("[%s] %s"), lpsz,(LPCTSTR)m_szServiceList);
  1510. }
  1511. ///////////////////////////////////////////////////////////////////
  1512. // CDNS_WINS_Record
  1513. CDNS_WINS_Record::CDNS_WINS_Record()
  1514. {
  1515. m_wType = DNS_TYPE_WINS;
  1516. m_dwMappingFlag = 0x0;
  1517. m_dwLookupTimeout = DNS_RR_WINS_LOOKUP_DEFAULT_TIMEOUT;
  1518. m_dwCacheTimeout = DNS_RR_WINS_CACHE_DEFAULT_TIMEOUT;
  1519. m_ipWinsServersArray.SetSize(4,4); // SetSize(size, grow by)
  1520. m_nWinsServerCount = 0; // empty
  1521. }
  1522. WORD CDNS_WINS_Record::GetRPCDataLength()
  1523. {
  1524. return static_cast<WORD>((SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER +
  1525. m_nWinsServerCount*sizeof(IP_ADDRESS)) & 0xff);
  1526. }
  1527. void CDNS_WINS_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1528. {
  1529. CDNSRecord::ReadRPCData(pDnsRecord);
  1530. ASSERT(pDnsRecord->wType == DNS_TYPE_WINS);
  1531. ASSERT(pDnsRecord->wDataLength == SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER +
  1532. pDnsRecord->Data.WINS.cWinsServerCount*sizeof(IP_ADDRESS));
  1533. m_dwMappingFlag = pDnsRecord->Data.WINS.dwMappingFlag;
  1534. m_dwLookupTimeout = pDnsRecord->Data.WINS.dwLookupTimeout;
  1535. m_dwCacheTimeout = pDnsRecord->Data.WINS.dwCacheTimeout;
  1536. m_nWinsServerCount = pDnsRecord->Data.WINS.cWinsServerCount;
  1537. for (DWORD k=0; k<pDnsRecord->Data.WINS.cWinsServerCount; k++)
  1538. m_ipWinsServersArray.SetAtGrow(k, pDnsRecord->Data.WINS.aipWinsServers[k]);
  1539. }
  1540. void CDNS_WINS_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1541. {
  1542. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1543. ASSERT(FALSE); // TODO
  1544. }
  1545. void CDNS_WINS_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1546. {
  1547. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1548. (*ppDnsRecord)->Data.WINS.dwMappingFlag = m_dwMappingFlag;
  1549. (*ppDnsRecord)->Data.WINS.dwLookupTimeout = m_dwLookupTimeout;
  1550. (*ppDnsRecord)->Data.WINS.dwCacheTimeout = m_dwCacheTimeout;
  1551. (*ppDnsRecord)->Data.WINS.cWinsServerCount = m_nWinsServerCount;
  1552. for (DWORD k=0; k<(*ppDnsRecord)->Data.WINS.cWinsServerCount; k++)
  1553. (*ppDnsRecord)->Data.WINS.aipWinsServers[k] = m_ipWinsServersArray[k];
  1554. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1555. SIZEOF_DNS_RPC_WINS_RECORD_DATA_HEADER +
  1556. (*ppDnsRecord)->Data.WINS.cWinsServerCount*sizeof(IP_ADDRESS)) &
  1557. 0xffff);
  1558. }
  1559. void CDNS_WINS_Record::UpdateDisplayData(CString& szDisplayData)
  1560. {
  1561. szDisplayData.Empty();
  1562. if (m_nWinsServerCount == 0)
  1563. return;
  1564. // need to chain the IP addresses in a single string
  1565. CString szTemp;
  1566. szTemp.GetBuffer(20); // length of an IP string
  1567. szTemp.ReleaseBuffer();
  1568. szDisplayData.GetBuffer(20*m_nWinsServerCount);
  1569. szDisplayData.ReleaseBuffer();
  1570. for (int k=0; k<m_nWinsServerCount; k++)
  1571. {
  1572. szDisplayData += _T("[");
  1573. FormatIpAddress(szTemp, m_ipWinsServersArray[k]);
  1574. szDisplayData += szTemp;
  1575. szDisplayData += _T("] ");
  1576. }
  1577. }
  1578. ///////////////////////////////////////////////////////////////////
  1579. // CDNS_NBSTAT_Record
  1580. CDNS_NBSTAT_Record::CDNS_NBSTAT_Record()
  1581. {
  1582. m_wType = DNS_TYPE_NBSTAT;
  1583. m_dwMappingFlag = 0x0;
  1584. m_dwLookupTimeout = DNS_RR_WINS_LOOKUP_DEFAULT_TIMEOUT;
  1585. m_dwCacheTimeout = DNS_RR_WINS_CACHE_DEFAULT_TIMEOUT;
  1586. }
  1587. WORD CDNS_NBSTAT_Record::GetRPCDataLength()
  1588. {
  1589. return static_cast<WORD>(SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER +
  1590. RPCBufferStringLen(m_szNameResultDomain));
  1591. }
  1592. void CDNS_NBSTAT_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1593. {
  1594. CDNSRecord::ReadRPCData(pDnsRecord);
  1595. ASSERT(pDnsRecord->wType == DNS_TYPE_NBSTAT);
  1596. m_dwMappingFlag = pDnsRecord->Data.NBSTAT.dwMappingFlag;
  1597. m_dwLookupTimeout = pDnsRecord->Data.NBSTAT.dwLookupTimeout;
  1598. m_dwCacheTimeout = pDnsRecord->Data.NBSTAT.dwCacheTimeout;
  1599. DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.NBSTAT.nameResultDomain);
  1600. ASSERT(pDnsRecord->wDataLength ==
  1601. SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER + pRPCName->cchNameLength +1);
  1602. ReadRPCString(m_szNameResultDomain, pRPCName);
  1603. }
  1604. void CDNS_NBSTAT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1605. {
  1606. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1607. ASSERT(FALSE); // TODO
  1608. }
  1609. void CDNS_NBSTAT_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1610. {
  1611. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1612. (*ppDnsRecord)->Data.NBSTAT.dwMappingFlag = m_dwMappingFlag;
  1613. (*ppDnsRecord)->Data.NBSTAT.dwLookupTimeout = m_dwLookupTimeout;
  1614. (*ppDnsRecord)->Data.NBSTAT.dwCacheTimeout= m_dwCacheTimeout;
  1615. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_NBSTAT_RECORD_DATA_HEADER;
  1616. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.NBSTAT.nameResultDomain);
  1617. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1618. WriteString(pRPCName,m_szNameResultDomain)) & 0xffff);
  1619. }
  1620. void CDNS_NBSTAT_Record::UpdateDisplayData(CString& szDisplayData)
  1621. {
  1622. szDisplayData = m_szNameResultDomain;
  1623. }
  1624. ///////////////////////////////////////////////////////////////////
  1625. // CDNS_SRV_Record
  1626. CDNS_SRV_Record::CDNS_SRV_Record()
  1627. {
  1628. m_wType = DNS_TYPE_SRV;
  1629. m_wPriority = 0x0;
  1630. m_wWeight = 0x0;
  1631. m_wPort = 0x0;
  1632. }
  1633. WORD CDNS_SRV_Record::GetRPCDataLength()
  1634. {
  1635. return static_cast<WORD>(SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER +
  1636. RPCBufferStringLen(m_szNameTarget));
  1637. }
  1638. void CDNS_SRV_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1639. {
  1640. CDNSRecord::ReadRPCData(pDnsRecord);
  1641. ASSERT(pDnsRecord->wType == DNS_TYPE_SRV);
  1642. m_wPriority = pDnsRecord->Data.SRV.wPriority;
  1643. m_wWeight = pDnsRecord->Data.SRV.wWeight;
  1644. m_wPort= pDnsRecord->Data.SRV.wPort;
  1645. DNS_RPC_NAME* pRPCName = &(pDnsRecord->Data.SRV.nameTarget);
  1646. ASSERT(pDnsRecord->wDataLength ==
  1647. SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER + pRPCName->cchNameLength +1);
  1648. ReadRPCString(m_szNameTarget, pRPCName);
  1649. }
  1650. void CDNS_SRV_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1651. {
  1652. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1653. ASSERT(FALSE); // TODO
  1654. }
  1655. void CDNS_SRV_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1656. {
  1657. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1658. (*ppDnsRecord)->Data.SRV.wPriority = m_wPriority;
  1659. (*ppDnsRecord)->Data.SRV.wWeight = m_wWeight;
  1660. (*ppDnsRecord)->Data.SRV.wPort = m_wPort;
  1661. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SRV_RECORD_DATA_HEADER;
  1662. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.SRV.nameTarget);
  1663. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1664. WriteString(pRPCName,m_szNameTarget)) & 0xffff);
  1665. }
  1666. void CDNS_SRV_Record::UpdateDisplayData(CString& szDisplayData)
  1667. {
  1668. szDisplayData.Format(_T("[%d][%d][%d] %s"),
  1669. m_wPriority, m_wWeight, m_wPort, m_szNameTarget);
  1670. }
  1671. ///////////////////////////////////////////////////////////////////
  1672. // CDNS_SIG_Record
  1673. CDNS_SIG_Record::CDNS_SIG_Record()
  1674. {
  1675. m_wType = DNS_TYPE_SIG;
  1676. m_wTypeCovered = 0;
  1677. m_chAlgorithm = 0;
  1678. m_chLabels = 0;
  1679. m_dwOriginalTtl = 0;
  1680. m_dwExpiration = 0;
  1681. m_dwTimeSigned = 0;
  1682. m_wKeyFootprint = 0;
  1683. m_szSignerName = L"";
  1684. }
  1685. WORD CDNS_SIG_Record::GetRPCDataLength()
  1686. {
  1687. WORD wSize = static_cast<WORD>(SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER);
  1688. wSize = static_cast<WORD>(wSize + RPCBufferStringLen(m_szSignerName));
  1689. wSize = static_cast<WORD>(wSize + m_Signature.GetSize());
  1690. return wSize;
  1691. }
  1692. void CDNS_SIG_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1693. {
  1694. CDNSRecord::ReadRPCData(pDnsRecord);
  1695. ASSERT(pDnsRecord->wType == DNS_TYPE_SIG);
  1696. ASSERT(pDnsRecord->wDataLength >= (SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER));
  1697. // constant length data
  1698. m_wTypeCovered = pDnsRecord->Data.SIG.wTypeCovered;
  1699. m_chAlgorithm = pDnsRecord->Data.SIG.chAlgorithm;
  1700. m_chLabels = pDnsRecord->Data.SIG.chLabelCount;
  1701. m_dwOriginalTtl = pDnsRecord->Data.SIG.dwOriginalTtl;
  1702. m_dwExpiration = pDnsRecord->Data.SIG.dwSigExpiration;
  1703. m_dwTimeSigned = pDnsRecord->Data.SIG.dwSigInception;
  1704. m_wKeyFootprint = pDnsRecord->Data.SIG.wKeyTag;
  1705. ReadRPCString(m_szSignerName, &(pDnsRecord->Data.SIG.nameSigner));
  1706. BYTE* pBlob = (BYTE*)DNS_GET_NEXT_NAME(&(pDnsRecord->Data.SIG.nameSigner));
  1707. UINT blobSize = pDnsRecord->wDataLength -
  1708. SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER;
  1709. // Due to DNS server bug 716362 we must special case the length of the
  1710. // nameSigner. The server is returning a cchNameLength of 0 with no achString
  1711. // data. We are expecting a cchNameLength of 1 and an achString of '\0' when
  1712. // the string is empty. This only seems to happen for SIG records
  1713. if (pDnsRecord->Data.SIG.nameSigner.cchNameLength == 0)
  1714. {
  1715. blobSize -= sizeof(UCHAR);
  1716. }
  1717. else
  1718. {
  1719. blobSize -= RPCBufferStringLen(m_szSignerName);
  1720. }
  1721. m_Signature.Set(pBlob, blobSize);
  1722. }
  1723. void CDNS_SIG_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1724. {
  1725. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1726. ASSERT(pDnsQueryRecord->wType == DNS_TYPE_SIG);
  1727. ASSERT(FALSE); // TODO
  1728. }
  1729. void CDNS_SIG_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1730. {
  1731. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1732. // constant length data
  1733. (*ppDnsRecord)->Data.SIG.wTypeCovered = m_wTypeCovered;
  1734. (*ppDnsRecord)->Data.SIG.chAlgorithm = m_chAlgorithm;
  1735. (*ppDnsRecord)->Data.SIG.chLabelCount = m_chLabels;
  1736. (*ppDnsRecord)->Data.SIG.dwOriginalTtl = m_dwOriginalTtl;
  1737. (*ppDnsRecord)->Data.SIG.dwSigExpiration = m_dwExpiration;
  1738. (*ppDnsRecord)->Data.SIG.dwSigInception = m_dwTimeSigned;
  1739. (*ppDnsRecord)->Data.SIG.wKeyTag = m_wKeyFootprint;
  1740. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_SIG_RECORD_DATA_HEADER;
  1741. DNS_RPC_NAME* pRPCName = &((*ppDnsRecord)->Data.SIG.nameSigner);
  1742. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1743. WriteString(pRPCName, m_szSignerName)) & 0xffff);
  1744. BYTE* pSignature = (BYTE*)DNS_GET_NEXT_NAME(&((*ppDnsRecord)->Data.SIG.nameSigner));
  1745. memcpy(pSignature, m_Signature.GetData(), m_Signature.GetSize());
  1746. (*ppDnsRecord)->wDataLength = static_cast<WORD>((*ppDnsRecord)->wDataLength + m_Signature.GetSize());
  1747. }
  1748. void CDNS_SIG_Record::UpdateDisplayData(CString& szDisplayData)
  1749. {
  1750. szDisplayData.Empty();
  1751. //
  1752. // Load the type covered
  1753. //
  1754. PCWSTR pszDisplay = NULL;
  1755. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable();
  1756. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  1757. {
  1758. if (pTable->wType == m_wTypeCovered)
  1759. {
  1760. pszDisplay = pTable->lpszShortName;
  1761. break;
  1762. }
  1763. pTable++;
  1764. }
  1765. szDisplayData += L"[";
  1766. szDisplayData += pszDisplay;
  1767. szDisplayData += L"]";
  1768. //
  1769. // Show the inception date
  1770. //
  1771. CString szInceptionTime;
  1772. if (::ConvertTTLToLocalTimeString(m_dwTimeSigned, szInceptionTime))
  1773. {
  1774. szDisplayData += L"[Inception:";
  1775. szDisplayData += szInceptionTime;
  1776. szDisplayData += L"]";
  1777. }
  1778. //
  1779. // Show the expiration date
  1780. //
  1781. CString szExpirationTime;
  1782. if (::ConvertTTLToLocalTimeString(m_dwExpiration, szExpirationTime))
  1783. {
  1784. szDisplayData += L"[Expiration:";
  1785. szDisplayData += szExpirationTime;
  1786. szDisplayData += L"]";
  1787. }
  1788. //
  1789. // Show the signer's name
  1790. //
  1791. szDisplayData += L"[";
  1792. szDisplayData += m_szSignerName;
  1793. szDisplayData += L"]";
  1794. //
  1795. // Show the algorithms
  1796. //
  1797. PCOMBOBOX_TABLE_ENTRY pTableEntry = g_Algorithms;
  1798. while (pTableEntry->nComboStringID != 0)
  1799. {
  1800. if (static_cast<BYTE>(pTableEntry->dwComboData) == m_chAlgorithm)
  1801. {
  1802. CString szAlgorithm;
  1803. VERIFY(szAlgorithm.LoadString(pTableEntry->nComboStringID));
  1804. szDisplayData += L"[";
  1805. szDisplayData += szAlgorithm;
  1806. szDisplayData += L"]";
  1807. break;
  1808. }
  1809. pTableEntry++;
  1810. }
  1811. //
  1812. // Show the label count
  1813. //
  1814. szDisplayData.Format(L"%s[%d]", szDisplayData, m_chLabels);
  1815. //
  1816. // Show the key footprint
  1817. //
  1818. szDisplayData.Format(L"%s[%d]", szDisplayData, m_wKeyFootprint);
  1819. //
  1820. // Show the key as base64
  1821. //
  1822. szDisplayData += L"[";
  1823. szDisplayData += Base64BLOBToString(m_Signature);
  1824. szDisplayData += L"]";
  1825. }
  1826. ///////////////////////////////////////////////////////////////////
  1827. // CDNS_KEY_Record
  1828. CDNS_KEY_Record::CDNS_KEY_Record()
  1829. {
  1830. m_wType = DNS_TYPE_KEY;
  1831. m_wFlags = 0;
  1832. m_chProtocol = 0;
  1833. m_chAlgorithm = 0;
  1834. }
  1835. WORD CDNS_KEY_Record::GetRPCDataLength()
  1836. {
  1837. WORD wKeySize = static_cast<WORD>(m_Key.GetSize());
  1838. WORD wSize = static_cast<WORD>(SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER + wKeySize);
  1839. return wSize;
  1840. }
  1841. void CDNS_KEY_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1842. {
  1843. CDNSRecord::ReadRPCData(pDnsRecord);
  1844. ASSERT(pDnsRecord->wType == DNS_TYPE_KEY);
  1845. m_wFlags = pDnsRecord->Data.KEY.wFlags;
  1846. m_chProtocol = pDnsRecord->Data.KEY.chProtocol;
  1847. m_chAlgorithm = pDnsRecord->Data.KEY.chAlgorithm;
  1848. //
  1849. // set the blob
  1850. //
  1851. m_Key.Set(pDnsRecord->Data.KEY.bKey,
  1852. pDnsRecord->wDataLength - SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER);
  1853. }
  1854. void CDNS_KEY_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1855. {
  1856. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1857. ASSERT(pDnsQueryRecord->wType == DNS_TYPE_KEY);
  1858. ASSERT(FALSE); // TODO
  1859. }
  1860. void CDNS_KEY_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1861. {
  1862. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1863. (*ppDnsRecord)->Data.KEY.wFlags = m_wFlags;
  1864. (*ppDnsRecord)->Data.KEY.chProtocol = m_chProtocol;
  1865. (*ppDnsRecord)->Data.KEY.chAlgorithm = m_chAlgorithm;
  1866. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_KEY_RECORD_DATA_HEADER;
  1867. BYTE* pKey = (*ppDnsRecord)->Data.KEY.bKey;
  1868. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength + m_Key.Get(pKey)) & 0xffff);
  1869. }
  1870. void CDNS_KEY_Record::UpdateDisplayData(CString& szDisplayData)
  1871. {
  1872. szDisplayData.Empty();
  1873. //
  1874. // Turn the bitfield into a binary string
  1875. //
  1876. CString szTempField;
  1877. WORD wTemp = m_wFlags;
  1878. for (size_t idx = 0; idx < sizeof(WORD) * 8; idx++)
  1879. {
  1880. if ((wTemp & (0x1 << idx)) == 0)
  1881. {
  1882. szTempField = L'0' + szTempField;
  1883. }
  1884. else
  1885. {
  1886. szTempField = L'1' + szTempField;
  1887. }
  1888. }
  1889. szDisplayData += _T("[") + szTempField + _T("]");
  1890. //
  1891. // Load the protocols
  1892. //
  1893. PCOMBOBOX_TABLE_ENTRY pTableEntry = g_Protocols;
  1894. while (pTableEntry->nComboStringID != 0)
  1895. {
  1896. if (static_cast<BYTE>(pTableEntry->dwComboData) == m_chProtocol)
  1897. {
  1898. CString szProtocol;
  1899. VERIFY(szProtocol.LoadString(pTableEntry->nComboStringID));
  1900. szDisplayData += L"[";
  1901. szDisplayData += szProtocol;
  1902. szDisplayData += L"]";
  1903. break;
  1904. }
  1905. pTableEntry++;
  1906. }
  1907. //
  1908. // Load the algorithms
  1909. //
  1910. pTableEntry = g_Algorithms;
  1911. while (pTableEntry->nComboStringID != 0)
  1912. {
  1913. if (static_cast<BYTE>(pTableEntry->dwComboData) == m_chAlgorithm)
  1914. {
  1915. CString szAlgorithm;
  1916. VERIFY(szAlgorithm.LoadString(pTableEntry->nComboStringID));
  1917. szDisplayData += L"[";
  1918. szDisplayData += szAlgorithm;
  1919. szDisplayData += L"]";
  1920. break;
  1921. }
  1922. pTableEntry++;
  1923. }
  1924. //
  1925. // Show the key as base64
  1926. //
  1927. szDisplayData += L"[";
  1928. szDisplayData += Base64BLOBToString(m_Key);
  1929. szDisplayData += L"]";
  1930. }
  1931. ///////////////////////////////////////////////////////////////////
  1932. // CDNS_NXT_Record
  1933. CDNS_NXT_Record::CDNS_NXT_Record()
  1934. {
  1935. m_wType = DNS_TYPE_NXT;
  1936. m_wNumTypesCovered = 0;
  1937. m_pwTypesCovered = NULL;
  1938. }
  1939. CDNS_NXT_Record::~CDNS_NXT_Record()
  1940. {
  1941. if (m_pwTypesCovered != NULL)
  1942. {
  1943. delete[] m_pwTypesCovered;
  1944. m_pwTypesCovered = NULL;
  1945. }
  1946. m_wNumTypesCovered = 0;
  1947. }
  1948. WORD CDNS_NXT_Record::GetRPCDataLength()
  1949. {
  1950. WORD wSize = RPCBufferStringLen(m_szNextDomain);
  1951. wSize = wSize + static_cast<WORD>(m_wNumTypesCovered * sizeof(WORD));
  1952. wSize += static_cast<WORD>(SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER);
  1953. return wSize;
  1954. }
  1955. void CDNS_NXT_Record::ReadRPCData(DNS_RPC_RECORD* pDnsRecord)
  1956. {
  1957. CDNSRecord::ReadRPCData(pDnsRecord);
  1958. ASSERT(pDnsRecord->wType == DNS_TYPE_NXT);
  1959. m_wNumTypesCovered = pDnsRecord->Data.NXT.wNumTypeWords;
  1960. m_pwTypesCovered = new WORD[m_wNumTypesCovered];
  1961. if (m_pwTypesCovered != NULL)
  1962. {
  1963. for (DWORD dwIdx = 0; dwIdx < m_wNumTypesCovered; dwIdx++)
  1964. {
  1965. m_pwTypesCovered[dwIdx] = pDnsRecord->Data.NXT.wTypeWords[dwIdx];
  1966. }
  1967. }
  1968. ReadRPCString(m_szNextDomain, (DNS_RPC_STRING*)(pDnsRecord->Data.NXT.wTypeWords + m_wNumTypesCovered));
  1969. }
  1970. void CDNS_NXT_Record::ReadDnsQueryData(DNS_RECORD* pDnsQueryRecord)
  1971. {
  1972. CDNSRecord::ReadDnsQueryData(pDnsQueryRecord);
  1973. ASSERT(pDnsQueryRecord->wType == DNS_TYPE_NXT);
  1974. ASSERT(FALSE); // TODO
  1975. }
  1976. void CDNS_NXT_Record::WriteRPCData(BYTE* pMem, DNS_RPC_RECORD** ppDnsRecord)
  1977. {
  1978. CDNSRecord::WriteRPCData(pMem, ppDnsRecord);
  1979. (*ppDnsRecord)->wDataLength += SIZEOF_DNS_RPC_NXT_RECORD_DATA_HEADER;
  1980. (*ppDnsRecord)->Data.NXT.wNumTypeWords = m_wNumTypesCovered;
  1981. WORD* pTypesCovered = (*ppDnsRecord)->Data.NXT.wTypeWords;
  1982. if (pTypesCovered != NULL)
  1983. {
  1984. memcpy(pTypesCovered, m_pwTypesCovered, m_wNumTypesCovered * sizeof(WORD));
  1985. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1986. m_wNumTypesCovered * sizeof(WORD)) & 0xffff);
  1987. }
  1988. DNS_RPC_NAME* pRPCName = (DNS_RPC_NAME*)(pTypesCovered + m_wNumTypesCovered);
  1989. (*ppDnsRecord)->wDataLength = static_cast<WORD>(((*ppDnsRecord)->wDataLength +
  1990. WriteString(pRPCName,m_szNextDomain)) & 0xffff);
  1991. }
  1992. void CDNS_NXT_Record::UpdateDisplayData(CString& szDisplayData)
  1993. {
  1994. szDisplayData = m_szNextDomain;
  1995. if (m_wNumTypesCovered > 0)
  1996. {
  1997. szDisplayData += L"[";
  1998. UINT nCount = 0;
  1999. for (DWORD dwIdx = 0; dwIdx < m_wNumTypesCovered; dwIdx++)
  2000. {
  2001. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable();
  2002. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  2003. {
  2004. if (pTable->dwFlags & DNS_RECORD_INFO_FLAG_SHOW_NXT)
  2005. {
  2006. if (pTable->wType == m_pwTypesCovered[dwIdx])
  2007. {
  2008. if (nCount > 0)
  2009. {
  2010. szDisplayData += L",";
  2011. }
  2012. szDisplayData += pTable->lpszShortName;
  2013. nCount++;
  2014. }
  2015. }
  2016. pTable++;
  2017. }
  2018. }
  2019. szDisplayData += L"]";
  2020. }
  2021. }
  2022. ///////////////////////////////////////////////////////////////////
  2023. // CDNS_PTR_RecordNode
  2024. LPCWSTR CDNS_PTR_RecordNode::GetTrueRecordName()
  2025. {
  2026. return m_szLastOctectName;
  2027. }
  2028. void CDNS_PTR_RecordNode::SetRecordName(LPCTSTR lpszName, BOOL bAtTheNode)
  2029. {
  2030. // ASSERT(!bAtTheNode); // must have a non null name all the time
  2031. m_bAtTheNode = bAtTheNode;
  2032. #ifdef _DEBUG
  2033. int nDots = 0;
  2034. LPWSTR p = (LPWSTR)lpszName;
  2035. while (*p)
  2036. {
  2037. if (*p == TEXT('.'))
  2038. nDots++;
  2039. p++;
  2040. }
  2041. ASSERT(nDots == 0);
  2042. #endif // _DEBUG
  2043. m_szDisplayName = m_bAtTheNode ? CDNSRecordInfo::GetAtTheNodeDisplayString() : lpszName;
  2044. // m_szDisplayName = lpszName;
  2045. m_szLastOctectName = lpszName;
  2046. }
  2047. void CDNS_PTR_RecordNode::ChangeDisplayName(CDNSDomainNode* pDomainNode, BOOL bAdvancedView)
  2048. {
  2049. if (IsAtTheNode())
  2050. {
  2051. return;
  2052. }
  2053. if ((!pDomainNode->GetZoneNode()->IsReverse()) || bAdvancedView)
  2054. {
  2055. // for fwd lookup or advanced view, do not change the name
  2056. m_szDisplayName = m_szLastOctectName;
  2057. }
  2058. else
  2059. {
  2060. ASSERT(pDomainNode != NULL);
  2061. LPCWSTR lpszFullName = pDomainNode->GetFullName(); // e.g. "80.55.157.in-addr.arpa"
  2062. m_szDisplayName.Format(_T("%s.%s"), (LPCTSTR)m_szLastOctectName, lpszFullName);
  2063. // now got "77.80.55.157.in-addr.arpa"
  2064. BOOL bArpa = RemoveInAddrArpaSuffix(m_szDisplayName.GetBuffer(1));
  2065. m_szDisplayName.ReleaseBuffer(); // got "77.80.55.157"
  2066. if (!bArpa)
  2067. {
  2068. // failed to detect the arpa suffix, just restore the advanced name
  2069. m_szDisplayName = m_szLastOctectName;
  2070. }
  2071. else
  2072. {
  2073. ReverseIPString(m_szDisplayName.GetBuffer(1));
  2074. m_szDisplayName.ReleaseBuffer(); // finally got "157.55.80.77"
  2075. }
  2076. }
  2077. }
  2078. ////////////////////////////////////////////////////////////////////////////
  2079. // special data structures and definitions to handle NS record editing
  2080. ////////////////////////////////////////////////////////////////////////////
  2081. // CDNSRecordNodeEditInfo
  2082. CDNSRecordNodeEditInfo::CDNSRecordNodeEditInfo()
  2083. {
  2084. m_pRecordNode = NULL;
  2085. m_pRecord = NULL;
  2086. m_pEditInfoList = new CDNSRecordNodeEditInfoList;
  2087. m_bExisting = TRUE;
  2088. m_bUpdateUI = TRUE;
  2089. m_bOwnMemory = FALSE;
  2090. m_bFromDnsQuery = FALSE;
  2091. m_action = unchanged;
  2092. m_dwErr = 0x0;
  2093. }
  2094. CDNSRecordNodeEditInfo::~CDNSRecordNodeEditInfo()
  2095. {
  2096. Cleanup();
  2097. delete m_pEditInfoList;
  2098. ASSERT(m_pRecordNode == NULL);
  2099. ASSERT(m_pRecord == NULL);
  2100. }
  2101. void CDNSRecordNodeEditInfo::CreateFromExistingRecord(CDNSRecordNodeBase* pNode,
  2102. BOOL bOwnMemory,
  2103. BOOL bUpdateUI)
  2104. {
  2105. // copy the pointer to record node, and possibli assume ownership of memory
  2106. // but clone the record for editing
  2107. ASSERT(pNode != NULL);
  2108. m_bExisting = TRUE;
  2109. m_bUpdateUI = bUpdateUI;
  2110. m_bOwnMemory = bOwnMemory;
  2111. m_pRecordNode = pNode;
  2112. m_pRecord = pNode->CreateCloneRecord();
  2113. m_action = unchanged;
  2114. }
  2115. void CDNSRecordNodeEditInfo::CreateFromNewRecord(CDNSRecordNodeBase* pNode)
  2116. {
  2117. // this is a new record, so we own the memory
  2118. ASSERT(pNode != NULL);
  2119. m_bExisting = FALSE;
  2120. m_bOwnMemory = TRUE;
  2121. m_pRecordNode = pNode;
  2122. m_pRecord = pNode->CreateRecord();
  2123. m_action = add;
  2124. }
  2125. void CDNSRecordNodeEditInfo::Cleanup()
  2126. {
  2127. if (m_bOwnMemory && (m_pRecordNode != NULL))
  2128. delete m_pRecordNode;
  2129. m_pRecordNode = NULL;
  2130. if (m_pRecord != NULL)
  2131. {
  2132. delete m_pRecord; // if here, always to be discarded
  2133. m_pRecord = NULL;
  2134. }
  2135. m_pEditInfoList->RemoveAllNodes();
  2136. }
  2137. DNS_STATUS CDNSRecordNodeEditInfo::Update(CDNSDomainNode* pDomainNode, CComponentDataObject* pComponentData)
  2138. {
  2139. ASSERT((m_action == add) || (m_action == edit) || (m_action == unchanged));
  2140. if (m_action == add)
  2141. {
  2142. // new record
  2143. // hook up container and set name of node (same as the zone)
  2144. m_pRecordNode->SetContainer(pDomainNode);
  2145. }
  2146. else if (m_action == edit)
  2147. {
  2148. // preexisting, might have touched the TTL
  2149. // just in case domain node was not set when reading the RR
  2150. m_pRecordNode->SetContainer(pDomainNode);
  2151. }
  2152. // force a write, ignoring error if the record already exists
  2153. BOOL bUseDefaultTTL = (m_pRecord->m_dwTtlSeconds == pDomainNode->GetDefaultTTL());
  2154. m_dwErr = m_pRecordNode->Update(m_pRecord, bUseDefaultTTL,
  2155. /*bIgnoreAlreadyExists*/ TRUE);
  2156. if (m_dwErr == 0 && m_bUpdateUI)
  2157. {
  2158. // update the UI
  2159. if (m_action == add)
  2160. {
  2161. VERIFY(pDomainNode->AddChildToListAndUI(m_pRecordNode, pComponentData));
  2162. pComponentData->SetDescriptionBarText(pDomainNode);
  2163. }
  2164. else // edit
  2165. {
  2166. if (pDomainNode->IsVisible())
  2167. {
  2168. long changeMask = CHANGE_RESULT_ITEM;
  2169. VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pRecordNode, changeMask)));
  2170. }
  2171. }
  2172. }
  2173. return m_dwErr;
  2174. }
  2175. DNS_STATUS CDNSRecordNodeEditInfo::Remove(CDNSDomainNode* pDomainNode,
  2176. CComponentDataObject* pComponentData)
  2177. {
  2178. if (m_bUpdateUI)
  2179. {
  2180. ASSERT(m_pRecordNode->GetDomainNode() == pDomainNode);
  2181. m_dwErr = m_pRecordNode->DeleteOnServerAndUI(pComponentData);
  2182. }
  2183. else
  2184. {
  2185. // temporarily attach the provided domain
  2186. if (m_pRecordNode->GetContainer() == NULL)
  2187. m_pRecordNode->SetContainer(pDomainNode);
  2188. m_pRecordNode->DeleteOnServer();
  2189. }
  2190. if (m_dwErr == 0)
  2191. {
  2192. // own memory from now on
  2193. m_bOwnMemory = TRUE;
  2194. }
  2195. return m_dwErr;
  2196. }
  2197. ////////////////////////////////////////////////////////////////////////////
  2198. // CDNSRecordInfo : table driven info for record types
  2199. CDNSRecordNodeBase* CDNSRecordInfo::CreateRecordNodeFromRPCData(LPCTSTR lpszName,
  2200. DNS_RPC_RECORD* pDnsRecord,
  2201. BOOL bAtTheNode)
  2202. {
  2203. ASSERT(pDnsRecord != NULL);
  2204. //
  2205. // construct an object of the right type
  2206. //
  2207. CDNSRecordNodeBase* pNode = CreateRecordNode(pDnsRecord->wType);
  2208. if (pNode == NULL)
  2209. {
  2210. return NULL;
  2211. }
  2212. //
  2213. // set the object from RPC buffer
  2214. //
  2215. pNode->SetRecordName(lpszName, bAtTheNode);
  2216. pNode->CreateFromRPCRecord(pDnsRecord);
  2217. return pNode;
  2218. }
  2219. #define SWITCH_ENTRY(x) \
  2220. case DNS_TYPE_##x : \
  2221. pNode = new CDNS_##x_RecordNode; \
  2222. break;
  2223. CDNSRecordNodeBase* CDNSRecordInfo::CreateRecordNode(WORD wType)
  2224. {
  2225. CDNSRecordNodeBase* pNode = NULL;
  2226. // construct an object of the right type
  2227. switch (wType)
  2228. {
  2229. case DNS_TYPE_A:
  2230. pNode = new CDNS_A_RecordNode;
  2231. break;
  2232. case DNS_TYPE_ATMA:
  2233. pNode = new CDNS_ATMA_RecordNode;
  2234. break;
  2235. case DNS_TYPE_SOA:
  2236. {
  2237. pNode = new CDNS_SOA_RecordNode;
  2238. if (pNode)
  2239. {
  2240. pNode->SetFlagsDown(TN_FLAG_NO_DELETE, TRUE /*bSet*/);
  2241. }
  2242. }
  2243. break;
  2244. case DNS_TYPE_PTR:
  2245. pNode = new CDNS_PTR_RecordNode;
  2246. break;
  2247. case DNS_TYPE_NS:
  2248. pNode = new CDNS_NS_RecordNode;
  2249. break;
  2250. case DNS_TYPE_CNAME:
  2251. pNode = new CDNS_CNAME_RecordNode;
  2252. break;
  2253. case DNS_TYPE_MB:
  2254. pNode = new CDNS_MB_RecordNode;
  2255. break;
  2256. case DNS_TYPE_MD:
  2257. pNode = new CDNS_MD_RecordNode;
  2258. break;
  2259. case DNS_TYPE_MF:
  2260. pNode = new CDNS_MF_RecordNode;
  2261. break;
  2262. case DNS_TYPE_MG:
  2263. pNode = new CDNS_MG_RecordNode;
  2264. break;
  2265. case DNS_TYPE_MR:
  2266. pNode = new CDNS_MR_RecordNode;
  2267. break;
  2268. case DNS_TYPE_MINFO:
  2269. pNode = new CDNS_MINFO_RecordNode;
  2270. break;
  2271. case DNS_TYPE_RP:
  2272. pNode = new CDNS_RP_RecordNode;
  2273. break;
  2274. case DNS_TYPE_MX:
  2275. pNode = new CDNS_MX_RecordNode;
  2276. break;
  2277. case DNS_TYPE_AFSDB:
  2278. pNode = new CDNS_AFSDB_RecordNode;
  2279. break;
  2280. case DNS_TYPE_RT:
  2281. pNode = new CDNS_RT_RecordNode;
  2282. break;
  2283. case DNS_TYPE_AAAA:
  2284. pNode = new CDNS_AAAA_RecordNode;
  2285. break;
  2286. case DNS_TYPE_HINFO:
  2287. pNode = new CDNS_HINFO_RecordNode;
  2288. break;
  2289. case DNS_TYPE_ISDN:
  2290. pNode = new CDNS_ISDN_RecordNode;
  2291. break;
  2292. case DNS_TYPE_TEXT:
  2293. pNode = new CDNS_TXT_RecordNode;
  2294. break;
  2295. case DNS_TYPE_X25:
  2296. pNode = new CDNS_X25_RecordNode;
  2297. break;
  2298. case DNS_TYPE_WKS:
  2299. pNode = new CDNS_WKS_RecordNode;
  2300. break;
  2301. case DNS_TYPE_WINS:
  2302. pNode = new CDNS_WINS_RecordNode;
  2303. break;
  2304. case DNS_TYPE_NBSTAT:
  2305. pNode = new CDNS_NBSTAT_RecordNode;
  2306. break;
  2307. case DNS_TYPE_SRV:
  2308. pNode = new CDNS_SRV_RecordNode;
  2309. break;
  2310. case DNS_TYPE_KEY:
  2311. pNode = new CDNS_KEY_RecordNode;
  2312. break;
  2313. case DNS_TYPE_SIG:
  2314. pNode = new CDNS_SIG_RecordNode;
  2315. break;
  2316. case DNS_TYPE_NXT:
  2317. pNode = new CDNS_NXT_RecordNode;
  2318. break;
  2319. case DNS_TYPE_NULL:
  2320. pNode = new CDNS_Null_RecordNode;
  2321. break;
  2322. default:
  2323. {
  2324. pNode = new CDNS_Null_RecordNode; // unknown type of record
  2325. }
  2326. }
  2327. ASSERT(pNode != NULL);
  2328. return pNode;
  2329. }
  2330. #define INFO_ENTRY(x) \
  2331. {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", 0x0},
  2332. #define INFO_ENTRY_SHOWNXT(x) \
  2333. {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_SHOW_NXT},
  2334. #define INFO_ENTRY_UI_CREATE(x) \
  2335. {DNS_TYPE_##x , L#x , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE | DNS_RECORD_INFO_FLAG_SHOW_NXT},
  2336. #define INFO_ENTRY_UI_CREATE_AT_NODE(x) \
  2337. {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},
  2338. #define INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(x) \
  2339. {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},
  2340. #define INFO_ENTRY_NAME(x, namestr) \
  2341. {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", 0x0},
  2342. #define INFO_ENTRY_NAME_SHOWNXT(x, namestr) \
  2343. {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_SHOW_NXT},
  2344. #define INFO_ENTRY_NAME_UI_CREATE(x, namestr) \
  2345. {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE | DNS_RECORD_INFO_FLAG_SHOW_NXT},
  2346. #define INFO_ENTRY_NAME_UI_CREATE_AT_NODE(x, namestr) \
  2347. {DNS_TYPE_##x , namestr , NULL , NULL , IDS_RECORD_INFO_##x , L"", DNS_RECORD_INFO_FLAG_UICREATE_AT_NODE | DNS_RECORD_INFO_FLAG_SHOW_NXT},
  2348. #define END_OF_TABLE_INFO_ENTRY { 0 , NULL , NULL , NULL , (UINT)-1 , L"", 0x0}
  2349. const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetInfoEntryTable()
  2350. {
  2351. static DNS_RECORD_INFO_ENTRY info[] =
  2352. {
  2353. // createble record types (at the node also)
  2354. INFO_ENTRY_UI_CREATE_AT_NODE(A)
  2355. INFO_ENTRY_UI_CREATE_AT_NODE(ATMA)
  2356. INFO_ENTRY_UI_CREATE_AT_NODE(AAAA)
  2357. INFO_ENTRY_NAME_UI_CREATE_AT_NODE(TEXT, L"TXT" )
  2358. // createble record types (never at the node)
  2359. INFO_ENTRY_UI_CREATE(CNAME)
  2360. INFO_ENTRY_UI_CREATE(MB)
  2361. INFO_ENTRY_UI_CREATE(MG)
  2362. INFO_ENTRY_UI_CREATE(MR)
  2363. INFO_ENTRY_UI_CREATE(PTR)
  2364. INFO_ENTRY_UI_CREATE(WKS)
  2365. INFO_ENTRY_UI_CREATE(HINFO)
  2366. INFO_ENTRY_UI_CREATE(MINFO)
  2367. INFO_ENTRY_UI_CREATE(MX)
  2368. INFO_ENTRY_UI_CREATE(RP)
  2369. INFO_ENTRY_UI_CREATE(AFSDB)
  2370. INFO_ENTRY_UI_CREATE(X25)
  2371. INFO_ENTRY_UI_CREATE(ISDN)
  2372. INFO_ENTRY_UI_CREATE(RT)
  2373. INFO_ENTRY_UI_CREATE(SRV)
  2374. INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(SIG)
  2375. INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(KEY)
  2376. INFO_ENTRY_UI_CREATE_WHISTLER_OR_LATER(NXT)
  2377. // non createble record types
  2378. INFO_ENTRY_SHOWNXT(SOA) // cannot create an SOA record!!!
  2379. INFO_ENTRY(WINS) // cannot create a WINS record from the Wizard
  2380. INFO_ENTRY_NAME(NBSTAT, L"WINS-R" ) //cannot create a NBSTAT(WINS-R) record from the Wizard
  2381. INFO_ENTRY(NBSTAT)
  2382. INFO_ENTRY_SHOWNXT(NS) // use the Name Servers property page
  2383. INFO_ENTRY_SHOWNXT(MD) // obsolete, should use MX
  2384. INFO_ENTRY_SHOWNXT(MF) // obsolete, should use MX
  2385. INFO_ENTRY_SHOWNXT(NSAP)
  2386. INFO_ENTRY_SHOWNXT(NSAPPTR)
  2387. INFO_ENTRY_SHOWNXT(PX)
  2388. INFO_ENTRY_SHOWNXT(GPOS)
  2389. INFO_ENTRY(NULL) // Null/Unk records can only be viewed
  2390. INFO_ENTRY(UNK)
  2391. END_OF_TABLE_INFO_ENTRY
  2392. };
  2393. return (const DNS_RECORD_INFO_ENTRY*)&info;
  2394. }
  2395. const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetEntry(int nIndex)
  2396. {
  2397. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable();
  2398. int k = 0;
  2399. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  2400. {
  2401. if (k == nIndex)
  2402. return pTable;
  2403. pTable++;
  2404. k++;
  2405. }
  2406. return NULL;
  2407. }
  2408. const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetEntryFromName(LPCWSTR lpszName)
  2409. {
  2410. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable();
  2411. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  2412. {
  2413. LPCWSTR lpszTableName = pTable->lpszFullName;
  2414. if (_wcsicmp(lpszTableName,lpszName) == 0)
  2415. return pTable;
  2416. pTable++;
  2417. }
  2418. return NULL;
  2419. }
  2420. const DNS_RECORD_INFO_ENTRY* CDNSRecordInfo::GetTypeEntry(WORD wType)
  2421. {
  2422. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable();
  2423. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  2424. {
  2425. if (pTable->wType == wType)
  2426. {
  2427. return pTable;
  2428. }
  2429. pTable++;
  2430. }
  2431. return NULL;
  2432. }
  2433. LPCWSTR CDNSRecordInfo::GetTypeString(WORD wType, stringType type)
  2434. {
  2435. const DNS_RECORD_INFO_ENTRY* pTableEntry = GetTypeEntry(wType);
  2436. if (pTableEntry != NULL)
  2437. {
  2438. switch(type)
  2439. {
  2440. case shortName:
  2441. return pTableEntry->lpszShortName;
  2442. case fullName:
  2443. return pTableEntry->lpszFullName;
  2444. case description:
  2445. return pTableEntry->lpszDescription;
  2446. }
  2447. }
  2448. return g_lpszNullString;
  2449. }
  2450. CString CDNSRecordInfo::m_szAtTheNodeDisplayString;
  2451. BOOL CDNSRecordInfo::LoadResources()
  2452. {
  2453. HINSTANCE hInstance = _Module.GetModuleInstance();
  2454. ASSERT(hInstance != NULL);
  2455. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)GetInfoEntryTable();
  2456. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  2457. {
  2458. if (0 == ::LoadString(hInstance, pTable->nResourceID,
  2459. pTable->cStringData, MAX_RECORD_RESOURCE_STRLEN))
  2460. return FALSE; // mmissing resource string?
  2461. // parse and replace \n with NULL
  2462. pTable->lpszFullName = pTable->cStringData;
  2463. for (WCHAR* pCh = pTable->cStringData; (*pCh) != NULL; pCh++)
  2464. {
  2465. if ( (*pCh) == L'\n')
  2466. {
  2467. pTable->lpszDescription = (pCh+1);
  2468. (*pCh) = NULL;
  2469. break;
  2470. }
  2471. }
  2472. pTable++;
  2473. }
  2474. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2475. return m_szAtTheNodeDisplayString.LoadString(IDS_RECORD_AT_THE_NODE);
  2476. }