windows-nt/Source/XPSP1/NT/inetsrv/iis/admin/wmiprov_dynamic/utils.cpp
2020-09-26 16:20:57 +08:00

1126 lines
23 KiB
C++

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
utils.cpp
Abstract:
General purpose utilities
Author:
???
Revision History:
Mohit Srivastava 18-Dec-00
--*/
#include "iisprov.h"
#include "iiswmimsg.h"
extern CDynSchema* g_pDynSch;
extern HMODULE g_hModule;
BSTR CUtils::ExtractBstrFromVt(
const VARIANT* i_pvt,
LPCWSTR i_wszVtName) // default(NULL)
/*++
Synopsis:
This is different from VARAINT::ChangeType in that it handles conversion
from VT_NULL also.
Arguments: [i_pvt] -
Return Value:
BSTR: If non-null, points to i_pvt->bstrVal
--*/
{
DBG_ASSERT(i_pvt != NULL);
switch(i_pvt->vt)
{
case VT_BSTR:
return i_pvt->bstrVal;
case VT_NULL:
return NULL;
default:
CIIsProvException e;
e.SetHR(DISP_E_TYPEMISMATCH, i_wszVtName);
throw e;
}
return NULL;
}
LONG CUtils::ExtractLongFromVt(
const VARIANT* i_pvt,
LPCWSTR i_wszVtName) //default(NULL)
{
DBG_ASSERT(i_pvt);
try
{
_variant_t svt;
svt = *i_pvt;
return (long)svt;
}
catch(_com_error ce)
{
CIIsProvException e;
e.SetHR(ce.Error(), i_wszVtName);
throw e;
}
}
bool CUtils::CompareKeyType(
LPCWSTR i_wszKeyFromMb,
METABASE_KEYTYPE* i_pktKeyCompare)
{
DBG_ASSERT(i_wszKeyFromMb);
DBG_ASSERT(i_pktKeyCompare);
if(!i_pktKeyCompare->m_pszName)
{
return false;
}
if(_wcsicmp(i_wszKeyFromMb, i_pktKeyCompare->m_pszName) == 0)
{
return true;
}
//
// If i_wszKeyFromMb is not in our hashtable and i_wszKeyCompare is
// IIsObject, treat as a match.
//
METABASE_KEYTYPE* pKt = NULL;
HRESULT hr = g_pDynSch->GetHashKeyTypes()->Wmi_GetByKey(i_wszKeyFromMb, &pKt);
if( FAILED(hr) && i_pktKeyCompare == &METABASE_KEYTYPE_DATA::s_IIsObject )
{
return true;
}
return false;
}
bool CUtils::CompareMultiSz(
WCHAR* i_msz1,
WCHAR* i_msz2
)
{
if(i_msz1 == NULL && i_msz2 == NULL)
return true;
else if(i_msz1 == NULL || i_msz2 == NULL)
return false;
// compare the two multisz buffers.
for ( ; (*i_msz1 && *i_msz2); )
{
if (_wcsicmp(i_msz1, i_msz2) != NULL)
return false;
i_msz1 += wcslen(i_msz1) + 1;
i_msz2 += wcslen(i_msz2) + 1;
}
if (!*i_msz1 && !*i_msz2)
{
return true;
}
return false;
}
HRESULT CUtils::LoadSafeArrayFromByteArray(
LPBYTE i_aBytes,
DWORD i_iBytes,
_variant_t& io_vt
)
{
DBG_ASSERT(i_aBytes != NULL);
HRESULT hr = S_OK;
SAFEARRAY* pSafeArray = NULL;
SAFEARRAYBOUND safeArrayBounds[1];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = i_iBytes;
pSafeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBounds);
if(pSafeArray == NULL)
{
hr = WBEM_E_OUT_OF_MEMORY;
goto exit;
}
for(ULONG idx = 0; idx < i_iBytes; idx++)
{
hr = SafeArrayPutElement(pSafeArray, (LONG *)&idx, &i_aBytes[idx]);
if(FAILED(hr))
{
goto exit;
}
}
//
// If everything succeeded, set out parameters.
//
io_vt.vt = VT_UI1 | VT_ARRAY;
io_vt.parray = pSafeArray;
exit:
if(FAILED(hr))
{
if(pSafeArray != NULL)
{
SafeArrayDestroy(pSafeArray);
}
}
return hr;
}
//
// CreateByteArrayFromSafeArray
//
HRESULT CUtils::CreateByteArrayFromSafeArray(
_variant_t& i_vt,
LPBYTE* o_paBytes,
DWORD* io_pdw
)
{
DBG_ASSERT(i_vt.vt == (VT_ARRAY | VT_UI1));
DBG_ASSERT(o_paBytes != NULL);
DBG_ASSERT(io_pdw != NULL);
if(i_vt.parray == NULL)
{
*o_paBytes = NULL;
*io_pdw = 0;
}
HRESULT hr = S_OK;
LONG iLo = 0;
LONG iUp = 0;
LPBYTE aBytes = NULL;
hr = SafeArrayGetLBound(i_vt.parray,1,&iLo);
if(FAILED(hr))
{
goto exit;
}
hr = SafeArrayGetUBound(i_vt.parray,1,&iUp);
if(FAILED(hr))
{
goto exit;
}
aBytes = new BYTE[iUp-iLo+1];
if(aBytes == NULL)
{
hr = WBEM_E_OUT_OF_MEMORY;
goto exit;
}
for(LONG i = iLo; i <= iUp; i++)
{
hr = SafeArrayGetElement(i_vt.parray, &i, &aBytes[i-iLo]);
if(FAILED(hr))
{
goto exit;
}
}
//
// If everything succeeded, set out parameters.
//
*o_paBytes = aBytes;
*io_pdw = iUp-iLo+1;
exit:
if(FAILED(hr))
{
delete [] aBytes;
}
return hr;
}
bool CUtils::CompareByteArray(
LPBYTE i_aBytes1,
ULONG i_iBytes1,
LPBYTE i_aBytes2,
ULONG i_iBytes2
)
{
if(i_aBytes1 == NULL && i_aBytes2 == NULL)
{
return true;
}
if(i_aBytes1 == NULL || i_aBytes2 == NULL)
{
return false;
}
if(i_iBytes1 != i_iBytes2)
{
return false;
}
for(ULONG i = 0; i < i_iBytes1; i++)
{
if(i_aBytes1[i] != i_aBytes2[i])
{
return false;
}
}
return true;
}
KeyRef* CUtils::GetKey(
ParsedObjectPath* i_pParsedObjectPath,
WCHAR* i_wsz
)
/*++
Synopsis:
Return the KeyRef pointer from the ParsedObjectPath for the given string.
Arguments: [i_pParsedObjectPath] -
[i_wsz] -
Return Value:
--*/
{
KeyRef* pkr;
DWORD numkeys = i_pParsedObjectPath->m_dwNumKeys;
DWORD c;
if(numkeys == 1)
{
pkr = *(i_pParsedObjectPath->m_paKeys);
if(pkr->m_pName == NULL)
{
return pkr;
}
}
for ( c=0; numkeys; numkeys--,c++ )
{
pkr = *(i_pParsedObjectPath->m_paKeys + c);
if (!_wcsicmp(pkr->m_pName,i_wsz))
return pkr;
}
CIIsProvException e;
e.SetMC(WBEM_E_INVALID_OBJECT, IISWMI_NO_PRIMARY_KEY, i_wsz);
throw e;
}
bool CUtils::GetAssociation(
LPCWSTR i_wszAssocName,
WMI_ASSOCIATION** o_ppAssoc
)
/*++
Synopsis:
Association i_wszAssocName is returned in o_ppAssoc if found.
Arguments: [i_wszAssocName] -
[o_ppAssoc] -
Return Value:
true if found
false otherwise
--*/
{
DBG_ASSERT(o_ppAssoc != NULL);
HRESULT hr;
hr = g_pDynSch->GetHashAssociations()->Wmi_GetByKey(
(LPWSTR)i_wszAssocName,
o_ppAssoc);
if(SUCCEEDED(hr))
{
return true;
}
else
{
return false;
}
}
bool CUtils::GetClass(
LPCWSTR i_wszClassName,
WMI_CLASS** o_ppClass
)
/*++
Synopsis:
Class i_wszClassName is returned in o_ppClass if found.
Arguments: [i_wszClassName] -
[o_ppClass] -
Return Value:
true if found
false otherwise
--*/
{
DBG_ASSERT(o_ppClass != NULL);
HRESULT hr;
hr = g_pDynSch->GetHashClasses()->Wmi_GetByKey(
(LPWSTR)i_wszClassName,
o_ppClass);
if(SUCCEEDED(hr))
{
return true;
}
else
{
return false;
}
}
bool CUtils::GetMethod(
LPCWSTR i_wszMethod,
WMI_METHOD** i_apMethodList,
WMI_METHOD** o_ppMethod
)
/*++
Synopsis:
The Method descriptor for i_wszMethod is returned via o_ppMethod if found
Arguments: [i_wszMethod] -
[i_apMethodList] -
[o_ppMethod] -
Return Value:
true if found.
false otherwise.
--*/
{
DBG_ASSERT(i_wszMethod != NULL);
DBG_ASSERT(o_ppMethod != NULL);
WMI_METHOD** ppmethod;
if(i_apMethodList == NULL)
{
return false;
}
for (ppmethod = i_apMethodList; *ppmethod != NULL;ppmethod++)
{
if (_wcsicmp(i_wszMethod,(*ppmethod)->pszMethodName) ==0)
{
*o_ppMethod = *ppmethod;
return true;
}
}
return false;
}
HRESULT CUtils::ConstructObjectPath(
LPCWSTR i_wszMbPath,
const WMI_CLASS* i_pClass,
BSTR* o_pbstrPath)
{
DBG_ASSERT(i_wszMbPath != NULL);
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(o_pbstrPath != NULL);
DBG_ASSERT(*o_pbstrPath == NULL);
CComBSTR sbstrPath;
ULONG cchPrefix = wcslen(i_pClass->pszMetabaseKey);
DBG_ASSERT(cchPrefix <= wcslen(i_wszMbPath));
LPCWSTR wszSuffix = &i_wszMbPath[cchPrefix];
if(wszSuffix[0] == L'/')
{
wszSuffix++;
}
sbstrPath = i_pClass->pszClassName;
if(sbstrPath.m_str == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
sbstrPath += L"='";
if(sbstrPath.m_str == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
sbstrPath += wszSuffix;
if(sbstrPath.m_str == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
sbstrPath += L"'";
if(sbstrPath.m_str == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
*o_pbstrPath = sbstrPath.Detach();
return S_OK;
}
void CUtils::GetMetabasePath(
IWbemClassObject* io_pObj,
ParsedObjectPath* i_pParsedObjectPath,
WMI_CLASS* i_pClass,
_bstr_t& io_bstrPath)
/*++
Synopsis:
Populates io_bstrPath and sets the key field in IWbemClassObject
Arguments: [io_pObj] -
[i_pParsedObjectPath] -
[i_pClass] -
[io_bstrPath] -
--*/
{
KeyRef* pkr;
LPWSTR wszWmiKey = i_pClass->pszKeyName;
DBG_ASSERT(i_pParsedObjectPath != NULL);
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(wszWmiKey != NULL);
DBG_ASSERT(i_pClass->pszMetabaseKey != NULL);
pkr = GetKey(i_pParsedObjectPath, wszWmiKey);
DBG_ASSERT(pkr != NULL);
if (io_pObj)
{
_bstr_t bstr;
if(pkr->m_pName == NULL)
{
bstr = wszWmiKey;
}
else
{
bstr = pkr->m_pName;
}
HRESULT hr = io_pObj->Put(bstr, 0, &pkr->m_vValue, 0);
THROW_ON_ERROR(hr);
}
io_bstrPath = i_pClass->pszMetabaseKey;
switch ((pkr)->m_vValue.vt)
{
case VT_I4:
{
WCHAR wszBuf[32] = {0};
io_bstrPath += L"/";
io_bstrPath += _itow(pkr->m_vValue.lVal, wszBuf, 10);
break;
}
case VT_BSTR:
{
io_bstrPath += L"/";
io_bstrPath += pkr->m_vValue.bstrVal;
break;
}
}
return;
}
HRESULT CUtils::GetParentMetabasePath(
LPCWSTR i_wszChildPath,
LPWSTR io_wszParentPath)
/*++
Synopsis:
Eg. /LM/w3svc/1 => /LM/w3svc/
/ => E_FAIL
Arguments: [i_wszChildPath] -
[io_wszParentPath] - Should be allocated by caller to at least same
size as i_wszChildPath.
Return Value:
E_FAIL
S_OK
--*/
{
DBG_ASSERT(i_wszChildPath != NULL);
DBG_ASSERT(io_wszParentPath != NULL);
ULONG cchChildPath = wcslen(i_wszChildPath);
BOOL bParentFound = false;
//
// This should trim all the ending L'/'
//
while(cchChildPath > 0 && i_wszChildPath[cchChildPath-1] == L'/')
{
cchChildPath--;
}
if(cchChildPath <= 1)
{
//
// does not have a parent
//
return E_FAIL;
}
for(LONG i = cchChildPath-1; i >= 0; i--)
{
if(i_wszChildPath[i] == L'/')
{
bParentFound = true;
break;
}
}
if(!bParentFound)
{
return E_FAIL;
}
memcpy(io_wszParentPath, i_wszChildPath, (i+1)*sizeof(WCHAR));
io_wszParentPath[i+1] = L'\0';
return S_OK;
}
void CUtils::Throw_Exception(
HRESULT a_hr,
METABASE_PROPERTY* a_pmbp
)
{
CIIsProvException t_e;
t_e.SetHR(a_hr, a_pmbp->pszPropName);
throw(t_e);
}
//
// io_wszDateTime should be allocated outside with 30 elements
//
void CUtils::FileTimeToWchar(FILETIME *i_pFileTime, LPWSTR io_wszDateTime)
{
DBG_ASSERT(i_pFileTime != NULL);
DBG_ASSERT(io_wszDateTime != NULL);
SYSTEMTIME systime;
if(FileTimeToSystemTime(i_pFileTime, &systime) == 0)
{
THROW_ON_ERROR(HRESULT_FROM_WIN32(GetLastError()));
}
swprintf(
io_wszDateTime,
L"%04d%02d%02d%02d%02d%02d.%06d+000",
systime.wYear,
systime.wMonth,
systime.wDay,
systime.wHour,
systime.wMinute,
systime.wSecond,
systime.wMilliseconds
);
}
//
// Below this line, added by Mohit
//
HRESULT CUtils::CreateEmptyMethodInstance(
CWbemServices* i_pNamespace,
IWbemContext* i_pCtx,
LPCWSTR i_wszClassName,
LPCWSTR i_wszMethodName,
IWbemClassObject** o_ppMethodInstance)
/*++
Synopsis:
Generally used when executing a WMI method that has out parameters.
Arguments:
--*/
{
DBG_ASSERT(i_pNamespace != NULL);
DBG_ASSERT(i_pCtx != NULL);
DBG_ASSERT(i_wszClassName != NULL);
DBG_ASSERT(i_wszMethodName != NULL);
DBG_ASSERT(o_ppMethodInstance != NULL);
CComPtr<IWbemClassObject> spClass;
CComPtr<IWbemClassObject> spMethodClass;
CComPtr<IWbemClassObject> spMethodInstance;
HRESULT hr = S_OK;
hr = i_pNamespace->GetObject(_bstr_t(i_wszClassName), 0, i_pCtx, &spClass, NULL);
if(FAILED(hr))
{
goto exit;
}
hr = spClass->GetMethod(i_wszMethodName, 0, NULL, &spMethodClass);
if(FAILED(hr))
{
goto exit;
}
hr = spMethodClass->SpawnInstance(0, &spMethodInstance);
if(FAILED(hr))
{
goto exit;
}
//
// If everything succeeded, set out parameters
//
*o_ppMethodInstance = spMethodInstance;
(*o_ppMethodInstance)->AddRef();
exit:
return hr;
}
HRESULT CUtils::GetQualifiers(
IWbemClassObject* i_pClass,
LPCWSTR* i_awszQualNames,
VARIANT* io_aQualValues,
ULONG i_NrQuals
)
/*++
Synopsis:
Gets Qualifiers.
Arguments: [i_pClass] -
[i_awszQualNames] - An array of size i_NrQuals with names of quals.
[io_aQualValues] - An array of size i_NrQuals with empty variants.
Will be populated on success.
[i_NrQuals] -
--*/
{
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(i_awszQualNames != NULL);
DBG_ASSERT(io_aQualValues != NULL);
HRESULT hr = S_OK;
ULONG i = 0;
CComPtr<IWbemQualifierSet> spQualSet = NULL;
hr = i_pClass->GetQualifierSet(&spQualSet);
if(FAILED(hr))
{
goto exit;
}
// Looking for qualifiers
for(i = 0; i < i_NrQuals; i++)
{
DBG_ASSERT(i_awszQualNames[i] != NULL);
hr = spQualSet->Get(i_awszQualNames[i], 0, &io_aQualValues[i], NULL);
if(FAILED(hr) && hr != WBEM_E_NOT_FOUND)
{
break;
}
hr = WBEM_S_NO_ERROR;
}
if(FAILED(hr))
{
for(i = 0; i < i_NrQuals; i++)
{
VariantClear(&io_aQualValues[i]);
}
if(FAILED(hr))
{
goto exit;
}
}
exit:
return hr;
}
HRESULT CUtils::GetPropertyQualifiers(
IWbemClassObject* i_pClass,
LPCWSTR i_wszPropName,
DWORD* io_pdwQuals)
/*++
Synopsis: Unlike SetPropertyQualifiers, this method is specific to this
provider.
Arguments:
--*/
{
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(i_wszPropName != NULL);
DBG_ASSERT(io_pdwQuals != NULL);
HRESULT hr = S_OK;
CComPtr<IWbemQualifierSet> spQualSet = NULL;
BSTR bstrQualName = NULL;
VARIANT varQualValue;
VariantInit(&varQualValue);
DWORD dwQuals = 0;
bool bSeenForcePropertyOverwrite = false;
bool bSeenIsDefault = false;
bool bSeenIsInherit = false;
hr = i_pClass->GetPropertyQualifierSet(i_wszPropName, &spQualSet);
if(FAILED(hr))
{
goto exit;
}
// Looking for qualifiers
spQualSet->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
while(!bSeenForcePropertyOverwrite || !bSeenIsDefault || !bSeenIsInherit)
{
hr = spQualSet->Next(0, &bstrQualName, &varQualValue, NULL);
if(hr == WBEM_S_NO_MORE_DATA || FAILED(hr))
{
// No more qualifiers.
// We don't need to worry about cleanup - nothing was allocated.
break;
}
if(!bSeenForcePropertyOverwrite && _wcsicmp(bstrQualName, g_wszForcePropertyOverwrite) == 0)
{
bSeenForcePropertyOverwrite = true;
if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
{
dwQuals |= g_fForcePropertyOverwrite;
}
}
else if(!bSeenIsDefault && _wcsicmp(bstrQualName, g_wszIsDefault) == 0)
{
bSeenIsDefault = true;
if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
{
dwQuals |= g_fIsDefault;
}
}
else if(!bSeenIsInherit && _wcsicmp(bstrQualName, g_wszIsInherit) == 0)
{
bSeenIsInherit = true;
if(varQualValue.vt == VT_BOOL && varQualValue.boolVal)
{
dwQuals |= g_fIsInherit;
}
}
SysFreeString(bstrQualName);
VariantClear(&varQualValue);
}
spQualSet->EndEnumeration();
if(FAILED(hr))
{
goto exit;
}
*io_pdwQuals = dwQuals;
exit:
if(hr == WBEM_S_NO_MORE_DATA)
{
hr = WBEM_S_NO_ERROR;
}
return hr;
}
HRESULT CUtils::SetQualifiers(
IWbemClassObject* i_pClass,
LPCWSTR* i_awszQualNames,
VARIANT* i_avtQualValues,
ULONG i_iNrQuals,
ULONG i_iFlags)
{
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(i_awszQualNames != NULL);
DBG_ASSERT(i_avtQualValues != NULL);
HRESULT hr = S_OK;
CComPtr<IWbemQualifierSet> spQualSet = NULL;
hr = i_pClass->GetQualifierSet(&spQualSet);
if(FAILED(hr))
{
goto exit;
}
for(ULONG i = 0; i < i_iNrQuals; i++)
{
DBG_ASSERT(i_awszQualNames[i] != NULL);
hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i], i_iFlags);
if(FAILED(hr))
{
goto exit;
}
}
exit:
return hr;
}
HRESULT CUtils::SetMethodQualifiers(
IWbemClassObject* i_pClass,
LPCWSTR i_wszMethName,
LPCWSTR* i_awszQualNames,
VARIANT* i_avtQualValues,
ULONG i_iNrQuals)
{
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(i_wszMethName != NULL);
DBG_ASSERT(i_awszQualNames != NULL);
DBG_ASSERT(i_avtQualValues != NULL);
HRESULT hr = WBEM_S_NO_ERROR;
CComPtr<IWbemQualifierSet> spQualSet;
hr = i_pClass->GetMethodQualifierSet(i_wszMethName, &spQualSet);
if(FAILED(hr))
{
goto exit;
}
for(ULONG i = 0; i < i_iNrQuals; i++)
{
DBG_ASSERT(i_awszQualNames[i] != NULL);
hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i],
WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE);
if(FAILED(hr))
{
goto exit;
}
}
exit:
return hr;
}
HRESULT CUtils::SetPropertyQualifiers(
IWbemClassObject* i_pClass,
LPCWSTR i_wszPropName,
LPCWSTR* i_awszQualNames,
VARIANT* i_avtQualValues,
ULONG i_iNrQuals)
/*++
Synopsis:
Arguments: [i_pClass] -
[i_wszPropName] -
[i_awszQualNames] -
[i_avtQualValues] -
[i_iNrQuals] -
--*/
{
DBG_ASSERT(i_pClass != NULL);
DBG_ASSERT(i_wszPropName != NULL);
DBG_ASSERT(i_awszQualNames != NULL);
DBG_ASSERT(i_avtQualValues != NULL);
HRESULT hr = S_OK;
CComPtr<IWbemQualifierSet> spQualSet = NULL;
hr = i_pClass->GetPropertyQualifierSet(i_wszPropName, &spQualSet);
if(FAILED(hr))
{
goto exit;
}
for(ULONG i = 0; i < i_iNrQuals; i++)
{
DBG_ASSERT(i_awszQualNames[i] != NULL);
hr = spQualSet->Put(i_awszQualNames[i], &i_avtQualValues[i],
WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE);
if(FAILED(hr))
{
goto exit;
}
}
exit:
return hr;
}
HRESULT CUtils::CreateEmptyInstance(
LPWSTR i_wszClass,
CWbemServices* i_pNamespace,
IWbemClassObject** o_ppInstance)
/*++
Synopsis:
Creates an IWbemClassObject populated with default values.
Arguments: [i_wszClass] -
[i_pNamespace] -
[o_ppInstance] - Must Release() if this function succeeds.
--*/
{
DBG_ASSERT(i_wszClass != NULL);
DBG_ASSERT(i_pNamespace != NULL);
DBG_ASSERT(o_ppInstance != NULL);
HRESULT hr = S_OK;
CComPtr<IWbemClassObject> spClass;
CComPtr<IWbemClassObject> spInstance;
hr = i_pNamespace->GetObject(
i_wszClass,
0,
NULL,
&spClass,
NULL);
if(FAILED(hr))
{
goto exit;
}
hr = spClass->SpawnInstance(0, &spInstance);
if(FAILED(hr))
{
goto exit;
}
*o_ppInstance = spInstance;
(*o_ppInstance)->AddRef();
exit:
return hr;
}
void CUtils::MessageCodeToText(
DWORD i_dwMC,
va_list* i_pArgs,
BSTR* o_pbstrText)
/*++
Synopsis:
Arguments: [i_dwMC] -
[i_pArgs] - Can be NULL
[o_pbstrText] - Needs to be freed by caller
--*/
{
DBG_ASSERT(o_pbstrText != NULL);
*o_pbstrText = NULL;
LPVOID lpMsgBuf = NULL;
DWORD dwRet = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
g_hModule,
i_dwMC,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPWSTR) &lpMsgBuf,
0,
i_pArgs);
if(dwRet == 0)
{
DBG_ASSERT(lpMsgBuf == NULL);
}
CComBSTR sbstrOut;
if(lpMsgBuf != NULL)
{
//
// If out of memory, sbstrOut will be NULL. This is okay.
//
sbstrOut = (LPWSTR)lpMsgBuf;
//
// Free the buffer.
//
LocalFree( lpMsgBuf );
}
//
// Set out parameter
//
*o_pbstrText = sbstrOut.Detach();
}
void CUtils::HRToText(
HRESULT i_hr,
BSTR* o_pbstrText)
{
DBG_ASSERT(o_pbstrText != NULL);
CComPtr<IWbemStatusCodeText> spStatus;
*o_pbstrText = NULL;
i_hr = HRESULT_FROM_WIN32(i_hr);
if(HRESULT_FACILITY(i_hr) == FACILITY_INTERNET)
{
MessageCodeToText(i_hr, NULL, o_pbstrText);
return;
}
HRESULT hr = CoCreateInstance(
CLSID_WbemStatusCodeText,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemStatusCodeText,
(LPVOID *) &spStatus);
CComBSTR sbstrError = NULL;
CComBSTR sbstrFacility = NULL;
if(SUCCEEDED(hr))
{
spStatus->GetErrorCodeText(i_hr, 0, 0, &sbstrError); // ignore hr
spStatus->GetFacilityCodeText(i_hr, 0, 0, &sbstrFacility); // ignore hr
}
CComBSTR sbstrFullError = NULL;
if(sbstrError != NULL && sbstrFacility != NULL)
{
sbstrFullError = sbstrFacility;
sbstrFullError += L": ";
sbstrFullError += sbstrError; // sbstrFullError may be NULL in low mem -- okay
}
else if(sbstrError != NULL)
{
sbstrFullError = sbstrError; // sbstrFullError may be NULL in low mem -- okay
}
else if(sbstrFacility != NULL)
{
sbstrFullError = sbstrFacility; // sbstrFullError may be NULL in low mem -- okay
}
*o_pbstrText = sbstrFullError.Detach();
}