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.

910 lines
21 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000
  6. //
  7. // File: cimmap.cpp
  8. //
  9. //
  10. // This file contains routines that will establish a mapping between
  11. // Wdm class instances and Cdm class instances. See
  12. // MapWdmClassToCimClass for more information.
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <windows.h>
  16. #include <wbemidl.h>
  17. #include "debug.h"
  18. #include "wbemmisc.h"
  19. #include "useful.h"
  20. #include "cimmap.h"
  21. HRESULT WdmInstanceNameToPnPId(
  22. IWbemServices *pWdmServices,
  23. BSTR WdmInstanceName,
  24. VARIANT /* FREE */ *PnPId
  25. )
  26. /*+++
  27. Routine Description:
  28. This routine will convert a Wdm instance name into its
  29. corresponding pnp id
  30. Arguments:
  31. pWdmServices is the pointer to the root\wmi namespace
  32. WdmInstanceName
  33. *PnPId returns with the pnp id
  34. Return Value:
  35. HRESULT
  36. ---*/
  37. {
  38. WCHAR Query[2 * MAX_PATH];
  39. WCHAR s[MAX_PATH];
  40. BSTR sQuery;
  41. HRESULT hr;
  42. IEnumWbemClassObject *pWdmEnumInstances;
  43. IWbemClassObject *pWdmInstance;
  44. ULONG Count;
  45. BSTR sWQL;
  46. WmipAssert(pWdmServices != NULL);
  47. WmipAssert(WdmInstanceName != NULL);
  48. WmipAssert(PnPId != NULL);
  49. sWQL = SysAllocString(L"WQL");
  50. if (sWQL != NULL)
  51. {
  52. //
  53. // First get PnP id from Instance name from the MSWmi_PnPDeviceId
  54. // class (select * from MSWMI_PnPDeviceId where InstanceName =
  55. // "<WdmInstanceName>"
  56. //
  57. wsprintfW(Query,
  58. L"select * from MSWmi_PnPDeviceId where InstanceName = \"%ws\"",
  59. AddSlashesToStringW(s, WdmInstanceName));
  60. sQuery = SysAllocString(Query);
  61. if (sQuery != NULL)
  62. {
  63. hr = pWdmServices->ExecQuery(sWQL,
  64. sQuery,
  65. WBEM_FLAG_FORWARD_ONLY |
  66. WBEM_FLAG_ENSURE_LOCATABLE,
  67. NULL,
  68. &pWdmEnumInstances);
  69. if (hr == WBEM_S_NO_ERROR)
  70. {
  71. hr = pWdmEnumInstances->Next(WBEM_INFINITE,
  72. 1,
  73. &pWdmInstance,
  74. &Count);
  75. if ((hr == WBEM_S_NO_ERROR) &&
  76. (Count == 1))
  77. {
  78. hr = WmiGetProperty(pWdmInstance,
  79. L"PnPDeviceId",
  80. CIM_STRING,
  81. PnPId);
  82. pWdmInstance->Release();
  83. }
  84. pWdmEnumInstances->Release();
  85. } else {
  86. WmipDebugPrint(("CDMPROV: Query %ws failed %x\n",
  87. sQuery, hr));
  88. }
  89. SysFreeString(sQuery);
  90. } else {
  91. hr = WBEM_E_OUT_OF_MEMORY;
  92. }
  93. SysFreeString(sWQL);
  94. } else {
  95. hr = WBEM_E_OUT_OF_MEMORY;
  96. }
  97. return(hr);
  98. }
  99. HRESULT FindCimClassByWdmInstanceName(
  100. IN IWbemServices *pWdmServices,
  101. IN IWbemServices *pCimServices,
  102. IN BSTR CimClassName,
  103. IN BSTR WdmInstanceName,
  104. OUT BSTR *PnPId,
  105. OUT BSTR /* FREE */ *CimRelPath
  106. )
  107. /*+++
  108. Routine Description:
  109. This routine will find the Cim class instance that corresponds to a
  110. particular Wdm class instance
  111. Arguments:
  112. pWdmServices is the pointer to the root\wmi namespace
  113. pCdmServices is the pointer to the root\cimv2 namespace
  114. CimClassName is the name of the cim class that the wdm instance
  115. would map to
  116. WdmInstanceName
  117. *PnPId returns with the PnP id for the device stack
  118. *CimRelPath returns with the relpath for the Cim instance
  119. Return Value:
  120. HRESULT
  121. ---*/
  122. {
  123. HRESULT hr;
  124. VARIANT v;
  125. IEnumWbemClassObject *pCimEnumInstances;
  126. IWbemClassObject *pCimInstance;
  127. ULONG Count;
  128. BSTR sWQL;
  129. WmipAssert(pWdmServices != NULL);
  130. WmipAssert(pCimServices != NULL);
  131. WmipAssert(CimClassName != NULL);
  132. WmipAssert(WdmInstanceName != NULL);
  133. WmipAssert(CimRelPath != NULL);
  134. sWQL = SysAllocString(L"WQL");
  135. if (sWQL != NULL)
  136. {
  137. // ****************************************************************
  138. // Note: Net cards need to do something similar. We get the
  139. // netcard address in class MSNDIS_???? and then get the CIM class
  140. // by matching the netcard addresses.
  141. // ****************************************************************
  142. //
  143. // First thing is to convert from an instance name to a pnpid
  144. //
  145. hr = WdmInstanceNameToPnPId(pWdmServices,
  146. WdmInstanceName,
  147. &v);
  148. if (hr == WBEM_S_NO_ERROR)
  149. {
  150. //
  151. // Next select * from CimClassName where PnPDeviceId = "<PnPDevice
  152. // Id from above>".
  153. //
  154. WCHAR Query[2 * MAX_PATH];
  155. WCHAR s[MAX_PATH];
  156. BSTR sQuery;
  157. wsprintfW(Query,
  158. L"select * from %ws where PnPDeviceId = \"%ws\"",
  159. CimClassName,
  160. AddSlashesToStringW(s, v.bstrVal));
  161. *PnPId = v.bstrVal;
  162. sQuery = SysAllocString(Query);
  163. if (sQuery != NULL)
  164. {
  165. hr = pCimServices->ExecQuery(sWQL,
  166. sQuery,
  167. WBEM_FLAG_FORWARD_ONLY |
  168. WBEM_FLAG_ENSURE_LOCATABLE,
  169. NULL,
  170. &pCimEnumInstances);
  171. SysFreeString(sQuery);
  172. if (hr == WBEM_S_NO_ERROR)
  173. {
  174. hr = pCimEnumInstances->Next(WBEM_INFINITE,
  175. 1,
  176. &pCimInstance,
  177. &Count);
  178. if ((hr == WBEM_S_NO_ERROR) &&
  179. (Count == 1))
  180. {
  181. //
  182. // Finally grab the relpath from cim class and we're done
  183. //
  184. hr = WmiGetProperty(pCimInstance,
  185. L"__RELPATH",
  186. CIM_STRING,
  187. &v);
  188. if (hr == WBEM_S_NO_ERROR)
  189. {
  190. *CimRelPath = SysAllocString(v.bstrVal);
  191. if (*CimRelPath == NULL)
  192. {
  193. hr = WBEM_E_OUT_OF_MEMORY;
  194. }
  195. VariantClear(&v);
  196. }
  197. pCimInstance->Release();
  198. }
  199. pCimEnumInstances->Release();
  200. } else {
  201. WmipDebugPrint(("CDMPROV: Query %ws failed %x\n",
  202. Query, hr));
  203. }
  204. } else {
  205. hr = WBEM_E_OUT_OF_MEMORY;
  206. }
  207. }
  208. SysFreeString(sWQL);
  209. } else {
  210. hr = WBEM_E_OUT_OF_MEMORY;
  211. }
  212. return(hr);
  213. }
  214. HRESULT GetEnumCount(
  215. IN IEnumWbemClassObject *pEnumInstances,
  216. OUT int *RelPathCount
  217. )
  218. /*+++
  219. Routine Description:
  220. This routine will return the count of instances in the enumeration
  221. Arguments:
  222. pEnumInstance is the instance enumerator
  223. *RelPathCount returns the number of instances in the enumeration
  224. Return Value:
  225. HRESULT
  226. ---*/
  227. {
  228. ULONG Count;
  229. HRESULT hr;
  230. IWbemClassObject *pInstance;
  231. WmipAssert(pEnumInstances != NULL);
  232. WmipAssert(RelPathCount != NULL);
  233. *RelPathCount = 0;
  234. do
  235. {
  236. hr = pEnumInstances->Next(WBEM_INFINITE,
  237. 1,
  238. &pInstance,
  239. &Count);
  240. if ((hr == WBEM_S_NO_ERROR) &&
  241. (Count == 1))
  242. {
  243. (*RelPathCount)++;
  244. pInstance->Release();
  245. } else {
  246. if (hr == WBEM_S_FALSE)
  247. {
  248. hr = WBEM_S_NO_ERROR;
  249. }
  250. break;
  251. }
  252. } while (TRUE);
  253. return(hr);
  254. }
  255. HRESULT AllocateBstrArrays(
  256. ULONG Size,
  257. CBstrArray *WdmRelPaths,
  258. CBstrArray *CimRelPaths,
  259. CBstrArray *WdmInstanceNames,
  260. CBstrArray *PnPDeviceIds,
  261. CBstrArray *FriendlyName,
  262. CBstrArray *DeviceDesc
  263. )
  264. {
  265. HRESULT hr;
  266. hr = WdmRelPaths->Initialize(Size);
  267. if (hr == WBEM_S_NO_ERROR)
  268. {
  269. hr = CimRelPaths->Initialize(Size);
  270. if (hr == WBEM_S_NO_ERROR)
  271. {
  272. hr = WdmInstanceNames->Initialize(Size);
  273. if (hr == WBEM_S_NO_ERROR)
  274. {
  275. hr = PnPDeviceIds->Initialize(Size);
  276. if (hr == WBEM_S_NO_ERROR)
  277. {
  278. hr = FriendlyName->Initialize(Size);
  279. if (hr == WBEM_S_NO_ERROR)
  280. {
  281. hr = DeviceDesc->Initialize(Size);
  282. }
  283. }
  284. }
  285. }
  286. }
  287. //
  288. // We don't worry about cleaning up in the case of a failure since
  289. // the destructors for CBstrArray will take care of that for us
  290. //
  291. return(hr);
  292. }
  293. HRESULT GetDeviceProperties(
  294. IN IWbemContext *pCtx,
  295. IN IWbemServices *pWdmServices,
  296. IN PWCHAR InstanceName,
  297. OUT BSTR *FriendlyName,
  298. OUT BSTR *DeviceDesc
  299. )
  300. {
  301. HRESULT hr, hrDontCare;
  302. VARIANT v;
  303. IWbemClassObject *pInstance;
  304. WmipAssert(pWdmServices != NULL);
  305. WmipAssert(InstanceName != NULL);
  306. WmipAssert(FriendlyName != NULL);
  307. WmipAssert(DeviceDesc != NULL);
  308. hr = GetInstanceOfClass(pCtx,
  309. pWdmServices,
  310. L"MSWmi_ProviderInfo",
  311. L"InstanceName",
  312. InstanceName,
  313. NULL,
  314. &pInstance);
  315. if (hr == WBEM_S_NO_ERROR)
  316. {
  317. hrDontCare = WmiGetProperty(pInstance,
  318. L"FriendlyName",
  319. CIM_STRING,
  320. &v);
  321. if (hrDontCare == WBEM_S_NO_ERROR)
  322. {
  323. *FriendlyName = v.bstrVal;
  324. } else {
  325. *FriendlyName = NULL;
  326. }
  327. hrDontCare = WmiGetProperty(pInstance,
  328. L"Description",
  329. CIM_STRING,
  330. &v);
  331. if (hrDontCare == WBEM_S_NO_ERROR)
  332. {
  333. *DeviceDesc = v.bstrVal;
  334. } else {
  335. *DeviceDesc = NULL;
  336. }
  337. pInstance->Release();
  338. }
  339. return(hr);
  340. }
  341. HRESULT MapWdmClassToCimClassViaPnpId(
  342. IWbemContext *pCtx,
  343. IN IWbemServices *pWdmServices,
  344. IN IWbemServices *pCimServices,
  345. IN BSTR WdmClassName,
  346. IN BSTR CimClassName,
  347. OUT CBstrArray *PnPDeviceIds,
  348. OUT CBstrArray *FriendlyName,
  349. OUT CBstrArray *DeviceDesc,
  350. OUT CBstrArray *WdmInstanceNames,
  351. OUT CBstrArray *WdmRelPaths,
  352. OUT CBstrArray *CimRelPaths,
  353. OUT int *RelPathCount
  354. )
  355. /*+++
  356. Routine Description:
  357. This routine will perform a mapping between the instances of WDM
  358. classes and Cim Classes
  359. Arguments:
  360. pWdmServices
  361. pCdmServices
  362. WdmClassName
  363. CimClassName
  364. *PnPDeviceIds return with the an array of PnP device ids
  365. *WdmInstanceNames returns with an array of Wdm instnace names
  366. *WdmRelPaths returns with an array of relpaths to Wdm instances
  367. *CimRelpaths returns with an array of relapaths to Cim instance
  368. *RelPathCount returns with the count of instances that are mapped
  369. Return Value:
  370. HRESULT
  371. ---*/
  372. {
  373. IWbemClassObject *pWdmInstance;
  374. IEnumWbemClassObject *pWdmEnumInstances;
  375. HRESULT hr;
  376. int i, NumberWdmInstances;
  377. VARIANT v;
  378. ULONG Count;
  379. BSTR bstr1, bstr2;
  380. BSTR f,d;
  381. WmipAssert(pWdmServices != NULL);
  382. WmipAssert(pCimServices != NULL);
  383. WmipAssert(WdmClassName != NULL);
  384. WmipAssert(CimClassName != NULL);
  385. WmipAssert(RelPathCount != NULL);
  386. WmipAssert((PnPDeviceIds != NULL) && ( ! PnPDeviceIds->IsInitialized()));
  387. WmipAssert((FriendlyName != NULL) && ( ! FriendlyName->IsInitialized()));
  388. WmipAssert((DeviceDesc != NULL) && ( ! DeviceDesc->IsInitialized()));
  389. WmipAssert((WdmInstanceNames != NULL) && (! WdmInstanceNames->IsInitialized()));
  390. WmipAssert((WdmRelPaths != NULL) && ( ! WdmRelPaths->IsInitialized()));
  391. WmipAssert((CimRelPaths != NULL) && ( ! CimRelPaths->IsInitialized()));
  392. //
  393. // Get all instances of the Wdm Class
  394. //
  395. hr = pWdmServices->CreateInstanceEnum(WdmClassName,
  396. WBEM_FLAG_USE_AMENDED_QUALIFIERS |
  397. WBEM_FLAG_SHALLOW,
  398. NULL,
  399. &pWdmEnumInstances);
  400. if (hr == WBEM_S_NO_ERROR)
  401. {
  402. hr = GetEnumCount(pWdmEnumInstances,
  403. RelPathCount);
  404. NumberWdmInstances = *RelPathCount;
  405. if (hr == WBEM_S_NO_ERROR)
  406. {
  407. hr = AllocateBstrArrays(NumberWdmInstances,
  408. WdmRelPaths,
  409. CimRelPaths,
  410. WdmInstanceNames,
  411. PnPDeviceIds,
  412. FriendlyName,
  413. DeviceDesc);
  414. if (hr == WBEM_S_NO_ERROR)
  415. {
  416. pWdmEnumInstances->Reset();
  417. i = 0;
  418. do
  419. {
  420. hr = pWdmEnumInstances->Next(WBEM_INFINITE,
  421. 1,
  422. &pWdmInstance,
  423. &Count);
  424. if ((hr == WBEM_S_NO_ERROR) &&
  425. (Count == 1) &&
  426. (i < NumberWdmInstances))
  427. {
  428. //
  429. // Lets get the instance name and then lookup the pnp
  430. // id for it
  431. //
  432. hr = WmiGetProperty(pWdmInstance,
  433. L"InstanceName",
  434. CIM_STRING,
  435. &v);
  436. if (hr == WBEM_S_NO_ERROR)
  437. {
  438. //
  439. // Remember wdm instnace name
  440. //
  441. WmipDebugPrint(("CDMPROV: Wdm InstanceName is %ws\n",
  442. v.bstrVal));
  443. WdmInstanceNames->Set(i, v.bstrVal);
  444. hr = FindCimClassByWdmInstanceName(pWdmServices,
  445. pCimServices,
  446. CimClassName,
  447. v.bstrVal,
  448. &bstr1,
  449. &bstr2);
  450. PnPDeviceIds->Set(i, bstr1);
  451. CimRelPaths->Set(i, bstr2);
  452. if (hr == WBEM_S_NO_ERROR)
  453. {
  454. //
  455. // Remember Wdm class relative path
  456. //
  457. WmipDebugPrint(("CDMPROV: Found CimRelPath %ws for Wdm class %ws\n",
  458. CimRelPaths->Get(i), WdmClassName))
  459. hr = WmiGetProperty(pWdmInstance,
  460. L"__RELPATH",
  461. CIM_STRING,
  462. &v);
  463. if (hr == WBEM_S_NO_ERROR)
  464. {
  465. WdmRelPaths->Set(i, v.bstrVal);
  466. //
  467. // Now try to get FriendlyName and
  468. // DeviceDesc for the instance
  469. //
  470. hr = GetDeviceProperties(pCtx,
  471. pWdmServices,
  472. WdmInstanceNames->Get(i),
  473. &f,
  474. &d);
  475. if (hr == WBEM_S_NO_ERROR)
  476. {
  477. if (f != NULL)
  478. {
  479. FriendlyName->Set(i, f);
  480. }
  481. if (d != NULL)
  482. {
  483. DeviceDesc->Set(i, d);
  484. }
  485. }
  486. i++;
  487. }
  488. } else {
  489. //
  490. // We did not find a CIM class
  491. // to match our Wdm instance
  492. // names, so we decrement our
  493. // relpath count and continue
  494. // searching
  495. (*RelPathCount)--;
  496. if (*RelPathCount == 0)
  497. {
  498. hr = WBEM_E_NOT_FOUND;
  499. } else {
  500. hr = WBEM_S_NO_ERROR;
  501. }
  502. }
  503. }
  504. pWdmInstance->Release();
  505. } else {
  506. if (hr == WBEM_S_FALSE)
  507. {
  508. hr = WBEM_S_NO_ERROR;
  509. }
  510. break;
  511. }
  512. } while (hr == WBEM_S_NO_ERROR);
  513. } else {
  514. hr = WBEM_E_OUT_OF_MEMORY;
  515. }
  516. }
  517. pWdmEnumInstances->Release();
  518. }
  519. return(hr);
  520. }
  521. HRESULT FindRelPathByProperty(
  522. IN IWbemContext *pCtx,
  523. IN IWbemServices *pServices,
  524. IN BSTR ClassName,
  525. IN BSTR PropertyName,
  526. IN VARIANT *ValueToMatch,
  527. IN CIMTYPE CIMTypeToMatch,
  528. OUT VARIANT *RelPath
  529. )
  530. {
  531. WCHAR PropertyValue[MAX_PATH];
  532. PWCHAR pv;
  533. HRESULT hr;
  534. IWbemClassObject *pInstance;
  535. WmipAssert(pServices != NULL);
  536. WmipAssert(ClassName != NULL);
  537. WmipAssert(PropertyName != NULL);
  538. WmipAssert(ValueToMatch != NULL);
  539. WmipAssert(RelPath != NULL);
  540. pv = PropertyValue;
  541. switch (ValueToMatch->vt)
  542. {
  543. case VT_I1:
  544. {
  545. wsprintfW(PropertyValue, L"%d", ValueToMatch->cVal);
  546. break;
  547. }
  548. case VT_UI1:
  549. {
  550. wsprintfW(PropertyValue, L"%d", ValueToMatch->bVal);
  551. break;
  552. }
  553. case VT_I2:
  554. {
  555. wsprintfW(PropertyValue, L"%d", ValueToMatch->iVal);
  556. break;
  557. }
  558. case VT_UI2:
  559. {
  560. wsprintfW(PropertyValue, L"%d", ValueToMatch->uiVal);
  561. break;
  562. }
  563. case VT_UI4:
  564. {
  565. wsprintfW(PropertyValue, L"%d", ValueToMatch->ulVal);
  566. break;
  567. }
  568. case VT_I4:
  569. {
  570. wsprintfW(PropertyValue, L"%d", ValueToMatch->lVal);
  571. break;
  572. }
  573. case VT_BOOL:
  574. {
  575. pv = (ValueToMatch->boolVal == VARIANT_TRUE) ?
  576. L"TRUE":
  577. L"FALSE";
  578. break;
  579. }
  580. case VT_BSTR:
  581. {
  582. pv = ValueToMatch->bstrVal;
  583. break;
  584. }
  585. default:
  586. {
  587. WmipDebugPrint(("WMIMAP: Unable to map WDM to CIM for CIMTYPE/VT %d/%d\n",
  588. CIMTypeToMatch, ValueToMatch->vt));
  589. return(WBEM_E_FAILED);
  590. }
  591. }
  592. hr = GetInstanceOfClass(pCtx,
  593. pServices,
  594. ClassName,
  595. PropertyName,
  596. pv,
  597. NULL,
  598. &pInstance);
  599. if (hr == WBEM_S_NO_ERROR)
  600. {
  601. hr = WmiGetProperty(pInstance,
  602. L"__RELPATH",
  603. CIM_REFERENCE,
  604. RelPath);
  605. pInstance->Release();
  606. }
  607. return(hr);
  608. }
  609. HRESULT MapWdmClassToCimClassViaProperty(
  610. IN IWbemContext *pCtx,
  611. IN IWbemServices *pWdmServices,
  612. IN IWbemServices *pCimServices,
  613. IN BSTR WdmShadowClassName,
  614. IN BSTR WdmMappingClassName,
  615. IN OPTIONAL BSTR WdmMappingProperty,
  616. IN BSTR CimMappingClassName,
  617. IN OPTIONAL BSTR CimMappingProperty,
  618. OUT CBstrArray *WdmInstanceNames,
  619. OUT CBstrArray *WdmRelPaths,
  620. OUT CBstrArray *CimRelPaths,
  621. OUT int *RelPathCount
  622. )
  623. {
  624. HRESULT hr;
  625. IEnumWbemClassObject *pWdmEnumInstances;
  626. int NumberWdmInstances;
  627. CBstrArray PnPDeviceIds, FriendlyName, DeviceDesc;
  628. CIMTYPE WdmCimType;
  629. VARIANT WdmProperty, WdmInstanceName;
  630. VARIANT CimRelPath, WdmRelPath;
  631. int i;
  632. IWbemClassObject *pWdmInstance;
  633. ULONG Count;
  634. WmipAssert(pWdmServices != NULL);
  635. WmipAssert(pCimServices != NULL);
  636. WmipAssert(WdmShadowClassName != NULL);
  637. WmipAssert(WdmMappingClassName != NULL);
  638. WmipAssert(WdmMappingProperty != NULL);
  639. WmipAssert(CimMappingClassName != NULL);
  640. WmipAssert(CimMappingProperty != NULL);
  641. //
  642. // We need to do a mapping from a WDM class to a CIM class. This is
  643. // done via a common property value within the CIM and WDM mapping
  644. // classes. If the WDM mapping and shadow classes are different
  645. // then it is assumed that they both report the same instance names
  646. //
  647. //
  648. // First thing is to enumerate all instances of the WDM mapping
  649. // class.
  650. //
  651. hr = pWdmServices->CreateInstanceEnum(WdmMappingClassName,
  652. WBEM_FLAG_USE_AMENDED_QUALIFIERS |
  653. WBEM_FLAG_SHALLOW,
  654. NULL,
  655. &pWdmEnumInstances);
  656. if (hr == WBEM_S_NO_ERROR)
  657. {
  658. hr = GetEnumCount(pWdmEnumInstances,
  659. &NumberWdmInstances);
  660. if (hr == WBEM_S_NO_ERROR)
  661. {
  662. hr = AllocateBstrArrays(NumberWdmInstances,
  663. WdmRelPaths,
  664. CimRelPaths,
  665. WdmInstanceNames,
  666. &PnPDeviceIds,
  667. &FriendlyName,
  668. &DeviceDesc);
  669. if (hr == WBEM_S_NO_ERROR)
  670. {
  671. pWdmEnumInstances->Reset();
  672. i = 0;
  673. *RelPathCount = 0;
  674. do
  675. {
  676. VariantInit(&CimRelPath);
  677. VariantInit(&WdmRelPath);
  678. VariantInit(&WdmInstanceName);
  679. hr = pWdmEnumInstances->Next(WBEM_INFINITE,
  680. 1,
  681. &pWdmInstance,
  682. &Count);
  683. if ((hr == WBEM_S_NO_ERROR) &&
  684. (Count == 1) &&
  685. (i < NumberWdmInstances))
  686. {
  687. //
  688. // For each instance we try to find an instance
  689. // of a CIM class whose property matches that
  690. // of the WDM property. So first lets get the
  691. // WDM property
  692. //
  693. hr = pWdmInstance->Get(WdmMappingProperty,
  694. 0,
  695. &WdmProperty,
  696. &WdmCimType,
  697. NULL);
  698. if (hr == WBEM_S_NO_ERROR)
  699. {
  700. hr = FindRelPathByProperty(pCtx,
  701. pCimServices,
  702. CimMappingClassName,
  703. CimMappingProperty,
  704. &WdmProperty,
  705. WdmCimType,
  706. &CimRelPath);
  707. if (hr == WBEM_S_NO_ERROR)
  708. {
  709. //
  710. // We found a mapping to a CIM class so
  711. // get the instance name of the mapping
  712. // class
  713. //
  714. hr = WmiGetProperty(pWdmInstance,
  715. L"InstanceName",
  716. CIM_STRING,
  717. &WdmInstanceName);
  718. if (hr == WBEM_S_NO_ERROR)
  719. {
  720. //
  721. // Now finally we can get the
  722. // shadow class instance by means
  723. // of the instance name
  724. //
  725. hr = FindRelPathByProperty(pCtx,
  726. pWdmServices,
  727. WdmShadowClassName,
  728. L"InstanceName",
  729. &WdmInstanceName,
  730. CIM_STRING,
  731. &WdmRelPath);
  732. if (hr == WBEM_S_NO_ERROR)
  733. {
  734. CimRelPaths->Set(i, CimRelPath.bstrVal);
  735. VariantInit(&CimRelPath);
  736. WdmRelPaths->Set(i, WdmRelPath.bstrVal);
  737. VariantInit(&WdmRelPath);
  738. WdmInstanceNames->Set(i, WdmInstanceName.bstrVal);
  739. VariantInit(&WdmInstanceName);
  740. i++;
  741. (*RelPathCount)++;
  742. }
  743. }
  744. }
  745. VariantClear(&WdmProperty);
  746. }
  747. pWdmInstance->Release();
  748. } else {
  749. if (hr == WBEM_S_FALSE)
  750. {
  751. hr = WBEM_S_NO_ERROR;
  752. }
  753. break;
  754. }
  755. VariantClear(&CimRelPath);
  756. VariantClear(&WdmRelPath);
  757. VariantClear(&WdmInstanceName);
  758. } while (hr == WBEM_S_NO_ERROR);
  759. }
  760. }
  761. pWdmEnumInstances->Release();
  762. }
  763. return(hr);
  764. }