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.

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