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.

789 lines
20 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: dcom.cpp
  8. //
  9. // Contents: IDispatch helper functions
  10. //
  11. //--------------------------------------------------------------------------
  12. #include <pch.cpp>
  13. #pragma hdrstop
  14. #include "certsrvd.h"
  15. #define __dwFILE__ __dwFILE_CERTLIB_DCOM_CPP__
  16. HRESULT
  17. mySplitConfigString(
  18. IN WCHAR const *pwszConfig,
  19. OUT WCHAR **ppwszServer,
  20. OUT WCHAR **ppwszAuthority)
  21. {
  22. HRESULT hr;
  23. WCHAR const *pwsz;
  24. DWORD cwcServer;
  25. WCHAR *pwszAuthority = NULL;
  26. *ppwszServer = NULL;
  27. *ppwszAuthority = NULL;
  28. while (L'\\' == *pwszConfig)
  29. {
  30. pwszConfig++;
  31. }
  32. pwsz = wcschr(pwszConfig, L'\\');
  33. if (NULL == pwsz)
  34. {
  35. cwcServer = wcslen(pwszConfig);
  36. }
  37. else
  38. {
  39. cwcServer = SAFE_SUBTRACT_POINTERS(pwsz, pwszConfig);
  40. pwsz++;
  41. pwszAuthority = (WCHAR *) LocalAlloc(
  42. LMEM_FIXED,
  43. (wcslen(pwsz) + 1) * sizeof(WCHAR));
  44. if (NULL == pwszAuthority)
  45. {
  46. hr = E_OUTOFMEMORY;
  47. _JumpError(hr, error, "LocalAlloc");
  48. }
  49. wcscpy(pwszAuthority, pwsz);
  50. }
  51. *ppwszServer = (WCHAR *) LocalAlloc(
  52. LMEM_FIXED,
  53. (cwcServer + 1) * sizeof(WCHAR));
  54. if (NULL == *ppwszServer)
  55. {
  56. hr = E_OUTOFMEMORY;
  57. _JumpError(hr, error, "LocalAlloc");
  58. }
  59. CopyMemory(*ppwszServer, pwszConfig, cwcServer * sizeof(WCHAR));
  60. (*ppwszServer)[cwcServer] = L'\0';
  61. *ppwszAuthority = pwszAuthority;
  62. pwszAuthority = NULL;
  63. hr = S_OK;
  64. error:
  65. if (NULL != pwszAuthority)
  66. {
  67. LocalFree(pwszAuthority);
  68. }
  69. return(hr);
  70. }
  71. HRESULT
  72. _OpenDComConnection(
  73. IN WCHAR const *pwszConfig,
  74. IN CLSID const *pclsid,
  75. IN IID const *piid,
  76. OPTIONAL OUT WCHAR const **ppwszAuthority,
  77. OPTIONAL IN OUT WCHAR **ppwszServerName,
  78. OUT BOOL *pfNewConnection,
  79. IN OUT IUnknown **ppUnknown)
  80. {
  81. HRESULT hr;
  82. WCHAR *pwszServerName = NULL;
  83. WCHAR *pwsz;
  84. DWORD cwc;
  85. COSERVERINFO ComponentInfo;
  86. MULTI_QI mq;
  87. WCHAR *pwcDot = NULL;
  88. if (NULL == pwszConfig ||
  89. NULL == pclsid ||
  90. NULL == piid ||
  91. NULL == pfNewConnection ||
  92. NULL == ppUnknown)
  93. {
  94. hr = E_POINTER;
  95. _JumpError(hr, error, "NULL parm");
  96. }
  97. CSASSERT(NULL != pwszConfig);
  98. *pfNewConnection = FALSE;
  99. // Allow UNC-style config strings: \\server\CaName
  100. while (L'\\' == *pwszConfig)
  101. {
  102. pwszConfig++;
  103. }
  104. pwsz = wcschr(pwszConfig, L'\\');
  105. if (NULL == pwsz)
  106. {
  107. cwc = wcslen(pwszConfig);
  108. if (NULL != ppwszAuthority)
  109. {
  110. *ppwszAuthority = &pwszConfig[cwc];
  111. }
  112. }
  113. else
  114. {
  115. cwc = SAFE_SUBTRACT_POINTERS(pwsz, pwszConfig);
  116. if (NULL != ppwszAuthority)
  117. {
  118. *ppwszAuthority = &pwsz[1];
  119. }
  120. }
  121. pwszServerName = (WCHAR *) LocalAlloc(
  122. LMEM_FIXED,
  123. (cwc + 1) * sizeof(WCHAR));
  124. if (NULL == pwszServerName)
  125. {
  126. hr = E_OUTOFMEMORY;
  127. _JumpError(hr, error, "LocalAlloc");
  128. }
  129. CopyMemory(pwszServerName, pwszConfig, cwc * sizeof(WCHAR));
  130. pwszServerName[cwc] = L'\0';
  131. // NOTE: CoSetProxyBlanket returns RPC_S_UNKNOWN_AUTHN_SERVICE when
  132. // the Dns name ends with a '.'. Until that's fixed, truncate the dot.
  133. if (0 < cwc && L'.' == pwszServerName[cwc - 1])
  134. {
  135. pwszServerName[cwc - 1] = L'\0';
  136. cwc--;
  137. }
  138. if (NULL == *ppUnknown ||
  139. NULL == ppwszServerName ||
  140. NULL == *ppwszServerName ||
  141. 0 != mylstrcmpiL(pwszServerName, *ppwszServerName))
  142. {
  143. ZeroMemory(&ComponentInfo, sizeof(COSERVERINFO));
  144. ComponentInfo.pwszName = pwszServerName;
  145. //ComponentInfo.pAuthInfo = NULL;
  146. mq.pIID = piid;
  147. mq.pItf = NULL;
  148. mq.hr = S_OK;
  149. myCloseDComConnection(ppUnknown, ppwszServerName);
  150. for (;;)
  151. {
  152. hr = CoCreateInstanceEx(
  153. *pclsid,
  154. NULL,
  155. CLSCTX_SERVER, //CLSCTX_LOCAL_SERVER,
  156. &ComponentInfo,
  157. 1,
  158. &mq);
  159. _PrintIfErrorStr2(
  160. hr,
  161. "CoCreateInstanceEx",
  162. pwszServerName,
  163. E_NOINTERFACE);
  164. if (HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) == hr &&
  165. 0 < cwc &&
  166. L'.' == pwszServerName[cwc - 1])
  167. {
  168. pwcDot = &pwszServerName[cwc - 1];
  169. *pwcDot = L'\0';
  170. continue;
  171. }
  172. break;
  173. }
  174. if (NULL != pwcDot)
  175. {
  176. *pwcDot = L'.';
  177. }
  178. _JumpIfErrorStr2(hr, error, "CoCreateInstanceEx", pwszServerName, hr);
  179. *ppUnknown = mq.pItf;
  180. if (NULL != ppwszServerName)
  181. {
  182. CSASSERT(NULL == *ppwszServerName);
  183. *ppwszServerName = pwszServerName;
  184. pwszServerName = NULL;
  185. }
  186. *pfNewConnection = TRUE;
  187. }
  188. hr = S_OK;
  189. error:
  190. if (S_OK != hr)
  191. {
  192. myCloseDComConnection(ppUnknown, ppwszServerName);
  193. }
  194. if (NULL != pwszServerName)
  195. {
  196. LocalFree(pwszServerName);
  197. }
  198. return(hr);
  199. }
  200. HRESULT
  201. _OpenDComConnection2(
  202. IN WCHAR const *pwszConfig,
  203. IN CLSID const *pclsid,
  204. IN IID const *piid, // v1 interface
  205. IN IID const *piid2,// v2 interface
  206. OPTIONAL OUT WCHAR const **ppwszAuthority,
  207. OPTIONAL IN OUT WCHAR **ppwszServerName,
  208. OPTIONAL OUT BOOL *pfNewConnection,
  209. IN OUT DWORD *pdwServerVersion,
  210. IN OUT IUnknown **ppUnknown)
  211. {
  212. HRESULT hr = E_INVALIDARG;
  213. BOOL fNewConnection;
  214. DWORD dwAuthnSvc = RPC_C_AUTHN_DEFAULT;
  215. IUnknown *pUnknown;
  216. IUnknown *pRealUnknown = NULL;
  217. IRpcOptions *pRpcOpt = NULL;
  218. ULONG_PTR dwProperty = 0;
  219. if (NULL != pfNewConnection)
  220. {
  221. *pfNewConnection = FALSE;
  222. }
  223. CSASSERT(
  224. 0 == *pdwServerVersion ||
  225. 1 == *pdwServerVersion ||
  226. 2 == *pdwServerVersion);
  227. hr = _OpenDComConnection(
  228. pwszConfig,
  229. pclsid,
  230. piid,
  231. ppwszAuthority,
  232. ppwszServerName,
  233. &fNewConnection,
  234. ppUnknown);
  235. _JumpIfError(hr, error, "_OpenDComConnection");
  236. if (fNewConnection)
  237. {
  238. if (NULL != pfNewConnection)
  239. {
  240. *pfNewConnection = TRUE;
  241. }
  242. // determine if server is on local box, we'll pass in AuthN param based on this
  243. hr = (*ppUnknown)->QueryInterface (IID_IRpcOptions, (void**)&pRpcOpt);
  244. if (SUCCEEDED(hr))
  245. {
  246. hr = pRpcOpt->Query((*ppUnknown), COMBND_SERVER_LOCALITY, &dwProperty);
  247. if (SUCCEEDED(hr))
  248. {
  249. // if not local, set snego (locally snego doesn't work)
  250. if(SERVER_LOCALITY_MACHINE_LOCAL != dwProperty)
  251. dwAuthnSvc = RPC_C_AUTHN_GSS_NEGOTIATE;
  252. }
  253. pRpcOpt->Release();
  254. pRpcOpt = NULL;
  255. }
  256. hr = (*ppUnknown)->QueryInterface(IID_IUnknown, (VOID **) &pRealUnknown);
  257. _JumpIfError(hr, error, "QI IUnknown");
  258. hr = CoSetProxyBlanket(
  259. pRealUnknown,
  260. dwAuthnSvc,
  261. RPC_C_AUTHZ_DEFAULT, // use NT default authentication
  262. COLE_DEFAULT_PRINCIPAL,
  263. RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // call
  264. RPC_C_IMP_LEVEL_IMPERSONATE,
  265. NULL,
  266. EOAC_STATIC_CLOAKING);
  267. _JumpIfError(hr, error, "CoSetProxyBlanket");
  268. hr = CoSetProxyBlanket(
  269. *ppUnknown,
  270. dwAuthnSvc,
  271. RPC_C_AUTHZ_DEFAULT, // use NT default authentication
  272. COLE_DEFAULT_PRINCIPAL,
  273. RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // call
  274. RPC_C_IMP_LEVEL_IMPERSONATE,
  275. NULL,
  276. EOAC_STATIC_CLOAKING);
  277. _JumpIfError(hr, error, "CoSetProxyBlanket");
  278. hr = (*ppUnknown)->QueryInterface(*piid2, (VOID **) &pUnknown);
  279. if (S_OK != hr)
  280. {
  281. *pdwServerVersion = 1; // v2 not supported
  282. }
  283. else
  284. {
  285. *pdwServerVersion = 2; // v2 supported
  286. (*ppUnknown)->Release();
  287. *ppUnknown = pUnknown;
  288. hr = CoSetProxyBlanket(
  289. *ppUnknown,
  290. dwAuthnSvc,
  291. RPC_C_AUTHZ_DEFAULT, // use NT default authentication
  292. COLE_DEFAULT_PRINCIPAL,
  293. RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // call
  294. RPC_C_IMP_LEVEL_IMPERSONATE,
  295. NULL,
  296. EOAC_STATIC_CLOAKING);
  297. _JumpIfError(hr, error, "CoSetProxyBlanket");
  298. }
  299. }
  300. hr = S_OK;
  301. error:
  302. if(pRealUnknown)
  303. {
  304. pRealUnknown->Release();
  305. }
  306. return(hr);
  307. }
  308. HRESULT
  309. myOpenAdminDComConnection(
  310. IN WCHAR const *pwszConfig,
  311. OPTIONAL OUT WCHAR const **ppwszAuthority,
  312. OPTIONAL IN OUT WCHAR **ppwszServerName,
  313. IN OUT DWORD *pdwServerVersion,
  314. IN OUT ICertAdminD2 **ppICertAdminD)
  315. {
  316. HRESULT hr;
  317. hr = _OpenDComConnection2(
  318. pwszConfig,
  319. &CLSID_CCertAdminD,
  320. &IID_ICertAdminD,
  321. &IID_ICertAdminD2,
  322. ppwszAuthority,
  323. ppwszServerName,
  324. NULL, // pfNewConnection
  325. pdwServerVersion,
  326. (IUnknown **) ppICertAdminD);
  327. _JumpIfError(hr, error, "_OpenDComConnection2");
  328. error:
  329. return(hr);
  330. }
  331. HRESULT
  332. myOpenRequestDComConnection(
  333. IN WCHAR const *pwszConfig,
  334. OPTIONAL OUT WCHAR const **ppwszAuthority,
  335. OPTIONAL IN OUT WCHAR **ppwszServerName,
  336. OPTIONAL OUT BOOL *pfNewConnection,
  337. IN OUT DWORD *pdwServerVersion,
  338. IN OUT ICertRequestD2 **ppICertRequestD)
  339. {
  340. HRESULT hr;
  341. hr = _OpenDComConnection2(
  342. pwszConfig,
  343. &CLSID_CCertRequestD,
  344. &IID_ICertRequestD,
  345. &IID_ICertRequestD2,
  346. ppwszAuthority,
  347. ppwszServerName,
  348. pfNewConnection,
  349. pdwServerVersion,
  350. (IUnknown **) ppICertRequestD);
  351. _JumpIfError(hr, error, "_OpenDComConnection2");
  352. error:
  353. return(hr);
  354. }
  355. //+--------------------------------------------------------------------------
  356. // myCloseDComConnection -- release DCOM connection
  357. //
  358. //+--------------------------------------------------------------------------
  359. VOID
  360. myCloseDComConnection(
  361. OPTIONAL IN OUT IUnknown **ppUnknown,
  362. OPTIONAL IN OUT WCHAR **ppwszServerName)
  363. {
  364. if (NULL != ppUnknown && NULL != *ppUnknown)
  365. {
  366. (*ppUnknown)->Release();
  367. *ppUnknown = NULL;
  368. }
  369. if (NULL != ppwszServerName && NULL != *ppwszServerName)
  370. {
  371. LocalFree(*ppwszServerName);
  372. *ppwszServerName = NULL;
  373. }
  374. }
  375. HRESULT
  376. myPingCertSrv(
  377. IN WCHAR const *pwszConfigOrCAName,
  378. OPTIONAL IN WCHAR const *pwszMachineName,
  379. OPTIONAL OUT WCHAR **ppwszzCANames,
  380. OPTIONAL OUT WCHAR **ppwszSharedFolder,
  381. OPTIONAL OUT CAINFO **ppCAInfo,
  382. OPTIONAL OUT DWORD *pdwServerVersion,
  383. OPTIONAL OUT WCHAR **ppwszCADnsName)
  384. {
  385. HRESULT hr;
  386. WCHAR wszConfig[MAX_PATH];
  387. WCHAR const *pwszConfig;
  388. ICertRequestD2 *pICertRequestD = NULL;
  389. WCHAR const *pwszAuthority;
  390. CERTTRANSBLOB ctbCANames;
  391. CERTTRANSBLOB ctbSharedFolder;
  392. CERTTRANSBLOB ctbCAInfo;
  393. CERTTRANSBLOB ctbCADnsName;
  394. CAINFO CAInfo;
  395. CAINFO const *pCAInfo;
  396. DWORD dwServerVersion = 0;
  397. ctbCANames.pb = NULL;
  398. ctbCANames.cb = 0;
  399. ctbSharedFolder.pb = NULL;
  400. ctbSharedFolder.cb = 0;
  401. ctbCAInfo.pb = NULL;
  402. ctbCAInfo.cb = 0;
  403. ctbCADnsName.pb = NULL;
  404. ctbCADnsName.cb = 0;
  405. if (NULL != ppwszzCANames)
  406. {
  407. *ppwszzCANames = NULL;
  408. }
  409. if (NULL != ppwszSharedFolder)
  410. {
  411. *ppwszSharedFolder = NULL;
  412. }
  413. if (NULL != ppCAInfo)
  414. {
  415. *ppCAInfo = NULL;
  416. }
  417. if (NULL != ppwszCADnsName)
  418. {
  419. *ppwszCADnsName = NULL;
  420. }
  421. if (NULL == pwszConfigOrCAName)
  422. {
  423. hr = E_POINTER;
  424. _JumpError(hr, error, "Invalid parameters");
  425. }
  426. pwszConfig = pwszConfigOrCAName;
  427. if (NULL != pwszMachineName)
  428. {
  429. wcscpy(wszConfig, pwszMachineName);
  430. wcscat(wszConfig, L"\\");
  431. wcscat(wszConfig, pwszConfigOrCAName);
  432. pwszConfig = wszConfig;
  433. }
  434. hr = myOpenRequestDComConnection(
  435. pwszConfig,
  436. &pwszAuthority,
  437. NULL,
  438. NULL,
  439. &dwServerVersion,
  440. &pICertRequestD);
  441. _JumpIfError(hr, error, "myOpenRequestDComConnection");
  442. CSASSERT(0 != dwServerVersion);
  443. if (2 <= dwServerVersion)
  444. {
  445. __try
  446. {
  447. hr = pICertRequestD->Ping2(pwszAuthority);
  448. }
  449. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  450. {
  451. }
  452. _JumpIfError(hr, error, "Ping2");
  453. }
  454. else
  455. {
  456. __try
  457. {
  458. hr = pICertRequestD->Ping(pwszAuthority);
  459. }
  460. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  461. {
  462. }
  463. _JumpIfError(hr, error, "Ping");
  464. }
  465. if (NULL != ppwszzCANames)
  466. {
  467. __try
  468. {
  469. hr = pICertRequestD->GetCACert(
  470. GETCERT_CANAME,
  471. pwszAuthority,
  472. &ctbCANames);
  473. }
  474. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  475. {
  476. }
  477. _JumpIfError(hr, error, "GetCACert(CANames)");
  478. // must register this memory
  479. myRegisterMemAlloc(ctbCANames.pb, ctbCANames.cb, CSM_COTASKALLOC);
  480. // Only one CA Name expected for now...
  481. CSASSERT(
  482. (wcslen((WCHAR *) ctbCANames.pb) + 1) * sizeof(WCHAR) ==
  483. ctbCANames.cb);
  484. *ppwszzCANames = (WCHAR *) LocalAlloc(
  485. LMEM_FIXED,
  486. ctbCANames.cb + sizeof(WCHAR));
  487. if (NULL == *ppwszzCANames)
  488. {
  489. hr = E_OUTOFMEMORY;
  490. _JumpError(hr, error, "LocalAlloc");
  491. }
  492. CopyMemory(*ppwszzCANames, ctbCANames.pb, ctbCANames.cb);
  493. (*ppwszzCANames)[ctbCANames.cb/sizeof(WCHAR)] = L'\0';
  494. }
  495. if (NULL != ppwszSharedFolder)
  496. {
  497. __try
  498. {
  499. hr = pICertRequestD->GetCACert(
  500. GETCERT_SHAREDFOLDER,
  501. pwszAuthority,
  502. &ctbSharedFolder);
  503. }
  504. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  505. {
  506. }
  507. _JumpIfError(hr, error, "GetCACert(SharedFolder)");
  508. // must register this memory
  509. myRegisterMemAlloc(ctbSharedFolder.pb, ctbSharedFolder.cb, CSM_COTASKALLOC);
  510. *ppwszSharedFolder = (WCHAR *)LocalAlloc(LMEM_FIXED,
  511. ctbSharedFolder.cb + sizeof(WCHAR));
  512. if (NULL == *ppwszSharedFolder)
  513. {
  514. hr = E_OUTOFMEMORY;
  515. _JumpError(hr, error, "LocalAlloc");
  516. }
  517. CopyMemory(*ppwszSharedFolder, ctbSharedFolder.pb, ctbSharedFolder.cb);
  518. (*ppwszSharedFolder)[ctbSharedFolder.cb/sizeof(WCHAR)] = L'\0';
  519. CSASSERT(wcslen(*ppwszSharedFolder)*sizeof(WCHAR) == ctbSharedFolder.cb);
  520. }
  521. if (NULL != ppCAInfo)
  522. {
  523. __try
  524. {
  525. hr = pICertRequestD->GetCACert(
  526. GETCERT_CAINFO,
  527. pwszAuthority,
  528. &ctbCAInfo);
  529. }
  530. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  531. {
  532. }
  533. if (E_INVALIDARG == hr) // if old server
  534. {
  535. __try
  536. {
  537. hr = pICertRequestD->GetCACert(
  538. GETCERT_CATYPE,
  539. pwszAuthority,
  540. &ctbCAInfo);
  541. }
  542. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  543. {
  544. }
  545. _JumpIfError(hr, error, "GetCACert(CAType)");
  546. myRegisterMemAlloc(ctbCAInfo.pb, ctbCAInfo.cb, CSM_COTASKALLOC);
  547. ZeroMemory(&CAInfo, sizeof(CAInfo));
  548. CAInfo.cbSize = CCSIZEOF_STRUCT(CAINFO, cCASignatureCerts);
  549. CAInfo.CAType = *(ENUM_CATYPES *) ctbCAInfo.pb;
  550. CAInfo.cCASignatureCerts = 1;
  551. pCAInfo = &CAInfo;
  552. }
  553. else
  554. {
  555. _JumpIfError(hr, error, "GetCACert(CAInfo)");
  556. // must register this memory
  557. myRegisterMemAlloc(ctbCAInfo.pb, ctbCAInfo.cb, CSM_COTASKALLOC);
  558. pCAInfo = (CAINFO *) ctbCAInfo.pb;
  559. }
  560. *ppCAInfo = (CAINFO *) LocalAlloc(LMEM_FIXED, pCAInfo->cbSize);
  561. if (NULL == *ppCAInfo)
  562. {
  563. hr = E_OUTOFMEMORY;
  564. _JumpError(hr, error, "LocalAlloc");
  565. }
  566. CopyMemory(*ppCAInfo, pCAInfo, pCAInfo->cbSize);
  567. }
  568. if (NULL != pdwServerVersion)
  569. {
  570. *pdwServerVersion = dwServerVersion;
  571. }
  572. if (NULL != ppwszCADnsName && 2 <= dwServerVersion)
  573. {
  574. __try
  575. {
  576. hr = pICertRequestD->GetCAProperty(
  577. pwszAuthority,
  578. CR_PROP_DNSNAME,
  579. 0,
  580. PROPTYPE_STRING,
  581. &ctbCADnsName);
  582. }
  583. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  584. {
  585. }
  586. _JumpIfError(hr, error, "GetCACert(SharedFolder)");
  587. // must register this memory
  588. myRegisterMemAlloc(ctbCADnsName.pb, ctbCADnsName.cb, CSM_COTASKALLOC);
  589. *ppwszCADnsName = (WCHAR *)LocalAlloc(LMEM_FIXED, ctbCADnsName.cb + sizeof(WCHAR));
  590. if (NULL == *ppwszCADnsName)
  591. {
  592. hr = E_OUTOFMEMORY;
  593. _JumpError(hr, error, "LocalAlloc");
  594. }
  595. CopyMemory(*ppwszCADnsName, ctbCADnsName.pb, ctbCADnsName.cb);
  596. (*ppwszCADnsName)[ctbCADnsName.cb/sizeof(WCHAR)] = L'\0';
  597. CSASSERT((wcslen(*ppwszCADnsName)+1)*sizeof(WCHAR) == ctbCADnsName.cb);
  598. }
  599. hr = S_OK;
  600. error:
  601. myCloseDComConnection((IUnknown **) &pICertRequestD, NULL);
  602. if (NULL != ctbCANames.pb)
  603. {
  604. CoTaskMemFree(ctbCANames.pb);
  605. }
  606. if (NULL != ctbSharedFolder.pb)
  607. {
  608. CoTaskMemFree(ctbSharedFolder.pb);
  609. }
  610. if (NULL != ctbCAInfo.pb)
  611. {
  612. CoTaskMemFree(ctbCAInfo.pb);
  613. }
  614. if (NULL != ctbCADnsName.pb)
  615. {
  616. CoTaskMemFree(ctbCADnsName.pb);
  617. }
  618. return(hr);
  619. }
  620. HRESULT
  621. myEnablePrivilege(
  622. IN LPCTSTR szPrivilege,
  623. IN BOOL fEnable)
  624. {
  625. HRESULT hr = S_OK;
  626. TOKEN_PRIVILEGES NewState;
  627. CAutoHANDLE hThread;
  628. CAutoHANDLE hToken;
  629. NewState.PrivilegeCount = 1;
  630. hThread = GetCurrentThread();
  631. if (!hThread)
  632. {
  633. hr = myHLastError();
  634. _JumpIfError(hr, error, "GetCurrentThread");
  635. }
  636. // Get the access token for current thread
  637. if (!OpenThreadToken(
  638. hThread,
  639. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  640. FALSE,
  641. &hToken))
  642. {
  643. hr = myHLastError();
  644. if(hr==HRESULT_FROM_WIN32(ERROR_NO_TOKEN))
  645. {
  646. HANDLE hProcess = GetCurrentProcess();
  647. if (!hProcess)
  648. {
  649. hr = myHLastError();
  650. _JumpError(hr, error, "GetCurrentProcess");
  651. }
  652. if (!OpenProcessToken(hProcess,
  653. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  654. &hToken))
  655. {
  656. hr = myHLastError();
  657. _JumpError(hr, error, "OpenProcessToken");
  658. }
  659. hr = S_OK;
  660. }
  661. else
  662. {
  663. _JumpError(hr, error, "OpenThreadToken");
  664. }
  665. }
  666. if (!LookupPrivilegeValue(NULL, szPrivilege, &NewState.Privileges[0].Luid))
  667. {
  668. hr = myHLastError();
  669. _JumpIfError(hr, error, "LookupPrivelageValue");
  670. }
  671. NewState.Privileges[0].Attributes = (fEnable?SE_PRIVILEGE_ENABLED:0);
  672. if(!AdjustTokenPrivileges(hToken,
  673. FALSE,
  674. &NewState,
  675. sizeof(NewState),
  676. NULL,
  677. NULL))
  678. {
  679. hr = myHLastError();
  680. _JumpIfError(hr, error, "AdjustTokenPrivileges");
  681. }
  682. else
  683. {
  684. hr = myHLastError();
  685. if(HRESULT_FROM_WIN32(ERROR_NOT_ALL_ASSIGNED)==hr)
  686. {
  687. // privilege not held, return a generic access denied error
  688. hr = E_ACCESSDENIED;
  689. }
  690. }
  691. error:
  692. return hr;
  693. }