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.

888 lines
21 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: misc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <stdafx.h>
  11. // sddl.h requires this value to be at least
  12. // 0x0500. Bump it up if necessary. NOTE: This
  13. // 'bump' comes after all other H files that may
  14. // be sensitive to this value.
  15. #if(_WIN32_WINNT < 0x500)
  16. #undef _WIN32_WINNT
  17. #define _WIN32_WINNT 0x0500
  18. #endif
  19. #include <sddl.h>
  20. #include <shlobj.h>
  21. #include <dsclient.h>
  22. #include <dsgetdc.h>
  23. #include <lm.h>
  24. #include <lmapibuf.h>
  25. #include <objsel.h>
  26. CLIPFORMAT g_cfDsObjectPicker = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  27. // returns (if cstr.IsEmpty()) ? NULL : cstr)
  28. LPCWSTR GetNullMachineName(CString* pcstr)
  29. {
  30. LPCWSTR szMachine = (pcstr->IsEmpty()) ? NULL : (LPCWSTR)*pcstr;
  31. return szMachine;
  32. }
  33. BOOL StringFromDurationUnit(DWORD dwExpirationUnits, CString* pcstr, BOOL fLocalized)
  34. {
  35. if (NULL == pcstr)
  36. return FALSE;
  37. UINT uiRsc = 0;
  38. switch (dwExpirationUnits)
  39. {
  40. case(ENUM_PERIOD_YEARS):
  41. if (fLocalized)
  42. uiRsc = IDS_PERIOD_YEARS;
  43. else
  44. *pcstr = wszPERIODYEARS;
  45. break;
  46. case(ENUM_PERIOD_MONTHS):
  47. if (fLocalized)
  48. uiRsc = IDS_PERIOD_MONTHS;
  49. else
  50. *pcstr = wszPERIODMONTHS;
  51. break;
  52. case(ENUM_PERIOD_WEEKS):
  53. if (fLocalized)
  54. uiRsc = IDS_PERIOD_WEEKS;
  55. else
  56. *pcstr = wszPERIODWEEKS;
  57. break;
  58. case(ENUM_PERIOD_DAYS):
  59. if (fLocalized)
  60. uiRsc = IDS_PERIOD_DAYS;
  61. else
  62. *pcstr = wszPERIODDAYS;
  63. break;
  64. default:
  65. break;
  66. }
  67. if (uiRsc)
  68. pcstr->LoadString(uiRsc);
  69. return !pcstr->IsEmpty();
  70. }
  71. /////////////////////////////////////////
  72. // fxns to load/save cstrings to a streams
  73. STDMETHODIMP CStringLoad(CString& cstr, IStream *pStm)
  74. {
  75. ASSERT(pStm);
  76. HRESULT hr;
  77. DWORD cbSize=0;
  78. ULONG nBytesRead;
  79. // get cbSize (bytes)
  80. hr = pStm->Read(&cbSize, sizeof(cbSize), &nBytesRead);
  81. ASSERT(SUCCEEDED(hr) && (nBytesRead == sizeof(cbSize)) );
  82. if (FAILED(hr))
  83. return E_FAIL;
  84. // get string
  85. hr = pStm->Read(cstr.GetBuffer(cbSize), cbSize, &nBytesRead);
  86. ASSERT(SUCCEEDED(hr) && (nBytesRead == cbSize));
  87. cstr.ReleaseBuffer();
  88. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  89. }
  90. STDMETHODIMP CStringSave(CString& cstr, IStream *pStm, BOOL fClearDirty)
  91. {
  92. // Write the string
  93. DWORD cbSize = (cstr.GetLength()+1)*sizeof(WCHAR);
  94. ULONG nBytesWritten;
  95. HRESULT hr;
  96. // write size in bytes
  97. hr = pStm->Write(&cbSize, sizeof(cbSize), &nBytesWritten);
  98. ASSERT(SUCCEEDED(hr) && (nBytesWritten == sizeof(cbSize)) );
  99. if (FAILED(hr))
  100. return STG_E_CANTSAVE;
  101. // write string
  102. hr = pStm->Write((LPCWSTR)cstr, cbSize, &nBytesWritten);
  103. ASSERT(SUCCEEDED(hr) && (nBytesWritten == cbSize));
  104. // Verify that the write operation succeeded
  105. return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
  106. }
  107. LPSTR AllocAndCopyStr(LPCSTR psz)
  108. {
  109. LPSTR pszReturn;
  110. pszReturn = (LPSTR) new(BYTE[strlen(psz)+1]);
  111. if(pszReturn)
  112. {
  113. strcpy(pszReturn, psz);
  114. }
  115. return pszReturn;
  116. }
  117. LPWSTR AllocAndCopyStr(LPCWSTR pwsz)
  118. {
  119. LPWSTR pwszReturn;
  120. pwszReturn = (LPWSTR) new(WCHAR[wcslen(pwsz)+1]);
  121. if(pwszReturn)
  122. {
  123. wcscpy(pwszReturn, pwsz);
  124. }
  125. return pwszReturn;
  126. }
  127. LPWSTR BuildErrorMessage(DWORD dwErr)
  128. {
  129. LPWSTR lpMsgBuf = NULL;
  130. FormatMessageW(
  131. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  132. NULL,
  133. dwErr,
  134. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  135. (LPWSTR) &lpMsgBuf,
  136. 0,
  137. NULL );
  138. return lpMsgBuf;
  139. }
  140. //////////////////////////////////////////////////////////////////
  141. // given an error code and a console pointer, will pop error dlg
  142. void DisplayGenericCertSrvError(LPCONSOLE2 pConsole, DWORD dwErr)
  143. {
  144. ASSERT(pConsole);
  145. LPWSTR lpMsgBuf = BuildErrorMessage(dwErr);
  146. if(lpMsgBuf)
  147. {
  148. // ...
  149. // Display the string.
  150. pConsole->MessageBoxW(lpMsgBuf, L"Certificate Services Error", MB_OK | MB_ICONINFORMATION, NULL);
  151. // Free the buffer.
  152. LocalFree( lpMsgBuf );
  153. }
  154. }
  155. // returns localized, stringized time
  156. BOOL FileTimeToLocalTimeString(FILETIME* pftGMT, LPWSTR* ppszTmp)
  157. {
  158. FILETIME ftLocal;
  159. if (FileTimeToLocalFileTime(pftGMT, &ftLocal))
  160. {
  161. SYSTEMTIME sysLocal;
  162. if (FileTimeToSystemTime(
  163. &ftLocal,
  164. &sysLocal))
  165. {
  166. WCHAR rgTmpDate[128], rgTmpTime[128];
  167. DWORD dwLen;
  168. dwLen = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &sysLocal,
  169. NULL, rgTmpDate, ARRAYLEN(rgTmpDate));
  170. dwLen += GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &sysLocal,
  171. NULL, rgTmpTime, ARRAYLEN(rgTmpTime));
  172. dwLen += sizeof(L" ");
  173. *ppszTmp = new WCHAR[dwLen];
  174. if(*ppszTmp == NULL)
  175. {
  176. return FALSE;
  177. }
  178. wcscpy(*ppszTmp, rgTmpDate);
  179. wcscat(*ppszTmp, L" ");
  180. wcscat(*ppszTmp, rgTmpTime);
  181. }
  182. }
  183. return TRUE;
  184. }
  185. void MyErrorBox(HWND hwndParent, UINT nIDText, UINT nIDCaption, DWORD dwErrorCode)
  186. {
  187. CString cstrTitle, cstrFormatText, cstrFullText;
  188. cstrTitle.LoadString(nIDCaption);
  189. cstrFormatText.LoadString(nIDText);
  190. WCHAR const *pwszError = NULL;
  191. if (dwErrorCode != ERROR_SUCCESS)
  192. {
  193. pwszError = myGetErrorMessageText(dwErrorCode, TRUE);
  194. cstrFullText.Format(cstrFormatText, pwszError);
  195. // Free the buffer
  196. if (NULL != pwszError)
  197. {
  198. LocalFree(const_cast<WCHAR *>(pwszError));
  199. }
  200. }
  201. ::MessageBoxW(hwndParent, cstrFullText, cstrTitle, MB_OK | MB_ICONERROR);
  202. }
  203. BOOL MyGetOIDInfo(LPWSTR string, DWORD stringSize, LPSTR pszObjId)
  204. {
  205. PCCRYPT_OID_INFO pOIDInfo;
  206. pOIDInfo = CryptFindOIDInfo(
  207. CRYPT_OID_INFO_OID_KEY,
  208. pszObjId,
  209. 0);
  210. if (pOIDInfo != NULL)
  211. {
  212. if (wcslen(pOIDInfo->pwszName)+1 <= stringSize)
  213. {
  214. wcscpy(string, pOIDInfo->pwszName);
  215. }
  216. else
  217. {
  218. return FALSE;
  219. }
  220. }
  221. else
  222. {
  223. return (MultiByteToWideChar(CP_ACP, 0, pszObjId, -1, string, stringSize) != 0);
  224. }
  225. return TRUE;
  226. }
  227. BOOL MyGetEnhancedKeyUsages(HCERTTYPE hCertType, CString **aszUsages, DWORD *cUsages, BOOL *pfCritical, BOOL fGetOIDSNotNames)
  228. {
  229. PCERT_EXTENSIONS pCertExtensions;
  230. CERT_ENHKEY_USAGE *pehku;
  231. DWORD cb = 0;
  232. WCHAR OIDName[256];
  233. unsigned int i;
  234. LPWSTR pwszOID;
  235. HRESULT hr;
  236. CSASSERT(cUsages);
  237. if(aszUsages)
  238. *aszUsages = NULL;
  239. hr = CAGetCertTypeExtensions(hCertType, &pCertExtensions);
  240. if(hr != S_OK)
  241. {
  242. return FALSE;
  243. }
  244. i = 0;
  245. while ((i<pCertExtensions->cExtension) &&
  246. (strcmp(pCertExtensions->rgExtension[i].pszObjId, szOID_ENHANCED_KEY_USAGE) != 0))
  247. {
  248. i++;
  249. }
  250. if (i >= pCertExtensions->cExtension)
  251. {
  252. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  253. return FALSE;
  254. }
  255. if (pfCritical != NULL)
  256. {
  257. *pfCritical = pCertExtensions->rgExtension[i].fCritical;
  258. }
  259. CryptDecodeObject(
  260. X509_ASN_ENCODING,
  261. X509_ENHANCED_KEY_USAGE,
  262. pCertExtensions->rgExtension[i].Value.pbData,
  263. pCertExtensions->rgExtension[i].Value.cbData,
  264. 0,
  265. NULL,
  266. &cb);
  267. if (NULL == (pehku = (CERT_ENHKEY_USAGE *) new(BYTE[cb])))
  268. {
  269. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  270. return FALSE;
  271. }
  272. CryptDecodeObject(
  273. X509_ASN_ENCODING,
  274. X509_ENHANCED_KEY_USAGE,
  275. pCertExtensions->rgExtension[i].Value.pbData,
  276. pCertExtensions->rgExtension[i].Value.cbData,
  277. 0,
  278. pehku,
  279. &cb);
  280. if(!aszUsages)
  281. {
  282. // only retrieving the usage count
  283. *cUsages = pehku->cUsageIdentifier;
  284. }
  285. else
  286. {
  287. // retrieving usage strings, count better match
  288. CSASSERT(*cUsages == pehku->cUsageIdentifier);
  289. for (i=0; i<pehku->cUsageIdentifier; i++)
  290. {
  291. if (fGetOIDSNotNames)
  292. {
  293. pwszOID = MyMkWStr(pehku->rgpszUsageIdentifier[i]);
  294. aszUsages[i]= new CString(pwszOID);
  295. delete(pwszOID);
  296. if(aszUsages[i] == NULL)
  297. {
  298. return FALSE;
  299. }
  300. }
  301. else
  302. {
  303. MyGetOIDInfo(OIDName, sizeof(OIDName)/sizeof(WCHAR), pehku->rgpszUsageIdentifier[i]);
  304. aszUsages[i]= new CString(OIDName);
  305. if(aszUsages[i] == NULL)
  306. {
  307. return FALSE;
  308. }
  309. }
  310. }
  311. }
  312. delete[](pehku);
  313. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  314. return TRUE;
  315. }
  316. BOOL GetIntendedUsagesString(HCERTTYPE hCertType, CString *pUsageString)
  317. {
  318. CString **aszUsages = NULL;
  319. DWORD cNumUsages = 0;
  320. unsigned int i;
  321. if(!MyGetEnhancedKeyUsages(hCertType, NULL, &cNumUsages, NULL, FALSE))
  322. return FALSE;
  323. if(0==cNumUsages)
  324. {
  325. *pUsageString = "";
  326. return TRUE;
  327. }
  328. aszUsages = new CString*[cNumUsages];
  329. if(!aszUsages)
  330. return FALSE;
  331. if(!MyGetEnhancedKeyUsages(hCertType, aszUsages, &cNumUsages, NULL, FALSE))
  332. {
  333. delete[] aszUsages;
  334. return FALSE;
  335. }
  336. *pUsageString = "";
  337. for (i=0; i<cNumUsages; i++)
  338. {
  339. if (i != 0)
  340. {
  341. *pUsageString += ", ";
  342. }
  343. *pUsageString += *(aszUsages[i]);
  344. delete(aszUsages[i]);
  345. }
  346. delete[] aszUsages;
  347. return TRUE;
  348. }
  349. BOOL MyGetKeyUsages(HCERTTYPE hCertType, CRYPT_BIT_BLOB **ppBitBlob, BOOL *pfPublicKeyUsageCritical)
  350. {
  351. PCERT_EXTENSIONS pCertExtensions;
  352. DWORD cb = 0;
  353. unsigned int i;
  354. HRESULT hr;
  355. hr = CAGetCertTypeExtensions(hCertType, &pCertExtensions);
  356. if(hr != S_OK)
  357. {
  358. return FALSE;
  359. }
  360. i = 0;
  361. while ((i<pCertExtensions->cExtension) && (strcmp(pCertExtensions->rgExtension[i].pszObjId, szOID_KEY_USAGE) != 0))
  362. {
  363. i++;
  364. }
  365. if (i >= pCertExtensions->cExtension)
  366. {
  367. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  368. return FALSE;
  369. }
  370. if (pfPublicKeyUsageCritical != NULL)
  371. {
  372. *pfPublicKeyUsageCritical = pCertExtensions->rgExtension[i].fCritical;
  373. }
  374. CryptDecodeObject(
  375. X509_ASN_ENCODING,
  376. X509_KEY_USAGE,
  377. pCertExtensions->rgExtension[i].Value.pbData,
  378. pCertExtensions->rgExtension[i].Value.cbData,
  379. 0,
  380. NULL,
  381. &cb);
  382. if (NULL == (*ppBitBlob = (CRYPT_BIT_BLOB *) new(BYTE[cb])))
  383. {
  384. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  385. return FALSE;
  386. }
  387. CryptDecodeObject(
  388. X509_ASN_ENCODING,
  389. X509_KEY_USAGE,
  390. pCertExtensions->rgExtension[i].Value.pbData,
  391. pCertExtensions->rgExtension[i].Value.cbData,
  392. 0,
  393. *ppBitBlob,
  394. &cb);
  395. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  396. return TRUE;
  397. }
  398. BOOL MyGetBasicConstraintInfo(HCERTTYPE hCertType, BOOL *pfCA, BOOL *pfPathLenConstraint, DWORD *pdwPathLenConstraint)
  399. {
  400. PCERT_EXTENSIONS pCertExtensions;
  401. DWORD cb = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
  402. unsigned int i;
  403. CERT_BASIC_CONSTRAINTS2_INFO basicConstraintsInfo;
  404. HRESULT hr;
  405. hr = CAGetCertTypeExtensions(hCertType, &pCertExtensions);
  406. if(hr != S_OK)
  407. {
  408. return FALSE;
  409. }
  410. i = 0;
  411. while ((i<pCertExtensions->cExtension) && (strcmp(pCertExtensions->rgExtension[i].pszObjId, szOID_BASIC_CONSTRAINTS2) != 0))
  412. {
  413. i++;
  414. }
  415. if (i >= pCertExtensions->cExtension)
  416. {
  417. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  418. return FALSE;
  419. }
  420. CryptDecodeObject(
  421. X509_ASN_ENCODING,
  422. X509_BASIC_CONSTRAINTS2,
  423. pCertExtensions->rgExtension[i].Value.pbData,
  424. pCertExtensions->rgExtension[i].Value.cbData,
  425. 0,
  426. &basicConstraintsInfo,
  427. &cb);
  428. *pfCA = basicConstraintsInfo.fCA;
  429. *pfPathLenConstraint = basicConstraintsInfo.fPathLenConstraint;
  430. *pdwPathLenConstraint = basicConstraintsInfo.dwPathLenConstraint;
  431. CAFreeCertTypeExtensions(hCertType, pCertExtensions);
  432. return TRUE;
  433. }
  434. LPSTR MyMkMBStr(LPCWSTR pwsz)
  435. {
  436. int cb;
  437. LPSTR psz;
  438. if (pwsz == NULL)
  439. {
  440. return NULL;
  441. }
  442. cb = WideCharToMultiByte(
  443. 0,
  444. 0,
  445. pwsz,
  446. -1,
  447. NULL,
  448. 0,
  449. NULL,
  450. NULL);
  451. if (NULL == (psz = (LPSTR) new BYTE[cb]))
  452. {
  453. return NULL;
  454. }
  455. cb = WideCharToMultiByte(
  456. 0,
  457. 0,
  458. pwsz,
  459. -1,
  460. psz,
  461. cb,
  462. NULL,
  463. NULL);
  464. if (cb==0)
  465. {
  466. delete [] psz;
  467. return NULL;
  468. }
  469. return(psz);
  470. }
  471. LPWSTR MyMkWStr(LPCSTR psz)
  472. {
  473. int cWChars;
  474. LPWSTR pwsz;
  475. if (psz == NULL)
  476. {
  477. return NULL;
  478. }
  479. cWChars = MultiByteToWideChar(
  480. 0,
  481. 0,
  482. psz,
  483. -1,
  484. NULL,
  485. 0);
  486. if (NULL == (pwsz = (LPWSTR) new BYTE[cWChars * sizeof(WCHAR)] ))
  487. {
  488. return NULL;
  489. }
  490. cWChars = MultiByteToWideChar(
  491. 0,
  492. 0,
  493. psz,
  494. -1,
  495. pwsz,
  496. cWChars);
  497. if (cWChars == 0)
  498. {
  499. delete [] pwsz;
  500. return NULL;
  501. }
  502. return(pwsz);
  503. }
  504. BOOL IsCerttypeEditingAllowed()
  505. {
  506. DWORD lResult;
  507. HKEY hKey = NULL;
  508. DWORD dwType;
  509. DWORD dwEnabled = 0;
  510. DWORD cbEnabled = sizeof(dwEnabled);
  511. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  512. L"Software\\Microsoft\\Cryptography\\CertificateTemplateCache",
  513. 0,
  514. KEY_READ,
  515. &hKey);
  516. if (lResult == ERROR_SUCCESS)
  517. {
  518. lResult = RegQueryValueEx(hKey,
  519. REGSZ_ENABLE_CERTTYPE_EDITING,
  520. NULL,
  521. &dwType,
  522. (PBYTE)&dwEnabled,
  523. &cbEnabled);
  524. if(lResult == ERROR_SUCCESS)
  525. {
  526. if(dwType != REG_DWORD)
  527. {
  528. dwEnabled = 0;
  529. }
  530. }
  531. RegCloseKey (hKey);
  532. }
  533. return (dwEnabled != 0);
  534. }
  535. HRESULT RetrieveCATemplateListFromCA(
  536. HCAINFO hCAInfo,
  537. CTemplateList& list)
  538. {
  539. HRESULT hr = S_OK;
  540. LPWSTR *ppwszDNSName = NULL;
  541. LPWSTR *ppwszAuthority = NULL;
  542. ICertAdminD2 *pAdminD2 = NULL;
  543. DWORD dwServerVersion = 2;
  544. CERTTRANSBLOB ctbSD;
  545. ZeroMemory(&ctbSD, sizeof(CERTTRANSBLOB));
  546. hr = CAGetCAProperty(hCAInfo, CA_PROP_DNSNAME, &ppwszDNSName);
  547. _JumpIfError(hr, error, "CAGetCAProperty CA_PROP_DNSNAME");
  548. hr = CAGetCAProperty(hCAInfo, CA_PROP_NAME, &ppwszAuthority);
  549. _JumpIfError(hr, error, "CAGetCAProperty CA_PROP_DNSNAME");
  550. ASSERT(ppwszDNSName[0]);
  551. hr = myOpenAdminDComConnection(
  552. ppwszDNSName[0],
  553. NULL,
  554. NULL,
  555. &dwServerVersion,
  556. &pAdminD2);
  557. _JumpIfError(hr, error, "myOpenAdminDComConnection");
  558. if (2 > dwServerVersion)
  559. {
  560. hr = RPC_E_VERSION_MISMATCH;
  561. _JumpError(hr, error, "old server");
  562. }
  563. CSASSERT(ppwszAuthority[0]);
  564. hr = pAdminD2->GetCAProperty(
  565. ppwszAuthority[0],
  566. CR_PROP_TEMPLATES,
  567. 0,
  568. PROPTYPE_STRING,
  569. &ctbSD);
  570. _JumpIfErrorStr(hr, error, "ICertAdminD2::GetCAProperty CR_PROP_TEMPLATES",
  571. ppwszDNSName[0]);
  572. hr = list.Unmarshal(ctbSD.pb, ctbSD.cb);
  573. _JumpIfError(hr, error, "CTemplateList::Unmarshal");
  574. error:
  575. if(ppwszDNSName)
  576. CAFreeCAProperty(hCAInfo, ppwszDNSName);
  577. if(ppwszAuthority)
  578. CAFreeCAProperty(hCAInfo, ppwszAuthority);
  579. if(pAdminD2)
  580. pAdminD2->Release();
  581. return hr;
  582. }
  583. HRESULT RetrieveCATemplateListFromDS(
  584. HCAINFO hCAInfo,
  585. CTemplateList& list)
  586. {
  587. HRESULT hr = S_OK;
  588. HCERTTYPE hCertTypeNext, hCertTypePrev;
  589. hr = CAEnumCertTypesForCA(
  590. hCAInfo,
  591. CT_ENUM_MACHINE_TYPES |
  592. CT_ENUM_USER_TYPES |
  593. CT_FLAG_NO_CACHE_LOOKUP,
  594. &hCertTypeNext);
  595. _JumpIfError(hr, error, "CAEnumCertTypesForCA");
  596. while (hCertTypeNext != NULL)
  597. {
  598. hr = list.AddTemplateInfo(hCertTypeNext);
  599. _JumpIfError(hr, error, "CTemplateList::AddTemplate");
  600. hCertTypePrev = hCertTypeNext;
  601. hr = CAEnumNextCertType(hCertTypePrev, &hCertTypeNext);
  602. _JumpIfError(hr, error, "CAEnumNextCertType");
  603. }
  604. error:
  605. return hr;
  606. }
  607. HRESULT RetrieveCATemplateList(
  608. HCAINFO hCAInfo,
  609. CTemplateList& list)
  610. {
  611. HRESULT hr = S_OK;
  612. hr = RetrieveCATemplateListFromCA(hCAInfo, list);
  613. if(S_OK != hr)
  614. {
  615. // if failed to retrieve from the CA for any reason, try
  616. // fetching from DS
  617. hr = RetrieveCATemplateListFromDS(hCAInfo, list);
  618. }
  619. return hr;
  620. }
  621. HRESULT UpdateCATemplateListToDS(
  622. HCAINFO hCAInfo,
  623. const CTemplateList& list)
  624. {
  625. HRESULT hr = S_OK;
  626. hr = CAUpdateCA(hCAInfo);
  627. _JumpIfError(hr, error, "CAUpdateCA");
  628. error:
  629. return hr;
  630. }
  631. HRESULT UpdateCATemplateListToCA(
  632. HCAINFO hCAInfo,
  633. const CTemplateList& list)
  634. {
  635. HRESULT hr = S_OK;
  636. LPWSTR *ppwszDNSName = NULL;
  637. LPWSTR *ppwszAuthority = NULL;
  638. ICertAdminD2 *pAdminD2 = NULL;
  639. DWORD dwServerVersion = 2;
  640. CERTTRANSBLOB ctbSD;
  641. ZeroMemory(&ctbSD, sizeof(CERTTRANSBLOB));
  642. hr = CAGetCAProperty(hCAInfo, CA_PROP_DNSNAME, &ppwszDNSName);
  643. _JumpIfError(hr, error, "CAGetCAProperty CA_PROP_DNSNAME");
  644. hr = CAGetCAProperty(hCAInfo, CA_PROP_NAME, &ppwszAuthority);
  645. _JumpIfError(hr, error, "CAGetCAProperty CA_PROP_DNSNAME");
  646. ASSERT(ppwszDNSName[0]);
  647. hr = myOpenAdminDComConnection(
  648. ppwszDNSName[0],
  649. NULL,
  650. NULL,
  651. &dwServerVersion,
  652. &pAdminD2);
  653. _JumpIfError(hr, error, "myOpenAdminDComConnection");
  654. if (2 > dwServerVersion)
  655. {
  656. hr = RPC_E_VERSION_MISMATCH;
  657. _JumpError(hr, error, "old server");
  658. }
  659. CSASSERT(ppwszAuthority[0]);
  660. hr = list.Marshal(ctbSD.pb, ctbSD.cb);
  661. _JumpIfError(hr, error, "CTemplateList::Marshal");
  662. CSASSERT(S_OK==list.ValidateMarshalBuffer(ctbSD.pb, ctbSD.cb));
  663. hr = pAdminD2->SetCAProperty(
  664. ppwszAuthority[0],
  665. CR_PROP_TEMPLATES,
  666. 0,
  667. PROPTYPE_STRING,
  668. &ctbSD);
  669. _JumpIfErrorStr(hr, error, "ICertAdminD2::SetCAProperty CR_PROP_TEMPLATES",
  670. ppwszDNSName[0]);
  671. error:
  672. if(ppwszDNSName)
  673. CAFreeCAProperty(hCAInfo, ppwszDNSName);
  674. if(ppwszAuthority)
  675. CAFreeCAProperty(hCAInfo, ppwszAuthority);
  676. if(pAdminD2)
  677. pAdminD2->Release();
  678. if(ctbSD.pb)
  679. MIDL_user_free(ctbSD.pb);
  680. return hr;
  681. }
  682. HRESULT UpdateCATemplateList(
  683. HCAINFO hCAInfo,
  684. const CTemplateList& list)
  685. {
  686. HRESULT hr = UpdateCATemplateListToCA(hCAInfo, list);
  687. if(S_OK != hr)
  688. {
  689. // if failed to update through the CA for any reason, try
  690. // writing directly to DS
  691. hr = UpdateCATemplateListToDS(hCAInfo, list);
  692. }
  693. return hr;
  694. }
  695. HRESULT AddToCATemplateList(
  696. HCAINFO hCAInfo,
  697. CTemplateList& list,
  698. HCERTTYPE hCertType)
  699. {
  700. HRESULT hr = S_OK;
  701. hr = CAAddCACertificateType(hCAInfo, hCertType);
  702. _JumpIfError(hr, error, "CAAddCACertificateType");
  703. hr = list.AddTemplateInfo(hCertType);
  704. _JumpIfError(hr, error, "CTemplateList::AddTemplateInfo HCERTTYPE");
  705. error:
  706. return hr;
  707. }
  708. HRESULT RemoveFromCATemplateList(
  709. HCAINFO hCAInfo,
  710. CTemplateList& list,
  711. HCERTTYPE hCertType)
  712. {
  713. HRESULT hr = S_OK;
  714. hr = CARemoveCACertificateType(hCAInfo, hCertType);
  715. _JumpIfError(hr, error, "CARemoveCACertificateType");
  716. hr = list.RemoveTemplateInfo(hCertType);
  717. _JumpIfError(hr, error, "CTemplateList::RemoveTemplateInfo HCERTTYPE");
  718. error:
  719. return hr;
  720. }