|
|
//
// 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; }
|