|
|
//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: putget.cxx
//
// Contents:
//
//
// History: 01-14-97 krishnaG Created.
//
//----------------------------------------------------------------------------
#include "ldap.hxx"
#pragma hdrstop
STDMETHODIMP CLDAPGenObject::Get( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwStatus = 0; LDAPOBJECTARRAY ldapSrcObjects;
LDAPOBJECTARRAY_INIT(ldapSrcObjects);
//
// Make sure that the last error is reset
//
Macro_ClearADsLastError(L"LDAP Provider");
//
// In case some person decides to randomize us with a NULL
//
if (!pvProp || !bstrName) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
//
// retrieve data object from cache; if one exists
//
if ( GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = _pPropertyCache->unboundgetproperty( bstrName, &dwSyntaxId, &dwStatus, &ldapSrcObjects );
// For backward compatibility
if (!ldapSrcObjects.pLdapObjects && SUCCEEDED(hr)) { hr = E_FAIL; }
} else {
hr = _pPropertyCache->getproperty( bstrName, &dwSyntaxId, &dwStatus, &ldapSrcObjects );
// this will make sure we do not break existing code
if (!ldapSrcObjects.pLdapObjects && SUCCEEDED(hr)) { hr = E_ADS_PROPERTY_NOT_FOUND; }
}
BAIL_ON_FAILURE(hr);
//
// translate the Ldap objects to variants
//
if ( ldapSrcObjects.dwCount == 1 ) {
hr = LdapTypeToVarTypeCopy( _pszLDAPServer, _Credentials, ldapSrcObjects.pLdapObjects, dwSyntaxId, pvProp ); } else {
hr = LdapTypeToVarTypeCopyConstruct( _pszLDAPServer, _Credentials, ldapSrcObjects, dwSyntaxId, pvProp ); } BAIL_ON_FAILURE(hr);
error:
LdapTypeFreeLdapObjects( &ldapSrcObjects );
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CLDAPGenObject::Put( THIS_ BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0;
DWORD dwIndex = 0; LDAPOBJECTARRAY ldapDestObjects;
DWORD dwNumValues = 0; VARIANT * pVarArray = NULL; VARIANT * pvProp = NULL; BOOL fIndexValid = TRUE;
LDAPOBJECTARRAY_INIT(ldapDestObjects);
//
// Make sure that the last error is reset
//
Macro_ClearADsLastError(L"LDAP Provider");
//
// In case some person decides to randomize us with a NULL
//
if (!bstrName) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
//
// A VT_BYREF|VT_VARIANT may expand to a VT_VARIANT|VT_ARRAY.
// We should dereference a VT_BYREF|VT_VARIANT once and see
// what's inside.
//
pvProp = &vProp; if (V_VT(pvProp) == (VT_BYREF|VT_VARIANT)) { pvProp = V_VARIANTREF(&vProp); }
if ((V_VT(pvProp) & VT_VARIANT) && V_ISARRAY(pvProp) && V_ISBYREF(pvProp)){
hr = ConvertByRefSafeArrayToVariantArray( *pvProp, &pVarArray, &dwNumValues ); BAIL_ON_FAILURE(hr); pvProp = pVarArray;
}else if ((V_VT(pvProp) & VT_VARIANT) && V_ISARRAY(pvProp)) {
hr = ConvertSafeArrayToVariantArray( *pvProp, &pVarArray, &dwNumValues ); // returns E_FAIL if *pvProp is invalid
if (hr == E_FAIL) hr = E_ADS_BAD_PARAMETER; BAIL_ON_FAILURE(hr); pvProp = pVarArray;
} else {
dwNumValues = 1; }
if (pvProp == NULL) { dwSyntaxId = LDAPTYPE_UNKNOWN; } else {
hr = GetLdapSyntaxFromVariant( pvProp, &dwSyntaxId, _pszLDAPServer, bstrName, _Credentials, _dwPort );
BAIL_ON_FAILURE(hr);
if ( dwSyntaxId == LDAPTYPE_UNKNOWN ) { hr = E_ADS_CANT_CONVERT_DATATYPE; BAIL_ON_FAILURE(hr); } }
if (!_wcsicmp(bstrName, L"ntSecurityDescriptor")){ dwSyntaxId = LDAPTYPE_SECURITY_DESCRIPTOR; }
#if 0
//
// check if this is a legal property for this object,
//
// No Schema??
// mattrim 5/16/00 - doesn't matter if no schema since
// this isn't getting built, it's #if'ed out
//
hr = ValidatePropertyinCache( szLDAPTreeName, _ADsClass, bstrName, &dwSyntaxId ); BAIL_ON_FAILURE(hr); #endif
//
// check if the variant maps to the syntax of this property
//
if ( dwNumValues > 0 ) { hr = VarTypeToLdapTypeCopyConstruct( _pszLDAPServer, _Credentials, dwSyntaxId, pvProp, dwNumValues, &ldapDestObjects ); BAIL_ON_FAILURE(hr); }
//
// Find this property in the cache
//
hr = _pPropertyCache->findproperty( bstrName, &dwIndex );
//
// If this property does not exist in the
// cache, add this property into the cache.
//
if (FAILED(hr)) {
hr = _pPropertyCache->addproperty( bstrName );
//
// If dwNumValues == 0 ( delete the property ) but couldn't find
// the property, or if the add operation fails, return the error.
//
BAIL_ON_FAILURE(hr);
// Set the flag as the dwIndex is not valid in this case
fIndexValid = FALSE; }
//
// Now update the property in the cache
//
if (fIndexValid) { // do an optimized put
hr = _pPropertyCache->putproperty( dwIndex, PROPERTY_UPDATE, dwSyntaxId, ldapDestObjects ); } else {
// Index is not valid so let the cache figure it out.
hr = _pPropertyCache->putproperty( bstrName, PROPERTY_UPDATE, dwSyntaxId, ldapDestObjects ); }
BAIL_ON_FAILURE(hr);
error:
LdapTypeFreeLdapObjects( &ldapDestObjects );
if (pVarArray) {
DWORD i = 0;
for (i = 0; i < dwNumValues; i++) { VariantClear(pVarArray + i); } FreeADsMem(pVarArray); }
RRETURN(hr); }
STDMETHODIMP CLDAPGenObject::GetEx( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwStatus = 0; LDAPOBJECTARRAY ldapSrcObjects;
LDAPOBJECTARRAY_INIT(ldapSrcObjects);
//
// Make sure that the last error is reset
//
Macro_ClearADsLastError(L"LDAP Provider");
//
// For those who know no not what they do
//
if (!pvProp || !bstrName) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
//
// retrieve data object from cache; if one exists
//
if ( GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = _pPropertyCache->unboundgetproperty( bstrName, &dwSyntaxId, &dwStatus, &ldapSrcObjects );
// this will make sure we do not break existing code
if (!ldapSrcObjects.pLdapObjects && SUCCEEDED(hr)) { hr = E_FAIL; }
} else {
hr = _pPropertyCache->getproperty( bstrName, &dwSyntaxId, &dwStatus, &ldapSrcObjects );
// this will make sure we do not break existing code
if (!ldapSrcObjects.pLdapObjects && SUCCEEDED(hr)) { hr = E_ADS_PROPERTY_NOT_FOUND; }
}
BAIL_ON_FAILURE(hr);
//
// translate the Ldap objects to variants
//
hr = LdapTypeToVarTypeCopyConstruct( _pszLDAPServer, _Credentials, ldapSrcObjects, dwSyntaxId, pvProp ); BAIL_ON_FAILURE(hr);
error: LdapTypeFreeLdapObjects( &ldapSrcObjects );
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CLDAPGenObject::PutEx( THIS_ long lnControlCode, BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0; DWORD dwFlags = 0;
DWORD dwIndex = 0; LDAPOBJECTARRAY ldapDestObjects;
DWORD dwNumValues = 0; VARIANT * pVarArray = NULL; VARIANT * pvProp = NULL; BOOL fIndexValid = TRUE;
LDAPOBJECTARRAY_INIT(ldapDestObjects);
//
// Make sure that the last error is reset
//
Macro_ClearADsLastError(L"LDAP Provider");
//
// In case some person decides to randomize us with a NULL
//
if (!bstrName) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
switch ( lnControlCode ) { case ADS_PROPERTY_CLEAR: dwFlags = PROPERTY_DELETE; break;
case ADS_PROPERTY_UPDATE: dwFlags = PROPERTY_UPDATE; break;
case ADS_PROPERTY_APPEND: dwFlags = PROPERTY_ADD; break;
case ADS_PROPERTY_DELETE: dwFlags = PROPERTY_DELETE_VALUE; break;
default: RRETURN_EXP_IF_ERR(hr = E_ADS_BAD_PARAMETER); }
if ( dwFlags != PROPERTY_DELETE ) { //
// A VT_BYREF|VT_VARIANT may expand to a VT_VARIANT|VT_ARRAY.
// We should dereference a VT_BYREF|VT_VARIANT once and see
// what's inside.
//
pvProp = &vProp;
if (V_VT(pvProp) == (VT_BYREF|VT_VARIANT)) { pvProp = V_VARIANTREF(&vProp); }
if ((V_VT(pvProp) == (VT_VARIANT|VT_ARRAY|VT_BYREF)) || (V_VT(pvProp) == (VT_VARIANT|VT_ARRAY))) {
hr = ConvertSafeArrayToVariantArray( *pvProp, &pVarArray, &dwNumValues ); // returns E_FAIL if *pvProp is invalid
if (hr == E_FAIL) hr = E_ADS_BAD_PARAMETER; BAIL_ON_FAILURE(hr); pvProp = pVarArray;
} else {
hr = E_FAIL; BAIL_ON_FAILURE(hr); }
if (pvProp == NULL) { //
// If array is empty, set dwSyntaxId to Unknown. This value will not be used
//
dwSyntaxId = LDAPTYPE_UNKNOWN; } else {
hr = GetLdapSyntaxFromVariant( pvProp, &dwSyntaxId, _pszLDAPServer, bstrName, _Credentials, _dwPort );
BAIL_ON_FAILURE(hr);
if ( dwSyntaxId == LDAPTYPE_UNKNOWN ) { //
// If array is empty, set dwSyntaxId to Unknown. This value will
// not be used
//
hr = E_ADS_CANT_CONVERT_DATATYPE; BAIL_ON_FAILURE(hr); } }
//
// check if the variant maps to the syntax of this property
//
if ( dwNumValues > 0 ) { hr = VarTypeToLdapTypeCopyConstruct( _pszLDAPServer, _Credentials, dwSyntaxId, pvProp, dwNumValues, &ldapDestObjects ); BAIL_ON_FAILURE(hr); } }
//
// Find this property in the cache
//
hr = _pPropertyCache->findproperty( bstrName, &dwIndex );
//
// If this property does not exist in the
// cache, add this property into the cache.
//
if (FAILED(hr)) {
hr = _pPropertyCache->addproperty( bstrName );
//
// If dwNumValues == 0 ( delete the property ) but couldn't find
// the property, or if the add operation fails, return the error.
//
BAIL_ON_FAILURE(hr); fIndexValid = FALSE; }
//
// Now update the property in the cache
//
if (fIndexValid) {
// do an optimized put property with the index
hr = _pPropertyCache->putproperty( dwIndex, dwFlags, dwSyntaxId, ldapDestObjects ); } else {
// we need to use the property name in this case
hr = _pPropertyCache->putproperty( bstrName, dwFlags, dwSyntaxId, ldapDestObjects ); }
BAIL_ON_FAILURE(hr);
error:
LdapTypeFreeLdapObjects( &ldapDestObjects );
if (pVarArray) {
DWORD i = 0;
for (i = 0; i < dwNumValues; i++) { VariantClear(pVarArray + i); } FreeADsMem(pVarArray); }
RRETURN_EXP_IF_ERR(hr); }
|