windows-nt/Source/XPSP1/NT/admin/wmi/wbem/providers/dsprovider/wbemhelp.cpp
2020-09-26 16:20:57 +08:00

729 lines
22 KiB
C++

//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// ***************************************************************************
//
// Original Author: Rajesh Rao
//
// $Author: rajeshr $
// $Date: 6/11/98 4:43p $
// $Workfile:wbemhelp.cpp $
//
// $Modtime: 6/11/98 11:21a $
// $Revision: 1 $
// $Nokeywords: $
//
//
// Description: Contains the implementation the CWBEMHelper class. This is
// a class that has many static helper functions pertaining to WBEM
//***************************************************************************
/////////////////////////////////////////////////////////////////////////
#include "precomp.h"
LPCWSTR CWBEMHelper :: EQUALS_QUOTE = L"=\"";
LPCWSTR CWBEMHelper :: QUOTE = L"\"";
LPCWSTR CWBEMHelper :: OBJECT_CATEGORY_EQUALS = L"objectCategory=";
LPCWSTR CWBEMHelper :: OBJECT_CLASS_EQUALS = L"objectClass=";
//***************************************************************************
//
// CWBEMHelper::PutBSTRProperty
//
// Purpose: Puts a BSTR property
//
// Parameters:
// pWbemClass : The WBEM class on which the property has to be put
// strPropertyName : The name of the property to be put
// strPropertyValue : The value of the property to be put
// deallocatePropertyValue : whether to deallocate the parameter strPropertyValue before
// the function returns
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutBSTRProperty(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
BSTR strPropertyValue,
BOOLEAN deallocatePropertyValue)
{
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_BSTR;
variant.bstrVal = strPropertyValue;
HRESULT result = pWbemClass->Put(strPropertyName, 0, &variant, 0);
if (!deallocatePropertyValue)
variant.bstrVal = NULL;
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper::GetBSTRProperty
//
// Purpose: Gets a BSTR property
//
// Parameters:
// pWbemClass : The WBEM class on which the property has to be gotten
// strPropertyName : The name of the property to be gotten
// pStrPropertyValue : The address where the value of the property to should be put
//
// Return Value: The COM value representing the return status. The user should delete the
// string allocated when done
//
//***************************************************************************
HRESULT CWBEMHelper :: GetBSTRProperty(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
BSTR *pStrPropertyValue)
{
VARIANT variant;
VariantInit(&variant);
HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
if(variant.vt == VT_BSTR && variant.bstrVal)
*pStrPropertyValue = SysAllocString(variant.bstrVal);
else
*pStrPropertyValue = NULL;
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper::PutBSTRPropertyT
//
// Purpose: Puts a BSTR property
//
// Parameters:
// pWbemClass : The WBEM class on which the property has to be put
// strPropertyName : The name of the property to be put
// lpszPropertyValue : The value of the property to be put
// deallocatePropertyValue : whether to deallocate the parameter lpszPropertyValue before
// the function returns
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutBSTRPropertyT(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
LPWSTR lpszPropertyValue,
BOOLEAN deallocatePropertyValue)
{
BSTR strPropertyValue = SysAllocString(lpszPropertyValue);
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_BSTR;
variant.bstrVal = strPropertyValue;
HRESULT result = pWbemClass->Put(strPropertyName, 0, &variant, 0);
if (deallocatePropertyValue)
delete[] lpszPropertyValue;
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper::GetBSTRPropertyT
//
// Purpose: Gets a BSTR property
//
// Parameters:
// pWbemClass : The WBEM class on which the property has to be put
// strPropertyName : The name of the property to be put
// lppszPropertyValue : The pointer to LPWSTR where the value of the property will be placed. The user should
// delete this once he is done with it.
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: GetBSTRPropertyT(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
LPWSTR *lppszPropertyValue)
{
VARIANT variant;
VariantInit(&variant);
HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
if(SUCCEEDED(result))
{
*lppszPropertyValue = new WCHAR[wcslen(variant.bstrVal) + 1];
wcscpy(*lppszPropertyValue, variant.bstrVal);
}
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper::PutBSTRArrayProperty
//
// Purpose: Puts a BSTR Array property
//
// Parameters:
// pWbemClass : The WBEM class on which the property has to be put
// strPropertyName : The name of the property to be put
// pStrPropertyValue : The array of BSTRS that have the values of the property to be put
// lCount : The number of elements in the above array
// deallocatePropertyValue : whether to deallocate the parameter strPropertyValue before
// the function returns
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutBSTRArrayProperty(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
VARIANT *pInputVariant)
{
// THe input is a safe array of variants of type VT_BSTR
// The output is a safe array for VT_BSTRs
LONG lstart, lend;
SAFEARRAY *inputSafeArray = pInputVariant->parray;
// Get the lower and upper bound of the inpute safe array
SafeArrayGetLBound( inputSafeArray, 1, &lstart );
SafeArrayGetUBound( inputSafeArray, 1, &lend );
// Create the output SAFEARRAY
SAFEARRAY *outputSafeArray = NULL;
SAFEARRAYBOUND safeArrayBounds [ 1 ] ;
safeArrayBounds[0].lLbound = lstart ;
safeArrayBounds[0].cElements = lend - lstart + 1 ;
outputSafeArray = SafeArrayCreate (VT_BSTR, 1, safeArrayBounds);
// Fill it
VARIANT inputItem;
VariantInit(&inputItem);
HRESULT result = S_OK;
bool bError = false;
for ( long idx=lstart; !bError && (idx <=lend); idx++ )
{
VariantInit(&inputItem);
SafeArrayGetElement( inputSafeArray, &idx, &inputItem );
if(FAILED(result = SafeArrayPutElement(outputSafeArray, &idx, inputItem.bstrVal)))
bError = true;
VariantClear(&inputItem);
}
// Create the variant
if(SUCCEEDED(result))
{
VARIANT outputVariant;
VariantInit(&outputVariant);
outputVariant.vt = VT_ARRAY | VT_BSTR ;
outputVariant.parray = outputSafeArray ;
result = pWbemClass->Put (strPropertyName, 0, &outputVariant, 0);
VariantClear(&outputVariant);
}
else
SafeArrayDestroy(outputSafeArray);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: PutBOOLQualifier
//
// Purpose: Puts a BOOLEAN Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// bQualifierValue : The value of the qualifier to be put
// lFlavour : The flavour of the qualifer
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutBOOLQualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
VARIANT_BOOL bQualifierValue,
LONG lFlavour)
{
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_BOOL;
variant.boolVal = bQualifierValue;
HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: GetBOOLQualifier
//
// Purpose: Gets a BOOLEAN Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to get
// bQualifierValue : The value of the qualifier to get
// lFlavour : The flavour of the qualifer
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: GetBOOLQualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
VARIANT_BOOL *pbQualifierValue,
LONG *plFlavour)
{
VARIANT variant;
VariantInit(&variant);
HRESULT result = pQualifierSet->Get(strQualifierName, 0, &variant, plFlavour);
if(SUCCEEDED(result))
*pbQualifierValue = variant.boolVal;
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: PutI4Qualifier
//
// Purpose: Puts a VT_I4 Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// lQualifierValue : The value of the qualifier to be put
// lFlavour : The flavour of the qualifer
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutI4Qualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
long lQualifierValue,
LONG lFlavour)
{
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_I4;
variant.lVal = lQualifierValue;
HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: PutLONGQualifier
//
// Purpose: Puts a LONG Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// lQualifierValue : The value of the qualifier to be put
// lFlavour : The flavour of the qualifer
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutLONGQualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
LONG lQualifierValue,
LONG lFlavour)
{
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_I4;
variant.lVal = lQualifierValue;
HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: PutBSTRQualifier
//
// Purpose: Puts a BSTR Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// strQualifierValue : The value of the qualifier to be put
// lFlavour : The flavour of the qualifer
// deallocateQualifierValue : whether to deallocate the parameter strQualifierValue
// before the function returns
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutBSTRQualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
BSTR strQualifierValue,
LONG lFlavour,
BOOLEAN deallocateQualifierValue)
{
VARIANT variant;
VariantInit(&variant);
variant.vt = VT_BSTR;
variant.bstrVal = strQualifierValue;
HRESULT result = pQualifierSet->Put(strQualifierName, &variant, lFlavour);
if(!deallocateQualifierValue)
variant.bstrVal = NULL;
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: GetBSTRQualifierT
//
// Purpose: Gets a BSTR Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// lppszQualifierValue : The address of the LPWSTR where the qualifier value will be put/
// It is the duty of the caller to free this memory when done
// plFlavour : The address where the qualifier flavor will be put. This is optional
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: GetBSTRQualifierT(
IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
LPWSTR *lppszQualifierValue,
LONG *plFlavour)
{
VARIANT variant;
VariantInit(&variant);
HRESULT result = pQualifierSet->Get(strQualifierName, 0, &variant, plFlavour);
if(SUCCEEDED(result))
{
if(variant.vt == VT_BSTR && variant.bstrVal)
{
*lppszQualifierValue = NULL;
if(*lppszQualifierValue = new WCHAR [ wcslen(variant.bstrVal) + 1])
wcscpy(*lppszQualifierValue, variant.bstrVal);
else
result = E_OUTOFMEMORY;
}
else
result = E_FAIL;
}
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper :: PutUint8ArrayQualifier
//
// Purpose: Puts a Uint8 array Qualifier
//
// Parameters:
// pQualifierSet : The Qualifier set on which this qualifier has to be put
// strQualifierName : The name of the qualifier to be put
// lpQualifierValue : The value of the qualifier to be put. An array of BYTEs
// dwLenght : The number of elements in the above array
// lFlavour : The flavour of the qualifer
//
// Return Value: The COM value representing the return status
//
//***************************************************************************
HRESULT CWBEMHelper :: PutUint8ArrayQualifier(IWbemQualifierSet *pQualifierSet,
const BSTR strQualifierName,
LPBYTE lpQualifierValue,
DWORD dwLength,
LONG lFlavour)
{
// Create the variant
VARIANT variant;
VariantInit(&variant);
// Create the SAFEARRAY
SAFEARRAY *safeArray ;
SAFEARRAYBOUND safeArrayBounds [ 1 ] ;
safeArrayBounds[0].lLbound = 0 ;
safeArrayBounds[0].cElements = dwLength ;
safeArray = SafeArrayCreate (VT_I4, 1, safeArrayBounds);
// Fill it
UINT temp;
HRESULT result = S_OK;
bool bError = false;
for (LONG index = 0; !bError && (index<(LONG)dwLength); index++)
{
temp = (UINT)lpQualifierValue[index];
if(FAILED(result = SafeArrayPutElement(safeArray , &index, (LPVOID)&temp)))
bError = true;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_I4 ;
variant.parray = safeArray ;
result = pQualifierSet->Put (strQualifierName, &variant, lFlavour);
VariantClear(&variant);
}
else
SafeArrayDestroy(safeArray);
return result;
}
//***************************************************************************
//
// CWBEMHelper::GetADSIPathFromObjectPath
//
// Purpose: See Header File
//
//***************************************************************************
LPWSTR CWBEMHelper :: GetADSIPathFromObjectPath(LPCWSTR pszObjectRef)
{
// Parse the object path
CObjectPathParser theParser;
ParsedObjectPath *theParsedObjectPath = NULL;
LPWSTR pszADSIPath = NULL;
switch(theParser.Parse((LPWSTR)pszObjectRef, &theParsedObjectPath))
{
case CObjectPathParser::NoError:
{
KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
// Check to see that there is 1 key specified and that its type is VT_BSTR
if(theParsedObjectPath->m_dwNumKeys == 1 && pKeyRef->m_vValue.vt == VT_BSTR)
{
// If the name of the key is specified, check the name
if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_ATTR) != 0)
break;
pszADSIPath = new WCHAR[wcslen((*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal) + 1];
wcscpy(pszADSIPath, (*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal);
}
break;
}
default:
break;
}
// Free the parser object path
theParser.Free(theParsedObjectPath);
return pszADSIPath;
}
//***************************************************************************
//
// CWBEMHelper::GetObjectRefFromADSIPath
//
// Purpose: See Header File
//
//***************************************************************************
BSTR CWBEMHelper :: GetObjectRefFromADSIPath(LPCWSTR pszADSIPath, LPCWSTR pszWBEMClassName)
{
// We need the object path parser to add WMI escape characters
// from the key value which is an ADSI Path
ParsedObjectPath t_ObjectPath;
// Add a key value binding for the ADSIPath
//===========================================
VARIANT vKeyValue;
VariantInit(&vKeyValue);
vKeyValue.vt = VT_BSTR;
vKeyValue.bstrVal = SysAllocString(pszADSIPath);
t_ObjectPath.SetClassName(pszWBEMClassName);
t_ObjectPath.AddKeyRef(ADSI_PATH_ATTR, &vKeyValue);
VariantClear(&vKeyValue);
// Get the Object Path value now
//================================
CObjectPathParser t_Parser;
LPWSTR t_pszObjectPath = NULL;
BSTR retVal = NULL;
if(CObjectPathParser::NoError == t_Parser.Unparse(&t_ObjectPath, &t_pszObjectPath))
{
retVal = SysAllocString(t_pszObjectPath);
delete [] t_pszObjectPath;
}
return retVal;
}
//***************************************************************************
//
// CWBEMHelper::GetUint8ArrayProperty
//
// Purpose: See Header file
//
//***************************************************************************
HRESULT CWBEMHelper :: GetUint8ArrayProperty(IWbemClassObject *pWbemClass,
const BSTR strPropertyName,
LPBYTE *ppPropertyValues,
ULONG *plCount)
{
VARIANT variant;
VariantInit(&variant);
HRESULT result = pWbemClass->Get(strPropertyName, 0, &variant, NULL, NULL);
if(SUCCEEDED(result))
{
if(variant.vt == (VT_ARRAY|VT_UI1))
{
SAFEARRAY *pArray = variant.parray;
BYTE HUGEP *pb;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pb)))
{
if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)))
{
if (SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)))
{
if(*plCount = lUbound - lLbound + 1)
{
*ppPropertyValues = new BYTE[*plCount];
for(DWORD i=0; i<*plCount; i++)
(*ppPropertyValues)[i] = pb[i];
}
}
}
SafeArrayUnaccessData(pArray);
}
}
else
{
*ppPropertyValues = NULL;
*plCount = 0;
}
}
VariantClear(&variant);
return result;
}
//***************************************************************************
//
// CWBEMHelper::FormulateInstanceQuery
//
// Purpose: See Header file
//
//***************************************************************************
HRESULT CWBEMHelper :: FormulateInstanceQuery(IWbemServices *pServices, IWbemContext *pCtx, BSTR strClass, IWbemClassObject *pWbemClass, LPWSTR pszObjectCategory, BSTR strClassQualifier, BSTR strCategoryQualifier)
{
DWORD dwOutput = 0;
pszObjectCategory[dwOutput++] = LEFT_BRACKET_STR[0];
DWORD dwOrPosition = dwOutput;
pszObjectCategory[dwOutput++] = PIPE_STR[0];
HRESULT result = E_FAIL;
if(SUCCEEDED(result = AddSingleCategory(pszObjectCategory, &dwOutput, pWbemClass, strClassQualifier, strCategoryQualifier)))
{
}
/*
IEnumWbemClassObject *pEnum = NULL;
DWORD dwNumObjects = 0;
HRESULT result = pServices->CreateClassEnum(strClass, WBEM_FLAG_DEEP, pCtx, &pEnum);
if(SUCCEEDED(result))
{
IWbemClassObject *pNextObject = NULL;
ULONG lNum = 0;
while(SUCCEEDED(pEnum->Next(WBEM_INFINITE, 1, &pNextObject, &lNum)) && lNum )
{
if(!SUCCEEDED(AddSingleCategory(pszObjectCategory, &dwOutput, pNextObject, strClassQualifier, strCategoryQualifier)))
{
pNextObject->Release();
break;
}
dwNumObjects ++;
pNextObject->Release();
}
pEnum->Release();
}
// Remove the '|' if there is only one element
if(!dwNumObjects)
*/
pszObjectCategory[dwOrPosition] = SPACE_STR[0];
// Terminate the query
pszObjectCategory[dwOutput++] = RIGHT_BRACKET_STR[0];
pszObjectCategory[dwOutput] = NULL;
return result;
}
//***************************************************************************
//
// CWBEMHelper::AddSingleCategory
//
// Purpose: See Header file
//
//***************************************************************************
HRESULT CWBEMHelper :: AddSingleCategory(LPWSTR pszObjectCategory, DWORD *pdwOutput, IWbemClassObject *pNextObject, BSTR strLDAPNameQualifier, BSTR strCategoryQualifier)
{
pszObjectCategory[(*pdwOutput)++] = SPACE_STR[0];
pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
IWbemQualifierSet *pQualifierSet = NULL;
HRESULT result;
if(SUCCEEDED(result = pNextObject->GetQualifierSet(&pQualifierSet)))
{
VARIANT classNameVariant;
if(SUCCEEDED(result = pQualifierSet->Get(strLDAPNameQualifier, 0, &classNameVariant, NULL)))
{
VARIANT categoryVariant;
if(SUCCEEDED(result = pQualifierSet->Get(strCategoryQualifier, 0, &categoryVariant, NULL)))
{
pszObjectCategory[(*pdwOutput)++] = AMPERSAND_STR[0];
pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
wcscpy(pszObjectCategory + *pdwOutput, OBJECT_CATEGORY_EQUALS);
*pdwOutput += wcslen(OBJECT_CATEGORY_EQUALS);
wcscpy(pszObjectCategory + *pdwOutput, categoryVariant.bstrVal);
*pdwOutput += wcslen(categoryVariant.bstrVal);
pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
pszObjectCategory[(*pdwOutput)++] = LEFT_BRACKET_STR[0];
wcscpy(pszObjectCategory + *pdwOutput, OBJECT_CLASS_EQUALS);
*pdwOutput += wcslen(OBJECT_CLASS_EQUALS);
wcscpy(pszObjectCategory + *pdwOutput, classNameVariant.bstrVal);
*pdwOutput += wcslen(classNameVariant.bstrVal);
pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
VariantClear(&categoryVariant);
}
VariantClear(&classNameVariant);
}
pQualifierSet->Release();
}
pszObjectCategory[(*pdwOutput)++] = RIGHT_BRACKET_STR[0];
pszObjectCategory[(*pdwOutput)++] = SPACE_STR[0];
return result;
}
//***************************************************************************
//
// CWBEMHelper::IsPresentInBstrList
//
// Purpose: See Header file
//
//***************************************************************************
BOOLEAN CWBEMHelper :: IsPresentInBstrList(BSTR *pstrProperyNames, DWORD dwNumPropertyNames, BSTR strPropertyName)
{
for(DWORD i=0; i<dwNumPropertyNames; i++)
{
if(_wcsicmp(pstrProperyNames[i], strPropertyName) == 0)
return TRUE;
}
return FALSE;
}