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.

1602 lines
49 KiB

  1. //***************************************************************************
  2. //
  3. // CLASSPRO.CPP
  4. //
  5. // Module: CDM Provider
  6. //
  7. // Purpose: Defines the CClassPro class. An object of this class is
  8. // created by the class factory for each connection.
  9. //
  10. // Copyright (c) 2000 Microsoft Corporation
  11. //
  12. //***************************************************************************
  13. #include <objbase.h>
  14. #include "sample.h"
  15. #include <process.h>
  16. #include <unknwn.h>
  17. #include "wbemmisc.h"
  18. #include "debug.h"
  19. // @@BEGIN_DDKSPLIT
  20. // TODO: pass down all pCtx so that all calls into wbem use it
  21. // @@END_DDKSPLIT
  22. //
  23. // This is the global list of all of the CDM classes and their
  24. // corresponsing WDM classes that are managed by the provider.
  25. //
  26. // It is maintained as a global since WinMgmt is aggressive in
  27. // releasing the CClassProv, but we really want to maintain the result
  28. // objects and do not want to be unloaded unless all result objects are
  29. // cleared.
  30. //
  31. CTestServices *WdmTestHead;
  32. void CleanupAllTests(
  33. )
  34. {
  35. CTestServices *WdmTest;
  36. CTestServices *WdmTestNext;
  37. //
  38. // Loop over all classes that were supported by the provider and
  39. // clean them up
  40. //
  41. WdmTest = WdmTestHead;
  42. while (WdmTest != NULL)
  43. {
  44. WdmTestNext = WdmTest->GetNext();
  45. delete WdmTest;
  46. }
  47. }
  48. //***************************************************************************
  49. //
  50. // CClassPro::CClassPro
  51. // CClassPro::~CClassPro
  52. //
  53. //***************************************************************************
  54. CClassPro::CClassPro(
  55. BSTR ObjectPath,
  56. BSTR User,
  57. BSTR Password,
  58. IWbemContext * pCtx
  59. )
  60. {
  61. m_pCdmServices = NULL;
  62. m_cRef=0;
  63. InterlockedIncrement(&g_cObj);
  64. return;
  65. }
  66. CClassPro::~CClassPro(void)
  67. {
  68. if(m_pCdmServices)
  69. {
  70. m_pCdmServices->Release();
  71. }
  72. InterlockedDecrement(&g_cObj);
  73. return;
  74. }
  75. //***************************************************************************
  76. //
  77. // CClassPro::QueryInterface
  78. // CClassPro::AddRef
  79. // CClassPro::Release
  80. //
  81. // Purpose: IUnknown members for CClassPro object.
  82. //***************************************************************************
  83. STDMETHODIMP CClassPro::QueryInterface(REFIID riid, PPVOID ppv)
  84. {
  85. HRESULT hr;
  86. *ppv=NULL;
  87. // Since we have dual inheritance, it is necessary to cast the return type
  88. if(riid== IID_IWbemServices)
  89. {
  90. *ppv=(IWbemServices*)this;
  91. }
  92. if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
  93. {
  94. *ppv=(IWbemProviderInit*)this;
  95. }
  96. if (NULL!=*ppv)
  97. {
  98. AddRef();
  99. hr = NOERROR;
  100. }
  101. else {
  102. hr = E_NOINTERFACE;
  103. }
  104. return(hr);
  105. }
  106. STDMETHODIMP_(ULONG) CClassPro::AddRef(void)
  107. {
  108. return(++m_cRef);
  109. }
  110. STDMETHODIMP_(ULONG) CClassPro::Release(void)
  111. {
  112. ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
  113. if (0L == nNewCount)
  114. {
  115. delete this;
  116. }
  117. return(nNewCount);
  118. }
  119. /***********************************************************************
  120. * *
  121. * CClassPro::Initialize *
  122. * *
  123. * Purpose: This is the implementation of IWbemProviderInit. The method *
  124. * is need to initialize with CIMOM. *
  125. * *
  126. ***********************************************************************/
  127. STDMETHODIMP CClassPro::Initialize(LPWSTR pszUser, LONG lFlags,
  128. LPWSTR pszNamespace, LPWSTR pszLocale,
  129. IWbemServices *pNamespace,
  130. IWbemContext *pCtx,
  131. IWbemProviderInitSink *pInitSink)
  132. {
  133. if (pNamespace)
  134. {
  135. pNamespace->AddRef();
  136. }
  137. m_pCdmServices = pNamespace;
  138. //
  139. // Let CIMOM know you are initialized
  140. //
  141. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  142. return(WBEM_S_NO_ERROR);
  143. }
  144. //***************************************************************************
  145. //
  146. // CClassPro::CreateClassEnumAsync
  147. //
  148. // Purpose: Asynchronously enumerates the classes this provider supports.
  149. // Note that this sample only supports one.
  150. //
  151. //***************************************************************************
  152. SCODE CClassPro::CreateClassEnumAsync(
  153. const BSTR Superclass, long lFlags,
  154. IWbemContext *pCtx,
  155. IWbemObjectSink *pHandler
  156. )
  157. {
  158. return(WBEM_E_NOT_SUPPORTED);
  159. }
  160. //***************************************************************************
  161. //
  162. // CClassPro::CreateInstanceEnumAsync
  163. //
  164. // Purpose: Asynchronously enumerates the instances.
  165. //
  166. //***************************************************************************
  167. SCODE CClassPro::CreateInstanceEnumAsync(
  168. const BSTR ClassName,
  169. long lFlags,
  170. IWbemContext *pCtx,
  171. IWbemObjectSink FAR* pHandler
  172. )
  173. {
  174. HRESULT hr, hr2;
  175. ULONG i, Count;
  176. IWbemClassObject *pCdmTest;
  177. CTestServices *WdmTest;
  178. WmipDebugPrint(("CDMPROV: Enumerate instances of class %ws\n",
  179. ClassName));
  180. //
  181. // Do a check of arguments and make sure we have pointer to Namespace
  182. //
  183. if (pHandler == NULL || m_pCdmServices == NULL)
  184. {
  185. return WBEM_E_INVALID_PARAMETER;
  186. }
  187. //
  188. // Plan for success
  189. //
  190. hr = WBEM_S_NO_ERROR;
  191. //
  192. // Obtain a test services object that represents this class
  193. //
  194. hr = LookupTestServices(ClassName,
  195. &WdmTest);
  196. if (hr == WBEM_S_NO_ERROR)
  197. {
  198. if (_wcsicmp(ClassName, WdmTest->GetCdmTestClassName()) == 0)
  199. {
  200. hr = CreateTestInst(WdmTest, &pCdmTest, pCtx);
  201. if (hr == WBEM_S_NO_ERROR)
  202. {
  203. //
  204. // Send the object to the caller
  205. //
  206. hr = pHandler->Indicate(1,&pCdmTest);
  207. pCdmTest->Release();
  208. }
  209. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultClassName()) == 0) {
  210. //
  211. // Loop over all instances of the test and report all results
  212. // that we have previously recorded
  213. //
  214. IWbemClassObject **pCdmResultsList;
  215. ULONG ResultCount, j;
  216. Count = WdmTest->GetInstanceCount();
  217. for (i = 0; (i < Count) && SUCCEEDED(hr); i++)
  218. {
  219. hr2 = WdmTest->GetResultsList(i,
  220. &ResultCount,
  221. &pCdmResultsList);
  222. if ((hr2 == WBEM_S_NO_ERROR) && (pCdmResultsList != NULL))
  223. {
  224. //
  225. // Send the object to the caller
  226. //
  227. hr = pHandler->Indicate(ResultCount, pCdmResultsList);
  228. for (j = 0; j < ResultCount; j++)
  229. {
  230. //
  231. // Release ref taken when results list was
  232. // built
  233. //
  234. pCdmResultsList[j]->Release();
  235. }
  236. WmipFree(pCdmResultsList);
  237. }
  238. }
  239. } else if (_wcsicmp(ClassName, WdmTest->GetCdmSettingClassName()) == 0) {
  240. //
  241. // Return a setting instances for all tests
  242. //
  243. ULONG j, ListCount;
  244. IWbemClassObject *pCdmSetting;
  245. Count = WdmTest->GetInstanceCount();
  246. for (i = 0; (i < Count) && SUCCEEDED(hr); i++)
  247. {
  248. ListCount = WdmTest->GetCdmSettingCount(i);
  249. for (j = 0; (j < ListCount) && SUCCEEDED(hr); j++)
  250. {
  251. pCdmSetting = WdmTest->GetCdmSettingObject(i, j);
  252. if (pCdmSetting != NULL)
  253. {
  254. hr = pHandler->Indicate(1, &pCdmSetting);
  255. // NO release required since object is cached
  256. }
  257. }
  258. }
  259. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultForMSEClassName()) == 0) {
  260. IWbemClassObject **pCdmResultsList;
  261. ULONG ResultCount, j;
  262. IWbemClassObject *pCdmResultForMSE;
  263. Count = WdmTest->GetInstanceCount();
  264. for (i = 0; (i < Count) && SUCCEEDED(hr); i++)
  265. {
  266. hr2 = WdmTest->GetResultsList(i,
  267. &ResultCount,
  268. &pCdmResultsList);
  269. if ((hr2 == WBEM_S_NO_ERROR) && (pCdmResultsList != NULL))
  270. {
  271. for (j = 0; (j < ResultCount); j++)
  272. {
  273. if (SUCCEEDED(hr))
  274. {
  275. //
  276. // for each instance of this test we create a ResultForMSE
  277. // association instance and then set the properties within
  278. // it to the appropriate values and relpaths
  279. hr2 = CreateResultForMSEInst(WdmTest,
  280. &pCdmResultForMSE,
  281. i,
  282. pCdmResultsList[j],
  283. pCtx);
  284. if (hr2 == WBEM_S_NO_ERROR)
  285. {
  286. //
  287. // Send the object to the caller
  288. //
  289. hr = pHandler->Indicate(1, &pCdmResultForMSE);
  290. pCdmResultForMSE->Release();
  291. }
  292. }
  293. pCdmResultsList[j]->Release();
  294. }
  295. WmipFree(pCdmResultsList);
  296. }
  297. }
  298. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultForTestClassName()) == 0) {
  299. IWbemClassObject **pCdmResultsList;
  300. ULONG ResultCount,j;
  301. IWbemClassObject *pCdmResultForTest;
  302. Count = WdmTest->GetInstanceCount();
  303. for (i = 0; (i < Count) && SUCCEEDED(hr); i++)
  304. {
  305. hr2 = WdmTest->GetResultsList(i,
  306. &ResultCount,
  307. &pCdmResultsList);
  308. if ((hr2 == WBEM_S_NO_ERROR) && (pCdmResultsList != NULL))
  309. {
  310. for (j = 0; (j < ResultCount); j++)
  311. {
  312. if (SUCCEEDED(hr))
  313. {
  314. //
  315. // DiagnosticResult is a reference to the CIM_Diagnostic result class
  316. //
  317. hr2 = CreateResultForTestInst(WdmTest,
  318. &pCdmResultForTest,
  319. pCdmResultsList[j],
  320. pCtx);
  321. if (hr2 == WBEM_S_NO_ERROR)
  322. {
  323. //
  324. // Send the object to the caller
  325. //
  326. hr = pHandler->Indicate(1,&pCdmResultForTest);
  327. pCdmResultForTest->Release();
  328. }
  329. }
  330. pCdmResultsList[j]->Release();
  331. }
  332. WmipFree(pCdmResultsList);
  333. }
  334. }
  335. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestForMSEClassName()) == 0) {
  336. //
  337. // Here we create the associations between tests and MSE
  338. //
  339. IWbemClassObject *pCdmTestForMSE;
  340. Count = WdmTest->GetInstanceCount();
  341. for (i = 0; i < Count; i++)
  342. {
  343. //
  344. // for each instance of this test we create a TestForMSE
  345. // association instance and then set the properties within
  346. // it to the appropriate values and relpaths
  347. hr2 = CreateTestForMSEInst(WdmTest,
  348. &pCdmTestForMSE,
  349. i,
  350. pCtx);
  351. if (hr2 == WBEM_S_NO_ERROR)
  352. {
  353. //
  354. // Send the object to the caller
  355. //
  356. hr = pHandler->Indicate(1, &pCdmTestForMSE);
  357. pCdmTestForMSE->Release();
  358. }
  359. }
  360. } else if (_wcsicmp(ClassName, WdmTest->GetCdmSettingForTestClassName()) == 0) {
  361. //
  362. // Return all settings instances for this test
  363. //
  364. ULONG j, ListCount;
  365. IWbemClassObject *pCdmSettingForTest;
  366. Count = WdmTest->GetInstanceCount();
  367. for (i = 0; (i < Count) && SUCCEEDED(hr); i++)
  368. {
  369. ListCount = WdmTest->GetCdmSettingCount(i);
  370. for (j = 0; (j < ListCount) && SUCCEEDED(hr); j++)
  371. {
  372. hr2 = CreateSettingForTestInst(WdmTest,
  373. &pCdmSettingForTest,
  374. i,
  375. j,
  376. pCtx);
  377. if (hr2 == WBEM_S_NO_ERROR)
  378. {
  379. pHandler->Indicate(1, &pCdmSettingForTest);
  380. pCdmSettingForTest->Release();
  381. }
  382. }
  383. }
  384. #if 0 // Not supported
  385. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestForSoftwareClassName()) == 0) {
  386. //
  387. // We do not support this
  388. //
  389. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestInPackageClassName()) == 0) {
  390. //
  391. // We do not support packages
  392. //
  393. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultInPackageClassName()) == 0) {
  394. //
  395. // We do not support packages
  396. //
  397. #endif
  398. } else {
  399. //
  400. // Is this the right thing to do if we do not know what the
  401. // class name is
  402. //
  403. hr = WBEM_S_NO_ERROR;
  404. }
  405. }
  406. //
  407. // TODO: Create extended error object with more info about the
  408. // error that occured. The object is created by
  409. // CreateInst("__ExtendedStatus")
  410. //
  411. pHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  412. return(hr);
  413. }
  414. //***************************************************************************
  415. //
  416. // CClassPro::GetObjectByPathAsync
  417. //
  418. // Purpose: Returns either an instance or a class.
  419. //
  420. //***************************************************************************
  421. SCODE CClassPro::GetObjectAsync(
  422. const BSTR ObjectPath,
  423. long lFlags,
  424. IWbemContext *pCtx,
  425. IWbemObjectSink FAR* pHandler
  426. )
  427. {
  428. HRESULT hr;
  429. IWbemClassObject FAR* pObj;
  430. // Do a check of arguments and make sure we have pointer to Namespace
  431. if(ObjectPath == NULL || pHandler == NULL || m_pCdmServices == NULL)
  432. {
  433. return WBEM_E_INVALID_PARAMETER;
  434. }
  435. hr = GetByPath(ObjectPath,&pObj, pCtx);
  436. if (hr == WBEM_S_NO_ERROR)
  437. {
  438. WmipDebugPrint(("CDMProv: Found instance %p for relpath %ws\n",
  439. pObj, ObjectPath));
  440. hr = pHandler->Indicate(1,&pObj);
  441. pObj->Release();
  442. } else {
  443. WmipDebugPrint(("CDMProv: Did not find instance for relpath %ws\n",
  444. ObjectPath));
  445. hr = WBEM_E_NOT_FOUND;
  446. }
  447. // Set Status
  448. pHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  449. return(hr);
  450. }
  451. //***************************************************************************
  452. //
  453. // CClassPro::GetByPath
  454. //
  455. // Purpose: Creates an instance given a particular Path value.
  456. //
  457. // All objects returned are assumed to be AddRefed
  458. //
  459. //***************************************************************************
  460. HRESULT CClassPro::GetByPath(
  461. BSTR ObjectPath,
  462. IWbemClassObject **ppObj,
  463. IWbemContext *pCtx
  464. )
  465. {
  466. HRESULT hr = WBEM_S_NO_ERROR;
  467. WCHAR ClassName[MAX_PATH+1];
  468. WCHAR *p;
  469. int iNumQuotes = 0;
  470. int i, Count;
  471. CTestServices *WdmTest;
  472. BSTR s;
  473. //
  474. // This is where we are queried for a class based upon its relpath.
  475. // We need to parse the relpath to get the class name and then look
  476. // at the relpath to determine which instance of the class we are
  477. // interested in and then build up the instance and return it
  478. //
  479. //
  480. // Relpaths created at init
  481. //
  482. // Sample_Filter_DiagTest.Name="Sample_Filter_DiagTest"
  483. // Sample_Filter_DiagTestForMSE.Antecedent="Win32_USBController.DeviceID=\"PCI\\\\VEN_8086&DEV_7112&SUBSYS_00000000&REV_01\\\\2&EBB567F&0&3A\"",Dependent="Sample_Filter_DiagTest.Name=\"Sample_Filter_DiagTest\""
  484. //
  485. //
  486. // Relpaths created at method execute
  487. //
  488. // Sample_Filter_DiagResult.DiagnosticCreationClassName="MSSample_DiagnosticTest.InstanceName=\"PCI\\\\VEN_8086&DEV_7112&SUBSYS_00000000&REV_01\\\\2&ebb567f&0&3A_0\"",DiagnosticName="Sample_Filter_DiagTest",ExecutionID="0"
  489. // Sample_Filter_DiagResultForMSE.Result="Sample_Filter_DiagResult.DiagnosticCreationClassName=\"MSSample_DiagnosticTest.InstanceName=\\\"PCI\\\\\\\\VEN_8086&DEV_7112&SUBSYS_00000000&REV_01\\\\\\\\2&ebb567f&0&3A_0\\\"\",DiagnosticName=\"Sample_Filter_DiagTest\",ExecutionID=\"0\"",SystemElement="Win32_USBController.DeviceID=\"PCI\\\\VEN_8086&DEV_7112&SUBSYS_00000000&REV_01\\\\2&EBB567F&0&3A\""
  490. // Sample_Filter_DiagResultForTest.DiagnosticResult="Sample_Filter_DiagResult.DiagnosticCreationClassName=\"MSSample_DiagnosticTest.InstanceName=\\\"PCI\\\\\\\\VEN_8086&DEV_7112&SUBSYS_00000000&REV_01\\\\\\\\2&ebb567f&0&3A_0\\\"\",DiagnosticName=\"Sample_Filter_DiagTest\",ExecutionID=\"0\"",DiagnosticTest="Sample_Filter_DiagTest.Name=\"Sample_Filter_DiagTest\""
  491. //
  492. // Obtain the class name by copying up to the .
  493. //
  494. for (p = ObjectPath, i = 0;
  495. (*p != 0) && (*p != L'.') && (i < MAX_PATH);
  496. p++, i++)
  497. {
  498. ClassName[i] = *p;
  499. }
  500. if (*p != L'.')
  501. {
  502. //
  503. // If we did end our loop with a . then we failed to parse
  504. // properly
  505. //
  506. WmipDebugPrint(("CDMPROV: Unable to parse relpath %ws at %ws, i = %d\n",
  507. ObjectPath, p, i));
  508. }
  509. ClassName[i] = 0;
  510. WmipDebugPrint(("CDMPROV: Class %ws looking for relpath %ws\n",
  511. ClassName, ObjectPath));
  512. //
  513. // Obtain a test services object that represents this class
  514. //
  515. hr = LookupTestServices(ClassName,
  516. &WdmTest);
  517. if (hr == WBEM_S_NO_ERROR)
  518. {
  519. //
  520. // Assume that we will not find the object instance
  521. //
  522. hr = WBEM_E_NOT_FOUND;
  523. if (_wcsicmp(ClassName, WdmTest->GetCdmTestClassName()) == 0)
  524. {
  525. //
  526. // This is a CdmTest class object instance
  527. //
  528. #ifdef VERBOSE_DEBUG
  529. WmipDebugPrint(("CDMPROV: Compareing \n%ws\n\nwith\n%ws\n\n",
  530. ObjectPath, WdmTest->GetCdmTestRelPath()));
  531. #endif
  532. if (_wcsicmp(ObjectPath, WdmTest->GetCdmTestRelPath()) == 0)
  533. {
  534. hr = CreateTestInst(WdmTest, ppObj, pCtx);
  535. }
  536. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultClassName()) == 0) {
  537. //
  538. // This is a CdmResult class object instance
  539. //
  540. IWbemClassObject *pCdmResult;
  541. Count = WdmTest->GetInstanceCount();
  542. for (i = 0; i < Count; i++)
  543. {
  544. hr = WdmTest->GetCdmResultByResultRelPath(i,
  545. ObjectPath,
  546. &pCdmResult);
  547. if (hr == WBEM_S_NO_ERROR)
  548. {
  549. *ppObj = pCdmResult;
  550. break;
  551. }
  552. }
  553. } else if (_wcsicmp(ClassName, WdmTest->GetCdmSettingClassName()) == 0) {
  554. //
  555. // This is a CDM settings class instnace
  556. //
  557. ULONG j, ListCount;
  558. IWbemClassObject *pCdmSetting;
  559. Count = WdmTest->GetInstanceCount();
  560. for (i = 0; i < Count; i++)
  561. {
  562. ListCount = WdmTest->GetCdmSettingCount(i);
  563. for (j = 0; j < ListCount; j++)
  564. {
  565. s = WdmTest->GetCdmSettingRelPath(i, j);
  566. #ifdef VERBOSE_DEBUG
  567. WmipDebugPrint(("CDMPROV: Compareing \n%ws\n\nwith\n%ws\n\n",
  568. ObjectPath, s));
  569. #endif
  570. if (_wcsicmp(ObjectPath,
  571. s) == 0)
  572. {
  573. pCdmSetting = WdmTest->GetCdmSettingObject(i, j);
  574. pCdmSetting->AddRef();
  575. *ppObj = pCdmSetting;
  576. hr = WBEM_S_NO_ERROR;
  577. break;
  578. }
  579. }
  580. }
  581. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultForMSEClassName()) == 0) {
  582. //
  583. // This is a CDM result for MSE class instance
  584. //
  585. IWbemClassObject *pCdmResult;
  586. Count = WdmTest->GetInstanceCount();
  587. for (i = 0; i < Count; i++)
  588. {
  589. hr = WdmTest->GetCdmResultByResultForMSERelPath(i,
  590. ObjectPath,
  591. &pCdmResult);
  592. if (hr == WBEM_S_NO_ERROR)
  593. {
  594. hr = CreateResultForMSEInst(WdmTest,
  595. ppObj,
  596. i,
  597. pCdmResult,
  598. pCtx);
  599. pCdmResult->Release();
  600. break;
  601. }
  602. }
  603. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultForTestClassName()) == 0) {
  604. IWbemClassObject *pCdmResult;
  605. Count = WdmTest->GetInstanceCount();
  606. for (i = 0; i < Count; i++)
  607. {
  608. hr = WdmTest->GetCdmResultByResultForTestRelPath(i,
  609. ObjectPath,
  610. &pCdmResult);
  611. if (hr == WBEM_S_NO_ERROR)
  612. {
  613. hr = CreateResultForTestInst(WdmTest,
  614. ppObj,
  615. pCdmResult,
  616. pCtx);
  617. pCdmResult->Release();
  618. break;
  619. }
  620. }
  621. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestForMSEClassName()) == 0) {
  622. //
  623. // TestForMSE class object
  624. //
  625. Count = WdmTest->GetInstanceCount();
  626. for (i = 0; i < Count; i++)
  627. {
  628. #ifdef VERBOSE_DEBUG
  629. WmipDebugPrint(("CDMPROV: Compareing \n%ws\n\nwith\n%ws\n\n",
  630. ObjectPath, WdmTest->GetCdmTestForMSERelPath(i)));
  631. #endif
  632. if (_wcsicmp(ObjectPath,
  633. WdmTest->GetCdmTestForMSERelPath(i)) == 0)
  634. {
  635. hr = CreateTestForMSEInst(WdmTest,
  636. ppObj,
  637. i,
  638. pCtx);
  639. break;
  640. }
  641. }
  642. } else if (_wcsicmp(ClassName, WdmTest->GetCdmSettingForTestClassName()) == 0) {
  643. //
  644. // This is a CDM settings for test class instnace
  645. //
  646. ULONG j, ListCount;
  647. Count = WdmTest->GetInstanceCount();
  648. for (i = 0; i < Count; i++)
  649. {
  650. ListCount = WdmTest->GetCdmSettingCount(i);
  651. for (j = 0; j < ListCount; j++)
  652. {
  653. s = WdmTest->GetCdmSettingForTestRelPath(i, j);
  654. #ifdef VERBOSE_DEBUG
  655. WmipDebugPrint(("CDMPROV: Compareing \n%ws\n\nwith\n%ws\n\n",
  656. ObjectPath, s));
  657. #endif
  658. if (_wcsicmp(ObjectPath,
  659. s) == 0)
  660. {
  661. hr = CreateSettingForTestInst(WdmTest,
  662. ppObj,
  663. i,
  664. j,
  665. pCtx);
  666. break;
  667. }
  668. }
  669. }
  670. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestForSoftwareClassName()) == 0) {
  671. //
  672. // We do not support this
  673. //
  674. } else if (_wcsicmp(ClassName, WdmTest->GetCdmTestInPackageClassName()) == 0) {
  675. //
  676. // We do not support packages
  677. //
  678. } else if (_wcsicmp(ClassName, WdmTest->GetCdmResultInPackageClassName()) == 0) {
  679. //
  680. // We do not support packages
  681. //
  682. }
  683. }
  684. return(hr);
  685. }
  686. /************************************************************************
  687. * *
  688. *CMethodPro::ExecMethodAsync *
  689. * *
  690. *Purpose: This is the Async function implementation. *
  691. * The only method supported in this sample is named Echo. It *
  692. * takes an input string, copies it to the output and returns the*
  693. * length. *
  694. * *
  695. * *
  696. ************************************************************************/
  697. STDMETHODIMP CClassPro::ExecMethodAsync(
  698. const BSTR ObjectPath,
  699. const BSTR MethodName,
  700. long lFlags,
  701. IWbemContext* pCtx,
  702. IWbemClassObject* pInParams,
  703. IWbemObjectSink* pResultSink
  704. )
  705. {
  706. HRESULT hr, hrDontCare;
  707. IWbemClassObject * pMethodClass = NULL;
  708. IWbemClassObject * pOutClass = NULL;
  709. IWbemClassObject* pOutParams = NULL;
  710. WCHAR ClassName[MAX_PATH];
  711. WCHAR *p;
  712. VARIANT v, vRetVal;
  713. int RelPathIndex;
  714. CTestServices *WdmTest;
  715. BSTR ExecutionID;
  716. VariantInit(&v);
  717. VariantInit(&vRetVal);
  718. //
  719. // Extract this class name from the object path
  720. //
  721. wcscpy(ClassName, ObjectPath);
  722. p = ClassName;
  723. while ((*p != 0) && (*p != L'.'))
  724. {
  725. p++;
  726. }
  727. *p = 0;
  728. WmipDebugPrint(("CDMPROV: Exec method %ws for instanec %ws\n",
  729. MethodName, ObjectPath));
  730. //
  731. // Obtain a test services object that represents this class
  732. //
  733. hr = LookupTestServices(ClassName,
  734. &WdmTest);
  735. if (hr != WBEM_S_NO_ERROR)
  736. {
  737. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  738. return(WBEM_S_NO_ERROR);
  739. }
  740. //
  741. // Get the input parameter SystemElement which is the Cim Relative
  742. // Path
  743. //
  744. hr = WmiGetProperty(pInParams,
  745. L"SystemElement",
  746. CIM_REFERENCE,
  747. &v);
  748. if (hr != WBEM_S_NO_ERROR)
  749. {
  750. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  751. return(WBEM_S_NO_ERROR);
  752. }
  753. //
  754. // Find the relpath index that matches the Cim Path
  755. //
  756. hr = WdmTest->GetRelPathIndex(v.bstrVal,
  757. &RelPathIndex);
  758. VariantClear(&v);
  759. if (hr != WBEM_S_NO_ERROR)
  760. {
  761. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  762. return(WBEM_S_NO_ERROR);
  763. }
  764. //
  765. // Get our class object for the method so we can set the output
  766. // parameters
  767. //
  768. hr = m_pCdmServices->GetObject(ClassName, 0, pCtx, &pMethodClass, NULL);
  769. if (hr != S_OK)
  770. {
  771. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  772. return(WBEM_S_NO_ERROR);
  773. }
  774. //
  775. // These methods returns values, and so create an instance of the
  776. // output argument class.
  777. hr = pMethodClass->GetMethod(MethodName, 0, NULL, &pOutClass);
  778. if (hr != S_OK)
  779. {
  780. pMethodClass->Release();
  781. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  782. return(WBEM_S_NO_ERROR);
  783. }
  784. hr = pOutClass->SpawnInstance(0, &pOutParams);
  785. pOutClass->Release();
  786. pMethodClass->Release();
  787. if (hr != WBEM_S_NO_ERROR)
  788. {
  789. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  790. return(WBEM_S_NO_ERROR);
  791. }
  792. //
  793. // See what method we are being called on and deal with it
  794. //
  795. if (_wcsicmp(MethodName, L"RunTest") == 0)
  796. {
  797. //
  798. // Run test
  799. //
  800. // uint16 RunTest([IN] CIM_ManagedSystemElement ref SystemElement,
  801. // [IN] DiagnosticSetting ref Setting,
  802. // [OUT] CIM_DiagnosticResult ref Result);
  803. //
  804. IWbemClassObject *pCdmSettings;
  805. IWbemClassObject *pCdmResult;
  806. ULONG Result;
  807. VARIANT vSettingRelPath;
  808. VARIANT vResult;
  809. //
  810. // Get the settings for the test by first getting the
  811. // relpath for them and then getting the actual object
  812. //
  813. hr = WmiGetProperty(pInParams,
  814. L"Setting",
  815. CIM_REFERENCE,
  816. &vSettingRelPath);
  817. if (hr == WBEM_S_NO_ERROR)
  818. {
  819. if (vSettingRelPath.vt != VT_NULL)
  820. {
  821. hr = m_pCdmServices->GetObject(vSettingRelPath.bstrVal,
  822. WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  823. NULL,
  824. &pCdmSettings,
  825. NULL);
  826. } else {
  827. pCdmSettings = NULL;
  828. }
  829. VariantClear(&vSettingRelPath);
  830. if (hr == WBEM_S_NO_ERROR)
  831. {
  832. //
  833. // Create an empty instance of the results
  834. // class which will get filled in when the test
  835. // is run
  836. //
  837. hr = CreateInst(m_pCdmServices,
  838. &pCdmResult,
  839. WdmTest->GetCdmResultClassName(),
  840. NULL);
  841. if (hr == WBEM_S_NO_ERROR)
  842. {
  843. //
  844. // Setup the test starting time
  845. //
  846. v.vt = VT_BSTR;
  847. v.bstrVal = GetCurrentDateTime();
  848. hr = WmiSetProperty(pCdmResult,
  849. L"TestStartTime",
  850. &v);
  851. VariantClear(&v);
  852. if (hr == WBEM_S_NO_ERROR)
  853. {
  854. //
  855. // Go and get the Wdm test run and the
  856. // results copied back into our cdm class
  857. //
  858. hr = WdmTest->ExecuteWdmTest(pCdmSettings,
  859. pCdmResult,
  860. RelPathIndex,
  861. &Result,
  862. &ExecutionID);
  863. if (hr == WBEM_S_NO_ERROR)
  864. {
  865. //
  866. // Fill in any additional properties
  867. // for the result object
  868. //
  869. hr = WdmTest->FillInCdmResult(pCdmResult,
  870. pCdmSettings,
  871. RelPathIndex,
  872. ExecutionID);
  873. if (hr == WBEM_S_NO_ERROR)
  874. {
  875. //
  876. // return result as an output pointer
  877. //
  878. hr = WmiGetProperty(pCdmResult,
  879. L"__RelPath",
  880. CIM_STRING,
  881. &vResult);
  882. if (hr == WBEM_S_NO_ERROR)
  883. {
  884. hr = WmiSetProperty(pOutParams,
  885. L"Result",
  886. &vResult);
  887. if (hr == WBEM_S_NO_ERROR)
  888. {
  889. // @@BEGIN_DDKSPLIT
  890. // We'll do this when we support reboot diags and
  891. // keeping results after reboot
  892. #if 0
  893. //
  894. // Persist the result
  895. // object into the schema
  896. // for later access
  897. //
  898. hr = WdmTest->PersistResultInSchema(pCdmResult,
  899. ExecutionID,
  900. RelPathIndex);
  901. #endif
  902. // @@END_DDKSPLIT
  903. if (hr == WBEM_S_NO_ERROR)
  904. {
  905. //
  906. // Include the relpath
  907. // to the result
  908. // object to our
  909. // internal list
  910. hr = WdmTest->AddResultToList(pCdmResult,
  911. ExecutionID,
  912. RelPathIndex
  913. );
  914. if (hr == WBEM_S_NO_ERROR)
  915. {
  916. //
  917. // Setup a return value of success
  918. //
  919. vRetVal.vt = VT_I4;
  920. vRetVal.lVal = Result;
  921. }
  922. }
  923. }
  924. VariantClear(&vResult);
  925. }
  926. }
  927. SysFreeString(ExecutionID);
  928. }
  929. }
  930. pCdmResult->Release();
  931. }
  932. if (pCdmSettings != NULL)
  933. {
  934. pCdmSettings->Release();
  935. }
  936. }
  937. }
  938. } else if (_wcsicmp(MethodName, L"ClearResults") == 0) {
  939. //
  940. // Clear the results for the test
  941. //
  942. // uint32 ClearResults([IN] CIM_ManagedSystemElement ref SystemElement,
  943. // [OUT] String ResultsNotCleared[]);
  944. //
  945. VARIANT vResultsNotCleared;
  946. //
  947. // Clear all results for this test
  948. //
  949. WdmTest->ClearResultsList(RelPathIndex);
  950. //
  951. // Setup the output parameter
  952. //
  953. VariantInit(&vResultsNotCleared);
  954. vResultsNotCleared.vt = VT_BSTR;
  955. vResultsNotCleared.bstrVal = NULL;
  956. WmiSetProperty(pOutParams,
  957. L"ResultsNotCleared",
  958. &vResultsNotCleared);
  959. VariantClear(&vResultsNotCleared);
  960. //
  961. // Setup a return value of success
  962. //
  963. vRetVal.vt = VT_I4;
  964. vRetVal.ulVal = 0;
  965. } else if (_wcsicmp(MethodName, L"DiscontinueTest") == 0) {
  966. //
  967. // Discontinue a test in progress.
  968. //
  969. // uint32 DiscontinueTest([IN] CIM_ManagedSystemElement ref SystemElement,
  970. // [IN] CIM_DiagnosticResult ref Result,
  971. // [OUT] Boolean TestingStopped);
  972. //
  973. BOOLEAN TestingStopped;
  974. ULONG Result;
  975. VARIANT vTestingStopped;
  976. hr = WdmTest->StopWdmTest(RelPathIndex,
  977. &Result,
  978. &TestingStopped);
  979. //
  980. // Setup the output parameter
  981. //
  982. if (hr == WBEM_S_NO_ERROR)
  983. {
  984. VariantInit(&vTestingStopped);
  985. vTestingStopped.vt = VT_BOOL;
  986. vTestingStopped.boolVal = TestingStopped ? VARIANT_TRUE :
  987. VARIANT_FALSE;
  988. WmiSetProperty(pOutParams,
  989. L"TestingStopped",
  990. &vTestingStopped);
  991. VariantClear(&vTestingStopped);
  992. //
  993. // Setup a return value of result
  994. //
  995. vRetVal.vt = VT_I4;
  996. vRetVal.ulVal = Result;
  997. }
  998. } else {
  999. hr = WBEM_E_INVALID_PARAMETER;
  1000. }
  1001. if (hr == WBEM_S_NO_ERROR)
  1002. {
  1003. //
  1004. // Establish the return value for the method call
  1005. //
  1006. WmiSetProperty(pOutParams,
  1007. L"ReturnValue",
  1008. &vRetVal);
  1009. VariantClear(&vRetVal);
  1010. // Send the output object back to the client via the sink. Then
  1011. // release the pointers and free the strings.
  1012. hr = pResultSink->Indicate(1, &pOutParams);
  1013. }
  1014. pOutParams->Release();
  1015. pResultSink->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL,NULL);
  1016. return(hr);
  1017. }
  1018. SCODE CClassPro::PutClassAsync(
  1019. /* [in] */ IWbemClassObject __RPC_FAR *pObject,
  1020. /* [in] */ long lFlags,
  1021. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1022. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1023. {
  1024. return(WBEM_E_NOT_SUPPORTED);
  1025. }
  1026. SCODE CClassPro::DeleteClassAsync(
  1027. /* [in] */ const BSTR Class,
  1028. /* [in] */ long lFlags,
  1029. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1030. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1031. {
  1032. return(WBEM_E_NOT_SUPPORTED);
  1033. }
  1034. SCODE CClassPro::PutInstanceAsync(
  1035. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  1036. /* [in] */ long lFlags,
  1037. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1038. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1039. {
  1040. return(WBEM_E_NOT_SUPPORTED);
  1041. }
  1042. SCODE CClassPro::DeleteInstanceAsync(
  1043. /* [in] */ const BSTR ObjectPath,
  1044. /* [in] */ long lFlags,
  1045. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1046. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1047. {
  1048. return(WBEM_E_NOT_SUPPORTED);
  1049. }
  1050. CTestServices *CClassPro::FindExistingTestServices(
  1051. PWCHAR CdmClassName
  1052. )
  1053. {
  1054. CTestServices *WdmTest;
  1055. //
  1056. // This routine assumes any sync mechanism has been done outside of
  1057. // this routine
  1058. //
  1059. WdmTest = WdmTestHead;
  1060. while (WdmTest != NULL)
  1061. {
  1062. if (WdmTest->ClaimCdmClassName(CdmClassName))
  1063. {
  1064. //
  1065. // We found an existing test services for this class
  1066. //
  1067. return(WdmTest);
  1068. }
  1069. WdmTest = WdmTest->GetNext();
  1070. }
  1071. return(NULL);
  1072. }
  1073. HRESULT CClassPro::LookupTestServices(
  1074. const BSTR CdmClassName,
  1075. CTestServices **TestServices
  1076. )
  1077. {
  1078. HRESULT hr;
  1079. CTestServices *WdmTest, *OtherWdmTest;
  1080. WmipAssert(CdmClassName != NULL);
  1081. WmipAssert(TestServices != NULL);
  1082. //
  1083. // Look up the class name and find the Wdm Test Services
  1084. // class that represents it.
  1085. //
  1086. EnterCdmCritSection();
  1087. WdmTest = FindExistingTestServices(CdmClassName);
  1088. LeaveCdmCritSection();
  1089. if (WdmTest != NULL)
  1090. {
  1091. *TestServices = WdmTest;
  1092. return(WBEM_S_NO_ERROR);
  1093. }
  1094. //
  1095. // If the WDM test services has not yet been initialized for this
  1096. // CDM diagnostic classes then go ahead and do so
  1097. //
  1098. WdmTest = new CTestServices();
  1099. hr = WdmTest->InitializeCdmClasses(CdmClassName);
  1100. if (hr == WBEM_S_NO_ERROR)
  1101. {
  1102. //
  1103. // Now check to see if another thread created and inserted the
  1104. // test services for the class while we were trying to
  1105. // initialize it. Since we want only one test services we throw
  1106. // ours away and use the other
  1107. //
  1108. EnterCdmCritSection();
  1109. OtherWdmTest = FindExistingTestServices(CdmClassName);
  1110. if (OtherWdmTest == NULL)
  1111. {
  1112. //
  1113. // Horray, we win do insert our own test into list
  1114. //
  1115. WdmTest->InsertSelf(&WdmTestHead);
  1116. LeaveCdmCritSection();
  1117. } else {
  1118. //
  1119. // We lost, so use existing test services
  1120. //
  1121. WmipDebugPrint(("CDMPROV: WdmTest %p lost insertion race to %p\n",
  1122. WdmTest, OtherWdmTest));
  1123. LeaveCdmCritSection();
  1124. delete WdmTest;
  1125. WdmTest = OtherWdmTest;
  1126. }
  1127. *TestServices = WdmTest;
  1128. WmipDebugPrint(("CDMPROV: Inited WdmTest %p for %ws\n",
  1129. WdmTest, CdmClassName));
  1130. } else {
  1131. WmipDebugPrint(("CDMPROV: Inited failed %x for %p for %ws\n",
  1132. hr, WdmTest, CdmClassName));
  1133. delete WdmTest;
  1134. }
  1135. return(hr);
  1136. }
  1137. HRESULT CClassPro::CreateTestInst(
  1138. CTestServices *WdmTest,
  1139. IWbemClassObject **pCdmTest,
  1140. IWbemContext *pCtx
  1141. )
  1142. {
  1143. HRESULT hr;
  1144. VARIANT v;
  1145. //
  1146. // We create 1 instance of the CIM_DiagnosticTest class
  1147. // regardless of the number of devices that support this class.
  1148. // Note that for the CDM proeprties of the test we arbitrarily
  1149. // pick the first device and get its WDM properties.
  1150. //
  1151. hr = CreateInst(m_pCdmServices,
  1152. pCdmTest,
  1153. WdmTest->GetCdmTestClassName(),
  1154. pCtx);
  1155. if (hr == WBEM_S_NO_ERROR)
  1156. {
  1157. //
  1158. // Get WDM properties from WDM
  1159. //
  1160. hr = WdmTest->QueryWdmTest(*pCdmTest,
  1161. 0);
  1162. if (hr == WBEM_S_NO_ERROR)
  1163. {
  1164. //
  1165. // Set UM provider properties here. These are Name
  1166. //
  1167. VariantInit(&v);
  1168. V_VT(&v) = VT_BSTR;
  1169. V_BSTR(&v) = SysAllocString(WdmTest->GetCdmTestClassName());
  1170. hr = (*pCdmTest)->Put(L"Name", 0, &v, 0);
  1171. if (hr != WBEM_S_NO_ERROR)
  1172. {
  1173. (*pCdmTest)->Release();
  1174. }
  1175. VariantClear(&v);
  1176. } else {
  1177. (*pCdmTest)->Release();
  1178. }
  1179. }
  1180. return(hr);
  1181. }
  1182. HRESULT CClassPro::CreateResultForMSEInst(
  1183. CTestServices *WdmTest,
  1184. IWbemClassObject **pCdmResultForMSE,
  1185. int RelPathIndex,
  1186. IWbemClassObject *pCdmResult,
  1187. IWbemContext *pCtx
  1188. )
  1189. {
  1190. HRESULT hr;
  1191. PWCHAR PropertyNames[2];
  1192. VARIANT PropertyValues[2];
  1193. hr = CreateInst(m_pCdmServices,
  1194. pCdmResultForMSE,
  1195. WdmTest->GetCdmResultForMSEClassName(),
  1196. pCtx);
  1197. if (hr == WBEM_S_NO_ERROR)
  1198. {
  1199. //
  1200. // Result is a reference to the CIM_Diagnostic result class
  1201. //
  1202. hr = WmiGetProperty(pCdmResult,
  1203. L"__RelPath",
  1204. CIM_REFERENCE,
  1205. &PropertyValues[0]);
  1206. PropertyNames[0] = L"Result";
  1207. if (hr == WBEM_S_NO_ERROR)
  1208. {
  1209. //
  1210. // SystemElement is a reference to the CIM class (MSE)
  1211. //
  1212. PropertyNames[1] = L"SystemElement";
  1213. PropertyValues[1].vt = VT_BSTR;
  1214. PropertyValues[1].bstrVal = WdmTest->GetCimRelPath(RelPathIndex);
  1215. hr = WmiSetPropertyList(*pCdmResultForMSE,
  1216. 2,
  1217. PropertyNames,
  1218. PropertyValues);
  1219. if (hr != WBEM_S_NO_ERROR)
  1220. {
  1221. (*pCdmResultForMSE)->Release();
  1222. }
  1223. VariantClear(&PropertyValues[0]);
  1224. } else {
  1225. (*pCdmResultForMSE)->Release();
  1226. }
  1227. } else {
  1228. hr = WBEM_E_NOT_FOUND;
  1229. (*pCdmResultForMSE)->Release();
  1230. }
  1231. return(hr);
  1232. }
  1233. HRESULT CClassPro::CreateResultForTestInst(
  1234. CTestServices *WdmTest,
  1235. IWbemClassObject **pCdmResultForTest,
  1236. IWbemClassObject *pCdmResult,
  1237. IWbemContext *pCtx
  1238. )
  1239. {
  1240. PWCHAR PropertyNames[2];
  1241. VARIANT PropertyValues[2];
  1242. HRESULT hr;
  1243. //
  1244. // Set the DiagnosticTest property which is the relpath to
  1245. // this test
  1246. //
  1247. PropertyNames[0] = L"DiagnosticTest";
  1248. PropertyValues[0].vt = VT_BSTR;
  1249. PropertyValues[0].bstrVal = WdmTest->GetCdmTestRelPath();
  1250. hr = WmiGetProperty(pCdmResult,
  1251. L"__RelPath",
  1252. CIM_REFERENCE,
  1253. &PropertyValues[1]);
  1254. PropertyNames[1] = L"DiagnosticResult";
  1255. if (hr == WBEM_S_NO_ERROR)
  1256. {
  1257. //
  1258. // for each instance of this test we create a ResultForTest
  1259. // association instance and then set the properties within
  1260. // it to the appropriate values and relpaths
  1261. hr = CreateInst(m_pCdmServices,
  1262. pCdmResultForTest,
  1263. WdmTest->GetCdmResultForTestClassName(),
  1264. pCtx);
  1265. if (hr == WBEM_S_NO_ERROR)
  1266. {
  1267. hr = WmiSetPropertyList((*pCdmResultForTest),
  1268. 2,
  1269. PropertyNames,
  1270. PropertyValues);
  1271. if (hr != WBEM_S_NO_ERROR)
  1272. {
  1273. (*pCdmResultForTest)->Release();
  1274. }
  1275. }
  1276. VariantClear(&PropertyValues[1]);
  1277. }
  1278. return(hr);
  1279. }
  1280. HRESULT CClassPro::CreateTestForMSEInst(
  1281. CTestServices *WdmTest,
  1282. IWbemClassObject **pCdmTestForMSE,
  1283. int RelPathIndex,
  1284. IWbemContext *pCtx
  1285. )
  1286. {
  1287. HRESULT hr;
  1288. PWCHAR PropertyNames[8];
  1289. VARIANT PropertyValues[8];
  1290. hr = CreateInst(m_pCdmServices,
  1291. pCdmTestForMSE,
  1292. WdmTest->GetCdmTestForMSEClassName(),
  1293. pCtx);
  1294. if (hr == WBEM_S_NO_ERROR)
  1295. {
  1296. //
  1297. // Set the antecedent property which is the relpath to
  1298. // the DiagTest
  1299. //
  1300. PropertyNames[0] = L"Antecedent";
  1301. PropertyValues[0].vt = VT_BSTR;
  1302. PropertyValues[0].bstrVal = WdmTest->GetCdmTestRelPath();
  1303. //
  1304. // Set the dependent property which is the relpath to
  1305. // this MSE
  1306. //
  1307. PropertyNames[1] = L"Dependent";
  1308. PropertyValues[1].vt = VT_BSTR;
  1309. PropertyValues[1].bstrVal = WdmTest->GetCimRelPath(RelPathIndex);
  1310. //
  1311. // Set the estimated time of performing which is
  1312. // obtained from querying the test itself
  1313. //
  1314. PropertyNames[2] = L"EstimatedTimeOfPerforming";
  1315. PropertyValues[2].vt = VT_I4;
  1316. PropertyValues[2].lVal = WdmTest->GetTestEstimatedTime(RelPathIndex);
  1317. //
  1318. // Set IsExclusiveForMSE which is obtained from
  1319. // querying the test itself
  1320. //
  1321. PropertyNames[3] = L"IsExclusiveForMSE";
  1322. PropertyValues[3].vt = VT_BOOL;
  1323. PropertyValues[3].boolVal = WdmTest->GetTestIsExclusiveForMSE(RelPathIndex) ?
  1324. VARIANT_TRUE :
  1325. VARIANT_FALSE;
  1326. //
  1327. // Not sure what this is for
  1328. //
  1329. PropertyNames[4] = L"MessageLine";
  1330. PropertyValues[4].vt = VT_BSTR;
  1331. PropertyValues[4].bstrVal = NULL;
  1332. //
  1333. // Not sure what this is for
  1334. //
  1335. PropertyNames[5] = L"ReturnMessage";
  1336. PropertyValues[5].vt = VT_BSTR;
  1337. PropertyValues[5].bstrVal = NULL;
  1338. //
  1339. // Not sure what this is for
  1340. //
  1341. PropertyNames[6] = L"Prompt";
  1342. PropertyValues[6].vt = VT_I4;
  1343. PropertyValues[6].lVal = 0;
  1344. //
  1345. // Not sure what this is for
  1346. //
  1347. PropertyNames[7] = L"RequestedLanguage";
  1348. PropertyValues[7].vt = VT_I4;
  1349. PropertyValues[7].lVal = 0;
  1350. hr = WmiSetPropertyList(*pCdmTestForMSE,
  1351. 8,
  1352. PropertyNames,
  1353. PropertyValues);
  1354. if (hr != WBEM_S_NO_ERROR)
  1355. {
  1356. (*pCdmTestForMSE)->Release();
  1357. }
  1358. }
  1359. return(hr);
  1360. }
  1361. HRESULT CClassPro::CreateSettingForTestInst(
  1362. CTestServices *WdmTest,
  1363. IWbemClassObject **pCdmSettingForTest,
  1364. int RelPathIndex,
  1365. ULONG SettingIndex,
  1366. IWbemContext *pCtx
  1367. )
  1368. {
  1369. HRESULT hr;
  1370. PWCHAR PropertyNames[2];
  1371. VARIANT PropertyValues[2];
  1372. hr = CreateInst(m_pCdmServices,
  1373. pCdmSettingForTest,
  1374. WdmTest->GetCdmSettingForTestClassName(),
  1375. pCtx);
  1376. if (hr == WBEM_S_NO_ERROR)
  1377. {
  1378. //
  1379. // Set the e;lement property which is the relpath to
  1380. // the Diagn
  1381. //
  1382. PropertyNames[0] = L"Element";
  1383. PropertyValues[0].vt = VT_BSTR;
  1384. PropertyValues[0].bstrVal = WdmTest->GetCdmTestRelPath();
  1385. //
  1386. // Set the setting property which is the relpath to
  1387. // this setting
  1388. //
  1389. PropertyNames[1] = L"Setting";
  1390. PropertyValues[1].vt = VT_BSTR;
  1391. PropertyValues[1].bstrVal = WdmTest->GetCdmSettingRelPath(RelPathIndex,
  1392. SettingIndex);
  1393. hr = WmiSetPropertyList(*pCdmSettingForTest,
  1394. 2,
  1395. PropertyNames,
  1396. PropertyValues);
  1397. if (hr != WBEM_S_NO_ERROR)
  1398. {
  1399. (*pCdmSettingForTest)->Release();
  1400. }
  1401. }
  1402. return(hr);
  1403. }