Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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