|
|
/*++
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
Module Name:
BMOF.C
Abstract:
Structures and helper functions for naviagating a BMOF file.
History:
a-davj 14-April-97 Created.
--*/
#include <windows.h>
#include <oleauto.h>
#include <string.h>
#include "bmof.h"
#include <wbemutil.h>
wchar_t ToLower(wchar_t c) { wchar_t wideChar ;
if (LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, &c, 1, &wideChar, 1) ==0) { return c; } return wideChar; }
wchar_t wbem_towlower(wchar_t c) { if(c >= 0 && c <= 127) { if(c >= 'A' && c <= 'Z') return c + ('a' - 'A'); else return c; } else return ToLower(c); }
int wbem_wcsicmp( const wchar_t* wsz1, const wchar_t* wsz2) { while(*wsz1 || *wsz2) { int diff = wbem_towlower(*wsz1) - wbem_towlower(*wsz2); if(diff) return diff; wsz1++; wsz2++; }
return 0; }
int wmi_unaligned_wcslen( LPCWSTR wszString ) { BYTE* pbData = (BYTE*) wszString; int i;
// Walk the string looking for two 0 bytes next to each other.
for( i =0; !(!*(pbData) && !*(pbData+1) ); pbData+=2, i++ );
return i; }
WCHAR* wmi_unaligned_wcscpy( WCHAR* wszDest, LPCWSTR wszSource ) { int nLen = wmi_unaligned_wcslen( wszSource );
// Account for the NULL terminator when copying
CopyMemory( (BYTE*) wszDest, (BYTE*) wszSource, (nLen+1) * 2 );
return wszDest; }
//***************************************************************************
//
// BOOL LookupFlavor
//
// DESCRIPTION:
//
// Looks in the flavor table to see if a qualifier has a flavor.
//
// PARAMETERS:
//
// pQual Pointer to the qualifier.
// pdwFlavor Pointer to where the return value is put
// pBuff Pointer to the main buffer. I.e. "BMOF...."
// pToFar Pointer to 1 past the last byte in the buffer
//
//
// RETURN VALUE:
//
// TRUE if there is a flavor. Note that failure is normal
//
//***************************************************************************
BOOL LookupFlavor(BYTE * pQual, DWORD * pdwFlavor, BYTE * pBuff, BYTE * pToFar) { UNALIGNED DWORD * pTemp; BYTE * pFlavorBlob; DWORD dwNumPairs; UNALIGNED DWORD * pOffset; UNALIGNED DWORD * pFlavor; DWORD dwMyOffset; DWORD dwCnt;
*pdwFlavor = 0;
// Calculate the pointer of the start of the flavor data
pTemp = (DWORD * )pBuff; pTemp++; // point to the original blob size
pFlavorBlob = pBuff + *pTemp;
// Dont even try past the end of memory
if(pToFar == NULL) return FALSE;
if(pFlavorBlob + 16 >= pToFar) return FALSE;
// Check if the flavor blob is valid, it should start off with the
// characters "BMOFQUALFLAVOR11"
if(memcmp(pFlavorBlob, "BMOFQUALFLAVOR11", 16)) return FALSE; // Not really a problem since it may be old file
// The flavor part of the file has the format
// DWORD dwNumPair, followed by pairs of dwords;
// offset, flavor
// Determine the number of pairs
pFlavorBlob+= 16; pTemp = (DWORD *)pFlavorBlob; dwNumPairs = *pTemp; // Number of offset/value pairs
if(dwNumPairs < 1) return FALSE;
// point to the first offset/flavor pair
pOffset = pTemp+1; pFlavor = pOffset+1;
// Determine the offset we are looking for. That is the pointer to the qualifier minus
// the pointer to the start of the block;
dwMyOffset = (DWORD)(pQual - pBuff);
for(dwCnt = 0; dwCnt < dwNumPairs; dwCnt++) { if(dwMyOffset == *pOffset) { *pdwFlavor = *pFlavor; } if(dwMyOffset < *pOffset) return FALSE; pOffset += 2; pFlavor += 2; } return FALSE; }
//***************************************************************************
//
// int ITypeSize
//
// DESCRIPTION:
//
// Gets the number of bytes acutally used to store
// a variant type. 0 if the type is unknown
//
// PARAMETERS:
//
// vtTest Type in question.
//
//
// RETURN VALUE:
//
// see description
//
//***************************************************************************
int iTypeSize( IN DWORD vtTest) { int iRet; vtTest &= ~ VT_ARRAY; // get rid of possible array bit
vtTest &= ~ VT_BYREF; // get rid of possible byref bit
switch (vtTest) { case VT_UI1: case VT_LPSTR: iRet = 1; break; case VT_LPWSTR: case VT_BSTR: case VT_I2: iRet = 2; break; case VT_I4: case VT_R4: iRet = 4; break; case VT_R8: iRet = 8; break; case VT_BOOL: iRet = sizeof(VARIANT_BOOL); break; case VT_ERROR: iRet = sizeof(SCODE); break; case VT_CY: iRet = sizeof(CY); break; case VT_DATE: iRet = sizeof(DATE); break;
default: iRet = 0; } return iRet; }
//***************************************************************************
//
// CBMOFQualList * CreateQualList
//
// DESCRIPTION:
//
// Create a CBMOFQualList object which serves as a wrapper.
//
// PARAMETERS:
//
// pwql pointer to the WBEM_Qualifier structure in the binary
// MOF.
//
// RETURN VALUE:
//
// Pointer to CBMOFQualList structure that servers as a wrapper. NULL
// if error. This must be freed via BMOFFree() when no longer needed.
//
//
//***************************************************************************
CBMOFQualList * CreateQualList(UNALIGNED WBEM_QualifierList *pwql) {
CBMOFQualList * pRet = NULL; if(pwql == NULL) return NULL;
pRet = (CBMOFQualList *)BMOFAlloc(sizeof (CBMOFQualList)); if(pRet != NULL) { pRet->m_pql = pwql; pRet->m_pInfo = (UNALIGNED WBEM_Qualifier *) ((BYTE *)pRet->m_pql + sizeof(WBEM_QualifierList));; ResetQualList(pRet); } return pRet; }
//***************************************************************************
//
// void ResetQualList
//
// DESCRIPTION:
//
// Resets CBMOFQualList stucture to point to the first entry.
//
// PARAMETERS:
//
// pql structure to be reset
//
//***************************************************************************
void ResetQualList(CBMOFQualList * pql) { if(pql) { pql->m_CurrQual = 0; pql->m_pCurr = pql->m_pInfo; } }
//***************************************************************************
//
// BOOL NextQual
//
// DESCRIPTION:
//
// Gets the name and value of the next qualifier in the list.
//
// PARAMETERS:
//
// pql Input, points to CBMOFQualList object with data
// ppName Output, if functions succeeds, this points to a
// WCHAR string that the caller must free. May be
// NULL if caller doesnt want name.
// pItem Input/Output, if set, points to a data item structure
// which will be updated to point to the qualifier data.
//
// RETURN VALUE:
//
// TRUE if OK.
//
//
//***************************************************************************
BOOL NextQual(CBMOFQualList * pql,WCHAR ** ppName, CBMOFDataItem * pItem) { return NextQualEx(pql, ppName, pItem, NULL, NULL, NULL); }
//***************************************************************************
//
// BOOL NextQualEx
//
// DESCRIPTION:
//
// Gets the name and value of the next qualifier in the list.
//
// PARAMETERS:
//
// pql Input, points to CBMOFQualList object with data
// ppName Output, if functions succeeds, this points to a
// WCHAR string that the caller must free. May be
// NULL if caller doesnt want name.
// pItem Input/Output, if set, points to a data item structure
// which will be updated to point to the qualifier data.
// pdwFlavor optional, pointer to where the flavor value is to be copied
// if not null, then pBuff must be set!
// pBuff Pointer to the starting byte of the whole blob. Same as
// whats copied to CreateObjList.
// pToFar Pointer to one past the end of the memory buffer
//
// RETURN VALUE:
//
// TRUE if OK.
//
//
//***************************************************************************
BOOL NextQualEx(CBMOFQualList * pql,WCHAR ** ppName, CBMOFDataItem * pItem, DWORD * pdwFlavor, BYTE * pBuff, BYTE * pToFar) { BYTE * pInfo; BOOL bRet = TRUE;
if(pql == NULL || pql->m_CurrQual++ >= pql->m_pql->dwNumQualifiers) return FALSE;
if(pdwFlavor && pBuff) LookupFlavor((BYTE *)pql->m_pCurr, pdwFlavor, pBuff, pToFar); pInfo = (BYTE *)pql->m_pCurr + sizeof(WBEM_Qualifier); if(ppName) SetName(ppName, pInfo, pql->m_pCurr->dwOffsetName);
if(pInfo) bRet = SetValue(pItem, pInfo, pql->m_pCurr->dwOffsetValue, pql->m_pCurr->dwType);
// advance to next
pql->m_pCurr = (UNALIGNED WBEM_Qualifier *)((BYTE *)pql->m_pCurr + pql->m_pCurr->dwLength); return bRet; }
//***************************************************************************
//
// BOOL FindQual
//
// DESCRIPTION:
//
// Searches for a qualifier with a given name. The search is case
// insensitive
//
// PARAMETERS:
//
// pql Input, pointer to qualifier list
// pName Input, Name to be searched for.
// pItem Input/Output, if successful set to point to the data.
//
// RETURN VALUE:
//
// True if OK.
//
//***************************************************************************
BOOL FindQual(CBMOFQualList * pql,WCHAR * pName, CBMOFDataItem * pItem) { return FindQualEx(pql, pName, pItem, NULL, NULL, NULL); }
//***************************************************************************
//
// BOOL FindQualEx
//
// DESCRIPTION:
//
// Searches for a qualifier with a given name. The search is case
// insensitive
//
// PARAMETERS:
//
// pql Input, pointer to qualifier list
// pName Input, Name to be searched for.
// pItem Input/Output, if successful set to point to the data.
// pdwFlavor optional, pointer to where the flavor value is to be copied
// if not null, then pBuff must be set!
// pBuff Pointer to the starting byte of the whole blob. Same as
// whats copied to CreateObjList.
//
// RETURN VALUE:
//
// True if OK.
//
//***************************************************************************
BOOL FindQualEx(CBMOFQualList * pql,WCHAR * pName, CBMOFDataItem * pItem, DWORD * pdwFlavor, BYTE * pBuff, BYTE * pToFar) { DWORD dwCnt; UNALIGNED WBEM_Qualifier * pQual = pql->m_pInfo; for(dwCnt = 0; dwCnt < pql->m_pql->dwNumQualifiers; dwCnt++) { WCHAR * pTest; BOOL bMatch; BYTE * pInfo = (BYTE *)pQual + sizeof(WBEM_Qualifier); if(!SetName(&pTest, pInfo, pQual->dwOffsetName)) return FALSE;
bMatch = !wbem_wcsicmp(pTest, pName); BMOFFree(pTest); if(bMatch) { if(pdwFlavor && pBuff) LookupFlavor((BYTE *)pQual, pdwFlavor, pBuff, pToFar); return SetValue(pItem, pInfo, pQual->dwOffsetValue, pQual->dwType); } pQual = (UNALIGNED WBEM_Qualifier *)((BYTE *)pQual + pQual->dwLength); } return FALSE; }
//***************************************************************************
//
// BOOL SetValue
//
// DESCRIPTION:
//
// Sets up a CBMOFDataItem structure to point to a value in the BMOF.
//
// PARAMETERS:
//
// pItem Input/Output, item to be set
// pInfo Input, start of information block
// dwOffset Input, offset to actual data.
// dwType Input data type.
//
// RETURN VALUE:
//
// TRUE if OK.
//
//***************************************************************************
BOOL SetValue(CBMOFDataItem * pItem, BYTE * pInfo, DWORD dwOffset, DWORD dwType) {
if(pItem == NULL || pInfo == NULL) return FALSE;
pItem->m_dwType = dwType;
// Check for NULL case. This is how uninitialized data is stored.
if(dwOffset == 0xffffffff) pItem->m_pData = NULL; else pItem->m_pData = pInfo + dwOffset;
return TRUE; }
//***************************************************************************
//
// BOOL SetName
//
// DESCRIPTION:
//
// Gets a name out of an information block.
//
// PARAMETERS:
//
// ppName Input/Output. On successful return, will point to a
// WCHAR string containing the name. This MUST be freed
// by the caller via BMOFFree()!
// pInfo Input, start of information block
// dwOffset Input, offset to actual data.
//
// RETURN VALUE:
//
// TRUE if OK.
//***************************************************************************
BOOL SetName(WCHAR ** ppName, BYTE * pInfo, DWORD dwOffset) { UNALIGNED WCHAR * pName; if(ppName == NULL || pInfo == NULL || dwOffset == 0xffffffff) return FALSE;
pName = (UNALIGNED WCHAR *)(pInfo + dwOffset); // point to string in info block
*ppName = (WCHAR *)BMOFAlloc(2*(wmi_unaligned_wcslen((LPWSTR)pName) + 1)); if(*ppName == NULL) return FALSE; wmi_unaligned_wcscpy(*ppName, (LPWSTR)pName); return TRUE; }
//***************************************************************************
//
// CBMOFObj * CreateObj
//
// DESCRIPTION:
//
// Create a CBMOFObj structure which wraps a WBEM_Object
//
// PARAMETERS:
//
// pwob Input, structure to be wrapped
//
// RETURN VALUE:
//
// pointer to wrapper structure. NULL if error. This must be freed via
// BMOFFree() when no longer needed.
//
//***************************************************************************
CBMOFObj * CreateObj(UNALIGNED WBEM_Object * pwob) { CBMOFObj * pRet = (CBMOFObj *)BMOFAlloc(sizeof(CBMOFObj)); if(pRet) { pRet->m_pob = pwob; pRet->m_pInfo = ((BYTE *)pwob) + sizeof(WBEM_Object); pRet->m_ppl = (WBEM_PropertyList*)(pRet->m_pInfo + pwob->dwOffsetPropertyList); pRet->m_pml = (WBEM_PropertyList*)(pRet->m_pInfo + pwob->dwOffsetMethodList); ResetObj(pRet); } return pRet; }
//***************************************************************************
//
// void ResetObj
//
// DESCRIPTION:
//
// Resets a CBMOFObj structure so that it points to its first property.
//
// PARAMETERS:
//
// pob Input/Output, stucture to be reset.
//
//***************************************************************************
void ResetObj(CBMOFObj * pob) { if(pob) { pob->m_CurrProp = 0; pob->m_pCurrProp = (UNALIGNED WBEM_Property *) ((BYTE *)pob->m_ppl + sizeof(WBEM_PropertyList)); pob->m_CurrMeth = 0; pob->m_pCurrMeth = (UNALIGNED WBEM_Property *) ((BYTE *)pob->m_pml + sizeof(WBEM_PropertyList)); } }
//***************************************************************************
//
// CBMOFQualList * GetQualList
//
// DESCRIPTION:
//
// Returns a CBMOFQualList structure which wraps the objects qualifier list.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
//
// RETURN VALUE:
//
// Pointer to CBMOFQualList stucture. NULL if error. Note that this must
// be freed by the caller via BMOFFree()
//
//***************************************************************************
CBMOFQualList * GetQualList(CBMOFObj * pob) {
UNALIGNED WBEM_QualifierList *pql; if(pob->m_pob->dwOffsetQualifierList == 0xffffffff) return NULL; pql = (UNALIGNED WBEM_QualifierList *)((BYTE *)pob->m_pInfo+ pob->m_pob->dwOffsetQualifierList); return CreateQualList(pql); }
//***************************************************************************
//
// CBMOFQualList * GetPropQualList
// CBMOFQualList * GetMethQualList
//
// DESCRIPTION:
//
// Returns a CBMOFQualList structure which wraps a property or
// methods qualifier list.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
// pName Input. Property name. Note that this is case
// insensitive.
//
// RETURN VALUE:
//
// Pointer to CBMOFQualList stucture. NULL if error. Note that this must
// be freed by the caller via BMOFFree()
//
//***************************************************************************
CBMOFQualList * GetPropOrMethQualList(UNALIGNED WBEM_Property * pProp) { if(pProp == NULL) return NULL; if(pProp->dwOffsetQualifierSet == 0xffffffff) return NULL; return CreateQualList((UNALIGNED WBEM_QualifierList *)( (BYTE *)pProp + sizeof(WBEM_Property)+ pProp->dwOffsetQualifierSet)); }
CBMOFQualList * GetPropQualList(CBMOFObj * pob, WCHAR * pName) { UNALIGNED WBEM_Property * pProp = FindPropPtr(pob, pName); return GetPropOrMethQualList(pProp); }
CBMOFQualList * GetMethQualList(CBMOFObj * pob, WCHAR * pName) { UNALIGNED WBEM_Property * pProp = FindMethPtr(pob, pName); return GetPropOrMethQualList(pProp); }
//***************************************************************************
//
// BOOL NextProp
// BOOL NextMet
//
// DESCRIPTION:
//
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
// ppName Output, if functions succeeds, this points to a
// WCHAR string that the caller must free. May be
// NULL if caller doesnt want name.
// pItem Input/Output, if set, points to a data item structure
// which will be updated to point to the qualifier data.
///
// RETURN VALUE:
//
// TRUE if OK.
//***************************************************************************
BOOL Info(UNALIGNED WBEM_Property * pPropOrMeth, WCHAR ** ppName, CBMOFDataItem * pItem) { BYTE * pInfo; BOOL bRet = TRUE; if(pPropOrMeth == NULL) return FALSE;
pInfo = (BYTE *)pPropOrMeth + sizeof(WBEM_Property); if(ppName) { bRet = SetName(ppName, pInfo, pPropOrMeth->dwOffsetName); if(!bRet) return FALSE; } if(pItem) bRet = SetValue(pItem, pInfo, pPropOrMeth->dwOffsetValue, pPropOrMeth->dwType); return bRet; }
BOOL NextProp(CBMOFObj * pob, WCHAR ** ppName, CBMOFDataItem * pItem) { BOOL bRet = TRUE;
if(pob == FALSE || pob->m_CurrProp++ >= pob->m_ppl->dwNumberOfProperties) return FALSE;
if(!Info(pob->m_pCurrProp, ppName, pItem)) return FALSE;
// advance pointer to next property.
pob->m_pCurrProp = (UNALIGNED WBEM_Property *) ((BYTE *)pob->m_pCurrProp + pob->m_pCurrProp->dwLength); return bRet; }
BOOL NextMeth(CBMOFObj * pob, WCHAR ** ppName, CBMOFDataItem * pItem) { BOOL bRet = TRUE;
if(pob == FALSE || pob->m_CurrMeth++ >= pob->m_pml->dwNumberOfProperties) return FALSE;
if(!Info(pob->m_pCurrMeth, ppName, pItem)) return FALSE;
// advance pointer to next method.
pob->m_pCurrMeth = (UNALIGNED WBEM_Property *) ((BYTE *)pob->m_pCurrMeth + pob->m_pCurrMeth->dwLength); return bRet; }
//***************************************************************************
//
// BOOL FindProp
// BOOL FindMeth
//
// DESCRIPTION:
//
// Sets a CBMOFDataItem structure to point to a properties data.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
// pName Input. Name to be use for case insensitve search.
// pItem Input/Output. Data item stucture to be updated.
//
// RETURN VALUE:
//
// True if found.
//
//***************************************************************************
BOOL FindProp(CBMOFObj * pob, WCHAR * pName, CBMOFDataItem * pItem) { UNALIGNED WBEM_Property * pProp = FindPropPtr(pob, pName); return Info(pProp, NULL, pItem); }
BOOL FindMeth(CBMOFObj * pob, WCHAR * pName, CBMOFDataItem * pItem) { UNALIGNED WBEM_Property * pProp = FindMethPtr(pob, pName); return Info(pProp, NULL, pItem); }
//***************************************************************************
//
// BOOL GetName
//
// DESCRIPTION:
//
// Gets the name of an object. This is works be returning the "__Class"
// property.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
// ppName Input/Output. Points to a WCHAR string which
// has the name. The caller MUST free this via
// BMOFFree()
//
// RETURN VALUE:
//
// TRUE if OK.
//
//***************************************************************************
BOOL GetName(CBMOFObj * pob, WCHAR ** ppName) { CBMOFDataItem Item; BOOL bRet = FALSE, bFound; if(pob == NULL || ppName == NULL) return FALSE;
bFound = FindProp(pob, L"__Class", &Item); if(!bFound) return FALSE; if(Item.m_dwType == VT_BSTR && ppName) { bRet = GetData(&Item, (BYTE *)ppName, NULL); } return bRet; }
//***************************************************************************
//
// DWORD GetType
//
// DESCRIPTION:
//
// Returns an objects type. A 0 indicates a class while a 1 indicates an
// instance. A 0xffffffff if passed a null pointer.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
//
//
// RETURN VALUE:
//
// See description.
//
//***************************************************************************
DWORD GetType(CBMOFObj * pob) { if(pob) return pob->m_pob->dwType; else return 0xFFFFFFFF; }
//***************************************************************************
//
// WBEM_Property * FindPropPtr
// WBEM_Property * FindMethPtr
//
// DESCRIPTION:
//
// Returns a WBEM_Property stucture pointer for a particular property or
// method given its name.
//
// PARAMETERS:
//
// pob Input. Structure which wraps the object.
// pName Input. Name of property. Comparison is case
// insensitive.
//
// RETURN VALUE:
//
// pointer to WBEM_Property, NULL if it cant be found.
//
//***************************************************************************
UNALIGNED WBEM_Property * Search(BYTE * pList, DWORD dwListSize, WCHAR * pName) { DWORD dwCnt; UNALIGNED WBEM_Property * pProp = NULL;
// point to first property structure
pProp = (UNALIGNED WBEM_Property *)(pList + sizeof(WBEM_PropertyList));
for(dwCnt = 0; dwCnt < dwListSize; dwCnt++) { WCHAR * pTest; BOOL bMatch;
// point to the property's name and retrieve it
BYTE * pInfo = (BYTE *)pProp + sizeof(WBEM_Property); if(!SetName(&pTest, pInfo, pProp->dwOffsetName)) return NULL; bMatch = !wbem_wcsicmp(pTest, pName); BMOFFree(pTest);
// If we have a match, return
if(bMatch) return pProp;
pProp = (UNALIGNED WBEM_Property *)((BYTE *)pProp + pProp->dwLength); } return NULL; }
UNALIGNED WBEM_Property * FindPropPtr(CBMOFObj * pob, WCHAR * pName) { if(pob == NULL || pName == NULL) return NULL;
// point to first property structure
return Search((BYTE *)pob->m_ppl, pob->m_ppl->dwNumberOfProperties, pName); }
UNALIGNED WBEM_Property * FindMethPtr(CBMOFObj * pob, WCHAR * pName) { if(pob == NULL || pName == NULL) return NULL;
// point to first property structure
return Search((BYTE *)pob->m_pml, pob->m_pml->dwNumberOfProperties, pName); }
//***************************************************************************
//
// CBMOFObjList * CreateObjList
//
// DESCRIPTION:
//
// Create a CBMOFObjList structure which wraps a BMOF file.
//
// PARAMETERS:
//
// pBuff Input, points to start of BMOF file.
//
// RETURN VALUE:
//
// pointer to wrapper structure. NULL if error. This must be freed via
// BMOFFree() when no longer needed.
//
//***************************************************************************
CBMOFObjList * CreateObjList(BYTE * pBuff) { CBMOFObjList * pRet = (CBMOFObjList * )BMOFAlloc(sizeof(CBMOFObjList)); if(pRet) { pRet->m_pol = (WBEM_Binary_MOF *)pBuff; pRet->m_pInfo = (WBEM_Object *) ((BYTE *)pBuff + sizeof(WBEM_Binary_MOF)); ResetObjList(pRet); } return pRet; }
//***************************************************************************
//
// void ResetObjList
//
// DESCRIPTION:
//
// Resets a CBMOFObjList structure so that it points to its first object.
//
// PARAMETERS:
//
// pol Input/Output, stucture to be reset.
//
//***************************************************************************
void ResetObjList(CBMOFObjList * pol) { if(pol) { pol->m_pCurrObj = pol->m_pInfo; pol->m_CurrObj = 0; } }
//***************************************************************************
//
// CBMOFObj * NextObj
//
// DESCRIPTION:
//
// Gets the next object in the list.
//
// PARAMETERS:
//
// pol Input. Pointer to CBMOFObjList object
//
// RETURN VALUE:
//
// Pointer to a CBMOFObj stucture which can be use to access the object
// information. NULL if error. Note that the caller MUST Free this via
// BMOFFree().
//
//***************************************************************************
CBMOFObj * NextObj(CBMOFObjList *pol) { CBMOFObj * pRet;
if(pol == NULL || pol->m_CurrObj++ >= pol->m_pol->dwNumberOfObjects) return NULL;
pRet = CreateObj(pol->m_pCurrObj); pol->m_pCurrObj = (UNALIGNED WBEM_Object *)((BYTE *)pol->m_pCurrObj + pol->m_pCurrObj->dwLength); return pRet; }
//***************************************************************************
//
// CBMOFObj * FindObj
//
// DESCRIPTION:
//
// Searches the object list for the first object which has a "__className"
// property. The search is case insensitive.
//
// PARAMETERS:
//
// pol Input. Pointer to CBMOFObjList object
// pName Input. Name of object being searched for
//
// RETURN VALUE:
//
// Pointer to a CBMOFObj stucture which can be use to access the object
// information. NULL if error. Note that the caller MUST Free this via
// BMOFFree().
//
//***************************************************************************
CBMOFObj * FindObj(CBMOFObjList *pol, WCHAR * pName) { DWORD dwCnt; UNALIGNED WBEM_Object * pob;
if(pol->m_pol == NULL || pName == NULL) return NULL;
pob = pol->m_pInfo; for(dwCnt = 0; dwCnt < pol->m_pol->dwNumberOfObjects; dwCnt) { WCHAR * pwcName = NULL; BOOL bMatch = FALSE;
CBMOFObj * pRet = CreateObj(pob); if(pRet == NULL) return NULL; if(GetName(pRet,&pwcName)) bMatch = TRUE; if(pwcName) BMOFFree(pwcName);
// If we found it, return it, otherwise free object and advance
if(bMatch) return pRet; BMOFFree(pRet); pob = (UNALIGNED WBEM_Object *)((BYTE *)pob + pob->dwLength); } return NULL; }
//***************************************************************************
//
// int GetNumDimensions
//
// DESCRIPTION:
//
// Returns the number of dimensions for a data item.
//
// PARAMETERS:
//
// pItem Input. Item in question.
//
// RETURN VALUE:
// -1 if bogus argument, or if the data item doesnt hold data which would
// be the case for uninitialized properties.
// 0 if non array argument
// n Number of dimensions. Currently only single dimension arrays are
// supported.
//
//***************************************************************************
int GetNumDimensions(CBMOFDataItem * pItem) { UNALIGNED unsigned long * pdwTemp; if(pItem == NULL) return -1; if(!(pItem->m_dwType & VT_ARRAY)) return 0; if(pItem->m_pData == NULL) return -1;
pdwTemp = (unsigned long *)pItem->m_pData; pdwTemp++; // skip past total size
return *pdwTemp; }
//***************************************************************************
//
// int GetNumElements
//
// DESCRIPTION:
//
// Gets the number of elements for an array dimension. Note that 1 is the
// first dimenstion. Currently, only scalars and 1 dimensional arrays are
// supported.
//
// PARAMETERS:
//
// pItem Input. Data item in question.
// lDim Input. Dimension in question. The most significent
// (and for now only) dimension is 0.
//
// RETURN VALUE:
//
// Number of array elements. Note that scalars will return -1.
//
//***************************************************************************
int GetNumElements(CBMOFDataItem * pItem, long lDim) { int iCnt; UNALIGNED DWORD * pdwTemp; int lNumDim = GetNumDimensions(pItem); if(lNumDim == -1 || lDim > lNumDim) return -1; pdwTemp = (UNALIGNED unsigned long *)pItem->m_pData; pdwTemp++; // skip total size
pdwTemp++; // skip number of dimensions
for(iCnt = 0; iCnt < lDim; iCnt++) pdwTemp++; return *pdwTemp; }
//***************************************************************************
//
// BYTE * GetDataElemPtr
//
// DESCRIPTION:
//
// Used to get the pointer to a particular data element. Note that this is
// usually used internally.
//
// PARAMETERS:
//
// pItem Input. Data item to use.
// plDims Input. Pointer to array of dimension values. Note
// that currenly only a single dimension is supported.
// vtSimple Input. Variant type of the data with the VT_ARRAY
// and VT_BYREF bits cleared.
//
// RETURN VALUE:
//
// pointer to the data.
//***************************************************************************
BYTE * GetDataElemPtr(CBMOFDataItem * pItem, long * plDims, DWORD vtSimple) { int iNumDim; DWORD dwTotalDataSize; BYTE * pEndOfData; UNALIGNED DWORD * pdwCurr; UNALIGNED DWORD * pdwCurrObj; BYTE * pRow; int iCnt;
// first check the number of dimensions.
iNumDim = GetNumDimensions(pItem); if(iNumDim == -1) return NULL; if(iNumDim == 0) // simple case of scalar argument
return pItem->m_pData;
// for arrays, the data block starts off with this form,
// dwtotalsize, dwNumDimenstions, dwMostSigDimension... dwLeastSigDimension
// Since currently only 1 dimensional arrays are supported, a 5 element
// array would start with
// dwSize, 1, 5
pdwCurr = (UNALIGNED DWORD *)pItem->m_pData; dwTotalDataSize = *pdwCurr; pEndOfData = pItem->m_pData + dwTotalDataSize; pdwCurr+= 2; // skip to dimension list
pdwCurr += iNumDim; // skip of dimension sizes.
while((BYTE *)pdwCurr < pEndOfData) { // Each row has the format
// dwSizeOfRow, MostSigDimension ... dwLeastSignificentDimension+1,data
// For a one dimensional array, it would just be
// dwSizeOfRow, data
DWORD dwRowSize = *pdwCurr;
// test if this row is ok. Each row of data will have
// a set of Indicies for each higher dimension.
for(iCnt = 0; iCnt < iNumDim-1; iCnt++) { UNALIGNED DWORD * pRowInd = pdwCurr +1 + iCnt; if((long)*pRowInd != plDims[iCnt]) break;
} if(iCnt >= iNumDim -1) { break; // found the row.
}
// go to the next row
pdwCurr = (UNALIGNED DWORD *)((BYTE *)pdwCurr + dwRowSize);
}
if((BYTE *)pdwCurr >= pEndOfData) return NULL;
pRow = (BYTE *)(pdwCurr + 1 + iNumDim -1); for(iCnt = 0; iCnt < plDims[iNumDim-1]; iCnt++) { if(vtSimple == VT_BSTR) pRow += 2*(wmi_unaligned_wcslen((WCHAR *)pRow)+1); else if(vtSimple == VT_EMBEDDED_OBJECT) { // Each embedded object starts off with its own size
pdwCurrObj = (DWORD *)pRow; pRow += *pdwCurrObj;
} else pRow += iTypeSize(vtSimple); }
return pRow;
}
//***************************************************************************
//
// int GetData
//
// DESCRIPTION:
//
//
// PARAMETERS:
//
// pItem Input. Data item to use.
// pRet Input/Output. Pointer to where the data is to be
// copied. For simple data, such as ints, this can just
// be a pointer to an int. For BSTRs, or embedded
// objects, this is treated as a pointer to a pointer
// and it is the responsibility of the caller to free
// the strings via BMOFFree().
// plDims Input. Pointer to array of dimension values. Note
// that currenly only a single dimension is supported.
// The first element in any dimension is 0.
// RETURN VALUE:
//
// Number of bytes of data.
//***************************************************************************
int GetData(CBMOFDataItem * pItem, BYTE * pRet, long * plDims) { DWORD dwSimple; BYTE * pData; CBMOFObj * pObjRet = NULL; dwSimple = pItem->m_dwType &~ VT_ARRAY &~VT_BYREF; pData = GetDataElemPtr(pItem, plDims, dwSimple); if(pData == NULL) return 0; if(dwSimple == VT_BSTR) {
// For strings, a new WCHAR buffer is returned. Note that
// SysAllocString isnt used so as to avoid any Ole dependencies.
BYTE * pStr; DWORD dwSize = 2*(wmi_unaligned_wcslen((WCHAR *)pData)+1);
pStr = BMOFAlloc(dwSize); if(pStr == NULL) return 0; memcpy((void *)pRet, &pStr, sizeof(void *)); wmi_unaligned_wcscpy((WCHAR *)pStr, (WCHAR *)pData); return dwSize; } else if(dwSimple == VT_EMBEDDED_OBJECT) {
// This is the embedded object case.
pObjRet = CreateObj((UNALIGNED WBEM_Object *)pData); memcpy((void *)pRet, &pObjRet, sizeof(void *));
return sizeof(void *); } else { memcpy((void *)pRet, (void *)pData, iTypeSize(dwSimple)); return iTypeSize(dwSimple); } }
|