1281 lines
34 KiB
C
1281 lines
34 KiB
C
/*++
|
|
|
|
|
|
|
|
// 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>
|
|
|
|
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 = !_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)
|
|
SetName(ppName, pInfo, pPropOrMeth->dwOffsetName);
|
|
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;
|
|
|
|
Info(pob->m_pCurrProp, ppName, pItem);
|
|
|
|
// 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;
|
|
|
|
Info(pob->m_pCurrMeth, ppName, pItem);
|
|
|
|
// 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 = !_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);
|
|
}
|
|
}
|
|
|