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.

603 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: catalog.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <dbgdef.h>
  12. extern HINSTANCE HinstDll;
  13. extern HMODULE HmodRichEdit;
  14. static const HELPMAP helpmap[] = {
  15. {IDC_CATALOG_ENTRY_LIST, IDH_CATALOG_ENTRY_LIST},
  16. {IDC_CATALOG_ENTRY_DETAIL_LIST, IDH_CATALOG_ENTRY_DETAILS},
  17. {IDC_CATALOG_ENTRY_DETAIL_EDIT, IDH_CATALOG_ENTRY_DETAIL_DISPLAY}
  18. };
  19. //////////////////////////////////////////////////////////////////////////////////////
  20. //
  21. //////////////////////////////////////////////////////////////////////////////////////
  22. #define INDENT_STRING L" "
  23. #define TERMINATING_CHAR L""
  24. static void DisplayCatalogEntryValues(HWND hWndListView, PCTL_ENTRY pctlEntry)
  25. {
  26. LPWSTR pwszText;
  27. WCHAR szFieldText[_MAX_PATH]; // only used for calls to LoadString only
  28. WCHAR szValueText[CRYPTUI_MAX_STRING_SIZE];
  29. LV_ITEMW lvI;
  30. int index = 0;
  31. BYTE hash[20];
  32. DWORD hashSize = ARRAYSIZE(hash);
  33. BOOL fAddRows;
  34. DWORD i;
  35. SPC_INDIRECT_DATA_CONTENT *pIndirectData;
  36. DWORD cbIndirectData;
  37. CAT_NAMEVALUE *pNameValue;
  38. DWORD cbNameValue;
  39. #if (1) //DSIE: Bug 477237.
  40. ListView_DeleteAllItems(hWndListView);
  41. #endif
  42. //
  43. // set up the fields in the list view item struct that don't change from item to item
  44. //
  45. memset(&lvI, 0, sizeof(lvI));
  46. lvI.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  47. lvI.lParam = NULL;
  48. lvI.state = 0;
  49. lvI.stateMask = 0;
  50. lvI.iSubItem = 0;
  51. //
  52. // if the rows have already been added, then don't add them again, just
  53. // set the text in the subitem
  54. //
  55. fAddRows = ListView_GetItemCount(hWndListView) == 0;
  56. //
  57. // tag
  58. //
  59. if (NULL != (pwszText = (LPWSTR) malloc(pctlEntry->SubjectIdentifier.cbData)))
  60. {
  61. #if (0) // DSIE: Bug 331214.
  62. wcscpy(pwszText, (LPWSTR) pctlEntry->SubjectIdentifier.pbData);
  63. #else
  64. memcpy(pwszText, pctlEntry->SubjectIdentifier.pbData, pctlEntry->SubjectIdentifier.cbData);
  65. #endif
  66. LoadStringU(HinstDll, IDS_TAG, szFieldText, ARRAYSIZE(szFieldText));
  67. lvI.iItem = index++;
  68. lvI.pszText = szFieldText;
  69. lvI.cchTextMax = wcslen(szFieldText);
  70. ModifyOrInsertRow(
  71. hWndListView,
  72. &lvI,
  73. pwszText,
  74. pwszText,
  75. fAddRows,
  76. FALSE);
  77. }
  78. //
  79. // indirect data attribute
  80. //
  81. for (i=0; i<pctlEntry->cAttribute; i++)
  82. {
  83. if (strcmp(pctlEntry->rgAttribute[i].pszObjId, SPC_INDIRECT_DATA_OBJID) != 0)
  84. {
  85. continue;
  86. }
  87. pIndirectData = NULL;
  88. cbIndirectData = 0;
  89. //
  90. // decode the indirect data
  91. //
  92. if (!CryptDecodeObject(
  93. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  94. SPC_INDIRECT_DATA_CONTENT_STRUCT,
  95. pctlEntry->rgAttribute[i].rgValue[0].pbData,
  96. pctlEntry->rgAttribute[i].rgValue[0].cbData,
  97. 0,
  98. NULL,
  99. &cbIndirectData))
  100. {
  101. continue;
  102. }
  103. if (NULL == (pIndirectData = (SPC_INDIRECT_DATA_CONTENT *) malloc(cbIndirectData)))
  104. {
  105. continue;
  106. }
  107. if (!CryptDecodeObject(
  108. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  109. SPC_INDIRECT_DATA_CONTENT_STRUCT,
  110. pctlEntry->rgAttribute[i].rgValue[0].pbData,
  111. pctlEntry->rgAttribute[i].rgValue[0].cbData,
  112. 0,
  113. pIndirectData,
  114. &cbIndirectData))
  115. {
  116. free(pIndirectData);
  117. continue;
  118. }
  119. //
  120. // thumbprint algorithm
  121. //
  122. if (MyGetOIDInfo(szValueText, ARRAYSIZE(szValueText), pIndirectData->DigestAlgorithm.pszObjId) &&
  123. (NULL != (pwszText = AllocAndCopyWStr(szValueText))))
  124. {
  125. LoadStringU(HinstDll, IDS_THUMBPRINT_ALGORITHM, szFieldText, ARRAYSIZE(szFieldText));
  126. lvI.pszText = szFieldText;
  127. lvI.cchTextMax = wcslen(szFieldText);
  128. lvI.iItem = index++;
  129. ModifyOrInsertRow(
  130. hWndListView,
  131. &lvI,
  132. pwszText,
  133. pwszText,
  134. fAddRows,
  135. FALSE);
  136. }
  137. //
  138. // thumbprint
  139. //
  140. if (FormatMemBufToString(
  141. &pwszText,
  142. pIndirectData->Digest.pbData,
  143. pIndirectData->Digest.cbData))
  144. {
  145. LoadStringU(HinstDll, IDS_THUMBPRINT, szFieldText, ARRAYSIZE(szFieldText));
  146. lvI.iItem = index++;
  147. lvI.pszText = szFieldText;
  148. lvI.cchTextMax = wcslen(szFieldText);
  149. ModifyOrInsertRow(
  150. hWndListView,
  151. &lvI,
  152. pwszText,
  153. pwszText,
  154. fAddRows,
  155. TRUE);
  156. }
  157. free(pIndirectData);
  158. }
  159. //
  160. // name/value pair attributes
  161. //
  162. for (i=0; i<pctlEntry->cAttribute; i++)
  163. {
  164. if (strcmp(pctlEntry->rgAttribute[i].pszObjId, CAT_NAMEVALUE_OBJID) != 0)
  165. {
  166. continue;
  167. }
  168. pNameValue = NULL;
  169. cbNameValue = 0;
  170. //
  171. // decode the name/value
  172. //
  173. if (!CryptDecodeObject(
  174. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  175. CAT_NAMEVALUE_STRUCT,
  176. pctlEntry->rgAttribute[i].rgValue[0].pbData,
  177. pctlEntry->rgAttribute[i].rgValue[0].cbData,
  178. 0,
  179. NULL,
  180. &cbNameValue))
  181. {
  182. continue;
  183. }
  184. if (NULL == (pNameValue = (CAT_NAMEVALUE *) malloc(cbNameValue)))
  185. {
  186. continue;
  187. }
  188. if (!CryptDecodeObject(
  189. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  190. CAT_NAMEVALUE_STRUCT,
  191. pctlEntry->rgAttribute[i].rgValue[0].pbData,
  192. pctlEntry->rgAttribute[i].rgValue[0].cbData,
  193. 0,
  194. pNameValue,
  195. &cbNameValue))
  196. {
  197. free(pNameValue);
  198. continue;
  199. }
  200. if (NULL != (pwszText = (LPWSTR) malloc(pNameValue->Value.cbData)))
  201. {
  202. #if (0) // DSIE: Bug 331214.
  203. wcscpy(pwszText, (LPWSTR) pNameValue->Value.pbData);
  204. #else
  205. memcpy(pwszText, pNameValue->Value.pbData, pNameValue->Value.cbData);
  206. #endif
  207. lvI.pszText = pNameValue->pwszTag;
  208. lvI.cchTextMax = wcslen(lvI.pszText);
  209. lvI.iItem = index++;
  210. ModifyOrInsertRow(
  211. hWndListView,
  212. &lvI,
  213. pwszText,
  214. pwszText,
  215. fAddRows,
  216. FALSE);
  217. }
  218. free(pNameValue);
  219. }
  220. }
  221. //////////////////////////////////////////////////////////////////////////////////////
  222. //
  223. //////////////////////////////////////////////////////////////////////////////////////
  224. static void AddEntriesToList(HWND hWndListView, CTL_VIEW_HELPER *pviewhelp)
  225. {
  226. LV_ITEMW lvI;
  227. DWORD i;
  228. int index = 0;
  229. PCCTL_CONTEXT pctl;
  230. pctl = pviewhelp->pcvctl->pCTLContext;
  231. //
  232. // set up the fields in the list view item struct that don't change from item to item
  233. //
  234. lvI.mask = LVIF_TEXT | LVIF_STATE;
  235. lvI.state = 0;
  236. lvI.stateMask = 0;
  237. lvI.iSubItem = 0;
  238. lvI.lParam = (LPARAM)NULL;
  239. //
  240. // loop for each entry and add it to the list
  241. //
  242. for (i=0; i<pctl->pCtlInfo->cCTLEntry; i++)
  243. {
  244. lvI.iItem = index++;
  245. #if (0) // DSIE: Bug 331214.
  246. lvI.pszText = (LPWSTR) pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.pbData;
  247. lvI.cchTextMax = pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.cbData - sizeof(WCHAR);
  248. ListView_InsertItemU(hWndListView, &lvI);
  249. #else
  250. // Need to align data because this can generate alignment fault under ia64.
  251. WCHAR * pwszText = (WCHAR *) malloc(pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.cbData);
  252. if (pwszText)
  253. {
  254. memcpy(pwszText,
  255. pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.pbData,
  256. pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.cbData);
  257. lvI.pszText = pwszText;
  258. lvI.cchTextMax = pctl->pCtlInfo->rgCTLEntry[i].SubjectIdentifier.cbData - sizeof(WCHAR);
  259. ListView_InsertItemU(hWndListView, &lvI);
  260. free(pwszText);
  261. }
  262. #endif
  263. }
  264. }
  265. //////////////////////////////////////////////////////////////////////////////////////
  266. //
  267. //////////////////////////////////////////////////////////////////////////////////////
  268. INT_PTR APIENTRY ViewPageCatalogEntries(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  269. {
  270. DWORD i;
  271. PROPSHEETPAGE *ps;
  272. PCCTL_CONTEXT pctl;
  273. CTL_VIEW_HELPER *pviewhelp;
  274. HWND hWndListView;
  275. HWND hwnd;
  276. LV_COLUMNW lvC;
  277. WCHAR szText[1024];
  278. WCHAR szCompareText[CRYPTUI_MAX_STRING_SIZE];
  279. PCTL_INFO pCtlInfo;
  280. PCCERT_CONTEXT pCertContext;
  281. LPWSTR pwszText;
  282. int listIndex;
  283. LVITEMW lvI;
  284. LPNMLISTVIEW pnmv;
  285. NMLISTVIEW nmv;
  286. switch ( msg ) {
  287. case WM_INITDIALOG:
  288. //
  289. // save the pviewhelp struct in DWL_USER so it can always be accessed
  290. //
  291. ps = (PROPSHEETPAGE *) lParam;
  292. pviewhelp = (CTL_VIEW_HELPER *) (ps->lParam);
  293. pctl = pviewhelp->pcvctl->pCTLContext;
  294. SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR) pviewhelp);
  295. pviewhelp->previousSelection = -1;
  296. pviewhelp->currentSelection = -1;
  297. //
  298. // clear the text in the detail edit box
  299. //
  300. CryptUISetRicheditTextW(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_EDIT, L"");
  301. //
  302. // initialize the columns in the list view
  303. //
  304. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  305. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  306. lvC.pszText = szText; // The text for the column.
  307. //
  308. // Add the columns. They are loaded from a string table.
  309. //
  310. lvC.iSubItem = 0;
  311. lvC.cx = 345;
  312. LoadStringU(HinstDll, IDS_TAG, szText, ARRAYSIZE(szText));
  313. if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_LIST), 0, &lvC) == -1)
  314. {
  315. return FALSE;
  316. }
  317. lvC.iSubItem = 0;
  318. lvC.cx = 121;
  319. LoadStringU(HinstDll, IDS_FIELD, szText, ARRAYSIZE(szText));
  320. if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST), 0, &lvC) == -1)
  321. {
  322. return FALSE;
  323. }
  324. lvC.cx = 200;
  325. LoadStringU(HinstDll, IDS_VALUE, szText, ARRAYSIZE(szText));
  326. if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST), 1, &lvC) == -1)
  327. {
  328. return FALSE;
  329. }
  330. //
  331. // set the styles in the list views so that they highlight an entire line and
  332. // so they alway show their selection
  333. //
  334. SendDlgItemMessageA(
  335. hwndDlg,
  336. IDC_CATALOG_ENTRY_LIST,
  337. LVM_SETEXTENDEDLISTVIEWSTYLE,
  338. 0,
  339. LVS_EX_FULLROWSELECT);
  340. SendDlgItemMessageA(
  341. hwndDlg,
  342. IDC_CATALOG_ENTRY_DETAIL_LIST,
  343. LVM_SETEXTENDEDLISTVIEWSTYLE,
  344. 0,
  345. LVS_EX_FULLROWSELECT);
  346. //
  347. // add all the certificates to the certificate list box
  348. //
  349. AddEntriesToList(GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_LIST), pviewhelp);
  350. return TRUE;
  351. case WM_NOTIFY:
  352. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  353. pctl = pviewhelp->pcvctl->pCTLContext;
  354. pCtlInfo = pctl->pCtlInfo;
  355. switch (((NMHDR FAR *) lParam)->code)
  356. {
  357. case PSN_SETACTIVE:
  358. break;
  359. case PSN_APPLY:
  360. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  361. break;
  362. case PSN_KILLACTIVE:
  363. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  364. return TRUE;
  365. case PSN_RESET:
  366. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  367. break;
  368. case PSN_HELP:
  369. if (FIsWin95) {
  370. //WinHelpA(hwndDlg, (LPSTR) pviewhelp->pcvctl->szHelpFileName,
  371. // HELP_CONTEXT, pviewhelp->pcvctl->dwHelpId);
  372. }
  373. else {
  374. //WinHelpW(hwndDlg, pviewhelp->pcvctl->szHelpFileName, HELP_CONTEXT,
  375. // pviewhelp->pcvctl->dwHelpId);
  376. }
  377. return TRUE;
  378. case LVN_ITEMCHANGING:
  379. pnmv = (LPNMLISTVIEW) lParam;
  380. switch(((NMHDR FAR *) lParam)->idFrom)
  381. {
  382. case IDC_CATALOG_ENTRY_DETAIL_LIST:
  383. hWndListView = GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST);
  384. if (pnmv->uNewState & LVIS_SELECTED)
  385. {
  386. pviewhelp->currentSelection = pnmv->iItem;
  387. DisplayHelperTextInEdit(
  388. GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST),
  389. hwndDlg,
  390. IDC_CATALOG_ENTRY_DETAIL_EDIT,
  391. pnmv->iItem);
  392. }
  393. break;
  394. case IDC_CATALOG_ENTRY_LIST:
  395. if (pnmv->uNewState & LVIS_SELECTED)
  396. {
  397. hWndListView = GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_LIST);
  398. DisplayCatalogEntryValues(
  399. GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST),
  400. &(pctl->pCtlInfo->rgCTLEntry[pnmv->iItem]));
  401. //
  402. // clear the text in the detail edit box
  403. //
  404. CryptUISetRicheditTextW(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_EDIT, L"");
  405. DisplayHelperTextInEdit(
  406. GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST),
  407. hwndDlg,
  408. IDC_CATALOG_ENTRY_DETAIL_EDIT,
  409. pviewhelp->currentSelection);
  410. }
  411. break;
  412. }
  413. return TRUE;
  414. case NM_CLICK:
  415. pnmv = (LPNMLISTVIEW) lParam;
  416. switch (((NMHDR FAR *) lParam)->idFrom)
  417. {
  418. case IDC_CATALOG_ENTRY_LIST:
  419. // FALL THROUGH!! - do this so everything gets updated
  420. // break;
  421. case IDC_CATALOG_ENTRY_DETAIL_LIST:
  422. ListView_SetItemState(
  423. GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST),
  424. pviewhelp->currentSelection,
  425. LVIS_SELECTED | LVIS_FOCUSED,
  426. LVIS_SELECTED | LVIS_FOCUSED);
  427. DisplayHelperTextInEdit(
  428. GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST),
  429. hwndDlg,
  430. IDC_CATALOG_ENTRY_DETAIL_EDIT,
  431. pviewhelp->currentSelection);
  432. break;
  433. }
  434. break;
  435. case NM_SETFOCUS:
  436. switch (((NMHDR FAR *) lParam)->idFrom)
  437. {
  438. case IDC_CATALOG_ENTRY_LIST:
  439. hWndListView = GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_LIST);
  440. if ((ListView_GetItemCount(hWndListView) != 0) &&
  441. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  442. {
  443. memset(&lvI, 0, sizeof(lvI));
  444. lvI.mask = LVIF_STATE;
  445. lvI.iItem = 0;
  446. lvI.state = LVIS_FOCUSED;
  447. lvI.stateMask = LVIS_FOCUSED;
  448. ListView_SetItem(hWndListView, &lvI);
  449. }
  450. break;
  451. case IDC_CATALOG_ENTRY_DETAIL_LIST:
  452. hWndListView = GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST);
  453. if ((ListView_GetItemCount(hWndListView) != 0) &&
  454. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  455. {
  456. memset(&lvI, 0, sizeof(lvI));
  457. lvI.mask = LVIF_STATE;
  458. lvI.iItem = 0;
  459. lvI.state = LVIS_FOCUSED;
  460. lvI.stateMask = LVIS_FOCUSED;
  461. ListView_SetItem(hWndListView, &lvI);
  462. }
  463. break;
  464. }
  465. break;
  466. }
  467. break;
  468. case WM_DESTROY:
  469. //
  470. // get all the items in the list view and free the lParam
  471. // associated with each of them (lParam is the helper sruct)
  472. //
  473. hWndListView = GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST);
  474. memset(&lvI, 0, sizeof(lvI));
  475. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  476. lvI.mask = LVIF_PARAM;
  477. while (lvI.iItem >= 0)
  478. {
  479. if (ListView_GetItemU(hWndListView, &lvI))
  480. {
  481. FreeListDisplayHelper((PLIST_DISPLAY_HELPER) lvI.lParam);
  482. }
  483. lvI.iItem--;
  484. }
  485. break;
  486. case WM_HELP:
  487. case WM_CONTEXTMENU:
  488. if (msg == WM_HELP)
  489. {
  490. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  491. }
  492. else
  493. {
  494. hwnd = (HWND) wParam;
  495. }
  496. if ((hwnd != GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_LIST)) &&
  497. (hwnd != GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_LIST)) &&
  498. (hwnd != GetDlgItem(hwndDlg, IDC_CATALOG_ENTRY_DETAIL_EDIT)))
  499. {
  500. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  501. return TRUE;
  502. }
  503. else
  504. {
  505. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmap);
  506. }
  507. }
  508. return FALSE;
  509. }