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.

1391 lines
41 KiB

  1. #include <wbemidl.h>
  2. #include <wbemprov.h>
  3. #include <wbemtime.h>
  4. #include <atlbase.h>
  5. #include <stdio.h> // fprintf
  6. #include <stdlib.h>
  7. #include <locale.h>
  8. #include <buffer.h>
  9. #include <genlex.h>
  10. #include <qllex.h>
  11. #include <ql.h>
  12. #include "objpath.h"
  13. #include "iads.h"
  14. #include "adshlp.h"
  15. #include "Utility.h"
  16. #define MAX_ATTR 25
  17. //***************************************************************************
  18. // Function: Init
  19. //
  20. // Purpose: 1 - Create an instance of the WbemLocator interface
  21. // 2 - Use the pointer returned in step two to connect to
  22. // the server using the specified namespace.
  23. //***************************************************************************
  24. HRESULT ConnectToNameSpace(IWbemServices **ppIWbemServices, WCHAR *pNamespace)
  25. {
  26. HRESULT dwRes;
  27. IWbemLocator *pIWbemLocator = NULL;
  28. CReleaseMe
  29. RelpIWbemLocator(pIWbemLocator);
  30. // **** Create an instance of the WbemLocator interface
  31. dwRes = CoCreateInstance(CLSID_WbemLocator,
  32. NULL,
  33. CLSCTX_INPROC_SERVER,
  34. IID_IWbemLocator,
  35. (LPVOID *) &pIWbemLocator);
  36. // **** connect to the server using the passed in namespace.
  37. if(SUCCEEDED(dwRes))
  38. {
  39. dwRes = pIWbemLocator->ConnectServer(QString(pNamespace), // Namespace
  40. NULL, // Userid
  41. NULL, // PW
  42. NULL, // Locale
  43. NULL, // flags
  44. NULL, // Authority
  45. NULL, // Context
  46. ppIWbemServices);
  47. }
  48. return dwRes;
  49. }
  50. /*********************************************************************
  51. ************** Active Directory Methods ******************************
  52. *********************************************************************/
  53. HRESULT Policy_CIMToAD(long lFlags, IWbemClassObject *pSrcPolicyObj, IDirectoryObject *pDestContainer)
  54. {
  55. HRESULT
  56. hres = WBEM_S_NO_ERROR;
  57. CComVariant
  58. vPolicyType,
  59. v[MAX_ATTR];
  60. long
  61. lIsSimple = 0,
  62. c1,
  63. nOptArgs = 0,
  64. nArgs = 0;
  65. DWORD
  66. dwReturn;
  67. CComQIPtr<IDirectoryObject, &IID_IDirectoryObject>
  68. pDestPolicyObj,
  69. pDirObj;
  70. BYTE defaultBuffer[2048];
  71. ULONG bWritten = 0;
  72. LARGE_INTEGER offset;
  73. CBuffer
  74. ClassDefBuffer(defaultBuffer, 2048, FALSE);
  75. CIMTYPE vtType1;
  76. CComPtr<IDispatch>
  77. pDisp;
  78. CComPtr<IWbemClassObject>
  79. pParamObj;
  80. CComQIPtr<IADsContainer, &IID_IADsContainer>
  81. pADsContainer = pDestContainer;
  82. CComQIPtr<IADs, &IID_IADs>
  83. pADsLegacyObj;
  84. ADSVALUE
  85. AdsValue[MAX_ATTR];
  86. ADS_ATTR_INFO
  87. attrInfo[MAX_ATTR];
  88. WBEMTime
  89. wtCurrentTime;
  90. SYSTEMTIME
  91. SystemTime;
  92. GetSystemTime(&SystemTime);
  93. wtCurrentTime = SystemTime;
  94. // **** determine which class we are putting (Simple or Mergeable)
  95. hres = pSrcPolicyObj->Get(L"__CLASS", 0, &vPolicyType, NULL, NULL);
  96. if(FAILED(hres) || (NULL == V_BSTR(&vPolicyType))) return hres;
  97. if(0 == _wcsicmp(g_bstrClassSimplePolicy, V_BSTR(&vPolicyType)))
  98. lIsSimple = 1;
  99. // **** set policy object type
  100. Init_AdsAttrInfo(&attrInfo[nArgs],
  101. g_bstrADObjectClass,
  102. ADS_ATTR_UPDATE,
  103. ADSTYPE_CASE_IGNORE_STRING,
  104. &AdsValue[nArgs],
  105. 1);
  106. AdsValue[nArgs].CaseIgnoreString = g_bstrADClassSimplePolicy;
  107. int lTypeIndex = nArgs++;
  108. // **** security descriptor
  109. PSECURITY_DESCRIPTOR
  110. pSD = GetADSecurityDescriptor(pDestContainer);
  111. if(NULL == pSD)
  112. {
  113. ERRORTRACE((LOG_ESS, "POLICMAN: could not create security descriptor for policy object\n"));
  114. return WBEM_E_OUT_OF_MEMORY;
  115. }
  116. CNtSecurityDescriptor
  117. cSD(pSD, TRUE);
  118. if(CNtSecurityDescriptor::NoError != cSD.GetStatus()) return WBEM_E_FAILED;
  119. hres = RestrictSecurityDescriptor(cSD);
  120. AdsValue[nArgs].SecurityDescriptor.dwLength = cSD.GetSize();
  121. AdsValue[nArgs].SecurityDescriptor.lpValue = (LPBYTE) cSD.GetPtr();
  122. Init_AdsAttrInfo(&attrInfo[nArgs],
  123. L"ntSecurityDescriptor",
  124. ADS_ATTR_UPDATE,
  125. ADSTYPE_NT_SECURITY_DESCRIPTOR,
  126. &AdsValue[nArgs],
  127. 1);
  128. nArgs++;
  129. // **** ID
  130. hres = pSrcPolicyObj->Get(g_bstrID, 0, &v[nArgs], NULL, NULL);
  131. if(FAILED(hres)) return hres;
  132. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  133. {
  134. Init_AdsAttrInfo(&attrInfo[nArgs],
  135. g_bstrADID,
  136. ADS_ATTR_UPDATE,
  137. ADSTYPE_CASE_IGNORE_STRING,
  138. &AdsValue[nArgs],
  139. 1);
  140. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  141. }
  142. else
  143. return WBEM_E_ILLEGAL_NULL;
  144. int lIDIndex = nArgs++;
  145. // **** if object already exists, get a pointer to it
  146. CComBSTR
  147. PolicyName(L"CN=");
  148. PolicyName.Append(AdsValue[lIDIndex].CaseIgnoreString);
  149. // **** LEGACY code to delete existing mergeable policy AD objects
  150. if(SUCCEEDED(hres = pADsContainer->GetObject(NULL, PolicyName, &pDisp)))
  151. {
  152. pADsLegacyObj = pDisp;
  153. CComBSTR
  154. bstrClassName;
  155. hres = pADsLegacyObj->get_Class(&bstrClassName);
  156. if(FAILED(hres)) return hres;
  157. if(0 != _wcsicmp(g_bstrADClassMergeablePolicy, bstrClassName))
  158. pADsLegacyObj.Release();
  159. }
  160. // **** Description
  161. hres = pSrcPolicyObj->Get(g_bstrDescription, 0, &v[nArgs], NULL, NULL);
  162. if(FAILED(hres)) return hres;
  163. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  164. {
  165. Init_AdsAttrInfo(&attrInfo[nArgs],
  166. g_bstrADDescription,
  167. ADS_ATTR_UPDATE,
  168. ADSTYPE_CASE_IGNORE_STRING,
  169. &AdsValue[nArgs],
  170. 1);
  171. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  172. nArgs++;
  173. }
  174. // **** TargetType
  175. hres = pSrcPolicyObj->Get(g_bstrTargetType, 0, &v[nArgs], NULL, NULL);
  176. if(FAILED(hres)) return hres;
  177. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  178. {
  179. Init_AdsAttrInfo(&attrInfo[nArgs],
  180. g_bstrADTargetType,
  181. ADS_ATTR_UPDATE,
  182. ADSTYPE_CASE_IGNORE_STRING,
  183. &AdsValue[nArgs],
  184. 1);
  185. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  186. nArgs++;
  187. }
  188. // **** Name
  189. hres = pSrcPolicyObj->Get(g_bstrName, 0, &v[nArgs], NULL, NULL);
  190. if(FAILED(hres)) return hres;
  191. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  192. {
  193. Init_AdsAttrInfo(&attrInfo[nArgs],
  194. g_bstrADName,
  195. ADS_ATTR_UPDATE,
  196. ADSTYPE_CASE_IGNORE_STRING,
  197. &AdsValue[nArgs],
  198. 1);
  199. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  200. nArgs++;
  201. }
  202. // **** TargetNameSpace
  203. hres = pSrcPolicyObj->Get(g_bstrTargetNameSpace, 0, &v[nArgs], NULL, NULL);
  204. if(FAILED(hres)) return hres;
  205. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  206. {
  207. Init_AdsAttrInfo(&attrInfo[nArgs],
  208. g_bstrADTargetNameSpace,
  209. ADS_ATTR_UPDATE,
  210. ADSTYPE_CASE_IGNORE_STRING,
  211. &AdsValue[nArgs],
  212. 1);
  213. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  214. nArgs++;
  215. }
  216. else
  217. return WBEM_E_ILLEGAL_NULL;
  218. // **** TargetClass
  219. hres = pSrcPolicyObj->Get(g_bstrTargetClass, 0, &v[nArgs], NULL, NULL);
  220. if(FAILED(hres)) return hres;
  221. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  222. {
  223. Init_AdsAttrInfo(&attrInfo[nArgs],
  224. g_bstrADTargetClass,
  225. ADS_ATTR_UPDATE,
  226. ADSTYPE_CASE_IGNORE_STRING,
  227. &AdsValue[nArgs],
  228. 1);
  229. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  230. nArgs++;
  231. }
  232. // **** TargetPath
  233. if(lIsSimple)
  234. {
  235. CComPtr<IWbemClassObject>
  236. pTargetObj;
  237. CComVariant
  238. vTargetObj;
  239. hres = pSrcPolicyObj->Get(g_bstrTargetObject, 0, &vTargetObj, NULL, NULL);
  240. if(FAILED(hres)) return hres;
  241. if((vTargetObj.vt != VT_UNKNOWN) || (vTargetObj.punkVal == NULL))
  242. return WBEM_E_ILLEGAL_NULL;
  243. hres = vTargetObj.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pTargetObj);
  244. if(FAILED(hres)) return hres;
  245. hres = pTargetObj->Get(L"__RELPATH", 0, &v[nArgs], NULL, NULL);
  246. if(FAILED(hres)) return hres;
  247. if ((v[nArgs].vt != VT_BSTR) || (v[nArgs].bstrVal == NULL))
  248. return WBEM_E_ILLEGAL_NULL;
  249. }
  250. else
  251. {
  252. hres = pSrcPolicyObj->Get(g_bstrTargetPath, 0, &v[nArgs], NULL, NULL);
  253. if(FAILED(hres)) return hres;
  254. }
  255. {
  256. CObjectPathParser
  257. ObjPath(e_ParserAcceptRelativeNamespace);
  258. ParsedObjectPath
  259. *pParsedObjectPath = NULL;
  260. if(ObjPath.NoError != ObjPath.Parse(v[nArgs].bstrVal, &pParsedObjectPath))
  261. {
  262. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error target path: %S\n", v[nArgs].bstrVal));
  263. return WBEM_E_INVALID_PARAMETER;
  264. }
  265. if(NULL != pParsedObjectPath)
  266. ObjPath.Free(pParsedObjectPath);
  267. }
  268. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  269. {
  270. Init_AdsAttrInfo(&attrInfo[nArgs],
  271. g_bstrADTargetPath,
  272. ADS_ATTR_UPDATE,
  273. ADSTYPE_CASE_IGNORE_STRING,
  274. &AdsValue[nArgs],
  275. 1);
  276. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  277. nArgs++;
  278. }
  279. // **** NormalizedClass
  280. Init_AdsAttrInfo(&attrInfo[nArgs],
  281. g_bstrADNormalizedClass,
  282. ADS_ATTR_UPDATE,
  283. ADSTYPE_CASE_IGNORE_STRING,
  284. &AdsValue[nArgs],
  285. 1);
  286. if(lIsSimple)
  287. AdsValue[nArgs].CaseIgnoreString = g_bstrADClassSimplePolicy;
  288. else
  289. AdsValue[nArgs].CaseIgnoreString = g_bstrADClassMergeablePolicy;
  290. nArgs++;
  291. // **** SourceOrganization
  292. hres = pSrcPolicyObj->Get(g_bstrSourceOrganization, 0, &v[nArgs], NULL, NULL);
  293. if(FAILED(hres)) return hres;
  294. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  295. {
  296. Init_AdsAttrInfo(&attrInfo[nArgs],
  297. g_bstrADSourceOrganization,
  298. ADS_ATTR_UPDATE,
  299. ADSTYPE_CASE_IGNORE_STRING,
  300. &AdsValue[nArgs],
  301. 1);
  302. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  303. nArgs++;
  304. }
  305. // **** Author
  306. hres = pSrcPolicyObj->Get(g_bstrAuthor, 0, &v[nArgs], NULL, NULL);
  307. if(FAILED(hres)) return hres;
  308. if ((v[nArgs].vt == VT_BSTR) && (v[nArgs].bstrVal != NULL))
  309. {
  310. Init_AdsAttrInfo(&attrInfo[nArgs],
  311. g_bstrADAuthor,
  312. ADS_ATTR_UPDATE,
  313. ADSTYPE_CASE_IGNORE_STRING,
  314. &AdsValue[nArgs],
  315. 1);
  316. AdsValue[nArgs].CaseIgnoreString = V_BSTR(&v[nArgs]);
  317. nArgs++;
  318. }
  319. // **** ChangeDate
  320. Init_AdsAttrInfo(&attrInfo[nArgs],
  321. g_bstrADChangeDate,
  322. ADS_ATTR_UPDATE,
  323. ADSTYPE_CASE_IGNORE_STRING,
  324. &AdsValue[nArgs],
  325. 1);
  326. AdsValue[nArgs].CaseIgnoreString = wtCurrentTime.GetDMTF(FALSE);
  327. nArgs++;
  328. // **** CreationDate
  329. if(NULL == pDisp.p)
  330. {
  331. AdsValue[nArgs].CaseIgnoreString = wtCurrentTime.GetDMTF(FALSE);
  332. Init_AdsAttrInfo(&attrInfo[nArgs],
  333. g_bstrADCreationDate,
  334. ADS_ATTR_UPDATE,
  335. ADSTYPE_CASE_IGNORE_STRING,
  336. &AdsValue[nArgs],
  337. 1);
  338. nArgs++;
  339. }
  340. // **** LEGACY code to delete existing mergeable policy AD objects
  341. else if(NULL != pADsLegacyObj.p)
  342. {
  343. VARIANT
  344. vCreationDate;
  345. hres = pADsLegacyObj->Get(g_bstrADCreationDate, &vCreationDate);
  346. if(FAILED(hres)) return hres;
  347. AdsValue[nArgs].CaseIgnoreString = vCreationDate.bstrVal;
  348. Init_AdsAttrInfo(&attrInfo[nArgs],
  349. g_bstrADCreationDate,
  350. ADS_ATTR_UPDATE,
  351. ADSTYPE_CASE_IGNORE_STRING,
  352. &AdsValue[nArgs],
  353. 1);
  354. nArgs++;
  355. }
  356. // **** Target Object/Range Settings
  357. offset.LowPart = 0;
  358. offset.HighPart = 0;
  359. hres = ClassDefBuffer.Seek(offset, STREAM_SEEK_SET, NULL);
  360. if(FAILED(hres)) return hres;
  361. if(lIsSimple)
  362. {
  363. hres = pSrcPolicyObj->Get(g_bstrTargetObject, 0, &v[nArgs], NULL, NULL);
  364. if(FAILED(hres)) return hres;
  365. hres = CoMarshalInterface(&ClassDefBuffer,
  366. IID_IWbemClassObject,
  367. v[nArgs].punkVal,
  368. MSHCTX_NOSHAREDMEM,
  369. NULL,
  370. MSHLFLAGS_TABLESTRONG);
  371. if(FAILED(hres)) return hres;
  372. }
  373. else
  374. {
  375. CComVariant
  376. vRangeParams;
  377. SafeArray<IUnknown*, VT_UNKNOWN>
  378. Array1;
  379. wchar_t
  380. swArraySize[20];
  381. hres = pSrcPolicyObj->Get(g_bstrRangeSettings, 0, &vRangeParams, NULL, NULL);
  382. if(FAILED(hres)) return hres;
  383. if(vRangeParams.vt != (VT_ARRAY | VT_UNKNOWN)) return WBEM_E_INVALID_PARAMETER;
  384. Array1 = &vRangeParams;
  385. _itow(Array1.Size(), swArraySize, 10);
  386. ClassDefBuffer.Write(swArraySize, sizeof(wchar_t) * 20, NULL);
  387. for(c1 = 0; c1 < Array1.Size(); c1++)
  388. {
  389. CComVariant
  390. vParamType;
  391. CComQIPtr<IWbemClassObject, &IID_IWbemClassObject>
  392. pParamObj = Array1[c1];
  393. // **** verify valid range parameter
  394. hres = pParamObj->Get(L"__CLASS", 0, &vParamType, NULL, NULL);
  395. if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassRangeSint32))
  396. hres = Range_Sint32_Verify(pParamObj);
  397. else if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassRangeUint32))
  398. hres = Range_Uint32_Verify(pParamObj);
  399. else if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassRangeReal))
  400. hres = Range_Real_Verify(pParamObj);
  401. else if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassSetSint32))
  402. hres = Set_Sint32_Verify(pParamObj);
  403. else if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassSetUint32))
  404. hres = Set_Uint32_Verify(pParamObj);
  405. else if(0 == _wcsicmp(V_BSTR(&vParamType), g_bstrClassSetString))
  406. hres = Set_String_Verify(pParamObj);
  407. else
  408. hres = Param_Unknown_Verify(pParamObj);
  409. if(FAILED(hres)) return hres;
  410. // **** pack range parameter into TargetObject
  411. hres = CoMarshalInterface(&ClassDefBuffer, IID_IUnknown, Array1[c1],
  412. MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
  413. if(FAILED(hres)) return hres;
  414. }
  415. }
  416. Init_AdsAttrInfo(&attrInfo[nArgs],
  417. g_bstrADTargetObject,
  418. ADS_ATTR_UPDATE,
  419. ADSTYPE_OCTET_STRING,
  420. &AdsValue[nArgs],
  421. 1);
  422. AdsValue[nArgs].OctetString.dwLength = ClassDefBuffer.GetIndex();
  423. AdsValue[nArgs].OctetString.lpValue = ClassDefBuffer.GetRawData();
  424. nArgs++;
  425. // **** create AD policy object
  426. if(NULL != pDisp.p)
  427. {
  428. if(WBEM_FLAG_CREATE_ONLY & lFlags) return WBEM_E_ALREADY_EXISTS;
  429. if(NULL != pADsLegacyObj.p)
  430. {
  431. CComQIPtr<IADsDeleteOps, &IID_IADsDeleteOps>
  432. pDelObj = pADsLegacyObj;
  433. pDisp = NULL;
  434. pADsLegacyObj.Release();
  435. pDelObj->DeleteObject(0);
  436. hres = pDestContainer->CreateDSObject(PolicyName, attrInfo, nArgs, &pDisp);
  437. if(FAILED(hres)) return hres;
  438. }
  439. else
  440. {
  441. pDirObj = pDisp;
  442. hres = pDirObj->SetObjectAttributes(&attrInfo[2], nArgs - 2, &dwReturn);
  443. if(FAILED(hres)) return hres;
  444. }
  445. }
  446. else
  447. {
  448. if(WBEM_FLAG_UPDATE_ONLY & lFlags)
  449. return WBEM_E_NOT_FOUND;
  450. hres = pDestContainer->CreateDSObject(PolicyName, attrInfo, nArgs, &pDisp);
  451. if(FAILED(hres)) return hres;
  452. }
  453. return WBEM_S_NO_ERROR;
  454. }
  455. HRESULT Policy_ADToCIM(IWbemClassObject * *ppDestPolicyObj,
  456. IDirectoryObject *pSrcPolicyObj,
  457. IWbemServices *pDestCIM)
  458. {
  459. HRESULT
  460. hres = WBEM_S_NO_ERROR;
  461. CComVariant
  462. v1;
  463. wchar_t* AttrNames[] =
  464. {
  465. g_bstrADID,
  466. g_bstrADDescription,
  467. g_bstrADName,
  468. g_bstrADTargetNameSpace,
  469. g_bstrADTargetClass,
  470. g_bstrADTargetPath,
  471. g_bstrADTargetType,
  472. g_bstrADNormalizedClass,
  473. g_bstrADSourceOrganization,
  474. g_bstrADAuthor,
  475. g_bstrADChangeDate,
  476. g_bstrADCreationDate,
  477. g_bstrADTargetObject
  478. };
  479. wchar_t* AttrType[] =
  480. {
  481. g_bstrADNormalizedClass
  482. };
  483. wchar_t* AttrTypeLegacy[] =
  484. {
  485. g_bstrADObjectClass
  486. };
  487. BYTE defaultBuffer[2048];
  488. ULONG bWritten = 0;
  489. LARGE_INTEGER offset;
  490. CBuffer
  491. ClassDefBuffer(defaultBuffer, 2048, FALSE);
  492. ADsStruct<ADS_ATTR_INFO>
  493. pAttrTypeInfo,
  494. pAttrTypeInfoLegacy,
  495. pAttrInfo;
  496. unsigned long
  497. ulIsLegacy = 0,
  498. ulIsSimple = 0,
  499. c1,
  500. dwReturn;
  501. CComPtr<IUnknown>
  502. pUnknown;
  503. CComPtr<IWbemClassObject>
  504. pClassDef,
  505. pDestPolicyObj,
  506. pDestParamObj;
  507. CComPtr<IWbemContext>
  508. pCtx;
  509. ADsStruct<ADS_OBJECT_INFO>
  510. pInfo;
  511. // **** determine policy object type
  512. hres = pSrcPolicyObj->GetObjectAttributes(AttrTypeLegacy, 1, &pAttrTypeInfoLegacy, &dwReturn);
  513. if(FAILED(hres)) return hres;
  514. if(pAttrTypeInfoLegacy == NULL) return WBEM_E_NOT_FOUND;
  515. if(0 == _wcsicmp(g_bstrADClassMergeablePolicy, (pAttrTypeInfoLegacy->pADsValues + pAttrTypeInfoLegacy->dwNumValues - 1)->CaseIgnoreString))
  516. ulIsLegacy = 1;
  517. else
  518. {
  519. hres = pSrcPolicyObj->GetObjectAttributes(AttrType, 1, &pAttrTypeInfo, &dwReturn);
  520. if(FAILED(hres)) return hres;
  521. if(pAttrTypeInfo == NULL) return WBEM_E_NOT_FOUND;
  522. if(0 == _wcsicmp(g_bstrADClassSimplePolicy, (pAttrTypeInfo->pADsValues + pAttrTypeInfo->dwNumValues - 1)->CaseIgnoreString))
  523. ulIsSimple = 1;
  524. else if(0 == _wcsicmp(g_bstrClassMergeablePolicy, (pAttrTypeInfo->pADsValues + pAttrTypeInfo->dwNumValues - 1)->CaseIgnoreString))
  525. ulIsSimple = 1;
  526. }
  527. // **** create empty class policy
  528. if(ulIsSimple)
  529. hres = pDestCIM->GetObject(g_bstrClassSimplePolicy, 0, pCtx, &pClassDef, NULL);
  530. else
  531. hres = pDestCIM->GetObject(g_bstrClassMergeablePolicy, 0, pCtx, &pClassDef, NULL);
  532. if(FAILED(hres)) return hres;
  533. if(pClassDef == NULL) return WBEM_E_FAILED;
  534. hres = pClassDef->SpawnInstance(0, ppDestPolicyObj);
  535. if(FAILED(hres)) return hres;
  536. pDestPolicyObj = *ppDestPolicyObj;
  537. if(pDestPolicyObj == NULL) return WBEM_E_INVALID_CLASS;
  538. // **** get object attributes
  539. hres = pSrcPolicyObj->GetObjectAttributes(AttrNames, (ulIsLegacy ? 12 : 13), &pAttrInfo, &dwReturn);
  540. if(FAILED(hres)) return hres;
  541. if(pAttrInfo == NULL) return WBEM_E_NOT_FOUND;
  542. // **** Domain
  543. hres = pSrcPolicyObj->GetObjectInformation(&pInfo);
  544. if(SUCCEEDED(hres) && (pInfo != NULL))
  545. {
  546. QString
  547. DomainName;
  548. hres = DomainNameFromDistName(DomainName, QString(pInfo->pszObjectDN));
  549. v1 = (wchar_t*)DomainName;
  550. hres = pDestPolicyObj->Put(g_bstrDomain, 0, &v1, 0);
  551. }
  552. if(pInfo == NULL) return WBEM_E_FAILED;
  553. if(FAILED(hres)) return hres;
  554. for(c1 = 0; c1 < dwReturn; c1++)
  555. {
  556. // **** ID
  557. if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADID))
  558. {
  559. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  560. hres = pDestPolicyObj->Put(g_bstrID, 0, &v1, 0);
  561. }
  562. // **** Description
  563. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADDescription))
  564. {
  565. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  566. hres = pDestPolicyObj->Put(g_bstrDescription, 0, &v1, 0);
  567. }
  568. // **** TargetType
  569. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADTargetType))
  570. {
  571. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  572. hres = pDestPolicyObj->Put(g_bstrTargetType, 0, &v1, 0);
  573. }
  574. // **** Name
  575. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADName))
  576. {
  577. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  578. hres = pDestPolicyObj->Put(g_bstrName, 0, &v1, 0);
  579. }
  580. // **** TargetNameSpace
  581. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADTargetNameSpace))
  582. {
  583. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  584. hres = pDestPolicyObj->Put(g_bstrTargetNameSpace, 0, &v1, 0);
  585. }
  586. // **** TargetClass
  587. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADTargetClass))
  588. {
  589. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  590. hres = pDestPolicyObj->Put(g_bstrTargetClass, 0, &v1, 0);
  591. }
  592. // **** TargetPath
  593. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADTargetPath))
  594. {
  595. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  596. hres = pDestPolicyObj->Put(g_bstrTargetPath, 0, &v1, 0);
  597. }
  598. // **** SourceOrganization
  599. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADSourceOrganization))
  600. {
  601. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  602. hres = pDestPolicyObj->Put(g_bstrSourceOrganization, 0, &v1, 0);
  603. }
  604. // **** Author
  605. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADAuthor))
  606. {
  607. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  608. hres = pDestPolicyObj->Put(g_bstrAuthor, 0, &v1, 0);
  609. }
  610. // **** ChangeDate
  611. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADChangeDate))
  612. {
  613. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  614. hres = pDestPolicyObj->Put(g_bstrChangeDate, 0, &v1, 0);
  615. // dates are easy to mess up, we won't bail out for it
  616. if (hres == WBEM_E_TYPE_MISMATCH)
  617. {
  618. ERRORTRACE((LOG_ESS, "POLICMAN: Type mismatch on date property\n"));
  619. hres = WBEM_S_NO_ERROR;
  620. }
  621. }
  622. // **** CreationDate
  623. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADCreationDate))
  624. {
  625. v1 = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  626. hres = pDestPolicyObj->Put(g_bstrCreationDate, 0, &v1, 0);
  627. // dates are easy to mess up, we won't bail out for it
  628. if (hres == WBEM_E_TYPE_MISMATCH)
  629. {
  630. ERRORTRACE((LOG_ESS, "POLICMAN: Type mismatch on date property\n"));
  631. hres = WBEM_S_NO_ERROR;
  632. }
  633. }
  634. // **** TargetObject
  635. else if(0 == _wcsicmp((pAttrInfo + c1)->pszAttrName, g_bstrADTargetObject))
  636. {
  637. ADSVALUE
  638. *pADsObj = (pAttrInfo + c1)->pADsValues;
  639. offset.LowPart = 0;
  640. offset.HighPart = 0;
  641. if(NULL == pADsObj) continue;
  642. hres = ClassDefBuffer.Seek(offset, STREAM_SEEK_SET, NULL);
  643. if(SUCCEEDED(hres))
  644. {
  645. hres = ClassDefBuffer.Write(pADsObj->OctetString.lpValue, pADsObj->OctetString.dwLength, &bWritten);
  646. if(SUCCEEDED(hres))
  647. {
  648. hres = ClassDefBuffer.Seek(offset, STREAM_SEEK_SET, NULL);
  649. if(SUCCEEDED(hres))
  650. {
  651. if(ulIsSimple)
  652. {
  653. hres = CoUnmarshalInterface(&ClassDefBuffer, IID_IWbemClassObject, (void**)&pDestParamObj);
  654. if(SUCCEEDED(hres))
  655. {
  656. v1 = pDestParamObj;
  657. hres = pDestPolicyObj->Put(g_bstrTargetObject, 0, &v1, 0);
  658. }
  659. }
  660. else if(! ulIsLegacy)
  661. {
  662. SafeArray<IUnknown*, VT_UNKNOWN>
  663. Array1;
  664. IUnknown
  665. *pUnknown = NULL;
  666. wchar_t
  667. swArraySize[20];
  668. ClassDefBuffer.Read(swArraySize, sizeof(wchar_t) * 20, NULL);
  669. int nElts = _wtoi(swArraySize);
  670. while(nElts-- && SUCCEEDED(hres = CoUnmarshalInterface(&ClassDefBuffer, IID_IUnknown, (void**)&pUnknown)))
  671. {
  672. Array1.ReDim(0, Array1.Size() + 1);
  673. Array1[Array1.IndexMax()] = pUnknown;
  674. pUnknown = NULL;
  675. }
  676. if(0 < Array1.Size())
  677. {
  678. V_VT(&v1) = (VT_UNKNOWN | VT_ARRAY);
  679. V_ARRAY(&v1) = Array1.Data();
  680. hres = pDestPolicyObj->Put(g_bstrRangeSettings, 0, &v1, 0);
  681. }
  682. }
  683. }
  684. }
  685. }
  686. }
  687. if(FAILED(hres)) return hres;
  688. VariantClear(&v1);
  689. }
  690. if(ulIsLegacy)
  691. {
  692. CComQIPtr<IDirectorySearch, &IID_IDirectorySearch>
  693. pDirSrch;
  694. ADS_SEARCH_HANDLE
  695. SearchHandle;
  696. ADS_SEARCH_COLUMN
  697. SearchColumn;
  698. // **** now, get RangeSettings that are the children of this policy object in AD
  699. pDirSrch = pSrcPolicyObj;
  700. hres = pDirSrch->ExecuteSearch(L"(cn=*)", NULL, -1, &SearchHandle);
  701. if(FAILED(hres)) return hres;
  702. while(S_OK == (hres = pDirSrch->GetNextRow(SearchHandle)))
  703. {
  704. hres = pDirSrch->GetColumn(SearchHandle, g_bstrADObjectClass, &SearchColumn);
  705. if(FAILED(hres)) return hres;
  706. int x = SearchColumn.dwNumValues - 1;
  707. if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassRangeSint32))
  708. hres = Range_Sint32_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  709. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassRangeUint32))
  710. hres = Range_Uint32_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  711. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassRangeReal))
  712. hres = Range_Real_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  713. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassSetSint32))
  714. hres = Set_Sint32_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  715. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassSetUint32))
  716. hres = Set_Uint32_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  717. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassSetString))
  718. hres = Set_String_ADToCIM(&pDestParamObj, pDirSrch, SearchHandle, pDestCIM);
  719. else if(0 == _wcsicmp((SearchColumn.pADsValues + x)->CaseIgnoreString, g_bstrADClassParamUnknown))
  720. hres = Param_Unknown_ADToCIM(&pDestParamObj, pDirSrch, &SearchHandle, pDestCIM);
  721. // **** place pDestParamObj in pDestPolicyObj
  722. if(SUCCEEDED(hres) && (pDestParamObj != NULL))
  723. {
  724. hres = pDestPolicyObj->Get(g_bstrRangeSettings, 0, &v1, NULL, NULL);
  725. if(FAILED(hres)) return hres;
  726. SafeArray<IUnknown*, VT_UNKNOWN>
  727. ValidValues(&v1);
  728. hres = pDestParamObj.QueryInterface(&pUnknown);
  729. if(FAILED(hres)) return hres;
  730. pDestParamObj = NULL;
  731. ValidValues.ReDim(0, ValidValues.Size() + 1);
  732. ValidValues[ValidValues.IndexMax()] = pUnknown.Detach();
  733. VariantClear(&v1);
  734. V_VT(&v1) = (VT_ARRAY | ValidValues.Type());
  735. V_ARRAY(&v1) = ValidValues.Data();
  736. hres = pDestPolicyObj->Put(g_bstrRangeSettings, 0, &v1, 0);
  737. if(FAILED(hres)) return hres;
  738. VariantClear(&v1);
  739. }
  740. pDirSrch->FreeColumn(&SearchColumn);
  741. }
  742. pDirSrch->CloseSearchHandle(SearchHandle);
  743. }
  744. return WBEM_S_NO_ERROR;
  745. }
  746. inline int _NextIndex(long &cIndex, SafeArray<long, VT_I4> &ValidObjs)
  747. {
  748. if((cIndex < -1) || (cIndex >= ValidObjs.Size()))
  749. return 0;
  750. while((++cIndex < ValidObjs.Size()) && (ValidObjs[cIndex] == FALSE));
  751. if(cIndex >= ValidObjs.Size())
  752. return 0;
  753. return 1;
  754. }
  755. HRESULT Policy_Merge(SafeArray<IUnknown*, VT_UNKNOWN> &PolicyArray,
  756. CComPtr<IWbemClassObject> &pMergedPolicy,
  757. IWbemServices *pDestCIM)
  758. {
  759. HRESULT
  760. hres = WBEM_E_FAILED;
  761. ULONG
  762. nValidObjects = 0;
  763. CComVariant
  764. vFirstPolicyType,
  765. vPolicyAttr;
  766. long
  767. boolFinished = FALSE, boolNotMergeable = FALSE, c1, c2, c3;
  768. CComPtr<IWbemClassObject>
  769. pFirstPolicy,
  770. pClassRangeParam,
  771. pClassInParams,
  772. pInParams;
  773. SafeArray<BSTR, VT_BSTR>
  774. RangeNames;
  775. if(PolicyArray.Size() < 1)
  776. return NULL;
  777. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): # of objects to merge: %d\n", PolicyArray.Size()));
  778. // **** get input parameter for MSFT_RangeParam.Merge()
  779. hres = pDestCIM->GetObject(g_bstrClassRangeParam, 0, NULL, &pClassRangeParam, NULL);
  780. if(FAILED(hres)) return hres;
  781. hres = pClassRangeParam->GetMethod(L"Merge", 0, &pClassInParams, NULL);
  782. if(FAILED(hres)) return hres;
  783. hres = pClassInParams->SpawnInstance(0, &pInParams);
  784. if(FAILED(hres)) return hres;
  785. // **** check to see if 1st obj is Simple Policy Template
  786. if((0 == PolicyArray.Size()) || (NULL == PolicyArray[0])) return WBEM_E_INVALID_PARAMETER;
  787. hres = PolicyArray[0]->QueryInterface(IID_IWbemClassObject, (void **)&pFirstPolicy);
  788. if(FAILED(hres)) return WBEM_E_FAILED;
  789. if(pFirstPolicy->InheritsFrom(L"MSFT_PolicyTemplate") != WBEM_S_NO_ERROR)
  790. return WBEM_E_INVALID_PARAMETER;
  791. // **** create array of Policy objects to be merged
  792. SafeArray<long, VT_I4>
  793. ValidPolicyObjects(0, PolicyArray.Size());
  794. hres = pFirstPolicy->Get(L"__CLASS", 0, &vFirstPolicyType, NULL, NULL);
  795. if(FAILED(hres)) return WBEM_E_FAILED;
  796. if((_wcsicmp(g_bstrClassMergeablePolicy, vFirstPolicyType.bstrVal) == 0) ||
  797. (pFirstPolicy->InheritsFrom(g_bstrClassMergeablePolicy) == WBEM_S_NO_ERROR))
  798. {
  799. for(c1 = 0; c1 < PolicyArray.Size(); c1++)
  800. {
  801. if(NULL != PolicyArray[c1])
  802. {
  803. CComVariant
  804. vPolicyType,
  805. vPolicyGenus;
  806. CComPtr<IWbemClassObject>
  807. pCurrentPolicy;
  808. hres = PolicyArray[c1]->QueryInterface(IID_IWbemClassObject, (void**)&pCurrentPolicy);
  809. if(FAILED(hres)) return WBEM_E_FAILED;
  810. hres = pCurrentPolicy->Get(L"__CLASS", 0, &vPolicyType, NULL, NULL);
  811. if(FAILED(hres)) return WBEM_E_FAILED;
  812. hres = pCurrentPolicy->Get(L"__GENUS", 0, &vPolicyGenus, NULL, NULL);
  813. if(FAILED(hres)) return WBEM_E_FAILED;
  814. if(0x2 != vPolicyGenus.lVal)
  815. {
  816. ERRORTRACE((LOG_ESS, "POLICMAN: Policy Object %d is not an instance\n", c1));
  817. return WBEM_E_INVALID_PARAMETER;
  818. }
  819. if((_wcsicmp(g_bstrClassMergeablePolicy, vPolicyType.bstrVal) == 0) ||
  820. (pCurrentPolicy->InheritsFrom(g_bstrClassMergeablePolicy) == WBEM_S_NO_ERROR))
  821. {
  822. ValidPolicyObjects[c1] = TRUE;
  823. nValidObjects++;
  824. }
  825. else
  826. ValidPolicyObjects[c1] = FALSE;
  827. }
  828. else
  829. ValidPolicyObjects[c1] = FALSE;
  830. }
  831. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): %d out of %d template objects are of type MSFT_MergeablePolicyTemplate\n", nValidObjects, PolicyArray.Size()));
  832. }
  833. else
  834. {
  835. boolFinished = TRUE;
  836. boolNotMergeable = TRUE;
  837. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): 1st object is not mergeable policy template object\n"));
  838. }
  839. // **** create empty array for merged range parameters, one element per parameter name
  840. SafeArray<IUnknown*, VT_UNKNOWN>
  841. MergedParameters;
  842. // **** build list of merged range params and place them in MergedParameters
  843. while((FALSE == boolFinished) && (0 < nValidObjects))
  844. {
  845. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): ---- Start Merge Cycle ----\n"));
  846. // **** get list of attribute names from all policy objects
  847. c1 = -1;
  848. while(_NextIndex(c1, ValidPolicyObjects))
  849. {
  850. CComQIPtr<IWbemClassObject, &IID_IWbemClassObject>
  851. pCurrentPolicy;
  852. CComVariant
  853. vRangeSettings;
  854. pCurrentPolicy = PolicyArray[c1];
  855. hres = pCurrentPolicy->Get(g_bstrRangeSettings, 0, &vRangeSettings, NULL, NULL);
  856. if(FAILED(hres)) return hres;
  857. SafeArray<IUnknown*, VT_UNKNOWN>
  858. RangeSettings(&vRangeSettings);
  859. for(c2 = 0; c2 < RangeSettings.Size(); c2++)
  860. {
  861. CComQIPtr<IWbemClassObject, &IID_IWbemClassObject>
  862. pCurrentRange;
  863. CComVariant
  864. vRangeName;
  865. pCurrentRange = RangeSettings[c2];
  866. hres = pCurrentRange->Get(g_bstrPropertyName, 0, &vRangeName, NULL, NULL);
  867. if(FAILED(hres)) return hres;
  868. c3 = -1;
  869. while((++c3 < RangeNames.Size()) && (0 != _wcsicmp(V_BSTR(&vRangeName), RangeNames[c3])));
  870. if(c3 > RangeNames.IndexMax())
  871. {
  872. RangeNames.ReDim(0, RangeNames.Size() + 1);
  873. RangeNames[RangeNames.IndexMax()] = SysAllocString(V_BSTR(&vRangeName));
  874. }
  875. }
  876. }
  877. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): Merging %d parameters accross %d template objects\n", RangeNames.Size(), nValidObjects));
  878. // **** create and init array for matching parameters from each policy
  879. SafeArray<IUnknown*, VT_UNKNOWN>
  880. ParameterObjects(0, PolicyArray.Size());
  881. // **** resize MergedParameters to contain a slot for each parameter name
  882. MergedParameters.ReDim(0, RangeNames.Size());
  883. // **** assemble a list and merge for each parameter in RangeNames
  884. for(c1 = 0; c1 < RangeNames.Size(); c1++)
  885. {
  886. CComPtr<IWbemClassObject>
  887. pOutParams;
  888. CComVariant
  889. vRangeParamType,
  890. vRangeParamType2,
  891. vConflict = -1,
  892. vRanges,
  893. vReturnValue,
  894. vMergedParameter;
  895. // **** build list of parameters from policy objects with name RangeNames[c1]
  896. c2 = -1;
  897. while((_NextIndex(c2, ValidPolicyObjects)) && (-1 == vConflict.lVal))
  898. {
  899. CComQIPtr<IWbemClassObject, &IID_IWbemClassObject>
  900. pCurrentPolicyObject = PolicyArray[c2];
  901. CComVariant
  902. vCurrentParams;
  903. // **** walk through parameter settings for c2th policy object looking for a match
  904. hres = pCurrentPolicyObject->Get(g_bstrRangeSettings, 0, &vCurrentParams, NULL, NULL);
  905. if(FAILED(hres)) return hres;
  906. SafeArray<IUnknown*, VT_UNKNOWN>
  907. CurrentParams(&vCurrentParams);
  908. c3 = 0;
  909. ParameterObjects[c2] = NULL;
  910. while((c3 < CurrentParams.Size()) && (NULL == ParameterObjects[c2]))
  911. {
  912. CComQIPtr<IWbemClassObject, &IID_IWbemClassObject>
  913. pCurrentParameterObject = CurrentParams[c3];
  914. CComVariant
  915. vName;
  916. hres = pCurrentParameterObject->Get(g_bstrPropertyName, 0, &vName, NULL, NULL);
  917. if(FAILED(hres)) return hres;
  918. if(0 == _wcsicmp(V_BSTR(&vName), RangeNames[c1]))
  919. {
  920. ParameterObjects[c2] = CurrentParams[c3];
  921. ParameterObjects[c2]->AddRef();
  922. // **** check that all subsequent parameter objects are of the same type
  923. if(VT_BSTR != vRangeParamType.vt)
  924. {
  925. hres = pCurrentParameterObject->Get(L"__CLASS", 0, &vRangeParamType, NULL, NULL);
  926. if(FAILED(hres)) return hres;
  927. }
  928. else
  929. {
  930. hres = pCurrentParameterObject->Get(L"__CLASS", 0, &vRangeParamType2, NULL, NULL);
  931. if(FAILED(hres)) return hres;
  932. if((0 != _wcsicmp(V_BSTR(&vRangeParamType), V_BSTR(&vRangeParamType2))) ||
  933. (WBEM_S_NO_ERROR != pCurrentParameterObject->InheritsFrom(vRangeParamType.bstrVal)))
  934. {
  935. ERRORTRACE((LOG_ESS, "POLICMAN: Type Mismatch on element %d of type %S and type %S\n", c3, V_BSTR(&vRangeParamType), V_BSTR(&vRangeParamType2)));
  936. vConflict = c2;
  937. vReturnValue = WBEM_E_TYPE_MISMATCH;
  938. break;
  939. }
  940. }
  941. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): Got Parameter %S in template object %d\n", V_BSTR(&vName), c2));
  942. }
  943. c3 += 1;
  944. }
  945. }
  946. // **** now build merged parameter from list
  947. if(-1 == vConflict.lVal)
  948. {
  949. V_VT(&vRanges) = (VT_UNKNOWN | VT_ARRAY);
  950. V_ARRAY(&vRanges) = ParameterObjects.Data();
  951. hres = pInParams->Put(L"ranges", 0, &vRanges, 0);
  952. if(FAILED(hres)) return hres;
  953. hres = pDestCIM->ExecMethod(V_BSTR(&vRangeParamType), L"Merge", 0, NULL, pInParams, &pOutParams, NULL);
  954. if(FAILED(hres)) return hres;
  955. hres = pOutParams->Get(L"mergedRange", 0, &vMergedParameter, NULL, NULL);
  956. if(FAILED(hres)) return hres;
  957. hres = pOutParams->Get(L"conflict", 0, &vConflict, NULL, NULL);
  958. if(FAILED(hres)) return hres;
  959. hres = pOutParams->Get(L"ReturnValue", 0, &vReturnValue, NULL, NULL);
  960. if(FAILED(hres)) return hres;
  961. }
  962. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): Merge Complete : HRESULT = 0x%d\n", vReturnValue.lVal));
  963. // **** clean out parameter object array
  964. for(c2 = 0; c2 < ParameterObjects.Size(); c2++)
  965. if(NULL != ParameterObjects[c2])
  966. {
  967. ParameterObjects[c2]->Release();
  968. ParameterObjects[c2] = NULL;
  969. }
  970. // **** check for conflict
  971. if((vConflict.lVal >= 0) && (vConflict.lVal < ValidPolicyObjects.Size()))
  972. {
  973. DEBUGTRACE((LOG_ESS, " CONFLICT on obj %d\n", vConflict.lVal));
  974. // **** remove policy object containing offending parameter and start over
  975. RangeNames.ReDim(0,0);
  976. MergedParameters.ReDim(0,0);
  977. ValidPolicyObjects[vConflict.lVal] = FALSE;
  978. nValidObjects--;
  979. boolFinished = FALSE;
  980. // **** log merge conflict
  981. ERRORTRACE((LOG_ESS, "POLICMAN: Policy Object %d create merge conflict\n", vConflict.lVal));
  982. break;
  983. }
  984. else
  985. {
  986. DEBUGTRACE((LOG_ESS, " no conflict\n"));
  987. hres = (V_UNKNOWN(&vMergedParameter))->QueryInterface(IID_IWbemClassObject, (void **)&(MergedParameters[c1]));
  988. if(FAILED(hres)) return hres;
  989. boolFinished = TRUE;
  990. }
  991. }
  992. }
  993. if(FALSE == boolNotMergeable)
  994. {
  995. CComPtr<IWbemClassObject>
  996. pClassPolicy;
  997. // **** create new merged policy object
  998. hres = pDestCIM->GetObject(g_bstrClassMergeablePolicy, 0, NULL, &pClassPolicy, NULL);
  999. if(FAILED(hres)) return hres;
  1000. hres = pClassPolicy->SpawnInstance(0, &pMergedPolicy);
  1001. if(FAILED(hres)) return hres;
  1002. // **** Pack TargetType
  1003. hres = pFirstPolicy->Get(g_bstrTargetType, 0, &vPolicyAttr, NULL, NULL);
  1004. if(FAILED(hres)) return hres;
  1005. hres = pMergedPolicy->Put(g_bstrTargetType, 0, &vPolicyAttr, 0);
  1006. if(FAILED(hres)) return hres;
  1007. VariantClear(&vPolicyAttr);
  1008. // **** Pack TargetClass
  1009. hres = pFirstPolicy->Get(g_bstrTargetClass, 0, &vPolicyAttr, NULL, NULL);
  1010. if(FAILED(hres)) return hres;
  1011. hres = pMergedPolicy->Put(g_bstrTargetClass, 0, &vPolicyAttr, 0);
  1012. if(FAILED(hres)) return hres;
  1013. VariantClear(&vPolicyAttr);
  1014. // **** Pack TargetPath
  1015. hres = pFirstPolicy->Get(g_bstrTargetPath, 0, &vPolicyAttr, NULL, NULL);
  1016. if(FAILED(hres)) return hres;
  1017. hres = pMergedPolicy->Put(g_bstrTargetPath, 0, &vPolicyAttr, 0);
  1018. if(FAILED(hres)) return hres;
  1019. VariantClear(&vPolicyAttr);
  1020. // **** Pack TargetNamespace
  1021. hres = pFirstPolicy->Get(g_bstrTargetNameSpace, 0, &vPolicyAttr, NULL, NULL);
  1022. if(FAILED(hres)) return hres;
  1023. hres = pMergedPolicy->Put(g_bstrTargetNameSpace, 0, &vPolicyAttr, 0);
  1024. if(FAILED(hres)) return hres;
  1025. VariantClear(&vPolicyAttr);
  1026. // **** pack RangeSettings
  1027. V_VT(&vPolicyAttr) = (VT_ARRAY | VT_UNKNOWN);
  1028. V_ARRAY(&vPolicyAttr) = MergedParameters.Data();
  1029. hres = pMergedPolicy->Put(g_bstrRangeSettings, 0, &vPolicyAttr, 0);
  1030. if(FAILED(hres)) return hres;
  1031. VariantClear(&vPolicyAttr);
  1032. // **** clean out merged parameter object array
  1033. for(c1 = 0; c1 < MergedParameters.Size(); c1++)
  1034. if(NULL != MergedParameters[c1])
  1035. {
  1036. MergedParameters[c1]->Release();
  1037. MergedParameters[c1] = NULL;
  1038. }
  1039. }
  1040. else
  1041. pMergedPolicy = pFirstPolicy;
  1042. {
  1043. CComBSTR
  1044. pBstr;
  1045. hres = pMergedPolicy->GetObjectText(0, &pBstr);
  1046. DEBUGTRACE((LOG_ESS, "POLICMAN(merge): Merged Policy: %S\n", (BSTR)pBstr));
  1047. }
  1048. return WBEM_S_NO_ERROR;
  1049. }