639 lines
20 KiB
C++
639 lines
20 KiB
C++
//
|
|
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
// ***************************************************************************
|
|
//
|
|
// Original Author: Rajesh Rao
|
|
//
|
|
// $Author: rajeshr $
|
|
// $Date: 6/11/98 4:43p $
|
|
// $Workfile:ldapcach.cpp $
|
|
//
|
|
// $Modtime: 6/11/98 11:21a $
|
|
// $Revision: 1 $
|
|
// $Nokeywords: $
|
|
//
|
|
//
|
|
// Description: Cache for LDAP Schema objects.
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include "precomp.h"
|
|
|
|
// Initialize the statics
|
|
LPCWSTR CLDAPCache :: ROOT_DSE_PATH = L"LDAP://RootDSE";
|
|
LPCWSTR CLDAPCache :: SCHEMA_NAMING_CONTEXT = L"schemaNamingContext";
|
|
LPCWSTR CLDAPCache :: LDAP_PREFIX = L"LDAP://";
|
|
LPCWSTR CLDAPCache :: LDAP_TOP_PREFIX = L"LDAP://CN=top,";
|
|
LPCWSTR CLDAPCache :: RIGHT_BRACKET = L")";
|
|
LPCWSTR CLDAPCache :: OBJECT_CATEGORY_EQUALS_ATTRIBUTE_SCHEMA = L"(objectCategory=attributeSchema)";
|
|
|
|
DWORD CLDAPCache::dwLDAPCacheCount = 0;
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::CLDAPCache
|
|
//
|
|
// Purpose : Constructor. Fills in the cache with all the properties in LDAP.
|
|
//
|
|
// Parameters:
|
|
// dsLog : The CDSLog object onto which logging will be done.
|
|
//***************************************************************************
|
|
|
|
CLDAPCache :: CLDAPCache()
|
|
{
|
|
dwLDAPCacheCount++;
|
|
m_isInitialized = FALSE;
|
|
m_pDirectorySearchSchemaContainer = NULL;
|
|
|
|
// 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_ONELEVEL;
|
|
|
|
m_pSearchInfo[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
|
|
m_pSearchInfo[1].vValue.dwType = ADSTYPE_INTEGER;
|
|
m_pSearchInfo[1].vValue.Integer = 64;
|
|
|
|
/*
|
|
m_pSearchInfo[2].dwSearchPref = ADS_SEARCHPREF_CACHE_RESULTS;
|
|
m_pSearchInfo[2].vValue.dwType = ADSTYPE_BOOLEAN;
|
|
m_pSearchInfo[2].vValue.Boolean = 0;
|
|
*/
|
|
|
|
m_lpszSchemaContainerSuffix = NULL;
|
|
m_lpszSchemaContainerPath = NULL;
|
|
// 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 strSchemaPropertyName = SysAllocString((LPWSTR) SCHEMA_NAMING_CONTEXT);
|
|
|
|
|
|
// Get the schemaNamingContext property. This property contains the ADSI path
|
|
// of the schema container
|
|
VARIANT variant;
|
|
VariantInit(&variant);
|
|
if(SUCCEEDED(result = pRootDSE->Get(strSchemaPropertyName, &variant)))
|
|
{
|
|
// Store the ADSI path to the schema container
|
|
m_lpszSchemaContainerSuffix = NULL;
|
|
if(m_lpszSchemaContainerSuffix = new WCHAR[wcslen(variant.bstrVal) + 1])
|
|
{
|
|
wcscpy(m_lpszSchemaContainerSuffix, variant.bstrVal );
|
|
g_pLogObject->WriteW( L"CLDAPCache :: Got Schema Container as : %s\r\n", m_lpszSchemaContainerSuffix);
|
|
}
|
|
|
|
// Form the schema container path
|
|
//==================================
|
|
m_lpszSchemaContainerPath = NULL;
|
|
if(m_lpszSchemaContainerPath = new WCHAR[wcslen(LDAP_PREFIX) + wcslen(m_lpszSchemaContainerSuffix) + 1])
|
|
{
|
|
wcscpy(m_lpszSchemaContainerPath, LDAP_PREFIX);
|
|
wcscat(m_lpszSchemaContainerPath, m_lpszSchemaContainerSuffix);
|
|
|
|
m_isInitialized = TRUE;
|
|
/*
|
|
if(SUCCEEDED(result = ADsOpenObject(m_lpszSchemaContainerPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *) &m_pDirectorySearchSchemaContainer)))
|
|
{
|
|
|
|
g_pLogObject->WriteW( L"CLDAPCache :: Got IDirectorySearch on Schema Container \r\n");
|
|
|
|
if(SUCCEEDED(result = InitializeObjectTree()))
|
|
{
|
|
m_isInitialized = TRUE;
|
|
}
|
|
else
|
|
g_pLogObject->WriteW( L"CLDAPCache :: InitializeObjectTree() FAILED : %x \r\n", result);
|
|
}
|
|
else
|
|
g_pLogObject->WriteW( L"CLDAPCache :: FAILED to get IDirectorySearch on Schema Container : %x\r\n", result);
|
|
*/
|
|
}
|
|
}
|
|
else
|
|
g_pLogObject->WriteW( L"CLDAPCache :: Get on RootDSE FAILED : %x\r\n", result);
|
|
|
|
SysFreeString(strSchemaPropertyName);
|
|
VariantClear(&variant);
|
|
pRootDSE->Release();
|
|
|
|
}
|
|
else
|
|
g_pLogObject->WriteW( L"CLDAPClassProvider :: InitializeLDAPProvider ADsOpenObject on RootDSE FAILED : %x\r\n", result);
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::~CLDAPCache
|
|
//
|
|
// Purpose : Destructor
|
|
//
|
|
//***************************************************************************
|
|
|
|
CLDAPCache :: ~CLDAPCache()
|
|
{
|
|
dwLDAPCacheCount--;
|
|
if(m_pDirectorySearchSchemaContainer)
|
|
m_pDirectorySearchSchemaContainer->Release();
|
|
|
|
delete [] m_lpszSchemaContainerSuffix;
|
|
delete [] m_lpszSchemaContainerPath;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::GetProperty
|
|
//
|
|
// Purpose : Retreives the IDirectory interface of an LDAP property
|
|
//
|
|
// Parameters:
|
|
// lpszPropertyName : The name of the LDAP Property to be retreived
|
|
// ppADSIProperty : The address of the pointer where the CADSIProperty object will be placed
|
|
// bWBEMName : True if the lpszPropertyName is the WBEM name. False, if it is the LDAP name
|
|
//
|
|
// Return value:
|
|
// The COM value representing the return status. The user should release the object when done.
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CLDAPCache :: GetProperty(LPCWSTR lpszPropertyName, CADSIProperty **ppADSIProperty, BOOLEAN bWBEMName)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
|
|
// Get the LDAP property name from the WBEM class name
|
|
LPWSTR lpszLDAPPropertyName = NULL;
|
|
if(bWBEMName)
|
|
lpszLDAPPropertyName = CLDAPHelper::UnmangleWBEMNameToLDAP(lpszPropertyName);
|
|
else
|
|
lpszLDAPPropertyName = (LPWSTR)lpszPropertyName; // Save a copy by casting, be careful when deleting
|
|
|
|
try
|
|
{
|
|
// This is a cached implementation
|
|
// Check the object tree first
|
|
//===================================
|
|
|
|
if((*ppADSIProperty) = (CADSIProperty *) m_objectTree.GetElement(lpszLDAPPropertyName))
|
|
{
|
|
// Found it in the tree. Nothing more to be done. It has already been 'addreff'ed
|
|
result = S_OK;
|
|
}
|
|
else // Get it from ADSI
|
|
{
|
|
if(!m_pDirectorySearchSchemaContainer)
|
|
{
|
|
if(!SUCCEEDED(result = ADsOpenObject(m_lpszSchemaContainerPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *) &m_pDirectorySearchSchemaContainer)))
|
|
result = E_FAIL;
|
|
}
|
|
else
|
|
result = S_OK;
|
|
|
|
if(SUCCEEDED(result))
|
|
{
|
|
// Search for the property
|
|
LPWSTR lpszQuery = NULL;
|
|
if(lpszQuery = new WCHAR[ wcslen(OBJECT_CATEGORY_EQUALS_ATTRIBUTE_SCHEMA) + wcslen(LDAP_DISPLAY_NAME_ATTR) + wcslen(lpszLDAPPropertyName) + 20])
|
|
{
|
|
try
|
|
{
|
|
wcscpy(lpszQuery, LEFT_BRACKET_STR);
|
|
wcscat(lpszQuery, AMPERSAND_STR);
|
|
wcscat(lpszQuery, OBJECT_CATEGORY_EQUALS_ATTRIBUTE_SCHEMA);
|
|
wcscat(lpszQuery, LEFT_BRACKET_STR);
|
|
wcscat(lpszQuery, LDAP_DISPLAY_NAME_ATTR);
|
|
wcscat(lpszQuery, EQUALS_STR);
|
|
wcscat(lpszQuery, lpszLDAPPropertyName);
|
|
wcscat(lpszQuery, RIGHT_BRACKET_STR);
|
|
wcscat(lpszQuery, RIGHT_BRACKET_STR);
|
|
|
|
ADS_SEARCH_HANDLE hADSSearchOuter;
|
|
if(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->ExecuteSearch(lpszQuery, NULL, -1, &hADSSearchOuter)))
|
|
{
|
|
try
|
|
{
|
|
if(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetNextRow(hADSSearchOuter)) &&
|
|
result != S_ADS_NOMORE_ROWS)
|
|
{
|
|
*ppADSIProperty = NULL;
|
|
if(*ppADSIProperty = new CADSIProperty())
|
|
{
|
|
try
|
|
{
|
|
// Fill in the details of the property
|
|
if(SUCCEEDED(result = FillInAProperty(*ppADSIProperty, hADSSearchOuter)))
|
|
{
|
|
// Add the property to the tree
|
|
m_objectTree.AddElement((*ppADSIProperty)->GetADSIPropertyName(), *ppADSIProperty);
|
|
// No need to release it since we're returning it
|
|
}
|
|
else
|
|
{
|
|
delete *ppADSIProperty;
|
|
*ppADSIProperty = NULL;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete *ppADSIProperty;
|
|
*ppADSIProperty = NULL;
|
|
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
m_pDirectorySearchSchemaContainer->CloseSearchHandle(hADSSearchOuter);
|
|
throw;
|
|
}
|
|
|
|
m_pDirectorySearchSchemaContainer->CloseSearchHandle(hADSSearchOuter);
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete [] lpszQuery;
|
|
throw;
|
|
}
|
|
|
|
delete [] lpszQuery;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if(bWBEMName)
|
|
{
|
|
delete[] lpszLDAPPropertyName;
|
|
lpszLDAPPropertyName = NULL;
|
|
}
|
|
throw;
|
|
}
|
|
|
|
// Delete only what was allocated in this function
|
|
//================================================
|
|
if(bWBEMName)
|
|
{
|
|
delete[] lpszLDAPPropertyName;
|
|
lpszLDAPPropertyName = NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::GetClass
|
|
//
|
|
// Purpose : See Header File
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CLDAPCache :: GetClass(LPCWSTR lpszWBEMClassName, LPCWSTR lpszLDAPClassName, CADSIClass **ppADSIClass)
|
|
{
|
|
/************************************************************
|
|
*************************************************************
|
|
***** NO Cache implementation for now. Always fetch everytime
|
|
*************************************************************
|
|
*************************************************************/
|
|
|
|
*ppADSIClass = NULL;
|
|
if(!(*ppADSIClass = new CADSIClass(lpszWBEMClassName, lpszLDAPClassName)) )
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
HRESULT result = E_FAIL;
|
|
|
|
try
|
|
{
|
|
if(!m_pDirectorySearchSchemaContainer)
|
|
{
|
|
if(!SUCCEEDED(result = ADsOpenObject(m_lpszSchemaContainerPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *) &m_pDirectorySearchSchemaContainer)))
|
|
result = E_FAIL;
|
|
}
|
|
else
|
|
result = S_OK;
|
|
|
|
if(SUCCEEDED(result))
|
|
{
|
|
result = CLDAPHelper::GetLDAPClassFromLDAPName(m_pDirectorySearchSchemaContainer,
|
|
m_lpszSchemaContainerSuffix,
|
|
m_pSearchInfo,
|
|
2,
|
|
*ppADSIClass
|
|
);
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
// at least GetLDAPClassFromLDAPName throws
|
|
delete *ppADSIClass;
|
|
*ppADSIClass = NULL;
|
|
|
|
throw;
|
|
}
|
|
|
|
if(!SUCCEEDED(result))
|
|
{
|
|
delete *ppADSIClass;
|
|
*ppADSIClass = NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::GetSchemaContainerSearch
|
|
//
|
|
// Purpose : To return the IDirectorySearch interface on the schema container
|
|
//
|
|
// Parameters:
|
|
// ppDirectorySearch : The address where the pointer to the required interface will
|
|
// be stored.
|
|
//
|
|
//
|
|
// Return Value: The COM result representing the status. The user should release
|
|
// the interface pointer when done with it.
|
|
//***************************************************************************
|
|
HRESULT CLDAPCache :: GetSchemaContainerSearch(IDirectorySearch ** ppDirectorySearch)
|
|
{
|
|
if(m_pDirectorySearchSchemaContainer)
|
|
{
|
|
*ppDirectorySearch = m_pDirectorySearchSchemaContainer;
|
|
(*ppDirectorySearch)->AddRef();
|
|
return S_OK;
|
|
}
|
|
else
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::EnumerateClasses
|
|
//
|
|
// Purpose : See Header
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CLDAPCache::EnumerateClasses(LPCWSTR lpszWBEMSuperclass,
|
|
BOOLEAN bDeep,
|
|
LPWSTR **pppADSIClasses,
|
|
DWORD *pdwNumRows,
|
|
BOOLEAN bArtificialClass)
|
|
{
|
|
// Get the LDAP name of the super class
|
|
// Do not mangle if it one of the classes that we know
|
|
//=====================================================
|
|
LPWSTR lpszLDAPSuperClassName = NULL;
|
|
if(_wcsicmp(lpszWBEMSuperclass, LDAP_BASE_CLASS) != 0)
|
|
{
|
|
lpszLDAPSuperClassName = CLDAPHelper::UnmangleWBEMNameToLDAP(lpszWBEMSuperclass);
|
|
if(!lpszLDAPSuperClassName) // We were returned a NULL by the Unmangler, so not a DS class
|
|
{
|
|
*pppADSIClasses = NULL;
|
|
*pdwNumRows = 0;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
HRESULT result = E_FAIL;
|
|
if(!m_pDirectorySearchSchemaContainer)
|
|
{
|
|
if(!SUCCEEDED(result = ADsOpenObject(m_lpszSchemaContainerPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *) &m_pDirectorySearchSchemaContainer)))
|
|
result = E_FAIL;
|
|
}
|
|
else
|
|
result = S_OK;
|
|
|
|
if(SUCCEEDED(result))
|
|
{
|
|
result = CLDAPHelper::EnumerateClasses(m_pDirectorySearchSchemaContainer,
|
|
m_lpszSchemaContainerSuffix,
|
|
m_pSearchInfo,
|
|
2,
|
|
lpszLDAPSuperClassName,
|
|
bDeep,
|
|
pppADSIClasses,
|
|
pdwNumRows,
|
|
bArtificialClass);
|
|
}
|
|
|
|
// If the superclass is an artificial class like "ADS_User", then a concrete sub-class "DS_User" exists.
|
|
// This is added manually here, to both the EnumInfoList as well as the structure being returned
|
|
// The above call to EnumerateClasses would have helpfully left an extra element unfilled at the beginning
|
|
// of the array
|
|
if(SUCCEEDED(result) && bArtificialClass)
|
|
{
|
|
(*pppADSIClasses)[0] = NULL;
|
|
if((*pppADSIClasses)[0] = new WCHAR[wcslen(lpszWBEMSuperclass+1) + 1])
|
|
wcscpy((*pppADSIClasses)[0], lpszWBEMSuperclass+1);
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
}
|
|
|
|
delete[] lpszLDAPSuperClassName;
|
|
return result;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache::IsInitialized
|
|
//
|
|
// Purpose : Indicates whether the cache was created and initialized succeddfully
|
|
//
|
|
// Parameters:
|
|
// None
|
|
//
|
|
// Return value:
|
|
// A boolean value indicating the status
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOLEAN CLDAPCache :: IsInitialized()
|
|
{
|
|
return m_isInitialized;
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CLDAPCache :: InitializeObjectTree
|
|
//
|
|
// Purpose : Initialize the lexically ordered binary tree with all the properties
|
|
// LDAP
|
|
//
|
|
// Parameters:
|
|
// None
|
|
//
|
|
// Return Value: The COM status representing the return value
|
|
//***************************************************************************
|
|
|
|
HRESULT CLDAPCache :: InitializeObjectTree()
|
|
{
|
|
// Get the attributes of all the instances of the
|
|
// class "AttributeSchema"
|
|
//=================================================
|
|
HRESULT result = E_FAIL;
|
|
|
|
/*
|
|
// Now perform a search for all the attributes
|
|
//============================================
|
|
if(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->SetSearchPreference(m_pSearchInfo, 2)))
|
|
{
|
|
ADS_SEARCH_HANDLE hADSSearchOuter;
|
|
|
|
// Count of attributes
|
|
DWORD dwCount = 0;
|
|
|
|
if(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->ExecuteSearch((LPWSTR)OBJECT_CATEGORY_EQUALS_ATTRIBUTE_SCHEMA, NULL, -1, &hADSSearchOuter)))
|
|
{
|
|
CADSIProperty *pNextProperty;
|
|
while(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetNextRow(hADSSearchOuter)) &&
|
|
result != S_ADS_NOMORE_ROWS)
|
|
{
|
|
pNextProperty = new CADSIProperty();
|
|
dwCount ++;
|
|
|
|
// Fill in the details of the property
|
|
FillInAProperty(pNextProperty, hADSSearchOuter);
|
|
|
|
// Add the property to the tree
|
|
m_objectTree.AddElement(pNextProperty->GetADSIPropertyName(), pNextProperty);
|
|
pNextProperty->Release();
|
|
}
|
|
m_pDirectorySearchSchemaContainer->CloseSearchHandle(hADSSearchOuter);
|
|
}
|
|
|
|
g_pLogObject->WriteW( L"CLDAPCache :: InitializeObjectTree() Initialized with %d attributes\r\n", dwCount);
|
|
}
|
|
else
|
|
g_pLogObject->WriteW( L"CLDAPCache :: InitializeObjectTree() SetSearchPreference() FAILED with %x\r\n", result);
|
|
|
|
*/
|
|
return result;
|
|
}
|
|
|
|
HRESULT CLDAPCache :: FillInAProperty(CADSIProperty *pNextProperty, ADS_SEARCH_HANDLE hADSSearchOuter)
|
|
{
|
|
ADS_SEARCH_COLUMN adsNextColumn;
|
|
HRESULT result = E_FAIL;
|
|
LPWSTR lpszWBEMName = NULL;
|
|
BOOLEAN bNeedToCheckForORName = FALSE;
|
|
if(SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)ATTRIBUTE_SYNTAX_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
{
|
|
pNextProperty->SetSyntaxOID(adsNextColumn.pADsValues->CaseIgnoreString);
|
|
if(_wcsicmp(adsNextColumn.pADsValues->CaseIgnoreString, DN_WITH_BINARY_OID) == 0)
|
|
bNeedToCheckForORName = TRUE;
|
|
}
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)IS_SINGLE_VALUED_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetMultiValued( (adsNextColumn.pADsValues->Boolean)? FALSE : TRUE);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)ATTRIBUTE_ID_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetAttributeID(adsNextColumn.pADsValues->CaseIgnoreString);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)COMMON_NAME_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetCommonName(adsNextColumn.pADsValues->CaseIgnoreString);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)LDAP_DISPLAY_NAME_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
{
|
|
pNextProperty->SetADSIPropertyName(adsNextColumn.pADsValues->CaseIgnoreString);
|
|
lpszWBEMName = CLDAPHelper::MangleLDAPNameToWBEM(adsNextColumn.pADsValues->CaseIgnoreString);
|
|
pNextProperty->SetWBEMPropertyName(lpszWBEMName);
|
|
delete []lpszWBEMName;
|
|
}
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)MAPI_ID_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetMAPI_ID(adsNextColumn.pADsValues->Integer);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(result = m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)OM_SYNTAX_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetOMSyntax(adsNextColumn.pADsValues->Integer);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(bNeedToCheckForORName && SUCCEEDED(result) && SUCCEEDED(m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)OM_OBJECT_CLASS_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
{
|
|
// Just the first octet in the LPBYTE array is enough for differntiating between ORName and DNWithBinary
|
|
if((adsNextColumn.pADsValues->OctetString).lpValue[0] == 0x56)
|
|
pNextProperty->SetORName(TRUE);
|
|
}
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)SEARCH_FLAGS_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetSearchFlags(adsNextColumn.pADsValues->Integer);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
if(SUCCEEDED(result) && SUCCEEDED(m_pDirectorySearchSchemaContainer->GetColumn( hADSSearchOuter, (LPWSTR)SYSTEM_ONLY_ATTR, &adsNextColumn )))
|
|
{
|
|
if(adsNextColumn.dwADsType == ADSTYPE_PROV_SPECIFIC)
|
|
result = E_FAIL;
|
|
else
|
|
pNextProperty->SetSystemOnly(TRUE);
|
|
m_pDirectorySearchSchemaContainer->FreeColumn( &adsNextColumn );
|
|
}
|
|
|
|
return result;
|
|
} |