486 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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;
 | |
| 	}
 | |
| }
 | |
| 
 |