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.

1258 lines
33 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1998
  6. //
  7. // File: recpag1.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. #ifdef DEBUG_ALLOCATOR
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. #endif
  26. #define DISPLAY_KEY_BASE_COUNT 2
  27. #define HEX_DISPLAY_INDEX 0
  28. #define BASE64_DISPLAY_INDEX 1
  29. ////////////////////////////////////////////////////////////////////////////
  30. // CDNS_Unk_RecordPropertyPage
  31. CDNS_Unk_RecordPropertyPage::CDNS_Unk_RecordPropertyPage()
  32. : CDNSRecordStandardPropertyPage(IDD_RR_UNK)
  33. {
  34. }
  35. void CDNS_Unk_RecordPropertyPage::SetUIData()
  36. {
  37. STANDARD_REC_PP_SETUI_PROLOGUE(CDNS_Null_Record);
  38. // set record type field
  39. CString szBuf;
  40. CStatic* pType = (CStatic*)GetDlgItem(IDC_TYPE_STATIC);
  41. szBuf.Format(_T("%d (0x%x)"), pRecord->m_wType, pRecord->m_wType);
  42. pType->SetWindowText(szBuf);
  43. // set data type field
  44. CStatic* pSize = (CStatic*)GetDlgItem(IDC_SIZE_STATIC);
  45. szBuf.Format(_T("%d (0x%x)"), pRecord->m_blob.GetSize(), pRecord->m_blob.GetSize());
  46. pSize->SetWindowText(szBuf);
  47. LoadHexDisplay();
  48. }
  49. BOOL CDNS_Unk_RecordPropertyPage::OnInitDialog()
  50. {
  51. CDNSRecordStandardPropertyPage::OnInitDialog();
  52. CEdit* pEdit = GetEditBox();
  53. ASSERT(pEdit != NULL);
  54. VERIFY(m_font.CreatePointFont(120,_T("fixedsys")));
  55. pEdit->SetFont(&m_font);
  56. return TRUE;
  57. }
  58. #define MAX_LINE_SIZE 64
  59. #define HEX_BUF_SIZE 12
  60. #define CH_BUF_SIZE 5
  61. void CDNS_Unk_RecordPropertyPage::LoadHexDisplay()
  62. {
  63. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  64. CDNS_Null_Record* pRecord = (CDNS_Null_Record*)pHolder->GetTempDNSRecord();
  65. UINT nBytes = pRecord->m_blob.GetSize();
  66. BYTE* pData = pRecord->m_blob.GetData();
  67. UINT nLines = nBytes/4; // # of complete lines
  68. if (nLines*4 < nBytes)
  69. nLines++; // add one truncated line
  70. TCHAR* pMem = (TCHAR*)malloc(sizeof(TCHAR)*MAX_LINE_SIZE*nLines);
  71. if (!pMem)
  72. {
  73. ASSERT(FALSE);
  74. return;
  75. }
  76. TCHAR* pBuf = pMem;
  77. CEdit* pEdit = GetEditBox();
  78. pEdit->SetReadOnly(FALSE);
  79. // walk the blob and write to the display buffer
  80. for(UINT k=0; k<nLines; k++)
  81. {
  82. UINT i;
  83. BYTE* pOffset = (pData+4*k);
  84. UINT nBytesThisLine = min(nBytes - 4*k,4);
  85. // get the values for the hex representation
  86. TCHAR chHex[HEX_BUF_SIZE]; // "xx" * 4 fields
  87. for (i=0;i<HEX_BUF_SIZE-1;i++) chHex[i] = TEXT(' ');
  88. for (i=0;i<nBytesThisLine;i++)
  89. {
  90. BYTE high = static_cast<BYTE>(*(pOffset+i) >> 4);
  91. BYTE low = static_cast<BYTE>(*(pOffset+i) & 0x0f);
  92. // just offset out of the ASCII table
  93. *(chHex+3*i) = static_cast<TCHAR>((high <= 9) ? (high + TEXT('0')) : ( high - 10 + TEXT('a')));
  94. *(chHex+3*i+1) = static_cast<TCHAR>((low <= 9) ? (low + TEXT('0')) : ( low - 10 + TEXT('a')));
  95. *(chHex+3*i+2) = TEXT(' ');
  96. }
  97. chHex[HEX_BUF_SIZE-1] = NULL;
  98. // get the values for the character representation
  99. TCHAR ch[CH_BUF_SIZE];
  100. for (i=0;i<CH_BUF_SIZE-1;i++) ch[i] = TEXT(' ');
  101. for (i=0;i<nBytesThisLine;i++)
  102. {
  103. // 1. assume the blob of data IS in ASCII
  104. // 2. try to interpret bytes as ASCII printable chars
  105. // 3. if successful convert to UNICODE
  106. if (isprint(*(pOffset+i)) && (*(pOffset+i) != '\0')) // compare ASCII
  107. {
  108. // convert from ASCII to UNICODE
  109. USES_CONVERSION;
  110. CHAR szTmp[2]; // ASCII
  111. szTmp[0] = *(pOffset+i);
  112. szTmp[1] = NULL;
  113. LPWSTR lpszW = A2W(szTmp); // convert
  114. ch[i] = lpszW[0]; // UNICODE
  115. }
  116. else
  117. ch[i] = TEXT('?'); // unknown character or NULL, UNICODE
  118. }
  119. ch[CH_BUF_SIZE-1] = NULL;
  120. int nCharsPrinted = wsprintf(pBuf, _T("%.4x %s %s\r\n"), k*4, chHex,ch);
  121. pBuf = pBuf + nCharsPrinted;
  122. }
  123. // assign the buffer to the control and update
  124. pEdit->SetWindowText(pMem);
  125. pEdit->SetReadOnly(TRUE);
  126. pEdit->UpdateWindow();
  127. if (pMem)
  128. {
  129. free(pMem);
  130. pMem = 0;
  131. }
  132. }
  133. ////////////////////////////////////////////////////////////////////////////
  134. // CDNS_TXT_RecordPropertyPage
  135. BEGIN_MESSAGE_MAP(CDNS_TXT_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  136. ON_EN_CHANGE(IDC_RR_TXT_EDIT, OnTextEditBoxChange)
  137. END_MESSAGE_MAP()
  138. CDNS_TXT_RecordPropertyPage::CDNS_TXT_RecordPropertyPage()
  139. : CDNSRecordStandardPropertyPage(IDD_RR_TXT)
  140. {
  141. }
  142. void CDNS_TXT_RecordPropertyPage::SetUIData()
  143. {
  144. CDNSRecordStandardPropertyPage::SetUIData();
  145. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  146. CDNS_TXT_Record* pRecord = (CDNS_TXT_Record*)pHolder->GetTempDNSRecord();
  147. SetEditBoxValue(pRecord->m_stringDataArray,pRecord->m_nStringDataCount);
  148. //SetDirty(FALSE);
  149. }
  150. DNS_STATUS CDNS_TXT_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  151. {
  152. DNS_STATUS dwErr = 0;
  153. dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  154. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  155. CDNS_TXT_Record* pRecord = (CDNS_TXT_Record*)pHolder->GetTempDNSRecord();
  156. GetEditBoxValue(pRecord->m_stringDataArray,&(pRecord->m_nStringDataCount));
  157. return dwErr;
  158. }
  159. void CDNS_TXT_RecordPropertyPage::OnTextEditBoxChange()
  160. {
  161. SetDirty(TRUE);
  162. }
  163. void CDNS_TXT_RecordPropertyPage::SetEditBoxValue(CStringArray& sArr, int nSize)
  164. {
  165. CString szBuf;
  166. szBuf.GetBufferSetLength(128); // just to avoid too many reallocations
  167. szBuf.ReleaseBuffer();
  168. for (int k=0;k<nSize;k++)
  169. {
  170. szBuf += sArr[k];
  171. if (k < nSize-1)
  172. szBuf += _T("\r\n");
  173. }
  174. GetTextEditBox()->SetWindowText(szBuf);
  175. }
  176. void CDNS_TXT_RecordPropertyPage::GetEditBoxValue(CStringArray& sArr, int* pNSize)
  177. {
  178. CEdit* pEdit = GetTextEditBox();
  179. int nBufLen = pEdit->GetWindowTextLength() + 1;
  180. TCHAR* pMem = (TCHAR*) malloc(sizeof(TCHAR)*nBufLen);
  181. if (!pMem)
  182. {
  183. ASSERT(FALSE);
  184. return;
  185. }
  186. VERIFY(pEdit->GetWindowText(pMem, nBufLen) <= nBufLen);
  187. TCHAR *p1,*p2;
  188. p1=p2 = pMem;
  189. *pNSize = 0;
  190. while (TRUE)
  191. {
  192. if (*p2 == TEXT('\r'))
  193. {
  194. *p2 = NULL;
  195. sArr.SetAtGrow((*pNSize)++, p1);
  196. TRACE(_T("parsing<%s>\n"),(LPCTSTR)p1);
  197. p1 = p2+2;
  198. p2=p1;
  199. }
  200. else if (*p2 == NULL)
  201. {
  202. sArr.SetAtGrow((*pNSize)++, p1);
  203. TRACE(_T("parsing<%s>\n"),(LPCTSTR)p1);
  204. break;
  205. }
  206. else
  207. p2++;
  208. }
  209. if (pMem)
  210. {
  211. free(pMem);
  212. pMem = 0;
  213. }
  214. }
  215. ////////////////////////////////////////////////////////////////////////////
  216. COMBOBOX_TABLE_ENTRY g_Algorithms[] =
  217. {
  218. { IDS_ALGORITHM_RSAMD5, 1 },
  219. { IDS_ALGORITHM_DIFFIE, 2 },
  220. { IDS_ALGORITHM_DSA, 3 },
  221. { IDS_ALGORITHM_ELIPTIC, 4 },
  222. { IDS_ALGORITHM_INDIRECT, 252 },
  223. { NULL, NULL }
  224. };
  225. COMBOBOX_TABLE_ENTRY g_Protocols[] =
  226. {
  227. { IDS_PROTOCOL_TLS, 1 },
  228. { IDS_PROTOCOL_EMAIL, 2 },
  229. { IDS_PROTOCOL_DNSSEC, 3 },
  230. { IDS_PROTOCOL_IPSEC, 4 },
  231. { IDS_PROTOCOL_ALL, 255 },
  232. { NULL, NULL }
  233. };
  234. ////////////////////////////////////////////////////////////////////////////
  235. // CDNS_SIG_RecordPropertyPage
  236. BEGIN_MESSAGE_MAP(CDNS_SIG_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  237. ON_EN_CHANGE(IDC_KEY_TAG_EDIT, OnSigEditChange)
  238. ON_EN_CHANGE(IDC_SIGNERS_NAME_EDIT, OnSigEditChange)
  239. ON_EN_CHANGE(IDC_ORIG_TTL, OnSigEditChange)
  240. ON_EN_CHANGE(IDC_SIG_EDIT, OnSigEditChange)
  241. ON_EN_CHANGE(IDC_LABELS_EDIT, OnSigEditChange)
  242. ON_CBN_SELCHANGE(IDC_RECORD_TYPE_COMBO, OnComboChange)
  243. ON_CBN_SELCHANGE(IDC_ALGORITHM_COMBO, OnComboChange)
  244. ON_NOTIFY(DTN_DATETIMECHANGE, IDC_EXP_DATE, OnDateTimeChange)
  245. ON_NOTIFY(DTN_DATETIMECHANGE, IDC_EXP_TIME, OnDateTimeChange)
  246. ON_NOTIFY(DTN_DATETIMECHANGE, IDC_INC_DATE, OnDateTimeChange)
  247. ON_NOTIFY(DTN_DATETIMECHANGE, IDC_INC_TIME, OnDateTimeChange)
  248. END_MESSAGE_MAP()
  249. CDNS_SIG_RecordPropertyPage::CDNS_SIG_RecordPropertyPage()
  250. : CDNSRecordStandardPropertyPage(IDD_RR_SIG)
  251. {
  252. }
  253. BOOL CDNS_SIG_RecordPropertyPage::OnInitDialog()
  254. {
  255. CDNSRecordStandardPropertyPage::OnInitDialog();
  256. CDNSRecordStandardPropertyPage::SetUIData();
  257. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  258. CDNSRootData* pRootData = dynamic_cast<CDNSRootData*>(pHolder->GetDomainNode()->GetRootContainer());
  259. if (pRootData)
  260. {
  261. //
  262. // Load the type covered combo box
  263. //
  264. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable();
  265. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  266. {
  267. // some record types cannot be created with this wizard
  268. if (pTable->dwFlags & DNS_RECORD_INFO_FLAG_SHOW_NXT)
  269. {
  270. PCWSTR pszDisplay = (pTable->lpszFullName);
  271. LRESULT idx = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_ADDSTRING, 0, (LPARAM)pszDisplay);
  272. if (idx != CB_ERR)
  273. {
  274. SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_SETITEMDATA, (WPARAM)idx, (LPARAM)pTable->wType);
  275. }
  276. }
  277. pTable++;
  278. }
  279. }
  280. //
  281. // Load the Algorithms combo box
  282. //
  283. VERIFY(LoadComboBoxFromTable(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)),
  284. g_Algorithms));
  285. //
  286. // Select the first item in the combo box
  287. //
  288. SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_SETCURSEL, 0, 0);
  289. //
  290. // Limit the key tag to 5 characters (0-65535)
  291. //
  292. SendDlgItemMessage(IDC_KEY_TAG_EDIT, EM_SETLIMITTEXT, (WPARAM)5, 0);
  293. //
  294. // NTRAID#NTBUG9-505387-2002/01/22-JeffJon
  295. // Set limit on the key so that we don't AV
  296. //
  297. SendDlgItemMessage(IDC_KEY_EDIT, EM_SETLIMITTEXT, (WPARAM)1024, 0);
  298. //
  299. // Limit the labels tag to 3 characters (1-127)
  300. //
  301. SendDlgItemMessage(IDC_LABELS_EDIT, EM_SETLIMITTEXT, (WPARAM)3, 0);
  302. return FALSE;
  303. }
  304. void CDNS_SIG_RecordPropertyPage::ConvertUIKeyStringToByteArray(BYTE* pByte, DWORD* pdwLength)
  305. {
  306. CString szValue;
  307. GetDlgItemText(IDC_SIG_EDIT, szValue);
  308. //
  309. // Switch the value from base 64 to hex
  310. //
  311. DNS_STATUS err = Dns_SecurityBase64StringToKey(pByte, pdwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  312. ASSERT(err == 0);
  313. }
  314. void CDNS_SIG_RecordPropertyPage::OnDateTimeChange(NMHDR*, LRESULT*)
  315. {
  316. SetDirty(TRUE);
  317. }
  318. void CDNS_SIG_RecordPropertyPage::OnSigEditChange()
  319. {
  320. SetDirty(TRUE);
  321. }
  322. void CDNS_SIG_RecordPropertyPage::OnComboChange()
  323. {
  324. SetDirty(TRUE);
  325. }
  326. void CDNS_SIG_RecordPropertyPage::ShowSigValue(PBYTE pKey, DWORD dwKeySize)
  327. {
  328. SetDlgItemText(IDC_SIG_EDIT, Base64BLOBToString(pKey, dwKeySize));
  329. }
  330. void CDNS_SIG_RecordPropertyPage::SetUIData()
  331. {
  332. CDNSRecordStandardPropertyPage::SetUIData();
  333. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  334. CDNS_SIG_Record* pRecord = (CDNS_SIG_Record*)pHolder->GetTempDNSRecord();
  335. //
  336. // Set the type covered
  337. //
  338. m_wTypeCovered = pRecord->m_wTypeCovered;
  339. SelectTypeCoveredByType(pRecord->m_wTypeCovered);
  340. //
  341. // Set the algorithm
  342. //
  343. m_chAlgorithm = pRecord->m_chAlgorithm;
  344. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)), pRecord->m_chAlgorithm);
  345. //
  346. // Set the label count
  347. //
  348. SetDlgItemInt(IDC_LABELS_EDIT, pRecord->m_chLabels);
  349. //
  350. // Set the signer's name
  351. //
  352. m_szSignerName = pRecord->m_szSignerName;
  353. SetDlgItemText(IDC_SIGNERS_NAME_EDIT, m_szSignerName);
  354. //
  355. // Set the signature value
  356. //
  357. ShowSigValue(pRecord->m_Signature.GetData(), pRecord->m_Signature.GetSize());
  358. //
  359. // Set the original TTL
  360. //
  361. m_dwOriginalTtl = pRecord->m_dwOriginalTtl;
  362. GetOrigTTL()->SetTTL(m_dwOriginalTtl);
  363. //
  364. // Get the local time zone information
  365. //
  366. TIME_ZONE_INFORMATION tzInfo;
  367. memset(&tzInfo, 0, sizeof(TIME_ZONE_INFORMATION));
  368. ::GetTimeZoneInformation(&tzInfo);
  369. //
  370. // Set the expiration TTL
  371. //
  372. m_dwExpiration = pRecord->m_dwExpiration;
  373. SYSTEMTIME stExpTime;
  374. ::ConvertTTLToSystemTime(&tzInfo, m_dwExpiration, &stExpTime);
  375. SendDlgItemMessage(IDC_EXP_DATE, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stExpTime);
  376. SendDlgItemMessage(IDC_EXP_TIME, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stExpTime);
  377. //
  378. // Set the inception TTL
  379. //
  380. m_dwTimeSigned = pRecord->m_dwTimeSigned;
  381. SYSTEMTIME stIncTime;
  382. ::ConvertTTLToSystemTime(&tzInfo, m_dwTimeSigned, &stIncTime);
  383. SendDlgItemMessage(IDC_INC_DATE, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stIncTime);
  384. SendDlgItemMessage(IDC_INC_TIME, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stIncTime);
  385. //
  386. // Set key tag edit
  387. //
  388. m_wKeyTag = pRecord->m_wKeyFootprint;
  389. SetDlgItemInt(IDC_KEY_TAG_EDIT, m_wKeyTag, FALSE);
  390. }
  391. void CDNS_SIG_RecordPropertyPage::SelectTypeCoveredByType(WORD wType)
  392. {
  393. LRESULT lCount = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETCOUNT, 0, 0);
  394. if (lCount != CB_ERR)
  395. {
  396. for (LRESULT lIdx = 0; lIdx < lCount; lIdx++)
  397. {
  398. LRESULT lData = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETITEMDATA, (WPARAM)lIdx, 0);
  399. if (lData != CB_ERR)
  400. {
  401. if (wType == static_cast<WORD>(lData))
  402. {
  403. SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_SETCURSEL, (WPARAM)lIdx, 0);
  404. break;
  405. }
  406. }
  407. }
  408. }
  409. }
  410. DNS_STATUS CDNS_SIG_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  411. {
  412. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  413. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  414. CDNS_SIG_Record* pRecord = (CDNS_SIG_Record*)pHolder->GetTempDNSRecord();
  415. //
  416. // Get the type covered
  417. //
  418. LRESULT lTypeIdx = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  419. if (lTypeIdx != CB_ERR)
  420. {
  421. LRESULT lTypeData = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETITEMDATA, (WPARAM)lTypeIdx, 0);
  422. if (lTypeData != CB_ERR)
  423. {
  424. pRecord->m_wTypeCovered = static_cast<WORD>(lTypeData);
  425. }
  426. }
  427. //
  428. // Get the algorithm
  429. //
  430. LRESULT lAlgorithmIdx = SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETCURSEL, 0, 0);
  431. if (lAlgorithmIdx != CB_ERR)
  432. {
  433. pRecord->m_chAlgorithm = static_cast<BYTE>(SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETITEMDATA, (WPARAM)lAlgorithmIdx, 0));
  434. }
  435. //
  436. // Get the labels count
  437. //
  438. BOOL bLabelSuccess = FALSE;
  439. int iLabelVal = GetDlgItemInt(IDC_LABELS_EDIT, &bLabelSuccess, FALSE);
  440. if (bLabelSuccess)
  441. {
  442. if (iLabelVal > 127)
  443. {
  444. iLabelVal = 127;
  445. SetDlgItemInt(IDC_KEY_TAG_EDIT, iLabelVal, FALSE);
  446. if (!bSilent)
  447. {
  448. DNSMessageBox(IDS_MSG_SIG_LABEL_RANGE);
  449. }
  450. }
  451. pRecord->m_chLabels = static_cast<BYTE>(iLabelVal);
  452. }
  453. //
  454. // Get the original ttl
  455. //
  456. GetOrigTTL()->GetTTL(&pRecord->m_dwOriginalTtl);
  457. //
  458. // Get the expiration date
  459. //
  460. SYSTEMTIME stExpDate;
  461. memset(&stExpDate, 0, sizeof(SYSTEMTIME));
  462. LRESULT lExpDateRes = SendDlgItemMessage(IDC_EXP_DATE, DTM_GETSYSTEMTIME, 0, (LPARAM)&stExpDate);
  463. if (lExpDateRes == GDT_VALID)
  464. {
  465. SYSTEMTIME stExpTime;
  466. memset(&stExpTime, 0, sizeof(SYSTEMTIME));
  467. LRESULT lExpTimeRes = SendDlgItemMessage(IDC_EXP_TIME, DTM_GETSYSTEMTIME, 0, (LPARAM)&stExpTime);
  468. if (lExpTimeRes == GDT_VALID)
  469. {
  470. stExpDate.wHour = stExpTime.wHour;
  471. stExpDate.wMinute = stExpTime.wMinute;
  472. stExpDate.wSecond = stExpTime.wSecond;
  473. stExpDate.wMilliseconds = stExpTime.wMilliseconds;
  474. pRecord->m_dwExpiration = ConvertSystemTimeToTTL(&stExpDate);
  475. }
  476. }
  477. //
  478. // Get the inception date
  479. //
  480. SYSTEMTIME stIncDate;
  481. memset(&stIncDate, 0, sizeof(SYSTEMTIME));
  482. LRESULT lIncDateRes = SendDlgItemMessage(IDC_INC_DATE, DTM_GETSYSTEMTIME, 0, (LPARAM)&stIncDate);
  483. if (lIncDateRes == GDT_VALID)
  484. {
  485. SYSTEMTIME stIncTime;
  486. memset(&stIncTime, 0, sizeof(SYSTEMTIME));
  487. LRESULT lIncTimeRes = SendDlgItemMessage(IDC_INC_TIME, DTM_GETSYSTEMTIME, 0, (LPARAM)&stIncTime);
  488. if (lIncTimeRes == GDT_VALID)
  489. {
  490. stIncDate.wHour = stIncTime.wHour;
  491. stIncDate.wMinute = stIncTime.wMinute;
  492. stIncDate.wSecond = stIncTime.wSecond;
  493. stIncDate.wMilliseconds = stIncTime.wMilliseconds;
  494. pRecord->m_dwTimeSigned = ConvertSystemTimeToTTL(&stIncDate);
  495. }
  496. }
  497. //
  498. // Get the key tag
  499. //
  500. BOOL bSuccess = FALSE;
  501. int iVal = GetDlgItemInt(IDC_KEY_TAG_EDIT, &bSuccess, FALSE /*unsigned*/);
  502. if (bSuccess)
  503. {
  504. pRecord->m_wKeyFootprint = static_cast<WORD>(iVal);
  505. }
  506. //
  507. // Get the signer's name
  508. //
  509. GetDlgItemText(IDC_SIGNERS_NAME_EDIT, pRecord->m_szSignerName);
  510. //
  511. // Get the key
  512. //
  513. DWORD dwLength;
  514. CString szValue;
  515. GetDlgItemText(IDC_SIG_EDIT, szValue);
  516. //
  517. // Switch the value from base 64 to byte array
  518. //
  519. //
  520. // The conversion function is expecting characters in multiples of 4. So if we have
  521. // a string that does not have a multiple of 4 number of characters, pad the string
  522. // with the pad character, except if the string requires more than 2 pad characters.
  523. // RFC 2535 Appendix A doesn't address the issue where string length % 4 == 3. In this
  524. // case we will show an error.
  525. //
  526. int iLengthMod4 = szValue.GetLength() % 4;
  527. int iPads = 4 - iLengthMod4;
  528. if (iLengthMod4 == 1)
  529. {
  530. if (!bSilent)
  531. {
  532. dwErr = ERROR_INVALID_PARAMETER;
  533. ::DNSErrorDialog(dwErr, IDS_ERRMSG_BASE64);
  534. return dwErr;
  535. }
  536. }
  537. else if (iPads != 0 && iPads != 4)
  538. {
  539. for (int i = 0; i < iPads; i++)
  540. {
  541. szValue += SECURITY_PAD_CHAR;
  542. }
  543. }
  544. ASSERT(szValue.GetLength() % 4 == 0);
  545. // The largest string will have 4 characters for every 3 bytes in the string
  546. DWORD maxDataLength = (szValue.GetLength() / 4) * 3;
  547. BYTE* pByte = new BYTE[maxDataLength];
  548. if (pByte)
  549. {
  550. ZeroMemory(pByte, sizeof(BYTE) * maxDataLength);
  551. dwErr = Dns_SecurityBase64StringToKey(pByte, &dwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  552. if (dwErr != ERROR_SUCCESS)
  553. {
  554. if (!bSilent)
  555. {
  556. ::DNSErrorDialog(dwErr, IDS_ERRMSG_BASE64);
  557. }
  558. }
  559. else
  560. {
  561. pRecord->m_Signature.Set(pByte, dwLength);
  562. }
  563. // The CByteBlob::Set does a copy so we are OK to delete here
  564. delete[] pByte;
  565. }
  566. return dwErr;
  567. }
  568. ////////////////////////////////////////////////////////////////////////////
  569. // CDNS_KEY_RecordPropertyPage
  570. BEGIN_MESSAGE_MAP(CDNS_KEY_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  571. ON_EN_CHANGE(IDC_KEY_EDIT, OnEditChange)
  572. ON_CBN_SELCHANGE(IDC_KEY_TYPE_COMBO, OnKeyTypeChange)
  573. ON_CBN_SELCHANGE(IDC_NAME_TYPE_COMBO, OnNameTypeChange)
  574. ON_CBN_SELCHANGE(IDC_PROTOCOL_COMBO, OnProtocolChange)
  575. ON_CBN_SELCHANGE(IDC_ALGORITHM_COMBO, OnAlgorithmChange)
  576. ON_CLBN_CHKCHANGE(IDC_LOGGING_OPTIONS_LIST, OnSignatoryChange)
  577. END_MESSAGE_MAP()
  578. CDNS_KEY_RecordPropertyPage::CDNS_KEY_RecordPropertyPage()
  579. : CDNSRecordStandardPropertyPage(IDD_RR_KEY)
  580. {
  581. }
  582. BOOL CDNS_KEY_RecordPropertyPage::OnInitDialog()
  583. {
  584. CDNSRecordStandardPropertyPage::OnInitDialog();
  585. VERIFY(LoadStringsToComboBox(_Module.GetModuleInstance(),
  586. reinterpret_cast<CComboBox*>(GetDlgItem(IDC_KEY_TYPE_COMBO)),
  587. IDS_KEY_TYPES,
  588. 256,
  589. KEY_TYPE_COUNT));
  590. VERIFY(LoadStringsToComboBox(_Module.GetModuleInstance(),
  591. reinterpret_cast<CComboBox*>(GetDlgItem(IDC_NAME_TYPE_COMBO)),
  592. IDS_NAME_TYPES,
  593. 256,
  594. NAME_TYPE_COUNT));
  595. //
  596. // Load the Protocol combo box
  597. //
  598. VERIFY(LoadComboBoxFromTable(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_PROTOCOL_COMBO)),
  599. g_Protocols));
  600. SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_SETCURSEL, 0, 0);
  601. //
  602. // Load the Algorithms combo box
  603. //
  604. VERIFY(LoadComboBoxFromTable(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)),
  605. g_Algorithms));
  606. SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_SETCURSEL, 0, 0);
  607. //
  608. // Subclass the check list box for the signatory field
  609. //
  610. VERIFY(m_SignatoryCheckListBox.SubclassDlgItem(IDC_LOGGING_OPTIONS_LIST, this));
  611. m_SignatoryCheckListBox.SetCheckStyle(BS_AUTOCHECKBOX);
  612. CString szTemp;
  613. VERIFY(szTemp.LoadString(IDS_ZONE));
  614. m_SignatoryCheckListBox.AddString(szTemp);
  615. VERIFY(szTemp.LoadString(IDS_STRONG));
  616. m_SignatoryCheckListBox.AddString(szTemp);
  617. VERIFY(szTemp.LoadString(IDS_UNIQUE));
  618. m_SignatoryCheckListBox.AddString(szTemp);
  619. SendDlgItemMessage(IDC_BITFIELD_EDIT, EM_SETLIMITTEXT, (WPARAM)sizeof(WORD) * 8, 0);
  620. //
  621. // NTRAID#NTBUG9-505387-2002/01/22-JeffJon
  622. // Set limit on the key so that we don't AV
  623. //
  624. SendDlgItemMessage(IDC_SIG_EDIT, EM_SETLIMITTEXT, (WPARAM)1024, 0);
  625. CEdit* pBitEdit = (CEdit*)GetDlgItem(IDC_BITFIELD_EDIT);
  626. if (pBitEdit != NULL)
  627. {
  628. pBitEdit->SetReadOnly(TRUE);
  629. }
  630. SetDirty(FALSE);
  631. return TRUE;
  632. }
  633. void CDNS_KEY_RecordPropertyPage::OnEditChange()
  634. {
  635. SetDirty(TRUE);
  636. }
  637. void CDNS_KEY_RecordPropertyPage::OnKeyTypeChange()
  638. {
  639. LRESULT lSel = SendDlgItemMessage(IDC_KEY_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  640. if (lSel != CB_ERR)
  641. {
  642. //
  643. // Clear key type bits
  644. //
  645. m_wFlags &= ~(0xc000);
  646. if (lSel == 2)
  647. {
  648. m_wFlags |= 0x0000;
  649. }
  650. else if (lSel == 1)
  651. {
  652. m_wFlags |= 0x4000;
  653. }
  654. else if (lSel == 0)
  655. {
  656. m_wFlags |= 0x8000;
  657. }
  658. else // lSel == 3
  659. {
  660. m_wFlags |= 0xc000;
  661. }
  662. }
  663. ShowBitField(m_wFlags);
  664. SetDirty(TRUE);
  665. }
  666. void CDNS_KEY_RecordPropertyPage::OnNameTypeChange()
  667. {
  668. LRESULT lSel = SendDlgItemMessage(IDC_NAME_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  669. if (lSel != CB_ERR)
  670. {
  671. //
  672. // Clear key type bits
  673. //
  674. m_wFlags &= ~(0x00000300);
  675. if (lSel == 0)
  676. {
  677. m_wFlags |= 0x00000000;
  678. }
  679. else if (lSel == 1)
  680. {
  681. m_wFlags |= 0x00000100;
  682. }
  683. else if (lSel == 2)
  684. {
  685. m_wFlags |= 0x00000200;
  686. }
  687. else // shouldn't have more than 3
  688. {
  689. ASSERT(FALSE);
  690. }
  691. }
  692. ShowBitField(m_wFlags);
  693. SetDirty(TRUE);
  694. }
  695. void CDNS_KEY_RecordPropertyPage::OnSignatoryChange()
  696. {
  697. int iZoneCheck = m_SignatoryCheckListBox.GetCheck(0);
  698. int iStrongCheck = m_SignatoryCheckListBox.GetCheck(1);
  699. int iUniqueCheck = m_SignatoryCheckListBox.GetCheck(2);
  700. if (iZoneCheck == 1)
  701. {
  702. m_wFlags |= 0x1;
  703. }
  704. else
  705. {
  706. m_wFlags &= ~(0x1);
  707. }
  708. if (iStrongCheck == 1)
  709. {
  710. m_wFlags |= 0x2;
  711. }
  712. else
  713. {
  714. m_wFlags &= ~(0x2);
  715. }
  716. if (iUniqueCheck == 1)
  717. {
  718. m_wFlags |= 0x4;
  719. }
  720. else
  721. {
  722. m_wFlags &= ~(0x4);
  723. }
  724. ShowBitField(m_wFlags);
  725. SetDirty(TRUE);
  726. }
  727. void CDNS_KEY_RecordPropertyPage::OnProtocolChange()
  728. {
  729. LRESULT lProtocolSel = SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_GETCURSEL, 0, 0);
  730. if (lProtocolSel != CB_ERR)
  731. {
  732. m_chProtocol = static_cast<BYTE>(SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_GETITEMDATA, (WPARAM)lProtocolSel, 0));
  733. }
  734. SetDirty(TRUE);
  735. }
  736. void CDNS_KEY_RecordPropertyPage::OnAlgorithmChange()
  737. {
  738. LRESULT lAlgorithmSel = SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETCURSEL, 0, 0);
  739. if (lAlgorithmSel != CB_ERR)
  740. {
  741. m_chAlgorithm = static_cast<BYTE>(SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETITEMDATA, (WPARAM)lAlgorithmSel, 0));
  742. }
  743. SetDirty(TRUE);
  744. }
  745. void CDNS_KEY_RecordPropertyPage::SetUIData()
  746. {
  747. CDNSRecordStandardPropertyPage::SetUIData();
  748. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  749. CDNS_KEY_Record* pRecord = (CDNS_KEY_Record*)pHolder->GetTempDNSRecord();
  750. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_PROTOCOL_COMBO)), pRecord->m_chProtocol);
  751. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)), pRecord->m_chAlgorithm);
  752. m_chProtocol = pRecord->m_chProtocol;
  753. m_chAlgorithm = pRecord->m_chAlgorithm;
  754. m_wFlags = pRecord->m_wFlags;
  755. //
  756. // Fill in the flags fields
  757. //
  758. ShowBitField(pRecord->m_wFlags);
  759. ShowKeyType(pRecord->m_wFlags);
  760. ShowNameType(pRecord->m_wFlags);
  761. ShowSignatory(pRecord->m_wFlags);
  762. ShowKeyValue(pRecord->m_Key.GetData(), pRecord->m_Key.GetSize());
  763. }
  764. void CDNS_KEY_RecordPropertyPage::ShowKeyValue(PBYTE pKey, DWORD dwKeySize)
  765. {
  766. SetDlgItemText(IDC_KEY_EDIT, Base64BLOBToString(pKey, dwKeySize));
  767. }
  768. void CDNS_KEY_RecordPropertyPage::ShowBitField(WORD wFlags)
  769. {
  770. CString szTempField;
  771. WORD wTemp = wFlags;
  772. for (size_t idx = 0; idx < sizeof(WORD) * 8; idx++)
  773. {
  774. if ((wTemp & (0x1 << idx)) == 0)
  775. {
  776. szTempField = L'0' + szTempField;
  777. }
  778. else
  779. {
  780. szTempField = L'1' + szTempField;
  781. }
  782. }
  783. SetDlgItemText(IDC_BITFIELD_EDIT, szTempField);
  784. }
  785. //
  786. // REVIEW_JEFFJON : remove magic numbers
  787. //
  788. void CDNS_KEY_RecordPropertyPage::ShowKeyType(WORD wFlags)
  789. {
  790. UINT nIdx = 0;
  791. //
  792. // Note: after the shift we are only concerned with the last two bits
  793. //
  794. WORD wKeyType = static_cast<WORD>(wFlags >> 14);
  795. if ((wKeyType & 0x3) == 0)
  796. {
  797. nIdx = 2;
  798. }
  799. else if ((wKeyType & 0x3) == 1)
  800. {
  801. nIdx = 1;
  802. }
  803. else if ((wKeyType & 0x3) == 2)
  804. {
  805. nIdx = 0;
  806. }
  807. else
  808. {
  809. nIdx = 3;
  810. }
  811. SendDlgItemMessage(IDC_KEY_TYPE_COMBO, CB_SETCURSEL, (WPARAM)nIdx, 0);
  812. }
  813. void CDNS_KEY_RecordPropertyPage::ShowNameType(WORD wFlags)
  814. {
  815. UINT nIdx = (UINT)-1;
  816. //
  817. // Note: after the shift we are only concerned with the last two bits
  818. //
  819. WORD wKeyType = static_cast<WORD>(wFlags >> 8);
  820. if ((wKeyType & 0x3) == 0)
  821. {
  822. nIdx = 0;
  823. }
  824. else if ((wKeyType & 0x3) == 1)
  825. {
  826. nIdx = 1;
  827. }
  828. else if ((wKeyType & 0x3) == 2)
  829. {
  830. nIdx = 2;
  831. }
  832. else
  833. {
  834. //
  835. // 11 is reserved and should not occur in this dialog
  836. //
  837. ASSERT(FALSE);
  838. }
  839. if (nIdx != (UINT)-1)
  840. {
  841. SendDlgItemMessage(IDC_NAME_TYPE_COMBO, CB_SETCURSEL, (WPARAM)nIdx, 0);
  842. }
  843. }
  844. void CDNS_KEY_RecordPropertyPage::ShowSignatory(WORD wFlags)
  845. {
  846. //
  847. // Zone update?
  848. //
  849. if (wFlags & 0x1)
  850. {
  851. m_SignatoryCheckListBox.SetCheck(0, 1);
  852. }
  853. else
  854. {
  855. m_SignatoryCheckListBox.SetCheck(0, 0);
  856. }
  857. //
  858. // Strong update?
  859. //
  860. if (wFlags & 0x2)
  861. {
  862. m_SignatoryCheckListBox.SetCheck(1, 1);
  863. }
  864. else
  865. {
  866. m_SignatoryCheckListBox.SetCheck(1, 0);
  867. }
  868. //
  869. // Unique update?
  870. //
  871. if (wFlags & 0x4)
  872. {
  873. m_SignatoryCheckListBox.SetCheck(2, 1);
  874. }
  875. else
  876. {
  877. m_SignatoryCheckListBox.SetCheck(2, 0);
  878. }
  879. }
  880. DNS_STATUS CDNS_KEY_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  881. {
  882. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  883. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  884. CDNS_KEY_Record* pRecord = (CDNS_KEY_Record*)pHolder->GetTempDNSRecord();
  885. pRecord->m_chAlgorithm = m_chAlgorithm;
  886. pRecord->m_chProtocol = m_chProtocol;
  887. pRecord->m_wFlags = m_wFlags;
  888. //
  889. // Get the key
  890. //
  891. DWORD dwLength;
  892. CString szValue;
  893. GetDlgItemText(IDC_KEY_EDIT, szValue);
  894. //
  895. // Switch the value from base 64 to byte array
  896. //
  897. //
  898. // The conversion function is expecting characters in multiples of 4. So if we have
  899. // a string that does not have a multiple of 4 number of characters, pad the string
  900. // with the pad character, except if the string requires more than 2 pad characters.
  901. // RFC 2535 Appendix A doesn't address the issue where string length % 4 == 3. In this
  902. // case we will show an error.
  903. //
  904. int iLengthMod4 = szValue.GetLength() % 4;
  905. int iPads = 4 - iLengthMod4;
  906. if (iLengthMod4 == 1)
  907. {
  908. if (!bSilent)
  909. {
  910. dwErr = ERROR_INVALID_PARAMETER;
  911. ::DNSErrorDialog(dwErr, IDS_ERRMSG_BASE64);
  912. return dwErr;
  913. }
  914. }
  915. else if (iPads != 0 && iPads != 4)
  916. {
  917. for (int i = 0; i < iPads; i++)
  918. {
  919. szValue += SECURITY_PAD_CHAR;
  920. }
  921. }
  922. ASSERT(szValue.GetLength() % 4 == 0);
  923. // The largest string will have 4 characters for every 3 bytes in the string
  924. DWORD maxDataLength = (szValue.GetLength() / 4) * 3;
  925. BYTE* pByte = new BYTE[maxDataLength];
  926. if (pByte)
  927. {
  928. ZeroMemory(pByte, sizeof(BYTE) * maxDataLength);
  929. dwErr = Dns_SecurityBase64StringToKey(pByte, &dwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  930. if (dwErr != 0)
  931. {
  932. if (!bSilent)
  933. {
  934. DNSMessageBox(IDS_ERRMSG_BASE64);
  935. }
  936. }
  937. else
  938. {
  939. pRecord->m_Key.Set(pByte, dwLength);
  940. }
  941. // The CByteBlob::Set does a copy so we are OK to delete here
  942. delete[] pByte;
  943. }
  944. return dwErr;
  945. }
  946. ////////////////////////////////////////////////////////////////////////////
  947. // CDNS_NXT_RecordPropertyPage
  948. BEGIN_MESSAGE_MAP(CDNS_NXT_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  949. ON_EN_CHANGE(IDC_NEXT_DOMAIN_EDIT, OnNextDomainEdit)
  950. ON_CLBN_CHKCHANGE(IDC_LOGGING_OPTIONS_LIST, OnTypeCoveredChange)
  951. END_MESSAGE_MAP()
  952. CDNS_NXT_RecordPropertyPage::CDNS_NXT_RecordPropertyPage()
  953. : CDNSRecordStandardPropertyPage(IDD_RR_NXT)
  954. {
  955. }
  956. BOOL CDNS_NXT_RecordPropertyPage::OnInitDialog()
  957. {
  958. CDNSRecordStandardPropertyPage::OnInitDialog();
  959. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  960. VERIFY(m_TypeCheckListBox.SubclassDlgItem(IDC_LOGGING_OPTIONS_LIST, this));
  961. m_TypeCheckListBox.SetCheckStyle(BS_AUTOCHECKBOX);
  962. CDNSRootData* pRootData = dynamic_cast<CDNSRootData*>(pHolder->GetDomainNode()->GetRootContainer());
  963. if (pRootData)
  964. {
  965. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable();
  966. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  967. {
  968. // some record types cannot be created with this wizard
  969. if (pTable->dwFlags & DNS_RECORD_INFO_FLAG_SHOW_NXT)
  970. {
  971. int idx = m_TypeCheckListBox.AddString(pTable->lpszFullName);
  972. if (idx != LB_ERR)
  973. {
  974. m_TypeCheckListBox.SetItemData(idx, pTable->wType);
  975. if (pTable->wType == DNS_TYPE_NXT)
  976. {
  977. m_TypeCheckListBox.Enable(idx, FALSE);
  978. m_TypeCheckListBox.SetCheck(idx, TRUE);
  979. }
  980. }
  981. }
  982. pTable++;
  983. }
  984. }
  985. return TRUE;
  986. }
  987. void CDNS_NXT_RecordPropertyPage::OnNextDomainEdit()
  988. {
  989. SetDirty(TRUE);
  990. }
  991. void CDNS_NXT_RecordPropertyPage::OnTypeCoveredChange()
  992. {
  993. SetDirty(TRUE);
  994. }
  995. void CDNS_NXT_RecordPropertyPage::SetUIData()
  996. {
  997. CDNSRecordStandardPropertyPage::SetUIData();
  998. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  999. CDNS_NXT_Record* pRecord = (CDNS_NXT_Record*)pHolder->GetTempDNSRecord();
  1000. SendDlgItemMessage(IDC_NEXT_DOMAIN_EDIT, EM_SETLIMITTEXT, MAX_DNS_NAME_LEN, 0);
  1001. SetDlgItemText(IDC_NEXT_DOMAIN_EDIT, pRecord->m_szNextDomain);
  1002. for (DWORD dwIdx = 0; dwIdx < pRecord->m_wNumTypesCovered; dwIdx++)
  1003. {
  1004. SetTypeCheckForDNSType(pRecord->m_pwTypesCovered[dwIdx]);
  1005. }
  1006. }
  1007. void CDNS_NXT_RecordPropertyPage::SetTypeCheckForDNSType(WORD wType)
  1008. {
  1009. int iCount = m_TypeCheckListBox.GetCount();
  1010. for (int idx = 0; idx < iCount; idx++)
  1011. {
  1012. DWORD_PTR dwData = m_TypeCheckListBox.GetItemData(idx);
  1013. if (dwData != LB_ERR)
  1014. {
  1015. if (dwData == wType)
  1016. {
  1017. m_TypeCheckListBox.SetCheck(idx, TRUE);
  1018. }
  1019. }
  1020. }
  1021. }
  1022. DNS_STATUS CDNS_NXT_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  1023. {
  1024. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  1025. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  1026. CDNS_NXT_Record* pRecord = (CDNS_NXT_Record*)pHolder->GetTempDNSRecord();
  1027. //
  1028. // Get the next domain name
  1029. //
  1030. GetDlgItemText(IDC_NEXT_DOMAIN_EDIT, pRecord->m_szNextDomain);
  1031. //
  1032. // Get the types covered
  1033. //
  1034. int iCount = m_TypeCheckListBox.GetCount();
  1035. int iNumChecked = 0;
  1036. WORD* pTempTypesCovered = new WORD[iCount];
  1037. if (pTempTypesCovered != NULL)
  1038. {
  1039. memset(pTempTypesCovered, 0, iCount * sizeof(WORD));
  1040. for (int idx = 0; idx < iCount; idx++)
  1041. {
  1042. int iChecked = m_TypeCheckListBox.GetCheck(idx);
  1043. if (iChecked == 1)
  1044. {
  1045. pTempTypesCovered[idx] = static_cast<WORD>(m_TypeCheckListBox.GetItemData(idx));
  1046. iNumChecked++;
  1047. }
  1048. }
  1049. //
  1050. // Copy the covered types to the record
  1051. //
  1052. pRecord->m_wNumTypesCovered = static_cast<WORD>(iNumChecked);
  1053. if (pRecord->m_pwTypesCovered != NULL)
  1054. {
  1055. delete[] pRecord->m_pwTypesCovered;
  1056. pRecord->m_pwTypesCovered = NULL;
  1057. }
  1058. pRecord->m_pwTypesCovered = new WORD[pRecord->m_wNumTypesCovered];
  1059. if (pRecord->m_pwTypesCovered != NULL)
  1060. {
  1061. int iTypeCoveredIdx = 0;
  1062. for (int iTempCount = 0; iTempCount < iCount; iTempCount++)
  1063. {
  1064. if (pTempTypesCovered[iTempCount] != 0)
  1065. {
  1066. pRecord->m_pwTypesCovered[iTypeCoveredIdx] = pTempTypesCovered[iTempCount];
  1067. iTypeCoveredIdx++;
  1068. }
  1069. }
  1070. }
  1071. }
  1072. return dwErr;
  1073. }