2025-04-27 07:49:33 -04:00

486 lines
13 KiB
C++

//***************************************************************************
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// SERVICE.CPP
//
// rajesh 3/25/2000 Created.
//
// This file implements a class that wraps a standard IWbemServices pointer and
// and IEnumWbemClassObject pointer so that the implementation in NT4.0 (in the
// out-of-proc XML transport in Winmgmt.exe) can be accessed in the same way
// as the implementation in Win2k (standard COM pointers in WinMgmt.exe).
// Whenever and NT4.0 call is made, the thread token is sent in the call too,
// thereby acheiving COM cloaking
//
//***************************************************************************
//***************************************************************************
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include <tchar.h>
#include <comdef.h>
#include <wbemcli.h>
#include "wmixmlst.h"
#include "service.h"
#include "maindll.h"
CWMIXMLEnumWbemClassObject :: CWMIXMLEnumWbemClassObject(IEnumWbemClassObject *pEnum)
{
m_ReferenceCount = 0 ;
m_pEnum = NULL;
m_pXMLEnum = NULL;
m_pEnum = pEnum;
if(m_pEnum)
m_pEnum->AddRef();
}
CWMIXMLEnumWbemClassObject :: CWMIXMLEnumWbemClassObject(IWmiXMLEnumWbemClassObject *pEnum)
{
m_ReferenceCount = 0 ;
m_pEnum = NULL;
m_pXMLEnum = NULL;
m_pXMLEnum = pEnum;
if(m_pXMLEnum)
m_pXMLEnum->AddRef();
}
CWMIXMLEnumWbemClassObject :: ~CWMIXMLEnumWbemClassObject()
{
if(m_pEnum)
m_pEnum->Release();
if(m_pXMLEnum)
m_pXMLEnum->Release();
}
//***************************************************************************
//
// CWMIXMLServices::QueryInterface
// CWMIXMLServices::AddRef
// CWMIXMLServices::Release
//
// Purpose: Standard COM routines needed for all interfaces
//
//***************************************************************************
STDMETHODIMP CWMIXMLEnumWbemClassObject::QueryInterface (
REFIID iid ,
LPVOID FAR *iplpv
)
{
*iplpv = NULL ;
if ( iid == IID_IUnknown )
{
*iplpv = ( IUnknown * ) this ;
}
else if ( iid == IID_IEnumWbemClassObject )
{
*iplpv = ( IEnumWbemClassObject * ) this ;
}
else
{
return E_NOINTERFACE;
}
( ( LPUNKNOWN ) *iplpv )->AddRef () ;
return S_OK;
}
STDMETHODIMP_( ULONG ) CWMIXMLEnumWbemClassObject :: AddRef ()
{
return InterlockedIncrement ( & m_ReferenceCount ) ;
}
STDMETHODIMP_(ULONG) CWMIXMLEnumWbemClassObject :: Release ()
{
LONG ref ;
if ( ( ref = InterlockedDecrement ( & m_ReferenceCount ) ) == 0 )
{
delete this ;
return 0 ;
}
else
{
return ref ;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLEnumWbemClassObject::Next(
long lTimeout,
ULONG uCount,
IWbemClassObject** apObjects,
ULONG* puReturned
)
{
if(m_pEnum)
return m_pEnum->Next(lTimeout, uCount, apObjects, puReturned);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLEnum->Next((DWORD_PTR)pNewToken, lTimeout, uCount, apObjects, puReturned);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLEnum->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
CWMIXMLServices :: CWMIXMLServices(IWbemServices *pServices)
{
m_ReferenceCount = 0 ;
m_pServices = NULL;
m_pXMLServices = NULL;
m_pServices = pServices;
if(m_pServices)
m_pServices->AddRef();
}
CWMIXMLServices :: CWMIXMLServices(IWmiXMLWbemServices *pServices)
{
m_ReferenceCount = 0 ;
m_pServices = NULL;
m_pXMLServices = NULL;
m_pXMLServices = pServices;
if(m_pXMLServices)
m_pXMLServices->AddRef();
}
CWMIXMLServices :: ~CWMIXMLServices()
{
if(m_pServices)
m_pServices->Release();
if(m_pXMLServices)
m_pXMLServices->Release();
}
//***************************************************************************
//
// CWMIXMLServices::QueryInterface
// CWMIXMLServices::AddRef
// CWMIXMLServices::Release
//
// Purpose: Standard COM routines needed for all interfaces
//
//***************************************************************************
STDMETHODIMP CWMIXMLServices::QueryInterface (
REFIID iid ,
LPVOID FAR *iplpv
)
{
*iplpv = NULL ;
if ( iid == IID_IUnknown )
{
*iplpv = ( IUnknown * ) this ;
}
else if ( iid == IID_IWbemServices )
{
*iplpv = ( IWbemServices * ) this ;
}
else
{
return E_NOINTERFACE;
}
( ( LPUNKNOWN ) *iplpv )->AddRef () ;
return S_OK;
}
STDMETHODIMP_( ULONG ) CWMIXMLServices :: AddRef ()
{
return InterlockedIncrement ( & m_ReferenceCount ) ;
}
STDMETHODIMP_(ULONG) CWMIXMLServices :: Release ()
{
LONG ref ;
if ( ( ref = InterlockedDecrement ( & m_ReferenceCount ) ) == 0 )
{
delete this ;
return 0 ;
}
else
{
return ref ;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: GetObject(
/* [in] */ const BSTR strObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppObject,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->GetObject(strObjectPath, lFlags, pCtx, ppObject, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->GetObject((DWORD_PTR)pNewToken, strObjectPath, lFlags, pCtx, ppObject, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: PutClass(
/* [in] */ IWbemClassObject __RPC_FAR *pObject,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->PutClass(pObject, lFlags, pCtx, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->PutClass((DWORD_PTR)pNewToken, pObject, lFlags, pCtx, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: DeleteClass(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->DeleteClass(strClass, lFlags, pCtx, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->DeleteClass((DWORD_PTR)pNewToken, strClass, lFlags, pCtx, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: CreateClassEnum(
/* [in] */ const BSTR strSuperclass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
if(m_pServices)
return m_pServices->CreateClassEnum(strSuperclass, lFlags, pCtx, ppEnum);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
// Talk to WinMgmt
IWmiXMLEnumWbemClassObject *pEnum = NULL;
if(SUCCEEDED(result = m_pXMLServices->CreateClassEnum((DWORD_PTR)pNewToken, strSuperclass, lFlags, pCtx, &pEnum)))
{
// Wrap it up in one of our own enumerators
*ppEnum = NULL;
*ppEnum = new CWMIXMLEnumWbemClassObject(pEnum);
pEnum->Release();
if(!(*ppEnum))
result = E_OUTOFMEMORY;
}
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: PutInstance(
/* [in] */ IWbemClassObject __RPC_FAR *pInst,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->PutInstance(pInst, lFlags, pCtx, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->PutInstance((DWORD_PTR)pNewToken, pInst, lFlags, pCtx, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: DeleteInstance(
/* [in] */ const BSTR strObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->DeleteInstance(strObjectPath, lFlags, pCtx, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->DeleteInstance((DWORD_PTR)pNewToken, strObjectPath, lFlags, pCtx, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: CreateInstanceEnum(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
if(m_pServices)
return m_pServices->CreateInstanceEnum(strClass, lFlags, pCtx, ppEnum);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
// Talk to WinMgmt
IWmiXMLEnumWbemClassObject *pEnum = NULL;
if(SUCCEEDED(result = m_pXMLServices->CreateInstanceEnum((DWORD_PTR)pNewToken, strClass, lFlags, pCtx, &pEnum)))
{
// Wrap it up in one of our own enumerators
*ppEnum = NULL;
*ppEnum = new CWMIXMLEnumWbemClassObject(pEnum);
pEnum->Release();
if(!(*ppEnum))
result = E_OUTOFMEMORY;
}
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: ExecQuery(
/* [in] */ const BSTR strQueryLanguage,
/* [in] */ const BSTR strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
if(m_pServices)
return m_pServices->ExecQuery(strQueryLanguage, strQuery, lFlags, pCtx, ppEnum);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
// Talk to WinMgmt
IWmiXMLEnumWbemClassObject *pEnum = NULL;
if(SUCCEEDED(result = m_pXMLServices->ExecQuery((DWORD_PTR)pNewToken, strQueryLanguage, strQuery, lFlags, pCtx, &pEnum)))
{
// Wrap it up in one of our own enumerators
*ppEnum = NULL;
*ppEnum = new CWMIXMLEnumWbemClassObject(pEnum);
pEnum->Release();
if(!(*ppEnum))
result = E_OUTOFMEMORY;
}
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}
HRESULT STDMETHODCALLTYPE CWMIXMLServices :: ExecMethod(
/* [in] */ const BSTR strObjectPath,
/* [in] */ const BSTR strMethodName,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemClassObject __RPC_FAR *pInParams,
/* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppOutParams,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
if(m_pServices)
return m_pServices->ExecMethod(strObjectPath, strMethodName, lFlags, pCtx, pInParams, ppOutParams, ppCallResult);
else
{
HRESULT result = E_FAIL;
HANDLE pNewToken = NULL;
if(SUCCEEDED(result = DuplicateTokenInWinmgmt(&pNewToken)))
{
result = m_pXMLServices->ExecMethod((DWORD_PTR)pNewToken, strObjectPath, strMethodName, lFlags, pCtx, pInParams, ppOutParams, ppCallResult);
// No Need to close the duplicated handle - it will be closed in WinMgmt
}
else
{
if(pNewToken)
m_pXMLServices->FreeToken((DWORD_PTR)pNewToken);
}
return result;
}
}