284 lines
6.0 KiB
C++
284 lines
6.0 KiB
C++
//***************************************************************************
|
|
|
|
//
|
|
|
|
// propprov.cpp
|
|
|
|
//
|
|
|
|
// Module: WMI Sample Property Provider
|
|
|
|
//
|
|
|
|
// Purpose: Provider class code. An object of this class is
|
|
|
|
// created by the class factory for each connection.
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//***************************************************************************
|
|
|
|
|
|
#include <objbase.h>
|
|
#include "sample.h"
|
|
|
|
|
|
/******************************************************************************
|
|
* Name: GetCurrentImpersonationLevel
|
|
* Description:
|
|
* Get COM impersonation level of caller.
|
|
*****************************************************************************/
|
|
|
|
DWORD GetCurrentImpersonationLevel ()
|
|
{
|
|
DWORD t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
|
|
HANDLE t_ThreadToken = NULL ;
|
|
|
|
BOOL t_Status = OpenThreadToken (
|
|
|
|
GetCurrentThread() ,
|
|
TOKEN_QUERY,
|
|
TRUE,
|
|
&t_ThreadToken
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
SECURITY_IMPERSONATION_LEVEL t_Level = SecurityAnonymous ;
|
|
DWORD t_Returned = 0 ;
|
|
|
|
t_Status = GetTokenInformation (
|
|
|
|
t_ThreadToken ,
|
|
TokenImpersonationLevel ,
|
|
& t_Level ,
|
|
sizeof ( SECURITY_IMPERSONATION_LEVEL ) ,
|
|
& t_Returned
|
|
) ;
|
|
|
|
CloseHandle ( t_ThreadToken ) ;
|
|
|
|
if ( t_Status == FALSE )
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
}
|
|
else
|
|
{
|
|
switch ( t_Level )
|
|
{
|
|
case SecurityAnonymous:
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
}
|
|
break ;
|
|
|
|
case SecurityIdentification:
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_IDENTIFY ;
|
|
}
|
|
break ;
|
|
|
|
case SecurityImpersonation:
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE ;
|
|
}
|
|
break ;
|
|
|
|
case SecurityDelegation:
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_DELEGATE ;
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ULONG t_LastError = GetLastError () ;
|
|
|
|
if ( t_LastError == ERROR_NO_IMPERSONATION_TOKEN || t_LastError == ERROR_NO_TOKEN )
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_DELEGATE ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_LastError == ERROR_CANT_OPEN_ANONYMOUS )
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
}
|
|
else
|
|
{
|
|
t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_ImpersonationLevel ;
|
|
}
|
|
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CPropPro::CPropPro
|
|
// CPropPro::~CPropPro
|
|
//
|
|
//***************************************************************************
|
|
|
|
CPropPro::CPropPro()
|
|
{
|
|
m_cRef=0;
|
|
InterlockedIncrement(&g_cObj);
|
|
return;
|
|
}
|
|
|
|
CPropPro::~CPropPro(void)
|
|
{
|
|
InterlockedDecrement(&g_cObj);
|
|
return;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CPropPro::QueryInterface
|
|
//
|
|
// Returns a pointer to supported interfaces.
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDMETHODIMP CPropPro::QueryInterface(REFIID riid, PPVOID ppv)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
// This provider only support IUnknown and IWbemPropertyProvider.
|
|
|
|
if (IID_IUnknown==riid || IID_IWbemPropertyProvider == riid)
|
|
*ppv=this;
|
|
|
|
if (NULL!=*ppv)
|
|
{
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CPropPro::AddRef
|
|
//
|
|
// Interface has another user, up the usage count.
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDMETHODIMP_(ULONG) CPropPro::AddRef(void)
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CPropPro::Release
|
|
//
|
|
// Interface has been released. Object will be deleted if the
|
|
// usage count is zero.
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDMETHODIMP_(ULONG) CPropPro::Release(void)
|
|
{
|
|
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
|
|
if (0L == nNewCount)
|
|
delete this;
|
|
|
|
return nNewCount;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CPropPro::PutProperty
|
|
// CPropPro::GetProperty
|
|
//
|
|
// Purpose: PutProperty writes out data and GetProperty returns data.
|
|
//
|
|
//***************************************************************************
|
|
|
|
STDMETHODIMP CPropPro::PutProperty(
|
|
long lFlags,
|
|
const BSTR Locale,
|
|
const BSTR ClassMapping,
|
|
const BSTR InstMapping,
|
|
const BSTR PropMapping,
|
|
const VARIANT *pvValue)
|
|
{
|
|
|
|
return WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
|
|
}
|
|
|
|
STDMETHODIMP CPropPro::GetProperty(
|
|
long lFlags,
|
|
const BSTR Locale,
|
|
const BSTR ClassMapping,
|
|
const BSTR InstMapping,
|
|
const BSTR PropMapping,
|
|
VARIANT *pvValue)
|
|
{
|
|
|
|
SCODE sc = WBEM_S_NO_ERROR;
|
|
|
|
//Impersonate the client
|
|
sc = CoImpersonateClient () ;
|
|
|
|
if ( FAILED ( sc ) )
|
|
{
|
|
return sc ;
|
|
}
|
|
|
|
|
|
// Check to see if call is at lower than RPC_C_IMP_LEVEL_IMPERSONATE level. If that's the case,
|
|
// the provider will not be able to impersonate the client to access the protected resources.
|
|
|
|
DWORD t_CurrentImpersonationLevel = GetCurrentImpersonationLevel () ;
|
|
if ( t_CurrentImpersonationLevel < RPC_C_IMP_LEVEL_IMPERSONATE )
|
|
{
|
|
// Revert before we perform any operations
|
|
CoRevertToSelf () ;
|
|
return WBEM_E_ACCESS_DENIED ;
|
|
}
|
|
|
|
// Depending on the InstMapping, return either a hard coded integer or
|
|
// a string. These mapping strings could be used in a more sophisticated
|
|
// manner!
|
|
|
|
if (pvValue == NULL)
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(!_wcsicmp(PropMapping, L"GiveMeANumber!"))
|
|
{
|
|
pvValue->vt = VT_I4;
|
|
pvValue->lVal = 27;
|
|
}
|
|
else
|
|
{
|
|
pvValue->vt = VT_BSTR;
|
|
pvValue->bstrVal = SysAllocString(L"Hello World");
|
|
if(pvValue->bstrVal == NULL)
|
|
sc = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
return sc;
|
|
}
|