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.

724 lines
17 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 != lstrcmpi(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. while (TRUE)
  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. if (NULL != pfNewConnection)
  215. {
  216. *pfNewConnection = FALSE;
  217. }
  218. CSASSERT(
  219. 0 == *pdwServerVersion ||
  220. 1 == *pdwServerVersion ||
  221. 2 == *pdwServerVersion);
  222. hr = _OpenDComConnection(
  223. pwszConfig,
  224. pclsid,
  225. piid,
  226. ppwszAuthority,
  227. ppwszServerName,
  228. &fNewConnection,
  229. ppUnknown);
  230. _JumpIfError(hr, error, "_OpenDComConnection");
  231. if (fNewConnection)
  232. {
  233. IUnknown *pUnknown;
  234. if (NULL != pfNewConnection)
  235. {
  236. *pfNewConnection = TRUE;
  237. }
  238. hr = (*ppUnknown)->QueryInterface(*piid2, (VOID **) &pUnknown);
  239. if (S_OK != hr)
  240. {
  241. *pdwServerVersion = 1; // v2 not supported
  242. }
  243. else
  244. {
  245. *pdwServerVersion = 2; // v2 supported
  246. (*ppUnknown)->Release();
  247. *ppUnknown = pUnknown;
  248. }
  249. hr = CoSetProxyBlanket(
  250. *ppUnknown,
  251. RPC_C_AUTHN_DEFAULT, // use NT default security
  252. RPC_C_AUTHZ_DEFAULT, // use NT default authentication
  253. COLE_DEFAULT_PRINCIPAL,
  254. RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, // call
  255. RPC_C_IMP_LEVEL_IMPERSONATE,
  256. NULL,
  257. EOAC_STATIC_CLOAKING);
  258. _JumpIfError(hr, error, "CoSetProxyBlanket");
  259. }
  260. hr = S_OK;
  261. error:
  262. return(hr);
  263. }
  264. HRESULT
  265. myOpenAdminDComConnection(
  266. IN WCHAR const *pwszConfig,
  267. OPTIONAL OUT WCHAR const **ppwszAuthority,
  268. OPTIONAL IN OUT WCHAR **ppwszServerName,
  269. IN OUT DWORD *pdwServerVersion,
  270. IN OUT ICertAdminD2 **ppICertAdminD)
  271. {
  272. HRESULT hr;
  273. hr = _OpenDComConnection2(
  274. pwszConfig,
  275. &CLSID_CCertAdminD,
  276. &IID_ICertAdminD,
  277. &IID_ICertAdminD2,
  278. ppwszAuthority,
  279. ppwszServerName,
  280. NULL, // pfNewConnection
  281. pdwServerVersion,
  282. (IUnknown **) ppICertAdminD);
  283. _JumpIfError(hr, error, "_OpenDComConnection2");
  284. error:
  285. return(hr);
  286. }
  287. HRESULT
  288. myOpenRequestDComConnection(
  289. IN WCHAR const *pwszConfig,
  290. OPTIONAL OUT WCHAR const **ppwszAuthority,
  291. OPTIONAL IN OUT WCHAR **ppwszServerName,
  292. OPTIONAL OUT BOOL *pfNewConnection,
  293. IN OUT DWORD *pdwServerVersion,
  294. IN OUT ICertRequestD2 **ppICertRequestD)
  295. {
  296. HRESULT hr;
  297. hr = _OpenDComConnection2(
  298. pwszConfig,
  299. &CLSID_CCertRequestD,
  300. &IID_ICertRequestD,
  301. &IID_ICertRequestD2,
  302. ppwszAuthority,
  303. ppwszServerName,
  304. pfNewConnection,
  305. pdwServerVersion,
  306. (IUnknown **) ppICertRequestD);
  307. _JumpIfError(hr, error, "_OpenDComConnection2");
  308. error:
  309. return(hr);
  310. }
  311. //+--------------------------------------------------------------------------
  312. // myCloseDComConnection -- release DCOM connection
  313. //
  314. //+--------------------------------------------------------------------------
  315. VOID
  316. myCloseDComConnection(
  317. OPTIONAL IN OUT IUnknown **ppUnknown,
  318. OPTIONAL IN OUT WCHAR **ppwszServerName)
  319. {
  320. if (NULL != ppUnknown && NULL != *ppUnknown)
  321. {
  322. (*ppUnknown)->Release();
  323. *ppUnknown = NULL;
  324. }
  325. if (NULL != ppwszServerName && NULL != *ppwszServerName)
  326. {
  327. LocalFree(*ppwszServerName);
  328. *ppwszServerName = NULL;
  329. }
  330. }
  331. HRESULT
  332. myPingCertSrv(
  333. IN WCHAR const *pwszConfigOrCAName,
  334. OPTIONAL IN WCHAR const *pwszMachineName,
  335. OPTIONAL OUT WCHAR **ppwszzCANames,
  336. OPTIONAL OUT WCHAR **ppwszSharedFolder,
  337. OPTIONAL OUT CAINFO **ppCAInfo,
  338. OPTIONAL OUT DWORD *pdwServerVersion,
  339. OPTIONAL OUT WCHAR **ppwszCADnsName)
  340. {
  341. HRESULT hr;
  342. WCHAR wszConfig[MAX_PATH];
  343. WCHAR const *pwszConfig;
  344. ICertRequestD2 *pICertRequestD = NULL;
  345. WCHAR const *pwszAuthority;
  346. CERTTRANSBLOB ctbCANames;
  347. CERTTRANSBLOB ctbSharedFolder;
  348. CERTTRANSBLOB ctbCAInfo;
  349. CERTTRANSBLOB ctbCADnsName;
  350. CAINFO CAInfo;
  351. CAINFO const *pCAInfo;
  352. DWORD dwServerVersion = 0;
  353. ctbCANames.pb = NULL;
  354. ctbSharedFolder.pb = NULL;
  355. ctbCAInfo.pb = NULL;
  356. ctbCADnsName.pb = NULL;
  357. if (NULL != ppwszzCANames)
  358. {
  359. *ppwszzCANames = NULL;
  360. }
  361. if (NULL != ppwszSharedFolder)
  362. {
  363. *ppwszSharedFolder = NULL;
  364. }
  365. if (NULL != ppCAInfo)
  366. {
  367. *ppCAInfo = NULL;
  368. }
  369. if (NULL != ppwszCADnsName)
  370. {
  371. *ppwszCADnsName = NULL;
  372. }
  373. if (NULL == pwszConfigOrCAName)
  374. {
  375. hr = E_POINTER;
  376. _JumpError(hr, error, "Invalid parameters");
  377. }
  378. pwszConfig = pwszConfigOrCAName;
  379. if (NULL != pwszMachineName)
  380. {
  381. wcscpy(wszConfig, pwszMachineName);
  382. wcscat(wszConfig, L"\\");
  383. wcscat(wszConfig, pwszConfigOrCAName);
  384. pwszConfig = wszConfig;
  385. }
  386. hr = myOpenRequestDComConnection(
  387. pwszConfig,
  388. &pwszAuthority,
  389. NULL,
  390. NULL,
  391. &dwServerVersion,
  392. &pICertRequestD);
  393. _JumpIfError(hr, error, "myOpenRequestDComConnection");
  394. CSASSERT(0 != dwServerVersion);
  395. if (2 <= dwServerVersion)
  396. {
  397. __try
  398. {
  399. hr = pICertRequestD->Ping2(pwszAuthority);
  400. }
  401. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  402. {
  403. }
  404. _JumpIfError(hr, error, "Ping2");
  405. }
  406. else
  407. {
  408. __try
  409. {
  410. hr = pICertRequestD->Ping(pwszAuthority);
  411. }
  412. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  413. {
  414. }
  415. _JumpIfError(hr, error, "Ping");
  416. }
  417. if (NULL != ppwszzCANames)
  418. {
  419. __try
  420. {
  421. hr = pICertRequestD->GetCACert(
  422. GETCERT_CANAME,
  423. pwszAuthority,
  424. &ctbCANames);
  425. }
  426. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  427. {
  428. }
  429. _JumpIfError(hr, error, "GetCACert(CANames)");
  430. // must register this memory
  431. myRegisterMemAlloc(ctbCANames.pb, ctbCANames.cb, CSM_COTASKALLOC);
  432. // Only one CA Name expected for now...
  433. CSASSERT(
  434. (wcslen((WCHAR *) ctbCANames.pb) + 1) * sizeof(WCHAR) ==
  435. ctbCANames.cb);
  436. *ppwszzCANames = (WCHAR *) LocalAlloc(
  437. LMEM_FIXED,
  438. ctbCANames.cb + sizeof(WCHAR));
  439. if (NULL == *ppwszzCANames)
  440. {
  441. hr = E_OUTOFMEMORY;
  442. _JumpError(hr, error, "LocalAlloc");
  443. }
  444. CopyMemory(*ppwszzCANames, ctbCANames.pb, ctbCANames.cb);
  445. (*ppwszzCANames)[ctbCANames.cb/sizeof(WCHAR)] = L'\0';
  446. }
  447. if (NULL != ppwszSharedFolder)
  448. {
  449. __try
  450. {
  451. hr = pICertRequestD->GetCACert(
  452. GETCERT_SHAREDFOLDER,
  453. pwszAuthority,
  454. &ctbSharedFolder);
  455. }
  456. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  457. {
  458. }
  459. _JumpIfError(hr, error, "GetCACert(SharedFolder)");
  460. // must register this memory
  461. myRegisterMemAlloc(ctbSharedFolder.pb, ctbSharedFolder.cb, CSM_COTASKALLOC);
  462. *ppwszSharedFolder = (WCHAR *)LocalAlloc(LMEM_FIXED,
  463. ctbSharedFolder.cb + sizeof(WCHAR));
  464. if (NULL == *ppwszSharedFolder)
  465. {
  466. hr = E_OUTOFMEMORY;
  467. _JumpError(hr, error, "LocalAlloc");
  468. }
  469. CopyMemory(*ppwszSharedFolder, ctbSharedFolder.pb, ctbSharedFolder.cb);
  470. (*ppwszSharedFolder)[ctbSharedFolder.cb/sizeof(WCHAR)] = L'\0';
  471. CSASSERT(wcslen(*ppwszSharedFolder)*sizeof(WCHAR) == ctbSharedFolder.cb);
  472. }
  473. if (NULL != ppCAInfo)
  474. {
  475. __try
  476. {
  477. hr = pICertRequestD->GetCACert(
  478. GETCERT_CAINFO,
  479. pwszAuthority,
  480. &ctbCAInfo);
  481. }
  482. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  483. {
  484. }
  485. if (E_INVALIDARG == hr) // if old server
  486. {
  487. __try
  488. {
  489. hr = pICertRequestD->GetCACert(
  490. GETCERT_CATYPE,
  491. pwszAuthority,
  492. &ctbCAInfo);
  493. }
  494. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  495. {
  496. }
  497. _JumpIfError(hr, error, "GetCACert(CAType)");
  498. myRegisterMemAlloc(ctbCAInfo.pb, ctbCAInfo.cb, CSM_COTASKALLOC);
  499. ZeroMemory(&CAInfo, sizeof(CAInfo));
  500. CAInfo.cbSize = CCSIZEOF_STRUCT(CAINFO, cCASignatureCerts);
  501. CAInfo.CAType = *(ENUM_CATYPES *) ctbCAInfo.pb;
  502. CAInfo.cCASignatureCerts = 1;
  503. pCAInfo = &CAInfo;
  504. }
  505. else
  506. {
  507. _JumpIfError(hr, error, "GetCACert(CAInfo)");
  508. // must register this memory
  509. myRegisterMemAlloc(ctbCAInfo.pb, ctbCAInfo.cb, CSM_COTASKALLOC);
  510. pCAInfo = (CAINFO *) ctbCAInfo.pb;
  511. }
  512. *ppCAInfo = (CAINFO *) LocalAlloc(LMEM_FIXED, pCAInfo->cbSize);
  513. if (NULL == *ppCAInfo)
  514. {
  515. hr = E_OUTOFMEMORY;
  516. _JumpError(hr, error, "LocalAlloc");
  517. }
  518. CopyMemory(*ppCAInfo, pCAInfo, pCAInfo->cbSize);
  519. }
  520. if (NULL != pdwServerVersion)
  521. {
  522. *pdwServerVersion = dwServerVersion;
  523. }
  524. if (NULL != ppwszCADnsName && 2 <= dwServerVersion)
  525. {
  526. __try
  527. {
  528. hr = pICertRequestD->GetCAProperty(
  529. pwszAuthority,
  530. CR_PROP_DNSNAME,
  531. 0,
  532. PROPTYPE_STRING,
  533. &ctbCADnsName);
  534. }
  535. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  536. {
  537. }
  538. _JumpIfError(hr, error, "GetCACert(SharedFolder)");
  539. // must register this memory
  540. myRegisterMemAlloc(ctbCADnsName.pb, ctbCADnsName.cb, CSM_COTASKALLOC);
  541. *ppwszCADnsName = (WCHAR *)LocalAlloc(LMEM_FIXED, ctbCADnsName.cb + sizeof(WCHAR));
  542. if (NULL == *ppwszCADnsName)
  543. {
  544. hr = E_OUTOFMEMORY;
  545. _JumpError(hr, error, "LocalAlloc");
  546. }
  547. CopyMemory(*ppwszCADnsName, ctbCADnsName.pb, ctbCADnsName.cb);
  548. (*ppwszCADnsName)[ctbCADnsName.cb/sizeof(WCHAR)] = L'\0';
  549. CSASSERT((wcslen(*ppwszCADnsName)+1)*sizeof(WCHAR) == ctbCADnsName.cb);
  550. }
  551. hr = S_OK;
  552. error:
  553. myCloseDComConnection((IUnknown **) &pICertRequestD, NULL);
  554. if (NULL != ctbCANames.pb)
  555. {
  556. CoTaskMemFree(ctbCANames.pb);
  557. }
  558. if (NULL != ctbSharedFolder.pb)
  559. {
  560. CoTaskMemFree(ctbSharedFolder.pb);
  561. }
  562. if (NULL != ctbCAInfo.pb)
  563. {
  564. CoTaskMemFree(ctbCAInfo.pb);
  565. }
  566. if (NULL != ctbCADnsName.pb)
  567. {
  568. CoTaskMemFree(ctbCADnsName.pb);
  569. }
  570. return(hr);
  571. }
  572. HRESULT
  573. myEnablePrivilege(
  574. IN LPCTSTR szPrivilege,
  575. IN BOOL fEnable)
  576. {
  577. HRESULT hr = S_OK;
  578. TOKEN_PRIVILEGES NewState;
  579. CAutoHANDLE hThread;
  580. CAutoHANDLE hToken;
  581. NewState.PrivilegeCount = 1;
  582. hThread = GetCurrentThread();
  583. if (!hThread)
  584. {
  585. hr = myHLastError();
  586. _JumpIfError(hr, error, "GetCurrentThread");
  587. }
  588. // Get the access token for current thread
  589. if (!OpenThreadToken(
  590. hThread,
  591. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  592. FALSE,
  593. &hToken))
  594. {
  595. hr = myHLastError();
  596. if(hr==HRESULT_FROM_WIN32(ERROR_NO_TOKEN))
  597. {
  598. HANDLE hProcess = GetCurrentProcess();
  599. if (!hProcess)
  600. {
  601. hr = myHLastError();
  602. _JumpError(hr, error, "GetCurrentProcess");
  603. }
  604. if (!OpenProcessToken(hProcess,
  605. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  606. &hToken))
  607. {
  608. hr = myHLastError();
  609. _JumpError(hr, error, "OpenProcessToken");
  610. }
  611. hr = S_OK;
  612. }
  613. else
  614. {
  615. _JumpError(hr, error, "OpenThreadToken");
  616. }
  617. }
  618. if (!LookupPrivilegeValue(NULL, szPrivilege, &NewState.Privileges[0].Luid))
  619. {
  620. hr = myHLastError();
  621. _JumpIfError(hr, error, "LookupPrivelageValue");
  622. }
  623. NewState.Privileges[0].Attributes = (fEnable?SE_PRIVILEGE_ENABLED:0);
  624. if(!AdjustTokenPrivileges(hToken,
  625. FALSE,
  626. &NewState,
  627. sizeof(NewState),
  628. NULL,
  629. NULL))
  630. {
  631. hr = myHLastError();
  632. _JumpIfError(hr, error, "AdjustTokenPrivileges");
  633. }
  634. error:
  635. return hr;
  636. }