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.

1287 lines
26 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000
  6. //
  7. // File: wbemmisc.cpp
  8. //
  9. // Abstract: Misc routines useful for interfacing with WBEM
  10. //
  11. //--------------------------------------------------------------------------
  12. #include <objbase.h>
  13. #include <windows.h>
  14. #include <wbemidl.h>
  15. #include <wbemtime.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <wchar.h>
  19. #include "debug.h"
  20. #include "useful.h"
  21. #include "wbemmisc.h"
  22. HRESULT GetMethodInParamInstance(
  23. IN IWbemServices *pServices,
  24. IN PWCHAR ClassName,
  25. IN BSTR MethodName,
  26. OUT IWbemClassObject **ppInParamInstance
  27. )
  28. /*+++
  29. Routine Description:
  30. This routine will return an instance object for a methods in
  31. parameter. WBEM requires that we go through this dance to get an
  32. instance object.
  33. Arguments:
  34. pServices
  35. ClassName is the class containing the method
  36. MethodName is the name of the method
  37. *ppInParamInstance returns the instance object to fill with in
  38. parameters
  39. Return Value:
  40. HRESULT
  41. ---*/
  42. {
  43. HRESULT hr;
  44. IWbemClassObject *pClass;
  45. IWbemClassObject *pInParamClass;
  46. WmipAssert(pServices != NULL);
  47. WmipAssert(ClassName != NULL);
  48. WmipAssert(MethodName != NULL);
  49. WmipAssert(ppInParamInstance != NULL);
  50. hr = pServices->GetObject(ClassName,
  51. 0,
  52. NULL,
  53. &pClass,
  54. NULL);
  55. if (hr == WBEM_S_NO_ERROR)
  56. {
  57. hr = pClass->GetMethod(MethodName,
  58. 0,
  59. &pInParamClass,
  60. NULL);
  61. if (hr == WBEM_S_NO_ERROR)
  62. {
  63. hr = pInParamClass->SpawnInstance(0,
  64. ppInParamInstance);
  65. pInParamClass->Release();
  66. }
  67. pClass->Release();
  68. }
  69. return(hr);
  70. }
  71. HRESULT WmiGetQualifier(
  72. IN IWbemQualifierSet *pIWbemQualifierSet,
  73. IN PWCHAR QualifierName,
  74. IN VARTYPE Type,
  75. OUT /* FREE */ VARIANT *Value
  76. )
  77. /*+++
  78. Routine Description:
  79. This routine will return the value for a specific qualifier
  80. Arguments:
  81. pIWbemQualifierSet is the qualifier set object
  82. QualifierName is the name of the qualifier
  83. Type is the type of qualifier expected
  84. *Value returns with the value of the qualifier. Caller must call
  85. VariantClear
  86. Return Value:
  87. HRESULT
  88. ---*/
  89. {
  90. BSTR s;
  91. HRESULT hr;
  92. WmipAssert(pIWbemQualifierSet != NULL);
  93. WmipAssert(QualifierName != NULL);
  94. WmipAssert(Value != NULL);
  95. s = SysAllocString(QualifierName);
  96. if (s != NULL)
  97. {
  98. hr = pIWbemQualifierSet->Get(s,
  99. 0,
  100. Value,
  101. NULL);
  102. if ((Value->vt & ~CIM_FLAG_ARRAY) != Type)
  103. {
  104. hr = WBEM_E_FAILED;
  105. VariantClear(Value);
  106. }
  107. SysFreeString(s);
  108. } else {
  109. hr = WBEM_E_OUT_OF_MEMORY;
  110. }
  111. return(hr);
  112. }
  113. HRESULT GetListOfQualifiers(
  114. IN IWbemQualifierSet *pQualifiers,
  115. IN ULONG Count,
  116. IN PWCHAR *Names,
  117. IN VARTYPE *Types,
  118. OUT VARIANT /* FREE */ *Values,
  119. IN BOOLEAN AbortOnError
  120. )
  121. {
  122. HRESULT hr;
  123. ULONG i,j;
  124. WmipAssert(pQualifiers != NULL);
  125. WmipAssert(Names != NULL);
  126. WmipAssert(Types != NULL);
  127. WmipAssert(Values != NULL);
  128. for (i = 0, hr = WBEM_S_NO_ERROR; (i < Count) && (hr == WBEM_S_NO_ERROR); i++)
  129. {
  130. hr = WmiGetQualifier(pQualifiers,
  131. Names[i],
  132. Types[i],
  133. &Values[i]);
  134. if (hr != WBEM_S_NO_ERROR)
  135. {
  136. if (AbortOnError)
  137. {
  138. for (j = 0; j < i; j++)
  139. {
  140. VariantClear(&Values[j]);
  141. }
  142. break;
  143. } else {
  144. VariantInit(&Values[i]);
  145. hr = WBEM_S_NO_ERROR;
  146. }
  147. }
  148. }
  149. return(hr);
  150. }
  151. HRESULT WmiGetQualifierListByName(
  152. IN IWbemServices *pServices,
  153. IN PWCHAR ClassName,
  154. IN PWCHAR PropertyName,
  155. IN ULONG QualifierCount,
  156. IN PWCHAR *QualifierNames,
  157. IN VARTYPE *Types,
  158. OUT VARIANT /* FREE */ *Values
  159. )
  160. /*+++
  161. Routine Description:
  162. This routine will return the values for a list of qualifiers. If
  163. all qualifiers cannot be returned then none are.
  164. Arguments:
  165. pServices is the IWbemServices pointer
  166. ClassName is the name of the class with qualifiers
  167. PropertyName is the name of the property with qualfiers. If NULL
  168. then class qualifiers are returned
  169. QualifierCount is the count of qualifers to get
  170. QualifierNames is an array contaiing names of qualifiers to get
  171. Types is an array of expected value types for the qualifiers
  172. Values is an array of variants that return with the qualifer values
  173. Return Value:
  174. HRESULT
  175. ---*/
  176. {
  177. HRESULT hr;
  178. IWbemClassObject *pClass;
  179. IWbemQualifierSet *pQualifiers;
  180. ULONG i, j;
  181. WmipAssert(pServices != NULL);
  182. WmipAssert(ClassName != NULL);
  183. WmipAssert(QualifierNames != NULL);
  184. WmipAssert(Types != NULL);
  185. WmipAssert(Values != NULL);
  186. //
  187. // Create the class so we can look at the properties
  188. //
  189. hr = pServices->GetObject(ClassName,
  190. WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  191. NULL,
  192. &pClass,
  193. NULL);
  194. if (hr == WBEM_S_NO_ERROR)
  195. {
  196. if (PropertyName == NULL)
  197. {
  198. hr = pClass->GetQualifierSet(&pQualifiers);
  199. } else {
  200. hr = pClass->GetPropertyQualifierSet(PropertyName,
  201. &pQualifiers);
  202. }
  203. if (hr == WBEM_S_NO_ERROR)
  204. {
  205. for (i = 0; (i < QualifierCount) && (hr == WBEM_S_NO_ERROR); i++)
  206. {
  207. hr = WmiGetQualifier(pQualifiers,
  208. QualifierNames[i],
  209. Types[i],
  210. &Values[i]);
  211. }
  212. if (hr != WBEM_S_NO_ERROR)
  213. {
  214. for (j = 0; j < i; j++)
  215. {
  216. VariantClear(&Values[j]);
  217. }
  218. }
  219. pQualifiers->Release();
  220. }
  221. pClass->Release();
  222. }
  223. return(hr);
  224. }
  225. HRESULT WmiGetProperty(
  226. IN IWbemClassObject *pIWbemClassObject,
  227. IN PWCHAR PropertyName,
  228. IN CIMTYPE ExpectedCimType,
  229. OUT VARIANT /* FREE */ *Value
  230. )
  231. /*+++
  232. Routine Description:
  233. This routine will return the value for a specific property
  234. Arguments:
  235. pIWbemQualifierSet is the qualifier set object
  236. PropertyName is the name of the property
  237. Type is the type of property expected
  238. *Value returns with the value of the property
  239. Return Value:
  240. HRESULT
  241. ---*/
  242. {
  243. HRESULT hr;
  244. CIMTYPE CimType;
  245. WmipAssert(pIWbemClassObject != NULL);
  246. WmipAssert(PropertyName != NULL);
  247. WmipAssert(Value != NULL);
  248. hr = pIWbemClassObject->Get(PropertyName,
  249. 0,
  250. Value,
  251. &CimType,
  252. NULL);
  253. //
  254. // Treat a NULL value for a property as an error
  255. //
  256. if (Value->vt == VT_NULL)
  257. {
  258. hr = WBEM_E_ILLEGAL_NULL;
  259. WmipDebugPrint(("CDMPROV: Property %ws is NULL\n",
  260. PropertyName));
  261. }
  262. //
  263. // Treat CIM_REFERENCE and CIM_STRING as interchangable
  264. //
  265. if ((ExpectedCimType == CIM_REFERENCE) &&
  266. (CimType == CIM_STRING))
  267. {
  268. ExpectedCimType = CIM_STRING;
  269. }
  270. if ((ExpectedCimType == CIM_STRING) &&
  271. (CimType == CIM_REFERENCE))
  272. {
  273. ExpectedCimType = CIM_REFERENCE;
  274. }
  275. if ((hr == WBEM_S_NO_ERROR) && (ExpectedCimType != CimType))
  276. {
  277. WmipDebugPrint(("CDMPROV: Property %ws was expected as %d but was got as %d\n",
  278. PropertyName,
  279. ExpectedCimType,
  280. CimType));
  281. WmipAssert(FALSE);
  282. hr = WBEM_E_FAILED;
  283. VariantClear(Value);
  284. }
  285. return(hr);
  286. }
  287. HRESULT WmiGetPropertyList(
  288. IN IWbemClassObject *pIWbemClassObject,
  289. IN ULONG PropertyCount,
  290. IN PWCHAR *PropertyNames,
  291. IN CIMTYPE *ExpectedCimType,
  292. OUT VARIANT /* FREE */ *Value
  293. )
  294. /*+++
  295. Routine Description:
  296. This routine will return the value for a specific property
  297. Arguments:
  298. pIWbemQualifierSet is the qualifier set object
  299. PropertyNames is the name of the property
  300. Type is the type of property expected
  301. *Value returns with the value of the property
  302. Return Value:
  303. HRESULT
  304. ---*/
  305. {
  306. ULONG i,j;
  307. HRESULT hr;
  308. WmipAssert(pIWbemClassObject != NULL);
  309. WmipAssert(PropertyNames != NULL);
  310. WmipAssert(ExpectedCimType != NULL);
  311. WmipAssert(Value != NULL);
  312. for (i = 0, hr = WBEM_S_NO_ERROR;
  313. (i < PropertyCount) && (hr == WBEM_S_NO_ERROR);
  314. i++)
  315. {
  316. hr = WmiGetProperty(pIWbemClassObject,
  317. PropertyNames[i],
  318. ExpectedCimType[i],
  319. &Value[i]);
  320. }
  321. if (hr != WBEM_S_NO_ERROR)
  322. {
  323. for (j = 0; j < i; j++)
  324. {
  325. VariantClear(&Value[i]);
  326. }
  327. }
  328. return(hr);
  329. }
  330. HRESULT WmiGetPropertyByName(
  331. IN IWbemServices *pServices,
  332. IN PWCHAR ClassName,
  333. IN PWCHAR PropertyName,
  334. IN CIMTYPE ExpectedCimType,
  335. OUT VARIANT /* FREE */ *Value
  336. )
  337. /*+++
  338. Routine Description:
  339. This routine will return the value for a specific property within a
  340. class
  341. Arguments:
  342. pServices is the IWbemServices for the namespace containing your
  343. class
  344. ClassName is the name of the class whose property you are
  345. interested in
  346. PropertyName is the name of the property
  347. Type is the type of property expected
  348. *Value returns with the value of the property
  349. Return Value:
  350. HRESULT
  351. ---*/
  352. {
  353. HRESULT hr;
  354. IWbemClassObject *pClass;
  355. WmipAssert(pServices != NULL);
  356. WmipAssert(ClassName != NULL);
  357. WmipAssert(PropertyName != NULL);
  358. WmipAssert(Value != NULL);
  359. //
  360. // Create the class so we can look at the properties
  361. //
  362. hr = pServices->GetObject(ClassName, 0, NULL, &pClass, NULL);
  363. if (hr == WBEM_S_NO_ERROR)
  364. {
  365. hr = WmiGetProperty(pClass,
  366. PropertyName,
  367. ExpectedCimType,
  368. Value);
  369. pClass->Release();
  370. }
  371. return(hr);
  372. }
  373. HRESULT WmiSetProperty(
  374. IN IWbemClassObject *pIWbemClassObject,
  375. IN PWCHAR PropertyName,
  376. IN VARIANT *Value
  377. )
  378. /*+++
  379. Routine Description:
  380. This routine will set the value of a property to something
  381. Arguments:
  382. pIWbemClassObject is the object whose property is being set
  383. PropertyName is the name of the property being set
  384. Value is the value that the property is being set to
  385. Return Value:
  386. HRESULT
  387. ---*/
  388. {
  389. HRESULT hr;
  390. WmipAssert(pIWbemClassObject != NULL);
  391. WmipAssert(PropertyName != NULL);
  392. WmipAssert(Value != NULL);
  393. hr = pIWbemClassObject->Put(PropertyName,
  394. 0,
  395. Value,
  396. 0);
  397. if (hr == WBEM_E_TYPE_MISMATCH)
  398. {
  399. WmipDebugPrint(("CDMPROV: Put %ws has wrong type %d\n",
  400. PropertyName, Value->vt));
  401. WmipAssert(FALSE);
  402. }
  403. return(hr);
  404. }
  405. HRESULT WmiSetPropertyList(
  406. IN IWbemClassObject *pIWbemClassObject,
  407. IN ULONG PropertyCount,
  408. IN PWCHAR *PropertyNames,
  409. IN VARIANT *Values
  410. )
  411. /*+++
  412. Routine Description:
  413. This routine will set the values of multiple properties to something
  414. Arguments:
  415. pIWbemClassObject is the object whose property is being set
  416. PropertyCount is the number of properties to set
  417. PropertyNames is the names of the property being set
  418. Values is the value that the property is being set to
  419. Return Value:
  420. HRESULT
  421. ---*/
  422. {
  423. ULONG i;
  424. HRESULT hr = WBEM_S_NO_ERROR;
  425. WmipAssert(pIWbemClassObject != NULL);
  426. WmipAssert(PropertyNames != NULL);
  427. WmipAssert(Values != NULL);
  428. for (i = 0; (i < PropertyCount) && (hr == WBEM_S_NO_ERROR); i++)
  429. {
  430. hr = WmiSetProperty(pIWbemClassObject,
  431. PropertyNames[i],
  432. &Values[i]);
  433. }
  434. return(hr);
  435. }
  436. PWCHAR AddSlashesToStringW(
  437. OUT PWCHAR SlashedNamespace,
  438. IN PWCHAR Namespace
  439. )
  440. /*+++
  441. Routine Description:
  442. This routine will convert ever \ in the string into \\. It needs to
  443. do this since WBEM will collapse \\ into \ sometimes.
  444. Arguments:
  445. SlashedNamespace returns with string double slashed
  446. Namespace is the input string
  447. Return Value:
  448. pointer to SlashedNamespace
  449. ---*/
  450. {
  451. PWCHAR Return = SlashedNamespace;
  452. WmipAssert(SlashedNamespace != NULL);
  453. WmipAssert(Namespace != NULL);
  454. //
  455. // MOF likes the namespace paths to be C-style, that is to have a
  456. // '\\' instad of a '\'. So whereever we see a '\', we insert a
  457. // second one
  458. //
  459. while (*Namespace != 0)
  460. {
  461. if (*Namespace == L'\\')
  462. {
  463. *SlashedNamespace++ = L'\\';
  464. }
  465. *SlashedNamespace++ = *Namespace++;
  466. }
  467. *SlashedNamespace = 0;
  468. return(Return);
  469. }
  470. PWCHAR AddSlashesToStringExW(
  471. OUT PWCHAR SlashedNamespace,
  472. IN PWCHAR Namespace
  473. )
  474. /*+++
  475. Routine Description:
  476. This routine will convert ever \ in the string into \\ and " into
  477. \". It needs to do this since WBEM will collapse \\ into \ sometimes.
  478. Arguments:
  479. SlashedNamespace returns with string double slashed
  480. Namespace is the input string
  481. Return Value:
  482. pointer to SlashedNamespace
  483. ---*/
  484. {
  485. PWCHAR Return = SlashedNamespace;
  486. WmipAssert(SlashedNamespace != NULL);
  487. WmipAssert(Namespace != NULL);
  488. //
  489. // MOF likes the namespace paths to be C-style, that is to have a
  490. // '\\' instad of a '\'. So whereever we see a '\', we insert a
  491. // second one. We also need to add a \ before any ".
  492. //
  493. while (*Namespace != 0)
  494. {
  495. if ((*Namespace == L'\\') || (*Namespace == L'"'))
  496. {
  497. *SlashedNamespace++ = L'\\';
  498. }
  499. *SlashedNamespace++ = *Namespace++;
  500. }
  501. *SlashedNamespace = 0;
  502. return(Return);
  503. }
  504. HRESULT WmiConnectToWbem(
  505. IN PWCHAR Namespace,
  506. OUT IWbemServices **ppIWbemServices
  507. )
  508. /*+++
  509. Routine Description:
  510. This routine will establishes a connection to a WBEM namespace on
  511. the local machine.
  512. Arguments:
  513. Namespace is the namespace to which to connect
  514. *ppIWbemServices returns with a IWbemServices * for the namespace
  515. Return Value:
  516. HRESULT
  517. ---*/
  518. {
  519. IWbemLocator *pIWbemLocator;
  520. DWORD hr;
  521. BSTR s;
  522. WmipAssert(Namespace != NULL);
  523. WmipAssert(ppIWbemServices != NULL);
  524. hr = CoCreateInstance(CLSID_WbemLocator,
  525. NULL,
  526. CLSCTX_INPROC_SERVER,
  527. IID_IWbemLocator,
  528. (LPVOID *) &pIWbemLocator);
  529. if (hr == S_OK)
  530. {
  531. s = SysAllocString(Namespace);
  532. if (s != NULL)
  533. {
  534. *ppIWbemServices = NULL;
  535. hr = pIWbemLocator->ConnectServer(s,
  536. NULL, // Userid
  537. NULL, // PW
  538. NULL, // Locale
  539. 0, // flags
  540. NULL, // Authority
  541. NULL, // Context
  542. ppIWbemServices
  543. );
  544. SysFreeString(s);
  545. } else {
  546. *ppIWbemServices = NULL;
  547. hr = WBEM_E_OUT_OF_MEMORY;
  548. }
  549. pIWbemLocator->Release();
  550. }
  551. return(hr);
  552. }
  553. HRESULT CreateInst(
  554. IN IWbemContext *pCtx,
  555. IN IWbemServices * pNamespace,
  556. IN WCHAR * pwcClassName,
  557. OUT /* FREE */ IWbemClassObject ** pNewInst
  558. )
  559. /*+++
  560. Routine Description:
  561. This routine will create a new instance for the specified class
  562. Arguments:
  563. pNamespace is the IWbemServices * to the namespace in which the
  564. class lives
  565. *pNewinst returns with the new instance of the class
  566. pwcClassName has the name of the class whose instance is created
  567. pCtx is the context to use in creating the instance
  568. Return Value:
  569. HRESULT
  570. ---*/
  571. {
  572. HRESULT hr;
  573. IWbemClassObject * pClass;
  574. hr = pNamespace->GetObject(pwcClassName, 0, pCtx, &pClass, NULL);
  575. if (hr != S_OK)
  576. {
  577. return WBEM_E_FAILED;
  578. }
  579. hr = pClass->SpawnInstance(0, pNewInst);
  580. pClass->Release();
  581. WmipDebugPrint(("CDMProv:: Created %ws as %p\n",
  582. pwcClassName, *pNewInst));
  583. return(hr);
  584. }
  585. /* FREE */ BSTR GetCurrentDateTime(
  586. void
  587. )
  588. {
  589. SYSTEMTIME SystemTime;
  590. WBEMTime WbemTime;
  591. GetSystemTime(&SystemTime);
  592. WbemTime = SystemTime;
  593. return(WbemTime.GetBSTR());
  594. }
  595. HRESULT WmiGetArraySize(
  596. IN SAFEARRAY *Array,
  597. OUT LONG *LBound,
  598. OUT LONG *UBound,
  599. OUT LONG *NumberElements
  600. )
  601. /*+++
  602. Routine Description:
  603. This routine will information about the size and bounds of a single
  604. dimensional safe array.
  605. Arguments:
  606. Array is the safe array
  607. *LBound returns with the lower bound of the array
  608. *UBound returns with the upper bound of the array
  609. *NumberElements returns with the number of elements in the array
  610. Return Value:
  611. TRUE if successful else FALSE
  612. ---*/
  613. {
  614. HRESULT hr;
  615. WmipAssert(Array != NULL);
  616. WmipAssert(LBound != NULL);
  617. WmipAssert(UBound != NULL);
  618. WmipAssert(NumberElements != NULL);
  619. //
  620. // Only single dim arrays are supported
  621. //
  622. WmipAssert(SafeArrayGetDim(Array) == 1);
  623. hr = SafeArrayGetLBound(Array, 1, LBound);
  624. if (hr == WBEM_S_NO_ERROR)
  625. {
  626. hr = SafeArrayGetUBound(Array, 1, UBound);
  627. *NumberElements = (*UBound - *LBound) + 1;
  628. }
  629. return(hr);
  630. }
  631. BOOLEAN IsUlongAndStringEqual(
  632. IN ULONG Number,
  633. IN PWCHAR String
  634. )
  635. /*+++
  636. Routine Description:
  637. This routine will convert the passed string to an integer and
  638. compare it to the passed integer value
  639. Arguments:
  640. Number
  641. String
  642. Return Value:
  643. TRUE if equal else FALSE
  644. ---*/
  645. {
  646. ULONG SNumber;
  647. SNumber = _wtoi(String);
  648. return ( (Number == SNumber) ? TRUE : FALSE );
  649. }
  650. HRESULT LookupValueMap(
  651. IN IWbemServices *pServices,
  652. IN PWCHAR ClassName,
  653. IN PWCHAR PropertyName,
  654. IN ULONG Value,
  655. OUT /* FREE */ BSTR *MappedValue
  656. )
  657. /*+++
  658. Routine Description:
  659. This routine will lookup the string value corresponding to an
  660. integer valuemap
  661. Arguments:
  662. pServices is the pointer to the namespace in which the class is
  663. locaed
  664. ClassName is the name of the class
  665. PropertyName is the name of the property
  666. Value is the value of the property and is used to look up the
  667. string that corresponsds to it
  668. *MappedValue returns a string that contains the string which the
  669. value maps to
  670. Return Value:
  671. HRESULT
  672. ---*/
  673. {
  674. PWCHAR Names[2];
  675. VARIANT QualifierValues[2];
  676. VARTYPE Types[2];
  677. HRESULT hr;
  678. BSTR s;
  679. LONG ValuesLBound, ValuesUBound, ValuesElements;
  680. LONG ValueMapLBound, ValueMapUBound, ValueMapElements;
  681. LONG i, Index;
  682. WmipAssert(pServices != NULL);
  683. WmipAssert(ClassName != NULL);
  684. WmipAssert(PropertyName != NULL);
  685. WmipAssert(MappedValue != NULL);
  686. //
  687. // Get the Values and ValueMap qualifiers so we can do the mapping
  688. //
  689. Names[0] = L"Values";
  690. Types[0] = VT_BSTR;
  691. Names[1] = L"ValueMap";
  692. Types[1] = VT_BSTR;
  693. hr = WmiGetQualifierListByName(pServices,
  694. ClassName,
  695. PropertyName,
  696. 2,
  697. Names,
  698. Types,
  699. QualifierValues);
  700. if (hr == WBEM_S_NO_ERROR)
  701. {
  702. //
  703. // Now do a sanity check to make sure the values and valuemaps
  704. // have the same number of elements
  705. //
  706. if (QualifierValues[0].vt == QualifierValues[1].vt)
  707. {
  708. //
  709. // Values and ValueMap both agree that they are both
  710. // scalars or both arrays and are both strings
  711. //
  712. if (QualifierValues[0].vt & VT_ARRAY)
  713. {
  714. //
  715. // We have an array of thing to check for mapping.
  716. // First lets make sure that the arrays have identical
  717. // dimensions
  718. //
  719. hr = WmiGetArraySize(QualifierValues[0].parray,
  720. &ValuesLBound,
  721. &ValuesUBound,
  722. &ValuesElements);
  723. if (hr == WBEM_S_NO_ERROR)
  724. {
  725. hr = WmiGetArraySize(QualifierValues[1].parray,
  726. &ValueMapLBound,
  727. &ValueMapUBound,
  728. &ValueMapElements);
  729. if (hr == WBEM_S_NO_ERROR)
  730. {
  731. if ((ValuesLBound == ValueMapLBound) &&
  732. (ValuesUBound == ValueMapUBound) &&
  733. (ValuesElements == ValueMapElements))
  734. {
  735. for (i = 0; i < ValueMapElements; i++)
  736. {
  737. Index = i + ValueMapLBound;
  738. hr = SafeArrayGetElement(QualifierValues[1].parray,
  739. &Index,
  740. &s);
  741. if (hr == WBEM_S_NO_ERROR)
  742. {
  743. if (IsUlongAndStringEqual(Value,
  744. s))
  745. {
  746. hr = SafeArrayGetElement(QualifierValues[0].parray,
  747. &Index,
  748. MappedValue);
  749. //
  750. // Make sure loop will
  751. // terminate
  752. i = ValueMapElements;
  753. }
  754. SysFreeString(s);
  755. }
  756. }
  757. } else {
  758. hr = WBEM_E_NOT_FOUND;
  759. }
  760. }
  761. }
  762. } else {
  763. //
  764. // We have scalars so this should make a fairly simple
  765. // mapping
  766. //
  767. if (IsUlongAndStringEqual(Value,
  768. QualifierValues[1].bstrVal))
  769. {
  770. *MappedValue = SysAllocString(QualifierValues[0].bstrVal);
  771. if (*MappedValue == NULL)
  772. {
  773. hr = WBEM_E_OUT_OF_MEMORY;
  774. }
  775. } else {
  776. hr = WBEM_E_NOT_FOUND;
  777. }
  778. }
  779. } else {
  780. hr = WBEM_E_NOT_FOUND;
  781. }
  782. VariantClear(&QualifierValues[0]);
  783. VariantClear(&QualifierValues[1]);
  784. }
  785. return(hr);
  786. }
  787. HRESULT GetInstanceOfClass(
  788. IWbemContext *pCtx,
  789. IWbemServices *pServices,
  790. PWCHAR ClassName,
  791. PWCHAR PropertyName,
  792. PWCHAR PropertyValue,
  793. IEnumWbemClassObject **pEnum,
  794. IWbemClassObject **pInstance
  795. )
  796. {
  797. BSTR sWQL, sQuery;
  798. WCHAR Query[2*MAX_PATH];
  799. IEnumWbemClassObject *pEnumInstances;
  800. WCHAR s[MAX_PATH];
  801. HRESULT hr;
  802. ULONG Count;
  803. sWQL = SysAllocString(L"WQL");
  804. if (sWQL != NULL)
  805. {
  806. //
  807. // First get PnP id from Instance name from the MSWmi_PnPDeviceId
  808. // class (select * from MSWMI_PnPDeviceId where InstanceName =
  809. // "<WdmInstanceName>"
  810. //
  811. if (PropertyName != NULL)
  812. {
  813. wsprintfW(Query,
  814. L"select * from %ws where %ws = \"%ws\"",
  815. ClassName,
  816. PropertyName,
  817. AddSlashesToStringW(s, PropertyValue));
  818. } else {
  819. wsprintfW(Query,
  820. L"select * from %ws",
  821. ClassName);
  822. }
  823. sQuery = SysAllocString(Query);
  824. if (sQuery != NULL)
  825. {
  826. hr = pServices->ExecQuery(sWQL,
  827. sQuery,
  828. WBEM_FLAG_FORWARD_ONLY |
  829. WBEM_FLAG_ENSURE_LOCATABLE,
  830. pCtx,
  831. &pEnumInstances);
  832. if (hr == WBEM_S_NO_ERROR)
  833. {
  834. if (pEnum == NULL)
  835. {
  836. hr = pEnumInstances->Next(WBEM_INFINITE,
  837. 1,
  838. pInstance,
  839. &Count);
  840. pEnumInstances->Release();
  841. } else {
  842. *pEnum = pEnumInstances;
  843. }
  844. }
  845. SysFreeString(sQuery);
  846. } else {
  847. hr = WBEM_E_OUT_OF_MEMORY;
  848. }
  849. SysFreeString(sWQL);
  850. } else {
  851. hr = WBEM_E_OUT_OF_MEMORY;
  852. }
  853. return(hr);
  854. }
  855. VARTYPE WmiVarTypeForCimType(
  856. CIMTYPE CimType
  857. )
  858. {
  859. VARTYPE vt;
  860. //
  861. // Most things match their CIM types, except those below
  862. vt = (VARTYPE)CimType;
  863. switch(CimType)
  864. {
  865. case CIM_UINT32:
  866. case CIM_UINT8:
  867. case CIM_SINT8:
  868. {
  869. vt = VT_I4;
  870. break;
  871. }
  872. case CIM_CHAR16:
  873. case CIM_UINT16:
  874. {
  875. vt = VT_I2;
  876. break;
  877. }
  878. {
  879. vt = VT_I4;
  880. break;
  881. }
  882. case CIM_STRING:
  883. case CIM_DATETIME:
  884. case CIM_SINT64:
  885. case CIM_UINT64:
  886. {
  887. vt = VT_BSTR;
  888. break;
  889. }
  890. case CIM_OBJECT:
  891. {
  892. vt = VT_UNKNOWN;
  893. break;
  894. }
  895. case CIM_BOOLEAN:
  896. {
  897. vt = VT_BOOL;
  898. break;
  899. }
  900. }
  901. return(vt);
  902. }
  903. void WmiGetNumberFromVariant(
  904. VARIANT *v,
  905. CIMTYPE VType,
  906. ULONG64 *Number
  907. )
  908. {
  909. if ((VType == CIM_SINT64) || (VType == CIM_UINT64))
  910. {
  911. WmipAssert(v->vt == VT_BSTR);
  912. *Number = _wtoi(v->bstrVal);
  913. } else {
  914. *Number = 0;
  915. switch (v->vt)
  916. {
  917. case VT_UI1:
  918. {
  919. *Number = (ULONG64)v->bVal;
  920. break;
  921. }
  922. case VT_I1:
  923. {
  924. *Number = (ULONG64)v->cVal;
  925. break;
  926. }
  927. case VT_I2:
  928. {
  929. *Number = (ULONG64)v->iVal;
  930. break;
  931. }
  932. case VT_UI2:
  933. {
  934. *Number = (ULONG64)v->uiVal;
  935. break;
  936. }
  937. case VT_UI4:
  938. {
  939. *Number = (ULONG64)v->ulVal;
  940. break;
  941. }
  942. case VT_I4:
  943. {
  944. *Number = (ULONG64)v->lVal;
  945. break;
  946. }
  947. default:
  948. {
  949. WmipAssert(FALSE);
  950. *Number = (ULONG64)v->lVal;
  951. break;
  952. }
  953. }
  954. }
  955. }
  956. HRESULT WmiSetNumberInVariant(
  957. VARIANT *v,
  958. CIMTYPE VType,
  959. ULONG64 Number
  960. )
  961. {
  962. HRESULT hr = WBEM_S_NO_ERROR;
  963. switch (VType)
  964. {
  965. case CIM_UINT8:
  966. case CIM_SINT8:
  967. case CIM_UINT32:
  968. case CIM_SINT32:
  969. {
  970. v->vt = VT_I4;
  971. v->lVal = (LONG)Number;
  972. break;
  973. }
  974. case CIM_CHAR16:
  975. case CIM_UINT16:
  976. {
  977. v->vt = VT_I2;
  978. v->iVal = (SHORT)Number;
  979. break;
  980. }
  981. case CIM_SINT64:
  982. case CIM_UINT64:
  983. {
  984. WCHAR ss[MAX_PATH];
  985. BSTR s;
  986. v->vt = VT_BSTR;
  987. wsprintfW(ss, L"%d", Number);
  988. s = SysAllocString(ss);
  989. if (s != NULL)
  990. {
  991. v->bstrVal = s;
  992. } else {
  993. hr = WBEM_E_OUT_OF_MEMORY;
  994. }
  995. break;
  996. }
  997. default:
  998. {
  999. WmipAssert(FALSE);
  1000. break;
  1001. }
  1002. }
  1003. return(hr);
  1004. }