Source code of Windows XP (NT5)
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.

1232 lines
31 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 = (pRootData->IsAdvancedView() ? pTable->lpszShortName : 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. // Limit the labels tag to 3 characters (1-127)
  295. //
  296. SendDlgItemMessage(IDC_LABELS_EDIT, EM_SETLIMITTEXT, (WPARAM)3, 0);
  297. return FALSE;
  298. }
  299. void CDNS_SIG_RecordPropertyPage::ConvertUIKeyStringToByteArray(BYTE* pByte, DWORD* pdwLength)
  300. {
  301. CString szValue;
  302. GetDlgItemText(IDC_SIG_EDIT, szValue);
  303. //
  304. // Switch the value from base 64 to hex
  305. //
  306. DNS_STATUS err = Dns_SecurityBase64StringToKey(pByte, pdwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  307. ASSERT(err == 0);
  308. }
  309. void CDNS_SIG_RecordPropertyPage::OnDateTimeChange(NMHDR*, LRESULT*)
  310. {
  311. SetDirty(TRUE);
  312. }
  313. void CDNS_SIG_RecordPropertyPage::OnSigEditChange()
  314. {
  315. SetDirty(TRUE);
  316. }
  317. void CDNS_SIG_RecordPropertyPage::OnComboChange()
  318. {
  319. SetDirty(TRUE);
  320. }
  321. void CDNS_SIG_RecordPropertyPage::ShowSigValue(PBYTE pKey, DWORD dwKeySize)
  322. {
  323. //
  324. // REVIEW_JEFFJON : Find a way to tell apriori how big the string will be
  325. //
  326. CString szShowBuf;
  327. WCHAR szBuffer[4*MAX_PATH];
  328. ZeroMemory(szBuffer, sizeof(WCHAR) * 4 * MAX_PATH);
  329. PWSTR pszEnd = Dns_SecurityKeyToBase64String(pKey,
  330. dwKeySize,
  331. szBuffer);
  332. if (pszEnd != NULL)
  333. {
  334. //
  335. // NULL terminate the string
  336. //
  337. *pszEnd = L'\0';
  338. }
  339. szShowBuf = szBuffer;
  340. SetDlgItemText(IDC_SIG_EDIT, szShowBuf);
  341. }
  342. void CDNS_SIG_RecordPropertyPage::SetUIData()
  343. {
  344. CDNSRecordStandardPropertyPage::SetUIData();
  345. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  346. CDNS_SIG_Record* pRecord = (CDNS_SIG_Record*)pHolder->GetTempDNSRecord();
  347. //
  348. // Set the type covered
  349. //
  350. m_wTypeCovered = pRecord->m_wTypeCovered;
  351. SelectTypeCoveredByType(pRecord->m_wTypeCovered);
  352. //
  353. // Set the algorithm
  354. //
  355. m_chAlgorithm = pRecord->m_chAlgorithm;
  356. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)), pRecord->m_chAlgorithm);
  357. //
  358. // Set the label count
  359. //
  360. SetDlgItemInt(IDC_LABELS_EDIT, pRecord->m_chLabels);
  361. //
  362. // Set the signer's name
  363. //
  364. m_szSignerName = pRecord->m_szSignerName;
  365. SetDlgItemText(IDC_SIGNERS_NAME_EDIT, m_szSignerName);
  366. //
  367. // Set the signature value
  368. //
  369. ShowSigValue(pRecord->m_Signature.GetData(), pRecord->m_Signature.GetSize());
  370. //
  371. // Set the original TTL
  372. //
  373. m_dwOriginalTtl = pRecord->m_dwOriginalTtl;
  374. GetOrigTTL()->SetTTL(m_dwOriginalTtl);
  375. //
  376. // Get the local time zone information
  377. //
  378. TIME_ZONE_INFORMATION tzInfo;
  379. memset(&tzInfo, 0, sizeof(TIME_ZONE_INFORMATION));
  380. ::GetTimeZoneInformation(&tzInfo);
  381. //
  382. // Set the expiration TTL
  383. //
  384. m_dwExpiration = pRecord->m_dwExpiration;
  385. SYSTEMTIME stExpTime;
  386. ::ConvertTTLToSystemTime(&tzInfo, m_dwExpiration, &stExpTime);
  387. SendDlgItemMessage(IDC_EXP_DATE, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stExpTime);
  388. SendDlgItemMessage(IDC_EXP_TIME, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stExpTime);
  389. //
  390. // Set the inception TTL
  391. //
  392. m_dwTimeSigned = pRecord->m_dwTimeSigned;
  393. SYSTEMTIME stIncTime;
  394. ::ConvertTTLToSystemTime(&tzInfo, m_dwTimeSigned, &stIncTime);
  395. SendDlgItemMessage(IDC_INC_DATE, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stIncTime);
  396. SendDlgItemMessage(IDC_INC_TIME, DTM_SETSYSTEMTIME, (WPARAM)GDT_VALID, (LPARAM)&stIncTime);
  397. //
  398. // Set key tag edit
  399. //
  400. m_wKeyTag = pRecord->m_wKeyFootprint;
  401. SetDlgItemInt(IDC_KEY_TAG_EDIT, m_wKeyTag, FALSE);
  402. }
  403. void CDNS_SIG_RecordPropertyPage::SelectTypeCoveredByType(WORD wType)
  404. {
  405. LRESULT lCount = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETCOUNT, 0, 0);
  406. if (lCount != CB_ERR)
  407. {
  408. for (LRESULT lIdx = 0; lIdx < lCount; lIdx++)
  409. {
  410. LRESULT lData = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETITEMDATA, (WPARAM)lIdx, 0);
  411. if (lData != CB_ERR)
  412. {
  413. if (wType == static_cast<WORD>(lData))
  414. {
  415. SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_SETCURSEL, (WPARAM)lIdx, 0);
  416. break;
  417. }
  418. }
  419. }
  420. }
  421. }
  422. DNS_STATUS CDNS_SIG_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  423. {
  424. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  425. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  426. CDNS_SIG_Record* pRecord = (CDNS_SIG_Record*)pHolder->GetTempDNSRecord();
  427. //
  428. // Get the type covered
  429. //
  430. LRESULT lTypeIdx = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  431. if (lTypeIdx != CB_ERR)
  432. {
  433. LRESULT lTypeData = SendDlgItemMessage(IDC_RECORD_TYPE_COMBO, CB_GETITEMDATA, (WPARAM)lTypeIdx, 0);
  434. if (lTypeData != CB_ERR)
  435. {
  436. pRecord->m_wTypeCovered = static_cast<WORD>(lTypeData);
  437. }
  438. }
  439. //
  440. // Get the algorithm
  441. //
  442. LRESULT lAlgorithmIdx = SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETCURSEL, 0, 0);
  443. if (lAlgorithmIdx != CB_ERR)
  444. {
  445. pRecord->m_chAlgorithm = static_cast<BYTE>(SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETITEMDATA, (WPARAM)lAlgorithmIdx, 0));
  446. }
  447. //
  448. // Get the labels count
  449. //
  450. BOOL bLabelSuccess = FALSE;
  451. int iLabelVal = GetDlgItemInt(IDC_LABELS_EDIT, &bLabelSuccess, FALSE);
  452. if (bLabelSuccess)
  453. {
  454. if (iLabelVal > 127)
  455. {
  456. iLabelVal = 127;
  457. SetDlgItemInt(IDC_KEY_TAG_EDIT, iLabelVal, FALSE);
  458. if (!bSilent)
  459. {
  460. DNSMessageBox(IDS_MSG_SIG_LABEL_RANGE);
  461. }
  462. }
  463. pRecord->m_chLabels = static_cast<BYTE>(iLabelVal);
  464. }
  465. //
  466. // Get the original ttl
  467. //
  468. GetOrigTTL()->GetTTL(&pRecord->m_dwOriginalTtl);
  469. //
  470. // Get the expiration date
  471. //
  472. SYSTEMTIME stExpDate;
  473. memset(&stExpDate, 0, sizeof(SYSTEMTIME));
  474. LRESULT lExpDateRes = SendDlgItemMessage(IDC_EXP_DATE, DTM_GETSYSTEMTIME, 0, (LPARAM)&stExpDate);
  475. if (lExpDateRes == GDT_VALID)
  476. {
  477. SYSTEMTIME stExpTime;
  478. memset(&stExpTime, 0, sizeof(SYSTEMTIME));
  479. LRESULT lExpTimeRes = SendDlgItemMessage(IDC_EXP_TIME, DTM_GETSYSTEMTIME, 0, (LPARAM)&stExpTime);
  480. if (lExpTimeRes == GDT_VALID)
  481. {
  482. stExpDate.wHour = stExpTime.wHour;
  483. stExpDate.wMinute = stExpTime.wMinute;
  484. stExpDate.wSecond = stExpTime.wSecond;
  485. stExpDate.wMilliseconds = stExpTime.wMilliseconds;
  486. pRecord->m_dwExpiration = ConvertSystemTimeToTTL(&stExpDate);
  487. }
  488. }
  489. //
  490. // Get the inception date
  491. //
  492. SYSTEMTIME stIncDate;
  493. memset(&stIncDate, 0, sizeof(SYSTEMTIME));
  494. LRESULT lIncDateRes = SendDlgItemMessage(IDC_INC_DATE, DTM_GETSYSTEMTIME, 0, (LPARAM)&stIncDate);
  495. if (lIncDateRes == GDT_VALID)
  496. {
  497. SYSTEMTIME stIncTime;
  498. memset(&stIncTime, 0, sizeof(SYSTEMTIME));
  499. LRESULT lIncTimeRes = SendDlgItemMessage(IDC_INC_TIME, DTM_GETSYSTEMTIME, 0, (LPARAM)&stIncTime);
  500. if (lIncTimeRes == GDT_VALID)
  501. {
  502. stIncDate.wHour = stIncTime.wHour;
  503. stIncDate.wMinute = stIncTime.wMinute;
  504. stIncDate.wSecond = stIncTime.wSecond;
  505. stIncDate.wMilliseconds = stIncTime.wMilliseconds;
  506. pRecord->m_dwTimeSigned = ConvertSystemTimeToTTL(&stIncDate);
  507. }
  508. }
  509. //
  510. // Get the key tag
  511. //
  512. BOOL bSuccess = FALSE;
  513. int iVal = GetDlgItemInt(IDC_KEY_TAG_EDIT, &bSuccess, FALSE /*unsigned*/);
  514. if (bSuccess)
  515. {
  516. pRecord->m_wKeyFootprint = static_cast<WORD>(iVal);
  517. }
  518. //
  519. // Get the signer's name
  520. //
  521. GetDlgItemText(IDC_SIGNERS_NAME_EDIT, pRecord->m_szSignerName);
  522. //
  523. // Get the key
  524. //
  525. BYTE pByte[4*MAX_PATH];
  526. ZeroMemory(pByte, sizeof(BYTE) * 4 * MAX_PATH);
  527. DWORD dwLength;
  528. CString szValue;
  529. GetDlgItemText(IDC_SIG_EDIT, szValue);
  530. //
  531. // Switch the value from base 64 to byte array
  532. //
  533. //
  534. // The conversion function is expecting characters in multiples of 4. So if we have
  535. // a string that does not have a multiple of 4 number of characters, pad the string
  536. // with the pad character
  537. //
  538. int iLengthMod4 = 4 - (szValue.GetLength() % 4);
  539. if (iLengthMod4 != 0 && iLengthMod4 != 4)
  540. {
  541. for (int i = 0; i < iLengthMod4; i++)
  542. {
  543. szValue += SECURITY_PAD_CHAR;
  544. }
  545. }
  546. DNS_STATUS err = Dns_SecurityBase64StringToKey(pByte, &dwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  547. if (err != ERROR_SUCCESS)
  548. {
  549. if (!bSilent)
  550. {
  551. ::DNSErrorDialog(err, IDS_ERRMSG_BASE64);
  552. }
  553. return err;
  554. }
  555. pRecord->m_Signature.Set(pByte, dwLength);
  556. return dwErr;
  557. }
  558. ////////////////////////////////////////////////////////////////////////////
  559. // CDNS_KEY_RecordPropertyPage
  560. BEGIN_MESSAGE_MAP(CDNS_KEY_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  561. ON_EN_CHANGE(IDC_KEY_EDIT, OnEditChange)
  562. ON_CBN_SELCHANGE(IDC_KEY_TYPE_COMBO, OnKeyTypeChange)
  563. ON_CBN_SELCHANGE(IDC_NAME_TYPE_COMBO, OnNameTypeChange)
  564. ON_CBN_SELCHANGE(IDC_PROTOCOL_COMBO, OnProtocolChange)
  565. ON_CBN_SELCHANGE(IDC_ALGORITHM_COMBO, OnAlgorithmChange)
  566. ON_CLBN_CHKCHANGE(IDC_LOGGING_OPTIONS_LIST, OnSignatoryChange)
  567. END_MESSAGE_MAP()
  568. CDNS_KEY_RecordPropertyPage::CDNS_KEY_RecordPropertyPage()
  569. : CDNSRecordStandardPropertyPage(IDD_RR_KEY)
  570. {
  571. }
  572. BOOL CDNS_KEY_RecordPropertyPage::OnInitDialog()
  573. {
  574. CDNSRecordStandardPropertyPage::OnInitDialog();
  575. VERIFY(LoadStringsToComboBox(_Module.GetModuleInstance(),
  576. reinterpret_cast<CComboBox*>(GetDlgItem(IDC_KEY_TYPE_COMBO)),
  577. IDS_KEY_TYPES,
  578. 256,
  579. KEY_TYPE_COUNT));
  580. VERIFY(LoadStringsToComboBox(_Module.GetModuleInstance(),
  581. reinterpret_cast<CComboBox*>(GetDlgItem(IDC_NAME_TYPE_COMBO)),
  582. IDS_NAME_TYPES,
  583. 256,
  584. NAME_TYPE_COUNT));
  585. //
  586. // Load the Protocol combo box
  587. //
  588. VERIFY(LoadComboBoxFromTable(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_PROTOCOL_COMBO)),
  589. g_Protocols));
  590. SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_SETCURSEL, 0, 0);
  591. //
  592. // Load the Algorithms combo box
  593. //
  594. VERIFY(LoadComboBoxFromTable(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)),
  595. g_Algorithms));
  596. SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_SETCURSEL, 0, 0);
  597. //
  598. // Subclass the check list box for the signatory field
  599. //
  600. VERIFY(m_SignatoryCheckListBox.SubclassDlgItem(IDC_LOGGING_OPTIONS_LIST, this));
  601. m_SignatoryCheckListBox.SetCheckStyle(BS_AUTOCHECKBOX);
  602. CString szTemp;
  603. VERIFY(szTemp.LoadString(IDS_ZONE));
  604. m_SignatoryCheckListBox.AddString(szTemp);
  605. VERIFY(szTemp.LoadString(IDS_STRONG));
  606. m_SignatoryCheckListBox.AddString(szTemp);
  607. VERIFY(szTemp.LoadString(IDS_UNIQUE));
  608. m_SignatoryCheckListBox.AddString(szTemp);
  609. SendDlgItemMessage(IDC_BITFIELD_EDIT, EM_SETLIMITTEXT, (WPARAM)sizeof(WORD) * 8, 0);
  610. CEdit* pBitEdit = (CEdit*)GetDlgItem(IDC_BITFIELD_EDIT);
  611. if (pBitEdit != NULL)
  612. {
  613. pBitEdit->SetReadOnly(TRUE);
  614. }
  615. SetDirty(FALSE);
  616. return TRUE;
  617. }
  618. void CDNS_KEY_RecordPropertyPage::OnEditChange()
  619. {
  620. SetDirty(TRUE);
  621. }
  622. void CDNS_KEY_RecordPropertyPage::OnKeyTypeChange()
  623. {
  624. LRESULT lSel = SendDlgItemMessage(IDC_KEY_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  625. if (lSel != CB_ERR)
  626. {
  627. //
  628. // Clear key type bits
  629. //
  630. m_wFlags &= ~(0xc000);
  631. if (lSel == 2)
  632. {
  633. m_wFlags |= 0x0000;
  634. }
  635. else if (lSel == 1)
  636. {
  637. m_wFlags |= 0x4000;
  638. }
  639. else if (lSel == 0)
  640. {
  641. m_wFlags |= 0x8000;
  642. }
  643. else // lSel == 3
  644. {
  645. m_wFlags |= 0xc000;
  646. }
  647. }
  648. ShowBitField(m_wFlags);
  649. SetDirty(TRUE);
  650. }
  651. void CDNS_KEY_RecordPropertyPage::OnNameTypeChange()
  652. {
  653. LRESULT lSel = SendDlgItemMessage(IDC_NAME_TYPE_COMBO, CB_GETCURSEL, 0, 0);
  654. if (lSel != CB_ERR)
  655. {
  656. //
  657. // Clear key type bits
  658. //
  659. m_wFlags &= ~(0x00000300);
  660. if (lSel == 0)
  661. {
  662. m_wFlags |= 0x00000000;
  663. }
  664. else if (lSel == 1)
  665. {
  666. m_wFlags |= 0x00000100;
  667. }
  668. else if (lSel == 2)
  669. {
  670. m_wFlags |= 0x00000200;
  671. }
  672. else // shouldn't have more than 3
  673. {
  674. ASSERT(FALSE);
  675. }
  676. }
  677. ShowBitField(m_wFlags);
  678. SetDirty(TRUE);
  679. }
  680. void CDNS_KEY_RecordPropertyPage::OnSignatoryChange()
  681. {
  682. int iZoneCheck = m_SignatoryCheckListBox.GetCheck(0);
  683. int iStrongCheck = m_SignatoryCheckListBox.GetCheck(1);
  684. int iUniqueCheck = m_SignatoryCheckListBox.GetCheck(2);
  685. if (iZoneCheck == 1)
  686. {
  687. m_wFlags |= 0x1;
  688. }
  689. else
  690. {
  691. m_wFlags &= ~(0x1);
  692. }
  693. if (iStrongCheck == 1)
  694. {
  695. m_wFlags |= 0x2;
  696. }
  697. else
  698. {
  699. m_wFlags &= ~(0x2);
  700. }
  701. if (iUniqueCheck == 1)
  702. {
  703. m_wFlags |= 0x4;
  704. }
  705. else
  706. {
  707. m_wFlags &= ~(0x4);
  708. }
  709. ShowBitField(m_wFlags);
  710. SetDirty(TRUE);
  711. }
  712. void CDNS_KEY_RecordPropertyPage::OnProtocolChange()
  713. {
  714. LRESULT lProtocolSel = SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_GETCURSEL, 0, 0);
  715. if (lProtocolSel != CB_ERR)
  716. {
  717. m_chProtocol = static_cast<BYTE>(SendDlgItemMessage(IDC_PROTOCOL_COMBO, CB_GETITEMDATA, (WPARAM)lProtocolSel, 0));
  718. }
  719. SetDirty(TRUE);
  720. }
  721. void CDNS_KEY_RecordPropertyPage::OnAlgorithmChange()
  722. {
  723. LRESULT lAlgorithmSel = SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETCURSEL, 0, 0);
  724. if (lAlgorithmSel != CB_ERR)
  725. {
  726. m_chAlgorithm = static_cast<BYTE>(SendDlgItemMessage(IDC_ALGORITHM_COMBO, CB_GETITEMDATA, (WPARAM)lAlgorithmSel, 0));
  727. }
  728. SetDirty(TRUE);
  729. }
  730. void CDNS_KEY_RecordPropertyPage::SetUIData()
  731. {
  732. CDNSRecordStandardPropertyPage::SetUIData();
  733. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  734. CDNS_KEY_Record* pRecord = (CDNS_KEY_Record*)pHolder->GetTempDNSRecord();
  735. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_PROTOCOL_COMBO)), pRecord->m_chProtocol);
  736. SetComboSelByData(reinterpret_cast<CComboBox*>(GetDlgItem(IDC_ALGORITHM_COMBO)), pRecord->m_chAlgorithm);
  737. m_chProtocol = pRecord->m_chProtocol;
  738. m_chAlgorithm = pRecord->m_chAlgorithm;
  739. m_wFlags = pRecord->m_wFlags;
  740. //
  741. // Fill in the flags fields
  742. //
  743. ShowBitField(pRecord->m_wFlags);
  744. ShowKeyType(pRecord->m_wFlags);
  745. ShowNameType(pRecord->m_wFlags);
  746. ShowSignatory(pRecord->m_wFlags);
  747. ShowKeyValue(pRecord->m_Key.GetData(), pRecord->m_Key.GetSize());
  748. }
  749. void CDNS_KEY_RecordPropertyPage::ShowKeyValue(PBYTE pKey, DWORD dwKeySize)
  750. {
  751. //
  752. // REVIEW_JEFFJON : Find a way to tell apriori how big the string will be
  753. //
  754. CString szShowBuf;
  755. WCHAR szBuffer[4*MAX_PATH];
  756. ZeroMemory(szBuffer, sizeof(WCHAR) * 4 * MAX_PATH);
  757. PWSTR pszEnd = Dns_SecurityKeyToBase64String(pKey,
  758. dwKeySize,
  759. szBuffer);
  760. if (pszEnd != NULL)
  761. {
  762. //
  763. // NULL terminate the string
  764. //
  765. *pszEnd = L'\0';
  766. }
  767. szShowBuf = szBuffer;
  768. SetDlgItemText(IDC_KEY_EDIT, szShowBuf);
  769. }
  770. void CDNS_KEY_RecordPropertyPage::ShowBitField(WORD wFlags)
  771. {
  772. CString szTempField;
  773. WORD wTemp = wFlags;
  774. for (size_t idx = 0; idx < sizeof(WORD) * 8; idx++)
  775. {
  776. if ((wTemp & (0x1 << idx)) == 0)
  777. {
  778. szTempField = L'0' + szTempField;
  779. }
  780. else
  781. {
  782. szTempField = L'1' + szTempField;
  783. }
  784. }
  785. SetDlgItemText(IDC_BITFIELD_EDIT, szTempField);
  786. }
  787. //
  788. // REVIEW_JEFFJON : remove magic numbers
  789. //
  790. void CDNS_KEY_RecordPropertyPage::ShowKeyType(WORD wFlags)
  791. {
  792. UINT nIdx = 0;
  793. //
  794. // Note: after the shift we are only concerned with the last two bits
  795. //
  796. WORD wKeyType = static_cast<WORD>(wFlags >> 14);
  797. if ((wKeyType & 0x3) == 0)
  798. {
  799. nIdx = 2;
  800. }
  801. else if ((wKeyType & 0x3) == 1)
  802. {
  803. nIdx = 1;
  804. }
  805. else if ((wKeyType & 0x3) == 2)
  806. {
  807. nIdx = 0;
  808. }
  809. else
  810. {
  811. nIdx = 3;
  812. }
  813. SendDlgItemMessage(IDC_KEY_TYPE_COMBO, CB_SETCURSEL, (WPARAM)nIdx, 0);
  814. }
  815. void CDNS_KEY_RecordPropertyPage::ShowNameType(WORD wFlags)
  816. {
  817. UINT nIdx = (UINT)-1;
  818. //
  819. // Note: after the shift we are only concerned with the last two bits
  820. //
  821. WORD wKeyType = static_cast<WORD>(wFlags >> 8);
  822. if ((wKeyType & 0x3) == 0)
  823. {
  824. nIdx = 0;
  825. }
  826. else if ((wKeyType & 0x3) == 1)
  827. {
  828. nIdx = 1;
  829. }
  830. else if ((wKeyType & 0x3) == 2)
  831. {
  832. nIdx = 2;
  833. }
  834. else
  835. {
  836. //
  837. // 11 is reserved and should not occur in this dialog
  838. //
  839. ASSERT(FALSE);
  840. }
  841. if (nIdx != (UINT)-1)
  842. {
  843. SendDlgItemMessage(IDC_NAME_TYPE_COMBO, CB_SETCURSEL, (WPARAM)nIdx, 0);
  844. }
  845. }
  846. void CDNS_KEY_RecordPropertyPage::ShowSignatory(WORD wFlags)
  847. {
  848. //
  849. // Zone update?
  850. //
  851. if (wFlags & 0x1)
  852. {
  853. m_SignatoryCheckListBox.SetCheck(0, 1);
  854. }
  855. else
  856. {
  857. m_SignatoryCheckListBox.SetCheck(0, 0);
  858. }
  859. //
  860. // Strong update?
  861. //
  862. if (wFlags & 0x2)
  863. {
  864. m_SignatoryCheckListBox.SetCheck(1, 1);
  865. }
  866. else
  867. {
  868. m_SignatoryCheckListBox.SetCheck(1, 0);
  869. }
  870. //
  871. // Unique update?
  872. //
  873. if (wFlags & 0x4)
  874. {
  875. m_SignatoryCheckListBox.SetCheck(2, 1);
  876. }
  877. else
  878. {
  879. m_SignatoryCheckListBox.SetCheck(2, 0);
  880. }
  881. }
  882. DNS_STATUS CDNS_KEY_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  883. {
  884. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  885. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  886. CDNS_KEY_Record* pRecord = (CDNS_KEY_Record*)pHolder->GetTempDNSRecord();
  887. pRecord->m_chAlgorithm = m_chAlgorithm;
  888. pRecord->m_chProtocol = m_chProtocol;
  889. pRecord->m_wFlags = m_wFlags;
  890. //
  891. // Get the key
  892. //
  893. BYTE pByte[4*MAX_PATH];
  894. ZeroMemory(pByte, sizeof(BYTE) * 4 * MAX_PATH);
  895. DWORD dwLength;
  896. CString szValue;
  897. GetDlgItemText(IDC_KEY_EDIT, szValue);
  898. //
  899. // Switch the value from base 64 to byte array
  900. //
  901. //
  902. // The conversion function is expecting characters in multiples of 4. So if we have
  903. // a string that does not have a multiple of 4 number of characters, pad the string
  904. // with the pad character
  905. //
  906. int iLengthMod4 = 4 - (szValue.GetLength() % 4);
  907. if (iLengthMod4 != 0 && iLengthMod4 != 4)
  908. {
  909. for (int i = 0; i < iLengthMod4; i++)
  910. {
  911. szValue += SECURITY_PAD_CHAR;
  912. }
  913. }
  914. DNS_STATUS err = Dns_SecurityBase64StringToKey(pByte, &dwLength, (PWSTR)(PCWSTR)szValue, szValue.GetLength());
  915. if (err != 0)
  916. {
  917. if (!bSilent)
  918. {
  919. DNSMessageBox(IDS_ERRMSG_BASE64);
  920. }
  921. return err;
  922. }
  923. pRecord->m_Key.Set(pByte, dwLength);
  924. return dwErr;
  925. }
  926. ////////////////////////////////////////////////////////////////////////////
  927. // CDNS_NXT_RecordPropertyPage
  928. BEGIN_MESSAGE_MAP(CDNS_NXT_RecordPropertyPage, CDNSRecordStandardPropertyPage)
  929. ON_EN_CHANGE(IDC_NEXT_DOMAIN_EDIT, OnNextDomainEdit)
  930. ON_CLBN_CHKCHANGE(IDC_LOGGING_OPTIONS_LIST, OnTypeCoveredChange)
  931. END_MESSAGE_MAP()
  932. CDNS_NXT_RecordPropertyPage::CDNS_NXT_RecordPropertyPage()
  933. : CDNSRecordStandardPropertyPage(IDD_RR_NXT)
  934. {
  935. }
  936. BOOL CDNS_NXT_RecordPropertyPage::OnInitDialog()
  937. {
  938. CDNSRecordStandardPropertyPage::OnInitDialog();
  939. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  940. VERIFY(m_TypeCheckListBox.SubclassDlgItem(IDC_LOGGING_OPTIONS_LIST, this));
  941. m_TypeCheckListBox.SetCheckStyle(BS_AUTOCHECKBOX);
  942. CDNSRootData* pRootData = dynamic_cast<CDNSRootData*>(pHolder->GetDomainNode()->GetRootContainer());
  943. if (pRootData)
  944. {
  945. DNS_RECORD_INFO_ENTRY* pTable = (DNS_RECORD_INFO_ENTRY*)CDNSRecordInfo::GetInfoEntryTable();
  946. while (pTable->nResourceID != DNS_RECORD_INFO_END_OF_TABLE)
  947. {
  948. // some record types cannot be created with this wizard
  949. if (pTable->dwFlags & DNS_RECORD_INFO_FLAG_SHOW_NXT)
  950. {
  951. int idx = m_TypeCheckListBox.AddString(pRootData->IsAdvancedView() ? pTable->lpszShortName : pTable->lpszFullName);
  952. if (idx != LB_ERR)
  953. {
  954. m_TypeCheckListBox.SetItemData(idx, pTable->wType);
  955. if (pTable->wType == DNS_TYPE_NXT)
  956. {
  957. m_TypeCheckListBox.Enable(idx, FALSE);
  958. m_TypeCheckListBox.SetCheck(idx, TRUE);
  959. }
  960. }
  961. }
  962. pTable++;
  963. }
  964. }
  965. return TRUE;
  966. }
  967. void CDNS_NXT_RecordPropertyPage::OnNextDomainEdit()
  968. {
  969. SetDirty(TRUE);
  970. }
  971. void CDNS_NXT_RecordPropertyPage::OnTypeCoveredChange()
  972. {
  973. SetDirty(TRUE);
  974. }
  975. void CDNS_NXT_RecordPropertyPage::SetUIData()
  976. {
  977. CDNSRecordStandardPropertyPage::SetUIData();
  978. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  979. CDNS_NXT_Record* pRecord = (CDNS_NXT_Record*)pHolder->GetTempDNSRecord();
  980. SendDlgItemMessage(IDC_NEXT_DOMAIN_EDIT, EM_SETLIMITTEXT, MAX_DNS_NAME_LEN, 0);
  981. SetDlgItemText(IDC_NEXT_DOMAIN_EDIT, pRecord->m_szNextDomain);
  982. for (DWORD dwIdx = 0; dwIdx < pRecord->m_wNumTypesCovered; dwIdx++)
  983. {
  984. SetTypeCheckForDNSType(pRecord->m_pwTypesCovered[dwIdx]);
  985. }
  986. }
  987. void CDNS_NXT_RecordPropertyPage::SetTypeCheckForDNSType(WORD wType)
  988. {
  989. int iCount = m_TypeCheckListBox.GetCount();
  990. for (int idx = 0; idx < iCount; idx++)
  991. {
  992. DWORD_PTR dwData = m_TypeCheckListBox.GetItemData(idx);
  993. if (dwData != LB_ERR)
  994. {
  995. if (dwData == wType)
  996. {
  997. m_TypeCheckListBox.SetCheck(idx, TRUE);
  998. }
  999. }
  1000. }
  1001. }
  1002. DNS_STATUS CDNS_NXT_RecordPropertyPage::GetUIDataEx(BOOL bSilent)
  1003. {
  1004. DNS_STATUS dwErr = CDNSRecordStandardPropertyPage::GetUIDataEx(bSilent);
  1005. CDNSRecordPropertyPageHolder* pHolder = GetDNSRecordHolder();
  1006. CDNS_NXT_Record* pRecord = (CDNS_NXT_Record*)pHolder->GetTempDNSRecord();
  1007. //
  1008. // Get the next domain name
  1009. //
  1010. GetDlgItemText(IDC_NEXT_DOMAIN_EDIT, pRecord->m_szNextDomain);
  1011. //
  1012. // Get the types covered
  1013. //
  1014. int iCount = m_TypeCheckListBox.GetCount();
  1015. int iNumChecked = 0;
  1016. WORD* pTempTypesCovered = new WORD[iCount];
  1017. if (pTempTypesCovered != NULL)
  1018. {
  1019. memset(pTempTypesCovered, 0, iCount * sizeof(WORD));
  1020. for (int idx = 0; idx < iCount; idx++)
  1021. {
  1022. int iChecked = m_TypeCheckListBox.GetCheck(idx);
  1023. if (iChecked == 1)
  1024. {
  1025. pTempTypesCovered[idx] = static_cast<WORD>(m_TypeCheckListBox.GetItemData(idx));
  1026. iNumChecked++;
  1027. }
  1028. }
  1029. //
  1030. // Copy the covered types to the record
  1031. //
  1032. pRecord->m_wNumTypesCovered = static_cast<WORD>(iNumChecked);
  1033. if (pRecord->m_pwTypesCovered != NULL)
  1034. {
  1035. delete[] pRecord->m_pwTypesCovered;
  1036. pRecord->m_pwTypesCovered = NULL;
  1037. }
  1038. pRecord->m_pwTypesCovered = new WORD[pRecord->m_wNumTypesCovered];
  1039. if (pRecord->m_pwTypesCovered != NULL)
  1040. {
  1041. int iTypeCoveredIdx = 0;
  1042. for (int iTempCount = 0; iTempCount < iCount; iTempCount++)
  1043. {
  1044. if (pTempTypesCovered[iTempCount] != 0)
  1045. {
  1046. pRecord->m_pwTypesCovered[iTypeCoveredIdx] = pTempTypesCovered[iTempCount];
  1047. iTypeCoveredIdx++;
  1048. }
  1049. }
  1050. }
  1051. }
  1052. return dwErr;
  1053. }