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.

1184 lines
29 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: krapage.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "genpage.h"
  13. #include "csmmchlp.h"
  14. #include "cslistvw.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. //defines
  20. //dwFlags in KRA_NODE
  21. #define KRA_FROM_CACHE 0x00000001
  22. #define KRA_MARK_ADDED 0x00000002
  23. static const int nImageValidCert = 3;
  24. static const int nImageInvalidCert = 2;
  25. //macros
  26. //local globals
  27. CString CSvrSettingsKRAPage::m_strDispositions[7];
  28. //add a new into the link list
  29. HRESULT
  30. AddNewKRANode(
  31. IN CERT_CONTEXT const *pCert,
  32. IN DWORD dwDisposition,
  33. IN DWORD dwFlags,
  34. IN OUT KRA_NODE **ppKRAList,
  35. OUT OPTIONAL KRA_NODE **ppKRA)
  36. {
  37. CSASSERT(NULL != ppKRAList);
  38. HRESULT hr;
  39. KRA_NODE *pKRANode = NULL;
  40. KRA_NODE *pKRA = *ppKRAList;
  41. pKRANode = (KRA_NODE*)LocalAlloc(LMEM_FIXED, sizeof(KRA_NODE));
  42. if (NULL == pKRANode)
  43. {
  44. hr = E_OUTOFMEMORY;
  45. _JumpError(hr, error, "Out of memory");
  46. }
  47. //assign node data and put it at the end
  48. pKRANode->pCert = pCert;
  49. pKRANode->dwFlags = dwFlags;
  50. pKRANode->next = NULL;
  51. pKRANode->dwDisposition = dwDisposition;
  52. if (NULL == pKRA)
  53. {
  54. //empty list, 1st one
  55. *ppKRAList = pKRANode;
  56. }
  57. else
  58. {
  59. //always add to the end
  60. while (NULL != pKRA->next)
  61. {
  62. pKRA = pKRA->next;
  63. }
  64. //add
  65. pKRA->next = pKRANode;
  66. }
  67. if (NULL != ppKRA)
  68. {
  69. //optional return
  70. *ppKRA = pKRANode;
  71. }
  72. hr = S_OK;
  73. error:
  74. return hr;
  75. }
  76. void
  77. FreeKRANode(
  78. KRA_NODE *pKRA)
  79. {
  80. if (NULL != pKRA->pCert)
  81. {
  82. CertFreeCertificateContext(pKRA->pCert);
  83. pKRA->pCert = NULL;
  84. }
  85. LocalFree(pKRA);
  86. }
  87. void
  88. FreeKRAList(
  89. KRA_NODE *pKRAList)
  90. {
  91. KRA_NODE *pKRA = pKRAList; //point to list
  92. KRA_NODE *pKRATemp;
  93. while (NULL != pKRA)
  94. {
  95. pKRATemp= pKRA; //save it for free
  96. // update for the loop
  97. pKRA= pKRA->next;
  98. FreeKRANode(pKRATemp);
  99. }
  100. }
  101. //remove a kra node from the link list
  102. void
  103. RemoveKRANode(
  104. IN OUT KRA_NODE **ppKRAList,
  105. IN KRA_NODE *pKRA)
  106. {
  107. CSASSERT(NULL != ppKRAList && NULL != *ppKRAList && NULL != pKRA);
  108. KRA_NODE *pKRACurrent = *ppKRAList;
  109. KRA_NODE *pKRALast = NULL;
  110. //find the node
  111. while (NULL != pKRACurrent && pKRACurrent != pKRA)
  112. {
  113. pKRALast = pKRACurrent; //remember last one
  114. pKRACurrent = pKRACurrent->next;
  115. }
  116. CSASSERT(NULL != pKRACurrent); //node must be in the list
  117. if (NULL != pKRACurrent->next)
  118. {
  119. if (NULL == pKRALast)
  120. {
  121. //means the node is the begining
  122. CSASSERT(pKRA == *ppKRAList);
  123. *ppKRAList = pKRA->next; //make next as begining
  124. }
  125. else
  126. {
  127. //make next pointer of the last node to the next
  128. pKRALast->next = pKRACurrent->next;
  129. }
  130. }
  131. else
  132. {
  133. if (NULL == pKRALast)
  134. {
  135. //this is the only node
  136. *ppKRAList = NULL; //empty list
  137. }
  138. else
  139. {
  140. //the node is the end, make last as the end
  141. pKRALast->next = NULL;
  142. }
  143. }
  144. //now, remove the current node
  145. FreeKRANode(pKRACurrent);
  146. }
  147. BOOL
  148. DoesKRACertExist(
  149. IN KRA_NODE *pKRAList,
  150. IN CERT_CONTEXT const *pKRACert)
  151. {
  152. BOOL fExists = FALSE;
  153. while (NULL != pKRAList)
  154. {
  155. if(pKRAList->pCert)
  156. {
  157. fExists = CertCompareCertificate(
  158. X509_ASN_ENCODING,
  159. pKRAList->pCert->pCertInfo,
  160. pKRACert->pCertInfo);
  161. if (fExists)
  162. {
  163. //done
  164. break;
  165. }
  166. }
  167. pKRAList = pKRAList->next;
  168. }
  169. return fExists;
  170. }
  171. DWORD
  172. GetKRACount(
  173. IN KRA_NODE const *pKRAList)
  174. {
  175. DWORD count = 0;
  176. while(NULL != pKRAList)
  177. {
  178. pKRAList = pKRAList->next;
  179. ++count;
  180. }
  181. return count;
  182. }
  183. LPCWSTR CSvrSettingsKRAPage::MapDispositionToString(DWORD dwDisp)
  184. {
  185. if(dwDisp>ARRAYSIZE(m_strDispositions))
  186. dwDisp = KRA_DISP_INVALID;
  187. return CSvrSettingsKRAPage::m_strDispositions[dwDisp];
  188. }
  189. void CSvrSettingsKRAPage::LoadKRADispositions()
  190. {
  191. DWORD cKRA = GetKRACount(m_pKRAList);
  192. variant_t var;
  193. HWND hwndList = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  194. LVITEM lvitem;
  195. ICertAdmin2 *pAdmin = NULL;
  196. // Don't use a cached admin interface, we need latest KRA cert
  197. // state from the server, not a cached result
  198. m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
  199. if(!pAdmin)
  200. return;
  201. lvitem.mask = LVIF_IMAGE;
  202. lvitem.iSubItem = 0;
  203. for(DWORD cCrtKRA=0;cCrtKRA<cKRA;cCrtKRA++)
  204. {
  205. V_I4(&var) = KRA_DISP_INVALID;
  206. pAdmin->GetCAProperty(
  207. m_pCA->m_bstrConfig,
  208. CR_PROP_KRACERTSTATE,
  209. cCrtKRA,
  210. PROPTYPE_LONG,
  211. 0,
  212. &var);
  213. ListView_SetItemText(
  214. hwndList,
  215. cCrtKRA,
  216. 3,
  217. (LPWSTR)MapDispositionToString(V_I4(&var)));
  218. lvitem.iImage = V_I4(&var)==KRA_DISP_VALID?
  219. nImageValidCert:nImageInvalidCert;
  220. lvitem.iItem = cCrtKRA;
  221. ListView_SetItem(
  222. hwndList,
  223. &lvitem);
  224. }
  225. if(pAdmin)
  226. pAdmin->Release();
  227. }
  228. HRESULT
  229. CSvrSettingsKRAPage::LoadKRAList(ICertAdmin2 *pAdmin)
  230. {
  231. HRESULT hr;
  232. KRA_NODE *pKRAList = NULL;
  233. DWORD i;
  234. const CERT_CONTEXT *pCertContext;
  235. LPCWSTR pwszSanitizedCAName = m_pCA->m_strSanitizedName;
  236. KRA_NODE **ppKRAList = &m_pKRAList;
  237. variant_t var;
  238. hr = pAdmin->GetCAProperty(
  239. m_pCA->m_bstrConfig,
  240. CR_PROP_KRACERTCOUNT,
  241. 0,
  242. PROPTYPE_LONG,
  243. 0,
  244. &var);
  245. _JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTCOUNT");
  246. CSASSERT(V_VT(&var)==VT_I4);
  247. m_dwKRACount = V_I4(&var);
  248. for (i = 0; i < m_dwKRACount; ++i)
  249. {
  250. variant_t varCert;
  251. variant_t varDisp;
  252. pCertContext = NULL;
  253. hr = pAdmin->GetCAProperty(
  254. m_pCA->m_bstrConfig,
  255. CR_PROP_KRACERT,
  256. i,
  257. PROPTYPE_BINARY,
  258. CR_OUT_BINARY,
  259. &varCert);
  260. if(S_OK==hr)
  261. {
  262. CSASSERT(V_VT(&varCert)==VT_BSTR);
  263. CSASSERT(V_BSTR(&varCert));
  264. pCertContext = CertCreateCertificateContext(
  265. X509_ASN_ENCODING,
  266. (BYTE*)V_BSTR(&varCert),
  267. SysStringByteLen(V_BSTR(&varCert)));
  268. if(!pCertContext)
  269. {
  270. hr = HRESULT_FROM_WIN32(GetLastError());
  271. _JumpError(hr, error, "CertCreateCertificateContext");
  272. }
  273. }
  274. V_I4(&varDisp) = KRA_DISP_INVALID;
  275. pAdmin->GetCAProperty(
  276. m_pCA->m_bstrConfig,
  277. CR_PROP_KRACERTSTATE,
  278. i,
  279. PROPTYPE_LONG,
  280. 0,
  281. &varDisp);
  282. hr = AddNewKRANode(
  283. pCertContext, V_I4(&varDisp), KRA_FROM_CACHE, &pKRAList, NULL);
  284. _JumpIfError(hr, error, "AddNewKRANode");
  285. }
  286. *ppKRAList = pKRAList;
  287. pKRAList = NULL;
  288. hr = pAdmin->GetCAProperty(
  289. m_pCA->m_bstrConfig,
  290. CR_PROP_KRACERTUSEDCOUNT,
  291. 0,
  292. PROPTYPE_LONG,
  293. 0,
  294. &var);
  295. _JumpIfError(hr, error, "GetCAProperty wszREGKRACERTCOUNT");
  296. CSASSERT(VT_I4==V_VT(&var));
  297. m_dwKRAUsedCount = V_I4(&var);
  298. m_fArchiveKey = m_dwKRAUsedCount?TRUE:FALSE;
  299. hr = S_OK;
  300. error:
  301. if (NULL != pKRAList)
  302. {
  303. FreeKRAList(pKRAList);
  304. }
  305. return hr;
  306. }
  307. HRESULT
  308. CSvrSettingsKRAPage::SaveKRAList(ICertAdmin2 *pAdmin)
  309. {
  310. HRESULT hr;
  311. HCERTSTORE hCAStore = NULL;
  312. KRA_NODE *pKRA = m_pKRAList; //point to the list
  313. DWORD dwIndex = 0;
  314. DWORD dwNewKRACount;
  315. variant_t var;
  316. if (m_fKRAUpdate)
  317. {
  318. while (NULL != pKRA)
  319. {
  320. if(pKRA->pCert)
  321. {
  322. V_VT(&var) = VT_BSTR;
  323. V_BSTR(&var) = NULL;
  324. hr = EncodeCertString(
  325. pKRA->pCert->pbCertEncoded,
  326. pKRA->pCert->cbCertEncoded,
  327. CV_OUT_BINARY,
  328. &(V_BSTR(&var)));
  329. _JumpIfError(hr, error, "EncodeCertString");
  330. hr = pAdmin->SetCAProperty(
  331. m_pCA->m_bstrConfig,
  332. CR_PROP_KRACERT,
  333. dwIndex,
  334. PROPTYPE_BINARY,
  335. &var);
  336. _JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERT");
  337. var.Clear();
  338. }
  339. ++dwIndex;
  340. pKRA = pKRA->next;
  341. }
  342. dwNewKRACount = dwIndex;
  343. // Update total cert count only if the new list is smaller than the old
  344. // list, otherwise SetCAProperty calls above already extended the list
  345. if(dwNewKRACount<m_dwKRACount)
  346. {
  347. V_VT(&var) = VT_I4;
  348. V_I4(&var) = dwNewKRACount;
  349. hr = pAdmin->SetCAProperty(
  350. m_pCA->m_bstrConfig,
  351. CR_PROP_KRACERTCOUNT,
  352. 0,
  353. PROPTYPE_LONG,
  354. &var);
  355. _JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTCOUNT");
  356. }
  357. m_dwKRACount = dwNewKRACount;
  358. }
  359. if (m_fCountUpdate)
  360. {
  361. V_VT(&var) = VT_I4;
  362. V_I4(&var) = m_dwKRAUsedCount;
  363. hr = pAdmin->SetCAProperty(
  364. m_pCA->m_bstrConfig,
  365. CR_PROP_KRACERTUSEDCOUNT,
  366. 0,
  367. PROPTYPE_LONG,
  368. &var);
  369. _JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTUSEDCOUNT");
  370. }
  371. hr = S_OK;
  372. error:
  373. var.Clear();
  374. return hr;
  375. }
  376. HRESULT
  377. KRACertGetName(
  378. IN CERT_CONTEXT const *pCert,
  379. IN DWORD dwFlags, //dwFlags in CertGetNameString
  380. OUT WCHAR **ppwszName)
  381. {
  382. HRESULT hr;
  383. DWORD dwTypeParam;
  384. DWORD cch = 0;
  385. WCHAR *pwszName = NULL;
  386. LPCWSTR pcwszEmpty = L"";
  387. CSASSERT(NULL != ppwszName);
  388. cch = 0;
  389. while (TRUE)
  390. {
  391. if(pCert)
  392. {
  393. cch = CertGetNameString(
  394. pCert,
  395. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  396. dwFlags, //subject or issuer
  397. &dwTypeParam,
  398. pwszName,
  399. cch);
  400. }
  401. else
  402. {
  403. if(!pwszName)
  404. cch = sizeof(WCHAR)*(wcslen(pcwszEmpty)+1);
  405. else
  406. wcscpy(pwszName, pcwszEmpty);
  407. }
  408. if (0 == cch)
  409. {
  410. hr = myHLastError();
  411. _JumpError(hr, error, "CertGetNameString");
  412. }
  413. if (NULL != pwszName)
  414. {
  415. //done
  416. break;
  417. }
  418. pwszName = (WCHAR*)LocalAlloc(LMEM_FIXED, cch * sizeof(WCHAR));
  419. if (NULL == pwszName)
  420. {
  421. hr = E_OUTOFMEMORY;
  422. _JumpError(hr, error, "LocalAlloc");
  423. }
  424. }
  425. *ppwszName = pwszName;
  426. pwszName = NULL;
  427. hr = S_OK;
  428. error:
  429. if (NULL != pwszName)
  430. {
  431. LocalFree(pwszName);
  432. }
  433. return hr;
  434. }
  435. void
  436. ListView_AddKRAItem(
  437. HWND hwndListKRA,
  438. int iItem,
  439. KRA_NODE *pKRA)
  440. {
  441. HRESULT hr;
  442. WCHAR *pwszSubject = NULL;
  443. WCHAR *pwszIssuer = NULL;
  444. CSASSERT(NULL != pKRA);
  445. //get subject name
  446. hr = KRACertGetName(pKRA->pCert, 0x0, &pwszSubject);
  447. if (S_OK != hr)
  448. {
  449. CSASSERT(NULL == pwszSubject);
  450. _PrintError(hr, "Invalid KRA cert");
  451. }
  452. //create a new item, 1st column, subject name, item data point to KRA
  453. ListView_NewItem(hwndListKRA, iItem, pwszSubject, (LPARAM)pKRA,
  454. pKRA->dwDisposition==KRA_DISP_VALID?nImageValidCert:nImageInvalidCert);
  455. if(pKRA->pCert)
  456. {
  457. //get issuer name
  458. hr = KRACertGetName(pKRA->pCert, CERT_NAME_ISSUER_FLAG, &pwszIssuer);
  459. if (S_OK != hr)
  460. {
  461. CSASSERT(NULL == pwszIssuer);
  462. _PrintError(hr, "KRACertGetName(issuer)");
  463. }
  464. //2nd column, issuer name
  465. ListView_SetItemText(hwndListKRA, iItem, 1, pwszIssuer);
  466. //3rd column, expiration date
  467. ListView_SetItemFiletime(hwndListKRA, iItem, 2,
  468. &pKRA->pCert->pCertInfo->NotAfter);
  469. }
  470. //4th column, status
  471. ListView_SetItemText(hwndListKRA, iItem, 3,
  472. (LPWSTR)CSvrSettingsKRAPage::MapDispositionToString(
  473. pKRA->dwDisposition));
  474. if (NULL != pwszSubject)
  475. {
  476. LocalFree(pwszSubject);
  477. }
  478. if (NULL != pwszIssuer)
  479. {
  480. LocalFree(pwszIssuer);
  481. }
  482. }
  483. ////
  484. // Settings: KRA page
  485. /////////////////////////////////////////////////////////////////////////////
  486. // CSvrSettingsKRAPage property page
  487. CSvrSettingsKRAPage::CSvrSettingsKRAPage(
  488. CertSvrCA *pCA,
  489. CSvrSettingsGeneralPage *pControlPage,
  490. UINT uIDD)
  491. : CAutoDeletePropPage(uIDD), m_pControlPage(pControlPage), m_pCA(pCA)
  492. {
  493. m_fArchiveKey = FALSE;
  494. m_fCountUpdate = FALSE;
  495. m_fKRAUpdate = FALSE;
  496. m_pKRAList = NULL;
  497. m_dwKRAUsedCount = 0;
  498. m_dwKRACount = 0;
  499. for(DWORD cStr=0;cStr<ARRAYSIZE(m_strDispositions);cStr++)
  500. {
  501. // IDS_DISPOSITION_* order must match KRA_DISP_*
  502. if(m_strDispositions[cStr].IsEmpty())
  503. m_strDispositions[cStr].LoadString(IDS_DISPOSITION_EXPIRED+cStr);
  504. }
  505. SetHelp(CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_CERTSRV_PROPPAGE_CHOOSE_KRA);
  506. }
  507. CSvrSettingsKRAPage::~CSvrSettingsKRAPage()
  508. {
  509. if (NULL != m_pKRAList)
  510. {
  511. FreeKRAList(m_pKRAList);
  512. }
  513. }
  514. // replacement for DoDataExchange
  515. BOOL CSvrSettingsKRAPage::UpdateData(BOOL fSuckFromDlg /*= TRUE*/)
  516. {
  517. if (fSuckFromDlg)
  518. {
  519. m_dwKRAUsedCount = GetDlgItemInt(
  520. m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
  521. }
  522. else
  523. {
  524. SetDlgItemInt(m_hWnd, IDC_KRA_EDITCOUNT, m_dwKRAUsedCount, FALSE);
  525. }
  526. return TRUE;
  527. }
  528. void CSvrSettingsKRAPage::EnableKRAEdit(BOOL fEnabled)
  529. {
  530. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_EDITCOUNT), fEnabled);
  531. }
  532. void CSvrSettingsKRAPage::EnableKRAListView(BOOL fEnabled)
  533. {
  534. // when disabling the list, deselect any item
  535. if(!fEnabled)
  536. {
  537. ListView_SetItemState(GetDlgItem(m_hWnd, IDC_LIST_KRA),
  538. -1, 0, LVIS_SELECTED);
  539. }
  540. // when enabling the list, select first item
  541. else
  542. {
  543. ListView_SetItemState(GetDlgItem(m_hWnd, IDC_LIST_KRA),
  544. 0, LVIS_SELECTED, LVIS_SELECTED);
  545. }
  546. ::EnableWindow(GetDlgItem(m_hWnd, IDC_LIST_KRA), fEnabled);
  547. }
  548. bool CSvrSettingsKRAPage::IsCurrentItemValidCert()
  549. {
  550. HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  551. // get kra index # from the current selection
  552. int iSel = ListView_GetCurSel(hwndListKRA);
  553. if (-1 == iSel)
  554. {
  555. return false;
  556. }
  557. // get item data
  558. KRA_NODE* pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
  559. if(pKRA)
  560. return pKRA->pCert?true:false;
  561. else
  562. return false;
  563. }
  564. void CSvrSettingsKRAPage::EnableKRARemoveViewListButtons(BOOL fEnabled)
  565. {
  566. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_REMOVE), fEnabled);
  567. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_VIEW), fEnabled &&
  568. IsCurrentItemValidCert());
  569. }
  570. void CSvrSettingsKRAPage::EnableKRAAddListButton(BOOL fEnabled)
  571. {
  572. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_ADD), fEnabled);
  573. }
  574. void CSvrSettingsKRAPage::EnableKRARadioButtons(BOOL fMoreThanZero)
  575. {
  576. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_ENABLE), fMoreThanZero);
  577. ::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_DISABLE), fMoreThanZero);
  578. }
  579. void
  580. CSvrSettingsKRAPage::OnAddKRA()
  581. {
  582. HRESULT hr;
  583. CERT_CONTEXT const *pKRACert = NULL; //don't free
  584. KRA_NODE *pKRA = NULL; //don't free
  585. HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  586. hr = myGetKRACertificateFromPicker(
  587. g_hInstance,
  588. hwndListKRA,
  589. IDS_KRA_ADD_TITLE,
  590. IDS_KRA_ADD_SUBTITLE,
  591. NULL,
  592. m_pCA->FIsUsingDS(),
  593. FALSE, // fSilent
  594. &pKRACert);
  595. if ((S_OK == hr) && (pKRACert == NULL))
  596. hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
  597. if (S_OK != hr)
  598. {
  599. CSASSERT(NULL == pKRACert);
  600. _PrintError(hr, "myGetKRACertificateFromPicker");
  601. return;
  602. }
  603. if (!DoesKRACertExist(m_pKRAList, pKRACert))
  604. {
  605. hr = AddNewKRANode(
  606. pKRACert,
  607. KRA_DISP_NOTLOADED,
  608. KRA_MARK_ADDED,
  609. &m_pKRAList,
  610. &pKRA);
  611. if (S_OK == hr)
  612. {
  613. //add to the kra to the end of the list
  614. int iItem = ListView_GetItemCount(hwndListKRA);
  615. ListView_AddKRAItem(hwndListKRA, iItem, pKRA);
  616. ListView_SetItemState(hwndListKRA, iItem, LVIS_SELECTED, LVIS_SELECTED);
  617. if (0 == iItem)
  618. {
  619. //first item, buttons must have been disabled
  620. EnableKRARemoveViewListButtons(TRUE);
  621. EnableKRARadioButtons(TRUE);
  622. EnableKRAListView(TRUE);
  623. SendMessage(GetDlgItem(m_hWnd, IDC_KRA_ENABLE),
  624. BM_CLICK, (WPARAM)0, (LPARAM)0);
  625. }
  626. SetModified(TRUE);
  627. m_fDirty = TRUE;
  628. m_fKRAUpdate = TRUE;
  629. }
  630. else
  631. {
  632. //pop up???
  633. _PrintError(hr, "AddNewKRANode");
  634. }
  635. }
  636. else
  637. {
  638. //UNDONE, ideally, pass m_pKRAList to picker to filter them out
  639. _PrintError(S_OK, "KRA cert from the picker already in the list");
  640. }
  641. }
  642. void
  643. CSvrSettingsKRAPage::OnRemoveKRA()
  644. {
  645. KRA_NODE *pKRA;
  646. int cItem;
  647. HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  648. //get the selected KRA
  649. int iSel = ListView_GetCurSel(hwndListKRA);
  650. if (-1 == iSel)
  651. {
  652. return;
  653. }
  654. //get current count
  655. cItem = ListView_GetItemCount(hwndListKRA);
  656. pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
  657. CSASSERT(NULL != pKRA);
  658. //remove it from the link list
  659. RemoveKRANode(&m_pKRAList, pKRA);
  660. //remove it from UI
  661. if (ListView_DeleteItem(hwndListKRA, iSel))
  662. {
  663. //determine which item is selected
  664. if (iSel == cItem - 1)
  665. {
  666. //the item removed was the last, modify the index
  667. --iSel;
  668. }
  669. if (NULL != m_pKRAList)
  670. {
  671. ListView_SetItemState(hwndListKRA, iSel, LVIS_SELECTED, LVIS_SELECTED);
  672. }
  673. else
  674. {
  675. CSASSERT(1 == cItem);
  676. //should check disable radio
  677. SendMessage(GetDlgItem(m_hWnd, IDC_KRA_DISABLE),
  678. BM_CLICK, (WPARAM)0, (LPARAM)0);
  679. }
  680. SetModified(TRUE);
  681. m_fKRAUpdate = TRUE;
  682. }
  683. else
  684. {
  685. _PrintError(E_UNEXPECTED, "ListView_DeleteItem");
  686. }
  687. }
  688. void
  689. CSvrSettingsKRAPage::OnViewKRA()
  690. {
  691. HRESULT hr;
  692. HCERTSTORE rghStores[2];
  693. DWORD cStores = 0;
  694. HCERTSTORE hCAStore;
  695. HCERTSTORE hRootStore;
  696. KRA_NODE *pKRA;
  697. HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  698. CRYPTUI_VIEWCERTIFICATE_STRUCTW sViewCert;
  699. ZeroMemory(&sViewCert, sizeof(sViewCert));
  700. // get kra index # from the current selection
  701. int iSel = ListView_GetCurSel(hwndListKRA);
  702. if (-1 == iSel)
  703. {
  704. return;
  705. }
  706. // get item data
  707. pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
  708. CSASSERT(NULL != pKRA);
  709. // get CA stores
  710. hr = m_pCA->GetRootCertStore(&hRootStore);
  711. if (S_OK == hr)
  712. {
  713. rghStores[cStores] = hRootStore;
  714. ++cStores;
  715. }
  716. else
  717. {
  718. _PrintError(hr, "GetRootCertStore");
  719. }
  720. hr = m_pCA->GetCACertStore(&hCAStore);
  721. if (S_OK == hr)
  722. {
  723. rghStores[cStores] = hCAStore;
  724. ++cStores;
  725. }
  726. else
  727. {
  728. _PrintError(hr, "GetCACertStore");
  729. }
  730. sViewCert.pCertContext = pKRA->pCert;
  731. sViewCert.hwndParent = m_hWnd;
  732. sViewCert.dwSize = sizeof(sViewCert);
  733. sViewCert.dwFlags = CRYPTUI_ENABLE_REVOCATION_CHECKING |
  734. CRYPTUI_WARN_UNTRUSTED_ROOT |
  735. CRYPTUI_DISABLE_ADDTOSTORE;
  736. // if we're opening remotely, don't open local stores
  737. if (! m_pCA->m_pParentMachine->IsLocalMachine())
  738. sViewCert.dwFlags |= CRYPTUI_DONT_OPEN_STORES;
  739. if (0 < cStores)
  740. {
  741. sViewCert.rghStores = rghStores;
  742. sViewCert.cStores = cStores;
  743. if (!CryptUIDlgViewCertificateW(&sViewCert, NULL))
  744. {
  745. hr = myHLastError();
  746. if (hr != HRESULT_FROM_WIN32(ERROR_CANCELLED))
  747. {
  748. _PrintError(hr, "CryptUIDlgViewCertificateW");
  749. }
  750. }
  751. }
  752. else
  753. {
  754. DisplayCertSrvErrorWithContext(m_hWnd, hr, IDS_KRA_CANNOT_OPEN_STORE);
  755. }
  756. }
  757. // replacement for BEGIN_MESSAGE_MAP
  758. BOOL CSvrSettingsKRAPage::OnCommand(WPARAM wParam, LPARAM lParam)
  759. {
  760. BOOL fRet = TRUE;
  761. DWORD dwNewVal;
  762. switch(LOWORD(wParam))
  763. {
  764. case IDC_KRA_ADD:
  765. OnAddKRA();
  766. break;
  767. case IDC_KRA_REMOVE:
  768. OnRemoveKRA();
  769. break;
  770. case IDC_KRA_VIEW:
  771. OnViewKRA();
  772. break;
  773. case IDC_KRA_DISABLE:
  774. if ((BN_CLICKED == HIWORD(wParam)) && (m_dwKRAUsedCount != 0)) // if click to change state
  775. {
  776. SetModified(TRUE);
  777. m_fArchiveKey = FALSE;
  778. m_fCountUpdate = TRUE;
  779. m_dwKRAUsedCount = 0;
  780. EnableKRAListView(FALSE);
  781. EnableKRARemoveViewListButtons(FALSE);
  782. EnableKRAAddListButton(FALSE);
  783. EnableKRAEdit(FALSE);
  784. UpdateData(FALSE);
  785. }
  786. break;
  787. case IDC_KRA_ENABLE:
  788. if ((BN_CLICKED == HIWORD(wParam)) && (m_dwKRAUsedCount == 0)) // if click to change state
  789. {
  790. SetModified(TRUE);
  791. m_fArchiveKey = TRUE;
  792. m_fCountUpdate = TRUE;
  793. m_dwKRAUsedCount = 1;
  794. EnableKRAListView(TRUE);
  795. EnableKRARemoveViewListButtons(GetKRACount(m_pKRAList));
  796. EnableKRAAddListButton(TRUE);
  797. EnableKRAEdit(TRUE);
  798. UpdateData(FALSE);
  799. }
  800. break;
  801. case IDC_KRA_EDITCOUNT:
  802. dwNewVal = GetDlgItemInt(
  803. m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
  804. switch(HIWORD(wParam))
  805. {
  806. case EN_CHANGE:
  807. if(dwNewVal != m_dwKRAUsedCount)
  808. {
  809. SetModified(TRUE);
  810. m_fCountUpdate = TRUE;
  811. }
  812. break;
  813. default:
  814. fRet = FALSE;
  815. break;
  816. }
  817. break;
  818. case IDC_LIST_KRA:
  819. switch(HIWORD(wParam))
  820. {
  821. case LBN_SELCHANGE:
  822. int selected = ListView_GetCurSel(
  823. GetDlgItem(m_hWnd, IDC_LIST_KRA));
  824. EnableKRARemoveViewListButtons(selected!=-1);
  825. break;
  826. }
  827. break;
  828. default:
  829. fRet = FALSE;
  830. break;
  831. }
  832. return fRet;
  833. }
  834. /////////////////////////////////////////////////////////////////////////////
  835. // CSvrSettingsKRAPage radio controls handlers
  836. void CSvrSettingsKRAPage::UpdateKRARadioControls()
  837. {
  838. int iRadio = IDC_KRA_ENABLE;
  839. if (0 == m_dwKRAUsedCount)
  840. {
  841. iRadio = IDC_KRA_DISABLE;
  842. }
  843. SendMessage(GetDlgItem(m_hWnd, iRadio), BM_CLICK, (WPARAM)0, (LPARAM)0);
  844. }
  845. /////////////////////////////////////////////////////////////////////////////
  846. // CSvrSettingsKRAPage message handlers
  847. BOOL CSvrSettingsKRAPage::OnInitDialog()
  848. {
  849. HRESULT hr;
  850. HWND hwndListKRA;
  851. int iItem;
  852. CString cstrItemName;
  853. KRA_NODE *pKRA;
  854. variant_t var;
  855. ICertAdmin2 *pAdmin = NULL;
  856. HIMAGELIST hImageList = NULL;
  857. CWaitCursor WaitCursor;
  858. // does parent init and UpdateData call
  859. CAutoDeletePropPage::OnInitDialog();
  860. hr = m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
  861. _JumpIfError(hr, error, "GetAdmin2");
  862. // set edit max char limit
  863. SendDlgItemMessage(
  864. IDC_KRA_EDITCOUNT,
  865. EM_SETLIMITTEXT,
  866. (WPARAM)4,
  867. (LPARAM)0);
  868. // init listview
  869. hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
  870. //make listviews whole row selection
  871. ListView_SetExtendedListViewStyle(hwndListKRA, LVS_EX_FULLROWSELECT);
  872. hImageList = ImageList_LoadBitmap(
  873. g_hInstance,
  874. MAKEINTRESOURCE(IDB_16x16),
  875. 16,
  876. 1,
  877. RGB(255, 0, 255));
  878. ListView_SetImageList(hwndListKRA, hImageList, LVSIL_SMALL);
  879. //set kra list as default focus
  880. SetFocus(hwndListKRA);
  881. //add multiple columns
  882. //column 0
  883. cstrItemName.LoadString(IDS_LISTCOL_SUBJECT);
  884. ListView_NewColumn(hwndListKRA, 0, 90, (LPWSTR)(LPCWSTR)cstrItemName);
  885. //column 1
  886. cstrItemName.LoadString(IDS_LISTCOL_ISSUER);
  887. ListView_NewColumn(hwndListKRA, 1, 90, (LPWSTR)(LPCWSTR)cstrItemName);
  888. //column 2
  889. cstrItemName.LoadString(IDS_LISTCOL_EXPIRATION_DATE);
  890. ListView_NewColumn(hwndListKRA, 2, 90, (LPWSTR)(LPCWSTR)cstrItemName);
  891. //column 3
  892. cstrItemName.LoadString(IDS_LISTCOL_STATUS);
  893. ListView_NewColumn(hwndListKRA, 3, 65, (LPWSTR)(LPCWSTR)cstrItemName);
  894. CSASSERT(NULL == m_pKRAList);
  895. //load all KRA certs
  896. hr = LoadKRAList(pAdmin);
  897. if (S_OK != hr)
  898. {
  899. CSASSERT(NULL == m_pKRAList);
  900. _JumpError(hr, error, "LoadKRAList");
  901. }
  902. //list KRA certs in UI
  903. pKRA = m_pKRAList;
  904. iItem = 0;
  905. while (NULL != pKRA)
  906. {
  907. ListView_AddKRAItem(hwndListKRA, iItem, pKRA);
  908. ++iItem;
  909. pKRA = pKRA->next;
  910. }
  911. //enable view/remove buttons
  912. EnableKRARemoveViewListButtons(m_fArchiveKey && 0 < iItem);
  913. //enable add button
  914. EnableKRAAddListButton(m_fArchiveKey);
  915. EnableKRARadioButtons(TRUE);
  916. if (m_fArchiveKey && 0 < iItem)
  917. {
  918. //select first one
  919. ListView_SetItemState(hwndListKRA, 0, LVIS_SELECTED, LVIS_SELECTED);
  920. }
  921. EnableKRAEdit(m_dwKRAUsedCount);
  922. UpdateKRARadioControls();
  923. UpdateData(FALSE);
  924. EnableKRAListView(m_dwKRAUsedCount);
  925. error:
  926. if(pAdmin)
  927. pAdmin->Release();
  928. if (hr != S_OK)
  929. {
  930. DisplayGenericCertSrvError(m_hWnd, hr);
  931. return FALSE;
  932. }
  933. return TRUE;
  934. }
  935. void CSvrSettingsKRAPage::OnDestroy()
  936. {
  937. // Note - This needs to be called only once.
  938. // If called more than once, it will gracefully return an error.
  939. // if (m_hConsoleHandle)
  940. // MMCFreeNotifyHandle(m_hConsoleHandle);
  941. // m_hConsoleHandle = NULL;
  942. CAutoDeletePropPage::OnDestroy();
  943. }
  944. BOOL CSvrSettingsKRAPage::OnApply()
  945. {
  946. HRESULT hr = S_OK;
  947. ICertAdmin2 *pAdmin = NULL;
  948. HWND hwndEdit = GetDlgItem(m_hWnd, IDC_KRA_EDITCOUNT);
  949. DWORD dwNewVal = GetDlgItemInt(
  950. m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
  951. // If key archival is enabled, you must have at least one
  952. // KRA defined and the number of used KRAs must be between
  953. // 1 and total number of KRAs defined
  954. if(m_fArchiveKey)
  955. {
  956. if(0==GetKRACount(m_pKRAList))
  957. {
  958. DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_KRA_NOKRADEFINED);
  959. SetFocus(GetDlgItem(m_hWnd, IDC_KRA_ADD));//focus on add button
  960. return FALSE;
  961. }
  962. if(dwNewVal < 1 || dwNewVal > GetKRACount(m_pKRAList))
  963. {
  964. DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_KRA_COUNT_TOO_BIG);
  965. SetFocus(hwndEdit); // focus on edit box
  966. SendMessage(hwndEdit, EM_SETSEL, 0, -1); // select all text
  967. return FALSE;
  968. }
  969. }
  970. UpdateData(TRUE);
  971. if (m_fKRAUpdate || m_fCountUpdate)
  972. {
  973. hr = m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
  974. _JumpIfError(hr, error, "GetAdmin");
  975. // update reg hash list
  976. hr = SaveKRAList(pAdmin);
  977. _JumpIfError(hr, error, "SaveKRAList");
  978. m_pControlPage->NeedServiceRestart(SERVERSETTINGS_PROPPAGE_KRA);
  979. m_pControlPage->TryServiceRestart(SERVERSETTINGS_PROPPAGE_KRA);
  980. LoadKRADispositions();
  981. m_fKRAUpdate = FALSE;
  982. m_fCountUpdate = FALSE;
  983. }
  984. error:
  985. if(pAdmin)
  986. pAdmin->Release();
  987. if (hr != S_OK)
  988. {
  989. DisplayGenericCertSrvError(m_hWnd, hr);
  990. return FALSE;
  991. }
  992. return CAutoDeletePropPage::OnApply();
  993. }
  994. BOOL CSvrSettingsKRAPage::OnNotify(UINT idCtrl, NMHDR* pnmh)
  995. {
  996. LPNM_LISTVIEW pnmlv = (LPNM_LISTVIEW)pnmh;
  997. switch(idCtrl)
  998. {
  999. //handle double click on list items
  1000. case IDC_LIST_KRA:
  1001. switch(pnmh->code)
  1002. {
  1003. case NM_DBLCLK:
  1004. OnViewKRA();
  1005. break;
  1006. case LVN_ITEMCHANGED:
  1007. EnableKRARemoveViewListButtons(pnmlv->uNewState & LVIS_SELECTED);
  1008. break;
  1009. }
  1010. }
  1011. return FALSE;
  1012. }