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.

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