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.

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