You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
673 lines
20 KiB
673 lines
20 KiB
// SoftwareFeature.cpp: implementation of the CSoftwareFeature class.
|
|
|
|
//
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precomp.h"
|
|
#include "SoftwareFeature.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CSoftwareFeature::CSoftwareFeature(CRequestObject *pObj, IWbemServices *pNamespace,
|
|
IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
|
|
{
|
|
|
|
}
|
|
|
|
CSoftwareFeature::~CSoftwareFeature()
|
|
{
|
|
|
|
}
|
|
|
|
HRESULT CSoftwareFeature::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
int i = -1;
|
|
int iEnum;
|
|
long lDate;
|
|
WCHAR wcBuf[BUFF_SIZE];
|
|
WCHAR wcName[BUFF_SIZE];
|
|
WCHAR wcParent[BUFF_SIZE];
|
|
WCHAR wcDesc[BUFF_SIZE];
|
|
#if !defined(_UNICODE)
|
|
WCHAR wcTmp[BUFF_SIZE];
|
|
#endif
|
|
WCHAR wcProductCode[39];
|
|
DWORD dwBufSize;
|
|
DWORD dwBufSize2;
|
|
DWORD dwCount;
|
|
DWORD dwAttrib;
|
|
WORD wDate;
|
|
bool bMatch = false;
|
|
UINT uiStatus;
|
|
|
|
//These will change from class to class
|
|
bool bFeature, bName, bVersion = false , bIDNum, bProductHandle;
|
|
INSTALLSTATE piInstalled;
|
|
|
|
while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED)){
|
|
|
|
wcscpy(wcProductCode, m_pRequest->Package(i));
|
|
|
|
//Open our database
|
|
|
|
try
|
|
{
|
|
if ( GetView ( NULL, wcProductCode, NULL, NULL, FALSE, TRUE ) )
|
|
{
|
|
bProductHandle = true;
|
|
}
|
|
else
|
|
{
|
|
bProductHandle = false;
|
|
}
|
|
|
|
iEnum = 0;
|
|
|
|
// try to get available feature
|
|
do
|
|
{
|
|
uiStatus = g_fpMsiEnumFeaturesW(wcProductCode, iEnum++, wcName, wcParent);
|
|
}
|
|
while ( uiStatus == ERROR_MORE_DATA );
|
|
|
|
while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
|
|
|
|
CheckMSI(uiStatus);
|
|
|
|
if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
|
|
|
|
//----------------------------------------------------
|
|
|
|
dwBufSize = BUFF_SIZE;
|
|
CheckMSI(g_fpMsiGetProductInfoW(wcProductCode,
|
|
#if defined(_UNICODE)
|
|
INSTALLPROPERTY_PRODUCTNAME
|
|
#else
|
|
TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp)
|
|
#endif
|
|
, wcBuf, &dwBufSize));
|
|
PutKeyProperty(m_pObj, pProductName, wcBuf, &bName, m_pRequest);
|
|
|
|
dwBufSize = BUFF_SIZE;
|
|
if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
|
|
#if defined(_UNICODE)
|
|
INSTALLPROPERTY_VERSIONSTRING
|
|
#else
|
|
TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp)
|
|
#endif
|
|
, wcBuf, &dwBufSize))
|
|
PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
|
|
else{
|
|
dwBufSize = BUFF_SIZE;
|
|
if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,
|
|
#if defined(_UNICODE)
|
|
INSTALLPROPERTY_VERSION
|
|
#else
|
|
TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp)
|
|
#endif
|
|
, wcBuf, &dwBufSize))
|
|
PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
|
|
}
|
|
|
|
if ( bProductHandle )
|
|
{
|
|
dwBufSize = BUFF_SIZE;
|
|
CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"Manufacturer", wcBuf, &dwBufSize));
|
|
PutProperty(m_pObj, pVendor, wcBuf);
|
|
|
|
dwBufSize = BUFF_SIZE;
|
|
CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"ProductVersion", wcBuf, &dwBufSize));
|
|
PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
|
|
}
|
|
|
|
PutKeyProperty(m_pObj, pIdentifyingNumber, wcProductCode, &bIDNum, m_pRequest);
|
|
|
|
dwBufSize = BUFF_SIZE;
|
|
PutKeyProperty(m_pObj, pName, wcName, &bFeature, m_pRequest);
|
|
|
|
//====================================================
|
|
|
|
piInstalled = g_fpMsiQueryFeatureStateW(m_pRequest->Package(i), wcName);
|
|
|
|
PutProperty(m_pObj, pInstallState, (int)piInstalled);
|
|
|
|
if(ERROR_SUCCESS == g_fpMsiGetFeatureUsageW(wcProductCode, wcName, &dwCount, &wDate)){
|
|
|
|
PutProperty(m_pObj, pAccesses, (int)dwCount);
|
|
|
|
lDate = (1980 + ((wDate & 65024) >> 9)) * 10000;
|
|
lDate += ((wDate & 480) >> 5) * 100;
|
|
lDate += (wDate & 31 );
|
|
|
|
//safe operation
|
|
_ltow(lDate, wcBuf, 10);
|
|
wcscat(wcBuf, L"******.000000+***");
|
|
PutProperty(m_pObj, pLastUse, wcBuf);
|
|
}
|
|
|
|
if ( bProductHandle )
|
|
{
|
|
dwBufSize = dwBufSize2 = BUFF_SIZE;
|
|
if ( ERROR_SUCCESS == g_fpMsiGetFeatureInfoW ( msidata.GetProduct (),
|
|
wcName,
|
|
&dwAttrib,
|
|
wcBuf,
|
|
&dwBufSize,
|
|
wcDesc,
|
|
&dwBufSize2
|
|
)
|
|
)
|
|
{
|
|
PutProperty(m_pObj, pDescription, wcDesc);
|
|
PutProperty(m_pObj, pCaption, wcBuf);
|
|
PutProperty(m_pObj, pAttributes, (int)dwAttrib);
|
|
}
|
|
else
|
|
{
|
|
PutProperty(m_pObj, pDescription, wcName);
|
|
PutProperty(m_pObj, pCaption, wcName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PutProperty(m_pObj, pDescription, wcName);
|
|
PutProperty(m_pObj, pCaption, wcName);
|
|
}
|
|
|
|
//----------------------------------------------------
|
|
|
|
if(bFeature && bName && bVersion && bIDNum) bMatch = true;
|
|
|
|
if((atAction != ACTIONTYPE_GET) || bMatch){
|
|
|
|
hr = pHandler->Indicate(1, &m_pObj);
|
|
}
|
|
|
|
m_pObj->Release();
|
|
m_pObj = NULL;
|
|
|
|
// try to get available feature
|
|
do
|
|
{
|
|
uiStatus = g_fpMsiEnumFeaturesW(wcProductCode, iEnum++, wcName, wcParent);
|
|
}
|
|
while ( uiStatus == ERROR_MORE_DATA );
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
msidata.CloseProduct ();
|
|
|
|
if(m_pObj)
|
|
{
|
|
m_pObj->Release();
|
|
m_pObj = NULL;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
msidata.CloseProduct ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
bool CSoftwareFeature::CheckUsage(UINT uiStatus)
|
|
{
|
|
switch(uiStatus){
|
|
|
|
case ERROR_BAD_CONFIGURATION:
|
|
throw WBEM_E_FAILED;
|
|
|
|
case ERROR_INSTALL_FAILURE:
|
|
return false;
|
|
|
|
case ERROR_SUCCESS:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
HRESULT CSoftwareFeature::Configure(CRequestObject *pReqObj, IWbemClassObject *pInParams,
|
|
IWbemObjectSink *pHandler, IWbemContext *pCtx)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
HRESULT hrReturn = WBEM_S_NO_ERROR;
|
|
int iState;
|
|
UINT uiStatus = 1603;
|
|
WCHAR wcCode[BUFF_SIZE];
|
|
WCHAR wcFeature[BUFF_SIZE];
|
|
BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
|
|
if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
BSTR bstrConfigure = SysAllocString(L"Configure");
|
|
if(!bstrConfigure)
|
|
{
|
|
::SysFreeString (bstrReturnValue);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
IWbemClassObject *pClass = NULL;
|
|
IWbemClassObject *pOutClass = NULL;
|
|
IWbemClassObject *pOutParams = NULL;
|
|
VARIANT v;
|
|
INSTALLSTATE isState;
|
|
int i = -1;
|
|
bool bFoundCode = false;
|
|
bool bFoundFeature = false;
|
|
|
|
if(SUCCEEDED(hr = pReqObj->m_pNamespace->GetObject(pReqObj->m_bstrClass, 0, pCtx, &pClass, NULL)))
|
|
{
|
|
if(SUCCEEDED(hr = pClass->GetMethod(bstrConfigure, 0, NULL, &pOutClass)))
|
|
{
|
|
if(SUCCEEDED(hr = pOutClass->SpawnInstance(0, &pOutParams)))
|
|
{
|
|
//Get PackageLocation
|
|
if(!SUCCEEDED(GetProperty(pInParams, "InstallState", &iState)))
|
|
hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
//Get the Product Code
|
|
while(pReqObj->m_Property[++i])
|
|
{
|
|
if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
|
|
{
|
|
if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
|
|
{
|
|
wcscpy(wcCode, pReqObj->m_Value[i]);
|
|
bFoundCode = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Get the Feature Name
|
|
i = -1;
|
|
while(pReqObj->m_Property[++i])
|
|
{
|
|
if(wcscmp(pReqObj->m_Property[i], L"Name") == 0)
|
|
{
|
|
if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
|
|
{
|
|
wcscpy(wcFeature, pReqObj->m_Value[i]);
|
|
bFoundFeature = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bFoundCode && bFoundFeature){
|
|
//Get the appropriate State
|
|
switch(iState){
|
|
case 1:
|
|
isState = INSTALLSTATE_DEFAULT;
|
|
break;
|
|
case 2:
|
|
isState = INSTALLSTATE_ADVERTISED;
|
|
break;
|
|
case 3:
|
|
isState = INSTALLSTATE_LOCAL;
|
|
break;
|
|
case 4:
|
|
isState = INSTALLSTATE_ABSENT;
|
|
break;
|
|
case 5:
|
|
isState = INSTALLSTATE_SOURCE;
|
|
break;
|
|
default:
|
|
isState = INSTALLSTATE_NOTUSED;
|
|
break;
|
|
}
|
|
|
|
//If everything is valid, proceed
|
|
if((isState != INSTALLSTATE_NOTUSED) && (hrReturn == WBEM_S_NO_ERROR)){
|
|
|
|
if(!IsNT4()){
|
|
|
|
if ( msidata.Lock () )
|
|
{
|
|
INSTALLUI_HANDLER ui = NULL;
|
|
|
|
//Set UI Level w/ event callback
|
|
ui = SetupExternalUI ( );
|
|
|
|
try
|
|
{
|
|
//Call Installer
|
|
uiStatus = g_fpMsiConfigureFeatureW(wcCode, wcFeature, isState);
|
|
}
|
|
catch(...)
|
|
{
|
|
uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
|
|
}
|
|
|
|
//Restore UI Level w/ event callback
|
|
RestoreExternalUI ( ui );
|
|
|
|
msidata. Unlock();
|
|
}
|
|
|
|
}else{
|
|
|
|
/////////////////
|
|
// NT4 fix code....
|
|
|
|
try{
|
|
|
|
WCHAR wcAction[20];
|
|
wcscpy(wcAction, L"/sfconfigure");
|
|
|
|
WCHAR wcTmp[100];
|
|
_itow((int)isState, wcTmp, 10);
|
|
|
|
LPWSTR wcCommandLine = NULL;
|
|
|
|
try
|
|
{
|
|
if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + wcslen ( wcFeature ) + 3 + wcslen ( wcTmp ) ] ) != NULL )
|
|
{
|
|
wcscpy(wcCommandLine, wcCode);
|
|
wcscat(wcCommandLine, L" ");
|
|
wcscat(wcCommandLine, wcFeature);
|
|
wcscat(wcCommandLine, L" ");
|
|
wcscat(wcCommandLine, wcTmp);
|
|
|
|
hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
|
|
|
|
delete [] wcCommandLine;
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( wcCommandLine )
|
|
{
|
|
delete [] wcCommandLine;
|
|
wcCommandLine = NULL;
|
|
}
|
|
|
|
hrReturn = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}catch(...){
|
|
|
|
hrReturn = WBEM_E_FAILED;
|
|
}
|
|
|
|
////////////////////
|
|
|
|
}
|
|
|
|
if(SUCCEEDED(hrReturn)){
|
|
|
|
//Set up ReturnValue
|
|
VariantInit(&v);
|
|
V_VT(&v) = VT_I4;
|
|
V_I4(&v) = uiStatus;
|
|
|
|
BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
|
|
|
|
if(!bstrReturnValue)
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
|
|
&v, NULL)))
|
|
pHandler->Indicate(1, &pOutParams);
|
|
|
|
SysFreeString(bstrReturnValue);
|
|
}
|
|
|
|
}else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
}else hr = WBEM_E_FAILED;
|
|
|
|
pOutParams->Release();
|
|
|
|
}else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
pOutClass->Release();
|
|
}
|
|
|
|
pClass->Release();
|
|
}
|
|
|
|
SysFreeString(bstrReturnValue);
|
|
SysFreeString(bstrConfigure);
|
|
|
|
return hrReturn;
|
|
}
|
|
|
|
HRESULT CSoftwareFeature::Reinstall(CRequestObject *pReqObj, IWbemClassObject *pInParams,
|
|
IWbemObjectSink *pHandler, IWbemContext *pCtx)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
HRESULT hrReturn = WBEM_S_NO_ERROR;
|
|
int iMode;
|
|
UINT uiStatus = 1603;
|
|
WCHAR wcCode[BUFF_SIZE];
|
|
WCHAR wcFeature[BUFF_SIZE];
|
|
BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
|
|
if(!bstrReturnValue) throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
BSTR bstrReinstall = SysAllocString(L"Reinstall");
|
|
if(!bstrReinstall)
|
|
{
|
|
::SysFreeString (bstrReturnValue);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
IWbemClassObject *pClass = NULL;
|
|
IWbemClassObject *pOutClass = NULL;
|
|
IWbemClassObject *pOutParams = NULL;
|
|
VARIANT v;
|
|
DWORD dwMode;
|
|
int i = -1;
|
|
bool bFoundCode = false;
|
|
bool bFoundFeature = false;
|
|
|
|
if(SUCCEEDED(hr = pReqObj->m_pNamespace->GetObject(pReqObj->m_bstrClass, 0, pCtx, &pClass, NULL))){
|
|
if(SUCCEEDED(hr = pClass->GetMethod(bstrReinstall, 0, NULL, &pOutClass))){
|
|
if(SUCCEEDED(hr = pOutClass->SpawnInstance(0, &pOutParams))){
|
|
//Get Reinstall Mode
|
|
if(!SUCCEEDED(GetProperty(pInParams, "ReinstallMode", &iMode)))
|
|
hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
//Get the Product Code
|
|
while(pReqObj->m_Property[++i])
|
|
{
|
|
if(wcscmp(pReqObj->m_Property[i], L"IdentifyingNumber") == 0)
|
|
{
|
|
if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
|
|
{
|
|
wcscpy(wcCode, pReqObj->m_Value[i]);
|
|
bFoundCode = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Get the Feature Name
|
|
i = -1;
|
|
while(pReqObj->m_Property[++i])
|
|
{
|
|
if(wcscmp(pReqObj->m_Property[i], L"Name") == 0)
|
|
{
|
|
if ( wcslen (pReqObj->m_Value[i]) < BUFF_SIZE )
|
|
{
|
|
wcscpy(wcFeature, pReqObj->m_Value[i]);
|
|
bFoundFeature = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bFoundCode && bFoundFeature){
|
|
//Get the appropriate ReinstallMode
|
|
switch(iMode){
|
|
case 1:
|
|
dwMode = REINSTALLMODE_FILEMISSING;
|
|
break;
|
|
case 2:
|
|
dwMode = REINSTALLMODE_FILEOLDERVERSION;
|
|
break;
|
|
case 3:
|
|
dwMode = REINSTALLMODE_FILEEQUALVERSION;
|
|
break;
|
|
case 4:
|
|
dwMode = REINSTALLMODE_FILEEXACT;
|
|
break;
|
|
case 5:
|
|
dwMode = REINSTALLMODE_FILEVERIFY;
|
|
break;
|
|
case 6:
|
|
dwMode = REINSTALLMODE_FILEREPLACE;
|
|
break;
|
|
case 7:
|
|
dwMode = REINSTALLMODE_USERDATA;
|
|
break;
|
|
case 8:
|
|
dwMode = REINSTALLMODE_MACHINEDATA;
|
|
break;
|
|
case 9:
|
|
dwMode = REINSTALLMODE_SHORTCUT;
|
|
break;
|
|
case 10:
|
|
dwMode = REINSTALLMODE_PACKAGE;
|
|
break;
|
|
default:
|
|
dwMode = NULL;
|
|
break;
|
|
}
|
|
|
|
//If everything is valid, proceed
|
|
if ( dwMode && hrReturn == WBEM_S_NO_ERROR )
|
|
{
|
|
if(!IsNT4()){
|
|
|
|
if ( msidata.Lock () )
|
|
{
|
|
INSTALLUI_HANDLER ui = NULL;
|
|
|
|
//Set UI Level w/ event callback
|
|
ui = SetupExternalUI ( );
|
|
|
|
try
|
|
{
|
|
//Call Installer
|
|
uiStatus = g_fpMsiReinstallFeatureW(wcCode, wcFeature, dwMode);
|
|
}
|
|
catch(...)
|
|
{
|
|
uiStatus = static_cast < UINT > ( RPC_E_SERVERFAULT );
|
|
}
|
|
|
|
//Restore UI Level w/ event callback
|
|
RestoreExternalUI ( ui );
|
|
|
|
msidata. Unlock();
|
|
}
|
|
|
|
}else{
|
|
|
|
/////////////////
|
|
// NT4 fix code....
|
|
|
|
try{
|
|
|
|
WCHAR wcAction[20];
|
|
wcscpy(wcAction, L"/sfreinstall");
|
|
|
|
WCHAR wcTmp[100];
|
|
_itow((int)dwMode, wcTmp, 10);
|
|
|
|
LPWSTR wcCommandLine = NULL;
|
|
|
|
try
|
|
{
|
|
if ( ( wcCommandLine = new WCHAR [ wcslen ( wcCode ) + wcslen ( wcFeature ) + 3 + wcslen ( wcTmp ) ] ) != NULL )
|
|
{
|
|
wcscpy(wcCommandLine, wcCode);
|
|
wcscat(wcCommandLine, L" ");
|
|
wcscat(wcCommandLine, wcFeature);
|
|
wcscat(wcCommandLine, L" ");
|
|
wcscat(wcCommandLine, wcTmp);
|
|
|
|
hrReturn = LaunchProcess(wcAction, wcCommandLine, &uiStatus);
|
|
|
|
delete [] wcCommandLine;
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( wcCommandLine )
|
|
{
|
|
delete [] wcCommandLine;
|
|
wcCommandLine = NULL;
|
|
}
|
|
|
|
hrReturn = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}catch(...){
|
|
|
|
hrReturn = WBEM_E_FAILED;
|
|
}
|
|
|
|
////////////////////
|
|
|
|
}
|
|
|
|
if(SUCCEEDED(hrReturn)){
|
|
|
|
//Set up ReturnValue
|
|
VariantInit(&v);
|
|
V_VT(&v) = VT_I4;
|
|
V_I4(&v) = uiStatus;
|
|
|
|
BSTR bstrReturnValue = SysAllocString(L"ReturnValue");
|
|
|
|
if(!bstrReturnValue)
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
if(SUCCEEDED(hrReturn = pOutParams->Put(bstrReturnValue, 0,
|
|
&v, NULL)))
|
|
pHandler->Indicate(1, &pOutParams);
|
|
|
|
SysFreeString(bstrReturnValue);
|
|
}
|
|
|
|
}else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
}else hr = WBEM_E_FAILED;
|
|
|
|
pOutParams->Release();
|
|
|
|
}else hrReturn = WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
|
|
pOutClass->Release();
|
|
}
|
|
|
|
pClass->Release();
|
|
}
|
|
|
|
SysFreeString(bstrReturnValue);
|
|
SysFreeString(bstrReinstall);
|
|
|
|
return hrReturn;
|
|
}
|