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.

1167 lines
38 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: ctlgen.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <dbgdef.h>
  12. extern HINSTANCE HinstDll;
  13. extern HMODULE HmodRichEdit;
  14. static const HELPMAP CTLHelpmap[] = {
  15. {IDC_CTL_GENERAL_ITEM_LIST, IDH_CTLVIEW_GENERAL_ITEM_LIST},
  16. {IDC_CTL_GENERAL_DETAIL_EDIT, IDH_CTLVIEW_GENERAL_ITEM_EDIT},
  17. {IDC_CTL_GENERAL_VIEW_BUTTON, IDH_CTLVIEW_GENERAL_VIEWSIGNATURE_BUTTON}
  18. };
  19. static const HELPMAP CatHelpmap[] = {
  20. {IDC_CTL_GENERAL_ITEM_LIST, IDH_CATALOGVIEW_GENERAL_ITEM_LIST},
  21. {IDC_CTL_GENERAL_DETAIL_EDIT, IDH_CATALOGVIEW_GENERAL_ITEM_EDIT},
  22. {IDC_CTL_GENERAL_VIEW_BUTTON, IDH_CATALOGVIEW_GENERAL_VIEWSIGNATURE_BUTTON}
  23. };
  24. const WCHAR RgwchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
  25. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  26. #define SELPALMODE TRUE
  27. //////////////////////////////////////////////////////////////////////////////////////
  28. // This function will take a HWND for a list view and a certinfo struct and display
  29. // all the V1 fields of the cert in the list view
  30. //////////////////////////////////////////////////////////////////////////////////////
  31. static void DisplayV1Fields(HWND hWndListView, PCTL_INFO pCtlInfo, DWORD *index)
  32. {
  33. LPWSTR pwszText;
  34. WCHAR szFieldText[_MAX_PATH]; // used for calls to LoadString only
  35. LV_ITEMW lvI;
  36. DWORD i;
  37. int sequenceNumIndex;
  38. FILETIME tempFileTime;
  39. char szVersion[32];
  40. DWORD dwNumSpaces;
  41. DWORD dwNumCharsInserted;
  42. //
  43. // set up the fields in the list view item struct that don't change from item to item
  44. //
  45. lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  46. lvI.state = 0;
  47. lvI.stateMask = 0;
  48. lvI.pszText = szFieldText;
  49. lvI.iSubItem = 0;
  50. lvI.iImage = IMAGE_V1;
  51. lvI.lParam = (LPARAM)NULL;
  52. //
  53. // version
  54. //
  55. lvI.iItem = (*index)++;
  56. LoadStringU(HinstDll, IDS_ADV_VERSION, szFieldText, ARRAYSIZE(szFieldText));
  57. lvI.cchTextMax = wcslen(szFieldText);
  58. wsprintfA(szVersion, "V%d", pCtlInfo->dwVersion+1);
  59. if (NULL != (pwszText = CertUIMkWStr(szVersion)))
  60. {
  61. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  62. ListView_InsertItemU(hWndListView, &lvI);
  63. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  64. }
  65. //
  66. // Subject Usage
  67. //
  68. lvI.iItem = (*index)++;
  69. LoadStringU(HinstDll, IDS_ADV_SUBJECTUSAGE, szFieldText, ARRAYSIZE(szFieldText));
  70. lvI.cchTextMax = wcslen(szFieldText);
  71. if (NULL != (pwszText = FormatCTLSubjectUsage(&(pCtlInfo->SubjectUsage), TRUE)))
  72. {
  73. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  74. ListView_InsertItemU(hWndListView, &lvI);
  75. if (NULL != (pwszText = FormatCTLSubjectUsage(&(pCtlInfo->SubjectUsage), FALSE)))
  76. {
  77. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  78. free(pwszText);
  79. }
  80. }
  81. //
  82. // list identifier
  83. //
  84. if (pCtlInfo->ListIdentifier.cbData != 0)
  85. {
  86. if(FormatMemBufToString(&pwszText, pCtlInfo->ListIdentifier.pbData, pCtlInfo->ListIdentifier.cbData))
  87. {
  88. lvI.iItem = (*index)++;
  89. LoadStringU(HinstDll, IDS_ADV_LISTIDENTIFIER, szFieldText, ARRAYSIZE(szFieldText));
  90. lvI.cchTextMax = wcslen(szFieldText);
  91. lvI.lParam = (LPARAM) MakeListDisplayHelper(TRUE, pwszText, NULL, 0);
  92. ListView_InsertItemU(hWndListView, &lvI);
  93. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  94. }
  95. }
  96. //
  97. // sequence number
  98. //
  99. if (pCtlInfo->SequenceNumber.cbData != 0)
  100. {
  101. dwNumSpaces = (pCtlInfo->SequenceNumber.cbData * 2) / 4;
  102. pwszText = (LPWSTR) malloc(((pCtlInfo->SequenceNumber.cbData * 2) + dwNumSpaces + 1) * sizeof(WCHAR));
  103. if (pwszText != NULL)
  104. {
  105. lvI.iItem = (*index)++;
  106. LoadStringU(HinstDll, IDS_ADV_SEQUENCENUMBER, szFieldText, ARRAYSIZE(szFieldText));
  107. lvI.cchTextMax = wcslen(szFieldText);
  108. sequenceNumIndex = pCtlInfo->SequenceNumber.cbData - 1;
  109. i = 0;
  110. dwNumCharsInserted = 0;
  111. while (sequenceNumIndex >= 0)
  112. {
  113. //
  114. // insert a space if needed
  115. //
  116. if (dwNumCharsInserted == 4)
  117. {
  118. pwszText[i++] = L' ';
  119. dwNumCharsInserted = 0;
  120. }
  121. pwszText[i++] = RgwchHex[(pCtlInfo->SequenceNumber.pbData[sequenceNumIndex] & 0xf0) >> 4];
  122. pwszText[i++] = RgwchHex[pCtlInfo->SequenceNumber.pbData[sequenceNumIndex] & 0x0f];
  123. sequenceNumIndex--;
  124. dwNumCharsInserted += 2;
  125. }
  126. pwszText[i] = 0;
  127. lvI.lParam = (LPARAM) MakeListDisplayHelper(TRUE, pwszText, NULL, 0);
  128. ListView_InsertItemU(hWndListView, &lvI);
  129. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  130. }
  131. }
  132. //
  133. // Effective Data
  134. //
  135. if (FormatDateString(&pwszText, pCtlInfo->ThisUpdate, TRUE, TRUE, hWndListView))
  136. {
  137. lvI.iItem = (*index)++;
  138. LoadStringU(HinstDll, IDS_ADV_THISUPDATE, szFieldText, ARRAYSIZE(szFieldText));
  139. lvI.cchTextMax = wcslen(szFieldText);
  140. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  141. ListView_InsertItemU(hWndListView, &lvI);
  142. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  143. }
  144. //
  145. // Next Update
  146. //
  147. memset(&tempFileTime, 0, sizeof(FILETIME));
  148. if (memcmp(&tempFileTime, &(pCtlInfo->NextUpdate), sizeof(FILETIME)) != 0)
  149. {
  150. if (FormatDateString(&pwszText, pCtlInfo->NextUpdate, TRUE, TRUE, hWndListView))
  151. {
  152. lvI.iItem = (*index)++;
  153. LoadStringU(HinstDll, IDS_ADV_NEXTUPDATE, szFieldText, ARRAYSIZE(szFieldText));
  154. lvI.cchTextMax = wcslen(szFieldText);
  155. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  156. ListView_InsertItemU(hWndListView, &lvI);
  157. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  158. }
  159. }
  160. //
  161. // subject algorithm
  162. //
  163. if (FormatAlgorithmString(&pwszText, &(pCtlInfo->SubjectAlgorithm)))
  164. {
  165. lvI.iItem = (*index)++;
  166. LoadStringU(HinstDll, IDS_ADV_SUBJECTALGORITHM, szFieldText, ARRAYSIZE(szFieldText));
  167. lvI.cchTextMax = wcslen(szFieldText);
  168. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  169. ListView_InsertItemU(hWndListView, &lvI);
  170. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  171. }
  172. }
  173. //////////////////////////////////////////////////////////////////////////////////////
  174. // This function will take a HWND for a list view and a pointer to a cert contexxt and
  175. // display all the properties tagged to the cert in the list view
  176. //////////////////////////////////////////////////////////////////////////////////////
  177. static void DisplayProperties(HWND hWndListView, PCCTL_CONTEXT pctl, DWORD *index)
  178. {
  179. DWORD i;
  180. WCHAR szFieldText[_MAX_PATH]; // used for calls to LoadString only
  181. LPWSTR pwszText;
  182. LV_ITEMW lvI;
  183. BYTE hash[20];
  184. DWORD hashSize = ARRAYSIZE(hash);
  185. DWORD cbText;
  186. PCCRYPT_OID_INFO pThumbprintAlgorithm;
  187. DWORD dwAlgID = CALG_SHA1;
  188. //
  189. // set up the fields in the list view item struct that don't change from item to item
  190. //
  191. lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  192. lvI.state = 0;
  193. lvI.stateMask = 0;
  194. lvI.pszText = szFieldText;
  195. lvI.iSubItem = 0;
  196. lvI.iImage = IMAGE_PROPERTY;
  197. //
  198. // thumbprint algorithm
  199. //
  200. if (NULL != (pThumbprintAlgorithm = CryptFindOIDInfo(
  201. CRYPT_OID_INFO_ALGID_KEY,
  202. &dwAlgID,
  203. CRYPT_HASH_ALG_OID_GROUP_ID)) &&
  204. (NULL != (pwszText = AllocAndCopyWStr(pThumbprintAlgorithm->pwszName))))
  205. {
  206. lvI.iItem = (*index)++;
  207. LoadStringU(HinstDll, IDS_THUMBPRINT_ALGORITHM, szFieldText, ARRAYSIZE(szFieldText));
  208. lvI.cchTextMax = wcslen(szFieldText);
  209. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  210. ListView_InsertItemU(hWndListView, &lvI);
  211. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  212. }
  213. //
  214. // thumbprint
  215. //
  216. CertGetCTLContextProperty(
  217. pctl,
  218. CERT_SHA1_HASH_PROP_ID,
  219. hash,
  220. &hashSize);
  221. if (FormatMemBufToString(&pwszText, hash, ARRAYSIZE(hash)))
  222. {
  223. lvI.iItem = (*index)++;
  224. LoadStringU(HinstDll, IDS_THUMBPRINT, szFieldText, ARRAYSIZE(szFieldText));
  225. lvI.cchTextMax = wcslen(szFieldText);
  226. lvI.lParam = (LPARAM) MakeListDisplayHelper(TRUE, pwszText, NULL, 0);
  227. ListView_InsertItemU(hWndListView, &lvI);
  228. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  229. }
  230. //
  231. // friendly name
  232. //
  233. cbText = 0;
  234. if (CertGetCTLContextProperty( pctl,
  235. CERT_FRIENDLY_NAME_PROP_ID,
  236. NULL,
  237. &cbText) &&
  238. (NULL != (pwszText = (LPWSTR) malloc(cbText))))
  239. {
  240. lvI.iItem = (*index)++;
  241. LoadStringU(HinstDll, IDS_CTL_NAME, szFieldText, ARRAYSIZE(szFieldText));
  242. lvI.cchTextMax = wcslen(szFieldText);
  243. CertGetCTLContextProperty( pctl,
  244. CERT_FRIENDLY_NAME_PROP_ID,
  245. pwszText,
  246. &cbText);
  247. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  248. ListView_InsertItemU(hWndListView, &lvI);
  249. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  250. }
  251. //
  252. // description
  253. //
  254. cbText = 0;
  255. if (CertGetCTLContextProperty( pctl,
  256. CERT_DESCRIPTION_PROP_ID,
  257. NULL,
  258. &cbText) &&
  259. (NULL != (pwszText = (LPWSTR) malloc(cbText))))
  260. {
  261. lvI.iItem = (*index)++;
  262. LoadStringU(HinstDll, IDS_DESCRIPTION, szFieldText, ARRAYSIZE(szFieldText));
  263. lvI.cchTextMax = wcslen(szFieldText);
  264. CertGetCTLContextProperty( pctl,
  265. CERT_DESCRIPTION_PROP_ID,
  266. pwszText,
  267. &cbText);
  268. lvI.lParam = (LPARAM) MakeListDisplayHelper(FALSE, pwszText, NULL, 0);
  269. ListView_InsertItemU(hWndListView, &lvI);
  270. ListView_SetItemTextU(hWndListView, (*index)-1 , 1, pwszText);
  271. }
  272. }
  273. //////////////////////////////////////////////////////////////////////////////////////
  274. //
  275. //////////////////////////////////////////////////////////////////////////////////////
  276. static void GetSignerInfo(CTL_VIEW_HELPER *pviewhelp)
  277. {
  278. HCRYPTMSG hMsg;
  279. DWORD cbEncodedSigner = 0;
  280. BYTE *pbEncodedSigner = NULL;
  281. DWORD cbCertInfo = 0;
  282. CERT_INFO *pCertInfo = NULL;
  283. DWORD chStores = 0;
  284. HCERTSTORE *rghStores = NULL;
  285. CRYPT_PROVIDER_SGNR *pProvSigner = NULL;
  286. CRYPT_PROVIDER_CERT *pProvCert = NULL;
  287. if (!(pviewhelp->hMsg = CryptMsgOpenToDecode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  288. 0,
  289. 0,
  290. 0,
  291. NULL,
  292. NULL)))
  293. {
  294. return;
  295. }
  296. if (!CryptMsgUpdate(pviewhelp->hMsg,
  297. pviewhelp->pcvctl->pCTLContext->pbCtlEncoded,
  298. pviewhelp->pcvctl->pCTLContext->cbCtlEncoded,
  299. TRUE)) // fFinal
  300. {
  301. CryptMsgClose(pviewhelp->hMsg);
  302. pviewhelp->hMsg = NULL;
  303. return;
  304. }
  305. //
  306. // get the encoded signer BLOB
  307. //
  308. CryptMsgGetParam(pviewhelp->hMsg,
  309. CMSG_ENCODED_SIGNER,
  310. 0,
  311. NULL,
  312. &cbEncodedSigner);
  313. if (cbEncodedSigner == 0)
  314. {
  315. pviewhelp->fNoSignature = TRUE;
  316. return;
  317. }
  318. if (NULL == (pbEncodedSigner = (PBYTE) malloc(cbEncodedSigner)))
  319. {
  320. return;
  321. }
  322. if (!CryptMsgGetParam(pviewhelp->hMsg,
  323. CMSG_ENCODED_SIGNER,
  324. 0,
  325. pbEncodedSigner,
  326. &cbEncodedSigner))
  327. {
  328. free(pbEncodedSigner);
  329. return;
  330. }
  331. pviewhelp->fNoSignature = FALSE;
  332. //
  333. // decode the EncodedSigner info
  334. //
  335. pviewhelp->cbSignerInfo = 0;
  336. if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
  337. PKCS7_SIGNER_INFO,
  338. pbEncodedSigner,
  339. cbEncodedSigner,
  340. 0,
  341. NULL,
  342. &pviewhelp->cbSignerInfo))
  343. {
  344. free(pbEncodedSigner);
  345. return;
  346. }
  347. if (NULL == (pviewhelp->pbSignerInfo = (PCMSG_SIGNER_INFO) malloc(pviewhelp->cbSignerInfo)))
  348. {
  349. free(pbEncodedSigner);
  350. return;
  351. }
  352. if (!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
  353. PKCS7_SIGNER_INFO,
  354. pbEncodedSigner,
  355. cbEncodedSigner,
  356. 0,
  357. pviewhelp->pbSignerInfo,
  358. &pviewhelp->cbSignerInfo))
  359. {
  360. free(pbEncodedSigner);
  361. free(pviewhelp->pbSignerInfo);
  362. pviewhelp->pbSignerInfo = NULL;
  363. return;
  364. }
  365. free(pbEncodedSigner);
  366. //
  367. // get the signers cert
  368. //
  369. pviewhelp->pSignerCert = GetSignersCert(
  370. pviewhelp->pbSignerInfo,
  371. pviewhelp->hExtraStore,
  372. pviewhelp->pcvctl->cStores,
  373. pviewhelp->pcvctl->rghStores);
  374. }
  375. //////////////////////////////////////////////////////////////////////////////////////
  376. //
  377. //////////////////////////////////////////////////////////////////////////////////////
  378. static BOOL VerifyCounterSignature(CTL_VIEW_HELPER *pviewhelp, FILETIME *pft, BOOL *pfCertValid, BOOL *pfCounterSignerCertFound)
  379. {
  380. CRYPT_ATTRIBUTE *pAttr = NULL;
  381. PCMSG_ATTR pMsgAttr = NULL;
  382. DWORD cbMsgAttr = 0;
  383. HCRYPTMSG hMsg = NULL;
  384. BOOL fRet = TRUE;
  385. PCMSG_SIGNER_INFO pbCounterSignerInfo = NULL;
  386. DWORD cbCounterSignerInfo = 0;
  387. BYTE *pbEncodedSigner = NULL;
  388. DWORD cbEncodedSigner = 0;
  389. CERT_INFO CertInfo;
  390. PCCERT_CONTEXT pCertContext=NULL;
  391. *pfCounterSignerCertFound = FALSE;
  392. *pfCertValid = FALSE;
  393. //
  394. // get the unauthenticated attributes because that is where the counter signer is
  395. //
  396. CryptMsgGetParam(pviewhelp->hMsg,
  397. CMSG_SIGNER_UNAUTH_ATTR_PARAM,
  398. 0,
  399. NULL,
  400. &cbMsgAttr);
  401. if (cbMsgAttr == 0)
  402. {
  403. return TRUE;
  404. }
  405. if (NULL == (pMsgAttr = (CMSG_ATTR *) malloc(cbMsgAttr)))
  406. {
  407. goto ErrorCleanup;
  408. }
  409. if (!CryptMsgGetParam(pviewhelp->hMsg,
  410. CMSG_SIGNER_UNAUTH_ATTR_PARAM,
  411. 0,
  412. (void *) pMsgAttr,
  413. &cbMsgAttr))
  414. {
  415. goto ErrorCleanup;
  416. }
  417. //
  418. // search for the counter signer in the unauthenticated attributes
  419. //
  420. if ((pAttr = CertFindAttribute(szOID_RSA_counterSign,
  421. pMsgAttr->cAttr,
  422. pMsgAttr->rgAttr)) == NULL)
  423. {
  424. //
  425. // no counter signature
  426. //
  427. goto Cleanup;
  428. }
  429. //
  430. // decode the encoded counter signer info
  431. //
  432. if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
  433. PKCS7_SIGNER_INFO,
  434. pAttr->rgValue[0].pbData,
  435. pAttr->rgValue[0].cbData,
  436. 0,
  437. NULL,
  438. &cbCounterSignerInfo))
  439. {
  440. goto ErrorCleanup;
  441. }
  442. if (NULL == (pbCounterSignerInfo = (PCMSG_SIGNER_INFO) malloc(cbCounterSignerInfo)))
  443. {
  444. goto ErrorCleanup;
  445. }
  446. if (!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
  447. PKCS7_SIGNER_INFO,
  448. pAttr->rgValue[0].pbData,
  449. pAttr->rgValue[0].cbData,
  450. 0,
  451. pbCounterSignerInfo,
  452. &cbCounterSignerInfo))
  453. {
  454. goto ErrorCleanup;
  455. }
  456. pCertContext = GetSignersCert(
  457. pbCounterSignerInfo,
  458. pviewhelp->hExtraStore,
  459. pviewhelp->pcvctl->cStores,
  460. pviewhelp->pcvctl->rghStores);
  461. //
  462. // if the cert was not found, then set the boolean and return FALSE
  463. // for verifying the signature
  464. //
  465. if (pCertContext == NULL)
  466. {
  467. *pfCounterSignerCertFound = FALSE;
  468. goto ErrorCleanup;
  469. }
  470. else
  471. {
  472. *pfCounterSignerCertFound = TRUE;
  473. }
  474. //
  475. // validate the cert for usage
  476. //
  477. *pfCertValid = ValidateCertForUsage(
  478. pCertContext,
  479. pft,
  480. pviewhelp->pcvctl->cStores,
  481. pviewhelp->pcvctl->rghStores,
  482. pviewhelp->hExtraStore,
  483. szOID_PKIX_KP_TIMESTAMP_SIGNING); // currently the only type of counter signing permitted
  484. if (!(*pfCertValid))
  485. {
  486. goto ErrorCleanup;
  487. }
  488. //
  489. // get the encoded signer BLOB
  490. //
  491. CryptMsgGetParam(pviewhelp->hMsg,
  492. CMSG_ENCODED_SIGNER,
  493. 0,
  494. NULL,
  495. &cbEncodedSigner);
  496. if (cbEncodedSigner == 0)
  497. {
  498. goto ErrorCleanup;
  499. }
  500. if (NULL == (pbEncodedSigner = (PBYTE) malloc(cbEncodedSigner)))
  501. {
  502. goto ErrorCleanup;
  503. }
  504. if (!CryptMsgGetParam(pviewhelp->hMsg,
  505. CMSG_ENCODED_SIGNER,
  506. 0,
  507. pbEncodedSigner,
  508. &cbEncodedSigner))
  509. {
  510. goto ErrorCleanup;
  511. }
  512. //
  513. // verify the counter signature
  514. //
  515. fRet = CryptMsgVerifyCountersignatureEncoded(
  516. NULL, //HCRYPTPROV
  517. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  518. pbEncodedSigner,
  519. cbEncodedSigner,
  520. pAttr->rgValue[0].pbData,
  521. pAttr->rgValue[0].cbData,
  522. pCertContext->pCertInfo
  523. );
  524. Cleanup:
  525. if (pMsgAttr)
  526. free(pMsgAttr);
  527. if (pbCounterSignerInfo)
  528. free(pbCounterSignerInfo);
  529. if (pbEncodedSigner)
  530. free(pbEncodedSigner);
  531. if (pCertContext)
  532. CertFreeCertificateContext(pCertContext);
  533. return fRet;
  534. ErrorCleanup:
  535. fRet = FALSE;
  536. goto Cleanup;
  537. }
  538. //////////////////////////////////////////////////////////////////////////////////////
  539. //
  540. //////////////////////////////////////////////////////////////////////////////////////
  541. INT_PTR APIENTRY ViewPageCTLGeneral(HWND hwndDlg, UINT msg, WPARAM wParam,
  542. LPARAM lParam)
  543. {
  544. DWORD i;
  545. PROPSHEETPAGE *ps;
  546. PCCTL_CONTEXT pctl;
  547. CTL_VIEW_HELPER *pviewhelp;
  548. HIMAGELIST hIml;
  549. HWND hWndListView;
  550. HWND hwnd;
  551. LV_COLUMNW lvC;
  552. WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
  553. PCTL_INFO pCtlInfo;
  554. LVITEMW lvI;
  555. LPNMLISTVIEW pnmv;
  556. CHARFORMAT chFormat;
  557. FILETIME *pft;
  558. BOOL fCatFile;
  559. BOOL fCounterSignerCertFound;
  560. BOOL fCertValid;
  561. #ifdef CMS_PKCS7
  562. CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA CtrlPara;
  563. #endif // CMS_PKCS7
  564. switch ( msg ) {
  565. case WM_INITDIALOG:
  566. //
  567. // save the pviewhelp struct in DWL_USER so it can always be accessed
  568. //
  569. ps = (PROPSHEETPAGE *) lParam;
  570. pviewhelp = (CTL_VIEW_HELPER *) (ps->lParam);
  571. pctl = pviewhelp->pcvctl->pCTLContext;
  572. SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR) pviewhelp);
  573. //
  574. // clear the text in the detail edit box
  575. //
  576. CryptUISetRicheditTextW(hwndDlg, IDC_CTL_GENERAL_DETAIL_EDIT, L"");
  577. //
  578. // check to see if this is a CAT file or CTL file
  579. //
  580. pviewhelp->fCatFile = fCatFile = fIsCatalogFile(&(pctl->pCtlInfo->SubjectUsage));
  581. //
  582. // Get the CTL signer info
  583. //
  584. pviewhelp->hMsg = NULL;
  585. GetSignerInfo(pviewhelp);
  586. //
  587. // enable/disable the "View CTL Signature" button based on whether the signing
  588. // cert was passed in or not
  589. //
  590. EnableWindow(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_VIEW_BUTTON),
  591. (pviewhelp->pbSignerInfo != NULL));
  592. //
  593. // if there is a signer info, then get the sign time
  594. //
  595. if (pviewhelp->pbSignerInfo != NULL)
  596. {
  597. AllocAndReturnTimeStampersTimes(pviewhelp->pbSignerInfo, &pft);
  598. }
  599. #ifdef CMS_PKCS7
  600. memset(&CtrlPara, 0, sizeof(CtrlPara));
  601. CtrlPara.cbSize = sizeof(CtrlPara);
  602. // CtrlPara.hCryptProv =
  603. // Assume the CTL only has 1 signer
  604. CtrlPara.dwSignerIndex = 0;
  605. CtrlPara.dwSignerType = CMSG_VERIFY_SIGNER_CERT;
  606. CtrlPara.pvSigner = (void *) pviewhelp->pSignerCert;
  607. #endif // CMS_PKCS7
  608. //
  609. // set the valid/invalid bitmap and the validity text based on whether the signature of
  610. // CTL verifies or not
  611. //
  612. if (pviewhelp->fNoSignature == TRUE)
  613. {
  614. if (fCatFile)
  615. {
  616. LoadStringU(HinstDll, IDS_CAT_NO_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  617. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_CATLIST));
  618. }
  619. else
  620. {
  621. LoadStringU(HinstDll, IDS_CTL_NO_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  622. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_TRUSTLIST));
  623. }
  624. pviewhelp->dwInheritableError = CRYPT_E_NO_SIGNER;
  625. }
  626. else if (pviewhelp->pSignerCert == NULL)
  627. {
  628. if (fCatFile)
  629. {
  630. LoadStringU(HinstDll, IDS_CAT_UNAVAILABLE_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  631. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_CATLIST));
  632. }
  633. else
  634. {
  635. LoadStringU(HinstDll, IDS_CTL_UNAVAILABLE_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  636. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_TRUSTLIST));
  637. }
  638. pviewhelp->dwInheritableError = TRUST_E_NO_SIGNER_CERT;
  639. }
  640. else if (!ValidateCertForUsage(
  641. pviewhelp->pSignerCert,
  642. pft,
  643. pviewhelp->pcvctl->cStores,
  644. pviewhelp->pcvctl->rghStores,
  645. pviewhelp->hExtraStore,
  646. fCatFile ? szOID_PKIX_KP_CODE_SIGNING : szOID_KP_CTL_USAGE_SIGNING))
  647. {
  648. if (fCatFile)
  649. {
  650. LoadStringU(HinstDll, IDS_CAT_INVALID_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  651. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_CATLIST));
  652. }
  653. else
  654. {
  655. LoadStringU(HinstDll, IDS_CTL_INVALID_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  656. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_TRUSTLIST));
  657. }
  658. }
  659. #ifdef CMS_PKCS7
  660. // NOTE!!! the above ValidateCertForUsage() calls WinVerifyTrust().
  661. // As a result, for a DSS signer it would have inherited its public key
  662. // algorithm parameters.
  663. //
  664. // NOTE!!! also assumes dwSignerIndex == 0.
  665. else if (!CryptMsgControl(
  666. pviewhelp->pcvctl->pCTLContext->hCryptMsg,
  667. 0, // dwFlags
  668. CMSG_CTRL_VERIFY_SIGNATURE_EX,
  669. &CtrlPara
  670. ))
  671. #else
  672. else if (!CryptMsgControl(
  673. pviewhelp->pcvctl->pCTLContext->hCryptMsg,
  674. 0,
  675. CMSG_CTRL_VERIFY_SIGNATURE,
  676. pviewhelp->pSignerCert->pCertInfo
  677. ))
  678. #endif // CMS_PKCS7
  679. {
  680. if (fCatFile)
  681. {
  682. LoadStringU(HinstDll, IDS_CAT_INVALID_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  683. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_CATLIST));
  684. }
  685. else
  686. {
  687. LoadStringU(HinstDll, IDS_CTL_INVALID_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  688. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_TRUSTLIST));
  689. }
  690. pviewhelp->dwInheritableError = TRUST_E_BAD_DIGEST;
  691. }
  692. else if (!VerifyCounterSignature(pviewhelp, pft, &fCertValid, &fCounterSignerCertFound))
  693. {
  694. if (fCatFile)
  695. {
  696. if (!fCounterSignerCertFound)
  697. {
  698. LoadStringU(HinstDll, IDS_CAT_COUNTER_SIGNER_CERT_UNAVAILABLE, (LPWSTR)szText, ARRAYSIZE(szText));
  699. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_CATLIST));
  700. }
  701. else if (!fCertValid)
  702. {
  703. LoadStringU(HinstDll, IDS_CAT_INVALID_COUNTER_SIGNER_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  704. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_CATLIST));
  705. }
  706. else
  707. {
  708. LoadStringU(HinstDll, IDS_CAT_INVALID_COUNTER_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  709. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_CATLIST));
  710. }
  711. }
  712. else
  713. {
  714. if (!fCounterSignerCertFound)
  715. {
  716. LoadStringU(HinstDll, IDS_CTL_COUNTER_SIGNER_CERT_UNAVAILABLE, (LPWSTR)szText, ARRAYSIZE(szText));
  717. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_EXCLAMATION_TRUSTLIST));
  718. }
  719. else if (!fCertValid)
  720. {
  721. LoadStringU(HinstDll, IDS_CTL_INVALID_COUNTER_SIGNER_CERT, (LPWSTR)szText, ARRAYSIZE(szText));
  722. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_TRUSTLIST));
  723. }
  724. else
  725. {
  726. LoadStringU(HinstDll, IDS_CTL_INVALID_COUNTER_SIGNATURE, (LPWSTR)szText, ARRAYSIZE(szText));
  727. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_REVOKED_TRUSTLIST));
  728. }
  729. }
  730. pviewhelp->dwInheritableError = TRUST_E_COUNTER_SIGNER;
  731. }
  732. else
  733. {
  734. if (fCatFile)
  735. {
  736. LoadStringU(HinstDll, IDS_CAT_VALID, (LPWSTR)szText, ARRAYSIZE(szText));
  737. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_CATLIST));
  738. }
  739. else
  740. {
  741. LoadStringU(HinstDll, IDS_CTL_VALID, (LPWSTR)szText, ARRAYSIZE(szText));
  742. pviewhelp->hIcon = LoadIcon(HinstDll, MAKEINTRESOURCE(IDI_TRUSTLIST));
  743. }
  744. }
  745. CryptUISetRicheditTextW(hwndDlg, IDC_CTL_GENERAL_VALIDITY_EDIT, szText);
  746. if (pviewhelp->pbSignerInfo != NULL)
  747. {
  748. free(pft);
  749. }
  750. //
  751. // set the header text and subclass the edit controls so they display an
  752. // arrow cursor in their window
  753. //
  754. if (fCatFile)
  755. {
  756. LoadStringU(HinstDll, IDS_CAT_INFORMATION, (LPWSTR)szText, ARRAYSIZE(szText));
  757. }
  758. else
  759. {
  760. LoadStringU(HinstDll, IDS_CTL_INFORMATION, (LPWSTR)szText, ARRAYSIZE(szText));
  761. }
  762. CryptUISetRicheditTextW(hwndDlg, IDC_CTL_GENERAL_HEADER_EDIT, szText);
  763. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_VALIDITY_EDIT));
  764. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_HEADER_EDIT));
  765. //
  766. // set the font for the CTL header information
  767. //
  768. memset(&chFormat, 0, sizeof(chFormat));
  769. chFormat.cbSize = sizeof(chFormat);
  770. chFormat.dwMask = CFM_BOLD;
  771. chFormat.dwEffects = CFE_BOLD;
  772. SendMessageA(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_HEADER_EDIT), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  773. //
  774. // get the handle of the list view control
  775. //
  776. hWndListView = GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST);
  777. //
  778. // initialize the image list for the list view, load the icons,
  779. // then add the image list to the list view
  780. //
  781. hIml = ImageList_LoadImage(HinstDll, MAKEINTRESOURCE(IDB_PROPLIST), 0, 4, RGB(0,128,128), IMAGE_BITMAP, 0);
  782. ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
  783. //
  784. // initialize the columns in the list view
  785. //
  786. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  787. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  788. lvC.pszText = szText; // The text for the column.
  789. // Add the columns. They are loaded from a string table.
  790. lvC.iSubItem = 0;
  791. lvC.cx = 130;
  792. LoadStringU(HinstDll, IDS_FIELD, szText, ARRAYSIZE(szText));
  793. if (ListView_InsertColumnU(hWndListView, 0, &lvC) == -1)
  794. {
  795. // error
  796. }
  797. lvC.cx = 200;
  798. LoadStringU(HinstDll, IDS_VALUE, szText, ARRAYSIZE(szText));
  799. if (ListView_InsertColumnU(hWndListView, 1, &lvC) == -1)
  800. {
  801. // error
  802. }
  803. //
  804. // add all the certificate fields to the list box
  805. //
  806. i = 0;
  807. DisplayV1Fields(hWndListView, pctl->pCtlInfo, &i);
  808. DisplayExtensions(hWndListView, pctl->pCtlInfo->cExtension, pctl->pCtlInfo->rgExtension, FALSE, &i);
  809. DisplayExtensions(hWndListView, pctl->pCtlInfo->cExtension, pctl->pCtlInfo->rgExtension, TRUE, &i);
  810. DisplayProperties(hWndListView, pctl, &i);
  811. //
  812. // set the style in the list view so that it highlights an entire line
  813. //
  814. SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  815. return TRUE;
  816. case WM_NOTIFY:
  817. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  818. pctl = pviewhelp->pcvctl->pCTLContext;
  819. pCtlInfo = pctl->pCtlInfo;
  820. switch (((NMHDR FAR *) lParam)->code)
  821. {
  822. case PSN_SETACTIVE:
  823. break;
  824. case PSN_APPLY:
  825. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  826. break;
  827. case PSN_KILLACTIVE:
  828. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  829. return TRUE;
  830. case PSN_RESET:
  831. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  832. break;
  833. case PSN_QUERYCANCEL:
  834. pviewhelp->fCancelled = TRUE;
  835. return FALSE;
  836. case PSN_HELP:
  837. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  838. if (FIsWin95) {
  839. //WinHelpA(hwndDlg, (LPSTR) pviewhelp->pcvctl->szHelpFileName,
  840. // HELP_CONTEXT, pviewhelp->pcvctl->dwHelpId);
  841. }
  842. else {
  843. //WinHelpW(hwndDlg, pviewhelp->pcvctl->szHelpFileName, HELP_CONTEXT,
  844. // pviewhelp->pcvctl->dwHelpId);
  845. }
  846. return TRUE;
  847. case LVN_ITEMCHANGING:
  848. if ((((NMHDR FAR *) lParam)->idFrom) != IDC_CTL_GENERAL_ITEM_LIST)
  849. {
  850. break;
  851. }
  852. pnmv = (LPNMLISTVIEW) lParam;
  853. if (pnmv->uNewState & LVIS_SELECTED)
  854. {
  855. DisplayHelperTextInEdit(
  856. GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST),
  857. hwndDlg,
  858. IDC_CTL_GENERAL_DETAIL_EDIT,
  859. pnmv->iItem);
  860. }
  861. return TRUE;
  862. case NM_CLICK:
  863. if ((((NMHDR FAR *) lParam)->idFrom) != IDC_CTL_GENERAL_ITEM_LIST)
  864. {
  865. break;
  866. }
  867. DisplayHelperTextInEdit(
  868. GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST),
  869. hwndDlg,
  870. IDC_CTL_GENERAL_DETAIL_EDIT,
  871. -1);
  872. return TRUE;
  873. case NM_SETFOCUS:
  874. switch (((NMHDR FAR *) lParam)->idFrom)
  875. {
  876. case IDC_CTL_GENERAL_ITEM_LIST:
  877. hWndListView = GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST);
  878. if ((ListView_GetItemCount(hWndListView) != 0) &&
  879. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  880. {
  881. memset(&lvI, 0, sizeof(lvI));
  882. lvI.mask = LVIF_STATE;
  883. lvI.iItem = 0;
  884. lvI.state = LVIS_FOCUSED;
  885. lvI.stateMask = LVIS_FOCUSED;
  886. ListView_SetItem(hWndListView, &lvI);
  887. }
  888. break;
  889. }
  890. break;
  891. }
  892. break;
  893. case WM_COMMAND:
  894. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  895. pctl = pviewhelp->pcvctl->pCTLContext;
  896. pCtlInfo = pctl->pCtlInfo;
  897. switch (LOWORD(wParam))
  898. {
  899. case IDC_CTL_GENERAL_VIEW_BUTTON:
  900. {
  901. CRYPTUI_VIEWSIGNERINFO_STRUCTW cvsi;
  902. memset(&cvsi, 0, sizeof(cvsi));
  903. cvsi.dwSize = sizeof(cvsi);
  904. cvsi.hwndParent = hwndDlg;
  905. cvsi.pSignerInfo = pviewhelp->pbSignerInfo;
  906. cvsi.hMsg = pviewhelp->hMsg;
  907. cvsi.pszOID = fIsCatalogFile(&(pCtlInfo->SubjectUsage)) ? szOID_PKIX_KP_CODE_SIGNING : szOID_KP_CTL_USAGE_SIGNING;
  908. cvsi.cStores = 1;
  909. cvsi.rghStores = &(pviewhelp->hExtraStore);
  910. if (pviewhelp->dwInheritableError != 0)
  911. {
  912. cvsi.dwReserved = pviewhelp->dwInheritableError;
  913. cvsi.dwFlags |= CRYPTUI_VIEWSIGNERINFO_RESERVED_FIELD_IS_ERROR_CODE;
  914. }
  915. CryptUIDlgViewSignerInfoW(&cvsi);
  916. }
  917. break;
  918. case IDHELP:
  919. if (FIsWin95) {
  920. //WinHelpA(hwndDlg, (LPSTR) pviewhelp->pcvctl->szHelpFileName,
  921. // HELP_CONTEXT, pviewhelp->pcvctl->dwHelpId);
  922. }
  923. else {
  924. //WinHelpW(hwndDlg, pviewhelp->pcvctl->szHelpFileName, HELP_CONTEXT,
  925. // pviewhelp->pcvctl->dwHelpId);
  926. }
  927. return TRUE;
  928. }
  929. break;
  930. case WM_PAINT:
  931. RECT rect;
  932. PAINTSTRUCT paintstruct;
  933. HDC hdc;
  934. COLORREF colorRef;
  935. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  936. if (GetUpdateRect(hwndDlg, &rect, FALSE))
  937. {
  938. hdc = BeginPaint(hwndDlg, &paintstruct);
  939. if (hdc == NULL)
  940. {
  941. EndPaint(hwndDlg, &paintstruct);
  942. break;
  943. }
  944. colorRef = GetBkColor(hdc);
  945. SendMessageA(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_VALIDITY_EDIT), EM_SETBKGNDCOLOR , 0, (LPARAM) colorRef);
  946. SendMessageA(GetDlgItem(hwndDlg, IDC_CTL_GENERAL_HEADER_EDIT), EM_SETBKGNDCOLOR, 0, (LPARAM) colorRef);
  947. if (pviewhelp->hIcon != NULL)
  948. {
  949. DrawIcon(
  950. hdc,
  951. ICON_X_POS,
  952. ICON_Y_POS,
  953. pviewhelp->hIcon);
  954. }
  955. EndPaint(hwndDlg, &paintstruct);
  956. }
  957. break;
  958. case WM_DESTROY:
  959. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  960. if (pviewhelp->hIcon != NULL)
  961. {
  962. DeleteObject(pviewhelp->hIcon);
  963. pviewhelp->hIcon = NULL;
  964. }
  965. if (pviewhelp->pSignerCert != NULL)
  966. {
  967. CertFreeCertificateContext(pviewhelp->pSignerCert);
  968. pviewhelp->pSignerCert = NULL;
  969. }
  970. if (pviewhelp->pbSignerInfo)
  971. {
  972. free(pviewhelp->pbSignerInfo);
  973. pviewhelp->pbSignerInfo = NULL;
  974. }
  975. if (pviewhelp->hMsg != NULL)
  976. {
  977. CryptMsgClose(pviewhelp->hMsg);
  978. }
  979. pviewhelp->hMsg = NULL;
  980. //
  981. // get all the items in the list view and free the lParam
  982. // associated with each of them (lParam is the helper sruct)
  983. //
  984. hWndListView = GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST);
  985. memset(&lvI, 0, sizeof(lvI));
  986. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  987. lvI.mask = LVIF_PARAM;
  988. while (lvI.iItem >= 0)
  989. {
  990. if (ListView_GetItemU(hWndListView, &lvI))
  991. {
  992. FreeListDisplayHelper((PLIST_DISPLAY_HELPER) lvI.lParam);
  993. }
  994. lvI.iItem--;
  995. }
  996. break;
  997. case WM_HELP:
  998. case WM_CONTEXTMENU:
  999. pviewhelp = (CTL_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1000. if (msg == WM_HELP)
  1001. {
  1002. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  1003. }
  1004. else
  1005. {
  1006. hwnd = (HWND) wParam;
  1007. }
  1008. if ((hwnd != GetDlgItem(hwndDlg, IDC_CTL_GENERAL_ITEM_LIST)) &&
  1009. (hwnd != GetDlgItem(hwndDlg, IDC_CTL_GENERAL_DETAIL_EDIT)) &&
  1010. (hwnd != GetDlgItem(hwndDlg, IDC_CTL_GENERAL_VIEW_BUTTON)))
  1011. {
  1012. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1013. return TRUE;
  1014. }
  1015. else
  1016. {
  1017. if (pviewhelp->fCatFile)
  1018. {
  1019. return OnContextHelp(hwndDlg, msg, wParam, lParam, CatHelpmap);
  1020. }
  1021. else
  1022. {
  1023. return OnContextHelp(hwndDlg, msg, wParam, lParam, CTLHelpmap);
  1024. }
  1025. }
  1026. }
  1027. return FALSE;
  1028. }