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.

1044 lines
33 KiB

  1. //-------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: selcal.cpp
  5. //
  6. // Contents: The cpp file to implement CA selection dialogue
  7. //
  8. // History: Jan-2-1998 xiaohs created
  9. //
  10. //--------------------------------------------------------------
  11. #include "wzrdpvk.h"
  12. #include "certca.h"
  13. #include "cautil.h"
  14. #include "selca.h"
  15. //context sensitive help for the main dialogue
  16. static const HELPMAP SelCaMainHelpMap[] = {
  17. {IDC_CA_LIST, IDH_SELCA_LIST},
  18. };
  19. //-----------------------------------------------------------------------------
  20. // the call back function to compare the certificate
  21. //
  22. //-----------------------------------------------------------------------------
  23. int CALLBACK CompareCA(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  24. {
  25. PCRYPTUI_CA_CONTEXT pCAOne=NULL;
  26. PCRYPTUI_CA_CONTEXT pCATwo=NULL;
  27. DWORD dwColumn=0;
  28. int iCompare=0;
  29. LPWSTR pwszOne=NULL;
  30. LPWSTR pwszTwo=NULL;
  31. pCAOne=(PCRYPTUI_CA_CONTEXT)lParam1;
  32. pCATwo=(PCRYPTUI_CA_CONTEXT)lParam2;
  33. dwColumn=(DWORD)lParamSort;
  34. if((NULL==pCAOne) || (NULL==pCATwo))
  35. goto CLEANUP;
  36. switch(dwColumn & 0x0000FFFF)
  37. {
  38. case SORT_COLUMN_CA_NAME:
  39. pwszOne=(LPWSTR)(pCAOne->pwszCAName);
  40. pwszTwo=(LPWSTR)(pCATwo->pwszCAName);
  41. break;
  42. case SORT_COLUMN_CA_LOCATION:
  43. pwszOne=(LPWSTR)(pCAOne->pwszCAMachineName);
  44. pwszTwo=(LPWSTR)(pCATwo->pwszCAMachineName);
  45. break;
  46. }
  47. if((NULL==pwszOne) || (NULL==pwszTwo))
  48. goto CLEANUP;
  49. iCompare=_wcsicmp(pwszOne, pwszTwo);
  50. if(dwColumn & SORT_COLUMN_DESCEND)
  51. iCompare = 0-iCompare;
  52. CLEANUP:
  53. return iCompare;
  54. }
  55. //--------------------------------------------------------------
  56. // AddCAToList
  57. //--------------------------------------------------------------
  58. BOOL AddCAToList(HWND hwndControl,
  59. SELECT_CA_INFO *pSelectCAInfo)
  60. {
  61. BOOL fResult=FALSE;
  62. DWORD dwIndex=0;
  63. LV_ITEMW lvItem;
  64. if(!hwndControl || !pSelectCAInfo)
  65. goto InvalidArgErr;
  66. // set up the fields in the list view item struct that don't change from item to item
  67. memset(&lvItem, 0, sizeof(LV_ITEMW));
  68. lvItem.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE|LVIF_PARAM ;
  69. lvItem.state = 0;
  70. lvItem.stateMask = 0;
  71. lvItem.iSubItem=0;
  72. lvItem.iImage = 0;
  73. //add all the CAs
  74. for(dwIndex=0; dwIndex<pSelectCAInfo->dwCACount; dwIndex++)
  75. {
  76. if((pSelectCAInfo->prgCAContext)[dwIndex])
  77. {
  78. lvItem.iItem=dwIndex;
  79. lvItem.iSubItem=0;
  80. lvItem.lParam = (LPARAM)((pSelectCAInfo->prgCAContext)[dwIndex]);
  81. lvItem.pszText=(LPWSTR)((pSelectCAInfo->prgCAContext)[dwIndex]->pwszCAName);
  82. //CA common name
  83. ListView_InsertItemU(hwndControl, &lvItem);
  84. lvItem.iSubItem++;
  85. //CA machine name
  86. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  87. (pSelectCAInfo->prgCAContext)[dwIndex]->pwszCAMachineName);
  88. //set the item to be selected
  89. if(pSelectCAInfo->fUseInitSelect)
  90. {
  91. if(dwIndex == pSelectCAInfo->dwInitSelect)
  92. ListView_SetItemState(hwndControl, dwIndex, LVIS_SELECTED, LVIS_SELECTED);
  93. }
  94. }
  95. else
  96. goto InvalidArgErr;
  97. }
  98. if (!pSelectCAInfo->fUseInitSelect) {
  99. ListView_SetItemState(hwndControl, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  100. }
  101. fResult=TRUE;
  102. CommonReturn:
  103. return fResult;
  104. ErrorReturn:
  105. fResult=FALSE;
  106. goto CommonReturn;
  107. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  108. }
  109. //--------------------------------------------------------------
  110. // CopyCAContext
  111. //--------------------------------------------------------------
  112. BOOL CopyCAContext(PCRYPTUI_CA_CONTEXT pSrcCAContext,
  113. PCRYPTUI_CA_CONTEXT *ppDestCAContext)
  114. {
  115. BOOL fResult=FALSE;
  116. if((!pSrcCAContext) || (!ppDestCAContext))
  117. goto InvalidArgErr;
  118. *ppDestCAContext=NULL;
  119. *ppDestCAContext=(PCRYPTUI_CA_CONTEXT)WizardAlloc(sizeof(CRYPTUI_CA_CONTEXT));
  120. if(NULL==(*ppDestCAContext))
  121. goto MemoryErr;
  122. //memset
  123. memset(*ppDestCAContext, 0, sizeof(CRYPTUI_CA_CONTEXT));
  124. (*ppDestCAContext)->dwSize=sizeof(CRYPTUI_CA_CONTEXT);
  125. (*ppDestCAContext)->pwszCAName=(LPCWSTR)WizardAllocAndCopyWStr(
  126. (LPWSTR)(pSrcCAContext->pwszCAName));
  127. (*ppDestCAContext)->pwszCAMachineName=(LPCWSTR)WizardAllocAndCopyWStr(
  128. (LPWSTR)(pSrcCAContext->pwszCAMachineName));
  129. //make sure we have the correct informatiom
  130. if((NULL==(*ppDestCAContext)->pwszCAName) ||
  131. (NULL==(*ppDestCAContext)->pwszCAMachineName)
  132. )
  133. {
  134. CryptUIDlgFreeCAContext(*ppDestCAContext);
  135. *ppDestCAContext=NULL;
  136. goto TraceErr;
  137. }
  138. fResult=TRUE;
  139. CommonReturn:
  140. return fResult;
  141. ErrorReturn:
  142. fResult=FALSE;
  143. goto CommonReturn;
  144. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  145. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  146. TRACE_ERROR(TraceErr);
  147. }
  148. //--------------------------------------------------------------
  149. // The wineProc for SelectCADialogProc
  150. //--------------------------------------------------------------
  151. INT_PTR APIENTRY SelectCADialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  152. {
  153. SELECT_CA_INFO *pSelectCAInfo=NULL;
  154. PCCRYPTUI_SELECT_CA_STRUCT pCAStruct=NULL;
  155. HWND hWndListView=NULL;
  156. DWORD dwIndex=0;
  157. DWORD dwCount=0;
  158. WCHAR wszText[MAX_STRING_SIZE];
  159. UINT rgIDS[]={IDS_COLUMN_CA_NAME,
  160. IDS_COLUMN_CA_MACHINE};
  161. NM_LISTVIEW FAR * pnmv=NULL;
  162. LV_COLUMNW lvC;
  163. int listIndex=0;
  164. LV_ITEM lvItem;
  165. HIMAGELIST hIml=NULL;
  166. HWND hwnd=NULL;
  167. DWORD dwSortParam=0;
  168. switch ( msg ) {
  169. case WM_INITDIALOG:
  170. pSelectCAInfo = (SELECT_CA_INFO *) lParam;
  171. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pSelectCAInfo);
  172. pCAStruct=pSelectCAInfo->pCAStruct;
  173. if(NULL == pCAStruct)
  174. break;
  175. //
  176. // set the dialog title and the display string
  177. //
  178. if (pCAStruct->wszTitle)
  179. {
  180. SetWindowTextU(hwndDlg, pCAStruct->wszTitle);
  181. }
  182. if (pCAStruct->wszDisplayString != NULL)
  183. {
  184. SetDlgItemTextU(hwndDlg, IDC_CA_NOTE_STATIC, pCAStruct->wszDisplayString);
  185. }
  186. //create the image list
  187. hIml = ImageList_LoadImage(g_hmodThisDll, MAKEINTRESOURCE(IDB_CA), 0, 1, RGB(255,0,255), IMAGE_BITMAP, 0);
  188. //
  189. // add the colums to the list view
  190. //
  191. hWndListView = GetDlgItem(hwndDlg, IDC_CA_LIST);
  192. if(NULL==hWndListView)
  193. break;
  194. //set the image list
  195. if (hIml != NULL)
  196. {
  197. ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
  198. }
  199. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  200. //set up the common info for the column
  201. memset(&lvC, 0, sizeof(LV_COLUMNW));
  202. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  203. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  204. lvC.cx = 200; // Width of the column, in pixels.
  205. lvC.iSubItem=0;
  206. lvC.pszText = wszText; // The text for the column.
  207. //inser the column one at a time
  208. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  209. {
  210. //get the column header
  211. wszText[0]=L'\0';
  212. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  213. ListView_InsertColumnU(hWndListView, dwIndex, &lvC);
  214. }
  215. //Add the CAs to the List View. Go to the DS for more information
  216. AddCAToList(hWndListView, pSelectCAInfo);
  217. //Select first item
  218. ListView_SetItemState(hWndListView, 0, LVIS_SELECTED, LVIS_SELECTED);
  219. // if there is no cert selected initially disable the "view cert button"
  220. if (ListView_GetSelectedCount(hWndListView) == 0)
  221. {
  222. //diable the OK button.
  223. EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
  224. }
  225. //
  226. // set the style in the list view so that it highlights an entire line
  227. //
  228. SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  229. //we sort by the 1st column
  230. dwSortParam=pSelectCAInfo->rgdwSortParam[0];
  231. if(0!=dwSortParam)
  232. {
  233. //sort the 1st column
  234. SendDlgItemMessage(hwndDlg,
  235. IDC_CA_LIST,
  236. LVM_SORTITEMS,
  237. (WPARAM) (LPARAM) dwSortParam,
  238. (LPARAM) (PFNLVCOMPARE)CompareCA);
  239. }
  240. break;
  241. case WM_NOTIFY:
  242. switch (((NMHDR FAR *) lParam)->code)
  243. {
  244. //the column has been changed
  245. case LVN_COLUMNCLICK:
  246. pSelectCAInfo = (SELECT_CA_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  247. if(NULL == pSelectCAInfo)
  248. break;
  249. pnmv = (NM_LISTVIEW FAR *) lParam;
  250. //get the column number
  251. dwSortParam=0;
  252. switch(pnmv->iSubItem)
  253. {
  254. case 0:
  255. case 1:
  256. dwSortParam=pSelectCAInfo->rgdwSortParam[pnmv->iSubItem];
  257. break;
  258. default:
  259. dwSortParam=0;
  260. break;
  261. }
  262. if(0!=dwSortParam)
  263. {
  264. //remember to flip the ascend ording
  265. if(dwSortParam & SORT_COLUMN_ASCEND)
  266. {
  267. dwSortParam &= 0x0000FFFF;
  268. dwSortParam |= SORT_COLUMN_DESCEND;
  269. }
  270. else
  271. {
  272. if(dwSortParam & SORT_COLUMN_DESCEND)
  273. {
  274. dwSortParam &= 0x0000FFFF;
  275. dwSortParam |= SORT_COLUMN_ASCEND;
  276. }
  277. }
  278. //sort the column
  279. SendDlgItemMessage(hwndDlg,
  280. IDC_CA_LIST,
  281. LVM_SORTITEMS,
  282. (WPARAM) (LPARAM) dwSortParam,
  283. (LPARAM) (PFNLVCOMPARE)CompareCA);
  284. pSelectCAInfo->rgdwSortParam[pnmv->iSubItem]=dwSortParam;
  285. }
  286. break;
  287. //the item has been selected
  288. case LVN_ITEMCHANGED:
  289. //get the window handle of the purpose list view
  290. if(NULL==(hWndListView=GetDlgItem(hwndDlg, IDC_CA_LIST)))
  291. break;
  292. pSelectCAInfo = (SELECT_CA_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  293. if(NULL == pSelectCAInfo)
  294. break;
  295. pnmv = (LPNMLISTVIEW) lParam;
  296. if(NULL==pnmv)
  297. break;
  298. //we try not to let user de-select cert template
  299. if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
  300. {
  301. //we should have something selected
  302. if(-1 == ListView_GetNextItem(
  303. hWndListView,
  304. -1,
  305. LVNI_SELECTED
  306. ))
  307. {
  308. //we should re-select the original item
  309. ListView_SetItemState(
  310. hWndListView,
  311. pnmv->iItem,
  312. LVIS_SELECTED,
  313. LVIS_SELECTED);
  314. pSelectCAInfo->iOrgCA=pnmv->iItem;
  315. }
  316. }
  317. //if something is selected, we disable all other selection
  318. if(pnmv->uNewState & LVIS_SELECTED)
  319. {
  320. if(pnmv->iItem != pSelectCAInfo->iOrgCA && -1 != pSelectCAInfo->iOrgCA)
  321. {
  322. //we should de-select the original item
  323. ListView_SetItemState(
  324. hWndListView,
  325. pSelectCAInfo->iOrgCA,
  326. 0,
  327. LVIS_SELECTED);
  328. pSelectCAInfo->iOrgCA=-1;
  329. }
  330. }
  331. break;
  332. case LVN_ITEMCHANGING:
  333. pnmv = (NM_LISTVIEW FAR *) lParam;
  334. if (pnmv->uNewState & LVIS_SELECTED)
  335. {
  336. EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
  337. }
  338. break;
  339. case NM_DBLCLK:
  340. switch (((NMHDR FAR *) lParam)->idFrom)
  341. {
  342. case IDC_CA_LIST:
  343. pSelectCAInfo = (SELECT_CA_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  344. if(NULL == pSelectCAInfo)
  345. break;
  346. pCAStruct=pSelectCAInfo->pCAStruct;
  347. if(NULL == pCAStruct)
  348. break;
  349. hWndListView = GetDlgItem(hwndDlg, IDC_CA_LIST);
  350. //get the selected CA name and machine name
  351. listIndex = ListView_GetNextItem(
  352. hWndListView,
  353. -1,
  354. LVNI_SELECTED
  355. );
  356. if (listIndex != -1)
  357. {
  358. //get the selected certificate
  359. memset(&lvItem, 0, sizeof(LV_ITEM));
  360. lvItem.mask=LVIF_PARAM;
  361. lvItem.iItem=listIndex;
  362. if(ListView_GetItem(hWndListView, &lvItem))
  363. {
  364. //copy the CA context to the result
  365. if((listIndex < (int)(pSelectCAInfo->dwCACount)) && (listIndex >=0) )
  366. {
  367. if(!CopyCAContext((PCRYPTUI_CA_CONTEXT)(lvItem.lParam),
  368. &(pSelectCAInfo->pSelectedCAContext)))
  369. {
  370. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CA,
  371. pSelectCAInfo->idsMsg,
  372. pCAStruct->wszTitle,
  373. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  374. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  375. return TRUE;
  376. }
  377. }
  378. }
  379. }
  380. else
  381. {
  382. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CA,
  383. pSelectCAInfo->idsMsg,
  384. pCAStruct->wszTitle,
  385. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  386. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  387. return TRUE;
  388. }
  389. //double click will end the dialogue
  390. EndDialog(hwndDlg, NULL);
  391. break;
  392. }
  393. break;
  394. }
  395. break;
  396. case WM_HELP:
  397. case WM_CONTEXTMENU:
  398. if (msg == WM_HELP)
  399. {
  400. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  401. }
  402. else
  403. {
  404. hwnd = (HWND) wParam;
  405. }
  406. if ((hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  407. (hwnd != GetDlgItem(hwndDlg, IDCANCEL)) &&
  408. (hwnd != GetDlgItem(hwndDlg, IDC_CA_LIST)))
  409. {
  410. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  411. return TRUE;
  412. }
  413. else
  414. {
  415. return OnContextHelp(hwndDlg, msg, wParam, lParam, SelCaMainHelpMap);
  416. }
  417. break;
  418. case WM_DESTROY:
  419. //
  420. // get all the items in the list view //
  421. hWndListView = GetDlgItem(hwndDlg, IDC_CA_LIST);
  422. if(NULL==hWndListView)
  423. break;
  424. //no need to destroy the image list. Handled by ListView
  425. // ImageList_Destroy(ListView_GetImageList(hWndListView, LVSIL_SMALL));
  426. break;
  427. case WM_COMMAND:
  428. pSelectCAInfo = (SELECT_CA_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  429. if(NULL == pSelectCAInfo)
  430. break;
  431. pCAStruct=pSelectCAInfo->pCAStruct;
  432. if(NULL == pCAStruct)
  433. break;
  434. hWndListView = GetDlgItem(hwndDlg, IDC_CA_LIST);
  435. switch (LOWORD(wParam))
  436. {
  437. case IDOK:
  438. //get the selected CA name and machine name
  439. listIndex = ListView_GetNextItem(
  440. hWndListView,
  441. -1,
  442. LVNI_SELECTED
  443. );
  444. if (listIndex != -1)
  445. {
  446. //get the selected certificate
  447. memset(&lvItem, 0, sizeof(LV_ITEM));
  448. lvItem.mask=LVIF_PARAM;
  449. lvItem.iItem=listIndex;
  450. if(ListView_GetItem(hWndListView, &lvItem))
  451. {
  452. //copy the CA context to the result
  453. if((listIndex < (int)(pSelectCAInfo->dwCACount)) && (listIndex >=0) )
  454. {
  455. if(!CopyCAContext((PCRYPTUI_CA_CONTEXT)(lvItem.lParam),
  456. &(pSelectCAInfo->pSelectedCAContext)))
  457. {
  458. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CA,
  459. pSelectCAInfo->idsMsg,
  460. pCAStruct->wszTitle,
  461. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  462. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  463. return TRUE;
  464. }
  465. }
  466. }
  467. }
  468. else
  469. {
  470. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CA,
  471. pSelectCAInfo->idsMsg,
  472. pCAStruct->wszTitle,
  473. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  474. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  475. return TRUE;
  476. }
  477. EndDialog(hwndDlg, NULL);
  478. break;
  479. case IDCANCEL:
  480. EndDialog(hwndDlg, NULL);
  481. break;
  482. }
  483. break;
  484. }
  485. return FALSE;
  486. }
  487. //--------------------------------------------------------------
  488. //
  489. // Parameters:
  490. // pCryptUISelectCA IN Required
  491. //
  492. // the PCCRYPTUI_CA_CONTEXT that is returned must be released by calling
  493. // CryptUIDlgFreeCAContext
  494. // if NULL is returned and GetLastError() == 0 then the user dismissed the dialog by hitting the
  495. // "cancel" button, otherwise GetLastError() will contain the last error.
  496. //
  497. //
  498. //--------------------------------------------------------------
  499. PCCRYPTUI_CA_CONTEXT
  500. WINAPI
  501. CryptUIDlgSelectCA(
  502. IN PCCRYPTUI_SELECT_CA_STRUCT pCryptUISelectCA
  503. )
  504. {
  505. BOOL fResult=FALSE;
  506. DWORD dwIndex=0;
  507. SELECT_CA_INFO SelectCAInfo;
  508. DWORD dwNTCACount=0;
  509. BOOL fInitSelected=FALSE;
  510. DWORD dwSearchIndex=0;
  511. BOOL fFound=FALSE;
  512. CRYPTUI_CA_CONTEXT CAContext;
  513. LPWSTR *pwszCAName=NULL;
  514. LPWSTR *pwszCALocation=NULL;
  515. LPWSTR *pwszCADisplayName=NULL;
  516. //init
  517. memset(&SelectCAInfo, 0, sizeof(SELECT_CA_INFO));
  518. memset(&CAContext, 0, sizeof(CRYPTUI_CA_CONTEXT));
  519. //check the input parameter
  520. if(NULL==pCryptUISelectCA)
  521. goto InvalidArgErr;
  522. if(sizeof(CRYPTUI_SELECT_CA_STRUCT) != pCryptUISelectCA->dwSize)
  523. goto InvalidArgErr;
  524. if (!WizardInit())
  525. {
  526. goto TraceErr;
  527. }
  528. //either user supply known CAs or request us to retrieve info from the network
  529. if( (0== (pCryptUISelectCA->dwFlags & (CRYPTUI_DLG_SELECT_CA_FROM_NETWORK))) &&
  530. (0 == pCryptUISelectCA->cCAContext) )
  531. goto InvalidArgErr;
  532. //set up the private data
  533. SelectCAInfo.pCAStruct=pCryptUISelectCA;
  534. SelectCAInfo.idsMsg=IDS_CA_SELECT_TITLE;
  535. SelectCAInfo.fUseInitSelect=FALSE;
  536. SelectCAInfo.dwInitSelect=0;
  537. SelectCAInfo.pSelectedCAContext=NULL;
  538. SelectCAInfo.iOrgCA=-1;
  539. SelectCAInfo.rgdwSortParam[0]=SORT_COLUMN_CA_NAME | SORT_COLUMN_ASCEND;
  540. SelectCAInfo.rgdwSortParam[1]=SORT_COLUMN_CA_LOCATION | SORT_COLUMN_DESCEND;
  541. //get all the CA available from the DS if requested
  542. if(CRYPTUI_DLG_SELECT_CA_FROM_NETWORK & (pCryptUISelectCA->dwFlags))
  543. {
  544. //get all the availabe CAs from the network
  545. if((!CAUtilRetrieveCAFromCertType(
  546. NULL,
  547. NULL,
  548. FALSE,
  549. pCryptUISelectCA->dwFlags,
  550. &dwNTCACount,
  551. &pwszCALocation,
  552. &pwszCAName)) && (0==pCryptUISelectCA->cCAContext))
  553. goto TraceErr;
  554. //build up the CA's display name list based on the CA name
  555. pwszCADisplayName = (LPWSTR *)WizardAlloc(sizeof(LPWSTR) * dwNTCACount);
  556. if(NULL == pwszCADisplayName)
  557. goto MemoryErr;
  558. memset(pwszCADisplayName, 0, sizeof(LPWSTR) * dwNTCACount);
  559. for(dwIndex=0; dwIndex < dwNTCACount; dwIndex++)
  560. {
  561. if(CRYPTUI_DLG_SELECT_CA_USE_DN & pCryptUISelectCA->dwFlags)
  562. {
  563. //use the CA name
  564. pwszCADisplayName[dwIndex]=WizardAllocAndCopyWStr(pwszCAName[dwIndex]);
  565. if(NULL == pwszCADisplayName[dwIndex])
  566. goto MemoryErr;
  567. }
  568. else
  569. {
  570. if(!CAUtilGetCADisplayName(
  571. (CRYPTUI_DLG_SELECT_CA_LOCAL_MACHINE_ENUMERATION & pCryptUISelectCA->dwFlags) ? CA_FIND_LOCAL_SYSTEM:0,
  572. pwszCAName[dwIndex],
  573. &(pwszCADisplayName[dwIndex])))
  574. {
  575. //use the CA name if there is no display name
  576. pwszCADisplayName[dwIndex]=WizardAllocAndCopyWStr(pwszCAName[dwIndex]);
  577. if(NULL == pwszCADisplayName[dwIndex])
  578. goto MemoryErr;
  579. }
  580. }
  581. }
  582. //add all the CAs
  583. SelectCAInfo.prgCAContext=(PCRYPTUI_CA_CONTEXT *)WizardAlloc(
  584. sizeof(PCRYPTUI_CA_CONTEXT) * dwNTCACount);
  585. if(NULL == SelectCAInfo.prgCAContext)
  586. goto MemoryErr;
  587. //memset
  588. memset(SelectCAInfo.prgCAContext, 0, sizeof(PCRYPTUI_CA_CONTEXT) * dwNTCACount);
  589. //add the count
  590. SelectCAInfo.dwCACount = 0;
  591. for(dwIndex=0; dwIndex <dwNTCACount; dwIndex++)
  592. {
  593. //query user for whether to add the CA to the list
  594. CAContext.dwSize=sizeof(CRYPTUI_CA_CONTEXT);
  595. CAContext.pwszCAName=pwszCAName[dwIndex];
  596. CAContext.pwszCAMachineName=pwszCALocation[dwIndex];
  597. fInitSelected=FALSE;
  598. if(pCryptUISelectCA->pSelectCACallback)
  599. {
  600. if(!((pCryptUISelectCA->pSelectCACallback)(
  601. &CAContext,
  602. &fInitSelected,
  603. pCryptUISelectCA->pvCallbackData)))
  604. continue;
  605. }
  606. SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]=(PCRYPTUI_CA_CONTEXT)WizardAlloc(
  607. sizeof(CRYPTUI_CA_CONTEXT));
  608. if(NULL==SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount])
  609. goto MemoryErr;
  610. //memset
  611. memset(SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount], 0, sizeof(CRYPTUI_CA_CONTEXT));
  612. SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]->dwSize=sizeof(CRYPTUI_CA_CONTEXT);
  613. SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]->pwszCAName=(LPCWSTR)WizardAllocAndCopyWStr(
  614. pwszCADisplayName[dwIndex]);
  615. SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]->pwszCAMachineName=(LPCWSTR)WizardAllocAndCopyWStr(
  616. pwszCALocation[dwIndex]);
  617. //make sure we have the correct information
  618. if((NULL==SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]->pwszCAName) ||
  619. (NULL==SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount]->pwszCAMachineName)
  620. )
  621. goto TraceErr;
  622. //mark the initial selected CA
  623. if(fInitSelected)
  624. {
  625. SelectCAInfo.fUseInitSelect=TRUE;
  626. SelectCAInfo.dwInitSelect=SelectCAInfo.dwCACount;
  627. }
  628. //add the count of the CA
  629. (SelectCAInfo.dwCACount)++;
  630. }
  631. }
  632. //add the additional CA contexts
  633. if(pCryptUISelectCA->cCAContext)
  634. {
  635. SelectCAInfo.prgCAContext=(PCRYPTUI_CA_CONTEXT *)WizardRealloc(
  636. SelectCAInfo.prgCAContext,
  637. sizeof(PCRYPTUI_CA_CONTEXT) * (dwNTCACount + pCryptUISelectCA->cCAContext));
  638. if(NULL == SelectCAInfo.prgCAContext)
  639. goto MemoryErr;
  640. //memset
  641. memset(SelectCAInfo.prgCAContext + dwNTCACount,
  642. 0,
  643. sizeof(PCRYPTUI_CA_CONTEXT) * (pCryptUISelectCA->cCAContext));
  644. //copy the CA contexts
  645. for(dwIndex=0; dwIndex <pCryptUISelectCA->cCAContext; dwIndex++)
  646. {
  647. //query user for whether to add the CA to the list
  648. CAContext.dwSize=sizeof(CRYPTUI_CA_CONTEXT);
  649. CAContext.pwszCAName=(pCryptUISelectCA->rgCAContext)[dwIndex]->pwszCAName;
  650. CAContext.pwszCAMachineName=(pCryptUISelectCA->rgCAContext)[dwIndex]->pwszCAMachineName;
  651. fInitSelected=FALSE;
  652. if(pCryptUISelectCA->pSelectCACallback)
  653. {
  654. if(!((pCryptUISelectCA->pSelectCACallback)(
  655. &CAContext,
  656. &fInitSelected,
  657. pCryptUISelectCA->pvCallbackData)))
  658. continue;
  659. }
  660. //make sure the CA is not already in the list
  661. fFound=FALSE;
  662. for(dwSearchIndex=0; dwSearchIndex < SelectCAInfo.dwCACount; dwSearchIndex++)
  663. {
  664. if((0==_wcsicmp(CAContext.pwszCAName, (SelectCAInfo.prgCAContext)[dwSearchIndex]->pwszCAName)) &&
  665. (0==_wcsicmp(CAContext.pwszCAMachineName, (SelectCAInfo.prgCAContext)[dwSearchIndex]->pwszCAMachineName))
  666. )
  667. {
  668. fFound=TRUE;
  669. break;
  670. }
  671. }
  672. //do not need to include the CA since it is already in the list
  673. if(TRUE==fFound)
  674. continue;
  675. if(!CopyCAContext((PCRYPTUI_CA_CONTEXT)(pCryptUISelectCA->rgCAContext[dwIndex]),
  676. &(SelectCAInfo.prgCAContext[SelectCAInfo.dwCACount])))
  677. goto TraceErr;
  678. //mark the initial selected CA
  679. if(fInitSelected)
  680. {
  681. SelectCAInfo.fUseInitSelect=TRUE;
  682. SelectCAInfo.dwInitSelect=SelectCAInfo.dwCACount;
  683. }
  684. //increase the count
  685. (SelectCAInfo.dwCACount)++;
  686. }
  687. }
  688. //call the dialog box
  689. if (DialogBoxParamU(
  690. g_hmodThisDll,
  691. (LPCWSTR)MAKEINTRESOURCE(IDD_SELECTCA_DIALOG),
  692. (pCryptUISelectCA->hwndParent != NULL) ? pCryptUISelectCA->hwndParent : GetDesktopWindow(),
  693. SelectCADialogProc,
  694. (LPARAM) &SelectCAInfo) != -1)
  695. {
  696. SetLastError(0);
  697. }
  698. //map the CA's display name to its real name
  699. if(CRYPTUI_DLG_SELECT_CA_FROM_NETWORK & (pCryptUISelectCA->dwFlags))
  700. {
  701. if(SelectCAInfo.pSelectedCAContext)
  702. {
  703. //if the selection match with what the caller has supplied,
  704. //we leave it alone
  705. for(dwIndex=0; dwIndex <pCryptUISelectCA->cCAContext; dwIndex++)
  706. {
  707. if(0 == wcscmp((SelectCAInfo.pSelectedCAContext)->pwszCAName,
  708. (pCryptUISelectCA->rgCAContext)[dwIndex]->pwszCAName))
  709. {
  710. if(0==wcscmp((SelectCAInfo.pSelectedCAContext)->pwszCAMachineName,
  711. (pCryptUISelectCA->rgCAContext)[dwIndex]->pwszCAMachineName))
  712. break;
  713. }
  714. }
  715. //now that we did not find a match
  716. if(dwIndex == pCryptUISelectCA->cCAContext)
  717. {
  718. for(dwIndex=0; dwIndex <dwNTCACount; dwIndex++)
  719. {
  720. if(0 == wcscmp((SelectCAInfo.pSelectedCAContext)->pwszCAMachineName,
  721. pwszCALocation[dwIndex]))
  722. {
  723. if(0==wcscmp((SelectCAInfo.pSelectedCAContext)->pwszCAName,
  724. pwszCADisplayName[dwIndex]))
  725. {
  726. WizardFree((LPWSTR)((SelectCAInfo.pSelectedCAContext)->pwszCAName));
  727. (SelectCAInfo.pSelectedCAContext)->pwszCAName = NULL;
  728. (SelectCAInfo.pSelectedCAContext)->pwszCAName = WizardAllocAndCopyWStr(
  729. pwszCAName[dwIndex]);
  730. if(NULL == (SelectCAInfo.pSelectedCAContext)->pwszCAName)
  731. goto MemoryErr;
  732. //we find a match
  733. break;
  734. }
  735. }
  736. }
  737. }
  738. }
  739. }
  740. fResult=TRUE;
  741. CommonReturn:
  742. //free the CA list
  743. if(SelectCAInfo.prgCAContext)
  744. {
  745. for(dwIndex=0; dwIndex<SelectCAInfo.dwCACount; dwIndex++)
  746. {
  747. if(SelectCAInfo.prgCAContext[dwIndex])
  748. CryptUIDlgFreeCAContext(SelectCAInfo.prgCAContext[dwIndex]);
  749. }
  750. WizardFree(SelectCAInfo.prgCAContext);
  751. }
  752. //free the CA names array
  753. if(pwszCAName)
  754. {
  755. for(dwIndex=0; dwIndex<dwNTCACount; dwIndex++)
  756. {
  757. if(pwszCAName[dwIndex])
  758. WizardFree(pwszCAName[dwIndex]);
  759. }
  760. WizardFree(pwszCAName);
  761. }
  762. //free the CA location array
  763. if(pwszCADisplayName)
  764. {
  765. for(dwIndex=0; dwIndex<dwNTCACount; dwIndex++)
  766. {
  767. if(pwszCADisplayName[dwIndex])
  768. WizardFree(pwszCADisplayName[dwIndex]);
  769. }
  770. WizardFree(pwszCADisplayName);
  771. }
  772. //free the CA Display name array
  773. if(pwszCALocation)
  774. {
  775. for(dwIndex=0; dwIndex<dwNTCACount; dwIndex++)
  776. {
  777. if(pwszCALocation[dwIndex])
  778. WizardFree(pwszCALocation[dwIndex]);
  779. }
  780. WizardFree(pwszCALocation);
  781. }
  782. return (SelectCAInfo.pSelectedCAContext);
  783. ErrorReturn:
  784. if(SelectCAInfo.pSelectedCAContext)
  785. {
  786. CryptUIDlgFreeCAContext(SelectCAInfo.pSelectedCAContext);
  787. SelectCAInfo.pSelectedCAContext=NULL;
  788. }
  789. fResult=FALSE;
  790. goto CommonReturn;
  791. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  792. TRACE_ERROR(TraceErr);
  793. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  794. }
  795. //--------------------------------------------------------------
  796. // CryptUIDlgFreeCAContext
  797. //--------------------------------------------------------------
  798. BOOL
  799. WINAPI
  800. CryptUIDlgFreeCAContext(
  801. IN PCCRYPTUI_CA_CONTEXT pCAContext
  802. )
  803. {
  804. if(pCAContext)
  805. {
  806. if(pCAContext->pwszCAName)
  807. WizardFree((LPWSTR)(pCAContext->pwszCAName));
  808. if(pCAContext->pwszCAMachineName)
  809. WizardFree((LPWSTR)(pCAContext->pwszCAMachineName));
  810. WizardFree((PCRYPTUI_CA_CONTEXT)pCAContext);
  811. }
  812. return TRUE;
  813. }