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.

876 lines
26 KiB

  1. // Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  2. // CJobObjSecLimitInfoProps.cpp
  3. //#define _WIN32_WINNT 0x0500
  4. #include "precomp.h"
  5. #pragma warning( disable: 4154 )
  6. #include <wbemprov.h>
  7. #include "FRQueryEx.h"
  8. #include <vector>
  9. #include "helpers.h"
  10. #include "CVARIANT.h"
  11. #include "CObjProps.h"
  12. #include "CJobObjSecLimitInfoProps.h"
  13. #include <crtdbg.h>
  14. //*****************************************************************************
  15. // BEGIN: Declaration of Win32_JobObjectSecLimitInfo class properties.
  16. //*****************************************************************************
  17. // WARNING!! MUST KEEP MEMBERS OF THE FOLLOWING ARRAY
  18. // IN SYNCH WITH THE JOB_OBJ_PROPS ENUMERATION DECLARED
  19. // IN CJobObjProps.h !!!
  20. LPCWSTR g_rgJobObjSecLimitInfoPropNames[] =
  21. {
  22. { L"SettingID" },
  23. { L"SecurityLimitFlags" },
  24. { L"SidsToDisable" },
  25. { L"PrivilegesToDelete" },
  26. { L"RestrictedSids" }
  27. };
  28. //*****************************************************************************
  29. // END: Declaration of Win32_JobObjectSecLimitInfo class properties.
  30. //*****************************************************************************
  31. CJobObjSecLimitInfoProps::CJobObjSecLimitInfoProps()
  32. : m_hJob(NULL),
  33. m_pjosli(NULL)
  34. {
  35. }
  36. CJobObjSecLimitInfoProps::CJobObjSecLimitInfoProps(CHString& chstrNamespace)
  37. : CObjProps(chstrNamespace),
  38. m_hJob(NULL),
  39. m_pjosli(NULL)
  40. {
  41. }
  42. CJobObjSecLimitInfoProps::CJobObjSecLimitInfoProps(
  43. HANDLE hJob,
  44. CHString& chstrNamespace)
  45. : CObjProps(chstrNamespace),
  46. m_hJob(hJob),
  47. m_pjosli(NULL)
  48. {
  49. }
  50. CJobObjSecLimitInfoProps::~CJobObjSecLimitInfoProps()
  51. {
  52. if(m_pjosli)
  53. {
  54. delete m_pjosli;
  55. m_pjosli = NULL;
  56. }
  57. }
  58. // Clients call this to establish which properties
  59. // were requested. This function calls a base class
  60. // helper, which calls our CheckProps function.
  61. // The base class helper finally stores the result
  62. // in the base class member m_dwReqProps.
  63. HRESULT CJobObjSecLimitInfoProps::GetWhichPropsReq(
  64. CFrameworkQuery& cfwq)
  65. {
  66. HRESULT hr = S_OK;
  67. // Call base class version for help.
  68. // Base class version will call our
  69. // CheckProps function.
  70. hr = CObjProps::GetWhichPropsReq(
  71. cfwq,
  72. CheckProps);
  73. return hr;
  74. }
  75. DWORD CJobObjSecLimitInfoProps::CheckProps(
  76. CFrameworkQuery& Query)
  77. {
  78. DWORD dwReqProps = PROP_NONE_REQUIRED;
  79. // Get the requested properties for this
  80. // specific object...
  81. if (Query.IsPropertyRequired(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_ID]))
  82. dwReqProps |= PROP_JOSecLimitInfoID;
  83. if (Query.IsPropertyRequired(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_SecurityLimitFlags]))
  84. dwReqProps |= PROP_SecurityLimitFlags;
  85. if (Query.IsPropertyRequired(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_SidsToDisable]))
  86. dwReqProps |= PROP_SidsToDisable;
  87. if (Query.IsPropertyRequired(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_PrivilegesToDelete]))
  88. dwReqProps |= PROP_PrivilagesToDelete;
  89. if (Query.IsPropertyRequired(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_RestrictedSids]))
  90. dwReqProps |= PROP_RestrictedSids;
  91. return dwReqProps;
  92. }
  93. void CJobObjSecLimitInfoProps::SetHandle(
  94. const HANDLE hJob)
  95. {
  96. m_hJob = hJob;
  97. }
  98. HANDLE& CJobObjSecLimitInfoProps::GetHandle()
  99. {
  100. _ASSERT(m_hJob);
  101. return m_hJob;
  102. }
  103. // Sets the key properties from the ObjectPath.
  104. HRESULT CJobObjSecLimitInfoProps::SetKeysFromPath(
  105. const BSTR ObjectPath,
  106. IWbemContext __RPC_FAR *pCtx)
  107. {
  108. HRESULT hr = WBEM_S_NO_ERROR;
  109. // This array contains the key field names
  110. CHStringArray rgchstrKeys;
  111. rgchstrKeys.Add(g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_ID]);
  112. // This array contains the index numbers
  113. // in m_PropMap corresponding to the keys.
  114. short sKeyNum[1];
  115. sKeyNum[0] = JOSECLMTPROP_ID;
  116. hr = CObjProps::SetKeysFromPath(
  117. ObjectPath,
  118. pCtx,
  119. IDS_Win32_NamedJobObjectSecLimitSetting,
  120. rgchstrKeys,
  121. sKeyNum);
  122. return hr;
  123. }
  124. // Sets the key property from in supplied
  125. // parameter.
  126. HRESULT CJobObjSecLimitInfoProps::SetKeysDirect(
  127. std::vector<CVARIANT>& vecvKeys)
  128. {
  129. HRESULT hr = WBEM_S_NO_ERROR;
  130. if(vecvKeys.size() == 1)
  131. {
  132. short sKeyNum[1];
  133. sKeyNum[0] = JOSECLMTPROP_ID;
  134. hr = CObjProps::SetKeysDirect(
  135. vecvKeys,
  136. sKeyNum);
  137. }
  138. else
  139. {
  140. hr = WBEM_E_INVALID_PARAMETER;
  141. }
  142. return hr;
  143. }
  144. // Sets the non-key properties. Only those
  145. // properties requested are set (as determined
  146. // by base class member m_dwReqProps).
  147. HRESULT CJobObjSecLimitInfoProps::SetNonKeyReqProps()
  148. {
  149. HRESULT hr = WBEM_S_NO_ERROR;
  150. DWORD dwReqProps = GetReqProps();
  151. _ASSERT(m_hJob);
  152. if(!m_hJob) return WBEM_E_INVALID_PARAMETER;
  153. // Because all the properties of this class
  154. // come from the same underlying win32 job
  155. // object structure, we only need to get that
  156. // structure one time. We only need to get
  157. // it at all if at least one non-key property
  158. // was requested.
  159. if(dwReqProps != PROP_NONE_REQUIRED)
  160. {
  161. // Get the value from the underlying JO:
  162. // This is a really flakey API when used
  163. // with a JobObjectSecurityLimitInformation,
  164. // as there is no way to get the size of
  165. // the buffer beforehand. So we have to
  166. // allocate, see if it was enough, and if
  167. // not, reallocate! We'll do this 10 times
  168. // at most, and if still not enough then bail.
  169. // Remember: new's throw on allocation
  170. // failure, hence not checking their allocation
  171. // below.
  172. PBYTE pbBuff = NULL;
  173. DWORD dwSize = 128L;
  174. BOOL fQIJO = FALSE;
  175. try
  176. {
  177. for(short s = 0;
  178. s < 10 && !fQIJO;
  179. s++)
  180. {
  181. pbBuff = new BYTE[dwSize];
  182. ZeroMemory(pbBuff, dwSize);
  183. fQIJO = ::QueryInformationJobObject(
  184. m_hJob,
  185. JobObjectSecurityLimitInformation,
  186. pbBuff,
  187. dwSize,
  188. NULL);
  189. // Want to assign newly allocated
  190. // buffer to a place from which it
  191. // will be guarenteed to be cleaned
  192. // up while we are inside this try
  193. // block.
  194. if(fQIJO)
  195. {
  196. m_pjosli = (PJOBOBJECT_SECURITY_LIMIT_INFORMATION) pbBuff;
  197. }
  198. else
  199. {
  200. delete pbBuff;
  201. pbBuff = NULL;
  202. }
  203. dwSize = dwSize << 1;
  204. }
  205. }
  206. catch(...)
  207. {
  208. if(pbBuff)
  209. {
  210. delete pbBuff;
  211. pbBuff = NULL;
  212. }
  213. throw;
  214. }
  215. if(!fQIJO)
  216. {
  217. _ASSERT(0);
  218. hr = WBEM_E_FAILED;
  219. }
  220. }
  221. return hr;
  222. }
  223. HRESULT CJobObjSecLimitInfoProps::LoadPropertyValues(
  224. IWbemClassObject* pIWCO,
  225. IWbemContext* pCtx,
  226. IWbemServices* pNamespace)
  227. {
  228. HRESULT hr = WBEM_S_NO_ERROR;
  229. if(!pIWCO) return E_POINTER;
  230. // Load properties from the map...
  231. hr = CObjProps::LoadPropertyValues(
  232. g_rgJobObjSecLimitInfoPropNames,
  233. pIWCO);
  234. // Uses member josli and dwReqProps to
  235. // load properties to the instance.
  236. hr = SetInstanceFromJOSLI(
  237. pIWCO,
  238. pCtx,
  239. pNamespace);
  240. return hr;
  241. }
  242. //*****************************************************************************
  243. //
  244. // The following are a family of functions used to set information in a
  245. // Win32_NamedJobObjectSecLimitSetting instance from a
  246. // JOBOBJECT_SECURITY_LIMIT_INFORMATION structure. Called by LoadPropertyValues.
  247. //
  248. //*****************************************************************************
  249. HRESULT CJobObjSecLimitInfoProps::SetInstanceFromJOSLI(
  250. IWbemClassObject* pIWCO,
  251. IWbemContext* pCtx,
  252. IWbemServices* pNamespace)
  253. {
  254. HRESULT hr = WBEM_S_NO_ERROR;
  255. // We expect, when this function is called,
  256. // that at least the member m_pjosli has been
  257. // set (via a call to SetNonKeyReqProps).
  258. // That function will have set the other
  259. // member variables (such as m_ptgSidsToDisable)
  260. // based on which properties were requested.
  261. //
  262. // Our job in this function is to populate
  263. // only those properties of the IWbemClassObject
  264. // (which will be handed back to CIMOM) that
  265. // the user requested. We encapsulate this
  266. // work into helper fuctions for those properties
  267. // that are embedded objects.
  268. DWORD dwReqProps = GetReqProps();
  269. CVARIANT v;
  270. try // CVARIANT can throw and I want the error...
  271. {
  272. if(dwReqProps & PROP_SecurityLimitFlags)
  273. {
  274. v.SetLONG((LONG)m_pjosli->SecurityLimitFlags);
  275. hr = pIWCO->Put(
  276. g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_SecurityLimitFlags],
  277. 0,
  278. &v,
  279. NULL);
  280. }
  281. if(SUCCEEDED(hr))
  282. {
  283. if(dwReqProps & PROP_SidsToDisable)
  284. {
  285. hr = SetInstanceSidsToDisable(
  286. pIWCO,
  287. pCtx,
  288. pNamespace);
  289. }
  290. }
  291. if(SUCCEEDED(hr))
  292. {
  293. if(dwReqProps & PROP_PrivilagesToDelete)
  294. {
  295. hr = SetInstancePrivilegesToDelete(
  296. pIWCO,
  297. pCtx,
  298. pNamespace);
  299. }
  300. }
  301. if(SUCCEEDED(hr))
  302. {
  303. if(dwReqProps & PROP_RestrictedSids)
  304. {
  305. hr = SetInstanceRestrictedSids(
  306. pIWCO,
  307. pCtx,
  308. pNamespace);
  309. }
  310. }
  311. }
  312. catch(CVARIANTError& cve)
  313. {
  314. hr = cve.GetWBEMError();
  315. }
  316. return hr;
  317. }
  318. HRESULT CJobObjSecLimitInfoProps::SetInstanceSidsToDisable(
  319. IWbemClassObject* pIWCO,
  320. IWbemContext* pCtx,
  321. IWbemServices* pNamespace)
  322. {
  323. HRESULT hr = WBEM_S_NO_ERROR;
  324. // If m_ptgSidsToDisable is not null,
  325. // Create a Win32_TokenGroups instance
  326. // and call a function to populate it.
  327. if(m_pjosli->SidsToDisable)
  328. {
  329. IWbemClassObjectPtr pWin32TokenGroups;
  330. hr = CreateInst(
  331. pNamespace,
  332. &pWin32TokenGroups,
  333. _bstr_t(IDS_Win32_TokenGroups),
  334. pCtx);
  335. if(SUCCEEDED(hr))
  336. {
  337. hr = SetInstanceTokenGroups(
  338. pWin32TokenGroups,
  339. m_pjosli->SidsToDisable,
  340. pCtx,
  341. pNamespace);
  342. }
  343. if(SUCCEEDED(hr))
  344. {
  345. try
  346. {
  347. CVARIANT v;
  348. v.SetUnknown(pWin32TokenGroups);
  349. hr = pIWCO->Put(
  350. g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_SidsToDisable],
  351. 0,
  352. &v,
  353. NULL);
  354. }
  355. catch(CVARIANTError& cve)
  356. {
  357. hr = cve.GetWBEMError();
  358. }
  359. }
  360. }
  361. return hr;
  362. }
  363. HRESULT CJobObjSecLimitInfoProps::SetInstancePrivilegesToDelete(
  364. IWbemClassObject* pIWCO,
  365. IWbemContext* pCtx,
  366. IWbemServices* pNamespace)
  367. {
  368. HRESULT hr = WBEM_S_NO_ERROR;
  369. // If m_ptpPrivilegesToDelete is not null,
  370. // Create a Win32_TokenPrivileges instance
  371. // and call a function to populate it.
  372. if(m_pjosli->PrivilegesToDelete)
  373. {
  374. IWbemClassObjectPtr pWin32TokenPrivileges;
  375. hr = CreateInst(
  376. pNamespace,
  377. &pWin32TokenPrivileges,
  378. _bstr_t(IDS_Win32_TokenPrivileges),
  379. pCtx);
  380. if(SUCCEEDED(hr))
  381. {
  382. hr = SetInstanceTokenPrivileges(
  383. pWin32TokenPrivileges,
  384. m_pjosli->PrivilegesToDelete,
  385. pCtx,
  386. pNamespace);
  387. }
  388. if(SUCCEEDED(hr))
  389. {
  390. try
  391. {
  392. CVARIANT v;
  393. v.SetUnknown(pWin32TokenPrivileges);
  394. hr = pIWCO->Put(
  395. g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_PrivilegesToDelete],
  396. 0,
  397. &v,
  398. NULL);
  399. }
  400. catch(CVARIANTError& cve)
  401. {
  402. hr = cve.GetWBEMError();
  403. }
  404. }
  405. }
  406. return hr;
  407. }
  408. HRESULT CJobObjSecLimitInfoProps::SetInstanceRestrictedSids(
  409. IWbemClassObject* pIWCO,
  410. IWbemContext* pCtx,
  411. IWbemServices* pNamespace)
  412. {
  413. HRESULT hr = WBEM_S_NO_ERROR;
  414. // If m_ptgRestrictedSids is not null,
  415. // Create a Win32_TokenGroups instance
  416. // and call a function to populate it.
  417. if(m_pjosli->RestrictedSids)
  418. {
  419. IWbemClassObjectPtr pWin32TokenGroups;
  420. hr = CreateInst(
  421. pNamespace,
  422. &pWin32TokenGroups,
  423. _bstr_t(IDS_Win32_TokenGroups),
  424. pCtx);
  425. if(SUCCEEDED(hr))
  426. {
  427. hr = SetInstanceTokenGroups(
  428. pWin32TokenGroups,
  429. m_pjosli->RestrictedSids,
  430. pCtx,
  431. pNamespace);
  432. }
  433. if(SUCCEEDED(hr))
  434. {
  435. try
  436. {
  437. CVARIANT v;
  438. v.SetUnknown(pWin32TokenGroups);
  439. hr = pIWCO->Put(
  440. g_rgJobObjSecLimitInfoPropNames[JOSECLMTPROP_RestrictedSids],
  441. 0,
  442. &v,
  443. NULL);
  444. }
  445. catch(CVARIANTError& cve)
  446. {
  447. hr = cve.GetWBEMError();
  448. }
  449. }
  450. }
  451. return hr;
  452. }
  453. HRESULT CJobObjSecLimitInfoProps::SetInstanceTokenGroups(
  454. IWbemClassObject* pWin32TokenGroups,
  455. PTOKEN_GROUPS ptg,
  456. IWbemContext* pCtx,
  457. IWbemServices* pNamespace)
  458. {
  459. HRESULT hr = WBEM_S_NO_ERROR;
  460. _ASSERT(ptg);
  461. if(!ptg) return hr = WBEM_E_INVALID_PARAMETER;
  462. // We need to populate the two properties of
  463. // Win32_TokenGroups (passed in as pWin32TokenGroups:
  464. // GroupCount, and Groups. If GroupCount is
  465. // zero, on the other hand, don't bother with
  466. // the Groups property.
  467. try // CVARIANT can throw and I want the error...
  468. {
  469. CVARIANT vGroupCount;
  470. LONG lSize = (LONG)ptg->GroupCount;
  471. vGroupCount.SetLONG(lSize);
  472. hr = pWin32TokenGroups->Put(
  473. IDS_GroupCount,
  474. 0,
  475. &vGroupCount,
  476. NULL);
  477. if(SUCCEEDED(hr) &&
  478. lSize > 0)
  479. {
  480. // Need to create an array for the
  481. // Win32_SidAndAttributes instances...
  482. SAFEARRAY* saSidAndAttr;
  483. SAFEARRAYBOUND rgsabound[1];
  484. long ix[1];
  485. rgsabound[0].cElements = lSize;
  486. rgsabound[0].lLbound = 0;
  487. saSidAndAttr = SafeArrayCreate(VT_UNKNOWN, 1, rgsabound);
  488. ix[0] = 0;
  489. for(long m = 0; m < lSize && SUCCEEDED(hr); m++)
  490. {
  491. IWbemClassObjectPtr pWin32SidAndAttributes;
  492. IWbemClassObjectPtr pWin32Sid;
  493. hr = CreateInst(
  494. pNamespace,
  495. &pWin32SidAndAttributes,
  496. _bstr_t(IDS_Win32_SidAndAttributes),
  497. pCtx);
  498. if(SUCCEEDED(hr))
  499. {
  500. // Set the attrubutes...
  501. CVARIANT vAttributes;
  502. vAttributes.SetLONG((LONG)ptg->Groups[m].Attributes);
  503. hr = pWin32SidAndAttributes->Put(
  504. IDS_Attributes,
  505. 0,
  506. &vAttributes,
  507. NULL);
  508. }
  509. if(SUCCEEDED(hr))
  510. {
  511. // Set the sid...
  512. hr = CreateInst(
  513. pNamespace,
  514. &pWin32Sid,
  515. _bstr_t(IDS_Win32_Sid),
  516. pCtx);
  517. if(SUCCEEDED(hr))
  518. {
  519. _bstr_t bstrtSid;
  520. StringFromSid(
  521. ptg->Groups[m].Sid,
  522. bstrtSid);
  523. // Set the SID property of the Win32_SID...
  524. CVARIANT vSID;
  525. vSID.SetStr(bstrtSid);
  526. hr = pWin32Sid->Put(
  527. IDS_SID,
  528. 0,
  529. &vSID,
  530. NULL);
  531. // As a courtesy, set the domain and
  532. // account name props of win32_sid;
  533. // don't care about failures.
  534. {
  535. CHString chstrName;
  536. CHString chstrDom;
  537. GetNameAndDomainFromPSID(
  538. ptg->Groups[m].Sid,
  539. chstrName,
  540. chstrDom);
  541. vSID.SetStr(chstrName);
  542. pWin32Sid->Put(
  543. IDS_AccountName,
  544. 0,
  545. &vSID,
  546. NULL);
  547. vSID.SetStr(chstrDom);
  548. pWin32Sid->Put(
  549. IDS_ReferencedDomainName,
  550. 0,
  551. &vSID,
  552. NULL);
  553. }
  554. }
  555. // Set the SID property of the
  556. // Win32_SidAndAttributes...
  557. if(SUCCEEDED(hr))
  558. {
  559. CVARIANT vSAndASid;
  560. vSAndASid.SetUnknown(pWin32Sid);
  561. hr = pWin32SidAndAttributes->Put(
  562. IDS_SID,
  563. 0,
  564. &vSAndASid,
  565. NULL);
  566. }
  567. }
  568. // Now we need to add the Win32_SidAndAttributes
  569. // instance to the safearray. We need to make
  570. // sure that the instances we add to the safearray
  571. // don't go away as soon as pWin32SidAndAttributes
  572. // and pWin32Sid go out of scope (being smart
  573. // pointers, they will Release when they do), so
  574. // we must addref both interfaces...
  575. if(SUCCEEDED(hr))
  576. {
  577. pWin32Sid.AddRef();
  578. pWin32SidAndAttributes.AddRef();
  579. SafeArrayPutElement(
  580. saSidAndAttr,
  581. ix,
  582. pWin32SidAndAttributes);
  583. }
  584. ix[0]++;
  585. }
  586. // We now have a populated safe array.
  587. // Now we must set the Groups property
  588. // of the pWin32TokenGroups that was
  589. // passed into this function...
  590. if(SUCCEEDED(hr))
  591. {
  592. CVARIANT vGroups;
  593. vGroups.SetArray(
  594. saSidAndAttr,
  595. VT_UNKNOWN | VT_ARRAY);
  596. hr = pWin32TokenGroups->Put(
  597. IDS_Groups,
  598. 0,
  599. &vGroups,
  600. NULL);
  601. }
  602. }
  603. }
  604. catch(CVARIANTError& cve)
  605. {
  606. hr = cve.GetWBEMError();
  607. }
  608. return hr;
  609. }
  610. HRESULT CJobObjSecLimitInfoProps::SetInstanceTokenPrivileges(
  611. IWbemClassObject* pWin32TokenPrivileges,
  612. PTOKEN_PRIVILEGES ptp,
  613. IWbemContext* pCtx,
  614. IWbemServices* pNamespace)
  615. {
  616. HRESULT hr = WBEM_S_NO_ERROR;
  617. _ASSERT(ptp);
  618. if(!ptp) return hr = WBEM_E_INVALID_PARAMETER;
  619. // We need to populate the two properties of
  620. // Win32_TokenGroups (passed in as pWin32TokenGroups:
  621. // GroupCount, and Groups. If GroupCount is
  622. // zero, on the other hand, don't bother with
  623. // the Groups property.
  624. try // CVARIANT can throw and I want the error...
  625. {
  626. CVARIANT vPrivilegeCount;
  627. LONG lSize = (LONG)ptp->PrivilegeCount;
  628. vPrivilegeCount.SetLONG(lSize);
  629. hr = pWin32TokenPrivileges->Put(
  630. IDS_PrivilegeCount,
  631. 0,
  632. &vPrivilegeCount,
  633. NULL);
  634. if(SUCCEEDED(hr) &&
  635. lSize > 0)
  636. {
  637. // Need to create an array for the
  638. // Win32_LUIDAndAttributes instances...
  639. SAFEARRAY* saLUIDAndAttr;
  640. SAFEARRAYBOUND rgsabound[1];
  641. long ix[1];
  642. rgsabound[0].cElements = lSize;
  643. rgsabound[0].lLbound = 0;
  644. saLUIDAndAttr = SafeArrayCreate(VT_UNKNOWN, 1, rgsabound);
  645. ix[0] = 0;
  646. for(long m = 0; m < lSize && SUCCEEDED(hr); m++)
  647. {
  648. IWbemClassObjectPtr pWin32LUIDAndAttributes;
  649. IWbemClassObjectPtr pWin32LUID;
  650. hr = CreateInst(
  651. pNamespace,
  652. &pWin32LUIDAndAttributes,
  653. _bstr_t(IDS_Win32_LUIDAndAttributes),
  654. pCtx);
  655. if(SUCCEEDED(hr))
  656. {
  657. // Set the attrubutes...
  658. CVARIANT vAttributes;
  659. vAttributes.SetLONG((LONG)ptp->Privileges[m].Attributes);
  660. hr = pWin32LUIDAndAttributes->Put(
  661. IDS_Attributes,
  662. 0,
  663. &vAttributes,
  664. NULL);
  665. }
  666. if(SUCCEEDED(hr))
  667. {
  668. // Set the luid...
  669. hr = CreateInst(
  670. pNamespace,
  671. &pWin32LUID,
  672. _bstr_t(IDS_Win32_LUID),
  673. pCtx);
  674. if(SUCCEEDED(hr))
  675. {
  676. // Set the HighPart and LowPart properties
  677. // of the Win32_LUID...
  678. CVARIANT vHighPart;
  679. vHighPart.SetLONG(ptp->Privileges[m].Luid.HighPart);
  680. hr = pWin32LUID->Put(
  681. IDS_HighPart,
  682. 0,
  683. &vHighPart,
  684. NULL);
  685. if(SUCCEEDED(hr))
  686. {
  687. CVARIANT vLowPart;
  688. vLowPart.SetLONG((LONG)ptp->Privileges[m].Luid.LowPart);
  689. hr = pWin32LUID->Put(
  690. IDS_LowPart,
  691. 0,
  692. &vLowPart,
  693. NULL);
  694. }
  695. }
  696. // Set the LUID property of the
  697. // Win32_LUIDAndAttributes...
  698. if(SUCCEEDED(hr))
  699. {
  700. CVARIANT vLAndALUID;
  701. vLAndALUID.SetUnknown(pWin32LUID);
  702. hr = pWin32LUIDAndAttributes->Put(
  703. IDS_LUID,
  704. 0,
  705. &vLAndALUID,
  706. NULL);
  707. }
  708. }
  709. // Now we need to add the Win32_LUIDAndAttributes
  710. // instance to the safearray. We need to make
  711. // sure that the instances we add to the safearray
  712. // don't go away as soon as pWin32SidAndAttributes
  713. // goes out of scope (being a smart
  714. // pointer, it will Release when it does), so
  715. // we must addref the interface...
  716. if(SUCCEEDED(hr))
  717. {
  718. pWin32LUIDAndAttributes.AddRef();
  719. pWin32LUID.AddRef();
  720. SafeArrayPutElement(
  721. saLUIDAndAttr,
  722. ix,
  723. pWin32LUIDAndAttributes);
  724. }
  725. ix[0]++;
  726. }
  727. // We now have a populated safe array.
  728. // Now we must set the Privileges property
  729. // of the pWin32TokenPrivileges that was
  730. // passed into this function...
  731. if(SUCCEEDED(hr))
  732. {
  733. CVARIANT vPrivileges;
  734. vPrivileges.SetArray(
  735. saLUIDAndAttr,
  736. VT_UNKNOWN | VT_ARRAY);
  737. hr = pWin32TokenPrivileges->Put(
  738. IDS_Privileges,
  739. 0,
  740. &vPrivileges,
  741. NULL);
  742. }
  743. }
  744. }
  745. catch(CVARIANTError& cve)
  746. {
  747. hr = cve.GetWBEMError();
  748. }
  749. return hr;
  750. }