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.

861 lines
17 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. adminacl.cpp
  5. Abstract:
  6. Contains implementation of CAdminACL
  7. Author:
  8. ???
  9. Revision History:
  10. Mohit Srivastava 18-Dec-00
  11. --*/
  12. #define REF
  13. #include "iisprov.h"
  14. #include "adminacl.h"
  15. #include <adserr.h>
  16. CAdminACL::CAdminACL()
  17. {
  18. m_pADs = NULL;
  19. m_pSD = NULL;
  20. m_pDACL = NULL;
  21. }
  22. CAdminACL::~CAdminACL()
  23. {
  24. CloseSD();
  25. }
  26. void CAdminACL::CloseSD()
  27. {
  28. if(m_pDACL)
  29. {
  30. m_pDACL->Release();
  31. m_pDACL = NULL;
  32. }
  33. if(m_pSD)
  34. {
  35. m_pSD->Release();
  36. m_pSD = NULL;
  37. }
  38. if(m_pADs)
  39. {
  40. m_pADs->Release();
  41. m_pADs = NULL;
  42. }
  43. }
  44. HRESULT CAdminACL::GetObjectAsync(
  45. IWbemClassObject* pObj,
  46. ParsedObjectPath* pParsedObject,
  47. WMI_CLASS* pWMIClass)
  48. {
  49. DBG_ASSERT(m_pSD);
  50. DBG_ASSERT(m_pDACL);
  51. HRESULT hr = S_OK;
  52. if( pWMIClass->pkt == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL )
  53. {
  54. hr = PopulateWmiAdminACL(pObj);
  55. }
  56. else if( pWMIClass->pkt == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE )
  57. {
  58. _bstr_t bstrTrustee;
  59. GetTrustee(pObj, pParsedObject, bstrTrustee);
  60. CACEEnumOperation_FindAndReturn op(this, pObj, bstrTrustee);
  61. hr = EnumACEsAndOp(REF op);
  62. }
  63. else
  64. {
  65. DBG_ASSERT(false && "Only valid on AdminACL and AdminACE classes");
  66. hr = E_INVALIDARG;
  67. }
  68. return hr;
  69. }
  70. HRESULT CAdminACL::EnumerateACEsAndIndicate(
  71. BSTR i_bstrNameValue,
  72. CWbemServices& i_refNamespace,
  73. IWbemObjectSink& i_refWbemObjectSink)
  74. {
  75. DBG_ASSERT(m_pSD);
  76. DBG_ASSERT(m_pDACL);
  77. CACEEnumOperation_IndicateAll op(
  78. i_bstrNameValue,
  79. REF i_refNamespace,
  80. REF i_refWbemObjectSink);
  81. return EnumACEsAndOp(REF op);
  82. }
  83. HRESULT CAdminACL::DeleteObjectAsync(
  84. ParsedObjectPath* pParsedObject)
  85. {
  86. HRESULT hr = S_OK;
  87. _bstr_t bstrTrustee;
  88. //
  89. // get the trustee from key
  90. //
  91. GetTrustee(NULL, pParsedObject, bstrTrustee);
  92. //
  93. // remove the ACE
  94. //
  95. DBG_ASSERT(m_pDACL);
  96. CACEEnumOperation_FindAndRemove op(this, bstrTrustee);
  97. hr = EnumACEsAndOp(REF op);
  98. //
  99. // set the modified AdminACL back into the metabase
  100. //
  101. if(SUCCEEDED(hr))
  102. hr = SetSD();
  103. return hr;
  104. }
  105. HRESULT CAdminACL::PutObjectAsync(
  106. IWbemClassObject* pObj,
  107. ParsedObjectPath* pParsedObject,
  108. WMI_CLASS* pWMIClass)
  109. {
  110. DBG_ASSERT(m_pSD);
  111. DBG_ASSERT(m_pDACL);
  112. HRESULT hr = S_OK;
  113. if( pWMIClass->pkt == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL )
  114. {
  115. hr = SetADSIAdminACL(pObj);
  116. }
  117. else if( pWMIClass->pkt == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE )
  118. {
  119. _bstr_t bstrTrustee;
  120. GetTrustee(NULL, pParsedObject, bstrTrustee);
  121. CACEEnumOperation_FindAndUpdate op(this, pObj, bstrTrustee);
  122. hr = EnumACEsAndOp(REF op);
  123. if(hr == WBEM_E_NOT_FOUND)
  124. {
  125. hr = AddACE(pObj, bstrTrustee);
  126. }
  127. }
  128. else
  129. {
  130. DBG_ASSERT(false && "Only valid on AdminACL and AdminACE");
  131. hr = E_INVALIDARG;
  132. }
  133. // set the modified AdminACL back into the metabase
  134. if(SUCCEEDED(hr))
  135. hr = SetSD();
  136. return hr;
  137. }
  138. HRESULT CAdminACL::PopulateWmiAdminACL(
  139. IWbemClassObject* pObj
  140. )
  141. {
  142. VARIANT vt;
  143. HRESULT hr = S_OK;
  144. // Owner
  145. vt.vt = VT_BSTR;
  146. hr = m_pSD->get_Owner(&vt.bstrVal);
  147. if(SUCCEEDED(hr))
  148. {
  149. hr = pObj->Put(L"Owner", 0, &vt, 0);
  150. VariantClear(&vt);
  151. }
  152. // Group
  153. vt.vt = VT_BSTR;
  154. if(SUCCEEDED(hr))
  155. hr = m_pSD->get_Group(&vt.bstrVal);
  156. if(SUCCEEDED(hr))
  157. {
  158. hr = pObj->Put(L"Group", 0, &vt, 0);
  159. VariantClear(&vt);
  160. }
  161. // ControlFlags
  162. vt.vt = VT_I4;
  163. if(SUCCEEDED(hr))
  164. hr = m_pSD->get_Control(&vt.lVal);
  165. if(SUCCEEDED(hr))
  166. {
  167. hr = pObj->Put(L"ControlFlags", 0, &vt, 0);
  168. VariantClear(&vt);
  169. }
  170. return hr;
  171. }
  172. HRESULT CAdminACL::SetADSIAdminACL(
  173. IWbemClassObject* pObj
  174. )
  175. {
  176. VARIANT vt;
  177. HRESULT hr;
  178. // Owner
  179. hr = pObj->Get(L"Owner", 0, &vt, NULL, NULL);
  180. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  181. hr = m_pSD->put_Owner(vt.bstrVal);
  182. VariantClear(&vt);
  183. // Owner
  184. if(SUCCEEDED(hr))
  185. hr = pObj->Get(L"Group", 0, &vt, NULL, NULL);
  186. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  187. hr = m_pSD->put_Group(vt.bstrVal);
  188. VariantClear(&vt);
  189. // ControlFlags
  190. if(SUCCEEDED(hr))
  191. hr = pObj->Get(L"ControlFlags", 0, &vt, NULL, NULL);
  192. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  193. hr = m_pSD->put_Control(vt.lVal);
  194. VariantClear(&vt);
  195. if(FAILED(hr))
  196. {
  197. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  198. }
  199. return hr;
  200. }
  201. HRESULT CAdminACL::OpenSD(
  202. LPCWSTR wszMbPath)
  203. {
  204. DBG_ASSERT(wszMbPath);
  205. CComVariant svar;
  206. HRESULT hr = S_OK;
  207. // close SD interface first
  208. CloseSD();
  209. CComBSTR sbstrAdsPath;
  210. hr = GetAdsPath(wszMbPath, &sbstrAdsPath);
  211. if(FAILED(hr))
  212. {
  213. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  214. return hr;
  215. }
  216. // get m_pADs
  217. hr = ADsGetObject(
  218. sbstrAdsPath,
  219. IID_IADs,
  220. (void**)&m_pADs
  221. );
  222. if(FAILED(hr))
  223. {
  224. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  225. return hr;
  226. }
  227. // get m_pSD
  228. hr = m_pADs->Get(L"AdminACL",&svar);
  229. if(FAILED(hr))
  230. {
  231. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  232. if(hr == E_ADS_PROPERTY_NOT_SUPPORTED)
  233. {
  234. //
  235. // Do this, so WMI does not fail query operations.
  236. //
  237. hr = WBEM_E_NOT_FOUND;
  238. }
  239. return hr;
  240. }
  241. hr = V_DISPATCH(&svar)->QueryInterface(
  242. IID_IADsSecurityDescriptor,
  243. (void**)&m_pSD
  244. );
  245. if(FAILED(hr))
  246. {
  247. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  248. return hr;
  249. }
  250. // get m_pDACL
  251. CComPtr<IDispatch> spDisp;
  252. hr = m_pSD->get_DiscretionaryAcl(&spDisp);
  253. if(FAILED(hr))
  254. {
  255. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  256. return hr;
  257. }
  258. hr = spDisp->QueryInterface(
  259. IID_IADsAccessControlList,
  260. (void**)&m_pDACL
  261. );
  262. if(FAILED(hr))
  263. {
  264. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  265. return hr;
  266. }
  267. return hr;
  268. }
  269. HRESULT CAdminACL::SetSD()
  270. {
  271. VARIANT var;
  272. HRESULT hr = S_OK;
  273. IDispatch* pDisp = NULL;
  274. // put m_pDACL
  275. hr = m_pDACL->QueryInterface(
  276. IID_IDispatch,
  277. (void**)&pDisp
  278. );
  279. if(FAILED(hr))
  280. return hr;
  281. hr = m_pSD->put_DiscretionaryAcl(pDisp);
  282. pDisp->Release();
  283. if(FAILED(hr))
  284. return hr;
  285. //
  286. // put AdminACL
  287. //
  288. hr = m_pSD->QueryInterface(
  289. IID_IDispatch,
  290. (void**)&pDisp
  291. );
  292. if(FAILED(hr))
  293. return hr;
  294. var.vt = VT_DISPATCH;
  295. var.pdispVal = pDisp;
  296. hr = m_pADs->Put(L"AdminACL",var); // pDisp will be released by this call Put().
  297. if(FAILED(hr))
  298. return hr;
  299. //
  300. // Commit the change to the active directory
  301. //
  302. hr = m_pADs->SetInfo();
  303. return hr;
  304. }
  305. HRESULT CAdminACL::GetAdsPath(
  306. LPCWSTR i_wszMbPath,
  307. BSTR* o_pbstrAdsPath)
  308. {
  309. DBG_ASSERT(i_wszMbPath);
  310. DBG_ASSERT(o_pbstrAdsPath);
  311. DBG_ASSERT(*o_pbstrAdsPath == NULL);
  312. CComBSTR sbstr(L"IIS://LocalHost");
  313. if(sbstr.m_str == NULL)
  314. {
  315. return WBEM_E_OUT_OF_MEMORY;
  316. }
  317. //
  318. // trim the first three characters "/LM"
  319. //
  320. sbstr += (i_wszMbPath+3);
  321. if(sbstr.m_str == NULL)
  322. {
  323. return WBEM_E_OUT_OF_MEMORY;
  324. }
  325. //
  326. // Set out params if everything succeeds
  327. //
  328. *o_pbstrAdsPath = sbstr.Detach();
  329. return S_OK;
  330. }
  331. HRESULT CAdminACL::EnumACEsAndOp(
  332. CACEEnumOperation_Base& refOp)
  333. /*++
  334. Synopsis:
  335. This enumerates all the aces for the current acl.
  336. Arguments: [refOp] - Implements Do, and Done. It is okay if Do throws exceptions.
  337. This function will cleanup correctly.
  338. Return Value:
  339. --*/
  340. {
  341. HRESULT hr = S_OK;
  342. CComVariant var;
  343. CComPtr<IEnumVARIANT> spEnum;
  344. ULONG lFetch;
  345. CComPtr<IADsAccessControlEntry> spACE;
  346. hr = GetACEEnum(&spEnum);
  347. if ( FAILED(hr) )
  348. return hr;
  349. //
  350. // Enumerate ACEs
  351. //
  352. hr = spEnum->Next( 1, &var, &lFetch );
  353. while( hr == S_OK )
  354. {
  355. if (lFetch == 1)
  356. {
  357. if (VT_DISPATCH != V_VT(&var))
  358. {
  359. hr = E_UNEXPECTED;
  360. break;
  361. }
  362. //
  363. // Get the individual ACE
  364. //
  365. hr = V_DISPATCH(&var)->QueryInterface(
  366. IID_IADsAccessControlEntry,
  367. (void**)&spACE);
  368. if ( SUCCEEDED(hr) )
  369. {
  370. hr = refOp.Do(spACE);
  371. if(FAILED(hr))
  372. {
  373. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  374. return hr;
  375. }
  376. if(refOp.Done() == CACEEnumOperation_Base::eDONE_YES)
  377. {
  378. break;
  379. }
  380. spACE = NULL;
  381. }
  382. }
  383. var.Clear();
  384. hr = spEnum->Next( 1, &var, &lFetch );
  385. if(hr == S_FALSE && refOp.Done() == CACEEnumOperation_Base::eDONE_NO)
  386. {
  387. hr = WBEM_E_NOT_FOUND;
  388. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  389. return hr;
  390. }
  391. }
  392. return hr;
  393. }
  394. void CAdminACL::GetTrustee(
  395. IWbemClassObject* pObj,
  396. ParsedObjectPath* pPath,
  397. _bstr_t& bstrTrustee
  398. )
  399. /*++
  400. Synopsis:
  401. parse ParsedObjectPath to get the Trustee key
  402. Arguments: [pObj] -
  403. [pPath] -
  404. [bstrTrustee] -
  405. --*/
  406. {
  407. KeyRef* pkr;
  408. WCHAR* pszKey = L"Trustee";
  409. pkr = CUtils::GetKey(pPath, pszKey);
  410. if(pkr->m_vValue.vt == VT_BSTR && pkr->m_vValue.bstrVal != NULL)
  411. {
  412. bstrTrustee = pkr->m_vValue;
  413. }
  414. else
  415. {
  416. THROW_ON_ERROR(WBEM_E_INVALID_OBJECT);
  417. }
  418. if (pObj)
  419. {
  420. _bstr_t bstr = pkr->m_pName;
  421. HRESULT hr = pObj->Put(bstr, 0, &pkr->m_vValue, 0);
  422. THROW_ON_ERROR(hr);
  423. }
  424. }
  425. HRESULT CAdminACL::GetACEEnum(
  426. IEnumVARIANT** pEnum)
  427. {
  428. HRESULT hr = S_OK;
  429. LPUNKNOWN pUnk = NULL;
  430. DBG_ASSERT(pEnum);
  431. if(*pEnum)
  432. {
  433. (*pEnum)->Release();
  434. }
  435. hr = m_pDACL->get__NewEnum( &pUnk );
  436. if ( SUCCEEDED(hr) )
  437. {
  438. hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) pEnum );
  439. }
  440. return hr;
  441. }
  442. HRESULT CAdminACL::AddACE(
  443. IWbemClassObject* pObj,
  444. _bstr_t& bstrTrustee
  445. )
  446. /*++
  447. Synopsis:
  448. Add an ACE.
  449. Arguments: [pObj] -
  450. [bstrTrustee] -
  451. Return Value:
  452. --*/
  453. {
  454. HRESULT hr = m_pDACL->put_AclRevision(ADS_SD_REVISION_DS);
  455. if(FAILED(hr))
  456. {
  457. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  458. return hr;
  459. }
  460. // create a ACE
  461. IADsAccessControlEntry* pACE = NULL;
  462. hr = NewACE(
  463. pObj,
  464. bstrTrustee,
  465. &pACE);
  466. if(FAILED(hr))
  467. {
  468. DBGPRINTF((DBG_CONTEXT, "Failed, hr: 0x%x\n", hr));
  469. return hr;
  470. }
  471. // add the ACE
  472. IDispatch* pDisp = NULL;
  473. hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDisp);
  474. if(SUCCEEDED(hr))
  475. {
  476. hr = m_pDACL->AddAce(pDisp);
  477. pDisp->Release();
  478. }
  479. pACE->Release();
  480. return hr;
  481. }
  482. HRESULT CAdminACL::NewACE(
  483. IWbemClassObject* pObj,
  484. _bstr_t& bstrTrustee,
  485. IADsAccessControlEntry** ppACE
  486. )
  487. /*++
  488. Synopsis:
  489. function to create an ACE
  490. Arguments: [pObj] -
  491. [bstrTrustee] -
  492. [ppACE] -
  493. Return Value:
  494. --*/
  495. {
  496. DBG_ASSERT(ppACE);
  497. HRESULT hr = CoCreateInstance(
  498. CLSID_AccessControlEntry,
  499. NULL,
  500. CLSCTX_INPROC_SERVER,
  501. IID_IADsAccessControlEntry,
  502. (void**)ppACE);
  503. //
  504. // Trustee
  505. //
  506. if(SUCCEEDED(hr))
  507. hr = (*ppACE)->put_Trustee(bstrTrustee);
  508. if(SUCCEEDED(hr))
  509. hr = SetDataOfACE(pObj, *ppACE);
  510. return hr;
  511. }
  512. HRESULT CAdminACL::SetDataOfACE(
  513. IWbemClassObject* pObj,
  514. IADsAccessControlEntry* pACE
  515. )
  516. {
  517. HRESULT hr;
  518. CComVariant vt;
  519. //
  520. // AccessMask
  521. //
  522. hr = pObj->Get(L"AccessMask", 0, &vt, NULL, NULL);
  523. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  524. hr = pACE->put_AccessMask(vt.lVal);
  525. vt.Clear();
  526. //
  527. // AceType
  528. //
  529. if(SUCCEEDED(hr))
  530. hr = pObj->Get(L"AceType", 0, &vt, NULL, NULL);
  531. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  532. hr = pACE->put_AceType(vt.lVal);
  533. vt.Clear();
  534. //
  535. // AceFlags
  536. //
  537. if(SUCCEEDED(hr))
  538. hr = pObj->Get(L"AceFlags", 0, &vt, NULL, NULL);
  539. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  540. hr = pACE->put_AceFlags(vt.lVal);
  541. vt.Clear();
  542. //
  543. // Flags
  544. //
  545. if(SUCCEEDED(hr))
  546. hr = pObj->Get(L"Flags", 0, &vt, NULL, NULL);
  547. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  548. hr = pACE->put_Flags(vt.lVal);
  549. vt.Clear();
  550. //
  551. // ObjectType
  552. //
  553. if(SUCCEEDED(hr))
  554. hr = pObj->Get(L"ObjectType", 0, &vt, NULL, NULL);
  555. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  556. hr = pACE->put_ObjectType(vt.bstrVal);
  557. vt.Clear();
  558. //
  559. // InheritedObjectType
  560. //
  561. if(SUCCEEDED(hr))
  562. hr = pObj->Get(L"InheritedObjectType", 0, &vt, NULL, NULL);
  563. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  564. hr = pACE->put_InheritedObjectType(vt.bstrVal);
  565. vt.Clear();
  566. return hr;
  567. }
  568. //
  569. // CACEEnumOperation_Base
  570. //
  571. HRESULT CACEEnumOperation_Base::PopulateWmiACE(
  572. IWbemClassObject* pObj,
  573. IADsAccessControlEntry* pACE
  574. )
  575. {
  576. _variant_t vt;
  577. BSTR bstr;
  578. long lVal;
  579. HRESULT hr;
  580. // AccessMask
  581. hr = pACE->get_AccessMask(&lVal);
  582. if(SUCCEEDED(hr))
  583. {
  584. vt.vt = VT_I4;
  585. vt.lVal = lVal;
  586. hr = pObj->Put(L"AccessMask", 0, &vt, 0);
  587. }
  588. // AceType
  589. if(SUCCEEDED(hr))
  590. hr = pACE->get_AceType(&lVal);
  591. if(SUCCEEDED(hr))
  592. {
  593. vt.vt = VT_I4;
  594. vt.lVal = lVal;
  595. hr = pObj->Put(L"AceType", 0, &vt, 0);
  596. }
  597. // AceFlags
  598. if(SUCCEEDED(hr))
  599. hr = pACE->get_AceFlags(&lVal);
  600. if(SUCCEEDED(hr))
  601. {
  602. vt.vt = VT_I4;
  603. vt.lVal = lVal;
  604. hr = pObj->Put(L"AceFlags", 0, &vt, 0);
  605. }
  606. // Flags
  607. if(SUCCEEDED(hr))
  608. hr = pACE->get_Flags(&lVal);
  609. if(SUCCEEDED(hr))
  610. {
  611. vt.vt = VT_I4;
  612. vt.lVal = lVal;
  613. hr = pObj->Put(L"Flags", 0, &vt, 0);
  614. }
  615. // ObjectType
  616. if(SUCCEEDED(hr))
  617. hr = pACE->get_ObjectType(&bstr);
  618. if(SUCCEEDED(hr))
  619. {
  620. vt = bstr;
  621. hr = pObj->Put(L"ObjectType", 0, &vt, 0);
  622. SysFreeString(bstr);
  623. }
  624. // InheritedObjectType
  625. if(SUCCEEDED(hr))
  626. hr = pACE->get_InheritedObjectType(&bstr);
  627. if(SUCCEEDED(hr))
  628. {
  629. vt = bstr;
  630. hr = pObj->Put(L"InheritedObjectType", 0, &vt, 0);
  631. SysFreeString(bstr);
  632. }
  633. return hr;
  634. }
  635. //
  636. // CACEEnumOperation_IndicateAll
  637. //
  638. HRESULT CAdminACL::CACEEnumOperation_IndicateAll::Do(
  639. IADsAccessControlEntry* pACE)
  640. {
  641. DBG_ASSERT(pACE);
  642. if(FAILED(m_hr))
  643. {
  644. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", m_hr));
  645. return m_hr;
  646. }
  647. CComPtr<IWbemClassObject> spInstance;
  648. HRESULT hr = m_spClass->SpawnInstance(0, &spInstance);
  649. if(FAILED(hr))
  650. {
  651. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  652. return hr;
  653. }
  654. hr = spInstance->Put(
  655. WMI_CLASS_DATA::s_ACE.pszKeyName,
  656. 0,
  657. &m_vNameValue,
  658. 0);
  659. if(FAILED(hr))
  660. {
  661. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  662. return hr;
  663. }
  664. CComBSTR sbstrTrustee;
  665. hr = pACE->get_Trustee(&sbstrTrustee);
  666. if(FAILED(hr))
  667. {
  668. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  669. return hr;
  670. }
  671. VARIANT vTrustee;
  672. vTrustee.bstrVal = sbstrTrustee;
  673. vTrustee.vt = VT_BSTR;
  674. hr = spInstance->Put(L"Trustee", 0, &vTrustee, 0);
  675. if(FAILED(hr))
  676. {
  677. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  678. return hr;
  679. }
  680. hr = PopulateWmiACE(spInstance, pACE);
  681. if(FAILED(hr))
  682. {
  683. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  684. return hr;
  685. }
  686. hr = m_pWbemObjectSink->Indicate(1, &spInstance);
  687. if(FAILED(hr))
  688. {
  689. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  690. return hr;
  691. }
  692. return hr;
  693. }
  694. //
  695. // CACEEnumOperation_Find
  696. //
  697. HRESULT CAdminACL::CACEEnumOperation_Find::Do(
  698. IADsAccessControlEntry* pACE)
  699. {
  700. DBG_ASSERT(pACE);
  701. DBG_ASSERT(m_eDone == eDONE_NO);
  702. CComBSTR sbstr;
  703. HRESULT hr = pACE->get_Trustee(&sbstr);
  704. if(FAILED(hr))
  705. {
  706. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  707. return hr;
  708. }
  709. if(_wcsicmp(sbstr, m_bstrTrustee) == 0)
  710. {
  711. m_eDone = eDONE_YES;
  712. hr = DoOnMatch(pACE);
  713. if(FAILED(hr))
  714. {
  715. DBGPRINTF((DBG_CONTEXT, "Failure, hr=0x%x\n", hr));
  716. return hr;
  717. }
  718. }
  719. return hr;
  720. }