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.

900 lines
24 KiB

  1. //***************************************************************************
  2. //
  3. // VPMTHD.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the PutInstance implementation
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <provcoll.h>
  15. #include <provtempl.h>
  16. #include <provmt.h>
  17. #include <typeinfo.h>
  18. #include <process.h>
  19. #include <objbase.h>
  20. #include <stdio.h>
  21. #include <wbemidl.h>
  22. #include <provcont.h>
  23. #include <provevt.h>
  24. #include <provthrd.h>
  25. #include <provlog.h>
  26. #include <cominit.h>
  27. #include <dsgetdc.h>
  28. #include <lmcons.h>
  29. #include <instpath.h>
  30. #include <genlex.h>
  31. #include <sql_1.h>
  32. #include <objpath.h>
  33. #include <vpdefs.h>
  34. #include <vpquals.h>
  35. #include <vpserv.h>
  36. #include <vptasks.h>
  37. ExecMethodTaskObject :: ExecMethodTaskObject (
  38. CViewProvServ *a_Provider ,
  39. wchar_t *a_ObjectPath ,
  40. wchar_t *a_MethodName,
  41. ULONG a_Flag ,
  42. IWbemClassObject *a_InParams ,
  43. IWbemObjectSink *a_NotificationHandler ,
  44. IWbemContext *pCtx
  45. ) : WbemTaskObject ( a_Provider , a_NotificationHandler , a_Flag , pCtx ) ,
  46. m_InParamObject( a_InParams ), m_OutParamObject ( NULL ),
  47. m_ParsedObjectPath ( NULL ), m_ObjectPath(NULL), m_Method(NULL)
  48. {
  49. if (m_InParamObject != NULL)
  50. {
  51. m_InParamObject->AddRef();
  52. }
  53. m_ObjectPath = UnicodeStringDuplicate(a_ObjectPath);
  54. m_Method = UnicodeStringDuplicate(a_MethodName);
  55. }
  56. ExecMethodTaskObject :: ~ExecMethodTaskObject ()
  57. {
  58. if (m_OutParamObject != NULL)
  59. {
  60. if ( SUCCEEDED(m_ErrorObject.GetWbemStatus ()) )
  61. {
  62. HRESULT t_Result = m_NotificationHandler->Indicate(1, &m_OutParamObject);
  63. }
  64. m_OutParamObject->Release();
  65. }
  66. if (m_InParamObject != NULL)
  67. {
  68. m_InParamObject->Release();
  69. }
  70. delete [] m_ObjectPath ;
  71. delete [] m_Method ;
  72. if (NULL != m_ParsedObjectPath)
  73. {
  74. delete m_ParsedObjectPath;
  75. }
  76. // Get Status object
  77. IWbemClassObject *t_NotifyStatus = NULL ;
  78. BOOL t_Status = TRUE;
  79. if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ())
  80. {
  81. t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus ) ;
  82. }
  83. if ( t_Status )
  84. {
  85. HRESULT t_Result = m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , t_NotifyStatus ) ;
  86. if (t_NotifyStatus)
  87. {
  88. t_NotifyStatus->Release () ;
  89. }
  90. }
  91. else
  92. {
  93. HRESULT t_Result = m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , NULL ) ;
  94. }
  95. }
  96. BOOL ExecMethodTaskObject :: ExecMethod ()
  97. {
  98. DebugOut8(
  99. CViewProvServ::sm_debugLog->WriteFileAndLine (
  100. _T(__FILE__),__LINE__,
  101. _T("ExecMethodTaskObject :: ExecMethod\r\n")
  102. ) ;
  103. )
  104. CObjectPathParser objectPathParser;
  105. BOOL t_Status = ! objectPathParser.Parse ( m_ObjectPath , &m_ParsedObjectPath ) ;
  106. if ( t_Status )
  107. {
  108. t_Status = SetClass(m_ParsedObjectPath->m_pClass) ;
  109. if ( t_Status )
  110. {
  111. IWbemQualifierSet* pQuals = NULL;
  112. BOOL bStatic = FALSE;
  113. //get the method qualifier set so we can determine
  114. //if the method is static...
  115. if ( SUCCEEDED(m_ClassObject->GetMethodQualifierSet(m_Method, &pQuals)) )
  116. {
  117. //get the MethodSources qualifier
  118. VARIANT v;
  119. VariantInit(&v);
  120. if ( SUCCEEDED(pQuals->Get(VIEW_QUAL_STATIC, 0, &v, NULL)) )
  121. {
  122. if (v.vt == VT_BOOL)
  123. {
  124. bStatic = (v.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  125. }
  126. else
  127. {
  128. t_Status = FALSE;
  129. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  130. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  131. m_ErrorObject.SetMessage ( L"Static method qualifier should be boolean." ) ;
  132. }
  133. }
  134. VariantClear(&v);
  135. pQuals->Release();
  136. }
  137. else
  138. {
  139. t_Status = FALSE;
  140. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  141. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  142. m_ErrorObject.SetMessage ( L"Failed to get Method qualifiers" ) ;
  143. }
  144. if (t_Status)
  145. {
  146. t_Status = ParseAndProcessClassQualifiers(m_ErrorObject, bStatic ? NULL : m_ParsedObjectPath);
  147. }
  148. if (t_Status)
  149. {
  150. //only unions
  151. if (m_bAssoc || m_JoinOnArray.IsValid())
  152. {
  153. t_Status = FALSE;
  154. m_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_SUPPORTED ) ;
  155. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  156. m_ErrorObject.SetMessage ( L"Methods only supported for Union views" ) ;
  157. }
  158. }
  159. if (t_Status)
  160. {
  161. LONG t_index = 0;
  162. CStringW t_srcMethod;
  163. BOOL t_bStatic = FALSE;
  164. t_Status = CompareMethods(m_ErrorObject, t_index, t_srcMethod, t_bStatic);
  165. if (t_Status)
  166. {
  167. t_Status = PerformMethod(m_ErrorObject, t_index, t_srcMethod, t_bStatic);
  168. }
  169. }
  170. }
  171. else
  172. {
  173. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  174. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  175. m_ErrorObject.SetMessage ( L"Class definition not found" ) ;
  176. DebugOut8(
  177. CViewProvServ::sm_debugLog->WriteFileAndLine (
  178. _T(__FILE__),__LINE__,
  179. _T("ExecMethodTaskObject :: ExecMethod:Class definition not found\r\n")
  180. ) ;
  181. )
  182. }
  183. }
  184. else
  185. {
  186. t_Status = FALSE ;
  187. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ) ;
  188. m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  189. m_ErrorObject.SetMessage ( L"Unable to parse object path" ) ;
  190. DebugOut8(
  191. CViewProvServ::sm_debugLog->WriteW (
  192. L"ExecMethodTaskObject :: ExecMethod:Unable to parse object path %s\r\n",
  193. m_ObjectPath
  194. ) ;
  195. )
  196. }
  197. DebugOut8(
  198. CViewProvServ::sm_debugLog->WriteFileAndLine (
  199. _T(__FILE__),__LINE__,
  200. _T("leaving ExecMethodTaskObject :: ExecMethod with %lx\r\n"),
  201. t_Status
  202. ) ;
  203. )
  204. return t_Status ;
  205. }
  206. //steps...
  207. //1. Get the method signature and parse it's qualifiers
  208. //2. Get the source method and it's signature
  209. //3. Compare the signatures
  210. //========================================================
  211. BOOL ExecMethodTaskObject::CompareMethods(WbemProvErrorObject &a_ErrorObject, LONG &a_Index,
  212. CStringW &a_SrcMethodName, BOOL &a_bStatic)
  213. {
  214. BOOL retVal = FALSE;
  215. IWbemQualifierSet* pQuals = NULL;
  216. //get the method qualifier set so we can determine
  217. //what the source method for this view method is...
  218. if ( SUCCEEDED(m_ClassObject->GetMethodQualifierSet(m_Method, &pQuals)) )
  219. {
  220. //get the MethodSources qualifier
  221. VARIANT v;
  222. VariantInit(&v);
  223. if ( SUCCEEDED(pQuals->Get(VIEW_QUAL_METHOD, 0, &v, NULL)) )
  224. {
  225. retVal = TRUE;
  226. if (v.vt == VT_BSTR)
  227. {
  228. if (m_SourceArray.GetSize() != 1)
  229. {
  230. retVal = FALSE;
  231. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  232. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  233. a_ErrorObject.SetMessage ( L"MethodSources qualifier should match ViewSources size." ) ;
  234. }
  235. else
  236. {
  237. a_SrcMethodName = v.bstrVal;
  238. }
  239. }
  240. else if (v.vt == (VT_BSTR | VT_ARRAY))
  241. {
  242. if (SafeArrayGetDim(v.parray) == 1)
  243. {
  244. LONG count = v.parray->rgsabound[0].cElements;
  245. BSTR HUGEP *pbstr;
  246. if (m_SourceArray.GetSize() != count)
  247. {
  248. retVal = FALSE;
  249. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  250. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  251. a_ErrorObject.SetMessage ( L"MethodSources qualifier should match ViewSources size." ) ;
  252. }
  253. else
  254. {
  255. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pbstr)) )
  256. {
  257. for (LONG x = 0; x < count; x++)
  258. {
  259. if ((pbstr[x] != NULL) && (*(pbstr[x]) != L'\0'))
  260. {
  261. //only one value should be present
  262. if (a_SrcMethodName.IsEmpty())
  263. {
  264. a_SrcMethodName = pbstr[x];
  265. a_Index = x;
  266. }
  267. else
  268. {
  269. a_SrcMethodName.Empty();
  270. retVal = FALSE;
  271. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  272. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  273. a_ErrorObject.SetMessage ( L"MethodSources qualifier should have only one non-empty value." ) ;
  274. break;
  275. }
  276. }
  277. }
  278. SafeArrayUnaccessData(v.parray);
  279. }
  280. else
  281. {
  282. retVal = FALSE;
  283. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  284. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  285. a_ErrorObject.SetMessage (L"Failed to access MethodSources array.");
  286. }
  287. }
  288. }
  289. else
  290. {
  291. retVal = FALSE;
  292. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  293. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  294. a_ErrorObject.SetMessage (L"MethodSources array qualifier has incorrect dimensions.");
  295. }
  296. }
  297. else
  298. {
  299. retVal = FALSE;
  300. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  301. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  302. a_ErrorObject.SetMessage ( L"MethodSources qualifier has the wrong type." ) ;
  303. }
  304. if (retVal)
  305. {
  306. if (!a_SrcMethodName.IsEmpty())
  307. {
  308. IWbemClassObject* t_SrcObj = m_SourceArray[a_Index]->GetClassObject();
  309. if (t_SrcObj != NULL)
  310. {
  311. IWbemClassObject* pVInParam = NULL;
  312. IWbemClassObject* pVOutParam = NULL;
  313. IWbemClassObject* pSInParam = NULL;
  314. IWbemClassObject* pSOutParam = NULL;
  315. if ( SUCCEEDED(m_ClassObject->GetMethod(m_Method, 0, &pVInParam, &pVOutParam)) )
  316. {
  317. if ( SUCCEEDED(t_SrcObj->GetMethod(a_SrcMethodName, 0, &pSInParam, &pSOutParam)) )
  318. {
  319. //got all the info we need, now compare the signatures...
  320. if ( ((pVInParam == NULL) && (pSInParam != NULL)) ||
  321. ((pVInParam != NULL) && (pSInParam == NULL)) ||
  322. ((pVOutParam == NULL) && (pSOutParam != NULL)) ||
  323. ((pVOutParam != NULL) && (pSOutParam == NULL)) )
  324. {
  325. //signature mismatch
  326. retVal = FALSE;
  327. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_SUPPORTED) ;
  328. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  329. a_ErrorObject.SetMessage ( L"View method signature does not match source method signature." ) ;
  330. }
  331. else
  332. {
  333. if (pSInParam != NULL) //pVInParam is non-null
  334. {
  335. if (WBEM_S_DIFFERENT == pSInParam->CompareTo(WBEM_FLAG_IGNORE_OBJECT_SOURCE |
  336. WBEM_FLAG_IGNORE_DEFAULT_VALUES |
  337. WBEM_FLAG_IGNORE_FLAVOR, pVInParam))
  338. {
  339. //signature mismatch
  340. retVal = FALSE;
  341. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_SUPPORTED) ;
  342. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  343. a_ErrorObject.SetMessage ( L"View method signature does not match source method signature." ) ;
  344. }
  345. }
  346. if (retVal && (pSOutParam != NULL)) //pVOutParam is non-null
  347. {
  348. if (WBEM_S_DIFFERENT == pSOutParam->CompareTo(WBEM_FLAG_IGNORE_OBJECT_SOURCE |
  349. WBEM_FLAG_IGNORE_DEFAULT_VALUES |
  350. WBEM_FLAG_IGNORE_FLAVOR, pVOutParam))
  351. {
  352. //signature mismatch
  353. retVal = FALSE;
  354. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_SUPPORTED) ;
  355. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  356. a_ErrorObject.SetMessage ( L"View method signature does not match source method signature." ) ;
  357. }
  358. }
  359. //check to see that methods are both
  360. //static or both non-static
  361. if (retVal)
  362. {
  363. BOOL t_bViewStatic = FALSE;
  364. BOOL t_bSrcStatic = FALSE;
  365. VARIANT t_vStatic;
  366. VariantInit(&t_vStatic);
  367. if ( SUCCEEDED(pQuals->Get(VIEW_QUAL_STATIC, 0, &t_vStatic, NULL)) )
  368. {
  369. if (t_vStatic.vt == VT_BOOL)
  370. {
  371. t_bViewStatic = (t_vStatic.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  372. }
  373. else
  374. {
  375. retVal = FALSE;
  376. a_ErrorObject.SetStatus (WBEM_PROV_E_TYPE_MISMATCH) ;
  377. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  378. a_ErrorObject.SetMessage ( L"Static qualifier on Method should be boolean" ) ;
  379. }
  380. }
  381. VariantClear(&t_vStatic);
  382. VariantInit(&t_vStatic);
  383. IWbemQualifierSet* t_SrcQuals = NULL;
  384. if ( SUCCEEDED(t_SrcObj->GetMethodQualifierSet(a_SrcMethodName, &t_SrcQuals)) )
  385. {
  386. if ( SUCCEEDED(t_SrcQuals->Get(VIEW_QUAL_STATIC, 0, &t_vStatic, NULL)) )
  387. {
  388. if (t_vStatic.vt == VT_BOOL)
  389. {
  390. t_bSrcStatic = (t_vStatic.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  391. }
  392. else
  393. {
  394. retVal = FALSE;
  395. a_ErrorObject.SetStatus (WBEM_PROV_E_TYPE_MISMATCH) ;
  396. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  397. a_ErrorObject.SetMessage ( L"Static qualifier on Method should be boolean" ) ;
  398. }
  399. }
  400. t_SrcQuals->Release();
  401. }
  402. VariantClear(&t_vStatic);
  403. if (retVal)
  404. {
  405. if ((t_bSrcStatic) && (t_bViewStatic))
  406. {
  407. a_bStatic = TRUE;
  408. }
  409. else if ((!t_bSrcStatic) && (!t_bViewStatic))
  410. {
  411. a_bStatic = FALSE;
  412. }
  413. else
  414. {
  415. retVal = FALSE;
  416. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  417. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  418. a_ErrorObject.SetMessage (L"Both source and view methods must be static or both non-static");
  419. }
  420. }
  421. }
  422. }
  423. }
  424. else
  425. {
  426. retVal = FALSE;
  427. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  428. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  429. a_ErrorObject.SetMessage ( L"Source method could not be found" ) ;
  430. }
  431. }
  432. else
  433. {
  434. retVal = FALSE;
  435. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  436. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  437. a_ErrorObject.SetMessage ( L"View method could not be found" ) ;
  438. }
  439. //release all the signature objects
  440. if (pVInParam != NULL)
  441. {
  442. pVInParam->Release();
  443. }
  444. if (pVOutParam != NULL)
  445. {
  446. if (retVal)
  447. {
  448. if ( FAILED(pVOutParam->SpawnInstance(0, &m_OutParamObject)) )
  449. {
  450. retVal = FALSE;
  451. a_ErrorObject.SetStatus (WBEM_PROV_E_UNEXPECTED) ;
  452. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  453. a_ErrorObject.SetMessage (L"Failed to spawn out parameter");
  454. }
  455. }
  456. pVOutParam->Release();
  457. }
  458. if (pSInParam != NULL)
  459. {
  460. pSInParam->Release();
  461. }
  462. if (pSOutParam != NULL)
  463. {
  464. pSOutParam->Release();
  465. }
  466. //release the source class object
  467. t_SrcObj->Release();
  468. }
  469. else
  470. {
  471. retVal = FALSE;
  472. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  473. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  474. a_ErrorObject.SetMessage (L"Source class not available");
  475. }
  476. }
  477. else
  478. {
  479. retVal = FALSE;
  480. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  481. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  482. a_ErrorObject.SetMessage (L"Source of method not specified in MethodSources qualifier");
  483. }
  484. }
  485. }
  486. else
  487. {
  488. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  489. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  490. a_ErrorObject.SetMessage ( L"MethodSource qualifier is missing" ) ;
  491. }
  492. VariantClear(&v);
  493. pQuals->Release();
  494. }
  495. else
  496. {
  497. a_ErrorObject.SetStatus (WBEM_PROV_E_NOT_FOUND) ;
  498. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_METHOD ) ;
  499. a_ErrorObject.SetMessage ( L"Method or Method qualifiers are missing" ) ;
  500. }
  501. return retVal;
  502. }
  503. //map the object path to the source instance and perform the method
  504. //if static make sure that the object path supplied was a class path.
  505. BOOL ExecMethodTaskObject::PerformMethod(WbemProvErrorObject &a_ErrorObject, LONG a_Index,
  506. CStringW a_SrcMethodName, BOOL a_bStatic)
  507. {
  508. BOOL retVal = FALSE;
  509. int index = 0;
  510. BSTR inst_path = NULL;
  511. if (a_bStatic)
  512. {
  513. //make sure we were passed the class path
  514. if (m_ParsedObjectPath->IsClass())
  515. {
  516. //get the class and make sure there is
  517. //only one namespace associated with it.
  518. if (m_NSpaceArray[a_Index]->GetCount() == 1)
  519. {
  520. retVal = TRUE;
  521. inst_path = SysAllocString(m_SourceArray[a_Index]->GetClassName());
  522. }
  523. else
  524. {
  525. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  526. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  527. a_ErrorObject.SetMessage ( L"Could not resolve path to single namespace for source Static method." ) ;
  528. }
  529. }
  530. else
  531. {
  532. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ) ;
  533. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  534. a_ErrorObject.SetMessage ( L"Static method called with instance rather than class path" ) ;
  535. }
  536. }
  537. else
  538. {
  539. //get the source instance for the view instance
  540. IWbemClassObject* pSrcInst;
  541. inst_path = MapFromView(m_ObjectPath, NULL, &pSrcInst, TRUE);
  542. if (inst_path != NULL)
  543. {
  544. //get the index of the class
  545. VARIANT vCls;
  546. if ( SUCCEEDED(pSrcInst->Get(WBEM_PROPERTY_CLASS, 0, &vCls, NULL, NULL)) )
  547. {
  548. if (vCls.vt == VT_BSTR)
  549. {
  550. if (m_ClassToIndexMap.Lookup(vCls.bstrVal, index))
  551. {
  552. if (a_Index == index)
  553. {
  554. retVal = TRUE;
  555. }
  556. else
  557. {
  558. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  559. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  560. a_ErrorObject.SetMessage ( L"Object path passed resulted in a different class of object to that of the methodsource" ) ;
  561. }
  562. }
  563. else
  564. {
  565. VARIANT vSCls;
  566. VariantInit(&vSCls);
  567. if ( SUCCEEDED(pSrcInst->Get(WBEM_PROPERTY_DERIVATION, 0, &vSCls, NULL, NULL)) )
  568. {
  569. if (vSCls.vt == VT_BSTR)
  570. {
  571. if (m_ClassToIndexMap.Lookup(vSCls.bstrVal, index))
  572. {
  573. if (a_Index == index)
  574. {
  575. retVal = TRUE;
  576. }
  577. else
  578. {
  579. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  580. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  581. a_ErrorObject.SetMessage ( L"Source instance class not found in source list" ) ;
  582. }
  583. }
  584. }
  585. else if (vSCls.vt == (VT_ARRAY | VT_BSTR))
  586. {
  587. if (SafeArrayGetDim(vSCls.parray) == 1)
  588. {
  589. LONG count = vSCls.parray->rgsabound[0].cElements;
  590. BSTR HUGEP *pbstr;
  591. if ( SUCCEEDED(SafeArrayAccessData(vSCls.parray, (void HUGEP**)&pbstr)) )
  592. {
  593. for (LONG x = 0; x < count; x++)
  594. {
  595. if (m_ClassToIndexMap.Lookup(pbstr[x], index))
  596. {
  597. if (a_Index == index)
  598. {
  599. retVal = TRUE;
  600. break;
  601. }
  602. }
  603. }
  604. SafeArrayUnaccessData(vSCls.parray);
  605. if (!retVal)
  606. {
  607. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  608. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  609. a_ErrorObject.SetMessage ( L"Source instance class not found in source list" ) ;
  610. }
  611. }
  612. else
  613. {
  614. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  615. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  616. a_ErrorObject.SetMessage (L"Failed to access __Derivation array.");
  617. }
  618. }
  619. else
  620. {
  621. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  622. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  623. a_ErrorObject.SetMessage (L"__Derivation array qualifier has incorrect dimensions.");
  624. }
  625. }
  626. else
  627. {
  628. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  629. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  630. a_ErrorObject.SetMessage ( L"Source instance has non string __Derivation property" ) ;
  631. }
  632. VariantClear(&vSCls);
  633. }
  634. else
  635. {
  636. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  637. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  638. a_ErrorObject.SetMessage ( L"Source instance has no __Derivation property" ) ;
  639. }
  640. }
  641. }
  642. else
  643. {
  644. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  645. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  646. a_ErrorObject.SetMessage ( L"Source instance has non string __Class property" ) ;
  647. }
  648. VariantClear(&vCls);
  649. }
  650. else
  651. {
  652. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  653. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  654. a_ErrorObject.SetMessage ( L"Source instance has no __Class property" ) ;
  655. }
  656. pSrcInst->Release();
  657. }
  658. else
  659. {
  660. a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ;
  661. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  662. a_ErrorObject.SetMessage ( L"Instance supplied could not be mapped to a single source instance" ) ;
  663. }
  664. }
  665. if (retVal)
  666. {
  667. //Execute the method and indicate the outparams...
  668. //also set the result and we're all done!
  669. //which namespace do we execmethod, try them all until we succeed
  670. CWbemServerWrap** pServs = m_NSpaceArray[index]->GetServerPtrs();
  671. HRESULT hr = WBEM_E_FAILED;
  672. for (UINT i = 0; i < m_NSpaceArray[index]->GetCount(); i++)
  673. {
  674. if (pServs[i] != NULL)
  675. {
  676. IWbemClassObject *t_outparam = NULL;
  677. IWbemServices *ptmpServ = pServs[i]->GetServerOrProxy();
  678. if (ptmpServ)
  679. {
  680. BSTR t_MethName = a_SrcMethodName.AllocSysString();
  681. hr = ptmpServ->ExecMethod(inst_path, t_MethName, 0,
  682. m_Ctx, m_InParamObject,
  683. &t_outparam, NULL);
  684. if ( FAILED(hr) && (HRESULT_FACILITY(hr) != FACILITY_ITF) && pServs[i]->IsRemote())
  685. {
  686. if ( SUCCEEDED(UpdateConnection(&(pServs[i]), &ptmpServ)) )
  687. {
  688. if (ptmpServ)
  689. {
  690. hr = ptmpServ->ExecMethod(inst_path, t_MethName, 0,
  691. m_Ctx, m_InParamObject,
  692. &t_outparam, NULL);
  693. }
  694. }
  695. }
  696. SysFreeString(t_MethName);
  697. if (ptmpServ)
  698. {
  699. pServs[i]->ReturnServerOrProxy(ptmpServ);
  700. }
  701. }
  702. if (SUCCEEDED (hr) )
  703. {
  704. if (m_OutParamObject != NULL)
  705. {
  706. if (t_outparam != NULL)
  707. {
  708. //copy contents of the outparam to view outparam
  709. if ( SUCCEEDED(t_outparam->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)) )
  710. {
  711. BSTR t_propName = NULL;
  712. VARIANT t_propValue;
  713. VariantInit(&t_propValue);
  714. HRESULT t_hr = t_outparam->Next(0, &t_propName, &t_propValue, NULL, NULL);
  715. while (hr == WBEM_S_NO_ERROR)
  716. {
  717. //copy this property
  718. if (SUCCEEDED(hr = m_OutParamObject->Put(t_propName, 0, &t_propValue, NULL)))
  719. {
  720. //get the next property
  721. VariantClear(&t_propValue);
  722. VariantInit(&t_propValue);
  723. SysFreeString(t_propName);
  724. t_propName = NULL;
  725. hr = t_outparam->Next(0, &t_propName, &t_propValue, NULL, NULL);
  726. }
  727. else
  728. {
  729. break;
  730. }
  731. }
  732. VariantClear(&t_propValue);
  733. if (t_propName != NULL)
  734. {
  735. SysFreeString(t_propName);
  736. }
  737. if (FAILED(hr))
  738. {
  739. t_outparam->EndEnumeration();
  740. retVal = FALSE;
  741. }
  742. }
  743. else
  744. {
  745. retVal = FALSE;
  746. }
  747. if (!retVal)
  748. {
  749. m_OutParamObject->Release();
  750. m_OutParamObject = NULL;
  751. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  752. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  753. a_ErrorObject.SetMessage ( L"Source method executed but the view provider failed to copy the out parameter object" ) ;
  754. }
  755. }
  756. else
  757. {
  758. m_OutParamObject->Release();
  759. m_OutParamObject = NULL;
  760. retVal = FALSE;
  761. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  762. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  763. a_ErrorObject.SetMessage ( L"Source method executed without returning the out parameter object" ) ;
  764. }
  765. }
  766. if (t_outparam != NULL)
  767. {
  768. t_outparam->Release();
  769. }
  770. break;
  771. }
  772. }
  773. }
  774. if ( FAILED (hr) )
  775. {
  776. if (m_OutParamObject)
  777. {
  778. m_OutParamObject->Release();
  779. m_OutParamObject = NULL;
  780. }
  781. retVal = FALSE;
  782. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  783. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  784. #ifdef VP_SINGLE_NAMESPACE_TRIED
  785. wchar_t buff[100];
  786. wsprintf(buff, L"ExecMethod with source object failed with code: %lx", hr);
  787. a_ErrorObject.SetMessage ( buff ) ;
  788. #else //VP_SINGLE_NAMESPACE_TRIED
  789. a_ErrorObject.SetMessage ( L"ExecMethod with source object failed" ) ;
  790. #endif //VP_SINGLE_NAMESPACE_TRIED
  791. }
  792. }
  793. if (inst_path != NULL)
  794. {
  795. SysFreeString(inst_path);
  796. }
  797. return retVal;
  798. }