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.

811 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: csdisp.cpp
  8. //
  9. // Contents: IDispatch helper functions
  10. //
  11. // History: 09-Dec-96 vich created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <pch.cpp>
  15. #pragma hdrstop
  16. #include <stdlib.h>
  17. #include "csdisp.h"
  18. #define __dwFILE__ __dwFILE_CERTLIB_DISPATCH_CPP__
  19. #ifndef DBG_DISPATCH
  20. # define DBG_DISPATCH 0
  21. #endif
  22. TCHAR szRegKeyClsidValue[] = TEXT("");
  23. HRESULT
  24. DispatchGetReturnValue(
  25. VARIANT *pvar,
  26. IN LONG Type,
  27. OUT VOID *pretval)
  28. {
  29. HRESULT hr = S_OK;
  30. if (VT_EMPTY == pvar->vt)
  31. {
  32. hr = CERTSRV_E_PROPERTY_EMPTY;
  33. _JumpError2(hr, error, "VT_EMPTY", hr);
  34. }
  35. if (Type != pvar->vt)
  36. {
  37. DBGPRINT((
  38. DBG_SS_CERTLIB,
  39. "pvar->vt=%x, expected %x\n",
  40. pvar->vt,
  41. Type));
  42. hr = TYPE_E_WRONGTYPEKIND;
  43. _JumpError(hr, error, "pvar->vt != Type");
  44. }
  45. switch (Type)
  46. {
  47. case VT_I4:
  48. *(LONG *) pretval = pvar->lVal;
  49. break;
  50. case VT_DATE:
  51. *(DATE *) pretval = pvar->date;
  52. break;
  53. case VT_BSTR:
  54. *(BSTR *) pretval = pvar->bstrVal;
  55. pvar->vt = VT_EMPTY;
  56. break;
  57. case VT_DISPATCH:
  58. *(IDispatch **) pretval = pvar->pdispVal;
  59. pvar->vt = VT_EMPTY;
  60. break;
  61. default:
  62. hr = E_INVALIDARG;
  63. goto error;
  64. }
  65. error:
  66. return(hr);
  67. }
  68. HRESULT
  69. DispatchSetErrorInfoSub(
  70. IN HRESULT hrError,
  71. OPTIONAL IN WCHAR const *pwszIDispatchMethod,
  72. OPTIONAL IN WCHAR const *pwszDescription,
  73. OPTIONAL IN WCHAR const *pwszSource,
  74. OPTIONAL IN IID const *piid,
  75. OPTIONAL IN WCHAR const *pwszHelpFile,
  76. IN DWORD dwHelpFileContext)
  77. {
  78. HRESULT hr;
  79. WCHAR const *pwszError = NULL;
  80. ICreateErrorInfo *pCreateErrorInfo = NULL;
  81. IErrorInfo *pErrorInfo = NULL;
  82. #ifdef DBG_CERTSRV_DEBUG_PRINT
  83. if (NULL != pwszIDispatchMethod || DbgIsSSActive(DBG_SS_CERTLIBI))
  84. #else
  85. if (NULL != pwszIDispatchMethod)
  86. #endif
  87. {
  88. pwszError = myGetErrorMessageText(hrError, TRUE);
  89. if (NULL != pwszIDispatchMethod)
  90. {
  91. CONSOLEPRINT1((
  92. MAXDWORD,
  93. "IDispatch->Invoke(%ws) Exception:\n",
  94. pwszIDispatchMethod));
  95. }
  96. else
  97. {
  98. CONSOLEPRINT0((MAXDWORD, "COM Error:\n"));
  99. }
  100. CONSOLEPRINT5((
  101. MAXDWORD,
  102. " Source=%ws\n Description=%ws\n HelpFile=%ws[%x]\n %ws\n",
  103. pwszSource,
  104. pwszDescription,
  105. pwszHelpFile,
  106. dwHelpFileContext,
  107. pwszError));
  108. }
  109. hr = CreateErrorInfo(&pCreateErrorInfo);
  110. _JumpIfError(hr, error, "CreateErrorInfo");
  111. if (NULL != piid)
  112. {
  113. hr = pCreateErrorInfo->SetGUID(*piid);
  114. _PrintIfError(hr, "SetGUID");
  115. }
  116. if (NULL != pwszSource)
  117. {
  118. hr = pCreateErrorInfo->SetSource(const_cast<WCHAR *>(pwszSource));
  119. _PrintIfError(hr, "SetSource");
  120. }
  121. if (NULL != pwszDescription)
  122. {
  123. hr = pCreateErrorInfo->SetDescription(
  124. const_cast<WCHAR *>(pwszDescription));
  125. _PrintIfError(hr, "SetDescription");
  126. }
  127. if (NULL != pwszHelpFile)
  128. {
  129. hr = pCreateErrorInfo->SetHelpFile(const_cast<WCHAR *>(pwszHelpFile));
  130. _PrintIfError(hr, "SetHelpFile");
  131. hr = pCreateErrorInfo->SetHelpContext(dwHelpFileContext);
  132. _PrintIfError(hr, "SetHelpContext");
  133. }
  134. hr = pCreateErrorInfo->QueryInterface(
  135. IID_IErrorInfo,
  136. (VOID **) &pErrorInfo);
  137. _JumpIfError(hr, error, "QueryInterface");
  138. SetErrorInfo(0, pErrorInfo);
  139. hr = S_OK;
  140. error:
  141. if (NULL != pwszError)
  142. {
  143. LocalFree(const_cast<WCHAR *>(pwszError));
  144. }
  145. if (NULL != pErrorInfo)
  146. {
  147. pErrorInfo->Release();
  148. }
  149. if (NULL != pCreateErrorInfo)
  150. {
  151. pCreateErrorInfo->Release();
  152. }
  153. return(hr);
  154. }
  155. HRESULT
  156. DispatchInvoke(
  157. IN DISPATCHINTERFACE *pDispatchInterface,
  158. IN LONG MethodIndex,
  159. IN DWORD cvar,
  160. IN VARIANT avar[],
  161. IN LONG Type,
  162. OUT VOID *pretval)
  163. {
  164. HRESULT hr;
  165. DISPATCHTABLE const *pdt;
  166. EXCEPINFO excepinfo;
  167. VARIANT varResult;
  168. DISPPARAMS parms;
  169. unsigned iArgErr;
  170. DISPID *adispid;
  171. VariantInit(&varResult);
  172. CSASSERT(NULL != pDispatchInterface->pDispatchTable);
  173. CSASSERT((DWORD) MethodIndex < pDispatchInterface->m_cDispatchTable);
  174. pdt = &pDispatchInterface->pDispatchTable[MethodIndex];
  175. adispid = &pDispatchInterface->m_adispid[pdt->idispid];
  176. CSASSERT(NULL != pDispatchInterface->m_adispid);
  177. CSASSERT(pdt->idispid + pdt->cdispid <= pDispatchInterface->m_cdispid);
  178. parms.rgvarg = avar;
  179. parms.rgdispidNamedArgs = &adispid[1];
  180. parms.cArgs = pdt->cdispid - 1;
  181. parms.cNamedArgs = parms.cArgs;
  182. if (parms.cArgs != cvar)
  183. {
  184. CSASSERT(parms.cArgs == cvar);
  185. hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
  186. _JumpError(hr, error, "cvar");
  187. }
  188. CSASSERT(NULL != pDispatchInterface->pDispatch);
  189. hr = pDispatchInterface->pDispatch->Invoke(
  190. adispid[0],
  191. IID_NULL,
  192. LOCALE_SYSTEM_DEFAULT,
  193. DISPATCH_METHOD,
  194. &parms,
  195. &varResult,
  196. &excepinfo,
  197. &iArgErr);
  198. if (S_OK != hr)
  199. {
  200. _PrintErrorStr(hr, "Invoke", pdt->apszNames[0]);
  201. if (DISP_E_EXCEPTION == hr)
  202. {
  203. HRESULT hr2;
  204. if (FAILED(excepinfo.scode))
  205. {
  206. hr = excepinfo.scode;
  207. }
  208. hr2 = DispatchSetErrorInfoSub(
  209. hr,
  210. pdt->apszNames[0],
  211. excepinfo.bstrDescription,
  212. excepinfo.bstrSource,
  213. pDispatchInterface->GetIID(),
  214. excepinfo.bstrHelpFile,
  215. excepinfo.dwHelpContext);
  216. _PrintIfError(hr2, "DispatchSetErrorInfoSub");
  217. }
  218. goto error;
  219. }
  220. if (CLSCTX_INPROC_SERVER != pDispatchInterface->m_ClassContext)
  221. {
  222. myRegisterMemAlloc(&varResult, 0, CSM_VARIANT);
  223. }
  224. if (NULL != pretval)
  225. {
  226. hr = DispatchGetReturnValue(&varResult, Type, pretval);
  227. _JumpIfErrorStr2(
  228. hr,
  229. error,
  230. "DispatchGetReturnValue",
  231. pdt->apszNames[0],
  232. CERTSRV_E_PROPERTY_EMPTY);
  233. }
  234. error:
  235. VariantClear(&varResult);
  236. return(hr);
  237. }
  238. HRESULT
  239. DispatchGetIds(
  240. IN IDispatch *pDispatch,
  241. IN DWORD cDispatchTable,
  242. IN OUT DISPATCHTABLE *pDispatchTable,
  243. IN OUT DISPATCHINTERFACE *pDispatchInterface)
  244. {
  245. HRESULT hr = S_OK;
  246. DISPATCHTABLE *pdt;
  247. DISPATCHTABLE *pdtEnd;
  248. DISPID *adispid = NULL;
  249. DWORD idispid;
  250. pdtEnd = &pDispatchTable[cDispatchTable];
  251. pDispatchInterface->m_cdispid = 0;
  252. for (pdt = pDispatchTable; pdt < pdtEnd; pdt++)
  253. {
  254. if (0 == pdt->idispid)
  255. {
  256. pdt->idispid = pDispatchInterface->m_cdispid;
  257. }
  258. CSASSERT(pdt->idispid == pDispatchInterface->m_cdispid);
  259. pDispatchInterface->m_cdispid += pdt->cdispid;
  260. }
  261. adispid = (DISPID *) LocalAlloc(
  262. LMEM_FIXED,
  263. pDispatchInterface->m_cdispid * sizeof(adispid[0]));
  264. if (NULL == adispid)
  265. {
  266. hr = E_OUTOFMEMORY;
  267. _JumpError(hr, error, "LocalAlloc");
  268. }
  269. idispid = 0;
  270. for (pdt = pDispatchTable; pdt < pdtEnd; pdt++)
  271. {
  272. CSASSERT(idispid + pdt->cdispid <= pDispatchInterface->m_cdispid);
  273. hr = pDispatch->GetIDsOfNames(
  274. IID_NULL,
  275. pdt->apszNames,
  276. pdt->cdispid,
  277. LOCALE_SYSTEM_DEFAULT,
  278. &adispid[idispid]);
  279. #if DBG_CERTSRV
  280. if (S_OK != hr || CSExpr(DBG_DISPATCH))
  281. {
  282. DWORD i;
  283. DBGPRINT((
  284. MAXDWORD,
  285. "GetIDsOfNames(%ws) --> %x, dispid=%x" szLPAREN,
  286. pdt->apszNames[0],
  287. hr,
  288. adispid[idispid]));
  289. for (i = 1; i < pdt->cdispid; i++)
  290. {
  291. DBGPRINT((
  292. MAXDWORD,
  293. "%ws%x",
  294. i == 1? L"" : L", ",
  295. adispid[idispid + i]));
  296. }
  297. DBGPRINT((MAXDWORD, szRPAREN "\n"));
  298. }
  299. #endif
  300. _JumpIfError(hr, error, "GetIDsOfNames");
  301. idispid += pdt->cdispid;
  302. }
  303. pDispatchInterface->m_cDispatchTable = cDispatchTable;
  304. pDispatchInterface->pDispatchTable = pDispatchTable;
  305. pDispatchInterface->m_adispid = adispid;
  306. adispid = NULL;
  307. error:
  308. if (NULL != adispid)
  309. {
  310. LocalFree(adispid);
  311. }
  312. return(hr);
  313. }
  314. HRESULT
  315. DispatchSetup(
  316. IN DWORD Flags,
  317. IN DWORD ClassContext,
  318. OPTIONAL IN TCHAR const *pszProgID, // for IDispatch
  319. OPTIONAL IN CLSID const *pclsid, // for COM
  320. OPTIONAL IN IID const *piid, // for COM
  321. IN DWORD cDispatchTable, // for IDispatch
  322. IN OUT DISPATCHTABLE *pDispatchTable,
  323. IN OUT DISPATCHINTERFACE *pDispatchInterface)
  324. {
  325. HRESULT hr;
  326. CLSID clsid;
  327. pDispatchInterface->SetIID(piid);
  328. for (;;)
  329. {
  330. pDispatchInterface->pDispatch = NULL;
  331. pDispatchInterface->pUnknown = NULL;
  332. pDispatchInterface->m_adispid = NULL;
  333. CSASSERT(NULL != pszProgID || DISPSETUP_COM == Flags);
  334. CSASSERT(NULL != pclsid || DISPSETUP_IDISPATCH == Flags);
  335. CSASSERT(NULL != piid || DISPSETUP_IDISPATCH == Flags);
  336. if (DISPSETUP_IDISPATCH == Flags)
  337. {
  338. // use win32 version, not our own hack
  339. hr = CLSIDFromProgID(pszProgID, &clsid);
  340. _JumpIfError2(
  341. hr,
  342. error,
  343. "ClassNameToCLSID",
  344. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  345. pclsid = &clsid;
  346. piid = &IID_IDispatch;
  347. }
  348. hr = CoCreateInstance(
  349. *pclsid,
  350. NULL, // pUnkOuter
  351. ClassContext,
  352. *piid,
  353. DISPSETUP_IDISPATCH == Flags?
  354. (VOID **) &pDispatchInterface->pDispatch :
  355. (VOID **) &pDispatchInterface->pUnknown);
  356. #if DBG_DISPATCH
  357. printf("CoCreateInstance(%x) --> %x\n", Flags, hr);
  358. #endif
  359. if (S_OK != hr)
  360. {
  361. _PrintError2(hr, "CoCreateInstance", E_NOINTERFACE);
  362. if (DISPSETUP_COMFIRST != Flags)
  363. {
  364. _JumpError2(hr, error, "CoCreateInstance", E_NOINTERFACE);
  365. }
  366. Flags = DISPSETUP_IDISPATCH;
  367. continue;
  368. }
  369. pDispatchInterface->m_ClassContext = ClassContext;
  370. break;
  371. }
  372. if (DISPSETUP_IDISPATCH == Flags)
  373. {
  374. hr = DispatchGetIds(
  375. pDispatchInterface->pDispatch,
  376. cDispatchTable,
  377. pDispatchTable,
  378. pDispatchInterface);
  379. if (S_OK != hr)
  380. {
  381. DispatchRelease(pDispatchInterface);
  382. _JumpError(hr, error, "DispatchGetIds");
  383. }
  384. }
  385. error:
  386. return(hr);
  387. }
  388. HRESULT
  389. DispatchSetup2(
  390. IN DWORD Flags,
  391. IN DWORD ClassContext,
  392. IN WCHAR const *pwszClass, // wszRegKeyAdminClsid
  393. IN CLSID const *pclsid,
  394. IN DWORD cver,
  395. IN IID const * const *ppiid, // cver elements
  396. IN DWORD const *pcDispatch, // cver elements
  397. IN OUT DISPATCHTABLE *pDispatchTable,
  398. IN OUT DISPATCHINTERFACE *pDispatchInterface)
  399. {
  400. HRESULT hr = E_INVALIDARG;
  401. CSASSERT(0 < cver);
  402. for ( ; 0 < cver; cver--, ppiid++, pcDispatch++)
  403. {
  404. hr = DispatchSetup(
  405. Flags,
  406. ClassContext,
  407. pwszClass,
  408. pclsid,
  409. *ppiid,
  410. *pcDispatch,
  411. pDispatchTable,
  412. pDispatchInterface);
  413. if (S_OK == hr)
  414. {
  415. pDispatchInterface->m_dwVersion = cver;
  416. pDispatchInterface->pDispatchTable = pDispatchTable;
  417. break;
  418. }
  419. if (1 == cver)
  420. {
  421. _JumpErrorStr(hr, error, "DispatchSetup", pwszClass);
  422. }
  423. _PrintErrorStr2(hr, "DispatchSetup", pwszClass, hr);
  424. }
  425. error:
  426. return(hr);
  427. }
  428. VOID
  429. DispatchRelease(
  430. IN OUT DISPATCHINTERFACE *pDispatchInterface)
  431. {
  432. if (NULL != pDispatchInterface->pDispatch)
  433. {
  434. pDispatchInterface->pDispatch->Release();
  435. pDispatchInterface->pDispatch = NULL;
  436. }
  437. if (NULL != pDispatchInterface->pUnknown)
  438. {
  439. pDispatchInterface->pUnknown->Release();
  440. pDispatchInterface->pUnknown = NULL;
  441. }
  442. if (NULL != pDispatchInterface->m_adispid)
  443. {
  444. LocalFree(pDispatchInterface->m_adispid);
  445. pDispatchInterface->m_adispid = NULL;
  446. }
  447. }
  448. BOOL
  449. myConvertWszToBstr(
  450. OUT BSTR *pbstr,
  451. IN WCHAR const *pwc,
  452. IN LONG cb)
  453. {
  454. HRESULT hr;
  455. BSTR bstr;
  456. bstr = NULL;
  457. if (NULL != pwc)
  458. {
  459. if (-1 == cb)
  460. {
  461. cb = wcslen(pwc) * sizeof(WCHAR);
  462. }
  463. bstr = SysAllocStringByteLen((char const *) pwc, cb);
  464. if (NULL == bstr)
  465. {
  466. hr = E_OUTOFMEMORY;
  467. _JumpError(hr, error, "SysAllocStringByteLen");
  468. }
  469. }
  470. if (NULL != *pbstr)
  471. {
  472. SysFreeString(*pbstr);
  473. }
  474. *pbstr = bstr;
  475. hr = S_OK;
  476. error:
  477. if (S_OK != hr)
  478. {
  479. SetLastError(hr);
  480. }
  481. return(S_OK == hr);
  482. }
  483. BOOL
  484. myConvertSzToBstr(
  485. OUT BSTR *pbstr,
  486. IN CHAR const *pch,
  487. IN LONG cch)
  488. {
  489. HRESULT hr;
  490. BSTR bstr = NULL;
  491. LONG cwc = 0;
  492. if (-1 == cch)
  493. {
  494. cch = strlen(pch);
  495. }
  496. CSASSERT(0 != cch);
  497. for (;;)
  498. {
  499. cwc = MultiByteToWideChar(GetACP(), 0, pch, cch, bstr, cwc);
  500. if (0 >= cwc)
  501. {
  502. hr = myHLastError();
  503. _PrintError(hr, "MultiByteToWideChar");
  504. if (NULL != bstr)
  505. {
  506. SysFreeString(bstr);
  507. }
  508. break;
  509. }
  510. if (NULL != bstr)
  511. {
  512. bstr[cwc] = L'\0';
  513. if (NULL != *pbstr)
  514. {
  515. SysFreeString(*pbstr);
  516. }
  517. *pbstr = bstr;
  518. hr = S_OK;
  519. break;
  520. }
  521. bstr = SysAllocStringLen(NULL, cwc);
  522. if (NULL == bstr)
  523. {
  524. hr = E_OUTOFMEMORY;
  525. break;
  526. }
  527. }
  528. if (S_OK != hr)
  529. {
  530. SetLastError(hr);
  531. }
  532. return(S_OK == hr);
  533. }
  534. HRESULT
  535. DecodeCertString(
  536. IN BSTR const bstrIn,
  537. IN DWORD Flags,
  538. OUT BYTE **ppbOut,
  539. OUT DWORD *pcbOut)
  540. {
  541. HRESULT hr;
  542. DWORD dwSize;
  543. *ppbOut = NULL;
  544. CSASSERT(CSExpr(CR_IN_BASE64HEADER == CRYPT_STRING_BASE64HEADER));
  545. CSASSERT(CSExpr(CR_IN_BASE64 == CRYPT_STRING_BASE64));
  546. CSASSERT(CSExpr(CR_IN_BINARY == CRYPT_STRING_BINARY));
  547. switch (Flags)
  548. {
  549. case CRYPT_STRING_BASE64HEADER:
  550. case CRYPT_STRING_BASE64:
  551. case CRYPT_STRING_BASE64REQUESTHEADER:
  552. case CRYPT_STRING_HEX:
  553. case CRYPT_STRING_HEXASCII:
  554. case CRYPT_STRING_BASE64_ANY:
  555. case CRYPT_STRING_HEX_ANY:
  556. case CRYPT_STRING_BASE64X509CRLHEADER:
  557. case CRYPT_STRING_HEXADDR:
  558. case CRYPT_STRING_HEXASCIIADDR:
  559. CSASSERT(sizeof(WCHAR) * wcslen(bstrIn) == SysStringByteLen(bstrIn));
  560. // FALLTHROUGH
  561. case CRYPT_STRING_ANY:
  562. dwSize = (SysStringByteLen(bstrIn) + sizeof(WCHAR) - 1) / sizeof(WCHAR);
  563. break;
  564. case CRYPT_STRING_BINARY:
  565. dwSize = SysStringByteLen(bstrIn);
  566. break;
  567. default:
  568. hr = E_INVALIDARG;
  569. _JumpError(hr, error, "Flags");
  570. }
  571. hr = myCryptStringToBinary(
  572. bstrIn,
  573. dwSize,
  574. Flags,
  575. ppbOut,
  576. pcbOut,
  577. NULL,
  578. NULL);
  579. _JumpIfError(hr, error, "myCryptStringToBinary");
  580. if (CRYPT_STRING_ANY == Flags &&
  581. (SysStringByteLen(bstrIn) & (sizeof(WCHAR) - 1)))
  582. {
  583. (*pcbOut)--;
  584. CSASSERT(SysStringByteLen(bstrIn) == *pcbOut);
  585. }
  586. hr = S_OK;
  587. error:
  588. return(hr);
  589. }
  590. HRESULT
  591. EncodeCertString(
  592. IN BYTE const *pbIn,
  593. IN DWORD cbIn,
  594. IN DWORD Flags,
  595. OUT BSTR *pbstrOut)
  596. {
  597. HRESULT hr = E_INVALIDARG;
  598. WCHAR *pwcCert = NULL;
  599. DWORD cbCert;
  600. CSASSERT(CSExpr(CR_OUT_BASE64HEADER == CRYPT_STRING_BASE64HEADER));
  601. CSASSERT(CSExpr(CR_OUT_BASE64 == CRYPT_STRING_BASE64));
  602. CSASSERT(CSExpr(CR_OUT_BINARY == CRYPT_STRING_BINARY));
  603. //CSASSERT(CSExpr(CR_OUT_BASE64REQUESTHEADER == CRYPT_STRING_BASE64REQUESTHEADER));
  604. //CSASSERT(CSExpr(CR_OUT_HEX == CRYPT_STRING_HEX));
  605. CSASSERT(CSExpr(CV_OUT_BASE64HEADER == CRYPT_STRING_BASE64HEADER));
  606. CSASSERT(CSExpr(CV_OUT_BASE64 == CRYPT_STRING_BASE64));
  607. CSASSERT(CSExpr(CV_OUT_BINARY == CRYPT_STRING_BINARY));
  608. CSASSERT(CSExpr(CV_OUT_BASE64REQUESTHEADER == CRYPT_STRING_BASE64REQUESTHEADER));
  609. CSASSERT(CSExpr(CV_OUT_HEX == CRYPT_STRING_HEX));
  610. CSASSERT(CSExpr(CV_OUT_HEXASCII == CRYPT_STRING_HEXASCII));
  611. CSASSERT(CSExpr(CV_OUT_BASE64X509CRLHEADER == CRYPT_STRING_BASE64X509CRLHEADER));
  612. CSASSERT(CSExpr(CV_OUT_HEXADDR == CRYPT_STRING_HEXADDR));
  613. CSASSERT(CSExpr(CV_OUT_HEXASCIIADDR == CRYPT_STRING_HEXASCIIADDR));
  614. if (NULL == pbIn || (~CR_OUT_ENCODEMASK & Flags))
  615. {
  616. goto error;
  617. }
  618. switch (CR_OUT_ENCODEMASK & Flags)
  619. {
  620. case CRYPT_STRING_BASE64HEADER:
  621. case CRYPT_STRING_BASE64:
  622. case CRYPT_STRING_BASE64REQUESTHEADER:
  623. case CRYPT_STRING_HEX:
  624. case CRYPT_STRING_HEXASCII:
  625. case CRYPT_STRING_BASE64X509CRLHEADER:
  626. case CRYPT_STRING_HEXADDR:
  627. case CRYPT_STRING_HEXASCIIADDR:
  628. hr = myCryptBinaryToString(
  629. pbIn,
  630. cbIn,
  631. CR_OUT_ENCODEMASK & Flags,
  632. &pwcCert);
  633. _JumpIfError(hr, error, "myCryptBinaryToString");
  634. cbCert = sizeof(WCHAR) * wcslen(pwcCert);
  635. break;
  636. case CRYPT_STRING_BINARY:
  637. pwcCert = (WCHAR *) pbIn;
  638. cbCert = cbIn;
  639. hr = S_OK;
  640. break;
  641. default:
  642. goto error;
  643. }
  644. if (!ConvertWszToBstr(pbstrOut, pwcCert, cbCert))
  645. {
  646. hr = E_OUTOFMEMORY;
  647. }
  648. hr = S_OK;
  649. error:
  650. if (NULL != pwcCert && pwcCert != (WCHAR *) pbIn)
  651. {
  652. LocalFree(pwcCert);
  653. }
  654. return(hr);
  655. }
  656. HRESULT
  657. DispatchSetErrorInfo(
  658. IN HRESULT hrError,
  659. IN WCHAR const *pwszDescription,
  660. OPTIONAL IN WCHAR const *pwszProgId,
  661. OPTIONAL IN IID const *piid)
  662. {
  663. HRESULT hr;
  664. WCHAR const *pwszError = NULL;
  665. WCHAR *pwszText = NULL;
  666. if (NULL == pwszDescription)
  667. {
  668. hr = E_POINTER;
  669. _JumpError(hr, error, "NULL pointer");
  670. }
  671. CSASSERT(FAILED(hrError));
  672. pwszError = myGetErrorMessageText(hrError, TRUE);
  673. if (NULL == pwszError)
  674. {
  675. _PrintError(E_OUTOFMEMORY, "myGetErrorMessageText");
  676. }
  677. else
  678. {
  679. pwszText = (WCHAR *) LocalAlloc(
  680. LMEM_FIXED,
  681. (wcslen(pwszDescription) + 1 + wcslen(pwszError) + 1) *
  682. sizeof(WCHAR));
  683. if (NULL == pwszText)
  684. {
  685. _PrintError(E_OUTOFMEMORY, "LocalAlloc");
  686. }
  687. else
  688. {
  689. wcscpy(pwszText, pwszDescription);
  690. wcscat(pwszText, L" ");
  691. wcscat(pwszText, pwszError);
  692. }
  693. }
  694. hr = DispatchSetErrorInfoSub(
  695. hrError,
  696. NULL, // pwszIDispatchMethod
  697. NULL != pwszText?
  698. pwszText : const_cast<WCHAR *>(pwszDescription),
  699. pwszProgId,
  700. piid,
  701. NULL, // pwszHelpFile
  702. 0); // dwHelpFileContext
  703. _PrintIfError(hr, "DispatchSetErrorInfoSub");
  704. error:
  705. if (NULL != pwszText)
  706. {
  707. LocalFree(pwszText);
  708. }
  709. if (NULL != pwszError)
  710. {
  711. LocalFree(const_cast<WCHAR *>(pwszError));
  712. }
  713. return(hrError); // return input error!
  714. }