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.

890 lines
15 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // CopyRight ( c ) 1999 Microsoft Corporation
  4. //
  5. // Module Name: objectpath.cpp
  6. //
  7. // Description:
  8. // Implementation of CObjectpath and other utility class
  9. //
  10. // Author:
  11. // Henry Wang ( henrywa ) March 8, 2000
  12. //
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #include "DnsWmi.h"
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CPropertyValue::~CPropertyValue()
  20. {
  21. VariantClear(&m_PropValue);
  22. }
  23. CPropertyValue::CPropertyValue()
  24. {
  25. VariantInit(&m_PropValue);
  26. }
  27. CPropertyValue::CPropertyValue(
  28. const CPropertyValue& pv)
  29. {
  30. m_Operator = pv.m_Operator;
  31. m_PropName = pv.m_PropName;
  32. VariantInit(&m_PropValue);
  33. VariantCopy(
  34. &m_PropValue,
  35. (VARIANT*)&pv.m_PropValue
  36. );
  37. }
  38. CPropertyValue&
  39. CPropertyValue::operator =(
  40. const CPropertyValue& pv)
  41. {
  42. m_Operator = pv.m_Operator;
  43. m_PropName = pv.m_PropName;
  44. VariantInit(&m_PropValue);
  45. VariantCopy(
  46. &m_PropValue,
  47. (VARIANT*)&pv.m_PropValue
  48. );
  49. return *this;
  50. }
  51. CObjPath::CObjPath()
  52. {
  53. }
  54. CObjPath::CObjPath(
  55. const CObjPath& op)
  56. {
  57. m_Class = op.m_Class;
  58. m_NameSpace = op.m_NameSpace;
  59. m_Server = op.m_Server;
  60. m_PropList = op.m_PropList;
  61. }
  62. CObjPath::~CObjPath()
  63. {
  64. }
  65. wstring
  66. CObjPath::GetStringValueForProperty(
  67. const WCHAR* str
  68. )
  69. {
  70. list<CPropertyValue>::iterator i;
  71. for(i=m_PropList.begin(); i!= m_PropList.end(); ++i)
  72. {
  73. if( _wcsicmp(
  74. (*i).m_PropName.data(),
  75. str) == 0
  76. )
  77. {
  78. if( i->m_PropValue.vt == VT_BSTR)
  79. return i->m_PropValue.bstrVal;
  80. }
  81. }
  82. return L"";
  83. }
  84. wstring
  85. CObjPath::GetClassName(void)
  86. {
  87. return m_Class;
  88. }
  89. BOOL
  90. CObjPath::Init(
  91. const WCHAR* szObjPath
  92. )
  93. {
  94. BOOL flag = TRUE;
  95. CPropertyValue* pObjPV=NULL;
  96. BSTR bstrInput = SysAllocString(szObjPath);
  97. CObjectPathParser objParser(e_ParserAcceptRelativeNamespace);
  98. ParsedObjectPath* pParsed = NULL;
  99. objParser.Parse(bstrInput, &pParsed);
  100. SysFreeString(bstrInput);
  101. if( pParsed == NULL)
  102. {
  103. return FALSE;
  104. }
  105. SetClass(pParsed->m_pClass);
  106. WORD wKeyCount = pParsed->m_dwNumKeys;
  107. for(DWORD i = 0; i < wKeyCount; i++)
  108. {
  109. KeyRef* pKeyRef = pParsed->m_paKeys[i];
  110. AddProperty(
  111. pKeyRef->m_pName,
  112. &(pKeyRef->m_vValue)
  113. );
  114. }
  115. delete pParsed;
  116. return TRUE;
  117. }
  118. BOOL
  119. CObjPath::SetClass(
  120. const WCHAR *wszValue
  121. )
  122. {
  123. m_Class = wszValue;
  124. return TRUE;
  125. }
  126. BOOL
  127. CObjPath::SetNameSpace(
  128. const WCHAR *wszValue
  129. )
  130. {
  131. m_NameSpace = wszValue;
  132. return TRUE;
  133. }
  134. BOOL
  135. CObjPath::SetServer(
  136. const WCHAR *wszValue)
  137. {
  138. m_Server = wszValue;
  139. return TRUE;
  140. }
  141. BOOL
  142. CObjPath::SetProperty(
  143. const WCHAR* wszName,
  144. const WCHAR* wszValue)
  145. {
  146. list<CPropertyValue>::iterator i;
  147. for(i=m_PropList.begin(); i!= m_PropList.end(); ++i)
  148. {
  149. if ( _wcsicmp( (*i).m_PropName.data() , wszName ) == 0)
  150. {
  151. m_PropList.erase(i);
  152. break;
  153. }
  154. }
  155. return AddProperty(wszName, wszValue);
  156. }
  157. BOOL
  158. CObjPath::AddProperty(
  159. const WCHAR * wszName,
  160. const WCHAR * wszValue
  161. )
  162. {
  163. CPropertyValue pv;
  164. pv.m_PropName = wszName;
  165. pv.m_Operator = L"=";
  166. pv.m_PropValue.vt = VT_BSTR;
  167. pv.m_PropValue.bstrVal = SysAllocString(wszValue);
  168. m_PropList.insert(m_PropList.end(), pv);
  169. return TRUE;
  170. }
  171. BOOL CObjPath::AddProperty(
  172. const WCHAR * wszName,
  173. string & strValue
  174. )
  175. {
  176. wstring wstrValue = CharToWstring(strValue.data(), strValue.length());
  177. AddProperty(wszName, wstrValue.data());
  178. return TRUE;
  179. }
  180. wstring
  181. CObjPath::GetObjectPathString()
  182. {
  183. list<CPropertyValue>::iterator i;
  184. ParsedObjectPath parsed;
  185. parsed.SetClassName(GetClassName().data());
  186. for(i=m_PropList.begin(); i!= m_PropList.end(); ++i)
  187. {
  188. parsed.AddKeyRefEx(i->m_PropName.data(), &(i->m_PropValue));
  189. }
  190. LPWSTR pwszPath;
  191. CObjectPathParser::Unparse(&parsed, &pwszPath);
  192. wstring wstrResult = pwszPath;
  193. delete [] pwszPath;
  194. return wstrResult;
  195. }
  196. BOOL
  197. CObjPath::AddProperty(
  198. const WCHAR * wszName,
  199. VARIANT * pvValue
  200. )
  201. {
  202. CPropertyValue pvObj;
  203. pvObj.m_PropName = wszName;
  204. pvObj.m_Operator = L"=";
  205. VariantCopy(&pvObj.m_PropValue, pvValue);
  206. m_PropList.insert(m_PropList.end(), pvObj);
  207. return TRUE;
  208. }
  209. BOOL
  210. CObjPath::AddProperty(
  211. const WCHAR * wszName,
  212. WORD wValue
  213. )
  214. {
  215. VARIANT v;
  216. VariantInit(&v);
  217. v.vt = VT_I2;
  218. v.iVal = wValue;
  219. AddProperty(wszName, &v);
  220. VariantClear(&v);
  221. return TRUE;
  222. }
  223. BOOL
  224. CObjPath::GetNumericValueForProperty(
  225. const WCHAR * wszName,
  226. WORD * wValue
  227. )
  228. {
  229. list<CPropertyValue>::iterator i;
  230. for(i=m_PropList.begin(); i!= m_PropList.end(); ++i)
  231. {
  232. if( _wcsicmp((*i).m_PropName.data(), wszName) == 0)
  233. {
  234. if(i->m_PropValue.vt == VT_I4)
  235. {
  236. *wValue = i->m_PropValue.iVal;
  237. return TRUE;
  238. }
  239. }
  240. }
  241. return FALSE;
  242. }
  243. CDomainNode::CDomainNode()
  244. {
  245. }
  246. CDomainNode::~CDomainNode()
  247. {
  248. }
  249. CDomainNode::CDomainNode(
  250. const CDomainNode& rhs)
  251. {
  252. wstrZoneName = rhs.wstrZoneName;
  253. wstrNodeName = rhs.wstrNodeName;
  254. wstrChildName = rhs.wstrChildName;
  255. }
  256. CDnsProvException::CDnsProvException():m_dwCode(0)
  257. {
  258. }
  259. CDnsProvException::CDnsProvException(const char* psz, DWORD dwCode)
  260. {
  261. m_strError = psz;
  262. m_dwCode = dwCode;
  263. }
  264. CDnsProvException::~CDnsProvException()
  265. {
  266. }
  267. CDnsProvException&
  268. CDnsProvException::operator =(
  269. const CDnsProvException& rhs)
  270. {
  271. m_strError = rhs.m_strError;
  272. m_dwCode = rhs.m_dwCode;
  273. return *this;
  274. }
  275. const
  276. char*
  277. CDnsProvException::what() const
  278. {
  279. return m_strError.data();
  280. }
  281. DWORD
  282. CDnsProvException::GetErrorCode()
  283. {
  284. return m_dwCode;
  285. }
  286. CDnsProvException::CDnsProvException(
  287. const CDnsProvException& rhs)
  288. {
  289. m_strError = rhs.m_strError;
  290. m_dwCode = rhs.m_dwCode;
  291. }
  292. CDnsProvSetValueException::CDnsProvSetValueException()
  293. {
  294. }
  295. CDnsProvSetValueException::~CDnsProvSetValueException()
  296. {
  297. }
  298. CDnsProvSetValueException::CDnsProvSetValueException(
  299. const WCHAR* pwz)
  300. {
  301. string temp;
  302. WcharToString(pwz, temp);
  303. m_strError = "Fail to set value of " + temp;
  304. }
  305. CDnsProvSetValueException::CDnsProvSetValueException(
  306. const CDnsProvSetValueException &rhs)
  307. {
  308. m_strError = rhs.m_strError;
  309. }
  310. CDnsProvSetValueException&
  311. CDnsProvSetValueException::operator =(
  312. const CDnsProvSetValueException &rhs)
  313. {
  314. m_strError = rhs.m_strError;
  315. return *this;
  316. }
  317. CDnsProvGetValueException::CDnsProvGetValueException()
  318. {
  319. }
  320. CDnsProvGetValueException::~CDnsProvGetValueException()
  321. {
  322. }
  323. CDnsProvGetValueException::CDnsProvGetValueException(
  324. const WCHAR* pwz)
  325. {
  326. string temp;
  327. WcharToString(pwz, temp);
  328. m_strError = "Fail to get value of " + temp;
  329. }
  330. CDnsProvGetValueException::CDnsProvGetValueException(
  331. const CDnsProvGetValueException &rhs)
  332. {
  333. m_strError = rhs.m_strError;
  334. }
  335. CDnsProvGetValueException&
  336. CDnsProvGetValueException::operator =(
  337. const CDnsProvGetValueException &rhs)
  338. {
  339. m_strError = rhs.m_strError;
  340. return *this;
  341. }
  342. // CWbemClassObject
  343. CWbemClassObject::CWbemClassObject()
  344. :m_pClassObject(NULL)
  345. {
  346. VariantInit(&m_v);
  347. }
  348. CWbemClassObject::CWbemClassObject(
  349. IWbemClassObject* pInst )
  350. :m_pClassObject(NULL)
  351. {
  352. m_pClassObject = pInst;
  353. if(m_pClassObject)
  354. m_pClassObject->AddRef();
  355. VariantInit(&m_v);
  356. }
  357. CWbemClassObject::~CWbemClassObject()
  358. {
  359. if(m_pClassObject)
  360. m_pClassObject->Release();
  361. VariantClear(&m_v);
  362. }
  363. IWbemClassObject**
  364. CWbemClassObject::operator&()
  365. {
  366. return &m_pClassObject;
  367. }
  368. SCODE
  369. CWbemClassObject::SetProperty(
  370. DWORD dwValue,
  371. LPCWSTR wszPropName
  372. )
  373. {
  374. SCODE sc;
  375. VariantClear(&m_v);
  376. m_v.vt = VT_I4;
  377. m_v.lVal = dwValue;
  378. BSTR bstrName = AllocBstr(wszPropName);
  379. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  380. SysFreeString(bstrName);
  381. if( sc != S_OK)
  382. {
  383. CDnsProvSetValueException e(wszPropName);
  384. throw e;
  385. }
  386. return sc;
  387. }
  388. SCODE
  389. CWbemClassObject::SetProperty(
  390. UCHAR ucValue,
  391. LPCWSTR wszPropName
  392. )
  393. {
  394. SCODE sc;
  395. VariantClear(&m_v);
  396. m_v.vt = VT_UI1;
  397. m_v.bVal = ucValue;
  398. BSTR bstrName = AllocBstr(wszPropName);
  399. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  400. SysFreeString(bstrName);
  401. if( sc != S_OK)
  402. {
  403. CDnsProvSetValueException e(wszPropName);
  404. throw e;
  405. }
  406. return sc;
  407. }
  408. SCODE
  409. CWbemClassObject::SetProperty(
  410. LPCWSTR pszValue,
  411. LPCWSTR wszPropName
  412. )
  413. {
  414. SCODE sc;
  415. VariantClear(&m_v);
  416. if(!pszValue)
  417. return 0;
  418. m_v.vt = VT_BSTR;
  419. m_v.bstrVal = AllocBstr(pszValue);
  420. BSTR bstrName = AllocBstr(wszPropName);
  421. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  422. VariantClear(&m_v);
  423. SysFreeString(bstrName);
  424. if( sc != S_OK)
  425. {
  426. CDnsProvSetValueException e(wszPropName);
  427. throw e;
  428. }
  429. return sc;
  430. }
  431. SCODE
  432. CWbemClassObject::SetProperty(
  433. wstring & wstrValue,
  434. LPCWSTR wszPropName
  435. )
  436. {
  437. SCODE sc;
  438. VariantClear(&m_v);
  439. if(wstrValue.empty())
  440. return S_OK;
  441. m_v.vt = VT_BSTR;
  442. m_v.bstrVal = AllocBstr(wstrValue.data());
  443. BSTR bstrName = AllocBstr(wszPropName);
  444. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  445. SysFreeString(bstrName);
  446. if( sc != S_OK)
  447. {
  448. CDnsProvSetValueException e(wszPropName);
  449. throw e;
  450. }
  451. return sc;
  452. }
  453. SCODE
  454. CWbemClassObject::SetProperty(
  455. SAFEARRAY * psa,
  456. LPCWSTR wszPropName
  457. )
  458. {
  459. SCODE sc;
  460. VariantClear(&m_v);
  461. m_v.vt = (VT_ARRAY |VT_BSTR);
  462. m_v.parray = psa;
  463. BSTR bstrName = AllocBstr(wszPropName);
  464. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  465. SysFreeString(bstrName);
  466. if( sc != S_OK)
  467. {
  468. CDnsProvSetValueException e(wszPropName);
  469. throw e;
  470. }
  471. return sc;
  472. }
  473. SCODE
  474. CWbemClassObject::SetProperty(
  475. DWORD * pdwValue,
  476. DWORD dwSize,
  477. LPCWSTR wszPropName
  478. )
  479. {
  480. SCODE sc;
  481. VariantClear(&m_v);
  482. SAFEARRAY * psa;
  483. SAFEARRAYBOUND rgsabound[1];
  484. rgsabound[0].lLbound = 0;
  485. rgsabound[0].cElements = dwSize;
  486. try
  487. {
  488. psa = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  489. if(psa == NULL)
  490. {
  491. throw WBEM_E_OUT_OF_MEMORY;
  492. }
  493. for(int i=0; i< dwSize; i++)
  494. {
  495. BSTR bstrIP = AllocBstr(
  496. IpAddressToString(pdwValue[i]).data());
  497. LONG ix = i;
  498. sc = SafeArrayPutElement(
  499. psa,
  500. &ix,
  501. bstrIP);
  502. SysFreeString(bstrIP);
  503. if( sc != S_OK)
  504. throw sc;
  505. }
  506. m_v.vt = (VT_ARRAY |VT_BSTR);
  507. m_v.parray = psa;
  508. BSTR bstrName = AllocBstr(wszPropName);
  509. sc = m_pClassObject->Put(bstrName, 0, &m_v,0);
  510. SysFreeString(bstrName);
  511. if( sc != S_OK)
  512. {
  513. CDnsProvSetValueException e(wszPropName);
  514. throw e;
  515. }
  516. }
  517. catch(...)
  518. {
  519. if(psa != NULL)
  520. SafeArrayDestroy(psa);
  521. throw ;
  522. }
  523. return WBEM_S_NO_ERROR;
  524. }
  525. SCODE
  526. CWbemClassObject::SetProperty(
  527. LPCSTR pszValue,
  528. LPCWSTR wszPropName
  529. )
  530. {
  531. if(pszValue == NULL)
  532. return S_OK;
  533. wstring wstrValue = CharToWstring(pszValue, strlen(pszValue));
  534. return SetProperty(wstrValue, wszPropName);
  535. }
  536. SCODE
  537. CWbemClassObject::SpawnInstance(
  538. LONG lFlag,
  539. IWbemClassObject** ppNew)
  540. {
  541. return m_pClassObject->SpawnInstance(lFlag, ppNew);
  542. }
  543. SCODE
  544. CWbemClassObject::GetMethod(
  545. BSTR name,
  546. LONG lFlag,
  547. IWbemClassObject** ppIN,
  548. IWbemClassObject** ppOut
  549. )
  550. {
  551. return m_pClassObject->GetMethod(
  552. name,
  553. lFlag,
  554. ppIN,
  555. ppOut);
  556. }
  557. SCODE
  558. CWbemClassObject::GetProperty(
  559. DWORD * dwValue,
  560. LPCWSTR wszPropName
  561. )
  562. {
  563. SCODE sc;
  564. VariantClear(&m_v);
  565. BSTR bstrPropName = AllocBstr(wszPropName);
  566. sc = m_pClassObject->Get(bstrPropName, 0, &m_v,NULL, NULL);
  567. SysFreeString(bstrPropName);
  568. if(sc == S_OK)
  569. {
  570. if(m_v.vt == VT_I4)
  571. {
  572. *dwValue = m_v.lVal;
  573. return sc;
  574. }
  575. else if (m_v.vt == VT_BOOL)
  576. {
  577. if (m_v.boolVal == VARIANT_TRUE)
  578. *dwValue = 1;
  579. else
  580. *dwValue = 0;
  581. return sc;
  582. }
  583. else if(m_v.vt == VT_UI1)
  584. {
  585. *dwValue = (DWORD) m_v.bVal;
  586. }
  587. else if (m_v.vt == VT_NULL)
  588. {
  589. return WBEM_E_FAILED;
  590. }
  591. }
  592. // raise exception if sc is not S_OK or vt is not expected
  593. CDnsProvGetValueException e(wszPropName);
  594. throw e;
  595. return WBEM_E_FAILED;
  596. }
  597. SCODE
  598. CWbemClassObject::GetProperty(
  599. wstring & wsStr,
  600. LPCWSTR wszPropName
  601. )
  602. {
  603. SCODE sc;
  604. VariantClear(&m_v);
  605. BSTR bstrPropName = AllocBstr(wszPropName);
  606. sc = m_pClassObject->Get(bstrPropName, 0, &m_v,NULL, NULL);
  607. SysFreeString(bstrPropName);
  608. if(sc == S_OK)
  609. {
  610. if(m_v.vt == VT_BSTR)
  611. {
  612. wsStr = m_v.bstrVal;
  613. return sc;
  614. }
  615. else if(m_v.vt == VT_NULL)
  616. {
  617. return WBEM_E_FAILED;
  618. }
  619. }
  620. CDnsProvGetValueException e(wszPropName);
  621. throw e;
  622. return WBEM_E_FAILED;
  623. }
  624. SCODE
  625. CWbemClassObject::GetProperty(
  626. string & strStr,
  627. LPCWSTR wszPropName
  628. )
  629. {
  630. SCODE sc;
  631. VariantClear(&m_v);
  632. BSTR bstrPropName = AllocBstr(wszPropName);
  633. sc = m_pClassObject->Get(bstrPropName, 0, &m_v,NULL, NULL);
  634. SysFreeString(bstrPropName);
  635. if( sc == S_OK)
  636. {
  637. if(m_v.vt == VT_BSTR)
  638. {
  639. char* temp=NULL;
  640. WcharToChar(m_v.bstrVal, &temp);
  641. strStr = temp;
  642. delete [] temp;
  643. return sc;
  644. }
  645. else if (m_v.vt == VT_NULL)
  646. {
  647. return WBEM_E_FAILED;
  648. }
  649. }
  650. // exception
  651. CDnsProvGetValueException e(wszPropName);
  652. throw e;
  653. return WBEM_E_FAILED;
  654. }
  655. SCODE
  656. CWbemClassObject::GetProperty(
  657. BOOL * bValue,
  658. LPCWSTR szPropName
  659. )
  660. {
  661. SCODE sc;
  662. VariantClear(&m_v);
  663. BSTR bstrPropName = AllocBstr(szPropName);
  664. sc = m_pClassObject->Get(bstrPropName, 0, &m_v,NULL, NULL);
  665. SysFreeString(bstrPropName);
  666. if(m_v.vt == VT_BOOL)
  667. {
  668. *bValue = m_v.boolVal;
  669. return sc;
  670. }
  671. return WBEM_E_FAILED;
  672. }
  673. SCODE
  674. CWbemClassObject::GetProperty(
  675. DWORD ** ppValue,
  676. DWORD * dwSize,
  677. LPCWSTR szPropName
  678. )
  679. {
  680. SCODE sc;
  681. VariantClear(&m_v);
  682. BSTR bstrPropName = AllocBstr(szPropName);
  683. sc = m_pClassObject->Get(bstrPropName, 0, &m_v, NULL, NULL);
  684. SysFreeString(bstrPropName);
  685. *dwSize = 0;
  686. if(m_v.vt == (VT_ARRAY |VT_BSTR) && m_v.vt != VT_NULL)
  687. {
  688. SAFEARRAY* psa;
  689. sc = SafeArrayCopy(m_v.parray, &psa);
  690. if(sc == S_OK)
  691. {
  692. *dwSize = psa->rgsabound[0].cElements;
  693. *ppValue = new DWORD[*dwSize];
  694. if ( *ppValue )
  695. {
  696. BSTR* pbstr;
  697. sc = SafeArrayAccessData(psa, (void**) &pbstr);
  698. if(sc != S_OK)
  699. {
  700. delete [] *ppValue;
  701. throw sc;
  702. }
  703. for(LONG i = 0; i < *dwSize; i++)
  704. {
  705. //CHAR* pChar
  706. string str;
  707. WcharToString(pbstr[i], str);
  708. (*ppValue)[i] = inet_addr(str.data());
  709. }
  710. }
  711. else
  712. {
  713. sc = E_OUTOFMEMORY;
  714. }
  715. return sc;
  716. }
  717. }
  718. return WBEM_E_FAILED;
  719. }
  720. SCODE
  721. CWbemClassObject::GetProperty(
  722. DWORD Value[],
  723. DWORD *dwSize,
  724. LPCWSTR szPropName
  725. )
  726. {
  727. SCODE sc;
  728. VariantClear(&m_v);
  729. BSTR bstrPropName = AllocBstr(szPropName);
  730. sc = m_pClassObject->Get(bstrPropName, 0, &m_v,NULL, NULL);
  731. SysFreeString(bstrPropName);
  732. if(m_v.vt == (VT_ARRAY |VT_BSTR) && m_v.vt != VT_NULL)
  733. {
  734. SAFEARRAY* psa;
  735. try
  736. {
  737. sc = SafeArrayCopy(m_v.parray, &psa);
  738. if(sc != S_OK)
  739. throw sc;
  740. if(psa->rgsabound[0].cElements > *dwSize)
  741. throw WBEM_E_INVALID_PARAMETER;
  742. *dwSize = psa->rgsabound[0].cElements;
  743. BSTR* pbstr;
  744. sc = SafeArrayAccessData(psa, (void**) &pbstr);
  745. if(sc != S_OK)
  746. throw sc;
  747. for(LONG i = 0; i < *dwSize; i++)
  748. {
  749. //CHAR* pChar
  750. string str;
  751. WcharToString(pbstr[i], str);
  752. Value[i] = inet_addr(str.data());
  753. }
  754. SafeArrayDestroy(psa);
  755. return sc;
  756. }
  757. catch(SCODE sc)
  758. {
  759. SafeArrayDestroy(psa);
  760. throw sc;
  761. }
  762. }
  763. return WBEM_E_FAILED;
  764. }
  765. SCODE
  766. CWbemClassObject::GetProperty(
  767. VARIANT * pv,
  768. LPCWSTR wszPropName
  769. )
  770. {
  771. SCODE sc;
  772. BSTR bstrPropName = AllocBstr(wszPropName);
  773. sc = m_pClassObject->Get(bstrPropName, 0, pv,NULL, NULL);
  774. SysFreeString(bstrPropName);
  775. if(sc != S_OK)
  776. {
  777. CDnsProvGetValueException e(wszPropName);
  778. throw e;
  779. }
  780. return WBEM_S_NO_ERROR;
  781. }