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.

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