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.

1262 lines
33 KiB

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