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.

1094 lines
28 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. BMOF.C
  5. Abstract:
  6. Structures and helper functions for naviagating a BMOF file.
  7. History:
  8. a-davj 14-April-97 Created.
  9. --*/
  10. #include "precomp.h"
  11. #include <string.h>
  12. #include "bmof.h"
  13. #include <wbemutil.h>
  14. //***************************************************************************
  15. //
  16. // int ITypeSize
  17. //
  18. // DESCRIPTION:
  19. //
  20. // Gets the number of bytes acutally used to store
  21. // a variant type. 0 if the type is unknown
  22. //
  23. // PARAMETERS:
  24. //
  25. // vtTest Type in question.
  26. //
  27. //
  28. // RETURN VALUE:
  29. //
  30. // see description
  31. //
  32. //***************************************************************************
  33. int iTypeSize(
  34. IN DWORD vtTest)
  35. {
  36. int iRet;
  37. vtTest &= ~ VT_ARRAY; // get rid of possible array bit
  38. vtTest &= ~ VT_BYREF; // get rid of possible byref bit
  39. switch (vtTest) {
  40. case VT_UI1:
  41. case VT_LPSTR:
  42. iRet = 1;
  43. break;
  44. case VT_LPWSTR:
  45. case VT_BSTR:
  46. case VT_I2:
  47. iRet = 2;
  48. break;
  49. case VT_I4:
  50. case VT_R4:
  51. iRet = 4;
  52. break;
  53. case VT_R8:
  54. iRet = 8;
  55. break;
  56. case VT_BOOL:
  57. iRet = sizeof(VARIANT_BOOL);
  58. break;
  59. case VT_ERROR:
  60. iRet = sizeof(SCODE);
  61. break;
  62. case VT_CY:
  63. iRet = sizeof(CY);
  64. break;
  65. case VT_DATE:
  66. iRet = sizeof(DATE);
  67. break;
  68. default:
  69. iRet = 0;
  70. }
  71. return iRet;
  72. }
  73. //***************************************************************************
  74. //
  75. // CBMOFQualList * CreateQualList
  76. //
  77. // DESCRIPTION:
  78. //
  79. // Create a CBMOFQualList object which serves as a wrapper.
  80. //
  81. // PARAMETERS:
  82. //
  83. // pwql pointer to the WBEM_Qualifier structure in the binary
  84. // MOF.
  85. //
  86. // RETURN VALUE:
  87. //
  88. // Pointer to CBMOFQualList structure that servers as a wrapper. NULL
  89. // if error. This must be freed via BMOFFree() when no longer needed.
  90. //
  91. //
  92. //***************************************************************************
  93. CBMOFQualList * CreateQualList(WBEM_QualifierList *pwql)
  94. {
  95. CBMOFQualList * pRet = NULL;
  96. if(pwql == NULL)
  97. return NULL;
  98. pRet = (CBMOFQualList *)BMOFAlloc(sizeof (CBMOFQualList));
  99. if(pRet != NULL)
  100. {
  101. pRet->m_pql = pwql;
  102. pRet->m_pInfo = (WBEM_Qualifier *)
  103. ((BYTE *)pRet->m_pql + sizeof(WBEM_QualifierList));;
  104. ResetQualList(pRet);
  105. }
  106. return pRet;
  107. }
  108. //***************************************************************************
  109. //
  110. // void ResetQualList
  111. //
  112. // DESCRIPTION:
  113. //
  114. // Resets CBMOFQualList stucture to point to the first entry.
  115. //
  116. // PARAMETERS:
  117. //
  118. // pql structure to be reset
  119. //
  120. //***************************************************************************
  121. void ResetQualList(CBMOFQualList * pql)
  122. {
  123. if(pql)
  124. {
  125. pql->m_CurrQual = 0;
  126. pql->m_pCurr = pql->m_pInfo;
  127. }
  128. }
  129. //***************************************************************************
  130. //
  131. // BOOL NextQual
  132. //
  133. // DESCRIPTION:
  134. //
  135. // Gets the name and value of the next qualifier in the list.
  136. //
  137. // PARAMETERS:
  138. //
  139. // pql Input, points to CBMOFQualList object with data
  140. // ppName Output, if functions succeeds, this points to a
  141. // WCHAR string that the caller must free. May be
  142. // NULL if caller doesnt want name.
  143. // pItem Input/Output, if set, points to a data item structure
  144. // which will be updated to point to the qualifier data.
  145. //
  146. // RETURN VALUE:
  147. //
  148. // TRUE if OK.
  149. //
  150. //
  151. //***************************************************************************
  152. BOOL NextQual(CBMOFQualList * pql,WCHAR ** ppName, CBMOFDataItem * pItem)
  153. {
  154. BYTE * pInfo;
  155. BOOL bRet = TRUE;
  156. if(pql == NULL || pql->m_CurrQual++ >= pql->m_pql->dwNumQualifiers)
  157. return FALSE;
  158. pInfo = (BYTE *)pql->m_pCurr + sizeof(WBEM_Qualifier);
  159. if(ppName)
  160. SetName(ppName, pInfo, pql->m_pCurr->dwOffsetName);
  161. if(pInfo)
  162. bRet = SetValue(pItem, pInfo, pql->m_pCurr->dwOffsetValue,
  163. pql->m_pCurr->dwType);
  164. // advance to next
  165. pql->m_pCurr = (WBEM_Qualifier *)((BYTE *)pql->m_pCurr + pql->m_pCurr->dwLength);
  166. return bRet;
  167. }
  168. //***************************************************************************
  169. //
  170. // BOOL FindQual
  171. //
  172. // DESCRIPTION:
  173. //
  174. // Searches for a qualifier with a given name. The search is case
  175. // insensitive
  176. //
  177. // PARAMETERS:
  178. //
  179. // pql Input, pointer to qualifier list
  180. // pName Input, Name to be searched for.
  181. // pItem Input/Output, if successful set to point to the data.
  182. //
  183. // RETURN VALUE:
  184. //
  185. // True if OK.
  186. //
  187. //***************************************************************************
  188. BOOL FindQual(CBMOFQualList * pql,WCHAR * pName, CBMOFDataItem * pItem)
  189. {
  190. DWORD dwCnt;
  191. WBEM_Qualifier * pQual = pql->m_pInfo;
  192. for(dwCnt = 0; dwCnt < pql->m_pql->dwNumQualifiers; dwCnt++)
  193. {
  194. WCHAR * pTest;
  195. BOOL bMatch;
  196. BYTE * pInfo = (BYTE *)pQual + sizeof(WBEM_Qualifier);
  197. if(!SetName(&pTest, pInfo, pQual->dwOffsetName))
  198. return FALSE;
  199. bMatch = !_wcsicmp(pTest, pName);
  200. BMOFFree(pTest);
  201. if(bMatch)
  202. {
  203. return SetValue(pItem, pInfo, pQual->dwOffsetValue, pQual->dwType);
  204. }
  205. pQual = (WBEM_Qualifier *)((BYTE *)pQual + pQual->dwLength);
  206. }
  207. return FALSE;
  208. }
  209. //***************************************************************************
  210. //
  211. // BOOL SetValue
  212. //
  213. // DESCRIPTION:
  214. //
  215. // Sets up a CBMOFDataItem structure to point to a value in the BMOF.
  216. //
  217. // PARAMETERS:
  218. //
  219. // pItem Input/Output, item to be set
  220. // pInfo Input, start of information block
  221. // dwOffset Input, offset to actual data.
  222. // dwType Input data type.
  223. //
  224. // RETURN VALUE:
  225. //
  226. // TRUE if OK.
  227. //
  228. //***************************************************************************
  229. BOOL SetValue(CBMOFDataItem * pItem, BYTE * pInfo, DWORD dwOffset, DWORD dwType)
  230. {
  231. if(pItem == NULL || pInfo == NULL)
  232. return FALSE;
  233. pItem->m_dwType = dwType;
  234. // Check for NULL case. This is how uninitialized data is stored.
  235. if(dwOffset == 0xffffffff)
  236. pItem->m_pData = NULL;
  237. else
  238. pItem->m_pData = pInfo + dwOffset;
  239. return TRUE;
  240. }
  241. //***************************************************************************
  242. //
  243. // BOOL SetName
  244. //
  245. // DESCRIPTION:
  246. //
  247. // Gets a name out of an information block.
  248. //
  249. // PARAMETERS:
  250. //
  251. // ppName Input/Output. On successful return, will point to a
  252. // WCHAR string containing the name. This MUST be freed
  253. // by the caller via BMOFFree()!
  254. // pInfo Input, start of information block
  255. // dwOffset Input, offset to actual data.
  256. //
  257. // RETURN VALUE:
  258. //
  259. // TRUE if OK.
  260. //***************************************************************************
  261. BOOL SetName(WCHAR ** ppName, BYTE * pInfo, DWORD dwOffset)
  262. {
  263. WCHAR * pName;
  264. if(ppName == NULL || pInfo == NULL || dwOffset == 0xffffffff)
  265. return FALSE;
  266. pName = (WCHAR *)(pInfo + dwOffset); // point to string in info block
  267. *ppName = (WCHAR *)BMOFAlloc(2*(wcslen(pName) + 1));
  268. if(*ppName == NULL)
  269. return FALSE;
  270. wcscpy(*ppName, pName);
  271. return TRUE;
  272. }
  273. //***************************************************************************
  274. //
  275. // CBMOFObj * CreateObj
  276. //
  277. // DESCRIPTION:
  278. //
  279. // Create a CBMOFObj structure which wraps a WBEM_Object
  280. //
  281. // PARAMETERS:
  282. //
  283. // pwob Input, structure to be wrapped
  284. //
  285. // RETURN VALUE:
  286. //
  287. // pointer to wrapper structure. NULL if error. This must be freed via
  288. // BMOFFree() when no longer needed.
  289. //
  290. //***************************************************************************
  291. CBMOFObj * CreateObj(WBEM_Object * pwob)
  292. {
  293. CBMOFObj * pRet = (CBMOFObj *)BMOFAlloc(sizeof(CBMOFObj));
  294. if(pRet)
  295. {
  296. pRet->m_pob = pwob;
  297. pRet->m_pInfo = ((BYTE *)pwob) + sizeof(WBEM_Object);
  298. pRet->m_ppl = (WBEM_PropertyList*)(pRet->m_pInfo +
  299. pwob->dwOffsetPropertyList);
  300. pRet->m_pml = (WBEM_PropertyList*)(pRet->m_pInfo +
  301. pwob->dwOffsetMethodList);
  302. ResetObj(pRet);
  303. }
  304. return pRet;
  305. }
  306. //***************************************************************************
  307. //
  308. // void ResetObj
  309. //
  310. // DESCRIPTION:
  311. //
  312. // Resets a CBMOFObj structure so that it points to its first property.
  313. //
  314. // PARAMETERS:
  315. //
  316. // pob Input/Output, stucture to be reset.
  317. //
  318. //***************************************************************************
  319. void ResetObj(CBMOFObj * pob)
  320. {
  321. if(pob)
  322. {
  323. pob->m_CurrProp = 0;
  324. pob->m_pCurrProp = (WBEM_Property *) ((BYTE *)pob->m_ppl +
  325. sizeof(WBEM_PropertyList));
  326. pob->m_CurrMeth = 0;
  327. pob->m_pCurrMeth = (WBEM_Property *) ((BYTE *)pob->m_pml +
  328. sizeof(WBEM_PropertyList));
  329. }
  330. }
  331. //***************************************************************************
  332. //
  333. // CBMOFQualList * GetQualList
  334. //
  335. // DESCRIPTION:
  336. //
  337. // Returns a CBMOFQualList structure which wraps the objects qualifier list.
  338. //
  339. // PARAMETERS:
  340. //
  341. // pob Input. Structure which wraps the object.
  342. //
  343. // RETURN VALUE:
  344. //
  345. // Pointer to CBMOFQualList stucture. NULL if error. Note that this must
  346. // be freed by the caller via BMOFFree()
  347. //
  348. //***************************************************************************
  349. CBMOFQualList * GetQualList(CBMOFObj * pob)
  350. {
  351. WBEM_QualifierList *pql;
  352. if(pob->m_pob->dwOffsetQualifierList == 0xffffffff)
  353. return NULL;
  354. pql = (WBEM_QualifierList *)((BYTE *)pob->m_pInfo+
  355. pob->m_pob->dwOffsetQualifierList);
  356. return CreateQualList(pql);
  357. }
  358. //***************************************************************************
  359. //
  360. // CBMOFQualList * GetPropQualList
  361. // CBMOFQualList * GetMethQualList
  362. //
  363. // DESCRIPTION:
  364. //
  365. // Returns a CBMOFQualList structure which wraps a property or
  366. // methods qualifier list.
  367. //
  368. // PARAMETERS:
  369. //
  370. // pob Input. Structure which wraps the object.
  371. // pName Input. Property name. Note that this is case
  372. // insensitive.
  373. //
  374. // RETURN VALUE:
  375. //
  376. // Pointer to CBMOFQualList stucture. NULL if error. Note that this must
  377. // be freed by the caller via BMOFFree()
  378. //
  379. //***************************************************************************
  380. CBMOFQualList * GetPropOrMethQualList(WBEM_Property * pProp)
  381. {
  382. if(pProp == NULL)
  383. return NULL;
  384. if(pProp->dwOffsetQualifierSet == 0xffffffff)
  385. return NULL;
  386. return CreateQualList((WBEM_QualifierList *)(
  387. (BYTE *)pProp + sizeof(WBEM_Property)+
  388. pProp->dwOffsetQualifierSet));
  389. }
  390. CBMOFQualList * GetPropQualList(CBMOFObj * pob, WCHAR * pName)
  391. {
  392. WBEM_Property * pProp = FindPropPtr(pob, pName);
  393. return GetPropOrMethQualList(pProp);
  394. }
  395. CBMOFQualList * GetMethQualList(CBMOFObj * pob, WCHAR * pName)
  396. {
  397. WBEM_Property * pProp = FindMethPtr(pob, pName);
  398. return GetPropOrMethQualList(pProp);
  399. }
  400. //***************************************************************************
  401. //
  402. // BOOL NextProp
  403. // BOOL NextMet
  404. //
  405. // DESCRIPTION:
  406. //
  407. //
  408. // PARAMETERS:
  409. //
  410. // pob Input. Structure which wraps the object.
  411. // ppName Output, if functions succeeds, this points to a
  412. // WCHAR string that the caller must free. May be
  413. // NULL if caller doesnt want name.
  414. // pItem Input/Output, if set, points to a data item structure
  415. // which will be updated to point to the qualifier data.
  416. ///
  417. // RETURN VALUE:
  418. //
  419. // TRUE if OK.
  420. //***************************************************************************
  421. BOOL Info(WBEM_Property * pPropOrMeth, WCHAR ** ppName, CBMOFDataItem * pItem)
  422. {
  423. BYTE * pInfo;
  424. BOOL bRet = TRUE;
  425. if(pPropOrMeth == NULL)
  426. return FALSE;
  427. pInfo = (BYTE *)pPropOrMeth + sizeof(WBEM_Property);
  428. if(ppName)
  429. SetName(ppName, pInfo, pPropOrMeth->dwOffsetName);
  430. if(pItem)
  431. bRet = SetValue(pItem, pInfo,
  432. pPropOrMeth->dwOffsetValue,
  433. pPropOrMeth->dwType);
  434. return bRet;
  435. }
  436. BOOL NextProp(CBMOFObj * pob, WCHAR ** ppName, CBMOFDataItem * pItem)
  437. {
  438. BOOL bRet = TRUE;
  439. if(pob == FALSE || pob->m_CurrProp++ >= pob->m_ppl->dwNumberOfProperties)
  440. return FALSE;
  441. Info(pob->m_pCurrProp, ppName, pItem);
  442. // advance pointer to next property.
  443. pob->m_pCurrProp = (WBEM_Property *)
  444. ((BYTE *)pob->m_pCurrProp + pob->m_pCurrProp->dwLength);
  445. return bRet;
  446. }
  447. BOOL NextMeth(CBMOFObj * pob, WCHAR ** ppName, CBMOFDataItem * pItem)
  448. {
  449. BOOL bRet = TRUE;
  450. if(pob == FALSE || pob->m_CurrMeth++ >= pob->m_pml->dwNumberOfProperties)
  451. return FALSE;
  452. Info(pob->m_pCurrMeth, ppName, pItem);
  453. // advance pointer to next method.
  454. pob->m_pCurrMeth = (WBEM_Property *)
  455. ((BYTE *)pob->m_pCurrMeth + pob->m_pCurrMeth->dwLength);
  456. return bRet;
  457. }
  458. //***************************************************************************
  459. //
  460. // BOOL FindProp
  461. // BOOL FindMeth
  462. //
  463. // DESCRIPTION:
  464. //
  465. // Sets a CBMOFDataItem structure to point to a properties data.
  466. //
  467. // PARAMETERS:
  468. //
  469. // pob Input. Structure which wraps the object.
  470. // pName Input. Name to be use for case insensitve search.
  471. // pItem Input/Output. Data item stucture to be updated.
  472. //
  473. // RETURN VALUE:
  474. //
  475. // True if found.
  476. //
  477. //***************************************************************************
  478. BOOL FindProp(CBMOFObj * pob, WCHAR * pName, CBMOFDataItem * pItem)
  479. {
  480. WBEM_Property * pProp = FindPropPtr(pob, pName);
  481. return Info(pProp, NULL, pItem);
  482. }
  483. BOOL FindMeth(CBMOFObj * pob, WCHAR * pName, CBMOFDataItem * pItem)
  484. {
  485. WBEM_Property * pProp = FindMethPtr(pob, pName);
  486. return Info(pProp, NULL, pItem);
  487. }
  488. //***************************************************************************
  489. //
  490. // BOOL GetName
  491. //
  492. // DESCRIPTION:
  493. //
  494. // Gets the name of an object. This is works be returning the "__Class"
  495. // property.
  496. //
  497. // PARAMETERS:
  498. //
  499. // pob Input. Structure which wraps the object.
  500. // ppName Input/Output. Points to a WCHAR string which
  501. // has the name. The caller MUST free this via
  502. // BMOFFree()
  503. //
  504. // RETURN VALUE:
  505. //
  506. // TRUE if OK.
  507. //
  508. //***************************************************************************
  509. BOOL GetName(CBMOFObj * pob, WCHAR ** ppName)
  510. {
  511. CBMOFDataItem Item;
  512. BOOL bRet = FALSE, bFound;
  513. if(pob == NULL || ppName == NULL)
  514. return FALSE;
  515. bFound = FindProp(pob, L"__Class", &Item);
  516. if(!bFound)
  517. return FALSE;
  518. if(Item.m_dwType == VT_BSTR && ppName)
  519. {
  520. bRet = GetData(&Item, (BYTE *)ppName, NULL);
  521. }
  522. return bRet;
  523. }
  524. //***************************************************************************
  525. //
  526. // DWORD GetType
  527. //
  528. // DESCRIPTION:
  529. //
  530. // Returns an objects type. A 0 indicates a class while a 1 indicates an
  531. // instance. A 0xffffffff if passed a null pointer.
  532. //
  533. // PARAMETERS:
  534. //
  535. // pob Input. Structure which wraps the object.
  536. //
  537. //
  538. // RETURN VALUE:
  539. //
  540. // See description.
  541. //
  542. //***************************************************************************
  543. DWORD GetType(CBMOFObj * pob)
  544. {
  545. if(pob)
  546. return pob->m_pob->dwType;
  547. else
  548. return 0xFFFFFFFF;
  549. }
  550. //***************************************************************************
  551. //
  552. // WBEM_Property * FindPropPtr
  553. // WBEM_Property * FindMethPtr
  554. //
  555. // DESCRIPTION:
  556. //
  557. // Returns a WBEM_Property stucture pointer for a particular property or
  558. // method given its name.
  559. //
  560. // PARAMETERS:
  561. //
  562. // pob Input. Structure which wraps the object.
  563. // pName Input. Name of property. Comparison is case
  564. // insensitive.
  565. //
  566. // RETURN VALUE:
  567. //
  568. // pointer to WBEM_Property, NULL if it cant be found.
  569. //
  570. //***************************************************************************
  571. WBEM_Property * Search(BYTE * pList, DWORD dwListSize, WCHAR * pName)
  572. {
  573. DWORD dwCnt;
  574. WBEM_Property * pProp = NULL;
  575. // point to first property structure
  576. pProp = (WBEM_Property *)(pList + sizeof(WBEM_PropertyList));
  577. for(dwCnt = 0; dwCnt < dwListSize; dwCnt++)
  578. {
  579. WCHAR * pTest;
  580. BOOL bMatch;
  581. // point to the property's name and retrieve it
  582. BYTE * pInfo = (BYTE *)pProp + sizeof(WBEM_Property);
  583. if(!SetName(&pTest, pInfo, pProp->dwOffsetName))
  584. return NULL;
  585. bMatch = !_wcsicmp(pTest, pName);
  586. BMOFFree(pTest);
  587. // If we have a match, return
  588. if(bMatch)
  589. return pProp;
  590. pProp = (WBEM_Property *)((BYTE *)pProp + pProp->dwLength);
  591. }
  592. return NULL;
  593. }
  594. WBEM_Property * FindPropPtr(CBMOFObj * pob, WCHAR * pName)
  595. {
  596. if(pob == NULL || pName == NULL)
  597. return NULL;
  598. // point to first property structure
  599. return Search((BYTE *)pob->m_ppl, pob->m_ppl->dwNumberOfProperties, pName);
  600. }
  601. WBEM_Property * FindMethPtr(CBMOFObj * pob, WCHAR * pName)
  602. {
  603. if(pob == NULL || pName == NULL)
  604. return NULL;
  605. // point to first property structure
  606. return Search((BYTE *)pob->m_pml, pob->m_pml->dwNumberOfProperties, pName);
  607. }
  608. //***************************************************************************
  609. //
  610. // CBMOFObjList * CreateObjList
  611. //
  612. // DESCRIPTION:
  613. //
  614. // Create a CBMOFObjList structure which wraps a BMOF file.
  615. //
  616. // PARAMETERS:
  617. //
  618. // pBuff Input, points to start of BMOF file.
  619. //
  620. // RETURN VALUE:
  621. //
  622. // pointer to wrapper structure. NULL if error. This must be freed via
  623. // BMOFFree() when no longer needed.
  624. //
  625. //***************************************************************************
  626. CBMOFObjList * CreateObjList(BYTE * pBuff)
  627. {
  628. CBMOFObjList * pRet = (CBMOFObjList * )BMOFAlloc(sizeof(CBMOFObjList));
  629. if(pRet)
  630. {
  631. pRet->m_pol = (WBEM_Binary_MOF *)pBuff;
  632. pRet->m_pInfo = (WBEM_Object *)
  633. ((BYTE *)pBuff + sizeof(WBEM_Binary_MOF));
  634. ResetObjList(pRet);
  635. }
  636. return pRet;
  637. }
  638. //***************************************************************************
  639. //
  640. // void ResetObjList
  641. //
  642. // DESCRIPTION:
  643. //
  644. // Resets a CBMOFObjList structure so that it points to its first object.
  645. //
  646. // PARAMETERS:
  647. //
  648. // pol Input/Output, stucture to be reset.
  649. //
  650. //***************************************************************************
  651. void ResetObjList(CBMOFObjList * pol)
  652. {
  653. if(pol)
  654. {
  655. pol->m_pCurrObj = pol->m_pInfo;
  656. pol->m_CurrObj = 0;
  657. }
  658. }
  659. //***************************************************************************
  660. //
  661. // CBMOFObj * NextObj
  662. //
  663. // DESCRIPTION:
  664. //
  665. // Gets the next object in the list.
  666. //
  667. // PARAMETERS:
  668. //
  669. // pol Input. Pointer to CBMOFObjList object
  670. //
  671. // RETURN VALUE:
  672. //
  673. // Pointer to a CBMOFObj stucture which can be use to access the object
  674. // information. NULL if error. Note that the caller MUST Free this via
  675. // BMOFFree().
  676. //
  677. //***************************************************************************
  678. CBMOFObj * NextObj(CBMOFObjList *pol)
  679. {
  680. CBMOFObj * pRet;
  681. if(pol == NULL || pol->m_CurrObj++ >= pol->m_pol->dwNumberOfObjects)
  682. return NULL;
  683. pRet = CreateObj(pol->m_pCurrObj);
  684. pol->m_pCurrObj = (WBEM_Object *)((BYTE *)pol->m_pCurrObj + pol->m_pCurrObj->dwLength);
  685. return pRet;
  686. }
  687. //***************************************************************************
  688. //
  689. // CBMOFObj * FindObj
  690. //
  691. // DESCRIPTION:
  692. //
  693. // Searches the object list for the first object which has a "__className"
  694. // property. The search is case insensitive.
  695. //
  696. // PARAMETERS:
  697. //
  698. // pol Input. Pointer to CBMOFObjList object
  699. // pName Input. Name of object being searched for
  700. //
  701. // RETURN VALUE:
  702. //
  703. // Pointer to a CBMOFObj stucture which can be use to access the object
  704. // information. NULL if error. Note that the caller MUST Free this via
  705. // BMOFFree().
  706. //
  707. //***************************************************************************
  708. CBMOFObj * FindObj(CBMOFObjList *pol, WCHAR * pName)
  709. {
  710. DWORD dwCnt;
  711. WBEM_Object * pob;
  712. if(pol->m_pol == NULL || pName == NULL)
  713. return NULL;
  714. pob = pol->m_pInfo;
  715. for(dwCnt = 0; dwCnt < pol->m_pol->dwNumberOfObjects; dwCnt)
  716. {
  717. WCHAR * pwcName = NULL;
  718. BOOL bMatch = FALSE;
  719. CBMOFObj * pRet = CreateObj(pob);
  720. if(pRet == NULL)
  721. return NULL;
  722. if(GetName(pRet,&pwcName))
  723. bMatch = TRUE;
  724. if(pwcName)
  725. BMOFFree(pwcName);
  726. // If we found it, return it, otherwise free object and advance
  727. if(bMatch)
  728. return pRet;
  729. BMOFFree(pRet);
  730. pob = (WBEM_Object *)((BYTE *)pob + pob->dwLength);
  731. }
  732. return NULL;
  733. }
  734. //***************************************************************************
  735. //
  736. // int GetNumDimensions
  737. //
  738. // DESCRIPTION:
  739. //
  740. // Returns the number of dimensions for a data item.
  741. //
  742. // PARAMETERS:
  743. //
  744. // pItem Input. Item in question.
  745. //
  746. // RETURN VALUE:
  747. // -1 if bogus argument, or if the data item doesnt hold data which would
  748. // be the case for uninitialized properties.
  749. // 0 if non array argument
  750. // n Number of dimensions. Currently only single dimension arrays are
  751. // supported.
  752. //
  753. //***************************************************************************
  754. int GetNumDimensions(CBMOFDataItem * pItem)
  755. {
  756. unsigned long * pdwTemp;
  757. if(pItem == NULL)
  758. return -1;
  759. if(!(pItem->m_dwType & VT_ARRAY))
  760. return 0;
  761. if(pItem->m_pData == NULL)
  762. return -1;
  763. pdwTemp = (unsigned long *)pItem->m_pData;
  764. pdwTemp++; // skip past total size
  765. return *pdwTemp;
  766. }
  767. //***************************************************************************
  768. //
  769. // int GetNumElements
  770. //
  771. // DESCRIPTION:
  772. //
  773. // Gets the number of elements for an array dimension. Note that 1 is the
  774. // first dimenstion. Currently, only scalars and 1 dimensional arrays are
  775. // supported.
  776. //
  777. // PARAMETERS:
  778. //
  779. // pItem Input. Data item in question.
  780. // lDim Input. Dimension in question. The most significent
  781. // (and for now only) dimension is 0.
  782. //
  783. // RETURN VALUE:
  784. //
  785. // Number of array elements. Note that scalars will return -1.
  786. //
  787. //***************************************************************************
  788. int GetNumElements(CBMOFDataItem * pItem, long lDim)
  789. {
  790. int iCnt; DWORD * pdwTemp;
  791. int lNumDim = GetNumDimensions(pItem);
  792. if(lNumDim == -1 || lDim > lNumDim)
  793. return -1;
  794. pdwTemp = (unsigned long *)pItem->m_pData;
  795. pdwTemp++; // skip total size
  796. pdwTemp++; // skip number of dimensions
  797. for(iCnt = 0; iCnt < lDim; iCnt++)
  798. pdwTemp++;
  799. return *pdwTemp;
  800. }
  801. //***************************************************************************
  802. //
  803. // BYTE * GetDataElemPtr
  804. //
  805. // DESCRIPTION:
  806. //
  807. // Used to get the pointer to a particular data element. Note that this is
  808. // usually used internally.
  809. //
  810. // PARAMETERS:
  811. //
  812. // pItem Input. Data item to use.
  813. // plDims Input. Pointer to array of dimension values. Note
  814. // that currenly only a single dimension is supported.
  815. // vtSimple Input. Variant type of the data with the VT_ARRAY
  816. // and VT_BYREF bits cleared.
  817. //
  818. // RETURN VALUE:
  819. //
  820. // pointer to the data.
  821. //***************************************************************************
  822. BYTE * GetDataElemPtr(CBMOFDataItem * pItem, long * plDims, DWORD vtSimple)
  823. {
  824. int iNumDim;
  825. DWORD dwTotalDataSize;
  826. BYTE * pEndOfData;
  827. DWORD * pdwCurr;
  828. DWORD * pdwCurrObj;
  829. BYTE * pRow;
  830. int iCnt;
  831. // first check the number of dimensions.
  832. iNumDim = GetNumDimensions(pItem);
  833. if(iNumDim == -1)
  834. return NULL;
  835. if(iNumDim == 0) // simple case of scalar argument
  836. return pItem->m_pData;
  837. // for arrays, the data block starts off with this form,
  838. // dwtotalsize, dwNumDimenstions, dwMostSigDimension... dwLeastSigDimension
  839. // Since currently only 1 dimensional arrays are supported, a 5 element
  840. // array would start with
  841. // dwSize, 1, 5
  842. pdwCurr = (DWORD *)pItem->m_pData;
  843. dwTotalDataSize = *pdwCurr;
  844. pEndOfData = pItem->m_pData + dwTotalDataSize;
  845. pdwCurr+= 2; // skip to dimension list
  846. pdwCurr += iNumDim; // skip of dimension sizes.
  847. while((BYTE *)pdwCurr < pEndOfData)
  848. {
  849. // Each row has the format
  850. // dwSizeOfRow, MostSigDimension ... dwLeastSignificentDimension+1,data
  851. // For a one dimensional array, it would just be
  852. // dwSizeOfRow, data
  853. DWORD dwRowSize = *pdwCurr;
  854. // test if this row is ok. Each row of data will have
  855. // a set of Indicies for each higher dimension.
  856. for(iCnt = 0; iCnt < iNumDim-1; iCnt++)
  857. {
  858. DWORD * pRowInd = pdwCurr +1 + iCnt;
  859. if((long)*pRowInd != plDims[iCnt])
  860. break;
  861. }
  862. if(iCnt >= iNumDim -1)
  863. {
  864. break; // found the row.
  865. }
  866. // go to the next row
  867. pdwCurr = (DWORD *)((BYTE *)pdwCurr + dwRowSize);
  868. }
  869. if((BYTE *)pdwCurr >= pEndOfData)
  870. return NULL;
  871. pRow = (BYTE *)(pdwCurr + 1 + iNumDim -1);
  872. for(iCnt = 0; iCnt < plDims[iNumDim-1]; iCnt++)
  873. {
  874. if(vtSimple == VT_BSTR)
  875. pRow += 2*(wcslen((WCHAR *)pRow)+1);
  876. else if(vtSimple == VT_EMBEDDED_OBJECT)
  877. {
  878. // Each embedded object starts off with its own size
  879. pdwCurrObj = (DWORD *)pRow;
  880. pRow += *pdwCurrObj;
  881. }
  882. else
  883. pRow += iTypeSize(vtSimple);
  884. }
  885. return pRow;
  886. }
  887. //***************************************************************************
  888. //
  889. // int GetData
  890. //
  891. // DESCRIPTION:
  892. //
  893. //
  894. // PARAMETERS:
  895. //
  896. // pItem Input. Data item to use.
  897. // pRet Input/Output. Pointer to where the data is to be
  898. // copied. For simple data, such as ints, this can just
  899. // be a pointer to an int. For BSTRs, or embedded
  900. // objects, this is treated as a pointer to a pointer
  901. // and it is the responsibility of the caller to free
  902. // the strings via BMOFFree().
  903. // plDims Input. Pointer to array of dimension values. Note
  904. // that currenly only a single dimension is supported.
  905. // The first element in any dimension is 0.
  906. // RETURN VALUE:
  907. //
  908. // Number of bytes of data.
  909. //***************************************************************************
  910. int GetData(CBMOFDataItem * pItem, BYTE * pRet, long * plDims)
  911. {
  912. DWORD dwSimple;
  913. BYTE * pData;
  914. long * pLong = (long *)pRet; // easier for returning strings and embedded objs.
  915. dwSimple = pItem->m_dwType &~ VT_ARRAY &~VT_BYREF;
  916. pData = GetDataElemPtr(pItem, plDims, dwSimple);
  917. if(pData == NULL)
  918. return 0;
  919. if(dwSimple == VT_BSTR)
  920. {
  921. // For strings, a new WCHAR buffer is returned. Note that
  922. // SysAllocString isnt used so as to avoid any Ole dependencies.
  923. BYTE * pStr;
  924. DWORD dwSize = 2*(wcslen((WCHAR *)pData)+1);
  925. pStr = BMOFAlloc(dwSize);
  926. *pLong = (long)pStr;
  927. wcscpy((WCHAR *)pStr, (WCHAR *)pData);
  928. return dwSize;
  929. }
  930. else if(dwSimple == VT_EMBEDDED_OBJECT)
  931. {
  932. // This is the embedded object case.
  933. *pLong = (long) CreateObj((WBEM_Object *)pData);
  934. return sizeof(long);
  935. }
  936. else
  937. {
  938. memcpy((void *)pRet, (void *)pData, iTypeSize(dwSimple));
  939. return iTypeSize(dwSimple);
  940. }
  941. }