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.

1100 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: util.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <wininet.h>
  12. #include <dbgdef.h>
  13. extern HINSTANCE HinstDll;
  14. extern HMODULE HmodRichEdit;
  15. //////////////////////////////////////////////////////////////////////////////////////
  16. //
  17. //////////////////////////////////////////////////////////////////////////////////////
  18. BOOL CommonInit()
  19. {
  20. if (HmodRichEdit == NULL)
  21. {
  22. HmodRichEdit = LoadLibraryA("RichEd32.dll");
  23. if (HmodRichEdit == NULL) {
  24. return FALSE;
  25. }
  26. }
  27. INITCOMMONCONTROLSEX initcomm = {
  28. sizeof(initcomm), ICC_NATIVEFNTCTL_CLASS | ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES
  29. };
  30. InitCommonControlsEx(&initcomm);
  31. return TRUE;
  32. }
  33. /////////////////////////////////////////////////////////
  34. BOOL IsWin95()
  35. {
  36. BOOL f;
  37. OSVERSIONINFOA ver;
  38. ver.dwOSVersionInfoSize = sizeof(ver);
  39. f = GetVersionExA(&ver);
  40. return !f || (ver.dwPlatformId == 1);
  41. }
  42. BOOL CheckRichedit20Exists()
  43. {
  44. HMODULE hModRichedit20;
  45. hModRichedit20 = LoadLibraryA("RichEd20.dll");
  46. if (hModRichedit20 != NULL)
  47. {
  48. FreeLibrary(hModRichedit20);
  49. return TRUE;
  50. }
  51. else
  52. {
  53. return FALSE;
  54. }
  55. }
  56. //////////////////////////////////////////////////////////////////////////////////////
  57. //
  58. //////////////////////////////////////////////////////////////////////////////////////
  59. LPWSTR PrettySubject(PCCERT_CONTEXT pccert)
  60. {
  61. DWORD cb;
  62. DWORD cch;
  63. BOOL f;
  64. LPWSTR pwsz;
  65. //
  66. // If the user has put a friendly name onto a certificate, then we
  67. // should display that as the pretty name for the certificate.
  68. //
  69. f = CertGetCertificateContextProperty(pccert, CERT_FRIENDLY_NAME_PROP_ID,
  70. NULL, &cb);
  71. if (f && (cb > 0)) {
  72. pwsz = (LPWSTR) malloc(cb);
  73. if (pwsz == NULL)
  74. {
  75. return NULL;
  76. }
  77. CertGetCertificateContextProperty(pccert, CERT_FRIENDLY_NAME_PROP_ID,
  78. pwsz, &cb);
  79. return pwsz;
  80. }
  81. pwsz = GetDisplayNameString(pccert, 0);
  82. return pwsz;
  83. }
  84. //////////////////////////////////////////////////////////////////////////////////////
  85. //
  86. //////////////////////////////////////////////////////////////////////////////////////
  87. BOOL OnContextHelp(HWND /*hwnd*/, UINT uMsg, WPARAM wParam, LPARAM lParam,
  88. HELPMAP const * rgCtxMap)
  89. {
  90. if (uMsg == WM_HELP)
  91. {
  92. LPHELPINFO lphi = (LPHELPINFO) lParam;
  93. if (lphi->iContextType == HELPINFO_WINDOW)
  94. { // must be for a control
  95. if (lphi->iCtrlId != IDC_STATIC)
  96. {
  97. WinHelpU((HWND)lphi->hItemHandle, L"secauth.hlp", HELP_WM_HELP,
  98. (ULONG_PTR)(LPVOID)rgCtxMap);
  99. }
  100. }
  101. return (TRUE);
  102. }
  103. else if (uMsg == WM_CONTEXTMENU) {
  104. WinHelpU ((HWND) wParam, L"secauth.hlp", HELP_CONTEXTMENU,
  105. (ULONG_PTR)(LPVOID)rgCtxMap);
  106. return (TRUE);
  107. }
  108. return FALSE;
  109. }
  110. //////////////////////////////////////////////////////////////////////////////////////
  111. //
  112. //////////////////////////////////////////////////////////////////////////////////////
  113. STDAPI DllRegisterServer(void)
  114. {
  115. HRESULT hr = S_OK;
  116. return hr;
  117. }
  118. //////////////////////////////////////////////////////////////////////////////////////
  119. //
  120. //////////////////////////////////////////////////////////////////////////////////////
  121. STDAPI DllUnregisterServer(void)
  122. {
  123. HRESULT hr = S_OK;
  124. return hr;
  125. }
  126. //////////////////////////////////////////////////////////////////////////////////////
  127. //
  128. //////////////////////////////////////////////////////////////////////////////////////
  129. BOOL FreeAndCloseKnownStores(DWORD chStores, HCERTSTORE *phStores)
  130. {
  131. DWORD i;
  132. for (i=0; i<chStores; i++)
  133. {
  134. CertCloseStore(phStores[i], 0);
  135. }
  136. free(phStores);
  137. return TRUE;
  138. }
  139. //////////////////////////////////////////////////////////////////////////////////////
  140. //
  141. //////////////////////////////////////////////////////////////////////////////////////
  142. #define NUM_KNOWN_STORES 5
  143. BOOL AllocAndOpenKnownStores(DWORD *chStores, HCERTSTORE **pphStores)
  144. {
  145. HCERTSTORE hStore;
  146. if (NULL == (*pphStores = (HCERTSTORE *) malloc(NUM_KNOWN_STORES * sizeof(HCERTSTORE))))
  147. {
  148. return FALSE;
  149. }
  150. *chStores = 0;
  151. //
  152. // ROOT store - ALWAYS #0 !!!!
  153. //
  154. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  155. 0,
  156. 0,
  157. CERT_SYSTEM_STORE_CURRENT_USER |
  158. CERT_STORE_READONLY_FLAG |
  159. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  160. "ROOT"))
  161. {
  162. (*pphStores)[(*chStores)++] = hStore;
  163. }
  164. else
  165. {
  166. return(FALSE); // if we can't find the root, FAIL!
  167. }
  168. //
  169. // open the Trust List store
  170. //
  171. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  172. 0,
  173. 0,
  174. CERT_SYSTEM_STORE_CURRENT_USER |
  175. CERT_STORE_READONLY_FLAG |
  176. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  177. "TRUST"))
  178. {
  179. (*pphStores)[(*chStores)++] = hStore;
  180. }
  181. //
  182. // CA Store
  183. //
  184. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  185. 0,
  186. 0,
  187. CERT_SYSTEM_STORE_CURRENT_USER |
  188. CERT_STORE_READONLY_FLAG |
  189. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  190. "CA"))
  191. {
  192. (*pphStores)[(*chStores)++] = hStore;
  193. }
  194. //
  195. // MY Store
  196. //
  197. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  198. 0,
  199. 0,
  200. CERT_SYSTEM_STORE_CURRENT_USER |
  201. CERT_STORE_READONLY_FLAG |
  202. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  203. "MY"))
  204. {
  205. (*pphStores)[(*chStores)++] = hStore;
  206. }
  207. //
  208. // SPC Store (historic reasons!)
  209. //
  210. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  211. 0,
  212. 0,
  213. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  214. CERT_STORE_READONLY_FLAG |
  215. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  216. "SPC"))
  217. {
  218. (*pphStores)[(*chStores)++] = hStore;
  219. }
  220. return(TRUE);
  221. }
  222. //////////////////////////////////////////////////////////////////////////////////////
  223. // Create and return a palette from the info in a DIB bitmap.
  224. // To free the returned palette, use DeleteObject.
  225. //////////////////////////////////////////////////////////////////////////////////////
  226. #define SELPALMODE TRUE
  227. static HPALETTE CreateDIBPalette (LPBITMAPINFO lpbmi, LPINT lpiNumColors)
  228. {
  229. LPBITMAPINFOHEADER lpbi;
  230. LPLOGPALETTE lpPal;
  231. HANDLE hLogPal;
  232. HPALETTE hPal = NULL;
  233. int i;
  234. lpbi = (LPBITMAPINFOHEADER)lpbmi;
  235. if (lpbi->biBitCount <= 8)
  236. {
  237. if (lpbi->biClrUsed == 0)
  238. *lpiNumColors = (1 << lpbi->biBitCount);
  239. else
  240. *lpiNumColors = lpbi->biClrUsed;
  241. }
  242. else
  243. *lpiNumColors = 0; // No palette needed for 24 BPP DIB
  244. if (*lpiNumColors)
  245. {
  246. hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) + sizeof (PALETTEENTRY) * (*lpiNumColors));
  247. if (hLogPal == NULL)
  248. {
  249. return NULL;
  250. }
  251. lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
  252. lpPal->palVersion = 0x300;
  253. lpPal->palNumEntries = (WORD)*lpiNumColors;
  254. for (i = 0; i < *lpiNumColors; i++)
  255. {
  256. lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
  257. lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  258. lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
  259. lpPal->palPalEntry[i].peFlags = 0;
  260. }
  261. hPal = CreatePalette(lpPal);
  262. GlobalUnlock (hLogPal);
  263. GlobalFree (hLogPal);
  264. }
  265. return hPal;
  266. }
  267. //////////////////////////////////////////////////////////////////////////////////////
  268. //
  269. //////////////////////////////////////////////////////////////////////////////////////
  270. HBITMAP LoadResourceBitmap(HINSTANCE hInstance, LPSTR lpString, HPALETTE* lphPalette)
  271. // Load the indicated bitmap resource and its palette. To free the
  272. // bitmap, use DeleteObject
  273. // palette, use DeleteObject
  274. {
  275. HRSRC hRsrc;
  276. HGLOBAL hGlobal;
  277. HBITMAP hBitmapFinal = NULL;
  278. LPBITMAPINFOHEADER lpbi;
  279. HDC hdc;
  280. int iNumColors;
  281. if (hRsrc = ::FindResource(hInstance, lpString, RT_BITMAP))
  282. {
  283. hGlobal = ::LoadResource(hInstance, hRsrc);
  284. if (hGlobal == NULL)
  285. {
  286. return NULL;
  287. }
  288. lpbi = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
  289. hdc = GetDC(NULL);
  290. if (hdc == NULL)
  291. {
  292. return NULL;
  293. }
  294. HDC hdcMem = CreateCompatibleDC(hdc);
  295. if (hdcMem == NULL)
  296. {
  297. ReleaseDC(NULL,hdc);
  298. return NULL;
  299. }
  300. HBITMAP hbmMem = CreateCompatibleBitmap(hdc, 10, 10); assert(hbmMem);
  301. if (hbmMem == NULL)
  302. {
  303. ReleaseDC(NULL,hdc);
  304. DeleteDC(hdcMem);
  305. return NULL;
  306. }
  307. HBITMAP hbmPrev = (HBITMAP)SelectObject(hdcMem, hbmMem);
  308. HPALETTE hpal = CreateDIBPalette((LPBITMAPINFO)lpbi, &iNumColors);
  309. HPALETTE hpalPrev = NULL;
  310. if (hpal)
  311. {
  312. hpalPrev = SelectPalette(hdcMem,hpal,FALSE);
  313. RealizePalette(hdcMem);
  314. }
  315. hBitmapFinal = ::CreateDIBitmap(hdcMem,
  316. (LPBITMAPINFOHEADER)lpbi,
  317. (LONG)CBM_INIT,
  318. (LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
  319. (LPBITMAPINFO)lpbi,
  320. DIB_RGB_COLORS );
  321. if (hpalPrev)
  322. {
  323. SelectPalette(hdcMem, hpalPrev, FALSE);
  324. RealizePalette(hdcMem);
  325. }
  326. if (lphPalette)
  327. {
  328. // Let the caller own this if he asked for it
  329. *lphPalette = hpal;
  330. }
  331. else
  332. {
  333. // We don't need it any more
  334. ::DeleteObject(hpal);
  335. }
  336. // Tidy up
  337. SelectObject(hdcMem, hbmPrev);
  338. DeleteObject(hbmMem);
  339. DeleteDC(hdcMem);
  340. ReleaseDC(NULL,hdc);
  341. UnlockResource(hGlobal);
  342. FreeResource(hGlobal);
  343. }
  344. return (hBitmapFinal);
  345. }
  346. //////////////////////////////////////////////////////////////////////////////////////
  347. // Implement our own mask blt to deal with devices that don't support it natively
  348. //////////////////////////////////////////////////////////////////////////////////////
  349. void MaskBlt
  350. (
  351. HBITMAP& hbmImage,
  352. HPALETTE hpal,
  353. HDC& hdc, int xDst, int yDst, int dx, int dy
  354. )
  355. {
  356. int xSrc = 0, ySrc = 0;
  357. int xMsk = 0, yMsk = 0;
  358. // Either
  359. // a) I'm not testing for MaskBlt correctly, or
  360. // b) some Win95 cards lie about its support
  361. // For now, we just turn it off and roll our own
  362. if (FALSE) // && (GetDeviceCaps(hdc, RASTERCAPS) & RC_BITBLT))
  363. {
  364. // Device can handle it; let it do it
  365. // Raster opcode 0x00AA0029 == leave destination untouched
  366. //
  367. /* CDC hdcImage;
  368. hdc.CreateCompatibleDC(&hdcImage);
  369. CBitmap* pbmpPrev = hdcImage.SelectObject(&hbmImage);
  370. // We need to create the mask ourselves in any case
  371. // hdc.MaskBlt(xDst,yDst,dx,dy, &hdcImage,xSrc,ySrc, hbmMaskIn,xMsk,yMsk, MAKEROP4(0x00AA0029,SRCCOPY));
  372. hdcImage.SelectObject(pbmpPrev);
  373. */ }
  374. else
  375. {
  376. HDC hdcMask;
  377. HDC hdcMaskInv;
  378. HDC hdcCache;
  379. HDC hdcImage;
  380. HDC hdcImageCrop;
  381. HBITMAP hbmCache;
  382. HBITMAP hbmImageCrop;
  383. HBITMAP hbmMaskInvert;
  384. HBITMAP hbmMask;
  385. HBITMAP hbmPrevImage;
  386. HBITMAP hbmPrevImageCrop;
  387. HBITMAP hbmPrevCache;
  388. HBITMAP hbmPrevMask;
  389. HBITMAP hbmPrevMaskInv;
  390. COLORREF rgbTransparent;
  391. COLORREF rgbPrev;
  392. //
  393. // Device can't handle it; we roll our own
  394. //
  395. hdcMask = CreateCompatibleDC(hdc); assert(hdcMask);
  396. hdcMaskInv = CreateCompatibleDC(hdc); assert(hdcMaskInv);
  397. hdcCache = CreateCompatibleDC(hdc); assert(hdcCache);
  398. hdcImage = CreateCompatibleDC(hdc); assert(hdcImage);
  399. hdcImageCrop = CreateCompatibleDC(hdc); assert(hdcImageCrop);
  400. if ((hdcMask == NULL) ||
  401. (hdcMaskInv == NULL) ||
  402. (hdcCache == NULL) ||
  403. (hdcImage == NULL) ||
  404. (hdcImageCrop == NULL))
  405. {
  406. goto DCCleanUp;
  407. }
  408. // Create bitmaps
  409. hbmCache = CreateCompatibleBitmap(hdc, dx, dy); assert(hbmCache);
  410. hbmImageCrop = CreateCompatibleBitmap(hdc, dx, dy); assert(hbmImageCrop);
  411. hbmMaskInvert = CreateCompatibleBitmap(hdcMaskInv, dx, dy); assert(hbmMaskInvert);
  412. hbmMask = CreateBitmap(dx, dy, 1, 1, NULL); assert(hbmMask); // B&W bitmap
  413. if ((hbmCache == NULL) ||
  414. (hbmImageCrop == NULL) ||
  415. (hbmMaskInvert == NULL) ||
  416. (hbmMask == NULL))
  417. {
  418. goto BMCleanUp;
  419. }
  420. // Select bitmaps
  421. hbmPrevImage = (HBITMAP)SelectObject(hdcImage, hbmImage);
  422. hbmPrevImageCrop= (HBITMAP)SelectObject(hdcImageCrop, hbmImageCrop);
  423. hbmPrevCache = (HBITMAP)SelectObject(hdcCache, hbmCache);
  424. hbmPrevMask = (HBITMAP)SelectObject(hdcMask, hbmMask);
  425. hbmPrevMaskInv = (HBITMAP)SelectObject(hdcMaskInv, hbmMaskInvert);
  426. assert(hbmPrevMaskInv);
  427. assert(hbmPrevMask);
  428. assert(hbmPrevCache);
  429. assert(hbmPrevImageCrop);
  430. assert(hbmPrevImage);
  431. // Select the palette into each bitmap
  432. /*HPALETTE hpalCache = SelectPalette(hdcCache, hpal, SELPALMODE);
  433. HPALETTE hpalImage = SelectPalette(hdcImage, hpal, SELPALMODE);
  434. HPALETTE hpalImageCrop = SelectPalette(hdcImageCrop, hpal, SELPALMODE);
  435. HPALETTE hpalMaskInv = SelectPalette(hdcMaskInv, hpal, SELPALMODE);
  436. HPALETTE hpalMask = SelectPalette(hdcMask, hpal, SELPALMODE);
  437. */
  438. // Create the mask. We want a bitmap which is white (1) where the image is
  439. // rgbTransparent and black (0) where it is another color.
  440. //
  441. // When using BitBlt() to convert a color bitmap to a monochrome bitmap, GDI
  442. // sets to white (1) all pixels that match the background color of the source
  443. // DC. All other bits are set to black (0).
  444. //
  445. rgbTransparent = RGB(255,0,255); // this color becomes transparent
  446. rgbPrev = SetBkColor(hdcImage, rgbTransparent);
  447. BitBlt(hdcMask, 0,0,dx,dy, hdcImage, 0, 0, SRCCOPY);
  448. SetBkColor(hdcImage, rgbPrev);
  449. // Create the inverted mask
  450. BitBlt(hdcMaskInv, 0,0,dx,dy, hdcMask, xMsk,yMsk, NOTSRCCOPY); // Sn: Create inverted mask
  451. // Carry out the surgery
  452. BitBlt(hdcCache, 0,0,dx,dy, hdc, xDst,yDst, SRCCOPY); // S: Get copy of screen
  453. BitBlt(hdcCache, 0,0,dx,dy, hdcMask, 0, 0, SRCAND); // DSa: zero where new image goes
  454. BitBlt(hdcImageCrop,0,0,dx,dy, hdcImage, xSrc,ySrc, SRCCOPY); // S: Get copy of image
  455. BitBlt(hdcImageCrop,0,0,dx,dy, hdcMaskInv,0, 0, SRCAND); // DSa: zero out outside of image
  456. BitBlt(hdcCache, 0,0,dx,dy, hdcImageCrop,0, 0, SRCPAINT); // DSo: Combine image into cache
  457. BitBlt(hdc, xDst,yDst,dx,dy, hdcCache, 0, 0, SRCCOPY); // S: Put results back on screen
  458. // VERIFY(BitBlt(hdc, xDst,yDst,dx,dy, hdcCache, 0, 0, SRCCOPY));
  459. // VERIFY(BitBlt(hdc, xDst+dx,yDst,dx,dy, hdcMask, 0, 0, SRCCOPY));
  460. /*if (hpalCache) SelectPalette(hdcCache, hpalCache, SELPALMODE);
  461. if (hpalImage) SelectPalette(hdcImage, hpalImage, SELPALMODE);
  462. if (hpalImageCrop) SelectPalette(hdcImageCrop, hpalImageCrop, SELPALMODE);
  463. if (hpalMaskInv) SelectPalette(hdcMaskInv, hpalMaskInv, SELPALMODE);
  464. if (hpalMask) SelectPalette(hdcMask, hpalMask, SELPALMODE);
  465. */
  466. // Tidy up
  467. SelectObject(hdcImage, hbmPrevImage);
  468. SelectObject(hdcImageCrop, hbmPrevImageCrop);
  469. SelectObject(hdcCache, hbmPrevCache);
  470. SelectObject(hdcMask, hbmPrevMask);
  471. SelectObject(hdcMaskInv, hbmPrevMaskInv);
  472. // Free resources
  473. BMCleanUp:
  474. if (hbmMaskInvert != NULL)
  475. DeleteObject(hbmMaskInvert);
  476. if (hbmMask != NULL)
  477. DeleteObject(hbmMask);
  478. if (hbmImageCrop != NULL)
  479. DeleteObject(hbmImageCrop);
  480. if (hbmCache != NULL)
  481. DeleteObject(hbmCache);
  482. // Delete DCs
  483. DCCleanUp:
  484. if (hdcMask != NULL)
  485. DeleteDC(hdcMask);
  486. if (hdcMaskInv != NULL)
  487. DeleteDC(hdcMaskInv);
  488. if (hdcCache != NULL)
  489. DeleteDC(hdcCache);
  490. if (hdcImage != NULL)
  491. DeleteDC(hdcImage);
  492. if (hdcImageCrop != NULL)
  493. DeleteDC(hdcImageCrop);
  494. }
  495. }
  496. //////////////////////////////////////////////////////////////////////////////////////
  497. //
  498. //////////////////////////////////////////////////////////////////////////////////////
  499. PCCERT_CONTEXT GetSignersCert(CMSG_SIGNER_INFO const *pSignerInfo, HCERTSTORE hExtraStore, DWORD cStores, HCERTSTORE *rghStores)
  500. {
  501. DWORD i;
  502. PCCERT_CONTEXT pCertContext = NULL;
  503. CERT_INFO certInfo;
  504. DWORD chLocalStores = 0;
  505. HCERTSTORE *rghLocalStores = NULL;
  506. memset(&certInfo, 0, sizeof(CERT_INFO));
  507. certInfo.SerialNumber = pSignerInfo->SerialNumber;
  508. certInfo.Issuer = pSignerInfo->Issuer;
  509. pCertContext = CertGetSubjectCertificateFromStore(
  510. hExtraStore,
  511. X509_ASN_ENCODING,
  512. &certInfo);
  513. i = 0;
  514. while ((i<cStores) && (pCertContext == NULL))
  515. {
  516. pCertContext = CertGetSubjectCertificateFromStore(
  517. rghStores[i],
  518. X509_ASN_ENCODING,
  519. &certInfo);
  520. i++;
  521. }
  522. //
  523. // search the known stores if it was not found and caller wants to search them
  524. //
  525. if (pCertContext == NULL)
  526. {
  527. AllocAndOpenKnownStores(&chLocalStores, &rghLocalStores);
  528. i = 0;
  529. while ((pCertContext == NULL) && (i < chLocalStores))
  530. {
  531. pCertContext = CertGetSubjectCertificateFromStore(
  532. rghLocalStores[i++],
  533. X509_ASN_ENCODING,
  534. &certInfo);
  535. }
  536. FreeAndCloseKnownStores(chLocalStores, rghLocalStores);
  537. }
  538. return(pCertContext);
  539. }
  540. //////////////////////////////////////////////////////////////////////////////////////
  541. //
  542. //////////////////////////////////////////////////////////////////////////////////////
  543. BOOL fIsCatalogFile(CTL_USAGE *pSubjectUsage)
  544. {
  545. if (pSubjectUsage->cUsageIdentifier != 1)
  546. {
  547. return FALSE;
  548. }
  549. return (strcmp(pSubjectUsage->rgpszUsageIdentifier[0], szOID_CATALOG_LIST) == 0);
  550. }
  551. //////////////////////////////////////////////////////////////////////////////////////
  552. //
  553. //////////////////////////////////////////////////////////////////////////////////////
  554. typedef struct {
  555. LPSTR psz;
  556. LPCWSTR pwsz;
  557. LONG byteoffset;
  558. BOOL fStreamIn;
  559. } STREAMIN_HELPER_STRUCT;
  560. DWORD CALLBACK SetRicheditTextWCallback(
  561. DWORD_PTR dwCookie, // application-defined value
  562. LPBYTE pbBuff, // pointer to a buffer
  563. LONG cb, // number of bytes to read or write
  564. LONG *pcb // pointer to number of bytes transferred
  565. )
  566. {
  567. STREAMIN_HELPER_STRUCT *pHelpStruct = (STREAMIN_HELPER_STRUCT *) dwCookie;
  568. LONG lRemain = ((wcslen(pHelpStruct->pwsz) * sizeof(WCHAR)) - pHelpStruct->byteoffset);
  569. if (pHelpStruct->fStreamIn)
  570. {
  571. //
  572. // The whole string can be copied first time
  573. //
  574. if ((cb >= (LONG) (wcslen(pHelpStruct->pwsz) * sizeof(WCHAR))) && (pHelpStruct->byteoffset == 0))
  575. {
  576. memcpy(pbBuff, pHelpStruct->pwsz, wcslen(pHelpStruct->pwsz) * sizeof(WCHAR));
  577. *pcb = wcslen(pHelpStruct->pwsz) * sizeof(WCHAR);
  578. pHelpStruct->byteoffset = *pcb;
  579. }
  580. //
  581. // The whole string has been copied, so terminate the streamin callbacks
  582. // by setting the num bytes copied to 0
  583. //
  584. else if (((LONG)(wcslen(pHelpStruct->pwsz) * sizeof(WCHAR))) <= pHelpStruct->byteoffset)
  585. {
  586. *pcb = 0;
  587. }
  588. //
  589. // The rest of the string will fit in this buffer
  590. //
  591. else if (cb >= (LONG) ((wcslen(pHelpStruct->pwsz) * sizeof(WCHAR)) - pHelpStruct->byteoffset))
  592. {
  593. memcpy(
  594. pbBuff,
  595. ((BYTE *)pHelpStruct->pwsz) + pHelpStruct->byteoffset,
  596. ((wcslen(pHelpStruct->pwsz) * sizeof(WCHAR)) - pHelpStruct->byteoffset));
  597. *pcb = ((wcslen(pHelpStruct->pwsz) * sizeof(WCHAR)) - pHelpStruct->byteoffset);
  598. pHelpStruct->byteoffset += ((wcslen(pHelpStruct->pwsz) * sizeof(WCHAR)) - pHelpStruct->byteoffset);
  599. }
  600. //
  601. // copy as much as possible
  602. //
  603. else
  604. {
  605. memcpy(
  606. pbBuff,
  607. ((BYTE *)pHelpStruct->pwsz) + pHelpStruct->byteoffset,
  608. cb);
  609. *pcb = cb;
  610. pHelpStruct->byteoffset += cb;
  611. }
  612. }
  613. else
  614. {
  615. //
  616. // This is the EM_STREAMOUT which is only used during the testing of
  617. // the richedit2.0 functionality. (we know our buffer is 32 bytes)
  618. //
  619. if (cb <= 32)
  620. {
  621. memcpy(pHelpStruct->psz, pbBuff, cb);
  622. }
  623. *pcb = cb;
  624. }
  625. return 0;
  626. }
  627. DWORD CryptUISetRicheditTextW(HWND hwndDlg, UINT id, LPCWSTR pwsz)
  628. {
  629. EDITSTREAM editStream;
  630. STREAMIN_HELPER_STRUCT helpStruct;
  631. SetRicheditIMFOption(GetDlgItem(hwndDlg, id));
  632. //
  633. // setup the edit stream struct since it is the same no matter what
  634. //
  635. editStream.dwCookie = (DWORD_PTR) &helpStruct;
  636. editStream.dwError = 0;
  637. editStream.pfnCallback = SetRicheditTextWCallback;
  638. if (!fRichedit20Exists || !fRichedit20Usable(GetDlgItem(hwndDlg, id)))
  639. {
  640. SetDlgItemTextU(hwndDlg, id, pwsz);
  641. return 0;
  642. }
  643. helpStruct.pwsz = pwsz;
  644. helpStruct.byteoffset = 0;
  645. helpStruct.fStreamIn = TRUE;
  646. SendDlgItemMessageA(hwndDlg, id, EM_STREAMIN, SF_TEXT | SF_UNICODE, (LPARAM) &editStream);
  647. return editStream.dwError;
  648. }
  649. void SetRicheditIMFOption(HWND hWndRichEdit)
  650. {
  651. DWORD dwOptions;
  652. if (fRichedit20Exists && fRichedit20Usable(hWndRichEdit))
  653. {
  654. dwOptions = (DWORD)SendMessageA(hWndRichEdit, EM_GETLANGOPTIONS, 0, 0);
  655. dwOptions |= IMF_UIFONTS;
  656. SendMessageA(hWndRichEdit, EM_SETLANGOPTIONS, 0, dwOptions);
  657. }
  658. }
  659. BOOL fRichedit20UsableCheckMade = FALSE;
  660. BOOL fRichedit20UsableVar = FALSE;
  661. BOOL fRichedit20Usable(HWND hwndEdit)
  662. {
  663. EDITSTREAM editStream;
  664. STREAMIN_HELPER_STRUCT helpStruct;
  665. LPWSTR pwsz = L"Test String";
  666. LPSTR pwszCompare = "Test String";
  667. char compareBuf[32];
  668. if (fRichedit20UsableCheckMade)
  669. {
  670. return (fRichedit20UsableVar);
  671. }
  672. //
  673. // setup the edit stream struct since it is the same no matter what
  674. //
  675. editStream.dwCookie = (DWORD_PTR) &helpStruct;
  676. editStream.dwError = 0;
  677. editStream.pfnCallback = SetRicheditTextWCallback;
  678. helpStruct.pwsz = pwsz;
  679. helpStruct.byteoffset = 0;
  680. helpStruct.fStreamIn = TRUE;
  681. SendMessageA(hwndEdit, EM_SETSEL, 0, -1);
  682. SendMessageA(hwndEdit, EM_STREAMIN, SF_TEXT | SF_UNICODE | SFF_SELECTION, (LPARAM) &editStream);
  683. memset(&(compareBuf[0]), 0, 32 * sizeof(char));
  684. helpStruct.psz = compareBuf;
  685. helpStruct.fStreamIn = FALSE;
  686. SendMessageA(hwndEdit, EM_STREAMOUT, SF_TEXT, (LPARAM) &editStream);
  687. fRichedit20UsableVar = (strcmp(pwszCompare, compareBuf) == 0);
  688. fRichedit20UsableCheckMade = TRUE;
  689. SetWindowTextA(hwndEdit, "");
  690. return (fRichedit20UsableVar);
  691. }
  692. /*
  693. //--------------------------------------------------------------------------
  694. //
  695. // CryptUISetupFonts
  696. //
  697. //--------------------------------------------------------------------------
  698. BOOL
  699. CryptUISetupFonts(HFONT *pBoldFont)
  700. {
  701. //
  702. // Create the fonts we need based on the dialog font
  703. //
  704. NONCLIENTMETRICS ncm = {0};
  705. ncm.cbSize = sizeof(ncm);
  706. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  707. LOGFONT BoldLogFont = ncm.lfMessageFont;
  708. BoldLogFont.lfWeight = FW_BOLD;
  709. *pBoldFont = CreateFontIndirect(&BoldLogFont);
  710. if(*pBoldFont)
  711. return TRUE;
  712. else
  713. return FALSE;
  714. }
  715. //--------------------------------------------------------------------------
  716. //
  717. // CryptUIDestroyFonts
  718. //
  719. //--------------------------------------------------------------------------
  720. void
  721. CryptUIDestroyFonts(HFONT hBoldFont)
  722. {
  723. if( hBoldFont )
  724. {
  725. DeleteObject( hBoldFont );
  726. }
  727. }
  728. //--------------------------------------------------------------------------
  729. //
  730. // CryptUISetControlFont
  731. //
  732. //--------------------------------------------------------------------------
  733. void
  734. CryptUISetControlFont(HFONT hFont, HWND hwnd, INT nId)
  735. {
  736. if( hFont )
  737. {
  738. HWND hwndControl = GetDlgItem(hwnd, nId);
  739. if( hwndControl )
  740. {
  741. SendMessage(hwndControl, WM_SETFONT, (WPARAM) hFont, (LPARAM) TRUE);
  742. }
  743. }
  744. }*/
  745. //--------------------------------------------------------------------------
  746. //
  747. // IsValidURL
  748. //
  749. //--------------------------------------------------------------------------
  750. BOOL
  751. IsValidURL (LPWSTR pwszURL)
  752. {
  753. URL_COMPONENTSW UrlComponents;
  754. WCHAR pwszScheme[MAX_PATH+1];
  755. WCHAR pwszCanonicalUrl[INTERNET_MAX_PATH_LENGTH];
  756. DWORD dwNumChars = INTERNET_MAX_PATH_LENGTH;
  757. CERT_ALT_NAME_INFO NameInfo = {0, NULL};
  758. CRYPT_DATA_BLOB NameInfoBlob = {0, NULL};
  759. BOOL bResult = FALSE;
  760. if (NULL == pwszURL || 0 == wcslen(pwszURL))
  761. {
  762. goto ErrorExit;
  763. }
  764. if (!InternetCanonicalizeUrlW(pwszURL,
  765. pwszCanonicalUrl,
  766. &dwNumChars,
  767. ICU_BROWSER_MODE))
  768. {
  769. goto ErrorExit;
  770. }
  771. memset(&UrlComponents, 0, sizeof(URL_COMPONENTSW));
  772. UrlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
  773. UrlComponents.lpszScheme = pwszScheme;
  774. UrlComponents.dwSchemeLength = MAX_PATH;
  775. if (!InternetCrackUrlW(pwszCanonicalUrl,
  776. 0,
  777. 0,
  778. &UrlComponents))
  779. {
  780. goto ErrorExit;
  781. }
  782. NameInfo.cAltEntry = 1;
  783. NameInfo.rgAltEntry = (PCERT_ALT_NAME_ENTRY) malloc(sizeof(CERT_ALT_NAME_ENTRY));
  784. if (NULL == NameInfo.rgAltEntry)
  785. {
  786. goto ErrorExit;
  787. }
  788. NameInfo.rgAltEntry[0].dwAltNameChoice = 7;
  789. NameInfo.rgAltEntry[0].pwszURL = pwszURL;
  790. if (!CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  791. X509_ALTERNATE_NAME,
  792. &NameInfo,
  793. NULL,
  794. &NameInfoBlob.cbData))
  795. {
  796. goto ErrorExit;
  797. }
  798. NameInfoBlob.pbData = (BYTE *) malloc(NameInfoBlob.cbData);
  799. if (NULL == NameInfoBlob.pbData)
  800. {
  801. goto ErrorExit;
  802. }
  803. if (!CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  804. X509_ALTERNATE_NAME,
  805. &NameInfo,
  806. NameInfoBlob.pbData,
  807. &NameInfoBlob.cbData))
  808. {
  809. goto ErrorExit;
  810. }
  811. bResult = TRUE;
  812. CommonExit:
  813. if (NameInfo.rgAltEntry)
  814. {
  815. free(NameInfo.rgAltEntry);
  816. }
  817. if (NameInfoBlob.pbData)
  818. {
  819. free(NameInfoBlob.pbData);
  820. }
  821. return bResult;
  822. ErrorExit:
  823. bResult = FALSE;
  824. goto CommonExit;
  825. }
  826. //--------------------------------------------------------------------------
  827. //
  828. // FormatMessageUnicodeIds
  829. //
  830. //--------------------------------------------------------------------------
  831. LPWSTR FormatMessageUnicodeIds (UINT ids, ...)
  832. {
  833. va_list argList;
  834. LPWSTR pwszMessage = NULL;
  835. WCHAR wszFormat[CRYPTUI_MAX_STRING_SIZE] = L"";
  836. if (!LoadStringU(HinstDll, ids, wszFormat, CRYPTUI_MAX_STRING_SIZE - 1))
  837. {
  838. goto LoadStringError;
  839. }
  840. va_start(argList, ids);
  841. pwszMessage = FormatMessageUnicode(wszFormat, &argList);
  842. va_end(argList);
  843. CommonReturn:
  844. return pwszMessage;
  845. ErrorReturn:
  846. if (pwszMessage)
  847. {
  848. LocalFree(pwszMessage);
  849. }
  850. pwszMessage = NULL;
  851. goto CommonReturn;
  852. TRACE_ERROR(LoadStringError);
  853. }
  854. //--------------------------------------------------------------------------
  855. //
  856. // FormatMessageUnicodeString
  857. //
  858. //--------------------------------------------------------------------------
  859. LPWSTR FormatMessageUnicodeString (LPWSTR pwszFormat, ...)
  860. {
  861. va_list argList;
  862. LPWSTR pwszMessage = NULL;
  863. va_start(argList, pwszFormat);
  864. pwszMessage = FormatMessageUnicode(pwszFormat, &argList);
  865. va_end(argList);
  866. return pwszMessage;
  867. }
  868. //--------------------------------------------------------------------------
  869. //
  870. // FormatMessageUnicode
  871. //
  872. //--------------------------------------------------------------------------
  873. LPWSTR FormatMessageUnicode (LPWSTR pwszFormat, va_list * pArgList)
  874. {
  875. DWORD cbMsg = 0;
  876. LPWSTR pwszMessage = NULL;
  877. if (NULL == pwszFormat || NULL == pArgList)
  878. {
  879. goto InvalidArgErr;
  880. }
  881. if (!(cbMsg = FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  882. pwszFormat,
  883. 0, // dwMessageId
  884. 0, // dwLanguageId
  885. (LPWSTR) &pwszMessage,
  886. 0, // minimum size to allocate
  887. pArgList)))
  888. {
  889. //
  890. // FormatMessageU() will return 0, if data to be formatted is empty.
  891. // In this case, we return pointer to an empty string, instead of NULL
  892. // pointer which actually is used for error case.
  893. //
  894. if (0 == GetLastError())
  895. {
  896. if (NULL == (pwszMessage = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR))))
  897. {
  898. goto MemoryError;
  899. }
  900. }
  901. else
  902. {
  903. goto FormatMessageError;
  904. }
  905. }
  906. assert(NULL != pwszMessage);
  907. CommonReturn:
  908. return pwszMessage;
  909. ErrorReturn:
  910. if (pwszMessage)
  911. {
  912. LocalFree(pwszMessage);
  913. }
  914. pwszMessage = NULL;
  915. goto CommonReturn;
  916. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  917. SET_ERROR(MemoryError, E_OUTOFMEMORY);
  918. TRACE_ERROR(FormatMessageError);
  919. }