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.
251 lines
6.3 KiB
251 lines
6.3 KiB
//******************************************************************************
|
|
//
|
|
// TEMPFILT.CPP
|
|
//
|
|
// Copyright (C) 1996-1999 Microsoft Corporation
|
|
//
|
|
//******************************************************************************
|
|
|
|
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include "ess.h"
|
|
#include "tempfilt.h"
|
|
#include <cominit.h>
|
|
#include <tkncache.h>
|
|
#include <callsec.h>
|
|
#include <wbemutil.h>
|
|
|
|
CTempFilter::CTempFilter(CEssNamespace* pNamespace)
|
|
: CGenericFilter(pNamespace), m_wszQueryLanguage(NULL),
|
|
m_wszQuery(NULL), m_pSecurity(NULL), m_bInternal( false )
|
|
{
|
|
}
|
|
|
|
HRESULT CTempFilter::Initialize( LPCWSTR wszQueryLanguage,
|
|
LPCWSTR wszQuery,
|
|
long lFlags,
|
|
PSID pOwnerSid,
|
|
bool bInternal,
|
|
IWbemContext* pContext,
|
|
IWbemObjectSink* pSink )
|
|
{
|
|
HRESULT hres;
|
|
|
|
_DBG_ASSERT( pSink != NULL );
|
|
m_pSink = pSink;
|
|
m_bInternal = bInternal;
|
|
|
|
hres = CGenericFilter::Create(wszQueryLanguage, wszQuery);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
LPWSTR wszKey = ComputeThisKey();
|
|
if(wszKey == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
CVectorDeleteMe<WCHAR> vdm(wszKey);
|
|
if(!(m_isKey = wszKey))
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
m_wszQueryLanguage = CloneWstr(wszQueryLanguage);
|
|
if(m_wszQueryLanguage == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
m_wszQuery = CloneWstr(wszQuery);
|
|
if(m_wszQuery == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
//
|
|
// if this filter is effectively permanent, that is it is being created
|
|
// on behalf of a permanent subscription ( for cross namespace purposes ),
|
|
// then we need to propagate the SID of the original subscription.
|
|
// For a normal temp filter, we save the call context and use that later
|
|
// for checking access.
|
|
//
|
|
|
|
if ( pOwnerSid == NULL )
|
|
{
|
|
//
|
|
// if this call is an on behalf of an internal call, no need to
|
|
// check security.
|
|
//
|
|
if ( !bInternal )
|
|
{
|
|
WbemCoGetCallContext( IID_IWbemCallSecurity, (void**)&m_pSecurity);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int cOwnerSid = GetLengthSid( pOwnerSid );
|
|
|
|
m_pOwnerSid = new BYTE[cOwnerSid];
|
|
|
|
if ( m_pOwnerSid == NULL )
|
|
{
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
memcpy( m_pOwnerSid, pOwnerSid, cOwnerSid );
|
|
}
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
CTempFilter::~CTempFilter()
|
|
{
|
|
delete [] m_wszQuery;
|
|
delete [] m_wszQueryLanguage;
|
|
if(m_pSecurity)
|
|
m_pSecurity->Release();
|
|
}
|
|
|
|
DELETE_ME LPWSTR CTempFilter::ComputeThisKey()
|
|
{
|
|
LPWSTR wszKey = _new WCHAR[20];
|
|
|
|
if ( wszKey )
|
|
{
|
|
StringCchPrintfW( wszKey, 20, L"$%p", this);
|
|
}
|
|
return wszKey;
|
|
}
|
|
|
|
HRESULT CTempFilter::GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
|
|
DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
|
|
DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp)
|
|
{
|
|
bExact = TRUE;
|
|
wszQueryLanguage = CloneWstr(m_wszQueryLanguage);
|
|
if(wszQueryLanguage == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
wszQuery = CloneWstr(m_wszQuery);
|
|
if(wszQuery== NULL)
|
|
{
|
|
delete [] wszQueryLanguage;
|
|
wszQueryLanguage = NULL;
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if(ppExp)
|
|
{
|
|
CTextLexSource src((LPWSTR)wszQuery);
|
|
QL1_Parser parser(&src);
|
|
int nRes = parser.Parse(ppExp);
|
|
if (nRes)
|
|
{
|
|
delete [] wszQueryLanguage;
|
|
delete [] wszQuery;
|
|
wszQueryLanguage = NULL;
|
|
wszQuery = NULL;
|
|
|
|
ERRORTRACE((LOG_ESS, "Unable to construct event filter with "
|
|
"unparsable "
|
|
"query '%S'. The filter is not active\n", wszQuery));
|
|
return WBEM_E_UNPARSABLE_QUERY;
|
|
}
|
|
}
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
HRESULT CTempFilter::SetThreadSecurity( IUnknown** ppNewContext )
|
|
{
|
|
*ppNewContext = NULL;
|
|
|
|
HRESULT hr;
|
|
|
|
if ( m_pSecurity != NULL )
|
|
{
|
|
//
|
|
// need to clone the security call context since it could be
|
|
// attached to multiple threads at the same time and the security
|
|
// class is not designed for this. Since the clone operation is
|
|
// also not MT safe, need to use cs here.
|
|
//
|
|
CInCritSec ics(&m_cs);
|
|
|
|
CWbemPtr<IWbemCallSecurity> pClone = CWbemCallSecurity::CreateInst();
|
|
|
|
if ( pClone == NULL )
|
|
{
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
//
|
|
// CreateInst() returns a object with ref count of 1. With our
|
|
// auto ref assignment operator, it is now 2. Perform a release
|
|
// to knock it back down to the desired count.
|
|
//
|
|
pClone->Release();
|
|
|
|
IUnknown* pOld;
|
|
hr = WbemCoSwitchCallContext( m_pSecurity, &pOld );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = pClone->CloneThreadContext( TRUE );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = WbemCoSwitchCallContext( pClone, &pOld );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
*ppNewContext = pClone;
|
|
pClone->AddRef();
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_S_FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CTempFilter::ObtainToken(IWbemToken** ppToken)
|
|
{
|
|
HRESULT hr;
|
|
*ppToken = NULL;
|
|
|
|
//
|
|
// Construct an IWbemToken object to return.
|
|
//
|
|
|
|
if ( m_pSecurity != NULL )
|
|
{
|
|
CWmiToken* pNewToken = new CWmiToken(m_pSecurity->GetToken());
|
|
|
|
if ( pNewToken != NULL )
|
|
{
|
|
hr = pNewToken->QueryInterface(IID_IWbemToken, (void**)ppToken);
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else if ( m_pOwnerSid != NULL )
|
|
{
|
|
hr = m_pNamespace->GetToken( m_pOwnerSid, ppToken );
|
|
}
|
|
else if ( m_bInternal )
|
|
{
|
|
hr = WBEM_S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|