Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

880 lines
23 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <wbemcomn.h>
  4. #include <wbemtime.h>
  5. #include <activeds.h>
  6. #include <ArrTempl.h>
  7. #include <comutil.h>
  8. #undef _ASSERT
  9. #include <atlbase.h>
  10. #include <activeds.h>
  11. #include <string.h>
  12. #include "Utility.h"
  13. /*********************************************************************
  14. ************** Active Directory Methods ******************************
  15. *********************************************************************/
  16. #define MAX_ATTR_SOM 20
  17. #define MAX_ATTR_RULE 5
  18. #define DELIMITER (wchar_t)(L';')
  19. #define DELIMITER_STR (wchar_t*)(L";")
  20. HRESULT Som_CIMToAD(IWbemClassObject *pSrcPolicyObj, IDirectoryObject *pDestContainer, long lFlags)
  21. {
  22. HRESULT
  23. hres = WBEM_S_NO_ERROR;
  24. CComVariant
  25. v[MAX_ATTR_SOM];
  26. long
  27. nArgs_SOM = 0,
  28. c1;
  29. CComPtr<IDispatch>
  30. pDisp;
  31. CComPtr<IDirectoryObject>
  32. pDestSomObj;
  33. ADsObjAutoDelete
  34. AutoDelete;
  35. CComQIPtr<IADsContainer>
  36. pADsContainer = pDestContainer;
  37. SafeArray<IUnknown*, VT_UNKNOWN>
  38. Array1;
  39. ADSVALUE
  40. AdsValue[MAX_ATTR_SOM];
  41. ADS_ATTR_INFO
  42. attrInfo[MAX_ATTR_SOM];
  43. WBEMTime
  44. wtCurrentTime;
  45. SYSTEMTIME
  46. SystemTime;
  47. CComBSTR
  48. bstrID,
  49. bstrCurrentTimeDTMF,
  50. RulesBuffer,
  51. NULL_STRING(L"\0"),
  52. SomName(L"CN=");
  53. // **** get current time
  54. GetSystemTime(&SystemTime);
  55. wtCurrentTime = SystemTime;
  56. bstrCurrentTimeDTMF.Attach(wtCurrentTime.GetDMTF(FALSE));
  57. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  58. g_bstrADObjectClass,
  59. ADS_ATTR_UPDATE,
  60. ADSTYPE_CASE_IGNORE_STRING,
  61. &AdsValue[nArgs_SOM],
  62. 1);
  63. AdsValue[nArgs_SOM].CaseIgnoreString = g_bstrADClassSom;
  64. nArgs_SOM++;
  65. // **** ID
  66. hres = pSrcPolicyObj->Get(g_bstrID, 0, &v[nArgs_SOM], NULL, NULL);
  67. if(FAILED(hres)) return hres;
  68. if ((v[nArgs_SOM].vt == VT_BSTR) && (v[nArgs_SOM].bstrVal != NULL))
  69. {
  70. bstrID.AppendBSTR(v[nArgs_SOM].bstrVal);
  71. VariantClear(&v[nArgs_SOM]);
  72. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  73. g_bstrADID,
  74. ADS_ATTR_UPDATE,
  75. ADSTYPE_CASE_IGNORE_STRING,
  76. &AdsValue[nArgs_SOM],
  77. 1);
  78. AdsValue[nArgs_SOM].CaseIgnoreString = bstrID;
  79. nArgs_SOM++;
  80. }
  81. else
  82. return WBEM_E_ILLEGAL_NULL;
  83. SomName.AppendBSTR(bstrID);
  84. // **** security descriptor
  85. CNtSecurityDescriptor cSD;
  86. // flag to indicate whether we're updating an existing object as opposed to creating a new one.
  87. bool bEditExisting;
  88. pDisp.Release();
  89. if(SUCCEEDED(hres = pADsContainer->GetObject(g_bstrADClassSom, SomName, &pDisp)))
  90. {
  91. bEditExisting = true;
  92. if(lFlags & WBEM_FLAG_CREATE_ONLY) return WBEM_E_ALREADY_EXISTS;
  93. // HACK HACK HACK!
  94. // okay, at this point we know that we're editing an existing object.
  95. // therefor, we do *not* want to set the id or type
  96. // back up the array pointer - all the ATL classes should clean up after themselves with no problem.
  97. nArgs_SOM = 0;
  98. // we'll simply leave the existing security descriptor in place
  99. /*************************************************
  100. CComQIPtr<IDirectoryObject, &IID_IDirectoryObject>
  101. pDirObj = pDisp;
  102. PADS_ATTR_INFO pAttrInfo = NULL;
  103. LPWSTR pAttrName = L"ntSecurityDescriptor";
  104. DWORD dwReturn;
  105. hres = pDirObj->GetObjectAttributes(&pAttrName, 1, &pAttrInfo, &dwReturn);
  106. if((dwReturn != 1) || (pAttrInfo->dwADsType != ADSTYPE_NT_SECURITY_DESCRIPTOR)) return WBEM_E_FAILED;
  107. SecDescValue = pAttrInfo;
  108. if(FAILED(hres)) return hres;
  109. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  110. L"ntSecurityDescriptor",
  111. ADS_ATTR_UPDATE,
  112. ADSTYPE_NT_SECURITY_DESCRIPTOR,
  113. pAttrInfo->pADsValues,
  114. 1);
  115. ***************************************************/
  116. }
  117. else
  118. {
  119. if(WBEM_FLAG_UPDATE_ONLY & lFlags)
  120. return WBEM_E_NOT_FOUND;
  121. bEditExisting = false;
  122. hres = GetOwnerSecurityDescriptor(cSD);
  123. if (FAILED(hres)) return hres;
  124. if(CNtSecurityDescriptor::NoError == cSD.GetStatus())
  125. {
  126. AdsValue[nArgs_SOM].SecurityDescriptor.dwLength = cSD.GetSize();
  127. AdsValue[nArgs_SOM].SecurityDescriptor.lpValue = (LPBYTE) cSD.GetPtr();
  128. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  129. L"ntSecurityDescriptor",
  130. ADS_ATTR_UPDATE,
  131. ADSTYPE_NT_SECURITY_DESCRIPTOR,
  132. &AdsValue[nArgs_SOM],
  133. 1);
  134. }
  135. else
  136. return WBEM_E_FAILED;
  137. nArgs_SOM++;
  138. }
  139. pDisp.Release();
  140. // **** Name
  141. hres = pSrcPolicyObj->Get(g_bstrName, 0, &v[nArgs_SOM], NULL, NULL);
  142. if(FAILED(hres)) return hres;
  143. if ((v[nArgs_SOM].vt == VT_BSTR) && (v[nArgs_SOM].bstrVal != NULL))
  144. {
  145. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  146. g_bstrADName,
  147. ADS_ATTR_UPDATE,
  148. ADSTYPE_CASE_IGNORE_STRING,
  149. &AdsValue[nArgs_SOM],
  150. 1);
  151. AdsValue[nArgs_SOM].CaseIgnoreString = V_BSTR(&v[nArgs_SOM]);
  152. nArgs_SOM++;
  153. }
  154. else
  155. return WBEM_E_ILLEGAL_NULL;
  156. // **** Description
  157. hres = pSrcPolicyObj->Get(g_bstrDescription, 0, &v[nArgs_SOM], NULL, NULL);
  158. if(FAILED(hres)) return hres;
  159. if ((v[nArgs_SOM].vt == VT_BSTR) && (v[nArgs_SOM].bstrVal != NULL))
  160. {
  161. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  162. g_bstrADDescription,
  163. ADS_ATTR_UPDATE,
  164. ADSTYPE_CASE_IGNORE_STRING,
  165. &AdsValue[nArgs_SOM],
  166. 1);
  167. AdsValue[nArgs_SOM].CaseIgnoreString = V_BSTR(&v[nArgs_SOM]);
  168. nArgs_SOM++;
  169. }
  170. else if (bEditExisting)
  171. {
  172. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  173. g_bstrADDescription,
  174. ADS_ATTR_CLEAR,
  175. ADSTYPE_CASE_IGNORE_STRING,
  176. &AdsValue[nArgs_SOM],
  177. 1);
  178. AdsValue[nArgs_SOM].CaseIgnoreString = NULL_STRING;
  179. nArgs_SOM++;
  180. }
  181. // **** SourceOrganization
  182. hres = pSrcPolicyObj->Get(g_bstrSourceOrganization, 0, &v[nArgs_SOM], NULL, NULL);
  183. if(FAILED(hres)) return hres;
  184. if ((v[nArgs_SOM].vt == VT_BSTR) && (v[nArgs_SOM].bstrVal != NULL))
  185. {
  186. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  187. g_bstrADSourceOrganization,
  188. ADS_ATTR_UPDATE,
  189. ADSTYPE_CASE_IGNORE_STRING,
  190. &AdsValue[nArgs_SOM],
  191. 1);
  192. AdsValue[nArgs_SOM].CaseIgnoreString = V_BSTR(&v[nArgs_SOM]);
  193. nArgs_SOM++;
  194. }
  195. else if (bEditExisting)
  196. {
  197. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  198. g_bstrADSourceOrganization,
  199. ADS_ATTR_CLEAR,
  200. ADSTYPE_CASE_IGNORE_STRING,
  201. &AdsValue[nArgs_SOM],
  202. 1);
  203. AdsValue[nArgs_SOM].CaseIgnoreString = NULL_STRING;
  204. nArgs_SOM++;
  205. }
  206. // **** Author
  207. hres = pSrcPolicyObj->Get(g_bstrAuthor, 0, &v[nArgs_SOM], NULL, NULL);
  208. if(FAILED(hres)) return hres;
  209. if ((v[nArgs_SOM].vt == VT_BSTR) && (v[nArgs_SOM].bstrVal != NULL))
  210. {
  211. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  212. g_bstrADAuthor,
  213. ADS_ATTR_UPDATE,
  214. ADSTYPE_CASE_IGNORE_STRING,
  215. &AdsValue[nArgs_SOM],
  216. 1);
  217. AdsValue[nArgs_SOM].CaseIgnoreString = V_BSTR(&v[nArgs_SOM]);
  218. nArgs_SOM++;
  219. }
  220. else if (bEditExisting)
  221. {
  222. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  223. g_bstrADAuthor,
  224. ADS_ATTR_CLEAR,
  225. ADSTYPE_CASE_IGNORE_STRING,
  226. &AdsValue[nArgs_SOM],
  227. 1);
  228. AdsValue[nArgs_SOM].CaseIgnoreString = NULL_STRING;
  229. nArgs_SOM++;
  230. }
  231. // **** ChangeDate
  232. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  233. g_bstrADChangeDate,
  234. ADS_ATTR_UPDATE,
  235. ADSTYPE_CASE_IGNORE_STRING,
  236. &AdsValue[nArgs_SOM],
  237. 1);
  238. AdsValue[nArgs_SOM].CaseIgnoreString = bstrCurrentTimeDTMF;
  239. nArgs_SOM++;
  240. // **** CreationDate
  241. // **** if object already exists, leave it be
  242. // CComVariant
  243. // vCreationDate;
  244. if (!bEditExisting)
  245. {
  246. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  247. g_bstrADCreationDate,
  248. ADS_ATTR_UPDATE,
  249. ADSTYPE_CASE_IGNORE_STRING,
  250. &AdsValue[nArgs_SOM],
  251. 1);
  252. AdsValue[nArgs_SOM].CaseIgnoreString = bstrCurrentTimeDTMF;
  253. nArgs_SOM++;
  254. }
  255. /***********************************
  256. if(SUCCEEDED(hres = pADsContainer->GetObject(NULL, SomName, &pDisp)))
  257. {
  258. CComQIPtr<IADs, &IID_IADs>
  259. pADsLegacyObj = pDisp;
  260. hres = pADsLegacyObj->Get(g_bstrADCreationDate, &vCreationDate);
  261. if (SUCCEEDED(hres))
  262. creationDate = vCreationDate.bstrVal;
  263. else if (hres == E_ADS_PROPERTY_NOT_FOUND)
  264. // support for legacy objects, might not have creation date filled
  265. creationDate = NULL;
  266. else return hres;
  267. }
  268. else
  269. creationDate = wtCurrentTime.GetDMTF(FALSE);
  270. if (creationDate != NULL)
  271. {
  272. AdsValue[nArgs_SOM].CaseIgnoreString = creationDate;
  273. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  274. g_bstrADCreationDate,
  275. ADS_ATTR_UPDATE,
  276. ADSTYPE_CASE_IGNORE_STRING,
  277. &AdsValue[nArgs_SOM],
  278. 1);
  279. nArgs_SOM++;
  280. }
  281. **********************************/
  282. // **** Rules
  283. hres = pSrcPolicyObj->Get(g_bstrRules, 0, &v[nArgs_SOM], NULL, NULL);
  284. if(FAILED(hres)) return hres;
  285. if(v[nArgs_SOM].vt != (VT_ARRAY | VT_UNKNOWN)) return WBEM_E_TYPE_MISMATCH;
  286. Array1 = &v[nArgs_SOM];
  287. wchar_t
  288. swArraySize[20];
  289. _itow(Array1.Size(), swArraySize, 10);
  290. RulesBuffer.Append((wchar_t*)swArraySize);
  291. RulesBuffer.Append(DELIMITER_STR);
  292. for(c1 = 0; c1 < Array1.Size(); c1++)
  293. {
  294. CComVariant
  295. vLanguage,
  296. vNameSpace,
  297. vQuery;
  298. int
  299. languageLength,
  300. nameSpaceLength,
  301. queryLength;
  302. CComPtr<IWbemClassObject>
  303. pRuleObj;
  304. hres = Array1[c1]->QueryInterface(IID_IWbemClassObject, (void **)&pRuleObj);
  305. if(FAILED(hres)) return hres;
  306. if(pRuleObj == NULL) return WBEM_E_FAILED;
  307. // **** QueryLanguage
  308. hres = pRuleObj->Get(g_bstrQueryLanguage, 0, &vLanguage, NULL, NULL);
  309. if(FAILED(hres)) return hres;
  310. if((vLanguage.vt != VT_BSTR) || (vLanguage.bstrVal == NULL))
  311. return WBEM_E_ILLEGAL_NULL;
  312. languageLength = SysStringLen(vLanguage.bstrVal);
  313. _itow(languageLength, swArraySize, 10);
  314. RulesBuffer.Append((wchar_t*)swArraySize);
  315. RulesBuffer.Append(DELIMITER_STR);
  316. // **** NameSpace
  317. hres = pRuleObj->Get(g_bstrTargetNameSpace, 0, &vNameSpace, NULL, NULL);
  318. if(FAILED(hres)) return hres;
  319. if((vNameSpace.vt != VT_BSTR) || (vNameSpace.bstrVal == NULL))
  320. return WBEM_E_ILLEGAL_NULL;
  321. nameSpaceLength = SysStringLen(vNameSpace.bstrVal);
  322. _itow(nameSpaceLength, swArraySize, 10);
  323. RulesBuffer.Append((wchar_t*)swArraySize);
  324. RulesBuffer.Append(DELIMITER_STR);
  325. // **** Query
  326. hres = pRuleObj->Get(g_bstrQuery, 0, &vQuery, NULL, NULL);
  327. if(FAILED(hres)) return hres;
  328. if((vQuery.vt != VT_BSTR) || (vQuery.bstrVal == NULL))
  329. return WBEM_E_ILLEGAL_NULL;
  330. queryLength = SysStringLen(vQuery.bstrVal);
  331. _itow(queryLength, swArraySize, 10);
  332. RulesBuffer.Append((wchar_t*)swArraySize);
  333. RulesBuffer.Append(DELIMITER_STR);
  334. // **** write the contents of the current rule
  335. RulesBuffer.AppendBSTR(vLanguage.bstrVal);
  336. RulesBuffer.Append(DELIMITER_STR);
  337. RulesBuffer.AppendBSTR(vNameSpace.bstrVal);
  338. RulesBuffer.Append(DELIMITER_STR);
  339. RulesBuffer.AppendBSTR(vQuery.bstrVal);
  340. RulesBuffer.Append(DELIMITER_STR);
  341. }
  342. Init_AdsAttrInfo(&attrInfo[nArgs_SOM],
  343. g_bstrADParam2,
  344. ADS_ATTR_UPDATE,
  345. ADSTYPE_CASE_IGNORE_STRING,
  346. &AdsValue[nArgs_SOM],
  347. 1);
  348. AdsValue[nArgs_SOM].CaseIgnoreString = (BSTR)RulesBuffer;
  349. nArgs_SOM++;
  350. // **** create AD SOM object
  351. pDisp.Release();
  352. if (bEditExisting && SUCCEEDED(hres = pADsContainer->GetObject(g_bstrADClassSom, SomName, &pDisp)))
  353. {
  354. if(!pDisp) return WBEM_E_FAILED;
  355. CComQIPtr<IDirectoryObject>
  356. pDirObj = pDisp;
  357. DWORD dwAttrsModified;
  358. hres = pDirObj->SetObjectAttributes(attrInfo, nArgs_SOM, &dwAttrsModified);
  359. if(FAILED(hres))
  360. {
  361. ERRORTRACE((LOG_ESS, "POLICMAN: SetObjectAttributes failed: 0x%08X\n", hres));
  362. return hres;
  363. }
  364. }
  365. else
  366. {
  367. pDisp.Release(); hres = pDestContainer->CreateDSObject(SomName, attrInfo, nArgs_SOM, &pDisp);
  368. if(FAILED(hres) || (!pDisp))
  369. {
  370. ERRORTRACE((LOG_ESS, "POLICMAN: CreateDSObject failed: 0x%08X\n", hres));
  371. return hres;
  372. }
  373. }
  374. return WBEM_S_NO_ERROR;
  375. }
  376. struct ReleaseSearchHandle
  377. {
  378. ADS_SEARCH_HANDLE
  379. pHandle;
  380. CComPtr<IDirectorySearch>
  381. pDirSrch;
  382. ReleaseSearchHandle(ADS_SEARCH_HANDLE pIHandle, CComPtr<IDirectorySearch> &pIDirSrch)
  383. { pDirSrch = pIDirSrch; pHandle = pIHandle; }
  384. ~ReleaseSearchHandle(void)
  385. {if(pHandle) pDirSrch->CloseSearchHandle(pHandle); }
  386. };
  387. HRESULT Som_ADToCIM(IWbemClassObject **ppDestSomObj,
  388. IDirectoryObject *pSrcSomObj,
  389. IWbemServices *pDestCIM)
  390. {
  391. HRESULT
  392. hres = WBEM_S_NO_ERROR;
  393. CComVariant
  394. v1;
  395. wchar_t
  396. *AttrNames[] =
  397. {
  398. g_bstrADID,
  399. g_bstrADName,
  400. g_bstrADDescription,
  401. g_bstrADSourceOrganization,
  402. g_bstrADAuthor,
  403. g_bstrADChangeDate,
  404. g_bstrADCreationDate
  405. },
  406. *AttrNames2[] =
  407. {
  408. g_bstrADParam2
  409. };
  410. ADsStruct<ADS_ATTR_INFO>
  411. pAttrInfo,
  412. pAttrInfo2;
  413. unsigned long
  414. c1, c2, dwReturn, dwReturn2;
  415. CComQIPtr<IWbemClassObject>
  416. pClassDef,
  417. pClassDef_RULE,
  418. pDestSomObj;
  419. IWbemContext
  420. *pCtx = 0;
  421. // **** create empty som object
  422. hres = pDestCIM->GetObject(g_bstrClassSom, 0, pCtx, &pClassDef, NULL);
  423. if(FAILED(hres)) return hres;
  424. if(!pClassDef) return WBEM_E_FAILED;
  425. hres = pClassDef->SpawnInstance(0, ppDestSomObj);
  426. if(FAILED(hres)) return hres;
  427. pDestSomObj = *ppDestSomObj;
  428. if(!pDestSomObj) return WBEM_E_NOT_FOUND;
  429. // **** get object attributes
  430. hres = pSrcSomObj->GetObjectAttributes(AttrNames, 7, &pAttrInfo, &dwReturn);
  431. if(FAILED(hres)) return hres;
  432. if(pAttrInfo == NULL) return WBEM_E_NOT_FOUND;
  433. // **** get Param2 attribute
  434. hres = pSrcSomObj->GetObjectAttributes(AttrNames2, 1, &pAttrInfo2, &dwReturn2);
  435. if(FAILED(hres)) return hres;
  436. for(c1 = 0; c1 < dwReturn; c1++)
  437. {
  438. if((pAttrInfo + c1) == NULL)
  439. return WBEM_E_OUT_OF_MEMORY;
  440. if((pAttrInfo + c1)->dwADsType == ADSTYPE_PROV_SPECIFIC)
  441. return WBEM_E_NOT_AVAILABLE;
  442. BSTR
  443. bstrName = (pAttrInfo + c1)->pszAttrName,
  444. bstrValue = (pAttrInfo + c1)->pADsValues->CaseIgnoreString;
  445. if((NULL == bstrName) || (NULL == bstrValue))
  446. return WBEM_E_OUT_OF_MEMORY;
  447. v1 = bstrValue;
  448. // **** ID
  449. if(0 == _wcsicmp(bstrName, g_bstrADID))
  450. {
  451. hres = pDestSomObj->Put(g_bstrID, 0, &v1, 0);
  452. }
  453. // **** Name
  454. else if(0 == _wcsicmp(bstrName, g_bstrADName))
  455. {
  456. hres = pDestSomObj->Put(g_bstrName, 0, &v1, 0);
  457. }
  458. // **** Description
  459. else if(0 == _wcsicmp(bstrName, g_bstrADDescription))
  460. {
  461. hres = pDestSomObj->Put(g_bstrDescription, 0, &v1, 0);
  462. }
  463. // **** SourceOrganization
  464. else if(0 == _wcsicmp(bstrName, g_bstrADSourceOrganization))
  465. {
  466. hres = pDestSomObj->Put(g_bstrSourceOrganization, 0, &v1, 0);
  467. }
  468. // **** Author
  469. else if(0 == _wcsicmp(bstrName, g_bstrADAuthor))
  470. {
  471. hres = pDestSomObj->Put(g_bstrAuthor, 0, &v1, 0);
  472. }
  473. // **** ChangeDate
  474. else if(0 == _wcsicmp(bstrName, g_bstrADChangeDate))
  475. {
  476. hres = pDestSomObj->Put(g_bstrChangeDate, 0, &v1, 0);
  477. }
  478. // **** CreationDate
  479. else if(0 == _wcsicmp(bstrName, g_bstrADCreationDate))
  480. {
  481. hres = pDestSomObj->Put(g_bstrCreationDate, 0, &v1, 0);
  482. }
  483. if(FAILED(hres)) return hres;
  484. }
  485. // **** cache rule class definition
  486. hres = pDestCIM->GetObject(g_bstrClassRule, 0, pCtx, &pClassDef_RULE, NULL);
  487. if(FAILED(hres)) return hres;
  488. if(!pClassDef_RULE) return WBEM_E_FAILED;
  489. // **** now, get Rule objects that are children of this som object
  490. if(dwReturn2)
  491. {
  492. CComBSTR
  493. RulesBuffer = pAttrInfo2->pADsValues->CaseIgnoreString;
  494. wchar_t
  495. *pBeginChar = RulesBuffer,
  496. *pEndChar = RulesBuffer;
  497. if(NULL == pEndChar) return WBEM_S_NO_ERROR;
  498. // **** get number of rules
  499. pEndChar = wcschr(pEndChar, DELIMITER);
  500. if(NULL == pEndChar) return WBEM_S_NO_ERROR;
  501. *pEndChar = L'\0';
  502. int
  503. cElt = 0,
  504. nElts = _wtoi(pBeginChar);
  505. for(cElt = 0; (pEndChar) && (cElt < nElts); cElt++)
  506. {
  507. CComVariant
  508. vLanguage,
  509. vTargetNameSpace,
  510. vQuery,
  511. vRules1,
  512. vRules2;
  513. int
  514. numScanned,
  515. langLength,
  516. nameSpaceLength,
  517. queryLength;
  518. CComPtr<IWbemClassObject>
  519. pDestRuleObj;
  520. CComPtr<IUnknown>
  521. pUnknown;
  522. // **** get length of fields
  523. pBeginChar = pEndChar + 1;
  524. numScanned = swscanf(pBeginChar, L"%d;%d;%d;", &langLength, &nameSpaceLength, &queryLength);
  525. if(3 != numScanned) break;
  526. pEndChar = wcschr(pEndChar + 1, DELIMITER);
  527. pEndChar = wcschr(pEndChar + 1, DELIMITER);
  528. pEndChar = wcschr(pEndChar + 1, DELIMITER);
  529. // **** create new rule object
  530. hres = pClassDef_RULE->SpawnInstance(0, &pDestRuleObj);
  531. if(FAILED(hres)) return hres;
  532. if(pDestRuleObj == NULL) return WBEM_E_NOT_FOUND;
  533. // **** QueryLanguage
  534. pBeginChar = pEndChar + 1;
  535. pEndChar = pBeginChar + langLength;
  536. if(pEndChar)
  537. {
  538. *pEndChar = L'\0';
  539. vLanguage = pBeginChar;
  540. hres = pDestRuleObj->Put(g_bstrQueryLanguage, 0, &vLanguage, 0);
  541. if(FAILED(hres)) return hres;
  542. }
  543. else break;
  544. // **** NameSpace
  545. pBeginChar = pEndChar + 1;
  546. pEndChar = pBeginChar + nameSpaceLength;
  547. if(pEndChar)
  548. {
  549. *pEndChar = L'\0';
  550. vTargetNameSpace = pBeginChar;
  551. hres = pDestRuleObj->Put(g_bstrTargetNameSpace, 0, &vTargetNameSpace, 0);
  552. if(FAILED(hres)) return hres;
  553. }
  554. else break;
  555. // **** QueryLanguage
  556. pBeginChar = pEndChar + 1;
  557. pEndChar = pBeginChar + queryLength;
  558. if(pEndChar)
  559. {
  560. *pEndChar = L'\0';
  561. vQuery = pBeginChar;
  562. hres = pDestRuleObj->Put(g_bstrQuery, 0, &vQuery, 0);
  563. if(FAILED(hres)) return hres;
  564. }
  565. else break;
  566. // **** stuff new rule object into SOM object
  567. hres = pDestSomObj->Get(g_bstrRules, 0, &vRules1, NULL, NULL);
  568. if(FAILED(hres)) return hres;
  569. SafeArray<IUnknown*, VT_UNKNOWN>
  570. Rules(&vRules1);
  571. hres = pDestRuleObj->QueryInterface(IID_IUnknown, (void**)&pUnknown);
  572. if(FAILED(hres)) return hres;
  573. if(pUnknown == NULL) return WBEM_E_FAILED;
  574. Rules.ReDim(0, Rules.Size() + 1);
  575. Rules[Rules.IndexMax()] = pUnknown;
  576. Rules[Rules.IndexMax()]->AddRef();
  577. // **** place array in dest som object
  578. V_VT(&vRules2) = (VT_ARRAY | Rules.Type());
  579. V_ARRAY(&vRules2) = Rules.Data();
  580. hres = pDestSomObj->Put(g_bstrRules, 0, &vRules2, 0);
  581. if(FAILED(hres)) return hres;
  582. }
  583. }
  584. else
  585. {
  586. ADS_SEARCH_HANDLE
  587. SearchHandle;
  588. ADS_SEARCH_COLUMN
  589. SearchColumn;
  590. CComPtr<IDirectorySearch>
  591. pDirSrch;
  592. hres = pSrcSomObj->QueryInterface(IID_IDirectorySearch, (void **)&pDirSrch);
  593. if(FAILED(hres)) return hres;
  594. CComBSTR
  595. qsQuery(L"(objectClass=");
  596. qsQuery.Append(g_bstrADClassRule);
  597. qsQuery.Append(L")");
  598. hres = pDirSrch->ExecuteSearch(qsQuery, NULL, -1, &SearchHandle);
  599. if(FAILED(hres)) return hres;
  600. ReleaseSearchHandle
  601. HandleReleaseMe(SearchHandle, pDirSrch);
  602. while(S_OK == (hres = pDirSrch->GetNextRow(SearchHandle)))
  603. {
  604. CComVariant
  605. vLanguage,
  606. vNameSpace,
  607. vQuery,
  608. vRules1,
  609. vRules2;
  610. CComPtr<IUnknown>
  611. pUnknown;
  612. CComPtr<IWbemClassObject>
  613. pDestRuleObj;
  614. // **** create empty rule object
  615. hres = pClassDef_RULE->SpawnInstance(0, &pDestRuleObj);
  616. if(FAILED(hres)) return hres;
  617. if(pDestRuleObj == NULL) return WBEM_E_NOT_FOUND;
  618. // **** QueryLanguage
  619. hres = pDirSrch->GetColumn(SearchHandle, g_bstrADQueryLanguage, &SearchColumn);
  620. if((SUCCEEDED(hres)) && (ADSTYPE_INVALID != SearchColumn.dwADsType) && (NULL != SearchColumn.pADsValues))
  621. {
  622. vLanguage = SearchColumn.pADsValues->CaseIgnoreString;
  623. hres = pDestRuleObj->Put(g_bstrQueryLanguage, 0, &vLanguage, 0);
  624. pDirSrch->FreeColumn(&SearchColumn);
  625. if(FAILED(hres)) return hres;
  626. }
  627. // **** TargetNameSpace
  628. hres = pDirSrch->GetColumn(SearchHandle, g_bstrADTargetNameSpace, &SearchColumn);
  629. if((SUCCEEDED(hres)) && (ADSTYPE_INVALID != SearchColumn.dwADsType) && (NULL != SearchColumn.pADsValues))
  630. {
  631. vNameSpace = SearchColumn.pADsValues->CaseIgnoreString;
  632. hres = pDestRuleObj->Put(g_bstrTargetNameSpace, 0, &vNameSpace, 0);
  633. pDirSrch->FreeColumn(&SearchColumn);
  634. if(FAILED(hres)) return hres;
  635. }
  636. // **** Query
  637. hres = pDirSrch->GetColumn(SearchHandle, g_bstrADQuery, &SearchColumn);
  638. if((SUCCEEDED(hres)) && (ADSTYPE_INVALID != SearchColumn.dwADsType) && (NULL != SearchColumn.pADsValues))
  639. {
  640. vQuery = SearchColumn.pADsValues->CaseIgnoreString;
  641. hres = pDestRuleObj->Put(g_bstrQuery, 0, &vQuery, 0);
  642. hres = pDirSrch->FreeColumn(&SearchColumn);
  643. if(FAILED(hres)) return hres;
  644. }
  645. // **** stuff new rule object into SOM object
  646. hres = pDestSomObj->Get(g_bstrRules, 0, &vRules1, NULL, NULL);
  647. if(FAILED(hres)) return hres;
  648. SafeArray<IUnknown*, VT_UNKNOWN>
  649. Rules(&vRules1);
  650. hres = pDestRuleObj->QueryInterface(IID_IUnknown, (void**)&pUnknown);
  651. if(FAILED(hres)) return hres;
  652. if(pUnknown == NULL) return WBEM_E_FAILED;
  653. Rules.ReDim(0, Rules.Size() + 1);
  654. Rules[Rules.IndexMax()] = pUnknown;
  655. Rules[Rules.IndexMax()]->AddRef();
  656. // **** place array in dest som object
  657. V_VT(&vRules2) = (VT_ARRAY | Rules.Type());
  658. V_ARRAY(&vRules2) = Rules.Data();
  659. hres = pDestSomObj->Put(g_bstrRules, 0, &vRules2, 0);
  660. if(FAILED(hres)) return hres;
  661. }
  662. }
  663. return WBEM_S_NO_ERROR;
  664. }