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.

1280 lines
34 KiB

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