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.

1125 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. utils.cpp
  5. Abstract:
  6. General purpose utilities
  7. Author:
  8. ???
  9. Revision History:
  10. Mohit Srivastava 18-Dec-00
  11. --*/
  12. #include "iisprov.h"
  13. #include "iiswmimsg.h"
  14. extern CDynSchema* g_pDynSch;
  15. extern HMODULE g_hModule;
  16. BSTR CUtils::ExtractBstrFromVt(
  17. const VARIANT* i_pvt,
  18. LPCWSTR i_wszVtName) // default(NULL)
  19. /*++
  20. Synopsis:
  21. This is different from VARAINT::ChangeType in that it handles conversion
  22. from VT_NULL also.
  23. Arguments: [i_pvt] -
  24. Return Value:
  25. BSTR: If non-null, points to i_pvt->bstrVal
  26. --*/
  27. {
  28. DBG_ASSERT(i_pvt != NULL);
  29. switch(i_pvt->vt)
  30. {
  31. case VT_BSTR:
  32. return i_pvt->bstrVal;
  33. case VT_NULL:
  34. return NULL;
  35. default:
  36. CIIsProvException e;
  37. e.SetHR(DISP_E_TYPEMISMATCH, i_wszVtName);
  38. throw e;
  39. }
  40. return NULL;
  41. }
  42. LONG CUtils::ExtractLongFromVt(
  43. const VARIANT* i_pvt,
  44. LPCWSTR i_wszVtName) //default(NULL)
  45. {
  46. DBG_ASSERT(i_pvt);
  47. try
  48. {
  49. _variant_t svt;
  50. svt = *i_pvt;
  51. return (long)svt;
  52. }
  53. catch(_com_error ce)
  54. {
  55. CIIsProvException e;
  56. e.SetHR(ce.Error(), i_wszVtName);
  57. throw e;
  58. }
  59. }
  60. bool CUtils::CompareKeyType(
  61. LPCWSTR i_wszKeyFromMb,
  62. METABASE_KEYTYPE* i_pktKeyCompare)
  63. {
  64. DBG_ASSERT(i_wszKeyFromMb);
  65. DBG_ASSERT(i_pktKeyCompare);
  66. if(!i_pktKeyCompare->m_pszName)
  67. {
  68. return false;
  69. }
  70. if(_wcsicmp(i_wszKeyFromMb, i_pktKeyCompare->m_pszName) == 0)
  71. {
  72. return true;
  73. }
  74. //
  75. // If i_wszKeyFromMb is not in our hashtable and i_wszKeyCompare is
  76. // IIsObject, treat as a match.
  77. //
  78. METABASE_KEYTYPE* pKt = NULL;
  79. HRESULT hr = g_pDynSch->GetHashKeyTypes()->Wmi_GetByKey(i_wszKeyFromMb, &pKt);
  80. if( FAILED(hr) && i_pktKeyCompare == &METABASE_KEYTYPE_DATA::s_IIsObject )
  81. {
  82. return true;
  83. }
  84. return false;
  85. }
  86. bool CUtils::CompareMultiSz(
  87. WCHAR* i_msz1,
  88. WCHAR* i_msz2
  89. )
  90. {
  91. if(i_msz1 == NULL && i_msz2 == NULL)
  92. return true;
  93. else if(i_msz1 == NULL || i_msz2 == NULL)
  94. return false;
  95. // compare the two multisz buffers.
  96. for ( ; (*i_msz1 && *i_msz2); )
  97. {
  98. if (_wcsicmp(i_msz1, i_msz2) != NULL)
  99. return false;
  100. i_msz1 += wcslen(i_msz1) + 1;
  101. i_msz2 += wcslen(i_msz2) + 1;
  102. }
  103. if (!*i_msz1 && !*i_msz2)
  104. {
  105. return true;
  106. }
  107. return false;
  108. }
  109. HRESULT CUtils::LoadSafeArrayFromByteArray(
  110. LPBYTE i_aBytes,
  111. DWORD i_iBytes,
  112. _variant_t& io_vt
  113. )
  114. {
  115. DBG_ASSERT(i_aBytes != NULL);
  116. HRESULT hr = S_OK;
  117. SAFEARRAY* pSafeArray = NULL;
  118. SAFEARRAYBOUND safeArrayBounds[1];
  119. safeArrayBounds[0].lLbound = 0;
  120. safeArrayBounds[0].cElements = i_iBytes;
  121. pSafeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBounds);
  122. if(pSafeArray == NULL)
  123. {
  124. hr = WBEM_E_OUT_OF_MEMORY;
  125. goto exit;
  126. }
  127. for(ULONG idx = 0; idx < i_iBytes; idx++)
  128. {
  129. hr = SafeArrayPutElement(pSafeArray, (LONG *)&idx, &i_aBytes[idx]);
  130. if(FAILED(hr))
  131. {
  132. goto exit;
  133. }
  134. }
  135. //
  136. // If everything succeeded, set out parameters.
  137. //
  138. io_vt.vt = VT_UI1 | VT_ARRAY;
  139. io_vt.parray = pSafeArray;
  140. exit:
  141. if(FAILED(hr))
  142. {
  143. if(pSafeArray != NULL)
  144. {
  145. SafeArrayDestroy(pSafeArray);
  146. }
  147. }
  148. return hr;
  149. }
  150. //
  151. // CreateByteArrayFromSafeArray
  152. //
  153. HRESULT CUtils::CreateByteArrayFromSafeArray(
  154. _variant_t& i_vt,
  155. LPBYTE* o_paBytes,
  156. DWORD* io_pdw
  157. )
  158. {
  159. DBG_ASSERT(i_vt.vt == (VT_ARRAY | VT_UI1));
  160. DBG_ASSERT(o_paBytes != NULL);
  161. DBG_ASSERT(io_pdw != NULL);
  162. if(i_vt.parray == NULL)
  163. {
  164. *o_paBytes = NULL;
  165. *io_pdw = 0;
  166. }
  167. HRESULT hr = S_OK;
  168. LONG iLo = 0;
  169. LONG iUp = 0;
  170. LPBYTE aBytes = NULL;
  171. hr = SafeArrayGetLBound(i_vt.parray,1,&iLo);
  172. if(FAILED(hr))
  173. {
  174. goto exit;
  175. }
  176. hr = SafeArrayGetUBound(i_vt.parray,1,&iUp);
  177. if(FAILED(hr))
  178. {
  179. goto exit;
  180. }
  181. aBytes = new BYTE[iUp-iLo+1];
  182. if(aBytes == NULL)
  183. {
  184. hr = WBEM_E_OUT_OF_MEMORY;
  185. goto exit;
  186. }
  187. for(LONG i = iLo; i <= iUp; i++)
  188. {
  189. hr = SafeArrayGetElement(i_vt.parray, &i, &aBytes[i-iLo]);
  190. if(FAILED(hr))
  191. {
  192. goto exit;
  193. }
  194. }
  195. //
  196. // If everything succeeded, set out parameters.
  197. //
  198. *o_paBytes = aBytes;
  199. *io_pdw = iUp-iLo+1;
  200. exit:
  201. if(FAILED(hr))
  202. {
  203. delete [] aBytes;
  204. }
  205. return hr;
  206. }
  207. bool CUtils::CompareByteArray(
  208. LPBYTE i_aBytes1,
  209. ULONG i_iBytes1,
  210. LPBYTE i_aBytes2,
  211. ULONG i_iBytes2
  212. )
  213. {
  214. if(i_aBytes1 == NULL && i_aBytes2 == NULL)
  215. {
  216. return true;
  217. }
  218. if(i_aBytes1 == NULL || i_aBytes2 == NULL)
  219. {
  220. return false;
  221. }
  222. if(i_iBytes1 != i_iBytes2)
  223. {
  224. return false;
  225. }
  226. for(ULONG i = 0; i < i_iBytes1; i++)
  227. {
  228. if(i_aBytes1[i] != i_aBytes2[i])
  229. {
  230. return false;
  231. }
  232. }
  233. return true;
  234. }
  235. KeyRef* CUtils::GetKey(
  236. ParsedObjectPath* i_pParsedObjectPath,
  237. WCHAR* i_wsz
  238. )
  239. /*++
  240. Synopsis:
  241. Return the KeyRef pointer from the ParsedObjectPath for the given string.
  242. Arguments: [i_pParsedObjectPath] -
  243. [i_wsz] -
  244. Return Value:
  245. --*/
  246. {
  247. KeyRef* pkr;
  248. DWORD numkeys = i_pParsedObjectPath->m_dwNumKeys;
  249. DWORD c;
  250. if(numkeys == 1)
  251. {
  252. pkr = *(i_pParsedObjectPath->m_paKeys);
  253. if(pkr->m_pName == NULL)
  254. {
  255. return pkr;
  256. }
  257. }
  258. for ( c=0; numkeys; numkeys--,c++ )
  259. {
  260. pkr = *(i_pParsedObjectPath->m_paKeys + c);
  261. if (!_wcsicmp(pkr->m_pName,i_wsz))
  262. return pkr;
  263. }
  264. CIIsProvException e;
  265. e.SetMC(WBEM_E_INVALID_OBJECT, IISWMI_NO_PRIMARY_KEY, i_wsz);
  266. throw e;
  267. }
  268. bool CUtils::GetAssociation(
  269. LPCWSTR i_wszAssocName,
  270. WMI_ASSOCIATION** o_ppAssoc
  271. )
  272. /*++
  273. Synopsis:
  274. Association i_wszAssocName is returned in o_ppAssoc if found.
  275. Arguments: [i_wszAssocName] -
  276. [o_ppAssoc] -
  277. Return Value:
  278. true if found
  279. false otherwise
  280. --*/
  281. {
  282. DBG_ASSERT(o_ppAssoc != NULL);
  283. HRESULT hr;
  284. hr = g_pDynSch->GetHashAssociations()->Wmi_GetByKey(
  285. (LPWSTR)i_wszAssocName,
  286. o_ppAssoc);
  287. if(SUCCEEDED(hr))
  288. {
  289. return true;
  290. }
  291. else
  292. {
  293. return false;
  294. }
  295. }
  296. bool CUtils::GetClass(
  297. LPCWSTR i_wszClassName,
  298. WMI_CLASS** o_ppClass
  299. )
  300. /*++
  301. Synopsis:
  302. Class i_wszClassName is returned in o_ppClass if found.
  303. Arguments: [i_wszClassName] -
  304. [o_ppClass] -
  305. Return Value:
  306. true if found
  307. false otherwise
  308. --*/
  309. {
  310. DBG_ASSERT(o_ppClass != NULL);
  311. HRESULT hr;
  312. hr = g_pDynSch->GetHashClasses()->Wmi_GetByKey(
  313. (LPWSTR)i_wszClassName,
  314. o_ppClass);
  315. if(SUCCEEDED(hr))
  316. {
  317. return true;
  318. }
  319. else
  320. {
  321. return false;
  322. }
  323. }
  324. bool CUtils::GetMethod(
  325. LPCWSTR i_wszMethod,
  326. WMI_METHOD** i_apMethodList,
  327. WMI_METHOD** o_ppMethod
  328. )
  329. /*++
  330. Synopsis:
  331. The Method descriptor for i_wszMethod is returned via o_ppMethod if found
  332. Arguments: [i_wszMethod] -
  333. [i_apMethodList] -
  334. [o_ppMethod] -
  335. Return Value:
  336. true if found.
  337. false otherwise.
  338. --*/
  339. {
  340. DBG_ASSERT(i_wszMethod != NULL);
  341. DBG_ASSERT(o_ppMethod != NULL);
  342. WMI_METHOD** ppmethod;
  343. if(i_apMethodList == NULL)
  344. {
  345. return false;
  346. }
  347. for (ppmethod = i_apMethodList; *ppmethod != NULL;ppmethod++)
  348. {
  349. if (_wcsicmp(i_wszMethod,(*ppmethod)->pszMethodName) ==0)
  350. {
  351. *o_ppMethod = *ppmethod;
  352. return true;
  353. }
  354. }
  355. return false;
  356. }
  357. HRESULT CUtils::ConstructObjectPath(
  358. LPCWSTR i_wszMbPath,
  359. const WMI_CLASS* i_pClass,
  360. BSTR* o_pbstrPath)
  361. {
  362. DBG_ASSERT(i_wszMbPath != NULL);
  363. DBG_ASSERT(i_pClass != NULL);
  364. DBG_ASSERT(o_pbstrPath != NULL);
  365. DBG_ASSERT(*o_pbstrPath == NULL);
  366. CComBSTR sbstrPath;
  367. ULONG cchPrefix = wcslen(i_pClass->pszMetabaseKey);
  368. DBG_ASSERT(cchPrefix <= wcslen(i_wszMbPath));
  369. LPCWSTR wszSuffix = &i_wszMbPath[cchPrefix];
  370. if(wszSuffix[0] == L'/')
  371. {
  372. wszSuffix++;
  373. }
  374. sbstrPath = i_pClass->pszClassName;
  375. if(sbstrPath.m_str == NULL)
  376. {
  377. return WBEM_E_OUT_OF_MEMORY;
  378. }
  379. sbstrPath += L"='";
  380. if(sbstrPath.m_str == NULL)
  381. {
  382. return WBEM_E_OUT_OF_MEMORY;
  383. }
  384. sbstrPath += wszSuffix;
  385. if(sbstrPath.m_str == NULL)
  386. {
  387. return WBEM_E_OUT_OF_MEMORY;
  388. }
  389. sbstrPath += L"'";
  390. if(sbstrPath.m_str == NULL)
  391. {
  392. return WBEM_E_OUT_OF_MEMORY;
  393. }
  394. *o_pbstrPath = sbstrPath.Detach();
  395. return S_OK;
  396. }
  397. void CUtils::GetMetabasePath(
  398. IWbemClassObject* io_pObj,
  399. ParsedObjectPath* i_pParsedObjectPath,
  400. WMI_CLASS* i_pClass,
  401. _bstr_t& io_bstrPath)
  402. /*++
  403. Synopsis:
  404. Populates io_bstrPath and sets the key field in IWbemClassObject
  405. Arguments: [io_pObj] -
  406. [i_pParsedObjectPath] -
  407. [i_pClass] -
  408. [io_bstrPath] -
  409. --*/
  410. {
  411. KeyRef* pkr;
  412. LPWSTR wszWmiKey = i_pClass->pszKeyName;
  413. DBG_ASSERT(i_pParsedObjectPath != NULL);
  414. DBG_ASSERT(i_pClass != NULL);
  415. DBG_ASSERT(wszWmiKey != NULL);
  416. DBG_ASSERT(i_pClass->pszMetabaseKey != NULL);
  417. pkr = GetKey(i_pParsedObjectPath, wszWmiKey);
  418. DBG_ASSERT(pkr != NULL);
  419. if (io_pObj)
  420. {
  421. _bstr_t bstr;
  422. if(pkr->m_pName == NULL)
  423. {
  424. bstr = wszWmiKey;
  425. }
  426. else
  427. {
  428. bstr = pkr->m_pName;
  429. }
  430. HRESULT hr = io_pObj->Put(bstr, 0, &pkr->m_vValue, 0);
  431. THROW_ON_ERROR(hr);
  432. }
  433. io_bstrPath = i_pClass->pszMetabaseKey;
  434. switch ((pkr)->m_vValue.vt)
  435. {
  436. case VT_I4:
  437. {
  438. WCHAR wszBuf[32] = {0};
  439. io_bstrPath += L"/";
  440. io_bstrPath += _itow(pkr->m_vValue.lVal, wszBuf, 10);
  441. break;
  442. }
  443. case VT_BSTR:
  444. {
  445. io_bstrPath += L"/";
  446. io_bstrPath += pkr->m_vValue.bstrVal;
  447. break;
  448. }
  449. }
  450. return;
  451. }
  452. HRESULT CUtils::GetParentMetabasePath(
  453. LPCWSTR i_wszChildPath,
  454. LPWSTR io_wszParentPath)
  455. /*++
  456. Synopsis:
  457. Eg. /LM/w3svc/1 => /LM/w3svc/
  458. / => E_FAIL
  459. Arguments: [i_wszChildPath] -
  460. [io_wszParentPath] - Should be allocated by caller to at least same
  461. size as i_wszChildPath.
  462. Return Value:
  463. E_FAIL
  464. S_OK
  465. --*/
  466. {
  467. DBG_ASSERT(i_wszChildPath != NULL);
  468. DBG_ASSERT(io_wszParentPath != NULL);
  469. ULONG cchChildPath = wcslen(i_wszChildPath);
  470. BOOL bParentFound = false;
  471. //
  472. // This should trim all the ending L'/'
  473. //
  474. while(cchChildPath > 0 && i_wszChildPath[cchChildPath-1] == L'/')
  475. {
  476. cchChildPath--;
  477. }
  478. if(cchChildPath <= 1)
  479. {
  480. //
  481. // does not have a parent
  482. //
  483. return E_FAIL;
  484. }
  485. for(LONG i = cchChildPath-1; i >= 0; i--)
  486. {
  487. if(i_wszChildPath[i] == L'/')
  488. {
  489. bParentFound = true;
  490. break;
  491. }
  492. }
  493. if(!bParentFound)
  494. {
  495. return E_FAIL;
  496. }
  497. memcpy(io_wszParentPath, i_wszChildPath, (i+1)*sizeof(WCHAR));
  498. io_wszParentPath[i+1] = L'\0';
  499. return S_OK;
  500. }
  501. void CUtils::Throw_Exception(
  502. HRESULT a_hr,
  503. METABASE_PROPERTY* a_pmbp
  504. )
  505. {
  506. CIIsProvException t_e;
  507. t_e.SetHR(a_hr, a_pmbp->pszPropName);
  508. throw(t_e);
  509. }
  510. //
  511. // io_wszDateTime should be allocated outside with 30 elements
  512. //
  513. void CUtils::FileTimeToWchar(FILETIME *i_pFileTime, LPWSTR io_wszDateTime)
  514. {
  515. DBG_ASSERT(i_pFileTime != NULL);
  516. DBG_ASSERT(io_wszDateTime != NULL);
  517. SYSTEMTIME systime;
  518. if(FileTimeToSystemTime(i_pFileTime, &systime) == 0)
  519. {
  520. THROW_ON_ERROR(HRESULT_FROM_WIN32(GetLastError()));
  521. }
  522. swprintf(
  523. io_wszDateTime,
  524. L"%04d%02d%02d%02d%02d%02d.%06d+000",
  525. systime.wYear,
  526. systime.wMonth,
  527. systime.wDay,
  528. systime.wHour,
  529. systime.wMinute,
  530. systime.wSecond,
  531. systime.wMilliseconds
  532. );
  533. }
  534. //
  535. // Below this line, added by Mohit
  536. //
  537. HRESULT CUtils::CreateEmptyMethodInstance(
  538. CWbemServices* i_pNamespace,
  539. IWbemContext* i_pCtx,
  540. LPCWSTR i_wszClassName,
  541. LPCWSTR i_wszMethodName,
  542. IWbemClassObject** o_ppMethodInstance)
  543. /*++
  544. Synopsis:
  545. Generally used when executing a WMI method that has out parameters.
  546. Arguments:
  547. --*/
  548. {
  549. DBG_ASSERT(i_pNamespace != NULL);
  550. DBG_ASSERT(i_pCtx != NULL);
  551. DBG_ASSERT(i_wszClassName != NULL);
  552. DBG_ASSERT(i_wszMethodName != NULL);
  553. DBG_ASSERT(o_ppMethodInstance != NULL);
  554. CComPtr<IWbemClassObject> spClass;
  555. CComPtr<IWbemClassObject> spMethodClass;
  556. CComPtr<IWbemClassObject> spMethodInstance;
  557. HRESULT hr = S_OK;
  558. hr = i_pNamespace->GetObject(_bstr_t(i_wszClassName), 0, i_pCtx, &spClass, NULL);
  559. if(FAILED(hr))
  560. {
  561. goto exit;
  562. }
  563. hr = spClass->GetMethod(i_wszMethodName, 0, NULL, &spMethodClass);
  564. if(FAILED(hr))
  565. {
  566. goto exit;
  567. }
  568. hr = spMethodClass->SpawnInstance(0, &spMethodInstance);
  569. if(FAILED(hr))
  570. {
  571. goto exit;
  572. }
  573. //
  574. // If everything succeeded, set out parameters
  575. //
  576. *o_ppMethodInstance = spMethodInstance;
  577. (*o_ppMethodInstance)->AddRef();
  578. exit:
  579. return hr;
  580. }
  581. HRESULT CUtils::GetQualifiers(
  582. IWbemClassObject* i_pClass,
  583. LPCWSTR* i_awszQualNames,
  584. VARIANT* io_aQualValues,
  585. ULONG i_NrQuals
  586. )
  587. /*++
  588. Synopsis:
  589. Gets Qualifiers.
  590. Arguments: [i_pClass] -
  591. [i_awszQualNames] - An array of size i_NrQuals with names of quals.
  592. [io_aQualValues] - An array of size i_NrQuals with empty variants.
  593. Will be populated on success.
  594. [i_NrQuals] -
  595. --*/
  596. {
  597. DBG_ASSERT(i_pClass != NULL);
  598. DBG_ASSERT(i_awszQualNames != NULL);
  599. DBG_ASSERT(io_aQualValues != NULL);
  600. HRESULT hr = S_OK;
  601. ULONG i = 0;
  602. CComPtr<IWbemQualifierSet> spQualSet = NULL;
  603. hr = i_pClass->GetQualifierSet(&spQualSet);
  604. if(FAILED(hr))
  605. {
  606. goto exit;
  607. }
  608. // Looking for qualifiers
  609. for(i = 0; i < i_NrQuals; i++)
  610. {
  611. DBG_ASSERT(i_awszQualNames[i] != NULL);
  612. hr = spQualSet->Get(i_awszQualNames[i], 0, &io_aQualValues[i], NULL);
  613. if(FAILED(hr) && hr != WBEM_E_NOT_FOUND)
  614. {
  615. break;
  616. }
  617. hr = WBEM_S_NO_ERROR;
  618. }
  619. if(FAILED(hr))
  620. {
  621. for(i = 0; i < i_NrQuals; i++)
  622. {
  623. VariantClear(&io_aQualValues[i]);
  624. }
  625. if(FAILED(hr))
  626. {
  627. goto exit;
  628. }
  629. }
  630. exit:
  631. return hr;
  632. }
  633. HRESULT CUtils::GetPropertyQualifiers(
  634. IWbemClassObject* i_pClass,
  635. LPCWSTR i_wszPropName,
  636. DWORD* io_pdwQuals)
  637. /*++
  638. Synopsis: Unlike SetPropertyQualifiers, this method is specific to this
  639. provider.
  640. Arguments:
  641. --*/
  642. {
  643. DBG_ASSERT(i_pClass != NULL);
  644. DBG_ASSERT(i_wszPropName != NULL);
  645. DBG_ASSERT(io_pdwQuals != NULL);
  646. HRESULT hr = S_OK;
  647. CComPtr<IWbemQualifierSet> spQualSet = NULL;
  648. BSTR bstrQualName = NULL;
  649. VARIANT varQualValue;
  650. VariantInit(&varQualValue);
  651. DWORD dwQuals = 0;
  652. bool bSeenForcePropertyOverwrite = false;
  653. bool bSeenIsDefault = false;
  654. bool bSeenIsInherit = false;
  655. hr = i_pClass->GetPropertyQualifierSet(i_wszPropName, &spQualSet);
  656. if(FAILED(hr))
  657. {
  658. goto exit;
  659. }
  660. // Looking for qualifiers
  661. spQualSet->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
  662. while(!bSeenForcePropertyOverwrite || !bSeenIsDefault || !bSeenIsInherit)
  663. {
  664. hr = spQualSet->Next(0, &bstrQualName, &varQualValue, NULL);
  665. if(hr == WBEM_S_NO_MORE_DATA || FAILED(hr))
  666. {
  667. // No more qualifiers.
  668. // We don't need to worry about cleanup - nothing was allocated.
  669. break;
  670. }
  671. if(!bSeenForcePropertyOverwrite && _wcsicmp(bstrQualName, g_wszForcePropertyOverwrite) == 0)
  672. {
  673. bSeenForcePropertyOverwrite = true;
  674. if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
  675. {
  676. dwQuals |= g_fForcePropertyOverwrite;
  677. }
  678. }
  679. else if(!bSeenIsDefault && _wcsicmp(bstrQualName, g_wszIsDefault) == 0)
  680. {
  681. bSeenIsDefault = true;
  682. if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
  683. {
  684. dwQuals |= g_fIsDefault;
  685. }
  686. }
  687. else if(!bSeenIsInherit && _wcsicmp(bstrQualName, g_wszIsInherit) == 0)
  688. {
  689. bSeenIsInherit = true;
  690. if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
  691. {
  692. dwQuals |= g_fIsInherit;
  693. }
  694. }
  695. SysFreeString(bstrQualName);
  696. VariantClear(&varQualValue);
  697. }
  698. spQualSet->EndEnumeration();
  699. if(FAILED(hr))
  700. {
  701. goto exit;
  702. }
  703. *io_pdwQuals = dwQuals;
  704. exit:
  705. if(hr == WBEM_S_NO_MORE_DATA)
  706. {
  707. hr = WBEM_S_NO_ERROR;
  708. }
  709. return hr;
  710. }
  711. HRESULT CUtils::SetQualifiers(
  712. IWbemClassObject* i_pClass,
  713. LPCWSTR* i_awszQualNames,
  714. VARIANT* i_avtQualValues,
  715. ULONG i_iNrQuals,
  716. ULONG i_iFlags)
  717. {
  718. DBG_ASSERT(i_pClass != NULL);
  719. DBG_ASSERT(i_awszQualNames != NULL);
  720. DBG_ASSERT(i_avtQualValues != NULL);
  721. HRESULT hr = S_OK;
  722. CComPtr<IWbemQualifierSet> spQualSet = NULL;
  723. hr = i_pClass->GetQualifierSet(&spQualSet);
  724. if(FAILED(hr))
  725. {
  726. goto exit;
  727. }
  728. for(ULONG i = 0; i < i_iNrQuals; i++)
  729. {
  730. DBG_ASSERT(i_awszQualNames[i] != NULL);
  731. hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i], i_iFlags);
  732. if(FAILED(hr))
  733. {
  734. goto exit;
  735. }
  736. }
  737. exit:
  738. return hr;
  739. }
  740. HRESULT CUtils::SetMethodQualifiers(
  741. IWbemClassObject* i_pClass,
  742. LPCWSTR i_wszMethName,
  743. LPCWSTR* i_awszQualNames,
  744. VARIANT* i_avtQualValues,
  745. ULONG i_iNrQuals)
  746. {
  747. DBG_ASSERT(i_pClass != NULL);
  748. DBG_ASSERT(i_wszMethName != NULL);
  749. DBG_ASSERT(i_awszQualNames != NULL);
  750. DBG_ASSERT(i_avtQualValues != NULL);
  751. HRESULT hr = WBEM_S_NO_ERROR;
  752. CComPtr<IWbemQualifierSet> spQualSet;
  753. hr = i_pClass->GetMethodQualifierSet(i_wszMethName, &spQualSet);
  754. if(FAILED(hr))
  755. {
  756. goto exit;
  757. }
  758. for(ULONG i = 0; i < i_iNrQuals; i++)
  759. {
  760. DBG_ASSERT(i_awszQualNames[i] != NULL);
  761. hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i],
  762. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE);
  763. if(FAILED(hr))
  764. {
  765. goto exit;
  766. }
  767. }
  768. exit:
  769. return hr;
  770. }
  771. HRESULT CUtils::SetPropertyQualifiers(
  772. IWbemClassObject* i_pClass,
  773. LPCWSTR i_wszPropName,
  774. LPCWSTR* i_awszQualNames,
  775. VARIANT* i_avtQualValues,
  776. ULONG i_iNrQuals)
  777. /*++
  778. Synopsis:
  779. Arguments: [i_pClass] -
  780. [i_wszPropName] -
  781. [i_awszQualNames] -
  782. [i_avtQualValues] -
  783. [i_iNrQuals] -
  784. --*/
  785. {
  786. DBG_ASSERT(i_pClass != NULL);
  787. DBG_ASSERT(i_wszPropName != NULL);
  788. DBG_ASSERT(i_awszQualNames != NULL);
  789. DBG_ASSERT(i_avtQualValues != NULL);
  790. HRESULT hr = S_OK;
  791. CComPtr<IWbemQualifierSet> spQualSet = NULL;
  792. hr = i_pClass->GetPropertyQualifierSet(i_wszPropName, &spQualSet);
  793. if(FAILED(hr))
  794. {
  795. goto exit;
  796. }
  797. for(ULONG i = 0; i < i_iNrQuals; i++)
  798. {
  799. DBG_ASSERT(i_awszQualNames[i] != NULL);
  800. hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i],
  801. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE);
  802. if(FAILED(hr))
  803. {
  804. goto exit;
  805. }
  806. }
  807. exit:
  808. return hr;
  809. }
  810. HRESULT CUtils::CreateEmptyInstance(
  811. LPWSTR i_wszClass,
  812. CWbemServices* i_pNamespace,
  813. IWbemClassObject** o_ppInstance)
  814. /*++
  815. Synopsis:
  816. Creates an IWbemClassObject populated with default values.
  817. Arguments: [i_wszClass] -
  818. [i_pNamespace] -
  819. [o_ppInstance] - Must Release() if this function succeeds.
  820. --*/
  821. {
  822. DBG_ASSERT(i_wszClass != NULL);
  823. DBG_ASSERT(i_pNamespace != NULL);
  824. DBG_ASSERT(o_ppInstance != NULL);
  825. HRESULT hr = S_OK;
  826. CComPtr<IWbemClassObject> spClass;
  827. CComPtr<IWbemClassObject> spInstance;
  828. hr = i_pNamespace->GetObject(
  829. i_wszClass,
  830. 0,
  831. NULL,
  832. &spClass,
  833. NULL);
  834. if(FAILED(hr))
  835. {
  836. goto exit;
  837. }
  838. hr = spClass->SpawnInstance(0, &spInstance);
  839. if(FAILED(hr))
  840. {
  841. goto exit;
  842. }
  843. *o_ppInstance = spInstance;
  844. (*o_ppInstance)->AddRef();
  845. exit:
  846. return hr;
  847. }
  848. void CUtils::MessageCodeToText(
  849. DWORD i_dwMC,
  850. va_list* i_pArgs,
  851. BSTR* o_pbstrText)
  852. /*++
  853. Synopsis:
  854. Arguments: [i_dwMC] -
  855. [i_pArgs] - Can be NULL
  856. [o_pbstrText] - Needs to be freed by caller
  857. --*/
  858. {
  859. DBG_ASSERT(o_pbstrText != NULL);
  860. *o_pbstrText = NULL;
  861. LPVOID lpMsgBuf = NULL;
  862. DWORD dwRet = FormatMessageW(
  863. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
  864. g_hModule,
  865. i_dwMC,
  866. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  867. (LPWSTR) &lpMsgBuf,
  868. 0,
  869. i_pArgs);
  870. if(dwRet == 0)
  871. {
  872. DBG_ASSERT(lpMsgBuf == NULL);
  873. }
  874. CComBSTR sbstrOut;
  875. if(lpMsgBuf != NULL)
  876. {
  877. //
  878. // If out of memory, sbstrOut will be NULL. This is okay.
  879. //
  880. sbstrOut = (LPWSTR)lpMsgBuf;
  881. //
  882. // Free the buffer.
  883. //
  884. LocalFree( lpMsgBuf );
  885. }
  886. //
  887. // Set out parameter
  888. //
  889. *o_pbstrText = sbstrOut.Detach();
  890. }
  891. void CUtils::HRToText(
  892. HRESULT i_hr,
  893. BSTR* o_pbstrText)
  894. {
  895. DBG_ASSERT(o_pbstrText != NULL);
  896. CComPtr<IWbemStatusCodeText> spStatus;
  897. *o_pbstrText = NULL;
  898. i_hr = HRESULT_FROM_WIN32(i_hr);
  899. if(HRESULT_FACILITY(i_hr) == FACILITY_INTERNET)
  900. {
  901. MessageCodeToText(i_hr, NULL, o_pbstrText);
  902. return;
  903. }
  904. HRESULT hr = CoCreateInstance(
  905. CLSID_WbemStatusCodeText,
  906. 0,
  907. CLSCTX_INPROC_SERVER,
  908. IID_IWbemStatusCodeText,
  909. (LPVOID *) &spStatus);
  910. CComBSTR sbstrError = NULL;
  911. CComBSTR sbstrFacility = NULL;
  912. if(SUCCEEDED(hr))
  913. {
  914. spStatus->GetErrorCodeText(i_hr, 0, 0, &sbstrError); // ignore hr
  915. spStatus->GetFacilityCodeText(i_hr, 0, 0, &sbstrFacility); // ignore hr
  916. }
  917. CComBSTR sbstrFullError = NULL;
  918. if(sbstrError != NULL && sbstrFacility != NULL)
  919. {
  920. sbstrFullError = sbstrFacility;
  921. sbstrFullError += L": ";
  922. sbstrFullError += sbstrError; // sbstrFullError may be NULL in low mem -- okay
  923. }
  924. else if(sbstrError != NULL)
  925. {
  926. sbstrFullError = sbstrError; // sbstrFullError may be NULL in low mem -- okay
  927. }
  928. else if(sbstrFacility != NULL)
  929. {
  930. sbstrFullError = sbstrFacility; // sbstrFullError may be NULL in low mem -- okay
  931. }
  932. *o_pbstrText = sbstrFullError.Detach();
  933. }