Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3439 lines
114 KiB

//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// ***************************************************************************
//
// Original Author: Rajesh Rao
//
// $Author: rajeshr $
// $Date: 9/16/98 4:43p $
// $Workfile:instprov.cpp $
//
// $Modtime: 9/16/98 11:21a $
// $Revision: 1 $
// $Nokeywords: $
//
//
// Description: Contains implementation of the DS Instance Provider class.
//
//***************************************************************************
#include "precomp.h"
#include <helper.h>
/////////////////////////////////////////
// Initialize the static members
/////////////////////////////////////////
LPCWSTR CLDAPInstanceProvider :: DEFAULT_NAMING_CONTEXT_ATTR = L"defaultNamingContext";
LPCWSTR CLDAPInstanceProvider :: OBJECT_CLASS_EQUALS = L"(objectClass=";
LPCWSTR CLDAPInstanceProvider :: QUERY_FORMAT = L"select * from DSClass_To_DNInstance where DSClass=\"%s\"";
BSTR CLDAPInstanceProvider :: CLASS_STR = NULL;
BSTR CLDAPInstanceProvider :: DN_PROPERTY = NULL;
BSTR CLDAPInstanceProvider :: ROOT_DN_PROPERTY = NULL;
BSTR CLDAPInstanceProvider :: QUERY_LANGUAGE = NULL;
BSTR CLDAPInstanceProvider :: ADSI_PATH_STR = NULL;
BSTR CLDAPInstanceProvider :: UINT8ARRAY_STR = NULL;
BSTR CLDAPInstanceProvider :: DN_WITH_STRING_CLASS_STR = NULL;
BSTR CLDAPInstanceProvider :: DN_WITH_BINARY_CLASS_STR = NULL;
BSTR CLDAPInstanceProvider :: VALUE_PROPERTY_STR = NULL;
BSTR CLDAPInstanceProvider :: DN_STRING_PROPERTY_STR = NULL;
BSTR CLDAPInstanceProvider :: INSTANCE_ASSOCIATION_CLASS_STR = NULL;
BSTR CLDAPInstanceProvider :: CHILD_INSTANCE_PROPERTY_STR = NULL;
BSTR CLDAPInstanceProvider :: PARENT_INSTANCE_PROPERTY_STR = NULL;
BSTR CLDAPInstanceProvider :: RELPATH_STR = NULL;
BSTR CLDAPInstanceProvider :: ATTRIBUTE_SYNTAX_STR = NULL;
BSTR CLDAPInstanceProvider :: DEFAULT_OBJECT_CATEGORY_STR = NULL;
BSTR CLDAPInstanceProvider :: LDAP_DISPLAY_NAME_STR = NULL;
BSTR CLDAPInstanceProvider :: PUT_EXTENSIONS_STR = NULL;
BSTR CLDAPInstanceProvider :: PUT_EXT_PROPERTIES_STR = NULL;
BSTR CLDAPInstanceProvider :: CIMTYPE_STR = NULL;
// Names of the RootDSE attributes
BSTR CLDAPInstanceProvider :: SUBSCHEMASUBENTRY_STR = NULL;
BSTR CLDAPInstanceProvider :: CURRENTTIME_STR = NULL;
BSTR CLDAPInstanceProvider :: SERVERNAME_STR = NULL;
BSTR CLDAPInstanceProvider :: NAMINGCONTEXTS_STR = NULL;
BSTR CLDAPInstanceProvider :: DEFAULTNAMINGCONTEXT_STR = NULL;
BSTR CLDAPInstanceProvider :: SCHEMANAMINGCONTEXT_STR = NULL;
BSTR CLDAPInstanceProvider :: CONFIGURATIONNAMINGCONTEXT_STR = NULL;
BSTR CLDAPInstanceProvider :: ROOTDOMAINNAMINGCONTEXT_STR = NULL;
BSTR CLDAPInstanceProvider :: SUPPORTEDCONTROLS_STR = NULL;
BSTR CLDAPInstanceProvider :: SUPPORTEDVERSION_STR = NULL;
BSTR CLDAPInstanceProvider :: DNSHOSTNAME_STR = NULL;
BSTR CLDAPInstanceProvider :: DSSERVICENAME_STR = NULL;
BSTR CLDAPInstanceProvider :: HIGHESTCOMMITEDUSN_STR = NULL;
BSTR CLDAPInstanceProvider :: LDAPSERVICENAME_STR = NULL;
BSTR CLDAPInstanceProvider :: SUPPORTEDCAPABILITIES_STR = NULL;
BSTR CLDAPInstanceProvider :: SUPPORTEDLDAPPOLICIES_STR = NULL;
BSTR CLDAPInstanceProvider :: SUPPORTEDSASLMECHANISMS_STR = NULL;
//***************************************************************************
//
// CLDAPInstanceProvider::CLDAPInstanceProvider
// CLDAPInstanceProvider::~CLDAPInstanceProvider
//
// Constructor Parameters:
//
//
//***************************************************************************
CLDAPInstanceProvider :: CLDAPInstanceProvider ()
{
InterlockedIncrement(&g_lComponents);
// Initialize the search preferences often used
m_pSearchInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
m_pSearchInfo[0].vValue.dwType = ADSTYPE_INTEGER;
m_pSearchInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
m_pSearchInfo[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
m_pSearchInfo[1].vValue.dwType = ADSTYPE_INTEGER;
m_pSearchInfo[1].vValue.Integer = 1024;
m_lReferenceCount = 0 ;
m_IWbemServices = NULL;
m_pWbemUin8ArrayClass = NULL;
m_pWbemDNWithBinaryClass = NULL;
m_pWbemDNWithStringClass = NULL;
m_pAssociationsClass = NULL;
m_lpszTopLevelContainerPath = NULL;
m_bInitializedSuccessfully = FALSE;
if(g_pLogObject)
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CONSTRUCTOR\r\n");
}
CLDAPInstanceProvider::~CLDAPInstanceProvider ()
{
if(g_pLogObject)
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DESCTRUVTOR\r\n");
if (m_lpszTopLevelContainerPath)
{
delete [] m_lpszTopLevelContainerPath;
}
if(m_IWbemServices)
m_IWbemServices->Release();
if(m_pWbemUin8ArrayClass)
m_pWbemUin8ArrayClass->Release();
if(m_pWbemDNWithBinaryClass)
m_pWbemDNWithBinaryClass->Release();
if(m_pWbemDNWithStringClass)
m_pWbemDNWithStringClass->Release();
if(m_pAssociationsClass)
m_pAssociationsClass->Release();
InterlockedDecrement(&g_lComponents);
}
//***************************************************************************
//
// CLDAPInstanceProvider::QueryInterface
// CLDAPInstanceProvider::AddRef
// CLDAPInstanceProvider::Release
//
// Purpose: Standard COM routines needed for all COM objects
//
//***************************************************************************
STDMETHODIMP CLDAPInstanceProvider :: QueryInterface (
REFIID iid ,
LPVOID FAR *iplpv
)
{
*iplpv = NULL ;
if ( iid == IID_IUnknown )
{
*iplpv = ( LPVOID ) (IUnknown *)(IWbemProviderInit *)this ;
}
else if ( iid == IID_IWbemServices )
{
*iplpv = ( LPVOID ) (IWbemServices *)this ;
}
else if ( iid == IID_IWbemProviderInit )
{
*iplpv = ( LPVOID ) (IWbemProviderInit *)this ;
}
else
{
return E_NOINTERFACE;
}
( ( LPUNKNOWN ) *iplpv )->AddRef () ;
return S_OK;
}
STDMETHODIMP_( ULONG ) CLDAPInstanceProvider :: AddRef ()
{
return InterlockedIncrement ( & m_lReferenceCount ) ;
}
STDMETHODIMP_(ULONG) CLDAPInstanceProvider :: Release ()
{
LONG ref ;
if ( ( ref = InterlockedDecrement ( & m_lReferenceCount ) ) == 0 )
{
delete this ;
return 0 ;
}
else
{
return ref ;
}
}
HRESULT CLDAPInstanceProvider :: Initialize(
LPWSTR wszUser,
LONG lFlags,
LPWSTR wszNamespace,
LPWSTR wszLocale,
IWbemServices __RPC_FAR *pNamespace,
IWbemContext __RPC_FAR *pCtx,
IWbemProviderInitSink __RPC_FAR *pInitSink)
{
// Validate the arguments
if(pNamespace == NULL || lFlags != 0)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Argument validation FAILED\r\n");
pInitSink->SetStatus(WBEM_E_FAILED, 0);
return WBEM_S_NO_ERROR;
}
// Store the IWbemServices pointer for future use
m_IWbemServices = pNamespace;
m_IWbemServices->AddRef();
// Get the DefaultNamingContext to get at the top level container
// Get the ADSI path of the schema container and store it for future use
IADs *pRootDSE = NULL;
HRESULT result;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)ROOT_DSE_PATH, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID *) &pRootDSE)))
{
// Get the location of the schema container
BSTR strDefaultNamingContext = SysAllocString((LPWSTR) DEFAULT_NAMING_CONTEXT_ATTR);
// Get the DEFAULT_NAMING_CONTEXT property. This property contains the ADSI path
// of the top level container
VARIANT variant;
VariantInit(&variant);
if(SUCCEEDED(result = pRootDSE->Get(strDefaultNamingContext, &variant)))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Got Top Level Container as : %s\r\n", variant.bstrVal);
// Form the top level container path
m_lpszTopLevelContainerPath = new WCHAR[wcslen(LDAP_PREFIX) + wcslen(variant.bstrVal) + 1];
wcscpy(m_lpszTopLevelContainerPath, LDAP_PREFIX);
wcscat(m_lpszTopLevelContainerPath, variant.bstrVal);
// Get the Uint8Array Class
if(SUCCEEDED(result = m_IWbemServices->GetObject(UINT8ARRAY_STR, 0, pCtx, &m_pWbemUin8ArrayClass, NULL)))
{
// Get the DNWIthBinary Class
if(SUCCEEDED(result = m_IWbemServices->GetObject(DN_WITH_BINARY_CLASS_STR, 0, pCtx, &m_pWbemDNWithBinaryClass, NULL)))
{
// Get the DNWIthBinary Class
if(SUCCEEDED(result = m_IWbemServices->GetObject(DN_WITH_STRING_CLASS_STR, 0, pCtx, &m_pWbemDNWithStringClass, NULL)))
{
// Get the Associations Class
if(SUCCEEDED(result = m_IWbemServices->GetObject(INSTANCE_ASSOCIATION_CLASS_STR, 0, pCtx, &m_pAssociationsClass, NULL)))
{
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get Instance Associations class %x\r\n", result);
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get DNWithString class %x\r\n", result);
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get DNWithBinary class %x\r\n", result);
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get Uint8Array class %x\r\n", result);
}
VariantClear(&variant);
}
SysFreeString(strDefaultNamingContext);
pRootDSE->Release();
}
if(SUCCEEDED(result))
{
m_bInitializedSuccessfully = TRUE;
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
}
else
{
m_bInitializedSuccessfully = FALSE;
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialize() FAILED \r\n");
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
}
return WBEM_S_NO_ERROR;
}
HRESULT CLDAPInstanceProvider :: OpenNamespace(
/* [in] */ const BSTR strNamespace,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemServices __RPC_FAR *__RPC_FAR *ppWorkingNamespace,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppResult)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: CancelAsyncCall(
/* [in] */ IWbemObjectSink __RPC_FAR *pSink)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: QueryObjectSink(
/* [in] */ long lFlags,
/* [out] */ IWbemObjectSink __RPC_FAR *__RPC_FAR *ppResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: 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)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: GetObjectAsync(
/* [in] */ const BSTR strObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!m_bInitializedSuccessfully)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
return WBEM_E_FAILED;
}
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() called for %s \r\n", strObjectPath);
HRESULT result = S_OK;
// Impersonate the client
if(!SUCCEEDED(result = WbemCoImpersonateClient()))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() CoImpersonate FAILED for %s with %x\r\n", strObjectPath, result);
return WBEM_E_FAILED;
}
// Validate the arguments
if(strObjectPath == NULL)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() argument validation FAILED\r\n");
return WBEM_E_INVALID_PARAMETER;
}
// Parse the object path
CObjectPathParser theParser;
ParsedObjectPath *theParsedObjectPath = NULL;
switch(theParser.Parse(strObjectPath, &theParsedObjectPath))
{
case CObjectPathParser::NoError:
break;
default:
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() object path parsing FAILED\r\n");
return WBEM_E_INVALID_PARAMETER;
}
try
{
// Check if this is for associations
if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0)
{
// Check whether there are exactly 2 keys specified
if(theParsedObjectPath->m_dwNumKeys != 2)
result = WBEM_E_INVALID_PARAMETER;
// Check whether these keys are
KeyRef *pChildKeyRef = *(theParsedObjectPath->m_paKeys);
KeyRef *pParentKeyRef = *(theParsedObjectPath->m_paKeys + 1);
if(_wcsicmp(pChildKeyRef->m_pName, CHILD_INSTANCE_PROPERTY_STR) != 0)
{
// Exchange them
KeyRef *temp = pChildKeyRef;
pChildKeyRef = pParentKeyRef;
pParentKeyRef = pChildKeyRef;
}
// The status on the sink
IWbemClassObject *ppReturnWbemClassObjects[1];
ppReturnWbemClassObjects[0] = NULL;
if(SUCCEEDED(result))
{
// Convert the key values to ADSI paths
LPWSTR pszChildADSIPath = NULL;
LPWSTR pszParentADSIPath = NULL;
try
{
pszChildADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pChildKeyRef->m_vValue.bstrVal);
pszParentADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pParentKeyRef->m_vValue.bstrVal);
if(SUCCEEDED(result = IsContainedIn(pszChildADSIPath, pszParentADSIPath)))
{
if(result == S_OK)
{
if(SUCCEEDED(result = CreateWBEMInstance(pChildKeyRef->m_vValue.bstrVal, pParentKeyRef->m_vValue.bstrVal, ppReturnWbemClassObjects)))
{
result = pResponseHandler->Indicate(1, ppReturnWbemClassObjects);
ppReturnWbemClassObjects[0]->Release();
}
}
else // the instance was not found
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: returning WBEM_E_NOT_FOUND for %s \r\n", strObjectPath);
result = WBEM_E_NOT_FOUND;
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: IsContainedIn() FAILED with %x \r\n", result);
}
}
catch ( ... )
{
if ( pszChildADSIPath )
{
delete [] pszChildADSIPath;
pszChildADSIPath = NULL;
}
if ( pszParentADSIPath )
{
delete [] pszParentADSIPath;
pszParentADSIPath = NULL;
}
throw;
}
if ( pszChildADSIPath )
{
delete [] pszChildADSIPath;
pszChildADSIPath = NULL;
}
if ( pszParentADSIPath )
{
delete [] pszParentADSIPath;
pszParentADSIPath = NULL;
}
}
}
// Check if this is for the RootDSE class
else if(_wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0)
{
result = ProcessRootDSEGetObject(theParsedObjectPath->m_pClass, pResponseHandler, pCtx);
}
else // It is for ADSI instances
{
// Check whether there is exactly 1 key specified
if(theParsedObjectPath->m_dwNumKeys != 1 )
result = WBEM_E_INVALID_PARAMETER;
// Get the key
KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
// Check to see that the key name is correct, if it is present
if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
result = WBEM_E_INVALID_PARAMETER;
// The status on the sink
IWbemClassObject *ppReturnWbemClassObjects[1];
ppReturnWbemClassObjects[0] = NULL;
if(SUCCEEDED(result))
{
// Get the ADSI object
CADSIInstance *pADSIObject = NULL;
if(SUCCEEDED(result = CLDAPHelper::GetADSIInstance(pKeyRef->m_vValue.bstrVal, &pADSIObject, g_pLogObject)))
{
try
{
// Get the class to spawn an instance
IWbemClassObject *pWbemClass = NULL;
if(SUCCEEDED(result = m_IWbemServices->GetObject(theParsedObjectPath->m_pClass, 0, pCtx, &pWbemClass, NULL)))
{
try
{
// Spawn a instance of the WBEM Class
if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, ppReturnWbemClassObjects)))
{
// Map it to WBEM
if(SUCCEEDED(result = MapADSIInstance(pADSIObject, ppReturnWbemClassObjects[0], pWbemClass)))
{
// Indicate the result
if(FAILED(result = pResponseHandler->Indicate(1, ppReturnWbemClassObjects)))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : Indicate() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : MapADSIInstance() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
}
ppReturnWbemClassObjects[0]->Release();
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: SpawnInstance() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
}
}
catch ( ... )
{
pWbemClass->Release();
pWbemClass = NULL;
throw;
}
pWbemClass->Release();
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() GetObject() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
}
}
catch ( ... )
{
pADSIObject->Release();
pADSIObject = NULL;
throw;
}
pADSIObject->Release();
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : GetADSIInstance() FAILED with %x \r\n", result);
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() Argument processing FAILED \r\n");
}
}
}
catch ( ... )
{
theParser.Free(theParsedObjectPath);
throw;
}
// Free the parser object path
theParser.Free(theParsedObjectPath);
// Set the status of the request
result = (SUCCEEDED(result)? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND);
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, result, NULL, NULL);
if(SUCCEEDED(result))
g_pLogObject->WriteW( L"XXXXXXXXXXXXXXXXX CLDAPInstanceProvider :: GetObjectAsync() succeeded for %s\r\n", strObjectPath);
else
g_pLogObject->WriteW( L"XXXXXXXXXXXXXXXXX CLDAPInstanceProvider :: GetObjectAsync() FAILED for %s\r\n", strObjectPath);
return WBEM_S_NO_ERROR;
}
HRESULT CLDAPInstanceProvider :: PutClass(
/* [in] */ IWbemClassObject __RPC_FAR *pObject,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: PutClassAsync(
/* [in] */ IWbemClassObject __RPC_FAR *pObject,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: DeleteClass(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: DeleteClassAsync(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: CreateClassEnum(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: CreateClassEnumAsync(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: PutInstance(
/* [in] */ IWbemClassObject __RPC_FAR *pInst,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstance() called\r\n");
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: PutInstanceAsync(
/* [in] */ IWbemClassObject __RPC_FAR *pInst,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!m_bInitializedSuccessfully)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
return WBEM_E_FAILED;
}
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() called\r\n");
HRESULT result = WBEM_S_NO_ERROR;
// Impersonate the client
if(!SUCCEEDED(result = WbemCoImpersonateClient()))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CoImpersonate FAILED forwith %x\r\n", result);
return WBEM_E_FAILED;
}
// Get the object ref of the instance being put
BSTR strRelPath = NULL;
if(SUCCEEDED(CWBEMHelper::GetBSTRProperty(pInst, RELPATH_STR, &strRelPath)))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() calledfor %s\r\n", strRelPath);
// Check to see if the ADSI Path is present.
// Parse the object path
// Parse the object path
CObjectPathParser theParser;
ParsedObjectPath *theParsedObjectPath = NULL;
LPWSTR pszADSIPath = NULL;
LPWSTR pszWBEMClass = NULL;
LPWSTR pszADSIClass = NULL;
try
{
switch(theParser.Parse((LPWSTR)strRelPath, &theParsedObjectPath))
{
case CObjectPathParser::NoError:
{
KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
// Check to see that there is 1 key specified and that its type is VT_BSTR
if(pKeyRef && theParsedObjectPath->m_dwNumKeys == 1 && pKeyRef->m_vValue.vt == VT_BSTR)
{
try
{
// If the name of the key is specified, check the name
if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
break;
pszADSIPath = new WCHAR[wcslen((*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal) + 1];
wcscpy(pszADSIPath, (*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal);
pszWBEMClass = new WCHAR[wcslen(theParsedObjectPath->m_pClass) + 1];
wcscpy(pszWBEMClass, theParsedObjectPath->m_pClass);
}
catch ( ... )
{
theParser.Free(theParsedObjectPath);
throw;
}
}
break;
}
default:
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() Parsing of RELPATH FAILED\r\n");
SysFreeString(strRelPath);
return WBEM_E_FAILED;
break;
}
try
{
if(pszWBEMClass)
{
// CHeck to see if the class is the containment/RootDSE class, if so disallow the operation
if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0 ||
_wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0 )
{
result = WBEM_E_PROVIDER_NOT_CAPABLE;
}
else
pszADSIClass = CLDAPHelper::UnmangleWBEMNameToLDAP(pszWBEMClass);
}
}
catch ( ... )
{
theParser.Free(theParsedObjectPath);
throw;
}
// Free the parser object path
theParser.Free(theParsedObjectPath);
if ( strRelPath )
{
SysFreeString(strRelPath);
strRelPath = NULL;
}
if ( pszWBEMClass )
{
delete [] pszWBEMClass;
pszWBEMClass = NULL;
}
if(pszADSIPath && pszADSIClass && SUCCEEDED(result))
{
// Try to retreive the existing object
// Get the ADSI object
CADSIInstance *pADSIObject = NULL;
result = CLDAPHelper::GetADSIInstance(pszADSIPath, &pADSIObject, g_pLogObject);
try
{
// Check if the WBEM_FLAG_UPDATE_ONLY flag is specified
if(lFlags & WBEM_FLAG_UPDATE_ONLY)
{
if(!pADSIObject)
result = WBEM_E_FAILED;
}
// Check if the WBEM_FLAG_CREATE_ONLY flag is specified
if(SUCCEEDED(result) && lFlags & WBEM_FLAG_CREATE_ONLY)
{
if(pADSIObject)
result = WBEM_E_ALREADY_EXISTS;
}
else
result = WBEM_S_NO_ERROR;
if(SUCCEEDED(result))
{
if(pADSIObject)
{
if(SUCCEEDED(result = ModifyExistingADSIInstance(pInst, pszADSIPath, pADSIObject, pszADSIClass, pCtx)))
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() ModifyExistingInstance succeeded for %s\r\n", pszADSIPath);
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() ModifyExistingInstance FAILED for %s with %x\r\n", pszADSIPath, result);
}
else
{
if(SUCCEEDED(result = CreateNewADSIInstance(pInst, pszADSIPath, pszADSIClass)))
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CreateNewInstance succeeded for %s\r\n", pszADSIPath);
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CreateNewInstance FAILED for %s with %x\r\n", pszADSIPath, result);
}
}
}
catch ( ... )
{
// Release any existing object
if(pADSIObject)
{
pADSIObject->Release();
pADSIObject = NULL;
}
throw;
}
// Release any existing object
if(pADSIObject)
pADSIObject->Release();
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() one of ADSIPath or ADSIClass is NULL\r\n");
}
catch ( ... )
{
if ( strRelPath )
{
SysFreeString(strRelPath);
strRelPath = NULL;
}
if ( pszWBEMClass )
{
delete [] pszWBEMClass;
pszWBEMClass = NULL;
}
if ( pszADSIClass )
{
delete [] pszADSIClass;
pszADSIClass = NULL;
}
if ( pszADSIPath )
{
delete [] pszADSIPath;
pszADSIPath = NULL;
}
throw;
}
delete [] pszADSIClass;
delete [] pszADSIPath;
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() FAILED to get RELPATH \r\n");
// Set the status of the request
result = (SUCCEEDED(result)? WBEM_S_NO_ERROR : WBEM_E_FAILED);
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, result, NULL, NULL);
return result;
}
HRESULT CLDAPInstanceProvider :: DeleteInstance(
/* [in] */ const BSTR strObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: DeleteInstanceAsync(
/* [in] */ const BSTR strObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!m_bInitializedSuccessfully)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
return WBEM_E_FAILED;
}
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() called for %s\r\n", strObjectPath);
HRESULT result = S_OK;
// Impersonate the client
if(!SUCCEEDED(result = WbemCoImpersonateClient()))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() CoImpersonate FAILED for %s with %x\r\n", strObjectPath, result);
return WBEM_E_FAILED;
}
// Validate the arguments
if(strObjectPath == NULL)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() argument validation FAILED\r\n");
return WBEM_E_INVALID_PARAMETER;
}
// Parse the object path
CObjectPathParser theParser;
ParsedObjectPath *theParsedObjectPath = NULL;
switch(theParser.Parse(strObjectPath, &theParsedObjectPath))
{
case CObjectPathParser::NoError:
break;
default:
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() object path parsing FAILED\r\n");
return WBEM_E_INVALID_PARAMETER;
}
// CHeck to see if the class is the containment/RootDSE class, if so disallow the operation
if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0 ||
_wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0 )
{
result = WBEM_E_PROVIDER_NOT_CAPABLE;
}
// Check whether there is exactly 1 key specified
if(theParsedObjectPath->m_dwNumKeys != 1 )
result = WBEM_E_INVALID_PARAMETER;
// Get the key
KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
// Check to see that the key name is correct, if it is present
if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
result = WBEM_E_INVALID_PARAMETER;
// Unfortunately, ADSI uses different interfaces to delete containers and non-containers
//=======================================================================================
if(SUCCEEDED(result))
{
IDirectoryObject *pDirectoryObject = NULL;
if(SUCCEEDED(result = ADsOpenObject(pKeyRef->m_vValue.bstrVal, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *)&pDirectoryObject)))
{
PADS_OBJECT_INFO pObjectInfo = NULL;
if(SUCCEEDED(result = pDirectoryObject->GetObjectInformation(&pObjectInfo)))
{
// CHeck whether it is the same class as the class being deleted.
LPWSTR pszWbemClass = CLDAPHelper::MangleLDAPNameToWBEM(pObjectInfo->pszClassName);
if(_wcsicmp(theParsedObjectPath->m_pClass, pszWbemClass) == 0)
{
// Get its parent. THis should be the container from which the child is deleted
IADsContainer *pParent = NULL;
if(SUCCEEDED(result = ADsOpenObject(pObjectInfo->pszParentDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsContainer, (LPVOID *)&pParent)))
{
if(SUCCEEDED(result = pParent->Delete(pObjectInfo->pszClassName, pObjectInfo->pszRDN)))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() Deleted %s successfully\r\n", pKeyRef->m_vValue.bstrVal);
result = WBEM_S_NO_ERROR;
}
else
{
if (HRESULT_CODE(result) == ERROR_DS_CANT_ON_NON_LEAF)
{
// this is non-empty container we wanted to delete here
IADsDeleteOps *pADsDeleteOps = NULL;
if(SUCCEEDED(result = ADsOpenObject(pKeyRef->m_vValue.bstrVal, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsDeleteOps, (LPVOID *)&pADsDeleteOps)))
{
if(FAILED(result = pADsDeleteOps->DeleteObject(0)))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() DeleteObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
if ( result == ERROR_DS_AUTH_METHOD_NOT_SUPPORTED )
{
result = WBEM_E_ACCESS_DENIED;
}
else
{
result = WBEM_E_FAILED;
}
}
pADsDeleteOps->Release();
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() DeleteDSObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
result = WBEM_E_FAILED;
}
}
pParent->Release();
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() ADsOpenObject on parent FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
result = WBEM_E_FAILED;
}
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() wrong class returning success\r\n");
result = WBEM_S_NO_ERROR;
}
delete [] pszWbemClass;
FreeADsMem((LPVOID *) pObjectInfo);
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() GetObjectInformation FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
result = WBEM_E_NOT_FOUND;
}
pDirectoryObject->Release();
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() ADsOpenObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
result = WBEM_E_NOT_FOUND;
}
}
// Free the parser object path
theParser.Free(theParsedObjectPath);
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE , result, NULL, NULL);
return WBEM_S_NO_ERROR;
}
HRESULT CLDAPInstanceProvider :: CreateInstanceEnum(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: CreateInstanceEnumAsync(
/* [in] */ const BSTR strClass,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!m_bInitializedSuccessfully)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
return WBEM_E_FAILED;
}
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync() called for %s Class \r\n", strClass );
HRESULT result;
// Impersonate the client
if(!SUCCEEDED(result = WbemCoImpersonateClient()))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync() CoImpersonate FAILED for %s with %x\r\n", strClass, result);
return WBEM_E_FAILED;
}
// CHeck to see if the class is the containment class, if so disallow an enumeration
if(_wcsicmp(strClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CLDAPInstanceProvider() Enumeration called on the containment class. Returning FAILED : WBEM_E_PROVIDER_NOT_CAPABLE\r\n");
return WBEM_E_PROVIDER_NOT_CAPABLE;
}
// Check if this is for the RootDSE class
else if(_wcsicmp(strClass, ROOTDSE_CLASS) == 0)
{
result = ProcessRootDSEGetObject(strClass, pResponseHandler, pCtx);
}
else // The rest of the classes
{
// Fetch the class from CIMOM
IWbemClassObject *pWbemClass = NULL;
if(SUCCEEDED(result = m_IWbemServices->GetObject(strClass, 0, pCtx, &pWbemClass, NULL)))
{
// We need the object category information
LPWSTR pszLDAPQuery = new WCHAR[10*(wcslen(strClass) + 25) + 50];
if(SUCCEEDED(CWBEMHelper::FormulateInstanceQuery(m_IWbemServices, pCtx, strClass, pWbemClass, pszLDAPQuery, LDAP_DISPLAY_NAME_STR, DEFAULT_OBJECT_CATEGORY_STR)))
{
// Check to see if the client has specified any hints as to the DN of the object from
// which the search should start
BOOLEAN bRootDNSpecified = FALSE;
LPWSTR *ppszRootDN = NULL;
DWORD dwRootDNCount = 0;
if(SUCCEEDED(GetRootDN(strClass, &ppszRootDN, &dwRootDNCount, pCtx)) && dwRootDNCount)
bRootDNSpecified = TRUE;
// Enumerate the ADSI Instances
// If any RootDNs were specified, use them. Otherwise use the default naming context
if(bRootDNSpecified)
{
for( DWORD i=0; i<dwRootDNCount; i++)
{
DoSingleQuery(strClass, pWbemClass, ppszRootDN[i], pszLDAPQuery, pResponseHandler);
}
}
else
{
DoSingleQuery(strClass, pWbemClass, m_lpszTopLevelContainerPath, pszLDAPQuery, pResponseHandler);
}
if(bRootDNSpecified)
{
for(DWORD i=0; i<dwRootDNCount; i++)
{
delete [] ppszRootDN[i];
}
delete [] ppszRootDN;
}
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync : FormulateInstanceQuery() FAILED for %s with %x \r\n", strClass, result);
delete [] pszLDAPQuery;
pWbemClass->Release();
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync : GetObject() FAILED for %s with %x \r\n", strClass, result);
}
if(SUCCEEDED(result))
{
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
g_pLogObject->WriteW( L"XXXXXXXXXXXXX CLDAPInstanceProvider :: CreateInstanceEnumAsync() Enumeration succeeded for %s\r\n", strClass);
return WBEM_S_NO_ERROR;
}
else
{
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_FAILED, NULL, NULL);
g_pLogObject->WriteW( L"XXXXXXXXXXXXX CLDAPInstanceProvider :: CreateInstanceEnumAsync() Enumeration FAILED for %s\r\n", strClass);
return WBEM_S_NO_ERROR;
}
}
HRESULT CLDAPInstanceProvider :: ExecQuery(
/* [in] */ const BSTR strQueryLanguage,
/* [in] */ const BSTR strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: ExecQueryAsync(
/* [in] */ const BSTR strQueryLanguage,
/* [in] */ const BSTR strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!m_bInitializedSuccessfully)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
return WBEM_E_FAILED;
}
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() called with %s\r\n", strQuery);
HRESULT result;
// Impersonate the client
if(!SUCCEEDED(result = WbemCoImpersonateClient()))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() CoImpersonate FAILED for %s with %x\r\n", strQuery, result);
return WBEM_E_FAILED;
}
// Create Parser for the Query.
CTextLexSource src(strQuery);
SQL1_Parser parser(&src);
// Get the class name
wchar_t classbuf[128];
*classbuf = 0;
parser.GetQueryClass(classbuf, 127);
// Compare to see if it is the association class, Otherwise do an enuemration
if(_wcsicmp(classbuf, INSTANCE_ASSOCIATION_CLASS_STR) != 0)
{
BSTR strClass = SysAllocString((LPWSTR)classbuf);
// Ask CIMOM to postprocess the result
pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_S_NO_ERROR, NULL, NULL);
// Try to process the query myself. If not successful, enumerate
if(SUCCEEDED(result = ProcessInstanceQuery(strClass, strQuery, pCtx, pResponseHandler, &parser)))
{
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() FAILED to process query %s. Resorting to enumeration\r\n", strQuery);
CreateInstanceEnumAsync(strClass, 0, pCtx, pResponseHandler);
}
SysFreeString(strClass);
}
else
{
// Process query for associations
result = ProcessAssociationQuery(pCtx, pResponseHandler, &parser);
}
return WBEM_S_NO_ERROR;
}
HRESULT CLDAPInstanceProvider :: ExecNotificationQuery(
/* [in] */ const BSTR strQueryLanguage,
/* [in] */ const BSTR strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: ExecNotificationQueryAsync(
/* [in] */ const BSTR strQueryLanguage,
/* [in] */ const BSTR strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: 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)
{
return WBEM_E_NOT_SUPPORTED;
}
HRESULT CLDAPInstanceProvider :: ExecMethodAsync(
/* [in] */ const BSTR strObjectPath,
/* [in] */ const BSTR strMethodName,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemClassObject __RPC_FAR *pInParams,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
return WBEM_E_NOT_SUPPORTED;
}
// Maps an ADSI Instance to WBEM
HRESULT CLDAPInstanceProvider :: MapADSIInstance(CADSIInstance *pADSIObject, IWbemClassObject *pWbemObject, IWbemClassObject *pWbemClass)
{
DWORD dwNumAttributes = 0;
PADS_ATTR_INFO pAttributeEntries = pADSIObject->GetAttributes(&dwNumAttributes);
HRESULT result;
for(DWORD i=0; i<dwNumAttributes; i++)
{
PADS_ATTR_INFO pNextAttribute = pAttributeEntries+i;
// Get the WBEM Property Name
LPWSTR pszWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pNextAttribute->pszAttrName);
BSTR strWbemName = SysAllocString(pszWbemName);
delete[] pszWbemName;
// No point in checking the return code, except for logging
if(SUCCEEDED(result = MapPropertyValueToWBEM(strWbemName, pWbemClass, pWbemObject, pNextAttribute)))
{
}
else if( result != WBEM_E_NOT_FOUND )
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() MapPropertyValueToWBEM FAILED with %x for attribute %s\r\n", result, strWbemName);
}
SysFreeString(strWbemName);
}
// Map the key property and other properties of the base-most class
PADS_OBJECT_INFO pObjectInfo = pADSIObject->GetObjectInfo();
if(!SUCCEEDED(result = CWBEMHelper::PutBSTRPropertyT(pWbemObject, ADSI_PATH_STR, pObjectInfo->pszObjectDN, FALSE)))
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() Put FAILED for Key Property with %x\r\n", result);
return S_OK;
}
// Gets the IDIrectoryObject interface on an ADSI instance
HRESULT CLDAPInstanceProvider :: MapPropertyValueToWBEM(BSTR strWbemName, IWbemClassObject *pWbemClass, IWbemClassObject *pWbemObject, PADS_ATTR_INFO pAttribute)
{
// This happens in WMI Stress sometimes.
if(pAttribute->dwADsType == ADSTYPE_INVALID || pAttribute->dwADsType == ADSTYPE_PROV_SPECIFIC)
return E_FAIL;
VARIANT variant;
VariantInit(&variant);
CIMTYPE cimType;
// Get the CIM TYPE of the property
VARIANT dummyUnused;
VariantInit(&dummyUnused);
HRESULT result = pWbemClass->Get(strWbemName, 0, &dummyUnused, &cimType, NULL);
VariantClear(&dummyUnused);
// Whether the value was mapped successfully;
BOOLEAN bMappedValue = FALSE;
if(SUCCEEDED(result))
{
if(cimType & CIM_FLAG_ARRAY)
{
switch(cimType & ~CIM_FLAG_ARRAY)
{
case CIM_BOOLEAN:
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_BOOL, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
for ( long index = 0; index<(long)dwLength; index ++ )
{
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , &(pNextValue->Boolean))))
break;
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_BOOL;
variant.parray = safeArray;
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
break;
}
case CIM_SINT32:
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_I4, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
for ( long index = 0; index<(long)dwLength; index ++ )
{
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , &(pNextValue->Integer))))
break;
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_I4;
variant.parray = safeArray;
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
break;
}
case CIM_SINT64:
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
WCHAR temp[22]; // number of characters for biggest i64 plus sign and terminator
BSTR strTemp = NULL;
for ( long index = 0; index<(long)dwLength; index ++ )
{
swprintf(temp, L"%I64d", (pNextValue->LargeInteger).QuadPart);
strTemp = SysAllocString(temp);
OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
{
break;
}
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_BSTR;
variant.parray = safeArray;
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
break;
}
case CIM_STRING:
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
BSTR strTemp = NULL;
for ( long index = 0; index<(long)dwLength; index ++ )
{
strTemp = SysAllocString(pNextValue->DNString);
OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
{
break;
}
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_BSTR;
variant.parray = safeArray;
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
break;
}
case CIM_DATETIME:
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
BSTR strTemp = NULL;
for ( long index = 0; index<(long)dwLength; index ++ )
{
WBEMTime wbemValue(pNextValue->UTCTime);
strTemp = wbemValue.GetDMTF(TRUE);
OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
{
break;
}
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_BSTR;
variant.parray = safeArray;
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
break;
}
case CIM_OBJECT:
{
// Get its cimType Qualifier to determine the "type" of the embedded object
IWbemQualifierSet *pQualifierSet = NULL;
if(SUCCEEDED(pWbemClass->GetPropertyQualifierSet(strWbemName, &pQualifierSet)))
{
LPWSTR pszQualifierValue = NULL;
if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, CIMTYPE_STR, &pszQualifierValue, NULL)))
{
// Create the safe array elements
SAFEARRAY *safeArray;
DWORD dwLength = pAttribute->dwNumValues;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_UNKNOWN, 1, safeArrayBounds);
PADSVALUE pNextValue = pAttribute->pADsValues;
IUnknown *pNextObject = NULL;
for ( long index = 0; index<(long)dwLength; index ++ )
{
// Put the Embedded object in the array
if(SUCCEEDED(MapEmbeddedObjectToWBEM(pNextValue, pszQualifierValue, &pNextObject)))
{
OnDelete<IUnknown *,VOID(*)(IUnknown *),RM> dm(pNextObject);
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , pNextObject)))
{
break;
}
pNextObject = NULL;
}
else
break;
pNextValue ++;
}
if(SUCCEEDED(result))
{
variant.vt = VT_ARRAY | VT_UNKNOWN;
variant.parray = safeArray;
if(index == (long)dwLength)
bMappedValue = TRUE;
}
else
SafeArrayDestroy(safeArray);
delete[] pszQualifierValue;
}
pQualifierSet->Release();
}
break;
}
default:
break;
}
}
else
{
switch(cimType)
{
case CIM_BOOLEAN:
variant.vt = VT_BOOL;
variant.boolVal = (pAttribute->pADsValues->Boolean)? VARIANT_TRUE : VARIANT_FALSE;
bMappedValue = TRUE;
break;
case CIM_SINT32:
variant.vt = VT_I4;
variant.lVal = pAttribute->pADsValues->Integer;
bMappedValue = TRUE;
break;
case CIM_SINT64:
variant.vt = VT_BSTR;
WCHAR temp[22]; // number of characters for biggest i64 plus sign an terminator
swprintf(temp, L"%I64d", (pAttribute->pADsValues->LargeInteger).QuadPart);
variant.bstrVal = SysAllocString(temp);
bMappedValue = TRUE;
break;
case CIM_STRING:
variant.vt = VT_BSTR;
if(pAttribute->pADsValues->DNString)
{
variant.bstrVal = SysAllocString(pAttribute->pADsValues->DNString);
bMappedValue = TRUE;
}
break;
case CIM_OBJECT:
{
// Get its cimType Qualifier to determine the "type" of the embedded object
IWbemQualifierSet *pQualifierSet = NULL;
if(SUCCEEDED(pWbemClass->GetPropertyQualifierSet(strWbemName, &pQualifierSet)))
{
LPWSTR pszQualifierValue = NULL;
if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, CIMTYPE_STR, &pszQualifierValue, NULL)))
{
IUnknown *pEmbeddedObject = NULL;
if(SUCCEEDED(MapEmbeddedObjectToWBEM(pAttribute->pADsValues, pszQualifierValue, &pEmbeddedObject)))
{
variant.vt = VT_UNKNOWN;
variant.punkVal = pEmbeddedObject;
bMappedValue = TRUE;
}
delete[] pszQualifierValue;
}
pQualifierSet->Release();
}
}
break;
case CIM_DATETIME:
{
variant.vt = VT_BSTR;
WBEMTime wbemValue(pAttribute->pADsValues->UTCTime);
if(variant.bstrVal = wbemValue.GetDMTF(TRUE))
bMappedValue = TRUE;
}
break;
default:
break;
}
}
}
if(bMappedValue && FAILED(result = pWbemObject->Put(strWbemName, 0, &variant, NULL)))
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() Put FAILED for %s with %x\r\n", strWbemName, result);
VariantClear(&variant);
return result;
}
HRESULT CLDAPInstanceProvider :: MapEmbeddedObjectToWBEM(PADSVALUE pAttribute, LPCWSTR pszQualifierName, IUnknown **ppEmbeddedObject)
{
HRESULT result = WBEM_E_FAILED;
// Skip the "object:" prefix while comparing
//===========================================
if (_wcsicmp(pszQualifierName+7, UINT8ARRAY_STR) == 0)
result = MapUint8ArrayToWBEM(pAttribute, ppEmbeddedObject);
else if(_wcsicmp(pszQualifierName+7, DN_WITH_BINARY_CLASS_STR) == 0)
result = MapDNWithBinaryToWBEM(pAttribute, ppEmbeddedObject);
else if (_wcsicmp(pszQualifierName+7, DN_WITH_STRING_CLASS_STR) == 0)
result = MapDNWithStringToWBEM(pAttribute, ppEmbeddedObject);
else
result = E_FAIL;
return result;
}
HRESULT CLDAPInstanceProvider :: MapUint8ArrayToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
{
HRESULT result = E_FAIL;
*ppEmbeddedObject = NULL;
IWbemClassObject *pEmbeddedObject;
if(SUCCEEDED(result = m_pWbemUin8ArrayClass->SpawnInstance(0, &pEmbeddedObject)))
{
if(SUCCEEDED(result = MapByteArray((pAttribute->OctetString).lpValue ,(pAttribute->OctetString).dwLength, VALUE_PROPERTY_STR, pEmbeddedObject)))
{
// Get the IUnknown interface of the embedded object
if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
{
}
}
pEmbeddedObject->Release();
}
return result;
}
HRESULT CLDAPInstanceProvider :: MapByteArray(LPBYTE lpBinaryValue, DWORD dwLength, const BSTR strPropertyName, IWbemClassObject *pInstance)
{
HRESULT result = S_OK;
// Create the safe array of uint8 elements
SAFEARRAY *safeArray = NULL;
SAFEARRAYBOUND safeArrayBounds [ 1 ];
safeArrayBounds[0].lLbound = 0;
safeArrayBounds[0].cElements = dwLength;
safeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBounds);
for ( long index = 0; index<(long)dwLength; index ++ )
{
if(FAILED(result = SafeArrayPutElement ( safeArray , &index , lpBinaryValue+index)))
break;
}
if(SUCCEEDED(result))
{
VARIANT embeddedVariant;
VariantInit(&embeddedVariant);
embeddedVariant.vt = VT_ARRAY | VT_UI1;
embeddedVariant.parray = safeArray;
result = pInstance->Put(strPropertyName, 0, &embeddedVariant, 0);
VariantClear(&embeddedVariant);
}
else
SafeArrayDestroy(safeArray);
return result;
}
HRESULT CLDAPInstanceProvider :: MapDNWithBinaryToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
{
HRESULT result = E_FAIL;
IWbemClassObject *pEmbeddedObject;
if(SUCCEEDED(result = m_pWbemDNWithBinaryClass->SpawnInstance(0, &pEmbeddedObject)))
{
if(pAttribute->pDNWithBinary->pszDNString && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, DN_STRING_PROPERTY_STR, SysAllocString(pAttribute->pDNWithBinary->pszDNString), TRUE)))
{
if(SUCCEEDED(result = MapByteArray(pAttribute->pDNWithBinary->lpBinaryValue, pAttribute->pDNWithBinary->dwLength, VALUE_PROPERTY_STR, pEmbeddedObject)))
{
// Get the IUnknown interface of the embedded object
if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
{
}
}
}
pEmbeddedObject->Release();
}
return result;
}
HRESULT CLDAPInstanceProvider :: MapDNWithStringToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
{
HRESULT result = E_FAIL;
IWbemClassObject *pEmbeddedObject;
if(SUCCEEDED(result = m_pWbemDNWithStringClass->SpawnInstance(0, &pEmbeddedObject)))
{
if(pAttribute->pDNWithString->pszDNString && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, DN_STRING_PROPERTY_STR, SysAllocString(pAttribute->pDNWithString->pszDNString), TRUE)))
{
if(pAttribute->pDNWithString->pszStringValue && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, VALUE_PROPERTY_STR, SysAllocString(pAttribute->pDNWithString->pszStringValue), TRUE)))
{
// Get the IUnknown interface of the embedded object
if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
{
}
}
}
pEmbeddedObject->Release();
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::IsContainedIn
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: IsContainedIn(LPCWSTR pszChildInstance, LPCWSTR pszParentInstance)
{
IDirectoryObject *pDirectoryObject = NULL;
HRESULT result = S_FALSE;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszChildInstance, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pDirectoryObject)))
{
PADS_OBJECT_INFO pObjectInfo = NULL;
if(SUCCEEDED(result = pDirectoryObject->GetObjectInformation(&pObjectInfo)))
{
if(_wcsicmp(pszParentInstance, pObjectInfo->pszParentDN) == 0)
result = S_OK;
else
result = S_FALSE;
FreeADsMem((LPVOID *)pObjectInfo);
}
pDirectoryObject->Release();
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::CreateWBEMInstance
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: CreateWBEMInstance(BSTR strChildName, BSTR strParentName, IWbemClassObject **ppInstance)
{
HRESULT result;
if(SUCCEEDED(result = m_pAssociationsClass->SpawnInstance(0, ppInstance)))
{
// Put the property values
if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, CHILD_INSTANCE_PROPERTY_STR, strChildName, FALSE)))
{
if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, PARENT_INSTANCE_PROPERTY_STR, strParentName, FALSE)))
{
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateWBEMInstance() PutBSTRProperty on parent property FAILED %x \r\n", result);
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateWBEMInstance() PutBSTRProperty on child property FAILED %x \r\n", result);
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::DoChildContainmentQuery
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: DoChildContainmentQuery(LPCWSTR pszChildPath, IWbemObjectSink *pResponseHandler, CNamesList *pListIndicatedSoFar)
{
IDirectoryObject *pChildObject = NULL;
HRESULT result = S_FALSE;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszChildPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pChildObject)))
{
PADS_OBJECT_INFO pChildInfo = NULL;
if(SUCCEEDED(result = pChildObject->GetObjectInformation(&pChildInfo)))
{
IDirectoryObject *pParentObject = NULL;
if(SUCCEEDED(result = ADsOpenObject(pChildInfo->pszParentDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pParentObject)))
{
PADS_OBJECT_INFO pParentInfo = NULL;
if(SUCCEEDED(result = pParentObject->GetObjectInformation(&pParentInfo)))
{
IWbemClassObject *pAssociationInstance = NULL;
// Get the WBEM names of the LDAP classes
LPWSTR pszChildClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pChildInfo->pszClassName);
LPWSTR pszParentClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pParentInfo->pszClassName);
BSTR strChildPath = CWBEMHelper::GetObjectRefFromADSIPath(pszChildPath, pszChildClassWbemName);
BSTR strParentPath = CWBEMHelper::GetObjectRefFromADSIPath(pParentInfo->pszObjectDN, pszParentClassWbemName);
delete [] pszChildClassWbemName;
delete [] pszParentClassWbemName;
// Check to see if it has already been indicated
LPWSTR pszCombinedName = NULL;
if(pszCombinedName = new WCHAR[wcslen(pszChildPath) + wcslen(pParentInfo->pszObjectDN) + 1])
{
wcscpy(pszCombinedName,pszChildPath);
wcscat(pszCombinedName,pParentInfo->pszObjectDN);
if(!pListIndicatedSoFar->IsNamePresent(pszCombinedName))
{
if(SUCCEEDED(result = CreateWBEMInstance(strChildPath, strParentPath, &pAssociationInstance)))
{
result = pResponseHandler->Indicate(1, &pAssociationInstance);
pAssociationInstance->Release();
// Add it to the list of objects indicated so far
pListIndicatedSoFar->AddName(pszCombinedName);
}
}
delete [] pszCombinedName;
}
else
result = E_OUTOFMEMORY;
SysFreeString(strChildPath);
SysFreeString(strParentPath);
FreeADsMem((LPVOID *)pParentInfo);
}
pParentObject->Release();
}
FreeADsMem((LPVOID *)pChildInfo);
}
pChildObject->Release();
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::DoParentContainmentQuery
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: DoParentContainmentQuery(LPCWSTR pszParentPath, IWbemObjectSink *pResponseHandler, CNamesList *pListIndicatedSoFar)
{
// We *have* to use the IADs interfaces since there are no container in
IADsContainer *pContainer = NULL;
IADs *pChild = NULL;
VARIANT variant;
VariantInit(&variant);
HRESULT result;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsContainer, (LPVOID *) &pContainer)))
{
IADs *pParent = NULL;
if(SUCCEEDED(result = pContainer->QueryInterface(IID_IADs, (LPVOID *)&pParent)))
{
BSTR strParentClass = NULL;
if(SUCCEEDED(result = pParent->get_Class(&strParentClass)))
{
// Get the WBEM names of the LDAP class
LPWSTR pszParentClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(strParentClass);
BSTR strParentWBEMPath = CWBEMHelper::GetObjectRefFromADSIPath(pszParentPath, pszParentClassWbemName);
delete [] pszParentClassWbemName;
SysFreeString(strParentClass);
IEnumVARIANT *pEnum = NULL;
if(SUCCEEDED(result = ADsBuildEnumerator(pContainer, &pEnum)))
{
bool bDone = false;
while(!bDone && SUCCEEDED(result = ADsEnumerateNext(pEnum, 1, &variant, NULL)) && result != S_FALSE)
{
if(SUCCEEDED(result = (variant.pdispVal)->QueryInterface(IID_IADs, (LPVOID *)&pChild)))
{
BSTR strChildADSIPath = NULL;
if(SUCCEEDED(result = pChild->get_ADsPath(&strChildADSIPath)))
{
BSTR strChildClass = NULL;
if(SUCCEEDED(result = pChild->get_Class(&strChildClass)))
{
// Create an instance of the association class
IWbemClassObject *pAssociationInstance = NULL;
// Get the WBEM Name oo the child class
LPWSTR pszChildClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(strChildClass);
BSTR strChildWBEMPath = CWBEMHelper::GetObjectRefFromADSIPath(strChildADSIPath, pszChildClassWbemName);
delete [] pszChildClassWbemName;
// Check to see if it has already been indicated
LPWSTR pszCombinedName = NULL;
if(pszCombinedName = new WCHAR[wcslen(strChildADSIPath) + wcslen(pszParentPath) + 1])
{
wcscpy(pszCombinedName,strChildADSIPath);
wcscat(pszCombinedName,pszParentPath);
if(!pListIndicatedSoFar->IsNamePresent(pszCombinedName))
{
if(SUCCEEDED(result = CreateWBEMInstance(strChildWBEMPath, strParentWBEMPath, &pAssociationInstance)))
{
if(FAILED(result = pResponseHandler->Indicate(1, &pAssociationInstance)))
bDone = true;
pAssociationInstance->Release();
// Add it to the list of objects indicated so far
pListIndicatedSoFar->AddName(pszCombinedName);
}
}
delete [] pszCombinedName;
}
else
result = E_OUTOFMEMORY;
SysFreeString(strChildClass);
SysFreeString(strChildWBEMPath);
}
SysFreeString(strChildADSIPath);
}
pChild->Release();
}
VariantClear(&variant);
VariantInit(&variant);
}
ADsFreeEnumerator(pEnum);
}
SysFreeString(strParentWBEMPath);
}
pParent->Release();
}
pContainer->Release();
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::ModifyExistingADSIInstance
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: ModifyExistingADSIInstance(IWbemClassObject *pWbemInstance,
LPCWSTR pszADSIPath,
CADSIInstance *pExistingObject,
LPCWSTR pszADSIClass,
IWbemContext *pCtx)
{
HRESULT result = S_OK;
BOOLEAN bPartialUpdate = FALSE;
DWORD dwPartialUpdateCount = 0;
BSTR *pstrProperyNames = NULL;
SAFEARRAY *pArray = NULL;
// See if the partial property list is indicated in the context
VARIANT v1, v2;
VariantInit(&v1);
VariantInit(&v2);
if(SUCCEEDED(result = pCtx->GetValue(PUT_EXTENSIONS_STR, 0, &v1)))
{
if(SUCCEEDED(result = pCtx->GetValue(PUT_EXT_PROPERTIES_STR, 0, &v2)))
{
switch(v2.vt)
{
case VT_BSTR | VT_ARRAY:
{
pArray = v2.parray;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pstrProperyNames) ) &&
SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
dwPartialUpdateCount = lUbound - lLbound + 1;
bPartialUpdate = TRUE;
}
}
break;
default:
result = WBEM_E_FAILED;
break;
}
}
VariantClear(&v1);
}
else
result = S_OK; // Reset it, there was no request for partial update
if (FAILED(result))
return WBEM_E_FAILED;
// Find the number of properties first by doing an enumeration
if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
{
DWORD dwNumProperties = 0;
while(SUCCEEDED(result = pWbemInstance->Next(0, NULL, NULL, NULL, NULL)) && result != WBEM_S_NO_MORE_DATA )
dwNumProperties ++;
pWbemInstance->EndEnumeration();
// Allocate ADSI structures for these properties
PADS_ATTR_INFO pAttributeEntries = NULL;
if(pAttributeEntries = new ADS_ATTR_INFO [dwNumProperties])
{
// Now go thru each wbem property and map it
if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
{
DWORD dwNumPropertiesMapped = 0;
BSTR strPropertyName = NULL;
VARIANT vPropertyValue;
CIMTYPE cType;
LONG lFlavour;
while(SUCCEEDED(result = pWbemInstance->Next(0, &strPropertyName, &vPropertyValue, &cType, &lFlavour)) && result != WBEM_S_NO_MORE_DATA )
{
// Skip those properties that should not go to ADSI
if(_wcsicmp(strPropertyName, ADSI_PATH_STR) == 0 )
{
}
else // Map the property to ADSI
{
BOOLEAN bMapProperty = FALSE;
if(bPartialUpdate)
{
if(CWBEMHelper::IsPresentInBstrList(pstrProperyNames, dwPartialUpdateCount, strPropertyName))
bMapProperty = TRUE;
}
else
bMapProperty = TRUE;
if(bMapProperty)
{
if(vPropertyValue.vt == VT_NULL)
{
(pAttributeEntries + dwNumPropertiesMapped)->dwControlCode = ADS_ATTR_CLEAR;
(pAttributeEntries + dwNumPropertiesMapped)->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(strPropertyName);
dwNumPropertiesMapped ++;
}
else if(SUCCEEDED(MapPropertyValueToADSI(pWbemInstance, strPropertyName, vPropertyValue, cType, lFlavour, pAttributeEntries + dwNumPropertiesMapped)))
{
// Set the "attribute has been modified" flag
(pAttributeEntries + dwNumPropertiesMapped)->dwControlCode = ADS_ATTR_UPDATE;
dwNumPropertiesMapped ++;
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ModifyExistingADSIInstance() MapPropertyValueToADSI FAILED %x for %s\r\n", result, strPropertyName);
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ModifyExistingADSIInstance() Skipping %s since it is not in Context list\r\n", strPropertyName);
}
SysFreeString(strPropertyName);
VariantClear(&vPropertyValue);
}
pWbemInstance->EndEnumeration();
// Logging
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: The %d attributes being put are:\r\n", dwNumPropertiesMapped);
for(DWORD i=0; i<dwNumPropertiesMapped; i++)
g_pLogObject->WriteW( L"%s\r\n", (pAttributeEntries + i)->pszAttrName);
// Get the actual object from ADSI to find out which attributes have changed.
DWORD dwNumModified = 0;
IDirectoryObject *pDirectoryObject = pExistingObject->GetDirectoryObject();
if(SUCCEEDED(result = pDirectoryObject->SetObjectAttributes(pAttributeEntries, dwNumPropertiesMapped, &dwNumModified)))
{
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: SetObjectAttributes FAILED with %x\r\n", result);
pDirectoryObject->Release();
// Delete the contents of each of the attributes
for(i=0; i<dwNumPropertiesMapped; i++)
{
if((pAttributeEntries + i)->dwControlCode != ADS_ATTR_CLEAR)
CLDAPHelper::DeleteAttributeContents(pAttributeEntries + i);
}
}
delete [] pAttributeEntries;
}
else
result = E_OUTOFMEMORY;
}
if(bPartialUpdate)
{
SafeArrayUnaccessData(pArray);
VariantClear(&v2);
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::CreateNewADSIInstance
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: CreateNewADSIInstance(IWbemClassObject *pWbemInstance, LPCWSTR pszADSIPath, LPCWSTR pszADSIClass)
{
// Find the ADSI path of the parent and the RDN of the child
BSTR strRDNName = NULL;
BSTR strParentADSIPath = NULL;
BSTR strParentADSIPathWithoutLDAP = NULL;
BSTR strParentPlusRDNADSIPath = NULL;
HRESULT result = WBEM_E_FAILED;
// Get the parentADSI path and RDN from the ADSI Path
IADsPathname *pADsPathName = NULL;
BSTR strADSIPath = SysAllocString(pszADSIPath);
if(SUCCEEDED(result = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_ALL, IID_IADsPathname, (LPVOID *)&pADsPathName)))
{
if(SUCCEEDED(result = pADsPathName->Set(strADSIPath, ADS_SETTYPE_FULL)))
{
// This gives "<Parent>" without the "LDAP://" prefix
if(SUCCEEDED(result = pADsPathName->Retrieve(ADS_FORMAT_X500_PARENT, &strParentADSIPathWithoutLDAP)))
{
// This gives "CN=Administrator,<Parent>"
if(SUCCEEDED(result = pADsPathName->Retrieve(ADS_FORMAT_X500_DN, &strParentPlusRDNADSIPath)))
{
// Form the RDN - Dont ignore the comma.
DWORD dwRDNLength = wcslen(strParentPlusRDNADSIPath) - wcslen(strParentADSIPathWithoutLDAP);
LPWSTR pszRDN = NULL;
if(pszRDN = new WCHAR [dwRDNLength])
{
wcsncpy(pszRDN, strParentPlusRDNADSIPath, dwRDNLength-1);
pszRDN[dwRDNLength-1] = NULL;
strRDNName = SysAllocString(pszRDN);
delete [] pszRDN;
}
else
result = E_OUTOFMEMORY;
if(SUCCEEDED(result))
{
LPWSTR pszParentADSIPath = NULL;
if(pszParentADSIPath = new WCHAR[wcslen(strParentADSIPathWithoutLDAP) + wcslen(LDAP_PREFIX) + 1])
{
wcscpy(pszParentADSIPath, LDAP_PREFIX);
wcscat(pszParentADSIPath, strParentADSIPathWithoutLDAP);
strParentADSIPath = SysAllocString(pszParentADSIPath);
delete [] pszParentADSIPath;
}
else
result = E_OUTOFMEMORY;
}
// Find the number of properties first by doing an enumeration
if(SUCCEEDED(result) && SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
{
DWORD dwNumProperties = 0;
while(SUCCEEDED(result = pWbemInstance->Next(0, NULL, NULL, NULL, NULL)) && result != WBEM_S_NO_MORE_DATA )
dwNumProperties ++;
pWbemInstance->EndEnumeration();
// Allocate ADSI structures for these properties. An additional one for the "objectclass" property
PADS_ATTR_INFO pAttributeEntries = NULL;
if(pAttributeEntries = new ADS_ATTR_INFO [dwNumProperties + 1])
{
// Now go thru each wbem property and map it
if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
{
DWORD dwNumPropertiesMapped = 0;
BSTR strPropertyName = NULL;
VARIANT vPropertyValue;
CIMTYPE cType;
LONG lFlavour;
while(SUCCEEDED(result = pWbemInstance->Next(0, &strPropertyName, &vPropertyValue, &cType, &lFlavour)) && result != WBEM_S_NO_MORE_DATA )
{
if(vPropertyValue.vt != VT_NULL)
{
// Skip those properties that should not go to ADSI
if(_wcsicmp(strPropertyName, ADSI_PATH_STR) == 0 ||
_wcsicmp(strPropertyName, OBJECT_CLASS_PROPERTY) == 0)
{
}
else // Map the property to ADSI
{
if(SUCCEEDED(MapPropertyValueToADSI(pWbemInstance, strPropertyName, vPropertyValue, cType, lFlavour, pAttributeEntries + dwNumPropertiesMapped)))
dwNumPropertiesMapped ++;
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateNewADSIInstance() MapPropertyValueToADSI FAILED %x for %s\r\n", result, strPropertyName);
}
}
SysFreeString(strPropertyName);
VariantClear(&vPropertyValue);
}
pWbemInstance->EndEnumeration();
// Set the objectClass attribute too
SetObjectClassAttribute(pAttributeEntries + dwNumPropertiesMapped, pszADSIClass);
dwNumPropertiesMapped++;
// Now get the parent ADSI object
IDirectoryObject *pParentObject = NULL;
if(SUCCEEDED(result = ADsOpenObject(strParentADSIPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *)&pParentObject)))
{
if(SUCCEEDED(result = pParentObject->CreateDSObject(strRDNName, pAttributeEntries, dwNumPropertiesMapped, NULL)))
{
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateDSObject on parent FAILED with %x\r\n", result);
pParentObject->Release();
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ADsOpenObject on parent %s FAILED with %x\r\n", strParentADSIPath, result);
// Delete the contents of each of the attributes
for(DWORD i=0; i<dwNumPropertiesMapped; i++)
CLDAPHelper::DeleteAttributeContents(pAttributeEntries + i);
}
delete [] pAttributeEntries;
}
else
result = E_OUTOFMEMORY;
}
SysFreeString(strParentPlusRDNADSIPath);
SysFreeString(strParentADSIPath);
}
SysFreeString(strParentADSIPathWithoutLDAP);
}
}
pADsPathName->Release();
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CoCreateInstance() on IADsPathName FAILED %x\r\n", result);
SysFreeString(strADSIPath);
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::MapPropertyValueToADSI
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: MapPropertyValueToADSI(IWbemClassObject *pWbemInstance, BSTR strPropertyName, VARIANT vPropertyValue, CIMTYPE cType, LONG lFlavour, PADS_ATTR_INFO pAttributeEntry)
{
// Set its fields to 0;
memset((LPVOID)pAttributeEntry, 0, sizeof(ADS_ATTR_INFO));
HRESULT result = E_FAIL;
// Set the name
pAttributeEntry->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(strPropertyName);
IWbemQualifierSet *pQualifierSet = NULL;
if(SUCCEEDED(result = pWbemInstance->GetPropertyQualifierSet(strPropertyName, &pQualifierSet)))
{
// Get its attributeSyntax qualifer
LPWSTR pszAttributeSyntax = NULL;
if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, ATTRIBUTE_SYNTAX_STR, &pszAttributeSyntax, NULL)))
{
if(_wcsicmp(pszAttributeSyntax, DISTINGUISHED_NAME_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_DN_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, OBJECT_IDENTIFIER_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, CASE_SENSITIVE_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_CASE_EXACT_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_CASE_EXACT_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, CASE_INSENSITIVE_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_CASE_IGNORE_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, PRINT_CASE_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_PRINTABLE_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_PRINTABLE_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, NUMERIC_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_NUMERIC_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_NUMERIC_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, DN_WITH_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_DN_WITH_STRING;
result = SetDNWithStringValues(pAttributeEntry, ADSTYPE_DN_WITH_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, DN_WITH_BINARY_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_DN_WITH_BINARY;
result = SetDNWithBinaryValues(pAttributeEntry, ADSTYPE_DN_WITH_BINARY, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, BOOLEAN_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_BOOLEAN;
result = SetBooleanValues(pAttributeEntry, ADSTYPE_BOOLEAN, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, INTEGER_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_INTEGER;
result = SetIntegerValues(pAttributeEntry, ADSTYPE_INTEGER, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, OCTET_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_OCTET_STRING;
result = SetOctetStringValues(pAttributeEntry, ADSTYPE_OCTET_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, TIME_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
result = SetTimeValues(pAttributeEntry, ADSTYPE_CASE_IGNORE_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, UNICODE_STRING_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, NT_SECURITY_DESCRIPTOR_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
result = SetOctetStringValues(pAttributeEntry, ADSTYPE_NT_SECURITY_DESCRIPTOR, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, LARGE_INTEGER_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_LARGE_INTEGER;
result = SetLargeIntegerValues(pAttributeEntry, ADSTYPE_LARGE_INTEGER, &vPropertyValue);
}
else if(_wcsicmp(pszAttributeSyntax, SID_OID) == 0)
{
pAttributeEntry->dwADsType = ADSTYPE_OCTET_STRING;
result = SetOctetStringValues(pAttributeEntry, ADSTYPE_OCTET_STRING, &vPropertyValue);
}
else
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapPropertyValueToADSI() Unknown attributeSyntax %s\r\n", pszAttributeSyntax);
result = E_FAIL;
}
delete[] pszAttributeSyntax;
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapPropertyValueToADSI() Get on attributeSyntax FAILED %x\r\n", result);
pQualifierSet->Release();
}
return WBEM_S_NO_ERROR;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetStringValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = S_OK;
switch(pvPropertyValue->vt)
{
case VT_BSTR:
{
if(pvPropertyValue->bstrVal)
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->DNString = NULL;
if(pAttributeEntry->pADsValues->DNString = new WCHAR[wcslen(pvPropertyValue->bstrVal) + 1])
wcscpy(pAttributeEntry->pADsValues->DNString, pvPropertyValue->bstrVal);
else
result = E_OUTOFMEMORY;
}
else
result = E_OUTOFMEMORY;
}
}
break;
case VT_BSTR | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
BSTR HUGEP *pbstr;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ))
{
if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
pValues->DNString = NULL;
if(pValues->DNString = new WCHAR[wcslen(pbstr[i]) + 1])
wcscpy(pValues->DNString, pbstr[i]);
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
}
SafeArrayUnaccessData(pArray);
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetIntegerValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetIntegerValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = S_OK;
switch(pvPropertyValue->vt)
{
case VT_I4:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->Integer = pvPropertyValue->lVal;
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_I4 | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
LONG HUGEP *pl;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pl) ) &&
SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
pValues->Integer = pl[i];
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
SafeArrayUnaccessData(pArray);
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetBooleanValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetBooleanValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = S_OK;
switch(pvPropertyValue->vt)
{
case VT_BOOL:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->Boolean = pvPropertyValue->boolVal;
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_BOOL | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
VARIANT_BOOL HUGEP *pb;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pb) ) &&
SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
pValues->Boolean = (pb[i] == VARIANT_TRUE)? TRUE : FALSE;
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
SafeArrayUnaccessData(pArray);
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetOctetStringValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetOctetStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = E_FAIL;
switch(pvPropertyValue->vt)
{
case VT_UNKNOWN:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
// Get the array
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->OctetString.lpValue), &(pAttributeEntry->pADsValues->OctetString.dwLength) )))
{
}
pEmbeddedObject->Release();
}
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_UNKNOWN | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
IUnknown *pNextElement = NULL;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
{
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pValues->OctetString.lpValue), &(pValues->OctetString.dwLength))))
{
}
pEmbeddedObject->Release();
}
pNextElement->Release();
}
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetDNWithStringValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetDNWithStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = E_FAIL;
switch(pvPropertyValue->vt)
{
case VT_UNKNOWN:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->pDNWithString = NULL;
if(pAttributeEntry->pADsValues->pDNWithString = new ADS_DN_WITH_STRING)
{
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithString->pszStringValue) )))
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithString->pszDNString) )))
{
}
}
pEmbeddedObject->Release();
}
}
else
result = E_OUTOFMEMORY;
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_UNKNOWN | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
IUnknown *pNextElement = NULL;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
{
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(pValues->pDNWithString = new ADS_DN_WITH_STRING)
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, VALUE_PROPERTY_STR, &(pValues->pDNWithString->pszStringValue) )))
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pValues->pDNWithString->pszDNString) )))
{
}
}
}
pEmbeddedObject->Release();
}
pNextElement->Release();
}
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetDNWithBinaryValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetDNWithBinaryValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = E_FAIL;
switch(pvPropertyValue->vt)
{
case VT_UNKNOWN:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->pDNWithBinary = NULL;
if(pAttributeEntry->pADsValues->pDNWithBinary = new ADS_DN_WITH_BINARY)
{
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->lpBinaryValue), &(pAttributeEntry->pADsValues->pDNWithBinary->dwLength) )))
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->pszDNString) )))
{
}
}
pEmbeddedObject->Release();
}
}
else
result = E_OUTOFMEMORY;
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_UNKNOWN | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
IUnknown *pNextElement = NULL;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
{
IWbemClassObject *pEmbeddedObject = NULL;
if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
{
if(pValues->pDNWithBinary = new ADS_DN_WITH_BINARY)
{
if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->lpBinaryValue), &(pAttributeEntry->pADsValues->pDNWithBinary->dwLength) )))
{
if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->pszDNString) )))
{
}
}
}
pEmbeddedObject->Release();
}
pNextElement->Release();
}
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetTimeValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetTimeValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = S_OK;
switch(pvPropertyValue->vt)
{
case VT_BSTR:
{
//199880819014734.000000+000 to 19980819014734.0Z to
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
pAttributeEntry->pADsValues->DNString = NULL;
if(pAttributeEntry->pADsValues->DNString = new WCHAR[27])
{
wcscpy(pAttributeEntry->pADsValues->DNString, pvPropertyValue->bstrVal);
(pAttributeEntry->pADsValues->DNString)[16] = L'Z';
(pAttributeEntry->pADsValues->DNString)[17] = NULL;
}
else
result = E_OUTOFMEMORY;
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_BSTR | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
BSTR HUGEP *pbstr;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ) &&
SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
bool bError = false;
for(DWORD i=0; !bError && (i<pAttributeEntry->dwNumValues); i++)
{
pValues->dwType = adType;
pValues->DNString = NULL;
if(pValues->DNString = new WCHAR[27])
{
wcscpy(pValues->DNString, pbstr[i]);
(pValues->DNString)[16] = L'Z';
(pValues->DNString)[17] = NULL;
pValues ++;
}
else
{
bError = true;
result = E_OUTOFMEMORY;
}
}
}
else
result = E_OUTOFMEMORY;
}
SafeArrayUnaccessData(pArray);
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetLargeIntegerValues
//
// Purpose: See Header File
//
//***************************************************************************
HRESULT CLDAPInstanceProvider :: SetLargeIntegerValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
{
HRESULT result = S_OK;
switch(pvPropertyValue->vt)
{
case VT_BSTR:
{
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = adType;
swscanf(pvPropertyValue->bstrVal, L"%I64d", &((pAttributeEntry->pADsValues->LargeInteger).QuadPart));
}
else
result = E_OUTOFMEMORY;
}
break;
case VT_BSTR | VT_ARRAY:
{
SAFEARRAY *pArray = pvPropertyValue->parray;
BSTR HUGEP *pbstr;
LONG lUbound = 0, lLbound = 0;
if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ) &&
SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
{
if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
{
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
{
PADSVALUE pValues = pAttributeEntry->pADsValues;
for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
{
pValues->dwType = adType;
swscanf(pbstr[i], L"%I64d", &((pValues->LargeInteger).QuadPart));
pValues ++;
}
}
else
result = E_OUTOFMEMORY;
}
SafeArrayUnaccessData(pArray);
}
}
break;
default:
return E_FAIL;
}
return result;
}
//***************************************************************************
//
// CLDAPInstanceProvider::SetObjectClassAttribute
//
// Purpose: See Header File
//
//***************************************************************************
void CLDAPInstanceProvider :: SetObjectClassAttribute(PADS_ATTR_INFO pAttributeEntry, LPCWSTR pszADSIClassName)
{
// Set its fields to 0;
memset((LPVOID)pAttributeEntry, 0, sizeof(ADS_ATTR_INFO));
// Set the name
pAttributeEntry->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(OBJECT_CLASS_PROPERTY);
// Set the value
pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
pAttributeEntry->dwNumValues = 1;
pAttributeEntry->pADsValues = NULL;
if(pAttributeEntry->pADsValues = new ADSVALUE)
{
pAttributeEntry->pADsValues->dwType = ADSTYPE_DN_STRING;
pAttributeEntry->pADsValues->DNString = NULL;
if(pAttributeEntry->pADsValues->DNString = new WCHAR[wcslen(pszADSIClassName) + 1])
wcscpy(pAttributeEntry->pADsValues->DNString, pszADSIClassName);
}
}
// Process query for associations
HRESULT CLDAPInstanceProvider :: ProcessAssociationQuery(
IWbemContext __RPC_FAR *pCtx,
IWbemObjectSink __RPC_FAR *pResponseHandler,
SQL1_Parser *pParser)
{
HRESULT result = WBEM_S_NO_ERROR;
// Parse the query
SQL_LEVEL_1_RPN_EXPRESSION *pExp = 0;
if(!pParser->Parse(&pExp))
{
// Check to see that it has exactly 1 or 2 clauses, and
// if 2 clauses are present, these should be different ones, and the operator should be an AND
// This is because we support only the following kinds of queries
// Select * From DS_LDAP_CONTAINMENT_CLASS Where parentInstance = <something>
// Select * From DS_LDAP_CONTAINMENT_CLASS Where childInstance = <something>
// For all other queries, if there is a NOT operator, we do not support it.
// Otherwise we just take the individual clauses and return theri union, asking CIMOM to postprocess
int iNumTokens = pExp->nNumTokens;
// Go thru the tokens to see that NOT is not present
SQL_LEVEL_1_TOKEN *pNextToken = pExp->pArrayOfTokens;
for(int i=0; i<iNumTokens; i++)
{
if(pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::TOKEN_NOT ||
(pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION && pNextToken->nOperator == SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL))
{
result = WBEM_E_PROVIDER_NOT_CAPABLE;
break;
}
pNextToken ++;
}
// No NOT was found
if(result != WBEM_E_PROVIDER_NOT_CAPABLE)
{
// Ask CIMOM to postprocess the result
pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_S_NO_ERROR, NULL, NULL);
// Duplicates need to be avoided. So keep a list of objects indicated so far.
// The key in the list is formed by concatenating the child and parent ADSI paths
//===========================================================================
CNamesList listIndicatedSoFar;
pNextToken = pExp->pArrayOfTokens;
i=0;
while(i<iNumTokens && result != WBEM_E_PROVIDER_NOT_CAPABLE)
{
if(pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION)
{
LPWSTR pszADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pNextToken->vConstValue.bstrVal);
if(_wcsicmp(pNextToken->pPropertyName, CHILD_INSTANCE_PROPERTY_STR) == 0)
{
DoChildContainmentQuery(pszADSIPath, pResponseHandler, &listIndicatedSoFar);
result = WBEM_S_NO_ERROR;
}
else if (_wcsicmp(pNextToken->pPropertyName, PARENT_INSTANCE_PROPERTY_STR) == 0)
{
DoParentContainmentQuery(pszADSIPath, pResponseHandler, &listIndicatedSoFar);
result = WBEM_S_NO_ERROR;
}
else
result = WBEM_E_PROVIDER_NOT_CAPABLE;
delete [] pszADSIPath;
}
i++;
pNextToken ++;
}
}
}
else
result = WBEM_E_FAILED;
delete pExp;
if(SUCCEEDED(result))
{
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
result = WBEM_S_NO_ERROR;
}
else
{
pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_FAILED, NULL, NULL);
result = WBEM_S_NO_ERROR;
}
return result;
}
// Process Query for DS instances
HRESULT CLDAPInstanceProvider :: ProcessInstanceQuery(
BSTR strClass,
BSTR strQuery,
IWbemContext __RPC_FAR *pCtx,
IWbemObjectSink __RPC_FAR *pResponseHandler,
SQL1_Parser *pParser)
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() called for %s Class and query %s\r\n", strClass, strQuery);
HRESULT result = WBEM_E_FAILED;
// Parse the query
SQL_LEVEL_1_RPN_EXPRESSION *pExp = NULL;
if(!pParser->Parse(&pExp))
{
// Fetch the class from CIMOM
IWbemClassObject *pWbemClass = NULL;
if(SUCCEEDED(result = m_IWbemServices->GetObject(strClass, 0, pCtx, &pWbemClass, NULL)))
{
// We need the object category information
LPWSTR pszLDAPQuery = NULL;
int nLength = 6*(2*wcslen(strClass) + 75) + wcslen(strQuery) + 500;
if(pszLDAPQuery = new WCHAR[nLength])
{
pszLDAPQuery[0] = LEFT_BRACKET_STR[0];
pszLDAPQuery[1] = AMPERSAND_STR[0];
pszLDAPQuery[2] = NULL;
if(SUCCEEDED(CWBEMHelper::FormulateInstanceQuery(m_IWbemServices, pCtx, strClass, pWbemClass, pszLDAPQuery + 2, LDAP_DISPLAY_NAME_STR, DEFAULT_OBJECT_CATEGORY_STR)))
{
// Check to see if it can be converted to an LDAP query
if(SUCCEEDED(result = ConvertWQLToLDAPQuery(pExp, pszLDAPQuery, nLength)))
{
// Complete the query string
DWORD dwLen = wcslen(pszLDAPQuery);
pszLDAPQuery[dwLen] = RIGHT_BRACKET_STR[0];
pszLDAPQuery[dwLen + 1] = NULL;
// Check to see if the client has specified any hints as to the DN of the object from
// which the search should start
BOOLEAN bRootDNSpecified = FALSE;
LPWSTR *ppszRootDN = NULL;
DWORD dwRootDNCount = 0;
if(SUCCEEDED(GetRootDN(strClass, &ppszRootDN, &dwRootDNCount, pCtx)) && dwRootDNCount)
bRootDNSpecified = TRUE;
// Enumerate the ADSI Instances
if(bRootDNSpecified)
{
for( DWORD i=0; i<dwRootDNCount; i++)
{
DoSingleQuery(strClass, pWbemClass, ppszRootDN[i], pszLDAPQuery, pResponseHandler);
}
}
else
{
DoSingleQuery(strClass, pWbemClass, m_lpszTopLevelContainerPath, pszLDAPQuery, pResponseHandler);
}
if(bRootDNSpecified)
{
for(DWORD i=0; i<dwRootDNCount; i++)
{
delete [] ppszRootDN[i];
}
delete [] ppszRootDN;
}
}
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FormulateInstanceQuery() on WBEM class %s FAILED with %x on query %s \r\n", strClass, result, strQuery);
}
else
result = E_OUTOFMEMORY;
pWbemClass->Release();
delete [] pszLDAPQuery;
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() Getting WBEM class %s FAILED with %x on query %s \r\n", strClass, result, strQuery);
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() Parse() FAILED on query %s \r\n", strQuery);
delete pExp;
return result;
}
HRESULT CLDAPInstanceProvider :: ConvertWQLToLDAPQuery(SQL_LEVEL_1_RPN_EXPRESSION *pExp, LPWSTR pszLDAPQuery, int nLength)
{
HRESULT result = E_FAIL;
DWORD dwLength = wcslen(pszLDAPQuery);
// Append to the existing string
if(QueryConvertor::ConvertQueryToLDAP(pExp, pszLDAPQuery + dwLength, nLength-dwLength-1))
{
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ConvertWQLToLDAPQuery() Query converted to %s \r\n", pszLDAPQuery);
result = S_OK;
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ConvertWQLToLDAPQuery() FAILED \r\n");
return result;
}
HRESULT CLDAPInstanceProvider :: GetRootDN( LPCWSTR pszClass, LPWSTR **pppszRootDN, DWORD *pdwCount, IWbemContext *pCtx)
{
*pppszRootDN = NULL;
*pdwCount = 0;
HRESULT result = WBEM_E_FAILED;
// For the correct query
LPWSTR pszQuery = new WCHAR[wcslen(pszClass) + wcslen(QUERY_FORMAT) + 10];
swprintf(pszQuery, QUERY_FORMAT, pszClass);
BSTR strQuery = SysAllocString(pszQuery);
delete [] pszQuery;
IEnumWbemClassObject *pEnum = NULL;
if(SUCCEEDED(result = m_IWbemServices->ExecQuery(QUERY_LANGUAGE, strQuery, WBEM_FLAG_BIDIRECTIONAL, pCtx, &pEnum)))
{
// We ignore more than one instance in this implementation
// Walk thru the enumeration and examine each class
IWbemClassObject *pInstance = NULL;
ULONG dwNextReturned = 0;
while(SUCCEEDED(result = pEnum->Next( WBEM_INFINITE, 1, &pInstance, &dwNextReturned)) && dwNextReturned == 1)
{
(*pdwCount)++;
pInstance->Release();
}
if(*pdwCount)
{
if(SUCCEEDED(result = pEnum->Reset()))
{
*pppszRootDN = new LPWSTR[*pdwCount];
DWORD i =0;
while(SUCCEEDED(result = pEnum->Next( WBEM_INFINITE, 1, &pInstance, &dwNextReturned)) && dwNextReturned == 1)
{
// Get the ROOT_DN_PROPERTY, which has the instance
BSTR strInstancePath = NULL;
if(SUCCEEDED(result = CWBEMHelper::GetBSTRProperty(pInstance, ROOT_DN_PROPERTY, &strInstancePath)))
{
// Now get the object
IWbemClassObject *pDNInstance = NULL;
if(SUCCEEDED(result = m_IWbemServices->GetObject(strInstancePath, 0, pCtx, &pDNInstance, NULL)))
{
// Now get the DN_PROPERTY from the instance
BSTR strRootDN = NULL;
if(SUCCEEDED(result = CWBEMHelper::GetBSTRProperty(pDNInstance, DN_PROPERTY, &strRootDN)))
{
(*pppszRootDN)[i] = new WCHAR[wcslen(strRootDN) + 1];
wcscpy((*pppszRootDN)[i], strRootDN);
SysFreeString(strRootDN);
i++;
}
pDNInstance->Release();
}
SysFreeString(strInstancePath);
}
pInstance->Release();
}
*pdwCount = i;
}
}
else
result = WBEM_E_FAILED; // To satisfy the return semantics of the function
pEnum->Release();
}
SysFreeString(strQuery);
return result;
}
// Process query for associations
HRESULT CLDAPInstanceProvider :: ProcessRootDSEGetObject(BSTR strClassName, IWbemObjectSink *pResponseHandler, IWbemContext *pCtx)
{
HRESULT result = E_FAIL;
// First get the object rom ADSI
//==============================
IADs *pADSIRootDSE = NULL;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)ROOT_DSE_PATH, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID *) &pADSIRootDSE)))
{
// Get the class to spawn an instance
IWbemClassObject *pWbemClass = NULL;
if(SUCCEEDED(result = m_IWbemServices->GetObject(strClassName, 0, pCtx, &pWbemClass, NULL)))
{
IWbemClassObject *pWBEMRootDSE = NULL;
// Spawn a instance of the WBEM Class
if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, &pWBEMRootDSE)))
{
// Map it to WBEM
if(SUCCEEDED(result = MapRootDSE(pADSIRootDSE, pWBEMRootDSE)))
{
// Indicate the result
result = pResponseHandler->Indicate(1, &pWBEMRootDSE);
}
pWBEMRootDSE->Release();
}
pWbemClass->Release();
}
pADSIRootDSE->Release();
}
return result;
}
HRESULT CLDAPInstanceProvider :: MapRootDSE(IADs *pADSIRootDSE, IWbemClassObject *pWBEMRootDSE)
{
// Map the properties one-by-one
//=================================
VARIANT variant;
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUBSCHEMASUBENTRY_STR, &variant)))
pWBEMRootDSE->Put(SUBSCHEMASUBENTRY_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SERVERNAME_STR, &variant)))
pWBEMRootDSE->Put(SERVERNAME_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(DEFAULTNAMINGCONTEXT_STR, &variant)))
pWBEMRootDSE->Put(DEFAULTNAMINGCONTEXT_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SCHEMANAMINGCONTEXT_STR, &variant)))
pWBEMRootDSE->Put(SCHEMANAMINGCONTEXT_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(CONFIGURATIONNAMINGCONTEXT_STR, &variant)))
pWBEMRootDSE->Put(CONFIGURATIONNAMINGCONTEXT_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(ROOTDOMAINNAMINGCONTEXT_STR, &variant)))
pWBEMRootDSE->Put(ROOTDOMAINNAMINGCONTEXT_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(CURRENTTIME_STR, &variant)))
pWBEMRootDSE->Put(CURRENTTIME_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDVERSION_STR, &variant)))
CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDVERSION_STR, &variant);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(NAMINGCONTEXTS_STR, &variant)))
CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, NAMINGCONTEXTS_STR, &variant);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDCONTROLS_STR, &variant)))
CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDCONTROLS_STR, &variant);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(DNSHOSTNAME_STR, &variant)))
pWBEMRootDSE->Put(DNSHOSTNAME_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(DSSERVICENAME_STR, &variant)))
pWBEMRootDSE->Put(DSSERVICENAME_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(HIGHESTCOMMITEDUSN_STR, &variant)))
pWBEMRootDSE->Put(HIGHESTCOMMITEDUSN_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(LDAPSERVICENAME_STR, &variant)))
pWBEMRootDSE->Put(LDAPSERVICENAME_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDCAPABILITIES_STR, &variant)))
pWBEMRootDSE->Put(SUPPORTEDCAPABILITIES_STR, 0, &variant, 0);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDLDAPPOLICIES_STR, &variant)))
CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDLDAPPOLICIES_STR, &variant);
VariantClear(&variant);
VariantInit(&variant);
if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDSASLMECHANISMS_STR, &variant)))
CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDSASLMECHANISMS_STR, &variant);
VariantClear(&variant);
return S_OK;
}
HRESULT CLDAPInstanceProvider :: DoSingleQuery(BSTR strClass, IWbemClassObject *pWbemClass, LPCWSTR pszRootDN, LPCWSTR pszLDAPQuery, IWbemObjectSink *pResponseHandler)
{
// Initialize the return values
HRESULT result = E_FAIL;
// Bind to the node from which the search should start
IDirectorySearch *pDirectorySearchContainer = NULL;
if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszRootDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *)&pDirectorySearchContainer)))
{
OnDelete<IUnknown *,void(*)(IUnknown *),RM> dm1(pDirectorySearchContainer);
// Now perform a search for the attribute DISTINGUISHED_NAME_ATTR name
if(SUCCEEDED(result = pDirectorySearchContainer->SetSearchPreference(m_pSearchInfo, 2)))
{
ADS_SEARCH_HANDLE hADSSearchOuter;
if(SUCCEEDED(result = pDirectorySearchContainer->ExecuteSearch((LPWSTR) pszLDAPQuery, (LPWSTR *)&ADS_PATH_ATTR, 1, &hADSSearchOuter)))
{
OnDeleteObj<ADS_SEARCH_HANDLE,
IDirectorySearch,
HRESULT(_stdcall IDirectorySearch::*)(ADS_SEARCH_HANDLE),
&IDirectorySearch::CloseSearchHandle> CloseSHandle(pDirectorySearchContainer,hADSSearchOuter);
bool bDone = false;
// Calculate the number of rows first.
while(!bDone && SUCCEEDED(result = pDirectorySearchContainer->GetNextRow(hADSSearchOuter)) &&
result != S_ADS_NOMORE_ROWS)
{
CADSIInstance *pADSIInstance = NULL;
// Get the columns for the attributes
ADS_SEARCH_COLUMN adsColumn;
// Store each of the LDAP class attributes
if(SUCCEEDED(pDirectorySearchContainer->GetColumn(hADSSearchOuter, (LPWSTR)ADS_PATH_ATTR, &adsColumn)))
{
OnDeleteObj<ADS_SEARCH_COLUMN *,
IDirectorySearch,
HRESULT(_stdcall IDirectorySearch::*)(ADS_SEARCH_COLUMN *),
&IDirectorySearch::FreeColumn> FreeCol(pDirectorySearchContainer,&adsColumn);
if(adsColumn.pADsValues->dwType != ADSTYPE_PROV_SPECIFIC)
{
// Create the CADSIInstance
if(SUCCEEDED(result = CLDAPHelper:: GetADSIInstance(adsColumn.pADsValues->DNString, &pADSIInstance, g_pLogObject)))
{
OnDeleteObj0<CADSIInstance,void(CADSIInstance::*)(),&CADSIInstance::Release> dm(pADSIInstance);
// Spawn a instance of the WBEM Class
IWbemClassObject *pWbemInstance = NULL;
if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, &pWbemInstance)))
{
OnDelete<IUnknown *,void(*)(IUnknown *),RM> dm(pWbemInstance);
// Map it to WBEM
if(SUCCEEDED(result = MapADSIInstance(pADSIInstance, pWbemInstance, pWbemClass)))
{
// Indicate the result
if(FAILED(result = pResponseHandler->Indicate(1, &pWbemInstance)))
{
bDone = true;
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync Indicate() FAILED with %x \r\n", result);
}
}
else
g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync MapADSIInstance() FAILED with %x \r\n", result);
}
}
}
}
}
} // ExecuteSearch()
else
g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery ExecuteSearch() %s FAILED with %x\r\n", pszLDAPQuery, result);
} // SetSearchPreference()
else
g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery SetSearchPreference() on %s FAILED with %x \r\n", pszLDAPQuery, result);
} // ADsOpenObject
else
g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery ADsOpenObject() on %s FAILED with %x \r\n", pszRootDN, result);
return result;
}