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.

1466 lines
42 KiB

  1. #include <unk.h>
  2. #include <wbemcli.h>
  3. #include <wbemprov.h>
  4. #include <atlbase.h>
  5. #include <sync.h>
  6. #include <ql.h>
  7. #include "activeds.h"
  8. #include "genlex.h"
  9. #include "objpath.h"
  10. #include "Utility.h"
  11. #include "polictempl.h"
  12. /******************************\
  13. **** POLICY PROVIDER HELPERS ***
  14. \******************************/
  15. #define TEMPLATE_RDN L"CN=PolicyTemplate,CN=WMIPolicy,CN=System"
  16. // returns addref'd pointer back to m_pWMIMgmt
  17. IWbemServices* CPolicyTemplate::GetWMIServices(void)
  18. {
  19. CInCritSec lock(&m_CS);
  20. if (NULL != m_pWMIMgmt)
  21. m_pWMIMgmt->AddRef();
  22. return m_pWMIMgmt;
  23. }
  24. // returns addref'd pointer back to m_pADMgmt
  25. IADsContainer *CPolicyTemplate::GetADServices(wchar_t *pDomain)
  26. {
  27. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] GetADServices (%S)\n", pDomain));
  28. CInCritSec lock(&m_CS);
  29. IADsContainer *pADsContainer = NULL;
  30. HRESULT hres;
  31. QString
  32. DistDomainName;
  33. if(NULL == pDomain)
  34. DistDomainName = m_vDsLocalContext.bstrVal;
  35. else
  36. hres = DistNameFromDomainName(QString(pDomain), DistDomainName);
  37. hres = ADsGetObject(QString(L"LDAP://") << TEMPLATE_RDN << L"," << DistDomainName,
  38. IID_IADsContainer,
  39. (void**) &pADsContainer);
  40. if(NULL == pADsContainer)
  41. pADsContainer = CreateContainers(DistDomainName, QString(TEMPLATE_RDN));
  42. return pADsContainer;
  43. }
  44. // returns false if services pointer has already been set
  45. bool CPolicyTemplate::SetWMIServices(IWbemServices* pServices)
  46. {
  47. CInCritSec lock(&m_CS);
  48. bool bOldOneNull = FALSE;
  49. if (bOldOneNull = (m_pWMIMgmt == NULL))
  50. {
  51. m_pWMIMgmt = pServices;
  52. if(pServices) pServices->AddRef();
  53. }
  54. return bOldOneNull;
  55. }
  56. // returns false if services pointer has already been set
  57. bool CPolicyTemplate::SetADServices(IADsContainer* pServices, unsigned context)
  58. {
  59. CInCritSec lock(&m_CS);
  60. bool
  61. bOldOneNull = TRUE;
  62. switch(context)
  63. {
  64. case AD_LOCAL_CONTEXT :
  65. case AD_GLOBAL_CONTEXT :
  66. m_pADMgmt[context] = pServices;
  67. pServices->AddRef();
  68. bOldOneNull = (m_pADMgmt[context] == NULL);
  69. break;
  70. default : ;
  71. }
  72. return bOldOneNull;
  73. }
  74. CPolicyTemplate::~CPolicyTemplate()
  75. {
  76. // **** WMI services object
  77. if (NULL != m_pWMIMgmt)
  78. {
  79. m_pWMIMgmt->Release();
  80. m_pWMIMgmt= NULL;
  81. }
  82. // **** AD services object
  83. if (NULL != m_pADMgmt)
  84. {
  85. for(int i = 0; i < AD_MAX_CONTEXT; i++)
  86. {
  87. if(NULL != m_pADMgmt[i])
  88. {
  89. m_pADMgmt[i]->Release();
  90. m_pADMgmt[i] = NULL;
  91. }
  92. }
  93. }
  94. };
  95. void* CPolicyTemplate::GetInterface(REFIID riid)
  96. {
  97. if(riid == IID_IWbemServices)
  98. return &m_XProvider;
  99. else if(riid == IID_IWbemProviderInit)
  100. return &m_XInit;
  101. else return NULL;
  102. }
  103. /*********************************************\
  104. *** Policy Template Specific Implementation ***
  105. \*********************************************/
  106. // returns addref'd pointer to class object
  107. IWbemClassObject* CPolicyTemplate::XProvider::GetPolicyTemplateClass()
  108. {
  109. CInCritSec lock(&m_pObject->m_CS);
  110. if(NULL == m_pWMIPolicyClassObject)
  111. {
  112. IWbemServices* pWinMgmt = NULL;
  113. if(pWinMgmt = m_pObject->GetWMIServices())
  114. {
  115. CReleaseMe relMgmt(pWinMgmt);
  116. pWinMgmt->GetObject(g_bstrClassMergeablePolicy,
  117. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  118. NULL,
  119. &m_pWMIPolicyClassObject,
  120. NULL);
  121. }
  122. }
  123. if (m_pWMIPolicyClassObject)
  124. m_pWMIPolicyClassObject->AddRef();
  125. return m_pWMIPolicyClassObject;
  126. }
  127. // returns addref'd pointer to emply class instance
  128. IWbemClassObject* CPolicyTemplate::XProvider::GetPolicyTemplateInstance()
  129. {
  130. IWbemClassObject* pObj = NULL;
  131. IWbemClassObject* pClass = NULL;
  132. if (pClass = GetPolicyTemplateClass())
  133. {
  134. CReleaseMe releaseClass(pClass);
  135. pClass->SpawnInstance(0, &pObj);
  136. }
  137. return pObj;
  138. }
  139. CPolicyTemplate::XProvider::~XProvider()
  140. {
  141. // I fixed it! - HMH ;-)
  142. // CInCritSec lock(&m_pObject->m_CS);
  143. if(NULL != m_pWMIPolicyClassObject)
  144. {
  145. m_pWMIPolicyClassObject->Release();
  146. m_pWMIPolicyClassObject = NULL;
  147. }
  148. }
  149. /*************************\
  150. *** IWbemProviderInit ***
  151. \*************************/
  152. STDMETHODIMP CPolicyTemplate::XInit::Initialize(
  153. LPWSTR, LONG, LPWSTR, LPWSTR, IWbemServices* pServices, IWbemContext* pCtxt,
  154. IWbemProviderInitSink* pSink)
  155. {
  156. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] IWbemProviderInit::Initialize\n"));
  157. CComPtr<IADs>
  158. pRootDSE;
  159. CComPtr<IADsContainer>
  160. pObject;
  161. HRESULT
  162. hres = WBEM_S_NO_ERROR,
  163. hres2 = WBEM_S_NO_ERROR;
  164. // **** impersonate client for security
  165. hres = CoImpersonateClient();
  166. if(FAILED(hres))
  167. {
  168. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume client permissions, 0x%08X\n", hres));
  169. hres = WBEM_S_ACCESS_DENIED;
  170. }
  171. else
  172. {
  173. // **** safe WMI name space pointer
  174. m_pObject->SetWMIServices(pServices);
  175. // **** get pointer to AD policy template table
  176. hres = ADsGetObject(L"LDAP://rootDSE", IID_IADs, (void**)&pRootDSE);
  177. if (FAILED(hres))
  178. {
  179. ERRORTRACE((LOG_ESS, "POLICMAN: (ADsGetObject) could not get object: LDAP://rootDSE, 0x%08X\n", hres));
  180. hres = WBEM_E_NOT_FOUND;
  181. }
  182. else
  183. {
  184. hres = pRootDSE->Get(L"defaultNamingContext",&m_pObject->m_vDsLocalContext);
  185. if(FAILED(hres))
  186. {
  187. ERRORTRACE((LOG_ESS, "POLICMAN: (IADs::Get) could not get defaultNamingContext, 0x%08X\n", hres));
  188. hres = WBEM_E_NOT_FOUND;
  189. }
  190. }
  191. }
  192. hres2 = pSink->SetStatus(hres, 0);
  193. if(FAILED(hres2))
  194. {
  195. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  196. if(SUCCEEDED(hres)) hres = hres2;
  197. }
  198. return hres;
  199. }
  200. /*******************\
  201. *** IWbemServices ***
  202. \*******************/
  203. STDMETHODIMP CPolicyTemplate::XProvider::GetObjectAsync(
  204. /* [in] */ const BSTR ObjectPath,
  205. /* [in] */ long lFlags,
  206. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  207. /* [in] */ IWbemObjectSink __RPC_FAR *pResponse)
  208. {
  209. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] IWbemServices::GetObjectAsync(%S, 0x%x, 0x%x, 0x%x)\n", ObjectPath, lFlags, pCtx, pResponse));
  210. HRESULT
  211. hres = WBEM_S_NO_ERROR,
  212. hres2 = WBEM_S_NO_ERROR;
  213. VARIANT
  214. *pvDomain = NULL,
  215. *pvkeyID = NULL;
  216. CComPtr<IDispatch>
  217. pDisp;
  218. CComPtr<IWbemClassObject>
  219. pObj;
  220. CComPtr<IDirectoryObject>
  221. pDirObj;
  222. CComPtr<IWbemServices>
  223. pNamespace;
  224. CComPtr<IADsContainer>
  225. pADsContainer;
  226. // **** impersonate client
  227. hres = CoImpersonateClient();
  228. if (FAILED(hres))
  229. {
  230. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume callers permissions, 0x%08X\n",hres));
  231. hres = WBEM_E_ACCESS_DENIED;
  232. }
  233. else
  234. {
  235. pNamespace = m_pObject->GetWMIServices();
  236. if(pNamespace == NULL)
  237. {
  238. ERRORTRACE((LOG_ESS, "POLICMAN: WMI services not initialized\n"));
  239. hres = WBEM_E_NOT_FOUND;
  240. }
  241. else
  242. {
  243. // **** Check arguments
  244. if(ObjectPath == NULL || pResponse == NULL)
  245. {
  246. ERRORTRACE((LOG_ESS, "POLICMAN: object path and/or return object are NULL\n"));
  247. hres = WBEM_E_INVALID_PARAMETER;
  248. }
  249. else
  250. {
  251. // **** parse object path
  252. CObjectPathParser
  253. ObjPath(e_ParserAcceptRelativeNamespace);
  254. ParsedObjectPath
  255. *pParsedObjectPath = NULL;
  256. if((ObjPath.NoError != ObjPath.Parse(ObjectPath, &pParsedObjectPath)) ||
  257. ((0 != _wcsicmp(g_bstrClassMergeablePolicy, pParsedObjectPath->m_pClass)) &&
  258. (0 != _wcsicmp(g_bstrClassSimplePolicy, pParsedObjectPath->m_pClass))) ||
  259. (2 != pParsedObjectPath->m_dwNumKeys))
  260. {
  261. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error for object: %S\n", ObjectPath));
  262. hres = WBEM_E_INVALID_QUERY;
  263. }
  264. else
  265. {
  266. int x;
  267. // **** only grab ID key for now
  268. for(x = 0; x < pParsedObjectPath->m_dwNumKeys; x++)
  269. {
  270. if(0 == _wcsicmp((*(pParsedObjectPath->m_paKeys + x))->m_pName, g_bstrID))
  271. pvkeyID = &((*(pParsedObjectPath->m_paKeys + x))->m_vValue);
  272. else if(0 == _wcsicmp((*(pParsedObjectPath->m_paKeys + x))->m_pName, g_bstrDomain))
  273. pvDomain = &((*(pParsedObjectPath->m_paKeys + x))->m_vValue);
  274. }
  275. try
  276. {
  277. pADsContainer = m_pObject->GetADServices(pvDomain->bstrVal);
  278. if(pADsContainer == NULL)
  279. {
  280. ERRORTRACE((LOG_ESS, "POLICMAN: Could not find domain: %S\n", V_BSTR(pvDomain)));
  281. return WBEM_E_ACCESS_DENIED;
  282. }
  283. // **** Get pointer to instance in AD
  284. hres = pADsContainer->GetObject(NULL, QString(L"CN=") << V_BSTR(pvkeyID), &pDisp);
  285. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  286. hres = pDisp->QueryInterface(IID_IDirectoryObject, (void **)&pDirObj);
  287. if(FAILED(hres)) return hres;
  288. // **** HACK **** do quick check to see if object is of correct type
  289. {
  290. CComVariant
  291. vObjType;
  292. CComQIPtr<IADs, &IID_IADs>
  293. pADsObj = pDirObj;
  294. hres2 = pADsObj->Get(g_bstrADNormalizedClass, &vObjType);
  295. if(FAILED(hres2)) return hres2;
  296. if(_wcsicmp(vObjType.bstrVal, pParsedObjectPath->m_pClass))
  297. return WBEM_E_NOT_FOUND;
  298. }
  299. // **** Get the instance and send it back
  300. hres = Policy_ADToCIM(&pObj, pDirObj, pNamespace);
  301. if(pObj == NULL) return WBEM_E_FAILED;
  302. // **** Set object
  303. pResponse->Indicate(1, &pObj);
  304. }
  305. catch(long hret)
  306. {
  307. hres = ADSIToWMIErrorCodes(hret);
  308. ERRORTRACE((LOG_ESS, "POLICMAN: Translation of Policy object from AD to WMI generated HRESULT 0x%08X\n", hres));
  309. }
  310. catch(wchar_t *swErrString)
  311. {
  312. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  313. hres = WBEM_E_FAILED;
  314. }
  315. catch(...)
  316. {
  317. ERRORTRACE((LOG_ESS, "POLICMAN: Caught unknown Exception\n"));
  318. hres = WBEM_E_FAILED;
  319. }
  320. }
  321. ObjPath.Free(pParsedObjectPath);
  322. hres2 = pResponse->SetStatus(0,hres, NULL, NULL);
  323. if(FAILED(hres2))
  324. {
  325. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  326. if(SUCCEEDED(hres)) hres = hres2;
  327. }
  328. }
  329. }
  330. CoRevertToSelf();
  331. }
  332. return hres;
  333. }
  334. STDMETHODIMP CPolicyTemplate::XProvider::CreateInstanceEnumAsync(/* [in] */ const BSTR Class,
  335. /* [in] */ long lFlags,
  336. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  337. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  338. {
  339. return WBEM_E_NOT_SUPPORTED;
  340. }
  341. STDMETHODIMP CPolicyTemplate::XProvider::PutInstanceAsync(
  342. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  343. /* [in] */ long lFlags,
  344. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  345. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  346. {
  347. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] IWbemServices::PutInstanceAsync(0x%x, 0x%x, 0x%x, 0x%x)\n", pInst, lFlags, pCtx, pResponseHandler));
  348. HRESULT
  349. hres = WBEM_S_NO_ERROR,
  350. hres2 = WBEM_S_NO_ERROR;
  351. CComPtr<IADsContainer>
  352. pADsContainer;
  353. CComPtr<IDirectoryObject>
  354. pDirObj;
  355. CComVariant
  356. v1, vRelPath;
  357. // **** impersonate client
  358. hres = CoImpersonateClient();
  359. if(FAILED(hres))
  360. {
  361. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume callers permissions, 0x%08X\n",hres));
  362. hres = WBEM_E_ACCESS_DENIED;
  363. }
  364. else
  365. {
  366. // **** check arguments
  367. if((NULL == pInst) || (NULL == pResponseHandler))
  368. {
  369. ERRORTRACE((LOG_ESS, "POLICMAN: object handle and/or return status object are NULL\n"));
  370. hres = WBEM_E_INVALID_PARAMETER;
  371. }
  372. else
  373. {
  374. // **** put policy obj into AD
  375. try
  376. {
  377. EnsureID(pInst, NULL);
  378. // **** aquire AD path in which to place object
  379. hres = pInst->Get(g_bstrDomain, 0, &v1, NULL, NULL);
  380. if(FAILED(hres)) return hres;
  381. if(VT_BSTR == v1.vt)
  382. pADsContainer = m_pObject->GetADServices(v1.bstrVal);
  383. else
  384. pADsContainer = m_pObject->GetADServices(NULL);
  385. if(pADsContainer == NULL)
  386. {
  387. ERRORTRACE((LOG_ESS, "POLICMAN: Could not find or connect to domain: %S\n", V_BSTR(&v1)));
  388. return WBEM_E_ACCESS_DENIED;
  389. }
  390. hres = pADsContainer->QueryInterface(IID_IDirectoryObject, (void **)&pDirObj);
  391. if(FAILED(hres)) return hres;
  392. // **** copy policy obj into AD
  393. hres = Policy_CIMToAD(lFlags, pInst, pDirObj);
  394. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  395. }
  396. catch(long hret)
  397. {
  398. hres = ADSIToWMIErrorCodes(hret);
  399. ERRORTRACE((LOG_ESS, "POLICMAN: Translation of Policy object from WMI to AD generated HRESULT 0x%08X\n", hres));
  400. }
  401. catch(wchar_t *swErrString)
  402. {
  403. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  404. hres = WBEM_E_FAILED;
  405. }
  406. catch(...)
  407. {
  408. ERRORTRACE((LOG_ESS, "POLICMAN: Caught unknown Exception\n"));
  409. hres = WBEM_E_FAILED;
  410. }
  411. // **** send it back as we may have added keys
  412. if (SUCCEEDED(hres))
  413. pResponseHandler->Indicate(1, &pInst);
  414. // **** indicate return status
  415. pInst->Get(L"__RELPATH", 0, &vRelPath, NULL, NULL);
  416. if(FAILED(pResponseHandler->SetStatus(0, hres, V_BSTR(&vRelPath), NULL)))
  417. {
  418. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  419. }
  420. }
  421. CoRevertToSelf();
  422. }
  423. return hres;
  424. }
  425. STDMETHODIMP CPolicyTemplate::XProvider::DeleteInstanceAsync(
  426. /* [in] */ const BSTR ObjectPath,
  427. /* [in] */ long lFlags,
  428. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  429. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  430. {
  431. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] IWbemServices::DeleteInstanceAsync(%S, 0x%x, 0x%x, 0x%x)\n", ObjectPath, lFlags, pCtx, pResponseHandler));
  432. HRESULT
  433. hres = WBEM_S_NO_ERROR,
  434. hres2 = WBEM_S_NO_ERROR;
  435. CComPtr<IADsContainer>
  436. pADsContainer;
  437. CComPtr<IDispatch>
  438. pDisp;
  439. CComPtr<IADsDeleteOps>
  440. pDelObj;
  441. VARIANT
  442. *pvDomain = NULL,
  443. *pvkeyID = NULL;
  444. ParsedObjectPath
  445. *pParsedObjectPath = NULL;
  446. // **** impersonate client
  447. hres = CoImpersonateClient();
  448. if(FAILED(hres))
  449. {
  450. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume callers permissions, 0x%08X\n",hres));
  451. hres = WBEM_E_ACCESS_DENIED;
  452. }
  453. else
  454. {
  455. // **** check arguments
  456. if((ObjectPath == NULL) || (pResponseHandler == NULL))
  457. {
  458. ERRORTRACE((LOG_ESS, "POLICMAN: object handle and/or return status object are NULL\n"));
  459. hres = WBEM_E_INVALID_PARAMETER;
  460. }
  461. else
  462. {
  463. // **** parse WMI object path
  464. CObjectPathParser
  465. ObjPath(e_ParserAcceptRelativeNamespace);
  466. if((ObjPath.NoError != ObjPath.Parse(ObjectPath, &pParsedObjectPath)) ||
  467. ((0 != _wcsicmp(g_bstrClassMergeablePolicy, pParsedObjectPath->m_pClass)) &&
  468. (0 != _wcsicmp(g_bstrClassSimplePolicy, pParsedObjectPath->m_pClass))) ||
  469. (2 != pParsedObjectPath->m_dwNumKeys))
  470. {
  471. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error for object: %S\n", ObjectPath));
  472. hres = WBEM_E_INVALID_QUERY;
  473. }
  474. else
  475. {
  476. int x;
  477. // **** only grab ID key for now
  478. for(x = 0; x < pParsedObjectPath->m_dwNumKeys; x++)
  479. {
  480. if(0 == _wcsicmp((*(pParsedObjectPath->m_paKeys + x))->m_pName, g_bstrID))
  481. pvkeyID = &((*(pParsedObjectPath->m_paKeys + x))->m_vValue);
  482. else if(0 == _wcsicmp((*(pParsedObjectPath->m_paKeys + x))->m_pName, g_bstrDomain))
  483. pvDomain = &((*(pParsedObjectPath->m_paKeys + x))->m_vValue);
  484. }
  485. pADsContainer = m_pObject->GetADServices(pvDomain->bstrVal);
  486. if(pADsContainer == NULL)
  487. {
  488. ERRORTRACE((LOG_ESS, "POLICMAN: Could not find domain: %S\n", V_BSTR(pvDomain)));;
  489. hres = WBEM_E_ACCESS_DENIED;
  490. }
  491. else
  492. {
  493. // **** Get pointer to instance in AD
  494. BSTR pADClassName;
  495. if(0 == _wcsicmp(g_bstrClassMergeablePolicy, pParsedObjectPath->m_pClass))
  496. pADClassName = g_bstrADClassMergeablePolicy;
  497. else if(0 == _wcsicmp(g_bstrClassSimplePolicy, pParsedObjectPath->m_pClass))
  498. pADClassName = g_bstrADClassSimplePolicy;
  499. hres = pADsContainer->GetObject(NULL, QString(L"CN=") << V_BSTR(pvkeyID), &pDisp);
  500. if(FAILED(hres))
  501. {
  502. hres = ADSIToWMIErrorCodes(hres);
  503. ERRORTRACE((LOG_ESS, "POLICMAN: (IADsContainer::GetObject) could not get object in AD %S, 0x%08X\n", V_BSTR(pvkeyID), hres));
  504. }
  505. else
  506. {
  507. hres = pDisp->QueryInterface(IID_IADsDeleteOps, (void **)&pDelObj);
  508. if(FAILED(hres))
  509. {
  510. ERRORTRACE((LOG_ESS, "POLICMAN: (IDispatch::QueryInterface) could not get IID_IADsDeleteOps interface on object\n"));
  511. }
  512. else
  513. {
  514. // **** delete the instance and all its children in AD
  515. hres = pDelObj->DeleteObject(0);
  516. if(FAILED(hres))
  517. {
  518. hres = ADSIToWMIErrorCodes(hres);
  519. ERRORTRACE((LOG_ESS, "POLICMAN: (IADsDeleteOps::DeleteObject) could not delete object\n"));
  520. }
  521. }
  522. }
  523. }
  524. ObjPath.Free(pParsedObjectPath);
  525. }
  526. // **** Set Status
  527. hres2 = pResponseHandler->SetStatus(0,hres, NULL, NULL);
  528. if(FAILED(hres2))
  529. {
  530. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  531. if(SUCCEEDED(hres)) hres = hres2;
  532. }
  533. }
  534. CoRevertToSelf();
  535. }
  536. return hres;
  537. }
  538. HRESULT GetADContainerInDomain(wchar_t *wcsDomain, wchar_t *wcsPath, IDirectorySearch **pObj);
  539. STDMETHODIMP CPolicyTemplate::XProvider::ExecQueryAsync(
  540. /* [in] */ const BSTR QueryLanguage,
  541. /* [in] */ const BSTR Query,
  542. /* [in] */ long lFlags,
  543. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  544. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  545. {
  546. DEBUGTRACE((LOG_ESS, "POLICMAN: [PolicyTemplate] IWbemServices::ExecQueryAsync(%S, %S, 0x%x, 0x%x, 0x%x)\n", QueryLanguage, Query, lFlags, pCtx, pResponseHandler));
  547. HRESULT
  548. hres = WBEM_E_FAILED;
  549. CComPtr<IWbemServices>
  550. pNameSpace = m_pObject->GetWMIServices();
  551. QL_LEVEL_1_TOKEN
  552. *pToken = NULL;
  553. CComPtr<IDirectorySearch>
  554. pDirectorySearch;
  555. QString
  556. LDAPQuery;
  557. wchar_t
  558. objPath[1024];
  559. ADS_SEARCH_HANDLE
  560. searchHandle;
  561. ADS_SEARCH_COLUMN
  562. searchColumn;
  563. wchar_t
  564. *pszDistName[] = { L"distinguishedName" };
  565. // **** parse WQL expression
  566. CTextLexSource
  567. src(Query);
  568. QL1_Parser
  569. parser(&src);
  570. QL_LEVEL_1_RPN_EXPRESSION
  571. *pExp = NULL;
  572. AutoDelete<QL_LEVEL_1_RPN_EXPRESSION>
  573. AutoExp(&pExp);
  574. int
  575. nRes;
  576. if(nRes = parser.Parse(&pExp))
  577. return WBEM_E_INVALID_QUERY;
  578. // **** find domain attribute
  579. for(int iToken = 0; (iToken < pExp->nNumTokens) && (NULL == pToken); iToken++)
  580. {
  581. pToken = &pExp->pArrayOfTokens[iToken];
  582. if(_wcsicmp(g_bstrDomain, pToken->PropertyName.GetStringAt(pToken->PropertyName.GetNumElements() - 1)))
  583. pToken = NULL;
  584. }
  585. if(NULL == pToken)
  586. {
  587. if(pResponseHandler != NULL)
  588. hres = pResponseHandler->SetStatus(0, WBEMESS_E_REGISTRATION_TOO_BROAD, 0, 0);
  589. return WBEMESS_E_REGISTRATION_TOO_BROAD;
  590. }
  591. if((QL_LEVEL_1_TOKEN::OP_EXPRESSION != pToken->nTokenType) ||
  592. (QL_LEVEL_1_TOKEN::OP_EQUAL != pToken->nOperator) ||
  593. (TRUE == pToken->m_bPropComp) ||
  594. (VT_BSTR != pToken->vConstValue.vt))
  595. return WBEM_E_INVALID_QUERY;
  596. // **** connect to LDAP location
  597. hres = GetADContainerInDomain(pToken->vConstValue.bstrVal, TEMPLATE_RDN, &pDirectorySearch);
  598. if(FAILED(hres) || (pDirectorySearch == NULL))
  599. return WBEM_E_ACCESS_DENIED;
  600. // **** build LDAP query to execute on container pADs
  601. if(0 == _wcsicmp(g_bstrClassMergeablePolicy, pExp->bsClassName))
  602. LDAPQuery << L"(|(objectCategory=msWMI-MergeablePolicyTemplate)(&(objectCategory=msWMI-SimplePolicyTemplate)(msWMI-NormalizedClass=msWMI-MergeablePolicyTemplate)))";
  603. else
  604. LDAPQuery << L"(&(objectCategory=msWMI-SimplePolicyTemplate)(|(msWMI-NormalizedClass=msWMI-SimplePolicyTemplate)(msWMI-NormalizedClass=MSFT_MergeablePolicyTemplate)))";
  605. // **** set search preferences
  606. ADS_SEARCHPREF_INFO
  607. SearchPreferences[1];
  608. SearchPreferences[0].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  609. SearchPreferences[0].vValue.dwType = ADSTYPE_INTEGER;
  610. SearchPreferences[0].vValue.Integer = 1000;
  611. hres = pDirectorySearch->SetSearchPreference(SearchPreferences, 1);
  612. if(FAILED(hres))
  613. {
  614. ERRORTRACE((LOG_ESS, "POLICMAN: Could not set search preferences, returned error: 0x%08X\n", (LPWSTR)LDAPQuery, hres));
  615. return WBEM_E_FAILED;
  616. }
  617. // **** execute query
  618. hres = pDirectorySearch->ExecuteSearch(LDAPQuery, pszDistName, 1, &searchHandle);
  619. if(FAILED(hres))
  620. {
  621. ERRORTRACE((LOG_ESS, "POLICMAN: Could execute query: (%s) returned error: 0x%08X\n", (LPWSTR)LDAPQuery, hres));
  622. return WBEM_E_FAILED;
  623. }
  624. // **** build result list
  625. try
  626. {
  627. while(SUCCEEDED(hres = pDirectorySearch->GetNextRow(searchHandle)) && (S_ADS_NOMORE_ROWS != hres))
  628. {
  629. CComPtr<IDirectoryObject>
  630. pDirectoryObject;
  631. CComPtr<IWbemClassObject>
  632. pWbemClassObject;
  633. // **** get path to object
  634. hres = pDirectorySearch->GetColumn(searchHandle, pszDistName[0], &searchColumn);
  635. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  636. // **** get pointer to object
  637. wcscpy(objPath, L"LDAP://");
  638. wcscat(objPath, searchColumn.pADsValues->CaseIgnoreString);
  639. pDirectorySearch->FreeColumn(&searchColumn);
  640. hres = ADsGetObject(objPath, IID_IDirectoryObject, (void **)&pDirectoryObject);
  641. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  642. hres = Policy_ADToCIM(&pWbemClassObject, pDirectoryObject, pNameSpace);
  643. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  644. if(pWbemClassObject == NULL) return WBEM_E_FAILED;
  645. hres = pResponseHandler->Indicate(1, &pWbemClassObject);
  646. }
  647. }
  648. catch(long hret)
  649. {
  650. hres = ADSIToWMIErrorCodes(hret);
  651. ERRORTRACE((LOG_ESS, "POLICMAN: Translation of Policy object from AD to WMI generated HRESULT 0x%08X\n", hres));
  652. }
  653. catch(wchar_t *swErrString)
  654. {
  655. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  656. hres = WBEM_E_FAILED;
  657. }
  658. catch(...)
  659. {
  660. ERRORTRACE((LOG_ESS, "POLICMAN: Caught unknown Exception\n"));
  661. hres = WBEM_E_FAILED;
  662. }
  663. hres = pDirectorySearch->CloseSearchHandle(searchHandle);
  664. if(pResponseHandler != NULL)
  665. hres = pResponseHandler->SetStatus(0, hres, 0, 0);
  666. return hres;
  667. }
  668. //TODO: clean up bstrs & variants upon raising an exception (maybe theres a CVariantClearMe or some such?)
  669. HRESULT CPolicyTemplate::XProvider::ResolveMergeable(IWbemClassObject* pResolveMe,
  670. IWbemClassObject* pClassDef,
  671. IWbemServices* pPolicyNamespace,
  672. IWbemContext __RPC_FAR* pCtx,
  673. IWbemClassObject __RPC_FAR* pOutParams,
  674. IWbemObjectSink __RPC_FAR* pResponseHandler)
  675. {
  676. HRESULT hr = WBEM_E_FAILED;
  677. DEBUGTRACE((LOG_ESS, "POLICMAN: CPolicyTemplate::ResolveMergeable\n"));
  678. // instanciate instance of target class (pClassDef)
  679. // loop through all range params & place each in out obj
  680. CComVariant
  681. vTable,
  682. vGazinta;
  683. CComPtr<IWbemClassObject>
  684. pTargetInstance,
  685. pRangeParamClass, // class object for range param & in & out params to RangeParam::Resolve
  686. pResolveParamClass,
  687. pResolveParamIn,
  688. pResolveParamOut;
  689. if (SUCCEEDED(hr = pClassDef->SpawnInstance(0, &pTargetInstance)) &&
  690. // **** get MSFT_RangeParam::Resolve() input parameter object
  691. SUCCEEDED(hr = pPolicyNamespace->GetObject(L"MSFT_RangeParam", 0, pCtx, &pRangeParamClass, NULL)) &&
  692. SUCCEEDED(hr = pRangeParamClass->GetMethod(L"Resolve", 0, &pResolveParamClass, NULL)) &&
  693. SUCCEEDED(hr = pResolveParamClass->SpawnInstance(0, &pResolveParamIn))
  694. )
  695. {
  696. // **** set keys from object path
  697. CComVariant
  698. vTargetPath;
  699. if(SUCCEEDED(hr = pResolveMe->Get(g_bstrTargetPath, 0, &vTargetPath, NULL, NULL)))
  700. {
  701. CObjectPathParser
  702. ObjPath(e_ParserAcceptRelativeNamespace);
  703. ParsedObjectPath
  704. *pParsedObjectPath = NULL;
  705. if(ObjPath.NoError != ObjPath.Parse(vTargetPath.bstrVal, &pParsedObjectPath))
  706. {
  707. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error for object: %S\n", vTargetPath.bstrVal));
  708. return WBEM_E_INVALID_OBJECT_PATH;
  709. }
  710. else
  711. {
  712. for(int x = 0; x < pParsedObjectPath->m_dwNumKeys; x++)
  713. {
  714. if((NULL != (*(pParsedObjectPath->m_paKeys + x))->m_pName) &&
  715. ((*(pParsedObjectPath->m_paKeys + x))->m_vValue.vt != VT_NULL))
  716. {
  717. CComVariant
  718. vCurVal;
  719. hr = pTargetInstance->Get((*(pParsedObjectPath->m_paKeys + x))->m_pName, 0, &vCurVal, NULL, NULL);
  720. if(FAILED(hr))
  721. {
  722. if(WBEM_E_NOT_FOUND == hr)
  723. ERRORTRACE((LOG_ESS, "POLICMAN: Policy key setting %S not in target object\n", (*(pParsedObjectPath->m_paKeys + x))->m_pName));
  724. return hr;
  725. }
  726. if(vCurVal.vt != VT_NULL)
  727. {
  728. ERRORTRACE((LOG_ESS, "POLICMAN: Attempt to set policy key setting %S more than once\n", (*(pParsedObjectPath->m_paKeys + x))->m_pName));
  729. return WBEM_E_FAILED;
  730. }
  731. hr = pTargetInstance->Put((*(pParsedObjectPath->m_paKeys + x))->m_pName, 0,
  732. &((*(pParsedObjectPath->m_paKeys + x))->m_vValue), NULL);
  733. if(FAILED(hr)) return hr;
  734. }
  735. }
  736. }
  737. }
  738. // get the array of settings we're setting
  739. pResolveMe->Get(L"RangeSettings", 0, &vTable, NULL, NULL);
  740. SafeArray<IUnknown*, VT_UNKNOWN>
  741. settings(&vTable);
  742. vGazinta = pTargetInstance;
  743. for (int i = 0; i < settings.Size(); i++)
  744. {
  745. CComVariant
  746. vSetting,
  747. vName;
  748. CComPtr<IWbemClassObject>
  749. pResolveParamOut,
  750. pRange;
  751. // **** an in/out param in WMI winds up being copied from the in to the out
  752. // **** so we need to put the new one in every time through the loop
  753. vSetting = settings[i];
  754. hr = pResolveParamIn->Put(L"obj", 0, &vGazinta, NULL);
  755. if(FAILED(hr)) return hr;
  756. hr = pResolveParamIn->Put(L"mergedRange", 0, &vSetting, NULL);
  757. if(FAILED(hr)) return hr;
  758. hr = vSetting.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pRange);
  759. if(FAILED(hr)) return hr;
  760. hr = pRange->Get(L"__CLASS", 0, &vName, NULL, NULL);
  761. if(FAILED(hr)) return hr;
  762. hr = pPolicyNamespace->ExecMethod(vName.bstrVal, L"Resolve", 0, pCtx, pResolveParamIn, &pResolveParamOut, NULL);
  763. if(FAILED(hr)) return hr;
  764. hr = pResolveParamOut->Get(L"obj",0, &vGazinta, NULL, NULL);
  765. if(FAILED(hr)) return hr;
  766. }
  767. // <whew> at this point, our new, improved & merge-ified object is held inside the vGazinta variant
  768. pOutParams->Put(L"obj", 0, &vGazinta, NULL);
  769. hr = WBEM_S_NO_ERROR;
  770. pResponseHandler->Indicate(1, &pOutParams);
  771. }
  772. else
  773. ERRORTRACE((LOG_ESS, "POLICMAN: Failed to create target instance to resolve, 0x%08X\n", hr));
  774. return hr;
  775. }
  776. // extract out class instance from PolicyTemplate in param
  777. HRESULT CPolicyTemplate::XProvider::DoResolve(IWbemServices* pPolicyNamespace,
  778. IWbemContext __RPC_FAR *pCtx,
  779. IWbemClassObject __RPC_FAR *pInParams,
  780. IWbemClassObject __RPC_FAR *pOutParams,
  781. IWbemObjectSink __RPC_FAR *pResponseHandler)
  782. {
  783. HRESULT
  784. hr = WBEM_E_FAILED;
  785. DEBUGTRACE((LOG_ESS, "POLICMAN: CPolicyTemplate::DoResolve\n"));
  786. CComVariant
  787. vTemplate, vClass, vObj, vClassDef;
  788. CComPtr<IWbemClassObject>
  789. pResolveMe, pClassDef;
  790. if(SUCCEEDED(hr = pInParams->Get(L"template", 0, &vTemplate, NULL, NULL)) &&
  791. SUCCEEDED(hr = pInParams->Get(L"classObject", 0, &vClassDef, NULL, NULL)))
  792. {
  793. // **** the instance from which we'll pull our object
  794. if(SUCCEEDED(hr = vTemplate.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pResolveMe)) &&
  795. SUCCEEDED(hr = vClassDef.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pClassDef)))
  796. {
  797. // **** find out what, exactly we are.
  798. // **** we're either a simple policy template, a mergeable policy template
  799. // **** or we're derived from one of those.
  800. pResolveMe->Get(L"__CLASS", 0, &vClass, NULL, NULL);
  801. // **** simple case first
  802. if((_wcsicmp(L"MSFT_SimplePolicyTemplate", vClass.bstrVal) == 0) ||
  803. (pResolveMe->InheritsFrom(L"MSFT_SimplePolicyTemplate") == WBEM_S_NO_ERROR))
  804. {
  805. // **** this one's easy - what's in the input goes into the output
  806. if (SUCCEEDED(hr = pResolveMe->Get(L"TargetObject", 0, &vObj, NULL, NULL)))
  807. {
  808. hr = pOutParams->Put(L"obj", 0, &vObj, NULL);
  809. pResponseHandler->Indicate(1, &pOutParams);
  810. }
  811. }
  812. else if((_wcsicmp(L"MSFT_MergeablePolicyTemplate", vClass.bstrVal) == 0) ||
  813. (pResolveMe->InheritsFrom(L"MSFT_MergeablePolicyTemplate") == WBEM_S_NO_ERROR))
  814. {
  815. hr = ResolveMergeable(pResolveMe, pClassDef, pPolicyNamespace, pCtx, pOutParams, pResponseHandler);
  816. }
  817. else
  818. {
  819. ERRORTRACE((LOG_ESS, "POLICMAN: Invalid class passed to Resolve\n"));
  820. hr = WBEM_E_INVALID_PARAMETER;
  821. }
  822. }
  823. }
  824. DEBUGTRACE((LOG_ESS, "POLICMAN: CPolicyTemplate::DoResolve returning 0x%08X\n", hr));
  825. return hr;
  826. }
  827. HRESULT CPolicyTemplate::XProvider::DoSet(IWbemClassObject* pInParams,
  828. IWbemClassObject* pOutParams,
  829. IWbemClassObject* pClass,
  830. IWbemObjectSink* pResponseHandler,
  831. IWbemServices* pPolicyNamespace)
  832. {
  833. HRESULT
  834. hr = WBEM_S_NO_ERROR;
  835. CComVariant
  836. v;
  837. CComPtr<IWbemClassObject>
  838. pTemplate,
  839. pObj;
  840. if(SUCCEEDED(pInParams->Get(L"base",0,&v,NULL,NULL)) &&
  841. (v.vt == VT_UNKNOWN) &&
  842. (v.punkVal != NULL))
  843. {
  844. if (SUCCEEDED(hr = v.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pObj)))
  845. {
  846. if (SUCCEEDED(hr = pClass->SpawnInstance(0, &pTemplate)))
  847. {
  848. if (SUCCEEDED(pObj->Get(L"__CLASS", 0, &v, NULL, NULL)))
  849. pTemplate->Put(L"TargetClass", 0, &v, NULL);
  850. VariantClear(&v);
  851. if (SUCCEEDED(pObj->Get(L"__NAMESPACE", 0, &v, NULL, NULL)))
  852. pTemplate->Put(L"TargetNamespace", 0, &v, NULL);
  853. VariantClear(&v);
  854. if (SUCCEEDED(pObj->Get(L"__RELPATH", 0, &v, NULL, NULL)))
  855. pTemplate->Put(L"TargetPath", 0, &v, NULL);
  856. VariantClear(&v);
  857. // loop through properties, any that are not NULL
  858. // get set into the template object as range params
  859. pObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
  860. BSTR propName = NULL;
  861. while (SUCCEEDED(hr = pObj->Next(0, &propName, &v, NULL, NULL)) && (hr != WBEM_S_NO_MORE_DATA))
  862. {
  863. CSysFreeMe freeProp(propName);
  864. // TODO: tighten up error checking here!
  865. if (v.vt != VT_NULL)
  866. pObj->Put(propName, 0, &v, NULL);
  867. VariantClear(&v);
  868. }
  869. pObj->EndEnumeration();
  870. if (SUCCEEDED(hr))
  871. {
  872. v = (IUnknown*)pTemplate;
  873. if (SUCCEEDED(hr = pOutParams->Put(L"PolicyObj", 0, &v, NULL)))
  874. pResponseHandler->Indicate(1, &pOutParams);
  875. }
  876. }
  877. }
  878. VariantClear(&v);
  879. }
  880. else
  881. hr = WBEM_E_INVALID_PARAMETER;
  882. return hr;
  883. }
  884. // get safearray out of variant
  885. // if safearray doesn't exist, create it & stuff it into the variant
  886. // in either case, the array you get back is a pointer to the array in the variant
  887. HRESULT CPolicyTemplate::XProvider::GetArray(VARIANT& vArray, SAFEARRAY*& pArray)
  888. {
  889. HRESULT hr = WBEM_S_NO_ERROR;
  890. if ((vArray.vt == (VT_UNKNOWN | VT_ARRAY))
  891. &&
  892. (vArray.parray != NULL))
  893. pArray = vArray.parray;
  894. else
  895. {
  896. VariantClear(&vArray);
  897. vArray.vt = (VT_UNKNOWN | VT_ARRAY);
  898. SAFEARRAYBOUND bounds = {0,0};
  899. vArray.parray = pArray = SafeArrayCreate(VT_UNKNOWN, 1, &bounds);
  900. if (!pArray)
  901. hr = WBEM_E_OUT_OF_MEMORY;
  902. }
  903. return hr;
  904. }
  905. // walk through array - if param of same name exists, replace, else add
  906. // assumptions: pRange is instance of a MSFT_RangeParam & pArray is an array of range params.
  907. HRESULT CPolicyTemplate::XProvider::SetSettingInOurArray(const WCHAR* pName, IWbemClassObject* pRange, SAFEARRAY* pArray)
  908. {
  909. HRESULT hr = WBEM_S_NO_ERROR;
  910. long bound;
  911. SafeArrayGetUBound(pArray, 1, &bound);
  912. // walk through array looking for our goodie
  913. bool bFound = false;
  914. for (long i = 0; (i < bound) && !bFound; i++)
  915. {
  916. // get pointer
  917. IWbemClassObject* pOldRange = NULL;
  918. SafeArrayGetElement(pArray, &i, &pOldRange);
  919. CReleaseMe relOldRange(pOldRange);
  920. // get name
  921. VARIANT vName;
  922. VariantInit(&vName);
  923. pOldRange->Get(L"PropertyName", 0, &vName, NULL, NULL);
  924. // compare name; if same: do game
  925. if ((vName.bstrVal != NULL)
  926. &&
  927. (_wcsicmp(vName.bstrVal, pName) == 0))
  928. {
  929. hr = SafeArrayPutElement(pArray, &i, pRange);
  930. bFound = true;
  931. }
  932. VariantClear(&vName);
  933. }
  934. // okay, wasn't there, grow the array & set it at end
  935. if (!bFound)
  936. {
  937. SAFEARRAYBOUND b = {bound + 2, 0};
  938. if (SUCCEEDED(hr = SafeArrayRedim(pArray, &b)))
  939. {
  940. bound++;
  941. hr = SafeArrayPutElement(pArray, &bound, pRange);
  942. }
  943. }
  944. return hr;
  945. }
  946. // in the inparams there should be a rangeparam
  947. // we'll walk through our array of range params, delete any that have the same name
  948. // and stuff this new one in!
  949. HRESULT CPolicyTemplate::XProvider::DoSetRange(IWbemClassObject* pInParams,
  950. IWbemClassObject* pOutParams,
  951. IWbemObjectSink* pResponseHandler)
  952. {
  953. HRESULT hr = WBEM_E_FAILED;
  954. DEBUGTRACE((LOG_ESS, "POLICMAN: CPolicyTemplate::DoSetRange\n"));
  955. IWbemClassObject* pRange = NULL;
  956. IWbemClassObject* pThis = NULL;
  957. VARIANT vRange;
  958. VARIANT vThis;
  959. VariantInit(&vRange);
  960. VariantInit(&vThis);
  961. if (SUCCEEDED(hr = pInParams->Get(L"rangeSetting", 0, &vRange, NULL, NULL))
  962. &&
  963. (vRange.vt == VT_UNKNOWN)
  964. &&
  965. (vRange.punkVal != NULL)
  966. &&
  967. SUCCEEDED(hr = pInParams->Get(L"PolicyObj", 0, &vThis, NULL, NULL))
  968. &&
  969. (vThis.vt == VT_UNKNOWN)
  970. &&
  971. (vThis.punkVal != NULL)
  972. )
  973. {
  974. if (SUCCEEDED(hr = vThis.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pThis)))
  975. {
  976. CReleaseMe relThis(pThis);
  977. hr = vRange.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pRange);
  978. CReleaseMe relRange(pRange);
  979. VARIANT vName;
  980. VariantInit(&vName);
  981. if (SUCCEEDED(pRange->Get(L"PropertyName", 0, &vName, NULL, NULL))
  982. &&
  983. (vName.vt == VT_BSTR)
  984. &&
  985. (vName.bstrVal != NULL)
  986. &&
  987. (wcslen(vName.bstrVal) != 0)
  988. )
  989. {
  990. VARIANT vArray;
  991. VariantInit(&vArray);
  992. SAFEARRAY* pArray = NULL;
  993. // get current state of range settings
  994. if (SUCCEEDED(hr = pThis->Get(L"RangeSettings", 0, &vArray, NULL, NULL))
  995. &&
  996. SUCCEEDED(hr = GetArray(vArray, pArray)))
  997. {
  998. // walk through pArray
  999. if (SUCCEEDED(hr = SetSettingInOurArray(vName.bstrVal, pRange, pArray)))
  1000. {
  1001. hr = pThis->Put(L"RangeSettings", 0, &vArray, NULL);
  1002. hr = pOutParams->Put(L"PolicyObj", 0, &vThis, NULL);
  1003. pResponseHandler->Indicate(1, &pOutParams);
  1004. }
  1005. }
  1006. VariantClear(&vArray);
  1007. VariantClear(&vName);
  1008. }
  1009. else
  1010. hr = WBEM_E_INVALID_PARAMETER;
  1011. }
  1012. }
  1013. else
  1014. {
  1015. DEBUGTRACE((LOG_ESS, "POLICMAN: failed to retrieve input parameters 0x%08X\n", hr));
  1016. hr = WBEM_E_INVALID_PARAMETER;
  1017. }
  1018. VariantClear(&vThis);
  1019. VariantClear(&vRange);
  1020. return hr;
  1021. }
  1022. HRESULT CPolicyTemplate::XProvider::DoMerge(IWbemServices* pNamespace,
  1023. const BSTR strObjectPath,
  1024. IWbemContext __RPC_FAR *pCtx,
  1025. IWbemClassObject __RPC_FAR *pInParams,
  1026. IWbemClassObject __RPC_FAR *pOutParams,
  1027. IWbemObjectSink __RPC_FAR *pResponseHandler)
  1028. {
  1029. HRESULT
  1030. hres = WBEM_E_FAILED;
  1031. CComPtr<IUnknown>
  1032. pUnk;
  1033. CComPtr<IWbemClassObject>
  1034. pOutResult;
  1035. ParsedObjectPath
  1036. *pParsedObjectPath = NULL;
  1037. CComVariant
  1038. v1;
  1039. // **** parse object path
  1040. CObjectPathParser
  1041. ObjPath(e_ParserAcceptRelativeNamespace);
  1042. if((ObjPath.NoError != ObjPath.Parse(strObjectPath, &pParsedObjectPath)) ||
  1043. (0 != _wcsicmp(pParsedObjectPath->m_pClass, g_bstrClassMergeablePolicy)))
  1044. {
  1045. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error for object: %S\n", strObjectPath));
  1046. hres = WBEM_E_INVALID_QUERY;
  1047. }
  1048. else
  1049. {
  1050. // **** get input array
  1051. hres = pInParams->Get(L"templateList", 0, &v1, NULL, NULL);
  1052. if(FAILED(hres)) return hres;
  1053. // **** perform merge
  1054. SafeArray<IUnknown*, VT_UNKNOWN>
  1055. InputArray(&v1);
  1056. hres = Policy_Merge(InputArray, pOutResult, pNamespace);
  1057. if(FAILED(hres)) return hres;
  1058. if(pOutResult == NULL) return WBEM_E_FAILED;
  1059. // **** insert output of merge
  1060. hres = pOutResult->QueryInterface(IID_IUnknown, (void **)&pUnk);
  1061. if(FAILED(hres)) return hres;
  1062. v1 = pUnk;
  1063. hres = pOutParams->Put(L"mergedTemplate", 0, &v1, 0);
  1064. if(FAILED(hres)) return hres;
  1065. // **** put status in return value
  1066. v1 = hres;
  1067. hres = pOutParams->Put(L"ReturnValue", 0, &v1, 0);
  1068. // **** send output back to client
  1069. hres = pResponseHandler->Indicate(1, &pOutParams);
  1070. if(FAILED(hres)) return hres;
  1071. }
  1072. ObjPath.Free(pParsedObjectPath);
  1073. return hres;
  1074. };
  1075. STDMETHODIMP CPolicyTemplate::XProvider::ExecMethodAsync(
  1076. /* [in] */ const BSTR strObjectPath,
  1077. /* [in] */ const BSTR strMethodName,
  1078. /* [in] */ long lFlags,
  1079. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1080. /* [in] */ IWbemClassObject __RPC_FAR *pInParams,
  1081. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1082. {
  1083. HRESULT
  1084. hres = WBEM_S_NO_ERROR,
  1085. hres2 = WBEM_S_NO_ERROR;
  1086. IWbemServices* pNamespace = m_pObject->GetWMIServices();
  1087. CReleaseMe RelpNamespace(pNamespace);
  1088. // **** impersonate client
  1089. hres = CoImpersonateClient();
  1090. if(FAILED(hres))
  1091. {
  1092. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume client permissions, 0x%08X\n", hres));
  1093. hres = WBEM_S_ACCESS_DENIED;
  1094. }
  1095. else
  1096. {
  1097. if((NULL == strObjectPath) ||
  1098. (NULL == strMethodName) ||
  1099. (NULL == pInParams) ||
  1100. (NULL == pResponseHandler))
  1101. {
  1102. ERRORTRACE((LOG_ESS, "POLICMAN: object handle and/or return status objects are NULL\n"));
  1103. hres = WBEM_E_INVALID_PARAMETER;
  1104. }
  1105. else
  1106. {
  1107. try
  1108. {
  1109. // **** get policy template class definition
  1110. IWbemClassObject* pClass = NULL;
  1111. hres = pNamespace->GetObject(g_bstrClassMergeablePolicy, 0, pCtx, &pClass, NULL);
  1112. if(FAILED(hres)) return WBEM_E_NOT_FOUND;
  1113. CReleaseMe relClass(pClass);
  1114. // **** get output object
  1115. IWbemClassObject* pOutClass = NULL;
  1116. IWbemClassObject* pOutParamsObj = NULL;
  1117. CReleaseMe relOutClass(pOutClass);
  1118. CReleaseMe relOutObj(pOutParamsObj);
  1119. hres = pClass->GetMethod(strMethodName, 0, NULL, &pOutClass);
  1120. if(FAILED(hres)) return hres;
  1121. hres = pOutClass->SpawnInstance(0, &pOutParamsObj);
  1122. if(FAILED(hres)) return hres;
  1123. // figure out which method we're here to service
  1124. if (_wcsicmp(strMethodName, L"Merge") == 0)
  1125. hres = DoMerge(pNamespace, strObjectPath, pCtx, pInParams, pOutParamsObj, pResponseHandler);
  1126. else if (_wcsicmp(strMethodName, L"SetRange") == 0)
  1127. hres = DoSetRange(pInParams, pOutParamsObj, pResponseHandler);
  1128. else if (_wcsicmp(strMethodName, L"Set") == 0)
  1129. hres = DoSet(pInParams, pOutParamsObj, pClass, pResponseHandler, pNamespace);
  1130. else if (_wcsicmp(strMethodName, L"Resolve") == 0)
  1131. hres = DoResolve(pNamespace, pCtx, pInParams, pOutParamsObj, pResponseHandler);
  1132. else
  1133. hres = WBEM_E_INVALID_PARAMETER;
  1134. }
  1135. catch(long hret)
  1136. {
  1137. ERRORTRACE((LOG_ESS, "POLICMAN: caught exception with HRESULT 0x%08X\n", hret));
  1138. hres = hret;
  1139. }
  1140. catch(wchar_t *swErrString)
  1141. {
  1142. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  1143. hres = WBEM_E_FAILED;
  1144. }
  1145. catch(...)
  1146. {
  1147. ERRORTRACE((LOG_ESS, "POLICMAN: Caught unknown Exception\n"));
  1148. hres = WBEM_E_FAILED;
  1149. }
  1150. }
  1151. hres2 = pResponseHandler->SetStatus(0, hres, NULL, NULL);
  1152. if(FAILED(hres2))
  1153. {
  1154. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  1155. if(SUCCEEDED(hres)) hres = hres2;
  1156. }
  1157. CoRevertToSelf();
  1158. }
  1159. return hres;
  1160. }