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

441 lines
12 KiB
C++

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
DSUMICONT.CPP
Abstract:
Call Result Class
History:
--*/
#include "precomp.h"
#include <wbemidl.h>
#include <wbemint.h>
#include <umi.h>
#include <arrtempl.h>
#include <wbemutil.h>
#include "DsUmiCont.h"
#pragma warning(disable:4355)
HRESULT ConvertClassPath(IUmiURL * pPath)
{
ULONG uLength = 0;
// Read the class name, it is something like "user"
HRESULT hr = pPath->GetLeafName(&uLength, NULL);
if(FAILED(hr))
return hr;
WCHAR * pClassName = new WCHAR[uLength];
if(pClassName == NULL)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe<WCHAR> dm(pClassName);
hr = pPath->GetLeafName(&uLength, pClassName);
if(FAILED(hr))
return hr;
// Now set the path to "class.name=user"
IUmiURLKeyList * pKeyList;
hr = pPath->GetKeyList(&pKeyList);
if(FAILED(hr))
return hr;
CReleaseMe rm(pKeyList);
hr = pKeyList->SetKey(L"name", pClassName);
if(FAILED(hr))
return hr;
return pPath->SetLeafName(L"class");
}
CDsUmiContainer::CDsUmiContainer()
{
m_pUmiContainer = NULL;
m_pUmiClassContainer = NULL;
m_pIUmiConn = NULL;
m_lRef = 0;
}
CDsUmiContainer::~CDsUmiContainer()
{
if(m_pUmiContainer)
m_pUmiContainer->Release();
if(m_pUmiClassContainer)
m_pUmiClassContainer->Release();
if(m_pIUmiConn)
m_pIUmiConn->Release();
}
HRESULT CDsUmiContainer::SetInterface(IUmiContainer * pUmiContainer, IUmiURL * pPath,
IUmiConnection *pIUmiConn)
{
HRESULT hr;
if(pUmiContainer == NULL || pPath == NULL || pIUmiConn == NULL)
return WBEM_E_INVALID_PARAMETER;
m_pUmiContainer = pUmiContainer;
m_pUmiContainer->AddRef();
m_pIUmiConn = pIUmiConn;
m_pIUmiConn->AddRef();
UMI_PROPERTY_VALUES * pPropValues;
IUmiPropList* pPropList = NULL;
// The _Schema property in the interface property list will contain the actual
// path to the schema for the container. The schema path would properly be
// obtained by an interface property from the connection. In the meantime
// we will get this value and march forwards through it until we find the
// word schema and assume that is the path to the schema container.
hr = m_pUmiContainer->GetInterfacePropList( 0L, &pPropList );
CReleaseMe rm(pPropList);
// Inability to get the schema container is not a critical failure
if ( SUCCEEDED( hr ) )
hr = pPropList->Get(L"__PADS_SCHEMA_CONTAINER_PATH", 0, &pPropValues);
if(FAILED(hr))
{
ERRORTRACE((LOG_WBEMPROX, "Get Schema Container Path failed, return code = 0x%x\n",hr));
return WBEM_S_NO_ERROR;
}
UMI_PROPERTY *pProp;
pProp = pPropValues->pPropArray; // wcValue
// Grab the class container.
LPWSTR * ppStr = (LPWSTR *)pProp->pUMIValue;
LPWSTR pwcsSchema = *ppStr;
pPath->Set( 0, pwcsSchema);
hr = m_pIUmiConn->Open(
pPath,
0,
IID_IUmiContainer,
(void **) &m_pUmiClassContainer
);
// Inability to connect to the schema container is not a critical failure
if(FAILED(hr))
{
ERRORTRACE((LOG_WBEMPROX, "Connecting to schema container failed, return code = 0x%x\n",hr));
return WBEM_S_NO_ERROR;
}
return S_OK;
}
STDMETHODIMP CDsUmiContainer::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == IID_IUmiContainer)
{
AddRef();
*ppv = (IUmiContainer*)this;
return S_OK;
}
else if(riid == IID__IUmiDsWrapper )
{
AddRef();
*ppv = (_IUmiDsWrapper*)this;
return S_OK;
}
else return E_NOINTERFACE;
}
HRESULT CDsUmiContainer::Put(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags,
/* [in] */ UMI_PROPERTY_VALUES __RPC_FAR *pProp)
{
IUmiPropList * pTemp = m_pUmiContainer;
return pTemp->Put(pszName, uFlags, pProp);
}
HRESULT CDsUmiContainer::Get(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags,
/* [out] */ UMI_PROPERTY_VALUES __RPC_FAR *__RPC_FAR *pProp)
{
return m_pUmiContainer->Get(pszName, uFlags, pProp);
}
HRESULT CDsUmiContainer::GetAt(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags,
/* [in] */ ULONG uBufferLength,
/* [out] */ LPVOID pExistingMem)
{
return m_pUmiContainer->GetAt(pszName, uFlags, uBufferLength, pExistingMem);
}
HRESULT CDsUmiContainer::GetAs(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags,
/* [in] */ ULONG uCoercionType,
/* [out] */ UMI_PROPERTY_VALUES __RPC_FAR *__RPC_FAR *pProp)
{
return m_pUmiContainer->GetAs(pszName, uFlags, uCoercionType, pProp);
}
HRESULT CDsUmiContainer::FreeMemory(
ULONG uReserved,
LPVOID pMem)
{
return m_pUmiContainer->FreeMemory(uReserved, pMem);
}
HRESULT CDsUmiContainer::Delete(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags)
{
IUmiPropList * pTemp = m_pUmiContainer;
return pTemp->Delete(pszName, uFlags);
}
HRESULT CDsUmiContainer::GetProps(
/* [in] */ LPCWSTR __RPC_FAR *pszNames,
/* [in] */ ULONG uNameCount,
/* [in] */ ULONG uFlags,
/* [out] */ UMI_PROPERTY_VALUES __RPC_FAR *__RPC_FAR *pProps)
{
return m_pUmiContainer->GetProps(pszNames, uNameCount, uFlags, pProps);
}
HRESULT CDsUmiContainer::PutProps(
/* [in] */ LPCWSTR __RPC_FAR *pszNames,
/* [in] */ ULONG uNameCount,
/* [in] */ ULONG uFlags,
/* [in] */ UMI_PROPERTY_VALUES __RPC_FAR *pProps)
{
return m_pUmiContainer->PutProps(pszNames, uNameCount, uFlags, pProps);
}
HRESULT CDsUmiContainer::PutFrom(
/* [in] */ LPCWSTR pszName,
/* [in] */ ULONG uFlags,
/* [in] */ ULONG uBufferLength,
/* [in] */ LPVOID pExistingMem)
{
return m_pUmiContainer->PutFrom(pszName, uFlags, uBufferLength, pExistingMem);
}
// IUmiBaseObject
HRESULT CDsUmiContainer::GetLastStatus(
/* [in] */ ULONG uFlags,
/* [out] */ ULONG __RPC_FAR *puSpecificStatus,
/* [in] */ REFIID riid,
/* [iid_is][out] */ LPVOID __RPC_FAR *pStatusObj)
{
return m_pUmiContainer->GetLastStatus(uFlags, puSpecificStatus, riid, pStatusObj);
}
HRESULT CDsUmiContainer::GetInterfacePropList(
/* [in] */ ULONG uFlags,
/* [out] */ IUmiPropList __RPC_FAR *__RPC_FAR *pPropList)
{
return m_pUmiContainer->GetInterfacePropList(uFlags, pPropList);
}
// IUmiObject
HRESULT CDsUmiContainer::Clone(
/* [in] */ ULONG uFlags,
/* [in] */ REFIID riid,
/* [iid_is][out] */ LPVOID __RPC_FAR *pCopy)
{
return m_pUmiContainer->Clone(uFlags, riid, pCopy);
}
HRESULT CDsUmiContainer::Refresh(
/* [in] */ ULONG uFlags,
/* [in] */ ULONG uNameCount,
/* [in] */ LPWSTR __RPC_FAR *pszNames)
{
return m_pUmiContainer->Refresh(uFlags, uNameCount, pszNames);
}
HRESULT CDsUmiContainer::CopyTo(
/* [in] */ ULONG uFlags,
/* [in] */ IUmiURL *pURL,
/* [in] */ REFIID riid,
/* [out, iid_is(riid)] */ LPVOID *pCopy)
{
return m_pUmiContainer->CopyTo(uFlags, pURL, riid, pCopy);
}
HRESULT CDsUmiContainer::Commit(
/* [in] */ ULONG uFlags)
{
return m_pUmiContainer->Commit(uFlags);
}
HRESULT CDsUmiContainer::Open(
/* [in] */ IUmiURL __RPC_FAR *pURL,
/* [in] */ ULONG uFlags,
/* [in] */ REFIID TargetIID,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvRes)
{
BOOL bClass = uFlags & UMI_OPERATION_CLASS;
uFlags = uFlags & ~(UMI_OPERATION_CLASS|UMI_OPERATION_INSTANCE);
if(bClass)
{
// Can't do a schema operation if we don't have a schema container
if ( NULL == m_pUmiClassContainer )
{
return WBEM_E_NO_SCHEMA;
}
HRESULT hr = ConvertClassPath(pURL);
if(FAILED(hr))
return hr;
return m_pUmiClassContainer->Open(pURL,uFlags,TargetIID,ppvRes);
}
else
{
// Two cases, we are either getting an object or a container
if(TargetIID != IID_IUmiContainer)
return m_pUmiContainer->Open(pURL,uFlags,TargetIID,ppvRes);
else
{
IUmiContainer * pCont = NULL;
HRESULT hr = m_pUmiContainer->Open(pURL,uFlags,TargetIID,(void **)&pCont);
if(FAILED(hr))
return hr;
CReleaseMe rm(pCont);
CDsUmiContainer * pNew = new CDsUmiContainer();
if(pNew == NULL)
return WBEM_E_OUT_OF_MEMORY;
hr = pNew->SetInterface(pCont, pURL, m_pIUmiConn);
if(FAILED(hr))
{
delete pNew;
return hr;
}
return pNew->QueryInterface(IID_IUmiContainer, ppvRes);
}
}
}
HRESULT CDsUmiContainer::PutObject(
/* [in] */ ULONG uFlags,
/* [in] */ REFIID TargetIID,
/* [iid_is][out][in] */ void __RPC_FAR *pObj)
{
return m_pUmiContainer->PutObject(uFlags,TargetIID,pObj);
}
HRESULT CDsUmiContainer::DeleteObject(
/* [in] */ IUmiURL __RPC_FAR *pURL,
/* [optional][in] */ ULONG uFlags)
{
BOOL bClass = uFlags & UMI_OPERATION_CLASS;
uFlags = uFlags & ~(UMI_OPERATION_CLASS|UMI_OPERATION_INSTANCE);
if(bClass)
{
// Can't do a schema operation if we don't have a schema container
if ( NULL == m_pUmiClassContainer )
{
return WBEM_E_NO_SCHEMA;
}
return m_pUmiClassContainer->DeleteObject(pURL,uFlags);
}
else
{
return m_pUmiContainer->DeleteObject(pURL,uFlags);
}
}
HRESULT CDsUmiContainer::Create(
/* [in] */ IUmiURL __RPC_FAR *pURL,
/* [in] */ ULONG uFlags,
/* [out] */ IUmiObject __RPC_FAR *__RPC_FAR *pNewObj)
{
BOOL bClass = uFlags & UMI_OPERATION_CLASS;
uFlags = uFlags & ~(UMI_OPERATION_CLASS|UMI_OPERATION_INSTANCE);
if(bClass)
{
// Can't do a schema operation if we don't have a schema container
if ( NULL == m_pUmiClassContainer )
{
return WBEM_E_NO_SCHEMA;
}
return m_pUmiClassContainer->Create(pURL,uFlags,pNewObj);
}
else
{
return m_pUmiContainer->Create(pURL,uFlags,pNewObj);
}
}
HRESULT CDsUmiContainer::Move(
/* [in] */ ULONG uFlags,
/* [in] */ IUmiURL __RPC_FAR *pOldURL,
/* [in] */ IUmiURL __RPC_FAR *pNewURL)
{
return m_pUmiContainer->Move(uFlags,pOldURL,pNewURL);
}
HRESULT CDsUmiContainer::CreateEnum(
/* [in] */ IUmiURL __RPC_FAR *pszEnumContext,
/* [in] */ ULONG uFlags,
/* [in] */ REFIID TargetIID,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvEnum)
{
BOOL bClass = uFlags & UMI_OPERATION_CLASS;
uFlags = uFlags & ~(UMI_OPERATION_CLASS|UMI_OPERATION_INSTANCE);
if(bClass)
{
// Can't do a schema operation if we don't have a schema container
if ( NULL == m_pUmiClassContainer )
{
return WBEM_E_NO_SCHEMA;
}
return m_pUmiClassContainer->CreateEnum(pszEnumContext,uFlags,TargetIID,ppvEnum);
}
else
{
return m_pUmiContainer->CreateEnum(pszEnumContext,uFlags,TargetIID,ppvEnum);
}
}
HRESULT CDsUmiContainer::ExecQuery(
/* [in] */ IUmiQuery __RPC_FAR *pQuery,
/* [in] */ ULONG uFlags,
/* [in] */ REFIID TargetIID,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppResult)
{
return m_pUmiContainer->ExecQuery(pQuery,uFlags,TargetIID,ppResult);
}
STDMETHODIMP CDsUmiContainer::GetRealContainer( IUnknown** pUnk )
{
return m_pUmiContainer->QueryInterface( IID_IUnknown, (void**) pUnk );
}