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.
5216 lines
152 KiB
5216 lines
152 KiB
/****************************************************************************
|
|
Copyright information : Copyright (c) 1998-1999 Microsoft Corporation
|
|
File Name : ExecEngine.cpp
|
|
Project Name : WMI Command Line
|
|
Author Name : Ch. Sriramachandramurthy
|
|
Date of Creation (dd/mm/yy) : 27th-September-2000
|
|
Version Number : 1.0
|
|
Brief Description : This class encapsulates the functionality of
|
|
Execution Engine. Obtains the needed information
|
|
from CGlobalSwitches and CCommandSwitches of
|
|
CParsedInfo and executes needed WMI operations.
|
|
The result is sent to Format Engine via
|
|
CGlobalSwitches and CCommandSwicthes
|
|
of CParsedInfo.
|
|
Revision History :
|
|
Last Modified By : Ch. Sriramachandramurthy
|
|
Last Modified Date : 20th-March-2001
|
|
****************************************************************************/
|
|
|
|
// include files
|
|
#include "Precomp.h"
|
|
#include "GlobalSwitches.h"
|
|
#include "CommandSwitches.h"
|
|
#include "HelpInfo.h"
|
|
#include "ErrorLog.h"
|
|
#include "ParsedInfo.h"
|
|
#include "ErrorInfo.h"
|
|
#include "WmiCliXMLLog.h"
|
|
#include "FormatEngine.h"
|
|
#include "CmdTokenizer.h"
|
|
#include "CmdAlias.h"
|
|
#include "ParserEngine.h"
|
|
#include "ExecEngine.h"
|
|
#include "WmiCmdLn.h"
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CExecEngine
|
|
Synopsis :Constructor, This function initializes the necessary
|
|
member variables.
|
|
Type :Constructor
|
|
Input Parameter(s) :None
|
|
Output Parameter(s):None
|
|
Return Type :None
|
|
Global Variables :None
|
|
Calling Syntax :None
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
CExecEngine::CExecEngine()
|
|
{
|
|
m_pITextSrc = NULL;
|
|
m_pIWbemLocator = NULL;
|
|
m_pITargetNS = NULL;
|
|
m_pIContext = NULL;
|
|
m_bTrace = FALSE;
|
|
m_bNoAssoc = FALSE;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :~CExecEngine
|
|
Synopsis :Destructor, This function call Uninitialize() which
|
|
frees memory held by the object.
|
|
Type :Destructor
|
|
Input Parameter(s) :None
|
|
Output Parameter(s):None
|
|
Return Type :None
|
|
Global Variables :None
|
|
Calling Syntax :None
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
CExecEngine::~CExecEngine()
|
|
{
|
|
SAFEIRELEASE(m_pITextSrc);
|
|
SAFEIRELEASE(m_pIContext);
|
|
SAFEIRELEASE(m_pIWbemLocator);
|
|
Uninitialize();
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :Uninitialize
|
|
Synopsis :This function uninitializes the member variables.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
bFinal - boolean value which when set indicates that the
|
|
program
|
|
Output Parameter(s):None
|
|
Return Type :void
|
|
Global Variables :None
|
|
Calling Syntax :Uninitialize()
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
void CExecEngine::Uninitialize(BOOL bFinal)
|
|
{
|
|
SAFEIRELEASE(m_pITargetNS);
|
|
m_bTrace = FALSE;
|
|
m_eloErrLogOpt = NO_LOGGING;
|
|
m_bNoAssoc = FALSE;
|
|
if (bFinal)
|
|
{
|
|
SAFEIRELEASE(m_pITextSrc);
|
|
SAFEIRELEASE(m_pIContext);
|
|
SAFEIRELEASE(m_pIWbemLocator);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :SetLocatorObject
|
|
Synopsis :Sets the locator object passed via parameter to member
|
|
of the class.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
pILocator - Pointer to IWbemLocator
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :SetLocatorObject(pILocator)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::SetLocatorObject(IWbemLocator* pILocator)
|
|
{
|
|
static BOOL bFirst = TRUE;
|
|
BOOL bRet = TRUE;
|
|
if (bFirst)
|
|
{
|
|
if (pILocator != NULL)
|
|
{
|
|
SAFEIRELEASE(m_pIWbemLocator);
|
|
m_pIWbemLocator = pILocator;
|
|
m_pIWbemLocator->AddRef();
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
bFirst = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ExecuteCommand
|
|
Synopsis :Executes the command referring to information
|
|
available with the CParsedInfo object.
|
|
Stores the results in the CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ExecuteCommand(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ExecuteCommand(CParsedInfo& rParsedInfo)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
HRESULT hr = S_OK;
|
|
_TCHAR *pszVerb = NULL;
|
|
BOOL bContinue = TRUE;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
try
|
|
{
|
|
|
|
// Obtain the TRACE flag
|
|
m_bTrace = rParsedInfo.GetGlblSwitchesObject().GetTraceStatus();
|
|
|
|
// Obtain the Logging mode
|
|
m_eloErrLogOpt = rParsedInfo.GetErrorLogObject().GetErrLogOption();
|
|
|
|
// Enable|Disable the privileges
|
|
hr = ModifyPrivileges(rParsedInfo.GetGlblSwitchesObject().
|
|
GetPrivileges());
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
_T("ModifyPrivileges(-)"), dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
// Obtian the verb name
|
|
pszVerb = rParsedInfo.GetCmdSwitchesObject().GetVerbName();
|
|
|
|
if (pszVerb != NULL)
|
|
{
|
|
// If GET | LIST verb is specified.
|
|
if (CompareTokens(pszVerb, CLI_TOKEN_GET) ||
|
|
CompareTokens(pszVerb, CLI_TOKEN_LIST))
|
|
{
|
|
bRet = ProcessSHOWInfo(rParsedInfo);
|
|
}
|
|
// If SET verb is specified.
|
|
else if (CompareTokens(pszVerb, CLI_TOKEN_SET))
|
|
{
|
|
bRet = ProcessSETVerb(rParsedInfo);
|
|
}
|
|
// If CALL verb is specified.
|
|
else if (CompareTokens(pszVerb, CLI_TOKEN_CALL))
|
|
{
|
|
bRet = ProcessCALLVerb(rParsedInfo);
|
|
}
|
|
// If ASSOC verb is specified.
|
|
else if (CompareTokens(pszVerb, CLI_TOKEN_ASSOC))
|
|
{
|
|
bRet = ProcessASSOCVerb(rParsedInfo);
|
|
}
|
|
// If CREATE verb is specified.
|
|
else if (CompareTokens(pszVerb, CLI_TOKEN_CREATE))
|
|
{
|
|
bRet = ProcessCREATEVerb(rParsedInfo);
|
|
}
|
|
// If DELETE verb is specified.
|
|
else if (CompareTokens(pszVerb, CLI_TOKEN_DELETE))
|
|
{
|
|
bRet = ProcessDELETEVerb(rParsedInfo);
|
|
}
|
|
// If user defined verb is specified.
|
|
else
|
|
bRet = ProcessCALLVerb(rParsedInfo);
|
|
}
|
|
// If no verb is specified, (default behavior is assumed to be that of
|
|
// GET i.e a command like 'w class Win32_Process' go ahead with
|
|
// displaying the instance information.
|
|
else
|
|
{
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
SetVerbName(_T("GET")))
|
|
{
|
|
bRet = ProcessSHOWInfo(rParsedInfo);
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
// To check unhandled exceptions thrown by _bstr_t objects etc..
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ObtainXMLResultSet
|
|
Synopsis :Executes query and obtain the result in XML file format.
|
|
Refers data in the CCommnadSwicthes object of
|
|
CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
bstrQuery - WQL query
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
bstrXML - reference to XML result set obtained
|
|
bSysProp - boolean flag indicating the presence of system
|
|
properties.
|
|
bNotAssoc - boolean flag indicating whether the query cotains
|
|
ASSOCIATORS OF {xxxx} (or) SELECT * FROM xxx form.
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :ObtainXMLResultSet(bstrQuery, rParsedInfo, bstrXML,
|
|
bSysProp, bNotAssoc);
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::ObtainXMLResultSet(BSTR bstrQuery,
|
|
CParsedInfo& rParsedInfo,
|
|
_bstr_t& bstrXML,
|
|
BOOL bSysProp,
|
|
BOOL bNotAssoc)
|
|
{
|
|
IWbemClassObject *pIObject = NULL;
|
|
HRESULT hr = S_OK;
|
|
IEnumWbemClassObject *pIEnum = NULL;
|
|
ULONG ulReturned = 0;
|
|
BSTR bstrInstXML = NULL;
|
|
BOOL bInstances = FALSE;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
VARIANT vSystem;
|
|
|
|
try
|
|
{
|
|
VariantInit(&vSystem);
|
|
if ( g_wmiCmd.GetBreakEvent() == FALSE )
|
|
{
|
|
// Add the <CIM> or <ASSOC.OBJECTARRAY> to the beginning of the
|
|
// XML result. This is to facilitate storing of mutiple object
|
|
// instances information.
|
|
bstrXML = (bNotAssoc) ? MULTINODE_XMLSTARTTAG :
|
|
MULTINODE_XMLASSOCSTAG1;
|
|
|
|
// Create the IWbemContext object, used for suppressing
|
|
// the system properties.
|
|
if (m_pIContext == NULL)
|
|
{
|
|
hr = CreateContext(rParsedInfo);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
_T("CreateContext(rParsedInfo)"), dwThreadId,
|
|
rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
// Execute the WQL query
|
|
// WBEM_FLAG_FORWARD_ONLY flag Increases the speed of execution
|
|
// WBEM_FLAG_RETURN_IMMEDIATELY flag makes semisynchronous call
|
|
// Setting these flags in combination saves time, space, and
|
|
// improves responsiveness.enumerators can be polled for the
|
|
// results of the call.
|
|
hr = m_pITargetNS->ExecQuery(_bstr_t(L"WQL"), bstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY |
|
|
WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pIEnum);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecQuery(L\"WQL\", L\"%s\", "
|
|
L"0, NULL, -)", (LPWSTR) bstrQuery);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// If no system properties are specified adjust the context to
|
|
// filter out the system properties.
|
|
vSystem.vt = VT_BOOL;
|
|
|
|
// Filterout the system properties.
|
|
if (!bSysProp)
|
|
vSystem.boolVal = VARIANT_TRUE;
|
|
// Don't filter the system properties.
|
|
else
|
|
vSystem.boolVal = VARIANT_FALSE;
|
|
|
|
hr = m_pIContext->SetValue(_bstr_t(EXCLUDESYSPROP), 0, &vSystem);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
_T("IWbemContext::SetValue(L\"ExcludeSystemProperties\","
|
|
L"0, -)"), dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
VARIANTCLEAR(vSystem);
|
|
|
|
// Set the interface level security for the IEnumWbemClass object.
|
|
hr = SetSecurity(pIEnum,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT,"
|
|
L"RPC_C_AUTHZ_NONE, NULL, %d, %d, -, EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Loop through the available instances
|
|
hr = pIEnum->Next(WBEM_INFINITE, 1, &pIObject, &ulReturned);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IEnumWbemClassObject->Next"
|
|
L"(WBEM_INFINITE, 1, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
while(ulReturned == 1)
|
|
{
|
|
// Set the instances flag to TRUE
|
|
bInstances = TRUE;
|
|
|
|
// Call the IWbemObjectTextSrc::GetText method, with
|
|
// IWbemClassObject as one of the arguments.
|
|
hr = m_pITextSrc->GetText(0, pIObject,
|
|
WMI_OBJ_TEXT_CIM_DTD_2_0, m_pIContext, &bstrInstXML);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemObjectTextSrc::GetText(0, -, "
|
|
L"WMI_OBJECT_TEXT_CIM_DTD_2_0, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Associators should be handled separately
|
|
if (bNotAssoc == FALSE)
|
|
{
|
|
// Append the XML node to the XML nodes stream
|
|
bstrXML = bstrXML + _bstr_t(MULTINODE_XMLASSOCSTAG2) +
|
|
+ bstrInstXML + _bstr_t(MULTINODE_XMLASSOCETAG2);
|
|
}
|
|
else
|
|
{
|
|
// Append the XML node to the XML nodes stream
|
|
bstrXML += bstrInstXML;
|
|
}
|
|
|
|
// Release the memory allocated for bstrInstXML
|
|
SAFEBSTRFREE(bstrInstXML);
|
|
|
|
SAFEIRELEASE(pIObject);
|
|
|
|
// if break event occurs then terminate the session
|
|
if ( g_wmiCmd.GetBreakEvent() == TRUE )
|
|
break;
|
|
|
|
// Move to next instance in the enumeration.
|
|
hr = pIEnum->Next(WBEM_INFINITE, 1, &pIObject, &ulReturned);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IEnumWbemClassObject->Next(WBEM_INFINITE, 1, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
// If instances are available
|
|
if (bInstances)
|
|
{
|
|
// Add the </CIM> or </ASSOC.OBJECTARRAY> at the end.
|
|
bstrXML += (bNotAssoc) ? MULTINODE_XMLENDTAG :
|
|
MULTINODE_XMLASSOCETAG1;
|
|
|
|
// if no break event occured then only set the
|
|
// xml result set
|
|
if ( g_wmiCmd.GetBreakEvent() == FALSE )
|
|
{
|
|
if (bNotAssoc)
|
|
{
|
|
// Store the XML result set
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetXMLResultSet(bstrXML);
|
|
bstrXML = L"";
|
|
}
|
|
}
|
|
}
|
|
// no instances
|
|
else
|
|
{
|
|
bstrXML = L"<ERROR>";
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage((bNotAssoc) ?
|
|
IDS_I_NO_INSTANCES : IDS_I_NO_ASSOCIATIONS,
|
|
0, bstrMsg, NULL);
|
|
|
|
if (bNotAssoc)
|
|
{
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP, TRUE, TRUE);
|
|
}
|
|
else
|
|
{
|
|
m_bNoAssoc = TRUE;
|
|
}
|
|
CHString sTemp;
|
|
sTemp.Format(_T("<DESCRIPTION>%s</DESCRIPTION>"),
|
|
(LPWSTR) bstrMsg);
|
|
|
|
bstrXML += _bstr_t(sTemp);
|
|
bstrXML += L"</ERROR>";
|
|
|
|
if (bNotAssoc)
|
|
{
|
|
// Store the XML result set
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetXMLResultSet(bstrXML);
|
|
bstrXML = L"";
|
|
}
|
|
}
|
|
SAFEIRELEASE(pIEnum);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
SAFEIRELEASE(pIEnum);
|
|
SAFEBSTRFREE(bstrInstXML);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
hr = e.Error();
|
|
}
|
|
//trap for CHeap_Exception
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
SAFEIRELEASE(pIEnum);
|
|
SAFEBSTRFREE(bstrInstXML);
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
_com_issue_error(hr);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ExecWMIMethod
|
|
Synopsis :Executes a WMI method referring to the information
|
|
available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ExecWMIMethod(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ExecWMIMethod(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject *pIClassObj = NULL,
|
|
*pIInSign = NULL,
|
|
*pIOutSign = NULL,
|
|
*pIInParam = NULL;
|
|
SAFEARRAY *psaNames = NULL;
|
|
BSTR bstrInParam = NULL;
|
|
BOOL bContinue = TRUE,
|
|
bRet = TRUE,
|
|
bMethodDtls = FALSE;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
CHARVECTOR::iterator cviUnnamedValue = NULL;
|
|
BSTRMAP::iterator bmiNamedValue = NULL;
|
|
VARIANT varPut,
|
|
varGet,
|
|
varTemp;
|
|
PROPDETMAP pdmPropDetMap;
|
|
PROPDETMAP::iterator itrPropDetMap;
|
|
VariantInit(&varPut);
|
|
VariantInit(&varGet);
|
|
VariantInit(&varTemp);
|
|
|
|
METHDETMAP mdmMethDet;
|
|
METHDETMAP::iterator mdmIterator = NULL;
|
|
mdmMethDet = rParsedInfo.GetCmdSwitchesObject().GetMethDetMap();
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrClassName("");
|
|
// Obtain the parameter details.
|
|
if (!mdmMethDet.empty())
|
|
{
|
|
mdmIterator = mdmMethDet.begin();
|
|
pdmPropDetMap = (*mdmIterator).second.Params;
|
|
bMethodDtls = TRUE;
|
|
}
|
|
|
|
// Obtain the WMI class name
|
|
|
|
// If <alias> is not specified
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL)
|
|
{
|
|
bstrClassName = _bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassPath());
|
|
}
|
|
// If <alias> specified
|
|
else
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrClassName);
|
|
}
|
|
|
|
// Obtain the object schema.
|
|
hr = m_pITargetNS->GetObject(bstrClassName,
|
|
WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL,
|
|
&pIClassObj, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::GetObject(L\"%s\", 0, NULL, -)",
|
|
(LPWSTR) bstrClassName);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Get method information
|
|
hr = pIClassObj->GetMethod(_bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetMethodName()), 0, &pIInSign, &pIOutSign);
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::GetMethod(L\"%s\", 0, -, -)",
|
|
rParsedInfo.GetCmdSwitchesObject().GetMethodName() ?
|
|
rParsedInfo.GetCmdSwitchesObject().GetMethodName()
|
|
: L"<null>");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if ( pIInSign != NULL )
|
|
{
|
|
// Spawn object instance.
|
|
hr = pIInSign->SpawnInstance(0, &pIInParam);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
_T("IWbemClassObject::SpawnInstance(0, -)"), dwThreadId,
|
|
rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
CHARVECTOR cvInParams =
|
|
rParsedInfo.GetCmdSwitchesObject().GetPropertyList();
|
|
BSTRMAP bmParameterMap =
|
|
rParsedInfo.GetCmdSwitchesObject().GetParameterMap();
|
|
|
|
// If parameter list is TRUE
|
|
if (!cvInParams.empty() || !bmParameterMap.empty())
|
|
{
|
|
// Get the input paramters for this method from the input
|
|
// signature object.
|
|
hr = pIInSign->GetNames(NULL,
|
|
WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,
|
|
NULL,
|
|
&psaNames);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::GetNames(NULL, "
|
|
L"WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, "
|
|
L"NULL, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
LONG lLower = 0, lUpper = 0, lIndex = 0;
|
|
hr = SafeArrayGetLBound(psaNames, 1, &lLower);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetLBound(-, 1, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
hr = SafeArrayGetUBound(psaNames, 1, &lUpper);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetUBound(-, 1, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Puting param values depend on named param list or not.
|
|
BOOL bNamedParamList = rParsedInfo.GetCmdSwitchesObject().
|
|
GetNamedParamListFlag();
|
|
|
|
// Make necessary initializations.
|
|
if ( bNamedParamList == FALSE)
|
|
cviUnnamedValue = cvInParams.begin();
|
|
lIndex = lLower;
|
|
|
|
// Associate the parameter values specified to the input
|
|
// parameters in the order available.
|
|
while(TRUE)
|
|
{
|
|
// Breaking conditions.
|
|
if ( lIndex > lUpper )
|
|
break;
|
|
if ( bNamedParamList == FALSE &&
|
|
cviUnnamedValue == cvInParams.end())
|
|
break;
|
|
|
|
hr = SafeArrayGetElement(psaNames, &lIndex, &bstrInParam);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetElement(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Obtain the property details
|
|
PROPERTYDETAILS pdPropDet;
|
|
GetPropertyAttributes(pIInParam, bstrInParam,
|
|
pdPropDet, m_bTrace);
|
|
|
|
_TCHAR* pszValue = NULL;
|
|
if ( bNamedParamList == TRUE )
|
|
{
|
|
// If in parameter not found in named parameter map.
|
|
if (!Find(bmParameterMap, bstrInParam, bmiNamedValue))
|
|
{
|
|
// If not found in alias verb parameters.
|
|
if ( !Find(pdmPropDetMap, bstrInParam,
|
|
itrPropDetMap) )
|
|
{
|
|
lIndex++;
|
|
SAFEBSTRFREE(bstrInParam);
|
|
continue;
|
|
}
|
|
else // If found in alias verb parameters.
|
|
{
|
|
// Value should be taken from Default of alias
|
|
// verb parameters.
|
|
if (!((*itrPropDetMap).second.Default))
|
|
{
|
|
lIndex++;
|
|
SAFEBSTRFREE(bstrInParam);
|
|
continue;
|
|
}
|
|
else
|
|
pszValue = (*itrPropDetMap).second.Default;
|
|
}
|
|
}
|
|
else
|
|
pszValue = (*bmiNamedValue).second;
|
|
}
|
|
else
|
|
pszValue = *cviUnnamedValue;
|
|
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetAliasName() == NULL)
|
|
{
|
|
// Check the parameter value supplied against
|
|
// the qualifier information for the parameter.
|
|
bRet = CheckQualifierInfo(rParsedInfo, pIInSign,
|
|
bstrInParam, pszValue);
|
|
}
|
|
else
|
|
{
|
|
// If method and parameter information is available
|
|
if (bMethodDtls && !pdmPropDetMap.empty())
|
|
{
|
|
bRet = CheckAliasQualifierInfo(rParsedInfo,
|
|
bstrInParam, pszValue, pdmPropDetMap);
|
|
}
|
|
}
|
|
|
|
// The parameter value does not fit into the qualifier
|
|
// allowed values.
|
|
if (!bRet)
|
|
{
|
|
bContinue = FALSE;
|
|
break;
|
|
}
|
|
|
|
if(!IsArrayType(pIInParam, bstrInParam))
|
|
{
|
|
VariantInit(&varTemp);
|
|
varTemp.vt = VT_BSTR;
|
|
varTemp.bstrVal = SysAllocString(pszValue);
|
|
|
|
if (varTemp.bstrVal == NULL)
|
|
{
|
|
//Reset the variant, it will be cleaned up by the catch...
|
|
VariantInit(&varTemp);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
VariantInit(&varPut);
|
|
if(_tcslen(pszValue) > 0){
|
|
hr = ConvertCIMTYPEToVarType(varPut, varTemp,
|
|
(_TCHAR*)pdPropDet.Type);
|
|
} else {
|
|
hr = VariantChangeType(&varPut, &varTemp, 0, VT_NULL);
|
|
}
|
|
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"VariantChangeType(-, -, 0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
BSTRVECTOR vArrayValues;
|
|
RemoveParanthesis(pszValue);
|
|
GetArrayFromToken(pszValue, vArrayValues);
|
|
hr = CheckForArray( pIInParam, bstrInParam,
|
|
varPut, vArrayValues, rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
hr = pIInParam->Put(bstrInParam, 0, &varPut, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Put(L\"%s\", 0,"
|
|
L"-, 0)", (LPWSTR) bstrInParam);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
VARIANTCLEAR(varPut);
|
|
VARIANTCLEAR(varGet);
|
|
VARIANTCLEAR(varTemp);
|
|
SAFEBSTRFREE(bstrInParam);
|
|
|
|
// Looping statements.
|
|
|
|
if ( bNamedParamList == FALSE )
|
|
cviUnnamedValue++;
|
|
lIndex++;
|
|
}
|
|
// Free the memory
|
|
SAFEADESTROY(psaNames);
|
|
|
|
if (bContinue)
|
|
{
|
|
// If insufficient parameters are specified.
|
|
if ( bNamedParamList == FALSE &&
|
|
cviUnnamedValue != cvInParams.end() )
|
|
{
|
|
bContinue = FALSE;
|
|
rParsedInfo.GetCmdSwitchesObject().SetErrataCode(
|
|
IDS_E_INVALID_NO_OF_PARAMS);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // No input parameters are available for this function.
|
|
{
|
|
// If unnamed parameters are specified.
|
|
if (!rParsedInfo.GetCmdSwitchesObject().GetPropertyList().empty())
|
|
{
|
|
bContinue = FALSE;
|
|
rParsedInfo.GetCmdSwitchesObject().SetErrataCode(
|
|
IDS_E_METHOD_HAS_NO_IN_PARAMS);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
SAFEIRELEASE(pIInSign);
|
|
SAFEIRELEASE(pIOutSign);
|
|
SAFEIRELEASE(pIClassObj);
|
|
|
|
if (bContinue)
|
|
{
|
|
hr = FormQueryAndExecuteMethodOrUtility(rParsedInfo, pIInParam);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
// Free the interface pointers and memory allocated.
|
|
SAFEIRELEASE(pIClassObj);
|
|
SAFEIRELEASE(pIInSign);
|
|
SAFEIRELEASE(pIOutSign);
|
|
SAFEIRELEASE(pIInParam);
|
|
SAFEADESTROY(psaNames);
|
|
SAFEBSTRFREE(bstrInParam);
|
|
VARIANTCLEAR(varPut);
|
|
VARIANTCLEAR(varGet);
|
|
VARIANTCLEAR(varTemp);
|
|
|
|
// Store the COM error object and set the return value to FALSE
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIClassObj);
|
|
SAFEIRELEASE(pIInSign);
|
|
SAFEIRELEASE(pIOutSign);
|
|
SAFEIRELEASE(pIInParam);
|
|
SAFEADESTROY(psaNames);
|
|
SAFEBSTRFREE(bstrInParam);
|
|
VARIANTCLEAR(varPut);
|
|
VARIANTCLEAR(varGet);
|
|
VARIANTCLEAR(varTemp);
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
_com_issue_error(hr);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CheckForArray
|
|
Synopsis :Check for the parameter of array type. If it is of
|
|
array type then creates a safearray and fills the
|
|
values passed in it.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
pIObj - pointer to IWbemClassObject object
|
|
bstrProp - property name
|
|
varDest - VARIANT Destination
|
|
vArrayValues - Input elements in Array for Array parameter
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s): None
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :CheckForArray( pIInParam, bstrInParam,
|
|
varPut, varTemp, rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::CheckForArray(IWbemClassObject* pIObj,
|
|
BSTR bstrProp, VARIANT& varDest,
|
|
BSTRVECTOR& vArrayValues,CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet* pIQualSet = NULL;
|
|
VARIANT vtType, vtTypeProp, vtTemp, varSrc;
|
|
CIMTYPE ctCimType;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
SAFEARRAY* pSa = NULL;
|
|
|
|
VariantInit(&vtType);
|
|
VariantInit(&vtTypeProp);
|
|
VariantInit(&vtTemp);
|
|
VariantInit(&varSrc);
|
|
try
|
|
{
|
|
// Obtain the property qualifier set for the property
|
|
hr = pIObj->GetPropertyQualifierSet(bstrProp, &pIQualSet);
|
|
if ( pIQualSet != NULL )
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIQualSet->Get(_bstr_t(L"CIMTYPE"), 0L, &vtType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ( vtType.vt == VT_BSTR )
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIObj->Get(bstrProp, 0L, &vtTypeProp, &ctCimType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ( ctCimType & VT_ARRAY )
|
|
{
|
|
WMICLIINT nSize = vArrayValues.size();
|
|
SAFEARRAYBOUND pSab[1];
|
|
pSab[0].lLbound = 0;
|
|
pSab[0].cElements = nSize;
|
|
VARTYPE vt = ReturnVarType(vtType.bstrVal);
|
|
if(vt != VT_NULL && vt != VT_BYREF && vt != VT_EMPTY)
|
|
{
|
|
pSa = SafeArrayCreate(vt, 1, pSab);
|
|
}
|
|
|
|
if(pSa != NULL)
|
|
{
|
|
BOOL bError = FALSE;
|
|
for(WMICLIINT i = 0; i < nSize; i++)
|
|
{
|
|
VariantInit(&varSrc);
|
|
VariantInit(&vtTemp);
|
|
varSrc.vt = VT_BSTR;
|
|
varSrc.bstrVal = SysAllocString(vArrayValues[i]);
|
|
|
|
if (varSrc.bstrVal == NULL)
|
|
{
|
|
//Reset the variant, it will be cleaned up by the catch...
|
|
VariantInit(&varSrc);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
hr = ConvertCIMTYPEToVarType ( vtTemp, varSrc, vtType.bstrVal );
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"VariantChangeType(-, -, 0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId,
|
|
rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
long lIndex[] = {i};
|
|
if ( V_VT ( & vtTemp ) == VT_NULL )
|
|
{
|
|
hr = SafeArrayPutElement(pSa, lIndex, NULL);
|
|
}
|
|
else
|
|
{
|
|
VARTYPE vt = ReturnVarType(vtType.bstrVal);
|
|
if(vt == VT_BSTR )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
vtTemp.bstrVal);
|
|
else if(vt == VT_I2 )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.iVal);
|
|
else if(vt == VT_I4 )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.lVal);
|
|
else if(vt == VT_R4 )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.fltVal);
|
|
else if(vt == VT_R8 )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.dblVal);
|
|
else if(vt == VT_BOOL )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.boolVal);
|
|
else if(vt == VT_DISPATCH )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
vtTemp.pdispVal);
|
|
else if(vt == VT_INT )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.intVal);
|
|
else if(vt == VT_UI1 )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.bVal);
|
|
else if(vt == VT_DATE )
|
|
hr = SafeArrayPutElement(pSa, lIndex,
|
|
&vtTemp.date);
|
|
else
|
|
{
|
|
bError = TRUE;
|
|
}
|
|
}
|
|
|
|
VARIANTCLEAR(vtTemp);
|
|
VARIANTCLEAR(varSrc);
|
|
if(!bError)
|
|
{
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayPutElement(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId,
|
|
rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
SAFEADESTROY(pSa);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!bError)
|
|
{
|
|
varDest.parray = pSa;
|
|
varDest.vt = vt | VT_ARRAY;
|
|
}
|
|
}
|
|
}
|
|
VARIANTCLEAR(vtTypeProp);
|
|
}
|
|
}
|
|
hr = S_OK;
|
|
VARIANTCLEAR(vtType);
|
|
}
|
|
SAFEIRELEASE(pIQualSet);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(vtType);
|
|
VARIANTCLEAR(vtTemp);
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(vtTypeProp);
|
|
SAFEIRELEASE(pIQualSet);
|
|
SAFEADESTROY(pSa);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
VARIANTCLEAR(vtType);
|
|
VARIANTCLEAR(vtTemp);
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(vtTypeProp);
|
|
SAFEIRELEASE(pIQualSet);
|
|
SAFEADESTROY(pSa);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :IsArrayType
|
|
Synopsis :Check for array type
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
pIObj - pointer to IWbemClassObject object
|
|
bstrProp - property name
|
|
Output Parameter(s): None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :IsArrayType(pIInParam, bstrInParam)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::IsArrayType( IWbemClassObject* pIObj,
|
|
BSTR bstrProp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet* pIQualSet = NULL;
|
|
VARIANT vtType, vtTypeProp;
|
|
CIMTYPE ctCimType;
|
|
BOOL bRet = FALSE;
|
|
|
|
VariantInit(&vtType);
|
|
VariantInit(&vtTypeProp);
|
|
try
|
|
{
|
|
// Obtain the property qualifier set for the property
|
|
hr = pIObj->GetPropertyQualifierSet(bstrProp, &pIQualSet);
|
|
if ( pIQualSet != NULL )
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIQualSet->Get(_bstr_t(L"CIMTYPE"), 0L, &vtType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ( vtType.vt == VT_BSTR )
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIObj->Get(bstrProp, 0L, &vtTypeProp, &ctCimType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ( ctCimType & VT_ARRAY )
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
VARIANTCLEAR(vtTypeProp);
|
|
}
|
|
}
|
|
VARIANTCLEAR(vtType);
|
|
}
|
|
SAFEIRELEASE(pIQualSet);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(vtType);
|
|
VARIANTCLEAR(vtTypeProp);
|
|
SAFEIRELEASE(pIQualSet);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :GetArrayFromToken
|
|
Synopsis :Separates comma delimited string and fill the values
|
|
in an array
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
pszValue - Comma separated array elements
|
|
Output Parameter(s):
|
|
vArrayValues - Fills with array elements
|
|
Return Type :void
|
|
Global Variables :None
|
|
Calling Syntax :GetArrayFromToken(pszValue, vArrayValues)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
void CExecEngine::GetArrayFromToken(_TCHAR* pszValue,
|
|
BSTRVECTOR& vArrayValues)
|
|
{
|
|
if(pszValue == NULL)
|
|
return;
|
|
|
|
// copy contents into local folder to stop original string changes because
|
|
// in case of multiple instance operations original string need to be called
|
|
// again and again
|
|
// i.e. \0 is inserted by call to _tcstok
|
|
_TCHAR* pszValueDup = new _TCHAR[lstrlen(pszValue)+1];
|
|
if(pszValueDup)
|
|
{
|
|
lstrcpy(pszValueDup, pszValue);
|
|
|
|
_TCHAR* pszToken = _tcstok(pszValueDup, CLI_TOKEN_COMMA);
|
|
if(pszToken != NULL)
|
|
{
|
|
TrimBlankSpaces(pszToken);
|
|
UnQuoteString(pszToken);
|
|
vArrayValues.push_back(_bstr_t(pszToken));
|
|
}
|
|
|
|
while (pszToken != NULL)
|
|
{
|
|
pszToken = _tcstok(NULL, CLI_TOKEN_COMMA);
|
|
if (pszToken != NULL)
|
|
{
|
|
TrimBlankSpaces(pszToken);
|
|
UnQuoteString(pszToken);
|
|
vArrayValues.push_back(_bstr_t(pszToken));
|
|
}
|
|
}
|
|
|
|
SAFEDELETE(pszValueDup);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessSHOWInfo
|
|
Synopsis :Executed the functionality requested by GET|LIST verb
|
|
referring to the information available with
|
|
CParsedInfo object or to display help in interactive mode
|
|
by displaying properties of concernrd instance.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
bVerb - Verb or interactive info
|
|
pszPath - the Path expression
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessSHOWInfo(rParsedInfo, bVerb, pszPath)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessSHOWInfo(CParsedInfo& rParsedInfo, BOOL bVerb,
|
|
_TCHAR* pszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bPropList = FALSE,
|
|
bRet = TRUE,
|
|
bSysProp = FALSE;
|
|
_TCHAR *pszWhereExpr = NULL,
|
|
*pszClassPath = NULL;
|
|
CHARVECTOR::iterator theIterator = NULL,
|
|
theEndIterator = NULL;
|
|
try
|
|
{
|
|
_bstr_t bstrPropList(""), bstrClassName(""),
|
|
bstrQuery(""), bstrXML("");
|
|
|
|
//Formation of query only once , useful in case /every is specified.
|
|
//if(rParsedInfo.GetCmdSwitchesObject().GetFirstQueryFormFlag() )
|
|
if(rParsedInfo.GetCmdSwitchesObject().GetFormedQuery() == NULL
|
|
|| !bVerb)
|
|
{
|
|
// Obtain the list of properties to be retrieved
|
|
if(bVerb)
|
|
{
|
|
theIterator = rParsedInfo.GetCmdSwitchesObject().
|
|
GetPropertyList().begin();
|
|
theEndIterator = rParsedInfo.GetCmdSwitchesObject().
|
|
GetPropertyList().end();
|
|
}
|
|
else
|
|
{
|
|
theIterator = rParsedInfo.GetCmdSwitchesObject().
|
|
GetInteractivePropertyList().begin();
|
|
theEndIterator = rParsedInfo.GetCmdSwitchesObject().
|
|
GetInteractivePropertyList().end();
|
|
}
|
|
|
|
// Loop thru the list of properties specified,form comma seaprated
|
|
// string of the properties i.e prop1, prop2, prop3, ....., propn
|
|
while (theIterator != theEndIterator)
|
|
{
|
|
// Set the bPropList to TRUE
|
|
bPropList = TRUE;
|
|
bstrPropList += _bstr_t(*theIterator);
|
|
|
|
// If the system properties flag is not set to true
|
|
if (!bSysProp)
|
|
bSysProp = IsSysProp(*theIterator);
|
|
|
|
// Move to next property
|
|
theIterator++;
|
|
if (theIterator != theEndIterator)
|
|
bstrPropList += _bstr_t(L", ");
|
|
};
|
|
|
|
// If properties are not specified, then by default retrieve all
|
|
// the properties. i.e '*'
|
|
if (!bPropList)
|
|
bstrPropList = ASTERIX;
|
|
|
|
// Obtain the alias target class
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrClassName);
|
|
|
|
// Obtain the class path
|
|
pszClassPath = rParsedInfo.GetCmdSwitchesObject().GetClassPath();
|
|
|
|
BOOL bClass = FALSE;
|
|
if(bVerb)
|
|
{
|
|
if(IsClassOperation(rParsedInfo))
|
|
{
|
|
bClass = TRUE;
|
|
}
|
|
}
|
|
|
|
// If CLASS | PATH expression is specified.
|
|
if ( pszClassPath != NULL)
|
|
{
|
|
if (bVerb && bClass)
|
|
{
|
|
bstrQuery = _bstr_t(L"SELECT * FROM") +
|
|
_bstr_t(" meta_class ");
|
|
}
|
|
else
|
|
bstrQuery = _bstr_t(L"SELECT ") + bstrPropList +
|
|
_bstr_t(" FROM ") + _bstr_t(pszClassPath);
|
|
}
|
|
else
|
|
{
|
|
bstrQuery = _bstr_t("SELECT ") + bstrPropList +
|
|
_bstr_t(" FROM ") + bstrClassName;
|
|
}
|
|
|
|
if(bVerb)
|
|
{
|
|
if (bClass)
|
|
{
|
|
_TCHAR pszWhere[MAX_BUFFER] = NULL_STRING;
|
|
lstrcpy(pszWhere, _T("__Class = \""));
|
|
lstrcat(pszWhere, pszClassPath);
|
|
lstrcat(pszWhere, _T("\""));
|
|
pszWhereExpr = pszWhere;
|
|
}
|
|
else
|
|
pszWhereExpr = rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression();
|
|
}
|
|
else if(pszPath)
|
|
{
|
|
_TCHAR pszWhere[MAX_BUFFER] = NULL_STRING;
|
|
bRet = ExtractClassNameandWhereExpr(pszPath,
|
|
rParsedInfo, pszWhere);
|
|
if(bRet)
|
|
pszWhereExpr = pszWhere;
|
|
}
|
|
|
|
if(pszWhereExpr)
|
|
{
|
|
bstrQuery += _bstr_t(" WHERE ") + _bstr_t(pszWhereExpr);
|
|
}
|
|
rParsedInfo.GetCmdSwitchesObject().SetFormedQuery(bstrQuery);
|
|
rParsedInfo.GetCmdSwitchesObject().SetSysPropFlag(bSysProp);
|
|
}
|
|
else
|
|
{
|
|
bstrQuery = rParsedInfo.GetCmdSwitchesObject().GetFormedQuery();
|
|
bSysProp = rParsedInfo.GetCmdSwitchesObject().GetSysPropFlag();
|
|
}
|
|
|
|
// Create the object of IWbemObjectTextSrc interface.
|
|
if (m_pITextSrc == NULL)
|
|
hr = CreateWMIXMLTextSrc(rParsedInfo);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
{
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Obtain the XML Result set.
|
|
hr = ObtainXMLResultSet(bstrQuery, rParsedInfo,
|
|
bstrXML, bSysProp, TRUE);
|
|
}
|
|
|
|
if(!bVerb)
|
|
{
|
|
BOOL bRet = g_wmiCmd.GetFormatObject().
|
|
DisplayResults(rParsedInfo, TRUE);
|
|
rParsedInfo.GetCmdSwitchesObject().FreeCOMError();
|
|
rParsedInfo.GetCmdSwitchesObject().SetErrataCode(0);
|
|
rParsedInfo.GetCmdSwitchesObject().SetInformationCode(0);
|
|
}
|
|
}
|
|
bRet = FAILED(hr) ? FALSE : TRUE;
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
bRet = FALSE;
|
|
_com_issue_error(e.Error());
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessCALLVerb
|
|
Synopsis :Processes the CALL verb request referring to the
|
|
information available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessCALLVerb(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessCALLVerb(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bRet = TRUE;
|
|
try
|
|
{
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
else
|
|
bRet = FALSE;
|
|
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
if ( bRet == TRUE )
|
|
{
|
|
// Check for the verb type, so as to handle lauching of other
|
|
// commandline utilities from the shell.
|
|
if ( rParsedInfo.GetCmdSwitchesObject().GetVerbType() == CMDLINE )
|
|
{
|
|
if (!ExecOtherCmdLineUtlty(rParsedInfo))
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!ExecWMIMethod(rParsedInfo))
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
// Store the COM error and set the return value to FALSE
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessASSOCVerb
|
|
Synopsis :Processes the ASSOC verb request referring to the
|
|
information available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessASSOCVerb(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessASSOCVerb(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bRet = TRUE;
|
|
WMICLIINT nReqType = 0;
|
|
BOOL bSwitches = FALSE,
|
|
bClass = TRUE,
|
|
bInstances = FALSE;
|
|
|
|
IEnumWbemClassObject *pIEnumObj = NULL;
|
|
IWbemClassObject *pIWbemObj = NULL;
|
|
VARIANT varPath;
|
|
VariantInit(&varPath);
|
|
try
|
|
{
|
|
_bstr_t bstrClassName(""), bstrQuery(""), bstrAssocWhere(""),
|
|
bstrResult(""), bstrXML(""), bstrAggResult("");
|
|
|
|
bstrAggResult = MULTINODE_XMLSTARTTAG;
|
|
|
|
//If assoc switches are specified, bSwitches is set and correspondingly
|
|
//assoc where clause is framed
|
|
bSwitches =((rParsedInfo.GetCmdSwitchesObject().GetResultClassName())||
|
|
(rParsedInfo.GetCmdSwitchesObject().GetResultRoleName()) ||
|
|
(rParsedInfo.GetCmdSwitchesObject().GetAssocClassName()));
|
|
|
|
if(bSwitches)
|
|
{
|
|
bstrAssocWhere += _bstr_t(" WHERE ");
|
|
if((rParsedInfo.GetCmdSwitchesObject().GetResultClassName())
|
|
!= NULL )
|
|
{
|
|
bstrAssocWhere += _bstr_t(L" ResultClass = ") +
|
|
_bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetResultClassName());
|
|
|
|
}
|
|
if((rParsedInfo.GetCmdSwitchesObject().GetResultRoleName())
|
|
!= NULL)
|
|
{
|
|
bstrAssocWhere += _bstr_t(L" ResultRole = ") +
|
|
_bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetResultRoleName());
|
|
|
|
}
|
|
if((rParsedInfo.GetCmdSwitchesObject().GetAssocClassName())
|
|
!= NULL)
|
|
{
|
|
bstrAssocWhere += _bstr_t(L" AssocClass = ") +
|
|
_bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetAssocClassName());
|
|
}
|
|
}
|
|
|
|
//NOTE: nReqType = 2 implies that first get all instances and then
|
|
// find associations for each instance
|
|
|
|
// If PATH is specified
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetPathExpression() != NULL)
|
|
{
|
|
// If PATH is specified (with key expression).
|
|
if (!rParsedInfo.GetCmdSwitchesObject().
|
|
GetExplicitWhereExprFlag())
|
|
{
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() == NULL)
|
|
{
|
|
nReqType = 2;
|
|
}
|
|
else
|
|
{
|
|
nReqType = 1;
|
|
|
|
bstrQuery = _bstr_t(L"ASSOCIATORS OF {")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetPathExpression()
|
|
+ _bstr_t("}"));
|
|
}
|
|
}
|
|
else
|
|
nReqType = 2;
|
|
}
|
|
|
|
|
|
// If CLASS expression is specified.
|
|
//associators of the class need to be displayed
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL
|
|
&& rParsedInfo.GetCmdSwitchesObject().
|
|
GetPathExpression() == NULL)
|
|
{
|
|
nReqType = 1;
|
|
bstrQuery = _bstr_t(L"ASSOCIATORS OF {")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject().GetClassPath())
|
|
+ _bstr_t("}");
|
|
|
|
if (!bSwitches)
|
|
bstrQuery += _bstr_t(L" WHERE SchemaOnly");
|
|
else
|
|
bstrQuery += bstrAssocWhere + _bstr_t(L" SchemaOnly");
|
|
}
|
|
|
|
// Check for <alias> or alias and path without keyclause
|
|
if (nReqType != 1)
|
|
{
|
|
// Obtain the alias target class
|
|
if(rParsedInfo.GetCmdSwitchesObject().GetAliasName() != NULL)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().GetClassOfAliasTarget(
|
|
bstrClassName);
|
|
}
|
|
else
|
|
bstrClassName = _bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassPath());
|
|
|
|
//obtain the instances corresponding to the alias target class
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ") + bstrClassName;
|
|
|
|
//if pwhere expression is specified or where is specified
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bstrQuery += _bstr_t(" WHERE ") +_bstr_t(rParsedInfo.
|
|
GetCmdSwitchesObject().GetWhereExpression());
|
|
}
|
|
|
|
nReqType = 2;
|
|
}
|
|
|
|
|
|
// Create the object of IWbemObjectTextSrc interface.
|
|
if (m_pITextSrc == NULL)
|
|
hr = CreateWMIXMLTextSrc(rParsedInfo);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
{
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
hr = E_FAIL; // Explicitly set error
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if(nReqType != 2)
|
|
{
|
|
// Obtain the XML Result Set.
|
|
hr = ObtainXMLResultSet(bstrQuery, rParsedInfo, bstrXML,
|
|
TRUE, FALSE);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if (m_bNoAssoc)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_NO_ASSOC, 0, bstrMsg, NULL);
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP, TRUE, TRUE);
|
|
m_bNoAssoc = FALSE;
|
|
}
|
|
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetPathExpression() == NULL)
|
|
{
|
|
bClass = TRUE;
|
|
hr = FrameAssocHeader(rParsedInfo.
|
|
GetCmdSwitchesObject().GetClassPath(),
|
|
bstrResult, bClass);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
bClass = FALSE;
|
|
hr = FrameAssocHeader(
|
|
rParsedInfo.GetCmdSwitchesObject()
|
|
.GetPathExpression(), bstrResult, bClass);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
bstrResult += bstrXML;
|
|
bstrResult += (bClass) ? L"</CLASS>" : L"</INSTANCE>";
|
|
bstrAggResult += bstrResult;
|
|
}
|
|
else
|
|
{
|
|
// Set the class flag to FALSE
|
|
bClass = FALSE;
|
|
ULONG ulReturned = 0;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId =
|
|
GetCurrentThreadId();
|
|
VariantInit(&varPath);
|
|
try
|
|
{
|
|
//enumerate the instances
|
|
hr = m_pITargetNS->ExecQuery(_bstr_t(L"WQL"),
|
|
bstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY |
|
|
WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pIEnumObj);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecQuery(L\"WQL\","
|
|
L"L\"%s\", 0, NULL, -)",
|
|
(LPWSTR)bstrQuery);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Set the interface security
|
|
hr = SetSecurity(pIEnumObj,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(
|
|
L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT, "
|
|
L"RPC_C_AUTHZ_NONE, NULL, %d, %d, -, "
|
|
L"EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId,
|
|
rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Loop thru the available instances
|
|
hr = pIEnumObj->Next( WBEM_INFINITE, 1, &pIWbemObj,
|
|
&ulReturned );
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IEnumWbemClassObject->Next(WBEM_INFINITE, 1,"
|
|
L"-, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Set this property in all objects of the collection
|
|
while (ulReturned == 1)
|
|
{
|
|
bInstances = TRUE;
|
|
|
|
VariantInit(&varPath);
|
|
hr = pIWbemObj->Get(L"__PATH", 0, &varPath, 0, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IWbemClassObject::Get(L\"__PATH\", 0, -,"
|
|
L"0, 0)");
|
|
GetBstrTFromVariant(varPath, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
//form the query for finding the associators
|
|
//of each of the instances
|
|
bstrQuery = _bstr_t(L"ASSOCIATORS OF {")
|
|
+ varPath.bstrVal
|
|
+ _bstr_t("}") ;
|
|
if (bSwitches)
|
|
bstrQuery += bstrAssocWhere;
|
|
|
|
hr = FrameAssocHeader(varPath.bstrVal, bstrResult,
|
|
bClass);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
//Obtain the result set for the associators
|
|
//of the corresponding instance
|
|
hr = ObtainXMLResultSet(bstrQuery, rParsedInfo,
|
|
bstrXML, TRUE, FALSE);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if (m_bNoAssoc)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_NO_ASSOCIATIONS, 1,
|
|
bstrMsg, (LPWSTR)varPath.bstrVal);
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP,
|
|
TRUE, TRUE);
|
|
m_bNoAssoc = FALSE;
|
|
}
|
|
|
|
bstrResult += bstrXML;
|
|
bstrResult += L"</INSTANCE>";
|
|
bstrAggResult += bstrResult;
|
|
|
|
//check for ctrl+c
|
|
if ( g_wmiCmd.GetBreakEvent() == TRUE )
|
|
{
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
break;
|
|
}
|
|
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
|
|
if ( bRet == FALSE )
|
|
break;
|
|
|
|
// Obtain the next instance in the enumeration.
|
|
hr = pIEnumObj->Next( WBEM_INFINITE, 1, &pIWbemObj,
|
|
&ulReturned);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IEnumWbemClassObject->Next(WBEM_INFINITE,"
|
|
L"1, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
SAFEIRELEASE(pIEnumObj);
|
|
|
|
// If no instances are available
|
|
if (bInstances == FALSE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_NO_INSTANCES,
|
|
0, bstrMsg, NULL);
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP,
|
|
TRUE, TRUE);
|
|
CHString sTemp;
|
|
sTemp.Format(
|
|
_T("<ERROR><DESCRIPTION>%s</DESCRIPTION></ERROR>"),
|
|
(LPWSTR) bstrMsg);
|
|
bstrAggResult = _bstr_t(sTemp);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ((nReqType != 2) || ((nReqType == 2) && bInstances))
|
|
{
|
|
bstrAggResult += L"</CIM>";
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetXMLResultSet(bstrAggResult);
|
|
}
|
|
}
|
|
}
|
|
bRet = FAILED(hr) ? FALSE : TRUE;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
_com_issue_error(e.Error());
|
|
}
|
|
// trap for CHeap_Exception
|
|
catch(CHeap_Exception)
|
|
{
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessSETVerb
|
|
Synopsis :Processes the SET verb referring to the information
|
|
available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessSETVerb(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessSETVerb(CParsedInfo& rParsedInfo)
|
|
{
|
|
// SET verb processing
|
|
BOOL bRet = TRUE;
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrQuery(""), bstrObject(""), bstrClass("");
|
|
|
|
// If anyone of the following is specified:
|
|
// a) PATH <path expr>
|
|
// b) PATH <class path expr> WHERE <where expr>
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetPathExpression() != NULL)
|
|
{
|
|
bstrClass = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
bstrObject = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetPathExpression());
|
|
|
|
// Form the query
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ") + bstrClass ;
|
|
|
|
// If WHERE expresion is given
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bstrQuery += _bstr_t(L" WHERE ")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetWhereExpression());
|
|
}
|
|
}
|
|
// If <alias> WHERE expression is specified.
|
|
else if (rParsedInfo.GetCmdSwitchesObject().GetWhereExpression()
|
|
!= NULL)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrObject);
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ")
|
|
+ bstrObject
|
|
+ _bstr_t(L" WHERE ")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetWhereExpression());
|
|
bstrClass = bstrObject;
|
|
}
|
|
// If CLASS is specified.
|
|
else if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL)
|
|
{
|
|
bstrObject = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
bstrClass = bstrObject;
|
|
}
|
|
// if only <alias> is specified
|
|
else
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrObject);
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ")
|
|
+ bstrObject;
|
|
bstrClass = bstrObject;
|
|
|
|
}
|
|
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
{
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
hr = E_FAIL; // Explicitly set error
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Validate the property values against the property
|
|
// qualifier information if available.
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetAliasName() != NULL)
|
|
{
|
|
// Validate the input parameters against the alias
|
|
// qualifier information.
|
|
bRet = ValidateAlaisInParams(rParsedInfo);
|
|
}
|
|
else
|
|
{
|
|
// Validate the input parameters against the class
|
|
// qualifier information
|
|
bRet = ValidateInParams(rParsedInfo, bstrClass);
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
// Set the values passed as input to the appropriate properties.
|
|
bRet = SetPropertyInfo(rParsedInfo, bstrQuery, bstrObject);
|
|
}
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :SetPropertyInfo
|
|
Synopsis :This function updates the property value for the
|
|
given property name and value
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
bstrQuery - String consist of WQL query
|
|
bstrObject - String consist of object path
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :SetPropertyInfo(rParsedInfo, bstrQuery, bstrObject)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::SetPropertyInfo(CParsedInfo& rParsedInfo,
|
|
_bstr_t& bstrQuery, _bstr_t& bstrObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IEnumWbemClassObject *pIEnumObj = NULL;
|
|
IWbemClassObject *pIWbemObj = NULL;
|
|
ULONG ulReturned = 0;
|
|
BOOL bSuccess = TRUE;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
VARIANT varPath;
|
|
VariantInit(&varPath);
|
|
|
|
try
|
|
{
|
|
if (bstrQuery == _bstr_t(""))
|
|
{
|
|
// If query is NULL then get the object of WMI Class based on
|
|
// PATH expression
|
|
hr = m_pITargetNS->GetObject(bstrObject,
|
|
0, NULL, &pIWbemObj, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::GetObject(L\"%s\", 0, "
|
|
L"NULL, -)", (LPWSTR) bstrObject);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// If instance path is specified then modify the instance
|
|
// properties otherwise modify class properties
|
|
if(rParsedInfo.GetCmdSwitchesObject().GetWhereExpression() == NULL)
|
|
bSuccess = SetProperties(rParsedInfo, pIWbemObj, TRUE);
|
|
else
|
|
bSuccess = SetProperties(rParsedInfo, pIWbemObj, FALSE);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
}
|
|
else
|
|
{
|
|
// Execute the query to get collection of objects
|
|
hr = m_pITargetNS->ExecQuery(_bstr_t(L"WQL"), bstrQuery, 0,
|
|
NULL, &pIEnumObj);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecQuery(L\"WQL\","
|
|
L"L\"%s\", 0, NULL, -)", (LPWSTR)bstrQuery);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
// Set the interface security
|
|
hr = SetSecurity(pIEnumObj,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT, "
|
|
L"RPC_C_AUTHZ_NONE, NULL, %d, %d, -, EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
BOOL bInstances = FALSE;
|
|
|
|
// Loop thru the available instances
|
|
hr = pIEnumObj->Next( WBEM_INFINITE, 1, &pIWbemObj, &ulReturned );
|
|
|
|
// Set this property in all objects of the collection
|
|
while (ulReturned == 1)
|
|
{
|
|
bInstances = TRUE;
|
|
|
|
// If instance updation failed.
|
|
if (!SetProperties(rParsedInfo, pIWbemObj, FALSE))
|
|
{
|
|
bSuccess = FALSE;
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
break;
|
|
}
|
|
VARIANTCLEAR(varPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
|
|
// Obtain the next instance in the enumeration.
|
|
hr = pIEnumObj->Next( WBEM_INFINITE, 1,
|
|
&pIWbemObj, &ulReturned);
|
|
}
|
|
SAFEIRELEASE(pIEnumObj);
|
|
// If no instances are available
|
|
if (!bInstances)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(IDS_I_NO_INSTANCES);
|
|
}
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bSuccess = FALSE;
|
|
}
|
|
// trap for CHeap_Exception
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :SetProperties
|
|
Synopsis :This function changes the property values for the
|
|
given property names and values in a passed
|
|
IWbemClassObject
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - CParsedInfo object consist of parsed tokens
|
|
pIWbemObj - IWbemClassObject in which property has to be set
|
|
bClass - Flag to indicate whether class object is passed or
|
|
instance is passed
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :SetProperties(rParsedInfo, pIWbemObj, bClass)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::SetProperties(CParsedInfo& rParsedInfo,
|
|
IWbemClassObject* pIWbemObj, BOOL bClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet *pIQualSet = NULL;
|
|
BOOL bRet = TRUE,
|
|
bInteractive = FALSE,
|
|
bChange = FALSE;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
BSTRMAP::iterator theIterator = NULL;
|
|
VARIANT varValue,
|
|
varDest,
|
|
varSrc,
|
|
varPath,
|
|
varType;
|
|
INTEROPTION interOption = YES;
|
|
|
|
VariantInit(&varValue);
|
|
VariantInit(&varDest);
|
|
VariantInit(&varSrc);
|
|
VariantInit(&varPath);
|
|
VariantInit(&varType);
|
|
|
|
// Get the proprty name and their corresponding value
|
|
BSTRMAP theMap = rParsedInfo.GetCmdSwitchesObject().GetParameterMap();
|
|
|
|
// Set the iterator to the start of the map.
|
|
theIterator = theMap.begin();
|
|
|
|
// obtian the verb interactive mode status.
|
|
bInteractive = IsInteractive(rParsedInfo);
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrResult;
|
|
// Obtain the __PATH property value
|
|
hr = pIWbemObj->Get(_bstr_t(L"__PATH"), 0, &varPath, 0, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Get(L\"__PATH\", 0, -,"
|
|
L"0, 0)");
|
|
GetBstrTFromVariant(varPath, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// If /INTERACTIVE switch is specified, obtain the user response.
|
|
if (bInteractive)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
while(TRUE)
|
|
{
|
|
if(IsClassOperation(rParsedInfo))
|
|
{
|
|
WMIFormatMessage(IDS_I_UPDATE_PROMPT, 1, bstrMsg,
|
|
(LPWSTR) _bstr_t(varPath.bstrVal));
|
|
interOption = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
else
|
|
{
|
|
WMIFormatMessage(IDS_I_UPDATE_PROMPT2, 1, bstrMsg,
|
|
(LPWSTR) _bstr_t(varPath.bstrVal));
|
|
interOption = GetUserResponseEx((LPWSTR)bstrMsg);
|
|
}
|
|
|
|
if (interOption == YES || interOption == NO)
|
|
break;
|
|
else
|
|
if (interOption == HELP)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(0);
|
|
ProcessSHOWInfo(rParsedInfo, FALSE,
|
|
(_TCHAR*)_bstr_t(varPath.bstrVal));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_PROMPT_UPDATING, 1, bstrMsg,
|
|
(LPWSTR) _bstr_t(varPath.bstrVal));
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP, FALSE, TRUE);
|
|
}
|
|
|
|
VARIANTCLEAR(varPath);
|
|
VariantInit(&varSrc);
|
|
VariantInit(&varDest);
|
|
|
|
if (interOption == YES)
|
|
{
|
|
PROPDETMAP pdmPropDetMap = rParsedInfo.GetCmdSwitchesObject().
|
|
GetPropDetMap();
|
|
PROPDETMAP::iterator itrPropDetMap;
|
|
BOOL bPropType = FALSE;
|
|
|
|
// Update all properties
|
|
while (theIterator != theMap.end())
|
|
{
|
|
// Get the property names and their corresponding values
|
|
_bstr_t bstrProp = _bstr_t((_TCHAR*)(*theIterator).first);
|
|
|
|
// Get the derivation of property name
|
|
if ( Find(pdmPropDetMap, bstrProp, itrPropDetMap) == TRUE )
|
|
{
|
|
if ( !((*itrPropDetMap).second.Derivation) == FALSE )
|
|
bstrProp = (*itrPropDetMap).second.Derivation;
|
|
bPropType = TRUE;
|
|
}
|
|
else
|
|
bPropType = FALSE;
|
|
|
|
// Check for the property validity(i.e. does it exist or not?)
|
|
VariantInit(&varValue);
|
|
hr = pIWbemObj->Get(bstrProp, 0, &varValue, 0, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Get(L\"%s\", 0, -,"
|
|
L"0, 0)", (LPWSTR) bstrProp);
|
|
if ( bPropType )
|
|
{
|
|
GetBstrTFromVariant(varValue, bstrResult,
|
|
(*itrPropDetMap).second.Type);
|
|
}
|
|
else
|
|
GetBstrTFromVariant(varValue, bstrResult);
|
|
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Set the change flag to TRUE
|
|
bChange = TRUE;
|
|
|
|
// If the property content is <empty>
|
|
if ((varValue.vt == VT_EMPTY) || (varValue.vt == VT_NULL))
|
|
{
|
|
// Obtain the property qualifier set for the property
|
|
hr = pIWbemObj->GetPropertyQualifierSet(bstrProp,
|
|
&pIQualSet);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IWbemClassObject::GetPropertyQualifierSet(L\"%s\","
|
|
L" -)", (LPWSTR)bstrProp);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
VariantInit(&varType);
|
|
if (pIQualSet)
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIQualSet->Get(_bstr_t(L"CIMTYPE"), 0L,
|
|
&varType, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemQualifierSet::Get(L\"CIMTYPE\","
|
|
L" 0, -, 0, 0)");
|
|
GetBstrTFromVariant(varType, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if(!IsArrayType(pIWbemObj, bstrProp))
|
|
{
|
|
bool bNullConst = FALSE;
|
|
|
|
varSrc.vt = VT_BSTR;
|
|
_TCHAR* pszValue = (*theIterator).second;
|
|
|
|
if(_tcsicmp(pszValue,_T("NULL")) == 0){
|
|
bNullConst = TRUE;
|
|
}
|
|
|
|
if(_tcsicmp(pszValue,_T("\"NULL\"")) == 0){
|
|
varSrc.bstrVal = SysAllocString(_T("NULL"));
|
|
} else {
|
|
|
|
varSrc.bstrVal = SysAllocString(pszValue);
|
|
}
|
|
|
|
if (varSrc.bstrVal == NULL)
|
|
{
|
|
//Reset the variant, it will be cleaned up by the catch...
|
|
VariantInit(&varSrc);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
if (bNullConst)
|
|
hr = VariantChangeType(&varDest, &varSrc, 0, VT_NULL);
|
|
else
|
|
hr = ConvertCIMTYPEToVarType(varDest, varSrc,
|
|
(_TCHAR*)varType.bstrVal);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"VariantChangeType(-, -, 0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
BSTRVECTOR vArrayValues;
|
|
_TCHAR* pszValue = (*theIterator).second;
|
|
|
|
RemoveParanthesis(pszValue);
|
|
GetArrayFromToken(pszValue,
|
|
vArrayValues);
|
|
hr = CheckForArray( pIWbemObj, bstrProp,
|
|
varDest, vArrayValues, rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
}
|
|
}
|
|
// If the property content is not <empty>
|
|
else
|
|
{
|
|
if(!IsArrayType(pIWbemObj, bstrProp))
|
|
{
|
|
bool bNullConst = FALSE;
|
|
|
|
varSrc.vt = VT_BSTR;
|
|
_TCHAR* pszValue = (*theIterator).second;
|
|
|
|
if(_tcsicmp(pszValue,_T("NULL")) == 0){
|
|
bNullConst = TRUE;
|
|
}
|
|
|
|
if(_tcsicmp(pszValue,_T("\"NULL\"")) == 0){
|
|
varSrc.bstrVal = SysAllocString(_T("NULL"));
|
|
} else {
|
|
|
|
varSrc.bstrVal = SysAllocString(pszValue);
|
|
}
|
|
|
|
if (varSrc.bstrVal == NULL)
|
|
{
|
|
//Reset the variant, it will be cleaned up by the catch...
|
|
VariantInit(&varSrc);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
// If _T("NULL") is the value should be treated as
|
|
// equivalent to VT_NULL
|
|
if (bNullConst)
|
|
hr = VariantChangeType(&varDest, &varSrc, 0, VT_NULL);
|
|
else
|
|
hr = VariantChangeType(&varDest, &varSrc,
|
|
0, varValue.vt);
|
|
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"VariantChangeType(-, -, 0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
BSTRVECTOR vArrayValues;
|
|
_TCHAR* pszValue = (*theIterator).second;
|
|
|
|
RemoveParanthesis(pszValue);
|
|
GetArrayFromToken(pszValue,
|
|
vArrayValues);
|
|
hr = CheckForArray( pIWbemObj, bstrProp,
|
|
varDest, vArrayValues, rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
}
|
|
|
|
// Update the property value
|
|
hr = pIWbemObj->Put(bstrProp, 0, &varDest, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Put(L\"%s\", 0, -, 0)",
|
|
(LPWSTR)bstrProp);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
VARIANTCLEAR(varValue);
|
|
|
|
// Move to next entry
|
|
theIterator++;
|
|
}
|
|
}
|
|
|
|
// Write the instance or class object to Windows Management
|
|
// Instrumentation (WMI).
|
|
if (bChange)
|
|
{
|
|
if(bClass)
|
|
{
|
|
// Update the class schema with the changes
|
|
hr = m_pITargetNS->PutClass(pIWbemObj, 0, NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::PutClass(-, 0, "
|
|
L"NULL, NULL)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
// Update the instance with the changes
|
|
hr = m_pITargetNS->PutInstance(pIWbemObj, WBEM_FLAG_UPDATE_ONLY, NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::PutInstance(-, 0, NULL"
|
|
L", NULL)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
}
|
|
DisplayString(IDS_I_SET_SUCCESS, CP_OEMCP, NULL, FALSE, TRUE);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
VARIANTCLEAR(varValue);
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
|
|
// Store the COM error, and set the return value to FALSE.
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
VARIANTCLEAR(varValue);
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ConnectToTargetNS
|
|
Synopsis :This function connects to WMI namespace on the target
|
|
machine with given user credentials.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :ConnectToTargetNS(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::ConnectToTargetNS(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
try
|
|
{
|
|
SAFEIRELEASE(m_pITargetNS);
|
|
_bstr_t bstrNameSpace = _bstr_t(L"\\\\")
|
|
+ _bstr_t(rParsedInfo.GetNode())
|
|
+ _bstr_t(L"\\")
|
|
+ _bstr_t(rParsedInfo.GetNamespace());
|
|
|
|
// Connect to the specified WMI namespace
|
|
hr = Connect(m_pIWbemLocator, &m_pITargetNS,
|
|
bstrNameSpace,
|
|
_bstr_t(rParsedInfo.GetUser()),
|
|
_bstr_t(rParsedInfo.GetPassword()),
|
|
_bstr_t(rParsedInfo.GetLocale()),
|
|
rParsedInfo);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemLocator::ConnectServer(L\"%s\", "
|
|
L"L\"%s\", *, L\"%s\", 0L, L\"%s\", NULL, -)",
|
|
(LPWSTR)bstrNameSpace,
|
|
(rParsedInfo.GetUser()) ? rParsedInfo.GetUser() : L"<null>",
|
|
rParsedInfo.GetLocale(),
|
|
(rParsedInfo.GetAuthorityPrinciple()) ?
|
|
rParsedInfo.GetAuthorityPrinciple() : L"<null>");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
// Set the interface level security
|
|
hr = SetSecurity(m_pITargetNS,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().GetImpersonationLevel());
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(
|
|
L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,"
|
|
L"NULL, %d, %d, -, EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CreateWMIXMLTextSrc
|
|
Synopsis :This function creates the IWbemObjectTextSrc instance
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :CreateWMIXMLTextSrc(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::CreateWMIXMLTextSrc(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
|
|
try
|
|
{
|
|
hr = CoCreateInstance(CLSID_WbemObjectTextSrc, NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemObjectTextSrc,
|
|
(LPVOID*) &m_pITextSrc);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"CoCreateInstance(CLSID_WbemObjectTextSrc, NULL,"
|
|
L"CLSCTX_INPROC_SERVER, IID_IWbemObjectTextSrc, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CreateContext
|
|
Synopsis :This function creates the IWbemContext instance
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :CreateContext(rParsedInfo)
|
|
Calls :CParsedInfo::GetCmdSwitchesObject()
|
|
CCommandSwitches::SetCOMError()
|
|
CoCreateInstance()
|
|
Called by :CExecEngine::ObtainXMLResultSet()
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::CreateContext(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
try
|
|
{
|
|
//Create context object
|
|
MULTI_QI mqi = { &IID_IWbemContext, 0, 0 };
|
|
hr = CoCreateInstanceEx(CLSID_WbemContext, NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
0, 1, &mqi);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"CoCreateInstanceEx(CLSID_WbemContext, NULL,"
|
|
L"CLSCTX_INPROC_SERVER, 0, 1, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
m_pIContext = reinterpret_cast<IWbemContext*>(mqi.pItf);
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Name :ExecuteMethodAndDisplayResults
|
|
Synopsis :This function executes and displays the
|
|
results corresponding to the method. If
|
|
interactive mode is set, the user is prompted
|
|
choose the method
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
bstrPath - _bstr_t type,Path expression
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
pIInParam - Pointer to the IWbemclassobject
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :ExecuteMethodAndDisplayResults(bstrPath, rParsedInfo,
|
|
pIInParam)
|
|
Calls :None
|
|
Called by :CExecEngine::ExecWMIMethod()
|
|
Notes :none
|
|
-------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::ExecuteMethodAndDisplayResults(_bstr_t bstrPath,
|
|
CParsedInfo& rParsedInfo,
|
|
IWbemClassObject* pIInParam)
|
|
{
|
|
_TCHAR *pszMethodName = NULL;
|
|
INTEROPTION interOption = YES;
|
|
IWbemClassObject *pIOutParam = NULL;
|
|
HRESULT hr = S_OK;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
VARIANT varTemp;
|
|
VariantInit(&varTemp);
|
|
|
|
// Obtain the method name
|
|
pszMethodName = rParsedInfo.GetCmdSwitchesObject().GetMethodName();
|
|
|
|
try
|
|
{
|
|
// If /INTERACTIVE switch is specified, obtain the user response.
|
|
if (IsInteractive(rParsedInfo) == TRUE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
while ( TRUE )
|
|
{
|
|
BOOL bInstanceLevel = TRUE;
|
|
if(IsClassOperation(rParsedInfo))
|
|
{
|
|
bInstanceLevel = FALSE;
|
|
}
|
|
else
|
|
{
|
|
_TCHAR *pszVerbName = rParsedInfo.GetCmdSwitchesObject().
|
|
GetVerbName();
|
|
if(CompareTokens(pszVerbName, CLI_TOKEN_CALL))
|
|
{
|
|
if ( rParsedInfo.GetCmdSwitchesObject().
|
|
GetAliasName() != NULL )
|
|
{
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() == NULL)
|
|
{
|
|
bInstanceLevel = FALSE;
|
|
}
|
|
else
|
|
bInstanceLevel = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ((rParsedInfo.GetCmdSwitchesObject().
|
|
GetPathExpression() != NULL)
|
|
&& (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() == NULL))
|
|
{
|
|
bInstanceLevel = FALSE;
|
|
}
|
|
else
|
|
bInstanceLevel = TRUE;
|
|
}
|
|
}
|
|
else
|
|
bInstanceLevel = TRUE;
|
|
}
|
|
|
|
if(bInstanceLevel)
|
|
{
|
|
WMIFormatMessage(IDS_I_METH_EXEC_PROMPT2, 2, bstrMsg,
|
|
(LPWSTR) bstrPath, pszMethodName);
|
|
interOption = GetUserResponseEx((LPWSTR)bstrMsg);
|
|
}
|
|
else
|
|
{
|
|
WMIFormatMessage(IDS_I_METH_EXEC_PROMPT, 2, bstrMsg,
|
|
(LPWSTR) bstrPath, pszMethodName);
|
|
interOption = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
|
|
if ( interOption == YES || interOption == NO )
|
|
break;
|
|
else if(interOption == HELP)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(0);
|
|
ProcessSHOWInfo(rParsedInfo, FALSE, (LPWSTR)bstrPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( interOption == YES )
|
|
{
|
|
if (IsInteractive(rParsedInfo) == FALSE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_METH_EXEC_STATUS, 2, bstrMsg,
|
|
(LPWSTR) bstrPath, pszMethodName);
|
|
DisplayMessage((LPWSTR)bstrMsg, CP_OEMCP, FALSE, TRUE);
|
|
}
|
|
|
|
// Execute the method with the given input arguments
|
|
hr = m_pITargetNS->ExecMethod(bstrPath,
|
|
_bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetMethodName()),
|
|
0L,
|
|
NULL,
|
|
pIInParam,
|
|
&pIOutParam,
|
|
NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecMethod(L\"%s\", L\"%s\", "
|
|
L"0, NULL, -, -, NULL)", (LPWSTR) bstrPath,
|
|
rParsedInfo.GetCmdSwitchesObject().GetMethodName()
|
|
? rParsedInfo.GetCmdSwitchesObject().GetMethodName()
|
|
: L"<null>");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
DisplayString(IDS_I_CALL_SUCCESS, CP_OEMCP, NULL, FALSE, TRUE);
|
|
|
|
// Check the method execution status.
|
|
if(pIOutParam)
|
|
{
|
|
_TCHAR szMsg[BUFFER1024] = NULL_STRING;
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetMethExecOutParam(pIOutParam);
|
|
|
|
DisplayMethExecOutput(rParsedInfo);
|
|
}
|
|
SAFEIRELEASE(pIOutParam);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIOutParam);
|
|
VARIANTCLEAR(varTemp);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIOutParam);
|
|
VARIANTCLEAR(varTemp);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :DisplayMethExecOutput
|
|
Synopsis :Displays the result of execution of the method.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - CParsedInfo object.
|
|
Output Parameter(s):None
|
|
Return Type :void
|
|
Global Variables :None
|
|
Calling Syntax :DisplayMethExecOutput(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
void CExecEngine::DisplayMethExecOutput(CParsedInfo& rParsedInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject *pIOutParam = NULL;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
BSTR pstrMofTextOfObj = NULL;
|
|
VARIANT vtTemp;
|
|
VariantInit(&vtTemp);
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrResult;
|
|
pIOutParam = rParsedInfo.GetCmdSwitchesObject().GetMethExecOutParam();
|
|
if ( pIOutParam != NULL )
|
|
{
|
|
hr = pIOutParam->GetObjectText(0, &pstrMofTextOfObj);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject->GetObjectText(0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
DisplayString(IDS_I_OUT_PARAMS,CP_OEMCP, NULL, FALSE, TRUE);
|
|
DisplayMessage(_bstr_t(pstrMofTextOfObj), CP_OEMCP, FALSE, TRUE);
|
|
DisplayMessage(_T("\n"), CP_OEMCP, TRUE, TRUE);
|
|
SAFEBSTRFREE(pstrMofTextOfObj);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEBSTRFREE(pstrMofTextOfObj);
|
|
_com_issue_error(e.Error());
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEBSTRFREE(pstrMofTextOfObj);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ExecOtherCmdLineUtlty
|
|
Synopsis :Invokes other command line utility specified in
|
|
Derivation of Verb if Verb Type is "CommandLine"
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - CParsedInfo object.
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ExecOtherCmdLineUtlty(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ExecOtherCmdLineUtlty(CParsedInfo& rParsedInfo)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
BOOL bInvalidNoOfArgs = FALSE;
|
|
|
|
if ( rParsedInfo.GetCmdSwitchesObject().GetNamedParamListFlag() == FALSE )
|
|
{
|
|
METHDETMAP mdpMethDetMap =
|
|
rParsedInfo.GetCmdSwitchesObject().GetMethDetMap();
|
|
METHDETMAP::iterator iMethDetMapItr = mdpMethDetMap.begin();
|
|
METHODDETAILS mdMethDet = (*iMethDetMapItr).second;
|
|
|
|
CHARVECTOR cvInParams =
|
|
rParsedInfo.GetCmdSwitchesObject().GetPropertyList();
|
|
|
|
PROPDETMAP pdmPropDetMap = mdMethDet.Params;
|
|
if ( !pdmPropDetMap.empty() )
|
|
{
|
|
if ( pdmPropDetMap.size() != cvInParams.size() )
|
|
bInvalidNoOfArgs = TRUE;
|
|
}
|
|
}
|
|
|
|
if ( bInvalidNoOfArgs == TRUE )
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().SetErrataCode(
|
|
IDS_E_INVALID_NO_OF_PARAMS);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
HRESULT hr = FormQueryAndExecuteMethodOrUtility(rParsedInfo);
|
|
bRet = FAILED(hr) ? FALSE : TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessDELETEVerb
|
|
Synopsis :Processes the DELETE verb referring to the information
|
|
available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input parameter :
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output parameters :
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessDELETEVerb(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessDELETEVerb(CParsedInfo& rParsedInfo)
|
|
{
|
|
// DELETE verb processing
|
|
BOOL bRet = TRUE;
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrQuery(""), bstrObject("");
|
|
// If anyone of the following is specified:
|
|
// a) PATH <path expr>
|
|
// b) PATH <class path expr> WHERE <where expr>
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetPathExpression() != NULL)
|
|
{
|
|
_bstr_t bstrClass = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
|
|
bstrObject = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetPathExpression());
|
|
|
|
// Form the query
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ") + bstrClass ;
|
|
|
|
// If WHERE expresion is given
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bstrQuery += _bstr_t(L" WHERE ")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetWhereExpression());
|
|
}
|
|
}
|
|
// If <alias> WHERE expression is specified.
|
|
else if (rParsedInfo.GetCmdSwitchesObject().GetWhereExpression()
|
|
!= NULL)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrObject);
|
|
bstrQuery = _bstr_t(L"SELECT * FROM ")
|
|
+ bstrObject
|
|
+ _bstr_t(L" WHERE ")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetWhereExpression());
|
|
}
|
|
// If CLASS is specified.
|
|
else if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL)
|
|
{
|
|
bstrObject = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
}
|
|
// if Alias name is specified
|
|
else
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrObject);
|
|
bstrQuery = _bstr_t (L"SELECT * FROM ")
|
|
+bstrObject;
|
|
}
|
|
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
{
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
hr = E_FAIL; // Explicitly set error
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
bRet = DeleteObjects(rParsedInfo, bstrQuery, bstrObject);
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :DeleteObjects
|
|
Synopsis :This function deletes the instances(s) or class
|
|
specified for deletion.
|
|
Type :Member Function
|
|
Input parameter :
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
bstrQuery - String consist of WQL query
|
|
bstrObject - String consist of object path
|
|
Output parameters :
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :DeleteObjects(rParsedInfo, bstrQuery, bstrObject)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::DeleteObjects(CParsedInfo& rParsedInfo,
|
|
_bstr_t& bstrQuery, _bstr_t& bstrObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bSuccess = TRUE;
|
|
IEnumWbemClassObject *pIEnumObj = NULL;
|
|
IWbemClassObject *pIWbemObj = NULL;
|
|
ULONG ulReturned = 0;
|
|
INTEROPTION interOption = YES;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
VARIANT vtPath;
|
|
VariantInit(&vtPath);
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrResult;
|
|
if (bstrQuery == _bstr_t(""))
|
|
{
|
|
// If /INTERACTIVE switch is specified, obtain the user response.
|
|
if (IsInteractive(rParsedInfo) == TRUE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
while ( TRUE )
|
|
{
|
|
if(IsClassOperation(rParsedInfo))
|
|
{
|
|
WMIFormatMessage(IDS_I_DELETE_CLASS_PROMPT, 1, bstrMsg,
|
|
(LPWSTR) bstrObject);
|
|
interOption = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
else
|
|
{
|
|
WMIFormatMessage(IDS_I_DELETE_CLASS_PROMPT2, 1, bstrMsg,
|
|
(LPWSTR) bstrObject);
|
|
interOption = GetUserResponseEx((LPWSTR)bstrMsg);
|
|
}
|
|
|
|
if ( interOption == YES || interOption == NO )
|
|
break;
|
|
else if(interOption == HELP)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(0);
|
|
ProcessSHOWInfo(rParsedInfo, FALSE,
|
|
(LPWSTR)bstrObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (interOption == YES)
|
|
{
|
|
// If instance path is specified then delete the instance
|
|
// properties otherwise delete the class
|
|
if(!rParsedInfo.GetCmdSwitchesObject().GetWhereExpression())
|
|
{
|
|
// If WHERE expression is NULL then delete the WMI class
|
|
hr = m_pITargetNS->DeleteClass(bstrObject, 0, NULL, NULL);
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::DeleteClass"
|
|
L"(L\"%s\", 0, NULL, NULL)", (LPWSTR)bstrObject);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
DisplayString(IDS_I_DELETE_SUCCESS,CP_OEMCP,
|
|
NULL, FALSE, TRUE);
|
|
}
|
|
else
|
|
{
|
|
// If WHERE expression is not NULL then delete the
|
|
// WMI instance
|
|
DisplayString(IDS_I_DELETING_INSTANCE,
|
|
CP_OEMCP,(LPWSTR)vtPath.bstrVal,
|
|
FALSE, TRUE);
|
|
hr = m_pITargetNS->DeleteInstance(bstrObject,
|
|
0, NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::DeleteInstance"
|
|
L"(L\"%s\", 0, NULL, NULL)",
|
|
(LPWSTR) bstrObject);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo,
|
|
m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
DisplayString(IDS_I_INSTANCE_DELETE_SUCCESS,
|
|
CP_OEMCP, NULL, FALSE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Execute the query to get collection of objects
|
|
hr = m_pITargetNS->ExecQuery(_bstr_t(L"WQL"), bstrQuery,
|
|
0, NULL, &pIEnumObj);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecQuery(L\"WQL\","
|
|
L"L\"%s\", 0, NULL, -)", (LPWSTR)bstrQuery);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
// Set the interface security
|
|
hr = SetSecurity(pIEnumObj,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT, "
|
|
L"RPC_C_AUTHZ_NONE, NULL, %d, %d, -, EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
BOOL bInstances = FALSE;
|
|
BOOL bInteractive = IsInteractive(rParsedInfo);
|
|
|
|
hr = pIEnumObj->Next(WBEM_INFINITE, 1, &pIWbemObj, &ulReturned);
|
|
|
|
// Set this property in all objects of the collection
|
|
while (ulReturned == 1)
|
|
{
|
|
INTEROPTION interOption = YES;
|
|
bInstances = TRUE;
|
|
VariantInit(&vtPath);
|
|
|
|
// Get the object path.
|
|
hr = pIWbemObj->Get(_bstr_t(L"__PATH"), 0, &vtPath, NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(
|
|
L"IWbemClassObject::Get(L\"__PATH\", 0, -, 0, 0)");
|
|
GetBstrTFromVariant(vtPath, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// If /INTERACTIVE switch is specified, obtain user response.
|
|
if (IsInteractive(rParsedInfo) == TRUE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
while ( TRUE )
|
|
{
|
|
if(IsClassOperation(rParsedInfo))
|
|
{
|
|
WMIFormatMessage(IDS_I_DELETE_CLASS_PROMPT,
|
|
1, bstrMsg, (LPWSTR) vtPath.bstrVal);
|
|
interOption = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
else
|
|
{
|
|
WMIFormatMessage(IDS_I_DELETE_CLASS_PROMPT2, 1,
|
|
bstrMsg, (LPWSTR) vtPath.bstrVal);
|
|
interOption = GetUserResponseEx((LPWSTR)bstrMsg);
|
|
}
|
|
|
|
if ( interOption == YES || interOption == NO )
|
|
break;
|
|
else if(interOption == HELP)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(0);
|
|
ProcessSHOWInfo(rParsedInfo, FALSE,
|
|
(LPWSTR)vtPath.bstrVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (interOption == YES)
|
|
{
|
|
DisplayString(IDS_I_DELETING_INSTANCE,
|
|
CP_OEMCP,(LPWSTR)vtPath.bstrVal, FALSE, TRUE);
|
|
hr = m_pITargetNS->DeleteInstance(vtPath.bstrVal,
|
|
0, NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::DeleteInstance"
|
|
L"(L\"%s\", 0, NULL, NULL)",
|
|
(LPWSTR) vtPath.bstrVal);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
VARIANTCLEAR(vtPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
DisplayString(IDS_I_INSTANCE_DELETE_SUCCESS,CP_OEMCP,
|
|
NULL, FALSE, TRUE);
|
|
}
|
|
hr = pIEnumObj->Next( WBEM_INFINITE, 1, &pIWbemObj,
|
|
&ulReturned);
|
|
}
|
|
SAFEIRELEASE(pIEnumObj);
|
|
|
|
// If no instances are available
|
|
if (!bInstances)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(IDS_I_NO_INSTANCES);
|
|
}
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(vtPath);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bSuccess = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
VARIANTCLEAR(vtPath);
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :GetUserResponse
|
|
Synopsis :This function accepts the user response before going
|
|
ahead, when /INTERACTIVE is specified at the verb
|
|
level
|
|
Type :Member Function
|
|
Input parameter :
|
|
pszMsg - message to be displayed.
|
|
Output parameters :None
|
|
Return Type :INTEROPTION
|
|
Global Variables :None
|
|
Calling Syntax :GetUserResponse(pszMsg)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
INTEROPTION CExecEngine::GetUserResponse(_TCHAR* pszMsg)
|
|
{
|
|
INTEROPTION bRet = YES;
|
|
_TCHAR szResp[BUFFER255] = NULL_STRING;
|
|
_TCHAR *pBuf = NULL;
|
|
|
|
if (pszMsg == NULL)
|
|
bRet = NO;
|
|
|
|
if(bRet != NO)
|
|
{
|
|
// Get the user response, till 'Y' - yes or 'N' - no
|
|
// is keyed in
|
|
while(TRUE)
|
|
{
|
|
DisplayMessage(pszMsg, CP_OEMCP, TRUE, TRUE);
|
|
pBuf = _fgetts(szResp, BUFFER255-1, stdin);
|
|
if(pBuf != NULL)
|
|
{
|
|
LONG lInStrLen = lstrlen(szResp);
|
|
if(szResp[lInStrLen - 1] == _T('\n'))
|
|
szResp[lInStrLen - 1] = _T('\0');
|
|
}
|
|
else if ( g_wmiCmd.GetBreakEvent() != TRUE )
|
|
{
|
|
lstrcpy(szResp, RESPONSE_NO);
|
|
DisplayMessage(_T("\n"), CP_OEMCP, TRUE, TRUE);
|
|
}
|
|
|
|
if ( g_wmiCmd.GetBreakEvent() == TRUE )
|
|
{
|
|
g_wmiCmd.SetBreakEvent(FALSE);
|
|
lstrcpy(szResp, RESPONSE_NO);
|
|
DisplayMessage(_T("\n"), CP_OEMCP, TRUE, TRUE);
|
|
}
|
|
if (CompareTokens(szResp, RESPONSE_YES)
|
|
|| CompareTokens(szResp, RESPONSE_NO))
|
|
break;
|
|
}
|
|
if (CompareTokens(szResp, RESPONSE_NO))
|
|
bRet = NO;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ProcessCREATEVerb
|
|
Synopsis :Processes the CREATE verb referring to the information
|
|
available with CParsedInfo object.
|
|
Type :Member Function
|
|
Input parameter :
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output parameters :
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ProcessCREATEVerb(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ProcessCREATEVerb(CParsedInfo& rParsedInfo)
|
|
{
|
|
// CREATE verb processing
|
|
BOOL bRet = TRUE;
|
|
INTEROPTION interCreate = YES;
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrClass("");
|
|
// If object PATH expression is specified.
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetPathExpression() != NULL)
|
|
{
|
|
bstrClass = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
}
|
|
// If CLASS is specified.
|
|
else if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL)
|
|
{
|
|
bstrClass = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassPath());
|
|
}
|
|
// if Alias name is specified
|
|
else
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrClass);
|
|
}
|
|
|
|
// Check if interactive mode
|
|
if (IsInteractive(rParsedInfo) == TRUE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
WMIFormatMessage(IDS_I_CREATE_INST_PROMPT, 1,
|
|
bstrMsg, (LPWSTR) bstrClass);
|
|
// Get the user response.
|
|
interCreate = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
if (interCreate == YES)
|
|
{
|
|
// Connect to WMI namespace
|
|
if (m_pITargetNS == NULL)
|
|
{
|
|
if ( IsFailFastAndNodeExist(rParsedInfo) == TRUE )
|
|
{
|
|
hr = ConnectToTargetNS(rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
hr = E_FAIL; // Explicitly set error
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Validate the property values against the property
|
|
// qualifier information if available.
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetAliasName() != NULL)
|
|
{
|
|
// Validate the input parameters against the alias
|
|
// qualifier information.
|
|
bRet = ValidateAlaisInParams(rParsedInfo);
|
|
}
|
|
else
|
|
{
|
|
// Validate the input parameters against the class
|
|
// qualifier information
|
|
bRet = ValidateInParams(rParsedInfo, bstrClass);
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
// Set the values passed as input to the appropriate properties.
|
|
bRet = CreateInstance(rParsedInfo, bstrClass);
|
|
}
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
// Message to be displayed to the user
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(IDS_I_NOCREATE);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CreateInstance
|
|
Synopsis :This function creates an instance of the specified
|
|
class
|
|
Type :Member Function
|
|
Input parameter :
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
bstrClass - classname
|
|
Output parameters :
|
|
rParsedInfo - reference to the CParsedInfo object
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :CreateInstance(rParsedInfo, bstrClass)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::CreateInstance(CParsedInfo& rParsedInfo, BSTR bstrClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject *pIWbemObj = NULL;
|
|
IWbemClassObject *pINewInst = NULL;
|
|
IWbemQualifierSet *pIQualSet = NULL;
|
|
BOOL bSuccess = TRUE;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
CHString chsMsg;
|
|
VARIANT varType,
|
|
varSrc,
|
|
varDest;
|
|
VariantInit(&varSrc);
|
|
VariantInit(&varDest);
|
|
VariantInit(&varType);
|
|
|
|
|
|
// Obtain the list of properties and their associated values
|
|
BSTRMAP theMap = rParsedInfo.GetCmdSwitchesObject().GetParameterMap();
|
|
BSTRMAP::iterator theIterator = NULL;
|
|
theIterator = theMap.begin();
|
|
try
|
|
{
|
|
_bstr_t bstrResult;
|
|
// Get the class definition
|
|
hr = m_pITargetNS->GetObject(bstrClass,
|
|
0, NULL, &pIWbemObj, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::GetObject(L\"%s\", 0, NULL, -)",
|
|
(LPWSTR) bstrClass);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Create a new instance.
|
|
hr = pIWbemObj->SpawnInstance(0, &pINewInst);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::SpawnInstance(0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
|
|
PROPDETMAP pdmPropDetMap = rParsedInfo.GetCmdSwitchesObject().
|
|
GetPropDetMap();
|
|
PROPDETMAP::iterator itrPropDetMap;
|
|
|
|
// Update all properties
|
|
while (theIterator != theMap.end())
|
|
{
|
|
// Get the propert name and the corresponding value
|
|
_bstr_t bstrProp = _bstr_t((_TCHAR*)(*theIterator).first);
|
|
|
|
// Get the derivation of property name
|
|
if ( Find(pdmPropDetMap, bstrProp, itrPropDetMap) == TRUE &&
|
|
!((*itrPropDetMap).second.Derivation) == FALSE )
|
|
bstrProp = (*itrPropDetMap).second.Derivation;
|
|
|
|
// Obtain the property qualifier set for the property
|
|
hr = pINewInst->GetPropertyQualifierSet(bstrProp, &pIQualSet);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::GetPropertyQualifierSet"
|
|
L"(L\"%s\", -)", (LPWSTR) bstrProp);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
VariantInit(&varType);
|
|
if (pIQualSet)
|
|
{
|
|
// Obtain the CIM type of the property
|
|
hr = pIQualSet->Get(_bstr_t(L"CIMTYPE"), 0L, &varType, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemQualifierSet::Get(L\"CIMTYPE\", "
|
|
L"0, -, NULL)");
|
|
GetBstrTFromVariant(varType, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if(!IsArrayType(pINewInst, bstrProp))
|
|
{
|
|
varSrc.vt = VT_BSTR;
|
|
varSrc.bstrVal = SysAllocString((_TCHAR*)(*theIterator).second);
|
|
|
|
if (varSrc.bstrVal == NULL)
|
|
{
|
|
//Reset the variant, it will be cleaned up by the catch...
|
|
VariantInit(&varSrc);
|
|
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
hr = ConvertCIMTYPEToVarType(varDest, varSrc,
|
|
(_TCHAR*)varType.bstrVal);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"VariantChangeType(-, -, 0, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
BSTRVECTOR vArrayValues;
|
|
_TCHAR* pszValue = (*theIterator).second;
|
|
|
|
RemoveParanthesis(pszValue);
|
|
GetArrayFromToken(pszValue,
|
|
vArrayValues);
|
|
hr = CheckForArray( pINewInst, bstrProp,
|
|
varDest, vArrayValues, rParsedInfo);
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
}
|
|
|
|
// Update the property value
|
|
hr = pINewInst->Put(bstrProp, 0, &varDest, 0);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Put(L\"%s\", 0, -, 0)",
|
|
(LPWSTR) bstrProp);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
theIterator++;
|
|
}
|
|
|
|
// Update the instance with the changes
|
|
hr = m_pITargetNS->PutInstance(pINewInst, WBEM_FLAG_CREATE_ONLY,
|
|
NULL, NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::PutInstance(-, "
|
|
L"WBEM_FLAG_CREATE_ONLY, NULL, NULL)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
SAFEIRELEASE(pINewInst);
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(IDS_I_CREATE_SUCCESS);
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
SAFEIRELEASE(pINewInst);
|
|
|
|
// Store the COM error and set the return value to FALSE
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bSuccess = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
VARIANTCLEAR(varSrc);
|
|
VARIANTCLEAR(varDest);
|
|
VARIANTCLEAR(varType);
|
|
SAFEIRELEASE(pIQualSet);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
SAFEIRELEASE(pINewInst);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ValidateInParams
|
|
Synopsis :Validates the property value specified against the
|
|
property qualifiers for that property (i.e checking
|
|
against the contents of following qualifiers if
|
|
available:
|
|
1. MaxLen,
|
|
2. ValueMap
|
|
3. Values
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - CParsedInfo object.
|
|
bstrClass - Bstr type, class name.
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ValidateInParams(rParsedInfo, bstrClass)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ValidateInParams(CParsedInfo& rParsedInfo, _bstr_t bstrClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject *pIObject = NULL;
|
|
IWbemQualifierSet *pIQualSet = NULL;
|
|
BOOL bRet = TRUE;
|
|
CHString chsMsg;
|
|
VARIANT varMap,
|
|
varValue,
|
|
varLen;
|
|
VariantInit(&varMap);
|
|
VariantInit(&varValue);
|
|
VariantInit(&varLen);
|
|
BSTRMAP theMap = rParsedInfo.GetCmdSwitchesObject().GetParameterMap();
|
|
BSTRMAP::iterator theIterator = theMap.begin();
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
|
|
try
|
|
{
|
|
// Obtain the class schema
|
|
hr = m_pITargetNS->GetObject(bstrClass,
|
|
WBEM_FLAG_RETURN_WBEM_COMPLETE |
|
|
WBEM_FLAG_USE_AMENDED_QUALIFIERS,
|
|
NULL,
|
|
&pIObject,
|
|
NULL);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::GetObject(L\"%s\", "
|
|
L"WBEM_FLAG_RETURN_WBEM_COMPLETE|WBEM_FLAG_USE_AMENDED_QUALIFIERS,"
|
|
L" 0, NULL, -)", (LPWSTR) bstrClass);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg, dwThreadId,
|
|
rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Loop through the list of available properties.
|
|
while (theIterator != theMap.end())
|
|
{
|
|
// Get the property name and the corresponding value.
|
|
_bstr_t bstrProp = _bstr_t((_TCHAR*)(*theIterator).first);
|
|
WCHAR* pszValue = (LPWSTR)(*theIterator).second;
|
|
|
|
// Check the value against the qualifier information
|
|
bRet = CheckQualifierInfo(rParsedInfo, pIObject,
|
|
bstrProp, pszValue);
|
|
if (bRet)
|
|
{
|
|
// A mapping between 'Values' and 'ValueMaps' is possible,
|
|
// hence update the parameter value to reflect the change.
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
UpdateParameterValue(bstrProp, _bstr_t(pszValue));
|
|
}
|
|
else
|
|
break;
|
|
theIterator++;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varMap);
|
|
VARIANTCLEAR(varValue);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varMap);
|
|
VARIANTCLEAR(varValue);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :IsInteractive()
|
|
Synopsis :Checks whether user has to be prompted for response
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - reference to CParsedInfo class object.
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :IsInteractive(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::IsInteractive(CParsedInfo& rParsedInfo)
|
|
{
|
|
BOOL bInteractive = FALSE;
|
|
|
|
// Get the status of /INTERACTIVE global switch.
|
|
bInteractive = rParsedInfo.GetGlblSwitchesObject().
|
|
GetInteractiveStatus();
|
|
|
|
// If /NOINTERACTIVE specified at the verb level.
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetInteractiveMode() == NOINTERACTIVE)
|
|
{
|
|
bInteractive = FALSE;
|
|
}
|
|
else if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetInteractiveMode() == INTERACTIVE)
|
|
{
|
|
bInteractive = TRUE;
|
|
}
|
|
return bInteractive;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CheckQualifierInfo
|
|
Synopsis :Validates the parameter value specified against the
|
|
parameter qualifiers for that parameter(i.e checking
|
|
against the contents of following qualifiers if
|
|
available:
|
|
1. MaxLen,
|
|
2. ValueMap
|
|
3. Values
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - CParsedInfo object.
|
|
pIMethodSign - input signature of the method.
|
|
bstrParam - parameter name
|
|
pszValue - new value.
|
|
Output Parameter(s):
|
|
pszValue - new value.
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :CheckQualifierInfo(rParsedInfo, pIMethodSign,
|
|
bstrParam, pszValue)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::CheckQualifierInfo(CParsedInfo& rParsedInfo,
|
|
IWbemClassObject *pIObject,
|
|
_bstr_t bstrParam,
|
|
WCHAR*& pszValue)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet *pIQualSet = NULL;
|
|
BOOL bRet = TRUE;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
VARIANT varMap,
|
|
varValue,
|
|
varLen;
|
|
VariantInit(&varMap);
|
|
VariantInit(&varValue);
|
|
VariantInit(&varLen);
|
|
|
|
try
|
|
{
|
|
BOOL bFound = FALSE;
|
|
|
|
// Obtain the property qualifier set for the parameter.
|
|
hr= pIObject->GetPropertyQualifierSet(bstrParam, &pIQualSet);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::GetPropertyQualifierSet"
|
|
L"(L\"%s\", -)", (LPWSTR) bstrParam);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Check whether the 'Maxlen' qualifier is applicable.
|
|
pIQualSet->Get(_bstr_t(L"MaxLen"), 0, &varLen, NULL);
|
|
if (varLen.vt != VT_EMPTY && varLen.vt != VT_NULL)
|
|
{
|
|
// If the property value length exceeds maximum length
|
|
// allowed set the return value to FALSE
|
|
if (lstrlen(pszValue) > varLen.lVal)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetErrataCode(IDS_E_VALUE_EXCEEDS_MAXLEN);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
VARIANTCLEAR(varLen);
|
|
|
|
if (bRet)
|
|
{
|
|
bool bValue = false;
|
|
WMICLIINT iValue = GetNumber ( pszValue );
|
|
if ( iValue && iValue != -1 )
|
|
{
|
|
bValue = true;
|
|
}
|
|
|
|
// Obtain the 'ValueMap' qualifier contents if present
|
|
pIQualSet->Get(_bstr_t(L"ValueMap"), 0, &varMap, NULL);
|
|
if (varMap.vt != VT_EMPTY && varMap.vt != VT_NULL)
|
|
{
|
|
// Get lower and upper bounds of Descriptions array
|
|
LONG lUpper = 0, lLower = 0;
|
|
hr = SafeArrayGetLBound(varMap.parray, varMap.parray->cDims,
|
|
&lLower);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetLBound(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
hr = SafeArrayGetUBound(varMap.parray, varMap.parray->cDims,
|
|
&lUpper);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetUBound(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
for (LONG lIndex = lLower; lIndex <= lUpper; lIndex++)
|
|
{
|
|
void* pv = NULL;
|
|
hr = SafeArrayGetElement(varMap.parray, &lIndex, &pv);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetElement(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if ( bValue )
|
|
{
|
|
WMICLIINT ipv = GetNumber ( ( WCHAR* ) pv );
|
|
if ( ipv != -1 )
|
|
{
|
|
if ( iValue == ipv )
|
|
{
|
|
_itow ( ipv, pszValue, 10);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check whether the property value is available with the
|
|
// value map entries.
|
|
if (CompareTokens(pszValue, (_TCHAR*)pv))
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
bRet = bFound;
|
|
}
|
|
|
|
// If not found in the ValueMap
|
|
if (!bRet || !bFound)
|
|
{
|
|
// Obtain the 'Values' qualifier contents if present
|
|
pIQualSet->Get(_bstr_t(L"Values"), 0, &varValue, NULL);
|
|
if (varValue.vt != VT_EMPTY && varValue.vt != VT_NULL)
|
|
{
|
|
// Get lower and upper bounds of Descriptions array
|
|
LONG lUpper = 0, lLower = 0;
|
|
hr = SafeArrayGetLBound(varValue.parray,
|
|
varValue.parray->cDims, &lLower);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetLBound(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
hr = SafeArrayGetUBound(varValue.parray,
|
|
varValue.parray->cDims, &lUpper);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetUBound(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
for (LONG lIndex = lLower; lIndex <= lUpper; lIndex++)
|
|
{
|
|
void *pv = NULL;
|
|
hr = SafeArrayGetElement(varValue.parray,
|
|
&lIndex, &pv);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(L"SafeArrayGetElement(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId, rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Check for any matching entry.
|
|
if (CompareTokens(pszValue, (_TCHAR*)pv))
|
|
{
|
|
void* pmv = NULL;
|
|
if (varMap.vt != VT_EMPTY && varMap.vt != VT_NULL)
|
|
{
|
|
// obtain the correponding ValueMap entry.
|
|
hr = SafeArrayGetElement(varMap.parray,
|
|
&lIndex, &pmv);
|
|
if ( m_eloErrLogOpt )
|
|
{
|
|
chsMsg.Format(
|
|
L"SafeArrayGetElement(-, -, -)");
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg, dwThreadId,
|
|
rParsedInfo, FALSE);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if ( bValue )
|
|
{
|
|
WMICLIINT ipmv = GetNumber ( (WCHAR*)pmv );
|
|
_itow ( ipmv, pszValue, 10);
|
|
}
|
|
else
|
|
{
|
|
// Modify the current property value
|
|
// (i.e 'Values' to 'ValueMap' content)
|
|
lstrcpy(pszValue, ((_TCHAR*)pmv));
|
|
}
|
|
}
|
|
// Only 'Values' qualifier available
|
|
else
|
|
{
|
|
_TCHAR szTemp[BUFFER255] = NULL_STRING;
|
|
_itot(lIndex, szTemp, 10);
|
|
// Modify the current property value
|
|
// (i.e 'Values' entry to index)
|
|
lstrcpy(pszValue, szTemp);
|
|
}
|
|
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
// If not match found in 'ValueMap' and 'Values' qualifier
|
|
// list
|
|
if (!bFound)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetErrataCode(IDS_E_VALUE_NOTFOUND);
|
|
}
|
|
bRet = bFound;
|
|
}
|
|
}
|
|
VARIANTCLEAR(varValue);
|
|
VARIANTCLEAR(varMap);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varMap);
|
|
VARIANTCLEAR(varValue);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
bRet = FALSE;
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIQualSet);
|
|
VARIANTCLEAR(varMap);
|
|
VARIANTCLEAR(varValue);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :ValidateAlaisInParams
|
|
Synopsis :Validates the property value specified against the
|
|
property qualifiers available for that property
|
|
from the <alias> definition (i.e checking
|
|
against the contents of following qualifiers if
|
|
available:
|
|
1. MaxLen,
|
|
2. ValueMap
|
|
3. Values
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - reference to CParsedInfo object.
|
|
Output Parameter(s):None
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ValidateAlaisInParams(rParsedInfo)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ValidateAlaisInParams(CParsedInfo& rParsedInfo)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
//_TCHAR szMsg[BUFFER1024] = NULL_STRING;
|
|
BSTRMAP theParamMap;
|
|
BSTRMAP::iterator theIterator = NULL;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
PROPDETMAP pdmPropDetMap;
|
|
|
|
// Get the property details map.
|
|
pdmPropDetMap = rParsedInfo.GetCmdSwitchesObject().GetPropDetMap();
|
|
|
|
// If the property details are available
|
|
if (!pdmPropDetMap.empty())
|
|
{
|
|
// Get the parameters map
|
|
theParamMap = rParsedInfo.GetCmdSwitchesObject().GetParameterMap();
|
|
theIterator = theParamMap.begin();
|
|
|
|
|
|
try
|
|
{
|
|
// Loop through the list of available parameters
|
|
while (theIterator != theParamMap.end())
|
|
{
|
|
// Get the property name and the corresponding value.
|
|
_bstr_t bstrProp = _bstr_t((_TCHAR*)(*theIterator).first);
|
|
WCHAR* pszValue = (LPWSTR)(*theIterator).second;
|
|
|
|
// Check the value against the qualifier information
|
|
bRet = CheckAliasQualifierInfo(rParsedInfo, bstrProp,
|
|
pszValue, pdmPropDetMap);
|
|
if (bRet)
|
|
{
|
|
// A mapping between 'Values' and 'ValueMaps' is possible,
|
|
// hence update the parameter value to reflect the change.
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
UpdateParameterValue(bstrProp, _bstr_t(pszValue));
|
|
}
|
|
else
|
|
break;
|
|
theIterator++;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
bRet = FALSE;
|
|
}
|
|
catch(...)
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :CheckAliasQualifierInfo
|
|
Synopsis :Validates the parameter value specified against the
|
|
parameter qualifiers for that parameter from the
|
|
<alias> definition (i.e checking
|
|
against the contents of following qualifiers if
|
|
available:
|
|
1. MaxLen,
|
|
2. ValueMap
|
|
3. Values
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedinfo - CParsedInfo object.
|
|
bstrParam - parameter name
|
|
pszValue - new value.
|
|
pdmPropDetMap - property details map
|
|
Output Parameter(s):
|
|
pszValue - new value
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :CheckAliasQualifierInfo(rParsedInfo, bstrParam,
|
|
pszValue, pdmPropDetMap)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::CheckAliasQualifierInfo(CParsedInfo& rParsedInfo,
|
|
_bstr_t bstrParam,
|
|
WCHAR*& pszValue,
|
|
PROPDETMAP pdmPropDetMap)
|
|
{
|
|
BOOL bRet = TRUE,
|
|
bFound = FALSE;
|
|
PROPDETMAP::iterator propItrtrStart = NULL;
|
|
PROPDETMAP::iterator propItrtrEnd = NULL;
|
|
|
|
QUALDETMAP qualMap;
|
|
QUALDETMAP::iterator qualDetMap = NULL;
|
|
|
|
BSTRVECTOR::iterator qualEntriesStart = NULL;
|
|
BSTRVECTOR::iterator qualEntriesEnd = NULL;
|
|
BSTRVECTOR qualVMEntries;
|
|
BSTRVECTOR qualVEntries;
|
|
BSTRVECTOR qualMEntries;
|
|
|
|
propItrtrStart = pdmPropDetMap.begin();
|
|
propItrtrEnd = pdmPropDetMap.end();
|
|
|
|
try
|
|
{
|
|
while (propItrtrStart != propItrtrEnd)
|
|
{
|
|
// If the property is found.
|
|
if (CompareTokens( (LPWSTR)bstrParam,
|
|
((LPWSTR)(*propItrtrStart).first) ))
|
|
{
|
|
// Get the qualifier map
|
|
qualMap = ((*propItrtrStart).second).QualDetMap;
|
|
|
|
// Check if the qualifier information is available.
|
|
if (!qualMap.empty())
|
|
{
|
|
// Check for the 'MaxLen' qualifier
|
|
qualDetMap = qualMap.find(_bstr_t(L"MaxLen"));
|
|
|
|
// If MaxLen qualifier information is available.
|
|
if (qualDetMap != qualMap.end())
|
|
{
|
|
qualMEntries = (*qualDetMap).second;
|
|
|
|
BSTRVECTOR::reference qualRef = qualMEntries.at(0);
|
|
if (lstrlen(pszValue) > _wtoi((LPWSTR)qualRef))
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetErrataCode(IDS_E_VALUE_EXCEEDS_MAXLEN);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
WMICLIINT iValue = 0;
|
|
|
|
bool bValue = false;
|
|
bool bNumber = true;
|
|
|
|
VARTYPE vt = ReturnVarType ( (_TCHAR*) ((*propItrtrStart).second).Type );
|
|
if (
|
|
vt == VT_I1 ||
|
|
vt == VT_I2 ||
|
|
vt == VT_I4 ||
|
|
vt == VT_R4 ||
|
|
vt == VT_R8 ||
|
|
vt == VT_UI1 ||
|
|
vt == VT_UI2 ||
|
|
vt == VT_UI4 ||
|
|
vt == VT_INT ||
|
|
vt == VT_UINT
|
|
)
|
|
{
|
|
iValue = GetNumber ( pszValue );
|
|
if ( iValue == -1 )
|
|
{
|
|
bNumber = false;
|
|
}
|
|
bValue = true;
|
|
}
|
|
|
|
// Check for the 'ValueMap' qualfiers
|
|
qualDetMap = qualMap.find(_bstr_t(L"ValueMap"));
|
|
|
|
// If 'ValueMap' qualifier information is available.
|
|
if (qualDetMap != qualMap.end())
|
|
{
|
|
// Get the qualifier entries vector
|
|
qualVMEntries = (*qualDetMap ).second;
|
|
qualEntriesStart = qualVMEntries.begin();
|
|
qualEntriesEnd = qualVMEntries.end();
|
|
|
|
if ( bNumber )
|
|
{
|
|
// Loop thru the available 'ValueMap' entries.
|
|
while (qualEntriesStart != qualEntriesEnd)
|
|
{
|
|
if ( bValue )
|
|
{
|
|
WMICLIINT iqualEntriesStart = GetNumber ( ( WCHAR* ) (*qualEntriesStart) );
|
|
if ( iqualEntriesStart != -1 )
|
|
{
|
|
if ( iValue == iqualEntriesStart )
|
|
{
|
|
_itow ( iqualEntriesStart, pszValue, 10);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check whether the property value is
|
|
// available with the value map entries.
|
|
if (CompareTokens(pszValue,
|
|
(_TCHAR*)(*qualEntriesStart)))
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Move to next entry
|
|
qualEntriesStart++;
|
|
}
|
|
bRet = bFound;
|
|
}
|
|
}
|
|
|
|
// If not found in the 'ValueMap' entries
|
|
if (!bRet || !bFound)
|
|
{
|
|
// Check for the 'Values' qualfiers
|
|
qualDetMap = qualMap.find(_bstr_t(L"Values"));
|
|
|
|
// If 'Values' qualifier information is available.
|
|
if (qualDetMap != qualMap.end())
|
|
{
|
|
// Get the qualifier entries vector
|
|
qualVEntries = (*qualDetMap).second;
|
|
qualEntriesStart = qualVEntries.begin();
|
|
qualEntriesEnd = qualVEntries.end();
|
|
|
|
WMICLIINT nLoop = 0;
|
|
// Loop thru the available 'Values' entries.
|
|
while (qualEntriesStart != qualEntriesEnd)
|
|
{
|
|
// Check whether the property value is
|
|
// available with the value map entries.
|
|
if (CompareTokens(pszValue,
|
|
(_TCHAR*)(*qualEntriesStart)))
|
|
{
|
|
// If 'ValueMap' entries are available.
|
|
if (!qualVMEntries.empty())
|
|
{
|
|
//Get corresponding entry from
|
|
//'ValueMap'
|
|
BSTRVECTOR::reference qualRef =
|
|
qualVMEntries.at(nLoop);
|
|
|
|
if ( bValue )
|
|
{
|
|
WMICLIINT iqualRef = GetNumber ( (WCHAR*)(qualRef) );
|
|
_itow ( iqualRef, pszValue, 10);
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(pszValue, (_TCHAR*)(qualRef));
|
|
}
|
|
}
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
// Move to next entry
|
|
qualEntriesStart++;
|
|
nLoop++;
|
|
}
|
|
// If match not found in 'ValueMap' and
|
|
// 'Values' qualifier entries list
|
|
if (!bFound)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetErrataCode(IDS_E_VALUE_NOTFOUND);
|
|
}
|
|
bRet = bFound;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
propItrtrStart++;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :SubstHashAndExecCmdUtility
|
|
Synopsis :Substitute hashes and execute command line utility.
|
|
If pIWbemObj != NULL then utility should be passed
|
|
with appropriate instance values.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo object.
|
|
pIWbemObj - pointer to object of type IWbemClassObject.
|
|
Output Parameter(s):None
|
|
Return Type :void
|
|
Global Variables :None
|
|
Calling Syntax :SubstHashAndExecCmdUtility(rParsedInfo, pIWbemObj)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
void CExecEngine::SubstHashAndExecCmdUtility(CParsedInfo& rParsedInfo,
|
|
IWbemClassObject *pIWbemObj)
|
|
{
|
|
size_t nHashPos = 0;
|
|
size_t nAfterVarSpacePos = 0;
|
|
LONG lHashLen = lstrlen(CLI_TOKEN_HASH);
|
|
LONG lSpaceLen = lstrlen(CLI_TOKEN_SPACE);
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
HRESULT hr = S_OK;
|
|
BOOL bSubstituted = FALSE;
|
|
VARIANT vtInstanceValue;
|
|
VARIANT vtPath;
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrResult;
|
|
_bstr_t bstrVerbDerivation =
|
|
_bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetVerbDerivation());
|
|
if ( bstrVerbDerivation == _bstr_t(CLI_TOKEN_NULL) )
|
|
bstrVerbDerivation = CLI_TOKEN_SPACE;
|
|
|
|
STRING strCmdLine(bstrVerbDerivation);
|
|
|
|
BOOL bNamedParamList = rParsedInfo.GetCmdSwitchesObject().
|
|
GetNamedParamListFlag();
|
|
|
|
// If NamedParamList is specified param=values are in Parameter map
|
|
// Order them as appear in alias verb parameter definition and put
|
|
// them in to cvInParams for further processing.
|
|
CHARVECTOR cvInParams;
|
|
if ( bNamedParamList == TRUE )
|
|
ObtainInParamsFromParameterMap(rParsedInfo, cvInParams);
|
|
else // else params are available in property list.
|
|
cvInParams = rParsedInfo.GetCmdSwitchesObject().GetPropertyList();
|
|
|
|
CHARVECTOR::iterator theActParamIterator = NULL;
|
|
try
|
|
{
|
|
// Loop initialization.
|
|
theActParamIterator = cvInParams.begin();
|
|
|
|
while( TRUE )
|
|
{
|
|
// Loop condition.
|
|
if (theActParamIterator == cvInParams.end())
|
|
break;
|
|
|
|
bSubstituted = FALSE;
|
|
|
|
while ( bSubstituted == FALSE )
|
|
{
|
|
nHashPos = strCmdLine.find(CLI_TOKEN_HASH,
|
|
nHashPos, lHashLen);
|
|
if ( nHashPos != STRING::npos )
|
|
{
|
|
// No instance specified.
|
|
if ( pIWbemObj == NULL )
|
|
{
|
|
strCmdLine.replace(nHashPos, lHashLen,
|
|
*theActParamIterator);
|
|
nHashPos = nHashPos + lstrlen(*theActParamIterator);
|
|
bSubstituted = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ( strCmdLine.compare(nHashPos + 1,
|
|
lSpaceLen,
|
|
CLI_TOKEN_SPACE) == 0 ||
|
|
strCmdLine.compare(nHashPos + 1,
|
|
lstrlen(CLI_TOKEN_SINGLE_QUOTE),
|
|
CLI_TOKEN_SINGLE_QUOTE) == 0 )
|
|
{
|
|
strCmdLine.replace(nHashPos, lHashLen,
|
|
*theActParamIterator);
|
|
nHashPos = nHashPos +
|
|
lstrlen(*theActParamIterator);
|
|
bSubstituted = TRUE;
|
|
}
|
|
else
|
|
{
|
|
nAfterVarSpacePos =
|
|
strCmdLine.find(
|
|
CLI_TOKEN_SPACE, nHashPos + 1,
|
|
lSpaceLen);
|
|
if ( nAfterVarSpacePos == STRING::npos )
|
|
{
|
|
strCmdLine.replace(nHashPos,
|
|
lHashLen, *theActParamIterator);
|
|
nHashPos = nHashPos +
|
|
lstrlen(*theActParamIterator);
|
|
bSubstituted = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strCmdLine.append(_T(" "));
|
|
strCmdLine.append(*theActParamIterator);
|
|
bSubstituted = TRUE;
|
|
}
|
|
|
|
if ( bSubstituted == FALSE )
|
|
nHashPos = nHashPos + lHashLen;
|
|
}
|
|
|
|
// Loop expression.
|
|
theActParamIterator++;
|
|
}
|
|
|
|
if ( pIWbemObj != NULL )
|
|
{
|
|
// Replacing #Variable parameters
|
|
nHashPos = 0;
|
|
|
|
while ( TRUE )
|
|
{
|
|
nHashPos = strCmdLine.find(CLI_TOKEN_HASH, nHashPos,
|
|
lHashLen);
|
|
if ( nHashPos == STRING::npos )
|
|
break;
|
|
|
|
nAfterVarSpacePos =
|
|
strCmdLine.find(CLI_TOKEN_SPACE,
|
|
nHashPos + 1, lSpaceLen);
|
|
if ( nAfterVarSpacePos == STRING::npos )
|
|
break;
|
|
|
|
_bstr_t bstrPropName(strCmdLine.substr(nHashPos + 1,
|
|
nAfterVarSpacePos - (nHashPos + 1)).data());
|
|
VariantInit(&vtInstanceValue);
|
|
hr = pIWbemObj->Get(bstrPropName, 0,
|
|
&vtInstanceValue, 0, 0);
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Get(%s, 0, "
|
|
L"-, 0, 0)", (LPWSTR)bstrPropName);
|
|
GetBstrTFromVariant(vtInstanceValue, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__,
|
|
(LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
_bstr_t bstrInstanceValue;
|
|
GetBstrTFromVariant(vtInstanceValue, bstrInstanceValue);
|
|
|
|
strCmdLine.replace(nHashPos, nAfterVarSpacePos - nHashPos ,
|
|
bstrInstanceValue);
|
|
nHashPos = nHashPos + lstrlen(bstrInstanceValue);
|
|
|
|
VARIANTCLEAR(vtInstanceValue);
|
|
}
|
|
|
|
VariantInit(&vtPath);
|
|
hr = pIWbemObj->Get(L"__PATH", 0, &vtPath, 0, 0);
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Get(L\"__PATH\", 0, "
|
|
L"-, 0, 0)");
|
|
GetBstrTFromVariant(vtPath, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
|
|
INTEROPTION interInvoke = YES;
|
|
_TCHAR szMsg[BUFFER1024] = NULL_STRING;
|
|
|
|
// Get the user response if interactive mode is set
|
|
if (IsInteractive(rParsedInfo) == TRUE)
|
|
{
|
|
_bstr_t bstrMsg;
|
|
if ( pIWbemObj != NULL )
|
|
{
|
|
WMIFormatMessage(IDS_I_METH_INVOKE_PROMPT1, 2, bstrMsg,
|
|
(LPWSTR)vtPath.bstrVal,
|
|
(LPWSTR)strCmdLine.data());
|
|
}
|
|
else
|
|
{
|
|
WMIFormatMessage(IDS_I_METH_INVOKE_PROMPT2, 1, bstrMsg,
|
|
(LPWSTR)strCmdLine.data());
|
|
}
|
|
interInvoke = GetUserResponse((LPWSTR)bstrMsg);
|
|
}
|
|
|
|
if ( interInvoke == YES )
|
|
{
|
|
DisplayMessage(L"\n", CP_OEMCP, FALSE, TRUE);
|
|
BOOL bResult = _tsystem(strCmdLine.data());
|
|
DisplayMessage(L"\n", CP_OEMCP, FALSE, TRUE);
|
|
}
|
|
VARIANTCLEAR(vtPath);
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
VARIANTCLEAR(vtInstanceValue);
|
|
VARIANTCLEAR(vtPath);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :FormQueryAndExecuteMethodOrUtility
|
|
Synopsis :Forms query and executes method or command line
|
|
utility.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo object.
|
|
pIInParam - pointer to object of type IWbemClassObject.
|
|
Output Parameter(s):None
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :FormQueryAndExecuteMethodOrUtility(rParsedInfo, pIInParam)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::FormQueryAndExecuteMethodOrUtility(
|
|
CParsedInfo& rParsedInfo,
|
|
IWbemClassObject *pIInParam)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IEnumWbemClassObject *pIEnumObj = NULL;
|
|
IWbemClassObject *pIWbemObj = NULL;
|
|
CHString chsMsg;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
|
|
try
|
|
{
|
|
_bstr_t bstrResult("");
|
|
_bstr_t bstrPath("");
|
|
BOOL bWhereExpr = FALSE;
|
|
|
|
// If PATH specified
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetPathExpression() != NULL)
|
|
{
|
|
if(rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bWhereExpr = TRUE;
|
|
}
|
|
else
|
|
bstrPath = _bstr_t(rParsedInfo.GetCmdSwitchesObject()
|
|
.GetPathExpression());
|
|
}
|
|
else
|
|
{
|
|
// If CLASS specfied
|
|
if (rParsedInfo.GetCmdSwitchesObject().GetClassPath() != NULL)
|
|
{
|
|
bstrPath = _bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassPath());
|
|
}
|
|
else if(rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bWhereExpr = TRUE;
|
|
}
|
|
else
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
GetClassOfAliasTarget(bstrPath);
|
|
}
|
|
|
|
// If bstrPath is not empty
|
|
if ( !bWhereExpr )
|
|
{
|
|
if ( rParsedInfo.GetCmdSwitchesObject().GetVerbType() == CMDLINE )
|
|
{
|
|
SubstHashAndExecCmdUtility(rParsedInfo);
|
|
}
|
|
else
|
|
{
|
|
hr = ExecuteMethodAndDisplayResults(bstrPath, rParsedInfo,
|
|
pIInParam);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
else
|
|
{
|
|
ULONG ulReturned = 0;
|
|
_bstr_t bstrQuery;
|
|
|
|
// Frame the WMI query to be executed.
|
|
if (rParsedInfo.GetCmdSwitchesObject().
|
|
GetPathExpression() != NULL)
|
|
{
|
|
bstrPath = _bstr_t(rParsedInfo.
|
|
GetCmdSwitchesObject().GetClassPath());
|
|
}
|
|
else
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject()
|
|
.GetClassOfAliasTarget(bstrPath);
|
|
}
|
|
|
|
bstrQuery = _bstr_t("SELECT * FROM ") + bstrPath;
|
|
if(rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression() != NULL)
|
|
{
|
|
bstrQuery += _bstr_t(" WHERE ")
|
|
+ _bstr_t(rParsedInfo.GetCmdSwitchesObject().
|
|
GetWhereExpression());
|
|
}
|
|
|
|
hr = m_pITargetNS->ExecQuery(_bstr_t(L"WQL"), bstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY |
|
|
WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pIEnumObj);
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemServices::ExecQuery(L\"WQL\","
|
|
L" L\"%s\", 0, NULL, -)", (LPWSTR)bstrQuery);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Set the interface security
|
|
hr = SetSecurity(pIEnumObj,
|
|
rParsedInfo.GetAuthorityPrinciple(),
|
|
rParsedInfo.GetNode(),
|
|
rParsedInfo.GetUser(),
|
|
rParsedInfo.GetPassword(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
_TCHAR* pszAuthority = rParsedInfo.GetAuthorityPrinciple();
|
|
|
|
if( pszAuthority != NULL &&
|
|
_tcslen(pszAuthority) > 9 &&
|
|
_tcsnicmp(pszAuthority, _T("KERBEROS:"), 9) == 0)
|
|
{
|
|
|
|
BSTR bstrPrincipalName = ::SysAllocString(&pszAuthority[9]);
|
|
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_GSS_KERBEROS,"
|
|
L"RPC_C_AUTHZ_NONE, %s, %d, %d, -, EOAC_NONE)",
|
|
(LPWSTR)bstrPrincipalName,
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
|
|
SAFEBSTRFREE(bstrPrincipalName);
|
|
}
|
|
else
|
|
{
|
|
chsMsg.Format(L"CoSetProxyBlanket(-, RPC_C_AUTHN_WINNT, "
|
|
L"RPC_C_AUTHZ_NONE, NULL, %d, %d, -, EOAC_NONE)",
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetAuthenticationLevel(),
|
|
rParsedInfo.GetGlblSwitchesObject().
|
|
GetImpersonationLevel());
|
|
}
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
BOOL bNoInstances = TRUE;
|
|
|
|
// Loop thru the available instances
|
|
while (((hr = pIEnumObj->Next( WBEM_INFINITE, 1,
|
|
&pIWbemObj, &ulReturned )) == S_OK)
|
|
&& (ulReturned == 1))
|
|
{
|
|
bNoInstances = FALSE;
|
|
VARIANT vtPath;
|
|
VariantInit(&vtPath);
|
|
hr = pIWbemObj->Get(L"__PATH", 0, &vtPath, 0, 0);
|
|
|
|
if (m_bTrace || m_eloErrLogOpt)
|
|
{
|
|
chsMsg.Format(L"IWbemClassObject::Get(L\"__PATH\", 0, "
|
|
L"-, 0, 0)");
|
|
GetBstrTFromVariant(vtPath, bstrResult);
|
|
WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
|
|
dwThreadId, rParsedInfo, m_bTrace, 0, bstrResult);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
if ( vtPath.vt == VT_BSTR )
|
|
{
|
|
if ( rParsedInfo.GetCmdSwitchesObject().GetVerbType()
|
|
== CMDLINE )
|
|
{
|
|
SubstHashAndExecCmdUtility(rParsedInfo, pIWbemObj);
|
|
}
|
|
else
|
|
{
|
|
hr = ExecuteMethodAndDisplayResults(vtPath.bstrVal,
|
|
rParsedInfo, pIInParam);
|
|
}
|
|
ONFAILTHROWERROR(hr);
|
|
}
|
|
VariantClear(&vtPath);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
}
|
|
// If next fails.
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
SAFEIRELEASE(pIEnumObj);
|
|
|
|
// If no instances are available
|
|
if ( bNoInstances == TRUE )
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetInformationCode(IDS_I_NO_INSTANCES);
|
|
}
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
rParsedInfo.GetCmdSwitchesObject().SetCOMError(e);
|
|
hr = e.Error();
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIEnumObj);
|
|
SAFEIRELEASE(pIWbemObj);
|
|
_com_issue_error(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Name :ExtractClassNameandWhereExpr
|
|
Synopsis :This function takes the input as a path expression and
|
|
extracts the Class and Where expression part from the
|
|
path expression.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
pszPathExpr - the path expression
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
Output Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo class object
|
|
pszWhere - the Where expression
|
|
Return Type :BOOL
|
|
Global Variables :None
|
|
Calling Syntax :ExtractClassNameandWhereExpr(pszPathExpr, rParsedInfo,
|
|
pszWhere)
|
|
Notes :None
|
|
----------------------------------------------------------------------------*/
|
|
BOOL CExecEngine::ExtractClassNameandWhereExpr(_TCHAR* pszPathExpr,
|
|
CParsedInfo& rParsedInfo,
|
|
_TCHAR* pszWhere)
|
|
{
|
|
// Frame the class name and where expression based on the object path
|
|
BOOL bRet = TRUE;
|
|
_TCHAR* pszToken = NULL;
|
|
BOOL bFirst = TRUE;
|
|
_TCHAR pszPath[MAX_BUFFER] = NULL_STRING;
|
|
|
|
if (pszPathExpr == NULL || pszWhere == NULL)
|
|
bRet = FALSE;
|
|
|
|
try
|
|
{
|
|
if ( bRet == TRUE )
|
|
{
|
|
lstrcpy(pszPath, pszPathExpr);
|
|
lstrcpy(pszWhere, CLI_TOKEN_NULL);
|
|
pszToken = _tcstok(pszPath, CLI_TOKEN_DOT);
|
|
if (pszToken != NULL)
|
|
{
|
|
if(CompareTokens(pszToken, pszPathExpr))
|
|
bRet = FALSE;
|
|
}
|
|
|
|
while (pszToken != NULL)
|
|
{
|
|
pszToken = _tcstok(NULL, CLI_TOKEN_COMMA);
|
|
if (pszToken != NULL)
|
|
{
|
|
if (!bFirst)
|
|
lstrcat(pszWhere, CLI_TOKEN_AND);
|
|
lstrcat(pszWhere, pszToken);
|
|
bFirst = FALSE;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
rParsedInfo.GetCmdSwitchesObject().
|
|
SetErrataCode(IDS_E_INVALID_PATH);
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
Name :GetUserResponseEx
|
|
Synopsis :This function accepts the user response before going
|
|
ahead, when /INTERACTIVE is specified at the verb
|
|
level
|
|
Type :Member Function
|
|
Input parameter :
|
|
pszMsg - message to be displayed.
|
|
Output parameters :None
|
|
Return Type :INTEROPTION
|
|
Global Variables :None
|
|
Calling Syntax :GetUserResponseEx(pszMsg)
|
|
Notes :None
|
|
------------------------------------------------------------------------*/
|
|
INTEROPTION CExecEngine::GetUserResponseEx(_TCHAR* pszMsg)
|
|
{
|
|
INTEROPTION bRet = YES;
|
|
_TCHAR szResp[BUFFER255] = NULL_STRING;
|
|
_TCHAR *pBuf = NULL;
|
|
|
|
if (pszMsg == NULL)
|
|
bRet = NO;
|
|
|
|
if(bRet != NO)
|
|
{
|
|
// Get the user response, till 'Y' - yes or 'N' - no
|
|
// is keyed in
|
|
while(TRUE)
|
|
{
|
|
DisplayMessage(pszMsg, CP_OEMCP, TRUE, TRUE);
|
|
pBuf = _fgetts(szResp, BUFFER255-1, stdin);
|
|
if(pBuf != NULL)
|
|
{
|
|
LONG lInStrLen = lstrlen(szResp);
|
|
if(szResp[lInStrLen - 1] == _T('\n'))
|
|
szResp[lInStrLen - 1] = _T('\0');
|
|
}
|
|
else if ( g_wmiCmd.GetBreakEvent() != TRUE )
|
|
{
|
|
lstrcpy(szResp, RESPONSE_NO);
|
|
DisplayMessage(_T("\n"), CP_OEMCP, TRUE, TRUE);
|
|
}
|
|
|
|
if ( g_wmiCmd.GetBreakEvent() == TRUE )
|
|
{
|
|
g_wmiCmd.SetBreakEvent(FALSE);
|
|
lstrcpy(szResp, RESPONSE_NO);
|
|
DisplayMessage(_T("\n"), CP_OEMCP, TRUE, TRUE);
|
|
}
|
|
if (CompareTokens(szResp, RESPONSE_YES)
|
|
|| CompareTokens(szResp, RESPONSE_NO)
|
|
|| CompareTokens(szResp, RESPONSE_HELP))
|
|
break;
|
|
}
|
|
if (CompareTokens(szResp, RESPONSE_NO))
|
|
bRet = NO;
|
|
else if (CompareTokens(szResp, RESPONSE_YES))
|
|
bRet = YES;
|
|
else if (CompareTokens(szResp, RESPONSE_HELP))
|
|
bRet = HELP;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Name :ObtainInParamsFromParameterMap
|
|
Synopsis :This function obtains param values from parameter map
|
|
in the same order as they appear in the alias verb
|
|
definition.
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
rParsedInfo - reference to CParsedInfo object
|
|
Output Parameter(s):
|
|
cvParamValues - reference to parameter values vector
|
|
Return Type :None
|
|
Global Variables :None
|
|
Calling Syntax :ObtainInParamsFromParameterMap(rParsedInfo, cvParamValues)
|
|
Notes :None
|
|
----------------------------------------------------------------------------*/
|
|
void CExecEngine::ObtainInParamsFromParameterMap(CParsedInfo& rParsedInfo,
|
|
CHARVECTOR& cvParamValues)
|
|
{
|
|
PROPDETMAP pdmVerbParamsFromAliasDef = (*(rParsedInfo.
|
|
GetCmdSwitchesObject().
|
|
GetMethDetMap().begin())).
|
|
second.Params;
|
|
PROPDETMAP::iterator itrVerbParams;
|
|
|
|
BSTRMAP bmNamedParamList = rParsedInfo.GetCmdSwitchesObject().
|
|
GetParameterMap();
|
|
BSTRMAP::iterator itrNamedParamList;
|
|
|
|
try
|
|
{
|
|
for ( itrVerbParams = pdmVerbParamsFromAliasDef.begin();
|
|
itrVerbParams != pdmVerbParamsFromAliasDef.end();
|
|
itrVerbParams++ )
|
|
{
|
|
_TCHAR* pszVerbParamName = (*itrVerbParams).first;
|
|
// To remove numbers from Names.
|
|
pszVerbParamName = pszVerbParamName + 5;
|
|
|
|
if ( Find(bmNamedParamList, pszVerbParamName, itrNamedParamList)
|
|
== TRUE)
|
|
{
|
|
cvParamValues.push_back(_bstr_t((*itrNamedParamList).second));
|
|
}
|
|
else
|
|
{
|
|
cvParamValues.push_back(
|
|
_bstr_t(((*itrVerbParams).second).Default));
|
|
}
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
_com_issue_error(e.Error());
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Name :FrameAssocHeader
|
|
Synopsis :This function frames the XML header to be used with
|
|
the ASSOCIATORS output
|
|
Type :Member Function
|
|
Input Parameter(s):
|
|
bstrPath - object/class path
|
|
bClass - TRUE - Indicates class level associators header
|
|
FALSE - Indicates instance level associators header
|
|
Output Parameter(s):
|
|
bstrFrag - fragment string
|
|
Return Type :HRESULT
|
|
Global Variables :None
|
|
Calling Syntax :FrameAssocHeader(bstrPath, bstrFrag, bClass)
|
|
Notes :None
|
|
----------------------------------------------------------------------------*/
|
|
HRESULT CExecEngine::FrameAssocHeader(_bstr_t bstrPath, _bstr_t& bstrFrag,
|
|
BOOL bClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject *pIObject = NULL;
|
|
try
|
|
{
|
|
_variant_t vClass, vSClass, vPath,
|
|
vOrigin, vType;
|
|
_bstr_t bstrProp;
|
|
CHString szBuf;
|
|
|
|
// Get the Class/instance information.
|
|
hr = m_pITargetNS->GetObject(bstrPath, WBEM_FLAG_USE_AMENDED_QUALIFIERS,
|
|
NULL, &pIObject, NULL);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Get the __CLASS property value
|
|
bstrProp = L"__CLASS";
|
|
hr = pIObject->Get(bstrProp, 0, &vClass, 0, 0);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// Get the __PATH property value
|
|
bstrProp = L"__PATH";
|
|
hr = pIObject->Get(bstrProp, 0, &vPath, 0, 0);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
// If CLASS level associators required
|
|
if (bClass)
|
|
{
|
|
// Get the __SUPERCLASS property value
|
|
bstrProp = L"__SUPERCLASS";
|
|
hr = pIObject->Get(bstrProp, 0, &vSClass, NULL, NULL);
|
|
ONFAILTHROWERROR(hr);
|
|
|
|
szBuf.Format(_T("<CLASS NAME=\"%s\" SUPERCLASS=\"%s\"><PROPERTY "
|
|
L"NAME=\"__PATH\" CLASSORIGIN=\"__SYSTEM\" TYPE=\"string\">"
|
|
L"<VALUE><![CDATA[%s]]></VALUE></PROPERTY>"),
|
|
(vClass.vt != VT_NULL && (LPWSTR)vClass.bstrVal)
|
|
? (LPWSTR)vClass.bstrVal : L"N/A",
|
|
(vSClass.vt != VT_NULL && (LPWSTR)vSClass.bstrVal)
|
|
? (LPWSTR)vSClass.bstrVal : L"N/A",
|
|
(vPath.vt != VT_NULL && (LPWSTR)vPath.bstrVal)
|
|
? (LPWSTR)vPath.bstrVal : L"N/A");
|
|
}
|
|
else
|
|
{
|
|
szBuf.Format(
|
|
_T("<INSTANCE CLASSNAME=\"%s\"><PROPERTY NAME=\"__PATH\""
|
|
L" CLASSORIGIN=\"__SYSTEM\" TYPE=\"string\"><VALUE><![CDATA[%s]]>"
|
|
L"</VALUE></PROPERTY>"),
|
|
(vClass.vt != VT_NULL && (LPWSTR)vClass.bstrVal)
|
|
? (LPWSTR)vClass.bstrVal : L"N/A",
|
|
(vPath.vt != VT_NULL && (LPWSTR)vPath.bstrVal)
|
|
? (LPWSTR)vPath.bstrVal : L"N/A");
|
|
}
|
|
SAFEIRELEASE(pIObject);
|
|
bstrFrag = _bstr_t(szBuf);
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
hr = e.Error();
|
|
}
|
|
// trap for CHeap_Exception
|
|
catch(CHeap_Exception)
|
|
{
|
|
SAFEIRELEASE(pIObject);
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|