|
|
//******************************************************************************
//
// 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; }
|