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.
263 lines
6.9 KiB
263 lines
6.9 KiB
/*++
|
|
|
|
Copyright (c) 2000-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
queryhelper.cpp
|
|
|
|
Abstract:
|
|
|
|
Implementation of:
|
|
CQueryHelper
|
|
|
|
Author:
|
|
|
|
Mohit Srivastava 22-Mar-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
//
|
|
// Needed for metabase.h
|
|
//
|
|
extern "C" {
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
}
|
|
|
|
#include "iisprov.h"
|
|
#include "assocbase.h"
|
|
#include "assocsamelevel.h"
|
|
#include "assocACLACE.h"
|
|
#include "assocComponent.h"
|
|
|
|
#include "adminacl.h"
|
|
#include "queryhelper.h"
|
|
#include "instancehelper.h"
|
|
#include "utils.h"
|
|
#include "metabase.h"
|
|
#include "enum.h"
|
|
#include "SmartPointer.h"
|
|
|
|
#include <opathlex.h>
|
|
#include <objpath.h>
|
|
|
|
CQueryHelper::CQueryHelper(
|
|
BSTR i_bstrQueryLanguage,
|
|
BSTR i_bstrQuery,
|
|
CWbemServices* i_pNamespace,
|
|
IWbemObjectSink* i_pResponseHandler) :
|
|
m_pWmiClass(NULL),
|
|
m_pWmiAssoc(NULL),
|
|
m_pExp(NULL),
|
|
m_pNamespace(NULL)
|
|
{
|
|
DBG_ASSERT(i_bstrQueryLanguage != NULL);
|
|
DBG_ASSERT(i_bstrQuery != NULL);
|
|
DBG_ASSERT(i_pNamespace != NULL);
|
|
DBG_ASSERT(i_pResponseHandler != NULL);
|
|
|
|
if(_wcsicmp(i_bstrQueryLanguage, L"WQL") != 0)
|
|
{
|
|
DBGPRINTF((DBG_CONTEXT, "Invalid query language: %ws\n", i_bstrQueryLanguage));
|
|
THROW_ON_ERROR(WBEM_E_INVALID_QUERY_TYPE);
|
|
}
|
|
|
|
m_spResponseHandler = i_pResponseHandler;
|
|
m_pNamespace = i_pNamespace;
|
|
|
|
//
|
|
// Get the class name from the query
|
|
//
|
|
WCHAR wszClass[512];
|
|
wszClass[0] = L'\0';
|
|
CTextLexSource src(i_bstrQuery);
|
|
SQL1_Parser parser(&src);
|
|
|
|
int nRes = parser.GetQueryClass(wszClass, 511);
|
|
if(nRes)
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
|
|
}
|
|
|
|
//
|
|
// Determine if class, association, or neither
|
|
//
|
|
if( CUtils::GetClass(wszClass, &m_pWmiClass) )
|
|
{
|
|
}
|
|
else if( CUtils::GetAssociation(wszClass,&m_pWmiAssoc) )
|
|
{
|
|
DBG_ASSERT(m_pWmiClass == NULL);
|
|
}
|
|
else
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_INVALID_CLASS);
|
|
}
|
|
DBG_ASSERT((m_pWmiClass == NULL) || (m_pWmiAssoc == NULL));
|
|
DBG_ASSERT((m_pWmiClass != NULL) || (m_pWmiAssoc != NULL));
|
|
|
|
//
|
|
// Parse
|
|
//
|
|
m_pExp = new SQL_LEVEL_1_RPN_EXPRESSION_EXT;
|
|
|
|
nRes = parser.Parse(&(m_pExp->m_pSqlExpr));
|
|
if(nRes)
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
|
|
}
|
|
}
|
|
|
|
CQueryHelper::~CQueryHelper()
|
|
{
|
|
delete m_pExp;
|
|
m_pExp = NULL;
|
|
m_pNamespace = NULL;
|
|
m_pWmiClass = NULL;
|
|
m_pWmiAssoc = NULL;
|
|
}
|
|
|
|
void CQueryHelper::GetAssociations()
|
|
{
|
|
DBG_ASSERT(IsAssoc());
|
|
|
|
TSmartPointer<CAssocBase> spAssocBase;
|
|
|
|
if( m_pWmiAssoc == &WMI_ASSOCIATION_DATA::s_AdminACLToACE )
|
|
{
|
|
//
|
|
// Special association
|
|
//
|
|
spAssocBase = new CAssocACLACE(m_pNamespace, m_spResponseHandler);
|
|
}
|
|
else if( m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_IPSecurity ||
|
|
m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_AdminACL ||
|
|
m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_ElementSetting )
|
|
{
|
|
spAssocBase = new CAssocSameLevel(m_pNamespace, m_spResponseHandler, m_pWmiAssoc);
|
|
}
|
|
else if( m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_Component )
|
|
{
|
|
spAssocBase = new CAssocComponent(m_pNamespace, m_spResponseHandler, m_pWmiAssoc);
|
|
}
|
|
else
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_INVALID_CLASS);
|
|
}
|
|
|
|
if(spAssocBase == NULL)
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
|
|
}
|
|
|
|
spAssocBase->GetInstances(m_pExp);
|
|
}
|
|
|
|
void CQueryHelper::GetInstances()
|
|
{
|
|
DBG_ASSERT(!IsAssoc());
|
|
DBG_ASSERT(m_pWmiClass != NULL);
|
|
|
|
if(m_pExp)
|
|
{
|
|
m_pExp->SetContainsOrOrNot();
|
|
}
|
|
|
|
//
|
|
// Optimization: Just return the instance
|
|
//
|
|
const SQL_LEVEL_1_TOKEN* pToken = NULL;
|
|
if( m_pExp && // query?
|
|
!m_pExp->GetContainsOrOrNot() && // simple enough?
|
|
(pToken = m_pExp->GetFilter(m_pWmiClass->pszKeyName)) && // filtering w/PK?
|
|
pToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION && // expression
|
|
pToken->nOperator == SQL_LEVEL_1_TOKEN::OP_EQUAL ) // only can optimize ==
|
|
{
|
|
if(pToken)
|
|
{
|
|
if(m_pWmiClass != &WMI_CLASS_DATA::s_ACE)
|
|
{
|
|
ParsedObjectPath popInstance;
|
|
|
|
if(!popInstance.SetClassName(m_pWmiClass->pszClassName))
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_FAILED);
|
|
}
|
|
if(!popInstance.AddKeyRef(m_pWmiClass->pszKeyName, &pToken->vConstValue))
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_FAILED);
|
|
}
|
|
|
|
CComPtr<IWbemClassObject> spInstance;
|
|
CInstanceHelper InstanceHelper(&popInstance, m_pNamespace);
|
|
DBG_ASSERT(!IsAssoc());
|
|
try
|
|
{
|
|
InstanceHelper.GetInstance(
|
|
false,
|
|
&CMetabase(),
|
|
&spInstance);
|
|
}
|
|
catch(...)
|
|
{
|
|
}
|
|
if(spInstance != NULL)
|
|
{
|
|
HRESULT hr = m_spResponseHandler->Indicate(1, &spInstance);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(pToken->vConstValue.vt != VT_BSTR)
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
|
|
}
|
|
|
|
_bstr_t bstrMbPath = WMI_CLASS_DATA::s_ACE.pszMetabaseKey;
|
|
bstrMbPath += L"/";
|
|
bstrMbPath += pToken->vConstValue.bstrVal;
|
|
|
|
//
|
|
// CloseSD called automatically.
|
|
//
|
|
CAdminACL AdminACL;
|
|
CMetabase metabase;
|
|
HRESULT hr = AdminACL.OpenSD(bstrMbPath, metabase);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
hr = AdminACL.EnumerateACEsAndIndicate(
|
|
pToken->vConstValue.bstrVal,
|
|
*m_pNamespace,
|
|
*m_spResponseHandler);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
ParsedObjectPath ParsedObject; //deconstructer frees memory
|
|
|
|
if (!ParsedObject.SetClassName(m_pWmiClass->pszClassName))
|
|
{
|
|
THROW_ON_ERROR(WBEM_E_FAILED);
|
|
}
|
|
CEnum EnumObject;
|
|
EnumObject.Init(
|
|
m_spResponseHandler,
|
|
m_pNamespace,
|
|
&ParsedObject,
|
|
m_pWmiClass->pszMetabaseKey,
|
|
NULL,
|
|
m_pExp);
|
|
EnumObject.Recurse(
|
|
NULL,
|
|
&METABASE_KEYTYPE_DATA::s_NO_TYPE,
|
|
NULL,
|
|
m_pWmiClass->pszKeyName,
|
|
m_pWmiClass->pkt);
|
|
}
|