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.

728 lines
22 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. // ***************************************************************************
  5. //
  6. // Original Author: Rajesh Rao
  7. //
  8. // $Author: rajeshr $
  9. // $Date: 6/11/98 4:43p $
  10. // $Workfile:wbemhelp.cpp $
  11. //
  12. // $Modtime: 6/11/98 11:21a $
  13. // $Revision: 1 $
  14. // $Nokeywords: $
  15. //
  16. //
  17. // Description: Contains the implementation the CWBEMHelper class. This is
  18. // a class that has many static helper functions pertaining to WBEM
  19. //***************************************************************************
  20. /////////////////////////////////////////////////////////////////////////
  21. #include "precomp.h"
  22. LPCWSTR CWBEMHelper :: EQUALS_QUOTE = L"=\"";
  23. LPCWSTR CWBEMHelper :: QUOTE = L"\"";
  24. LPCWSTR CWBEMHelper :: OBJECT_CATEGORY_EQUALS = L"objectCategory=";
  25. LPCWSTR CWBEMHelper :: OBJECT_CLASS_EQUALS = L"objectClass=";
  26. //***************************************************************************
  27. //
  28. // CWBEMHelper::PutBSTRProperty
  29. //
  30. // Purpose: Puts a BSTR property
  31. //
  32. // Parameters:
  33. // pWbemClass : The WBEM class on which the property has to be put
  34. // strPropertyName : The name of the property to be put
  35. // strPropertyValue : The value of the property to be put
  36. // deallocatePropertyValue : whether to deallocate the parameter strPropertyValue before
  37. // the function returns
  38. //
  39. // Return Value: The COM value representing the return status
  40. //
  41. //***************************************************************************
  42. HRESULT CWBEMHelper :: PutBSTRProperty(IWbemClassObject *pWbemClass,
  43. const BSTR strPropertyName,
  44. BSTR strPropertyValue,
  45. BOOLEAN deallocatePropertyValue)
  46. {
  47. VARIANT variant;
  48. VariantInit(&variant);
  49. variant.vt = VT_BSTR;
  50. variant.bstrVal = strPropertyValue;
  51. HRESULT result = pWbemClass->Put(strPropertyName, 0, &variant, 0);
  52. if (!deallocatePropertyValue)
  53. variant.bstrVal = NULL;
  54. VariantClear(&variant);
  55. return result;
  56. }
  57. //***************************************************************************
  58. //
  59. // CWBEMHelper::GetBSTRProperty
  60. //
  61. // Purpose: Gets a BSTR property
  62. //
  63. // Parameters:
  64. // pWbemClass : The WBEM class on which the property has to be gotten
  65. // strPropertyName : The name of the property to be gotten
  66. // pStrPropertyValue : The address where the value of the property to should be put
  67. //
  68. // Return Value: The COM value representing the return status. The user should delete the
  69. // string allocated when done
  70. //
  71. //***************************************************************************
  72. HRESULT CWBEMHelper :: GetBSTRProperty(IWbemClassObject *pWbemClass,
  73. const BSTR strPropertyName,
  74. BSTR *pStrPropertyValue)
  75. {
  76. VARIANT variant;
  77. VariantInit(&variant);
  78. HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
  79. if(variant.vt == VT_BSTR && variant.bstrVal)
  80. *pStrPropertyValue = SysAllocString(variant.bstrVal);
  81. else
  82. *pStrPropertyValue = NULL;
  83. VariantClear(&variant);
  84. return result;
  85. }
  86. //***************************************************************************
  87. //
  88. // CWBEMHelper::PutBSTRPropertyT
  89. //
  90. // Purpose: Puts a BSTR property
  91. //
  92. // Parameters:
  93. // pWbemClass : The WBEM class on which the property has to be put
  94. // strPropertyName : The name of the property to be put
  95. // lpszPropertyValue : The value of the property to be put
  96. // deallocatePropertyValue : whether to deallocate the parameter lpszPropertyValue before
  97. // the function returns
  98. //
  99. // Return Value: The COM value representing the return status
  100. //
  101. //***************************************************************************
  102. HRESULT CWBEMHelper :: PutBSTRPropertyT(IWbemClassObject *pWbemClass,
  103. const BSTR strPropertyName,
  104. LPWSTR lpszPropertyValue,
  105. BOOLEAN deallocatePropertyValue)
  106. {
  107. BSTR strPropertyValue = SysAllocString(lpszPropertyValue);
  108. VARIANT variant;
  109. VariantInit(&variant);
  110. variant.vt = VT_BSTR;
  111. variant.bstrVal = strPropertyValue;
  112. HRESULT result = pWbemClass->Put(strPropertyName, 0, &variant, 0);
  113. if (deallocatePropertyValue)
  114. delete[] lpszPropertyValue;
  115. VariantClear(&variant);
  116. return result;
  117. }
  118. //***************************************************************************
  119. //
  120. // CWBEMHelper::GetBSTRPropertyT
  121. //
  122. // Purpose: Gets a BSTR property
  123. //
  124. // Parameters:
  125. // pWbemClass : The WBEM class on which the property has to be put
  126. // strPropertyName : The name of the property to be put
  127. // lppszPropertyValue : The pointer to LPWSTR where the value of the property will be placed. The user should
  128. // delete this once he is done with it.
  129. //
  130. // Return Value: The COM value representing the return status
  131. //
  132. //***************************************************************************
  133. HRESULT CWBEMHelper :: GetBSTRPropertyT(IWbemClassObject *pWbemClass,
  134. const BSTR strPropertyName,
  135. LPWSTR *lppszPropertyValue)
  136. {
  137. VARIANT variant;
  138. VariantInit(&variant);
  139. HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
  140. if(SUCCEEDED(result))
  141. {
  142. *lppszPropertyValue = new WCHAR[wcslen(variant.bstrVal) + 1];
  143. wcscpy(*lppszPropertyValue, variant.bstrVal);
  144. }
  145. VariantClear(&variant);
  146. return result;
  147. }
  148. //***************************************************************************
  149. //
  150. // CWBEMHelper::PutBSTRArrayProperty
  151. //
  152. // Purpose: Puts a BSTR Array property
  153. //
  154. // Parameters:
  155. // pWbemClass : The WBEM class on which the property has to be put
  156. // strPropertyName : The name of the property to be put
  157. // pStrPropertyValue : The array of BSTRS that have the values of the property to be put
  158. // lCount : The number of elements in the above array
  159. // deallocatePropertyValue : whether to deallocate the parameter strPropertyValue before
  160. // the function returns
  161. //
  162. // Return Value: The COM value representing the return status
  163. //
  164. //***************************************************************************
  165. HRESULT CWBEMHelper :: PutBSTRArrayProperty(IWbemClassObject *pWbemClass,
  166. const BSTR strPropertyName,
  167. VARIANT *pInputVariant)
  168. {
  169. // THe input is a safe array of variants of type VT_BSTR
  170. // The output is a safe array for VT_BSTRs
  171. LONG lstart, lend;
  172. SAFEARRAY *inputSafeArray = pInputVariant->parray;
  173. // Get the lower and upper bound of the inpute safe array
  174. SafeArrayGetLBound( inputSafeArray, 1, &lstart );
  175. SafeArrayGetUBound( inputSafeArray, 1, &lend );
  176. // Create the output SAFEARRAY
  177. SAFEARRAY *outputSafeArray = NULL;
  178. SAFEARRAYBOUND safeArrayBounds [ 1 ] ;
  179. safeArrayBounds[0].lLbound = lstart ;
  180. safeArrayBounds[0].cElements = lend - lstart + 1 ;
  181. outputSafeArray = SafeArrayCreate (VT_BSTR, 1, safeArrayBounds);
  182. // Fill it
  183. VARIANT inputItem;
  184. VariantInit(&inputItem);
  185. HRESULT result = S_OK;
  186. bool bError = false;
  187. for ( long idx=lstart; !bError && (idx <=lend); idx++ )
  188. {
  189. VariantInit(&inputItem);
  190. SafeArrayGetElement( inputSafeArray, &idx, &inputItem );
  191. if(FAILED(result = SafeArrayPutElement(outputSafeArray, &idx, inputItem.bstrVal)))
  192. bError = true;
  193. VariantClear(&inputItem);
  194. }
  195. // Create the variant
  196. if(SUCCEEDED(result))
  197. {
  198. VARIANT outputVariant;
  199. VariantInit(&outputVariant);
  200. outputVariant.vt = VT_ARRAY | VT_BSTR ;
  201. outputVariant.parray = outputSafeArray ;
  202. result = pWbemClass->Put (strPropertyName, 0, &outputVariant, 0);
  203. VariantClear(&outputVariant);
  204. }
  205. else
  206. SafeArrayDestroy(outputSafeArray);
  207. return result;
  208. }
  209. //***************************************************************************
  210. //
  211. // CWBEMHelper :: PutBOOLQualifier
  212. //
  213. // Purpose: Puts a BOOLEAN Qualifier
  214. //
  215. // Parameters:
  216. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  217. // strQualifierName : The name of the qualifier to be put
  218. // bQualifierValue : The value of the qualifier to be put
  219. // lFlavour : The flavour of the qualifer
  220. //
  221. // Return Value: The COM value representing the return status
  222. //
  223. //***************************************************************************
  224. HRESULT CWBEMHelper :: PutBOOLQualifier(IWbemQualifierSet *pQualifierSet,
  225. const BSTR strQualifierName,
  226. VARIANT_BOOL bQualifierValue,
  227. LONG lFlavour)
  228. {
  229. VARIANT variant;
  230. VariantInit(&variant);
  231. variant.vt = VT_BOOL;
  232. variant.boolVal = bQualifierValue;
  233. HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
  234. VariantClear(&variant);
  235. return result;
  236. }
  237. //***************************************************************************
  238. //
  239. // CWBEMHelper :: GetBOOLQualifier
  240. //
  241. // Purpose: Gets a BOOLEAN Qualifier
  242. //
  243. // Parameters:
  244. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  245. // strQualifierName : The name of the qualifier to get
  246. // bQualifierValue : The value of the qualifier to get
  247. // lFlavour : The flavour of the qualifer
  248. //
  249. // Return Value: The COM value representing the return status
  250. //
  251. //***************************************************************************
  252. HRESULT CWBEMHelper :: GetBOOLQualifier(IWbemQualifierSet *pQualifierSet,
  253. const BSTR strQualifierName,
  254. VARIANT_BOOL *pbQualifierValue,
  255. LONG *plFlavour)
  256. {
  257. VARIANT variant;
  258. VariantInit(&variant);
  259. HRESULT result = pQualifierSet->Get(strQualifierName, 0, &variant, plFlavour);
  260. if(SUCCEEDED(result))
  261. *pbQualifierValue = variant.boolVal;
  262. VariantClear(&variant);
  263. return result;
  264. }
  265. //***************************************************************************
  266. //
  267. // CWBEMHelper :: PutI4Qualifier
  268. //
  269. // Purpose: Puts a VT_I4 Qualifier
  270. //
  271. // Parameters:
  272. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  273. // strQualifierName : The name of the qualifier to be put
  274. // lQualifierValue : The value of the qualifier to be put
  275. // lFlavour : The flavour of the qualifer
  276. //
  277. // Return Value: The COM value representing the return status
  278. //
  279. //***************************************************************************
  280. HRESULT CWBEMHelper :: PutI4Qualifier(IWbemQualifierSet *pQualifierSet,
  281. const BSTR strQualifierName,
  282. long lQualifierValue,
  283. LONG lFlavour)
  284. {
  285. VARIANT variant;
  286. VariantInit(&variant);
  287. variant.vt = VT_I4;
  288. variant.lVal = lQualifierValue;
  289. HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
  290. VariantClear(&variant);
  291. return result;
  292. }
  293. //***************************************************************************
  294. //
  295. // CWBEMHelper :: PutLONGQualifier
  296. //
  297. // Purpose: Puts a LONG Qualifier
  298. //
  299. // Parameters:
  300. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  301. // strQualifierName : The name of the qualifier to be put
  302. // lQualifierValue : The value of the qualifier to be put
  303. // lFlavour : The flavour of the qualifer
  304. //
  305. // Return Value: The COM value representing the return status
  306. //
  307. //***************************************************************************
  308. HRESULT CWBEMHelper :: PutLONGQualifier(IWbemQualifierSet *pQualifierSet,
  309. const BSTR strQualifierName,
  310. LONG lQualifierValue,
  311. LONG lFlavour)
  312. {
  313. VARIANT variant;
  314. VariantInit(&variant);
  315. variant.vt = VT_I4;
  316. variant.lVal = lQualifierValue;
  317. HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
  318. VariantClear(&variant);
  319. return result;
  320. }
  321. //***************************************************************************
  322. //
  323. // CWBEMHelper :: PutBSTRQualifier
  324. //
  325. // Purpose: Puts a BSTR Qualifier
  326. //
  327. // Parameters:
  328. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  329. // strQualifierName : The name of the qualifier to be put
  330. // strQualifierValue : The value of the qualifier to be put
  331. // lFlavour : The flavour of the qualifer
  332. // deallocateQualifierValue : whether to deallocate the parameter strQualifierValue
  333. // before the function returns
  334. //
  335. // Return Value: The COM value representing the return status
  336. //
  337. //***************************************************************************
  338. HRESULT CWBEMHelper :: PutBSTRQualifier(IWbemQualifierSet *pQualifierSet,
  339. const BSTR strQualifierName,
  340. BSTR strQualifierValue,
  341. LONG lFlavour,
  342. BOOLEAN deallocateQualifierValue)
  343. {
  344. VARIANT variant;
  345. VariantInit(&variant);
  346. variant.vt = VT_BSTR;
  347. variant.bstrVal = strQualifierValue;
  348. HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
  349. if(!deallocateQualifierValue)
  350. variant.bstrVal = NULL;
  351. VariantClear(&variant);
  352. return result;
  353. }
  354. //***************************************************************************
  355. //
  356. // CWBEMHelper :: GetBSTRQualifierT
  357. //
  358. // Purpose: Gets a BSTR Qualifier
  359. //
  360. // Parameters:
  361. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  362. // strQualifierName : The name of the qualifier to be put
  363. // lppszQualifierValue : The address of the LPWSTR where the qualifier value will be put/
  364. // It is the duty of the caller to free this memory when done
  365. // plFlavour : The address where the qualifier flavor will be put. This is optional
  366. //
  367. // Return Value: The COM value representing the return status
  368. //
  369. //***************************************************************************
  370. HRESULT CWBEMHelper :: GetBSTRQualifierT(
  371. IWbemQualifierSet *pQualifierSet,
  372. const BSTR strQualifierName,
  373. LPWSTR *lppszQualifierValue,
  374. LONG *plFlavour)
  375. {
  376. VARIANT variant;
  377. VariantInit(&variant);
  378. HRESULT result = pQualifierSet->Get(strQualifierName, 0, &variant, plFlavour);
  379. if(SUCCEEDED(result))
  380. {
  381. if(variant.vt == VT_BSTR && variant.bstrVal)
  382. {
  383. *lppszQualifierValue = NULL;
  384. if(*lppszQualifierValue = new WCHAR [ wcslen(variant.bstrVal) + 1])
  385. wcscpy(*lppszQualifierValue, variant.bstrVal);
  386. else
  387. result = E_OUTOFMEMORY;
  388. }
  389. else
  390. result = E_FAIL;
  391. }
  392. VariantClear(&variant);
  393. return result;
  394. }
  395. //***************************************************************************
  396. //
  397. // CWBEMHelper :: PutUint8ArrayQualifier
  398. //
  399. // Purpose: Puts a Uint8 array Qualifier
  400. //
  401. // Parameters:
  402. // pQualifierSet : The Qualifier set on which this qualifier has to be put
  403. // strQualifierName : The name of the qualifier to be put
  404. // lpQualifierValue : The value of the qualifier to be put. An array of BYTEs
  405. // dwLenght : The number of elements in the above array
  406. // lFlavour : The flavour of the qualifer
  407. //
  408. // Return Value: The COM value representing the return status
  409. //
  410. //***************************************************************************
  411. HRESULT CWBEMHelper :: PutUint8ArrayQualifier(IWbemQualifierSet *pQualifierSet,
  412. const BSTR strQualifierName,
  413. LPBYTE lpQualifierValue,
  414. DWORD dwLength,
  415. LONG lFlavour)
  416. {
  417. // Create the variant
  418. VARIANT variant;
  419. VariantInit(&variant);
  420. // Create the SAFEARRAY
  421. SAFEARRAY *safeArray ;
  422. SAFEARRAYBOUND safeArrayBounds [ 1 ] ;
  423. safeArrayBounds[0].lLbound = 0 ;
  424. safeArrayBounds[0].cElements = dwLength ;
  425. safeArray = SafeArrayCreate (VT_I4, 1, safeArrayBounds);
  426. // Fill it
  427. UINT temp;
  428. HRESULT result = S_OK;
  429. bool bError = false;
  430. for (LONG index = 0; !bError && (index<(LONG)dwLength); index++)
  431. {
  432. temp = (UINT)lpQualifierValue[index];
  433. if(FAILED(result = SafeArrayPutElement(safeArray , &index, (LPVOID)&temp)))
  434. bError = true;
  435. }
  436. if(SUCCEEDED(result))
  437. {
  438. variant.vt = VT_ARRAY | VT_I4 ;
  439. variant.parray = safeArray ;
  440. result = pQualifierSet->Put (strQualifierName, &variant, lFlavour);
  441. VariantClear(&variant);
  442. }
  443. else
  444. SafeArrayDestroy(safeArray);
  445. return result;
  446. }
  447. //***************************************************************************
  448. //
  449. // CWBEMHelper::GetADSIPathFromObjectPath
  450. //
  451. // Purpose: See Header File
  452. //
  453. //***************************************************************************
  454. LPWSTR CWBEMHelper :: GetADSIPathFromObjectPath(LPCWSTR pszObjectRef)
  455. {
  456. // Parse the object path
  457. CObjectPathParser theParser;
  458. ParsedObjectPath *theParsedObjectPath = NULL;
  459. LPWSTR pszADSIPath = NULL;
  460. switch(theParser.Parse((LPWSTR)pszObjectRef, &theParsedObjectPath))
  461. {
  462. case CObjectPathParser::NoError:
  463. {
  464. KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
  465. // Check to see that there is 1 key specified and that its type is VT_BSTR
  466. if(theParsedObjectPath->m_dwNumKeys == 1 && pKeyRef->m_vValue.vt == VT_BSTR)
  467. {
  468. // If the name of the key is specified, check the name
  469. if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_ATTR) != 0)
  470. break;
  471. pszADSIPath = new WCHAR[wcslen((*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal) + 1];
  472. wcscpy(pszADSIPath, (*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal);
  473. }
  474. break;
  475. }
  476. default:
  477. break;
  478. }
  479. // Free the parser object path
  480. theParser.Free(theParsedObjectPath);
  481. return pszADSIPath;
  482. }
  483. //***************************************************************************
  484. //
  485. // CWBEMHelper::GetObjectRefFromADSIPath
  486. //
  487. // Purpose: See Header File
  488. //
  489. //***************************************************************************
  490. BSTR CWBEMHelper :: GetObjectRefFromADSIPath(LPCWSTR pszADSIPath, LPCWSTR pszWBEMClassName)
  491. {
  492. // We need the object path parser to add WMI escape characters
  493. // from the key value which is an ADSI Path
  494. ParsedObjectPath t_ObjectPath;
  495. // Add a key value binding for the ADSIPath
  496. //===========================================
  497. VARIANT vKeyValue;
  498. VariantInit(&vKeyValue);
  499. vKeyValue.vt = VT_BSTR;
  500. vKeyValue.bstrVal = SysAllocString(pszADSIPath);
  501. t_ObjectPath.SetClassName(pszWBEMClassName);
  502. t_ObjectPath.AddKeyRef(ADSI_PATH_ATTR, &vKeyValue);
  503. VariantClear(&vKeyValue);
  504. // Get the Object Path value now
  505. //================================
  506. CObjectPathParser t_Parser;
  507. LPWSTR t_pszObjectPath = NULL;
  508. BSTR retVal = NULL;
  509. if(CObjectPathParser::NoError == t_Parser.Unparse(&t_ObjectPath, &t_pszObjectPath))
  510. {
  511. retVal = SysAllocString(t_pszObjectPath);
  512. delete [] t_pszObjectPath;
  513. }
  514. return retVal;
  515. }
  516. //***************************************************************************
  517. //
  518. // CWBEMHelper::GetUint8ArrayProperty
  519. //
  520. // Purpose: See Header file
  521. //
  522. //***************************************************************************
  523. HRESULT CWBEMHelper :: GetUint8ArrayProperty(IWbemClassObject *pWbemClass,
  524. const BSTR strPropertyName,
  525. LPBYTE *ppPropertyValues,
  526. ULONG *plCount)
  527. {
  528. VARIANT variant;
  529. VariantInit(&variant);
  530. HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
  531. if(SUCCEEDED(result))
  532. {
  533. if(variant.vt == (VT_ARRAY|VT_UI1))
  534. {
  535. SAFEARRAY *pArray = variant.parray;
  536. BYTE HUGEP *pb;
  537. LONG lUbound = 0, lLbound = 0;
  538. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pb)))
  539. {
  540. if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)))
  541. {
  542. if (SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)))
  543. {
  544. if(*plCount = lUbound - lLbound + 1)
  545. {
  546. *ppPropertyValues = new BYTE[*plCount];
  547. for(DWORD i=0; i<*plCount; i++)
  548. (*ppPropertyValues)[i] = pb[i];
  549. }
  550. }
  551. }
  552. SafeArrayUnaccessData(pArray);
  553. }
  554. }
  555. else
  556. {
  557. *ppPropertyValues = NULL;
  558. *plCount = 0;
  559. }
  560. }
  561. VariantClear(&variant);
  562. return result;
  563. }
  564. //***************************************************************************
  565. //
  566. // CWBEMHelper::FormulateInstanceQuery
  567. //
  568. // Purpose: See Header file
  569. //
  570. //***************************************************************************
  571. HRESULT CWBEMHelper :: FormulateInstanceQuery(IWbemServices *pServices, IWbemContext *pCtx, BSTR strClass, IWbemClassObject *pWbemClass, LPWSTR pszObjectCategory, BSTR strClassQualifier, BSTR strCategoryQualifier)
  572. {
  573. DWORD dwOutput = 0;
  574. pszObjectCategory[dwOutput++] = LEFT_BRACKET_STR[0];
  575. DWORD dwOrPosition = dwOutput;
  576. pszObjectCategory[dwOutput++] = PIPE_STR[0];
  577. HRESULT result = E_FAIL;
  578. if(SUCCEEDED(result = AddSingleCategory(pszObjectCategory, &dwOutput, pWbemClass, strClassQualifier, strCategoryQualifier)))
  579. {
  580. }
  581. /*
  582. IEnumWbemClassObject *pEnum = NULL;
  583. DWORD dwNumObjects = 0;
  584. HRESULT result = pServices->CreateClassEnum(strClass, WBEM_FLAG_DEEP, pCtx, &pEnum);
  585. if(SUCCEEDED(result))
  586. {
  587. IWbemClassObject *pNextObject = NULL;
  588. ULONG lNum = 0;
  589. while(SUCCEEDED(pEnum->Next(WBEM_INFINITE, 1, &pNextObject, &lNum)) && lNum )
  590. {
  591. if(!SUCCEEDED(AddSingleCategory(pszObjectCategory, &dwOutput, pNextObject, strClassQualifier, strCategoryQualifier)))
  592. {
  593. pNextObject->Release();
  594. break;
  595. }
  596. dwNumObjects ++;
  597. pNextObject->Release();
  598. }
  599. pEnum->Release();
  600. }
  601. // Remove the '|' if there is only one element
  602. if(!dwNumObjects)
  603. */
  604. pszObjectCategory[dwOrPosition] = SPACE_STR[0];
  605. // Terminate the query
  606. pszObjectCategory[dwOutput++] = RIGHT_BRACKET_STR[0];
  607. pszObjectCategory[dwOutput] = NULL;
  608. return result;
  609. }
  610. //***************************************************************************
  611. //
  612. // CWBEMHelper::AddSingleCategory
  613. //
  614. // Purpose: See Header file
  615. //
  616. //***************************************************************************
  617. HRESULT CWBEMHelper :: AddSingleCategory(LPWSTR pszObjectCategory, DWORD *pdwOutput, IWbemClassObject *pNextObject, BSTR strLDAPNameQualifier, BSTR strCategoryQualifier)
  618. {
  619. pszObjectCategory[(*pdwOutput)++] = SPACE_STR[0];
  620. pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
  621. IWbemQualifierSet *pQualifierSet = NULL;
  622. HRESULT result;
  623. if(SUCCEEDED(result = pNextObject->GetQualifierSet(&pQualifierSet)))
  624. {
  625. VARIANT classNameVariant;
  626. if(SUCCEEDED(result = pQualifierSet->Get(strLDAPNameQualifier, 0, &classNameVariant, NULL)))
  627. {
  628. VARIANT categoryVariant;
  629. if(SUCCEEDED(result = pQualifierSet->Get(strCategoryQualifier, 0, &categoryVariant, NULL)))
  630. {
  631. pszObjectCategory[(*pdwOutput)++] = AMPERSAND_STR[0];
  632. pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
  633. wcscpy(pszObjectCategory + *pdwOutput, OBJECT_CATEGORY_EQUALS);
  634. *pdwOutput += wcslen(OBJECT_CATEGORY_EQUALS);
  635. wcscpy(pszObjectCategory + *pdwOutput, categoryVariant.bstrVal);
  636. *pdwOutput += wcslen(categoryVariant.bstrVal);
  637. pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
  638. pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
  639. wcscpy(pszObjectCategory + *pdwOutput, OBJECT_CLASS_EQUALS);
  640. *pdwOutput += wcslen(OBJECT_CLASS_EQUALS);
  641. wcscpy(pszObjectCategory + *pdwOutput, classNameVariant.bstrVal);
  642. *pdwOutput += wcslen(classNameVariant.bstrVal);
  643. pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
  644. VariantClear(&categoryVariant);
  645. }
  646. VariantClear(&classNameVariant);
  647. }
  648. pQualifierSet->Release();
  649. }
  650. pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
  651. pszObjectCategory[(*pdwOutput)++] = SPACE_STR[0];
  652. return result;
  653. }
  654. //***************************************************************************
  655. //
  656. // CWBEMHelper::IsPresentInBstrList
  657. //
  658. // Purpose: See Header file
  659. //
  660. //***************************************************************************
  661. BOOLEAN CWBEMHelper :: IsPresentInBstrList(BSTR *pstrProperyNames, DWORD dwNumPropertyNames, BSTR strPropertyName)
  662. {
  663. for(DWORD i=0; i<dwNumPropertyNames; i++)
  664. {
  665. if(_wcsicmp(pstrProperyNames[i], strPropertyName) == 0)
  666. return TRUE;
  667. }
  668. return FALSE;
  669. }