441 lines
12 KiB
C++
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 );
|
|
}
|
|
|
|
|