1035 lines
36 KiB
C++
1035 lines
36 KiB
C++
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1996
|
||
|
//
|
||
|
// File: util.cxx
|
||
|
//
|
||
|
// Contents: Some misc helper functions
|
||
|
//
|
||
|
// History:
|
||
|
//----------------------------------------------------------------------------
|
||
|
#include "ldapc.hxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#if 0
|
||
|
// ADsGetSearchPreference code
|
||
|
//
|
||
|
// Must explicitly include here since adshlp.h
|
||
|
// is not #included.
|
||
|
//
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
HRESULT WINAPI
|
||
|
ADsGetSearchPreference(
|
||
|
ADS_SEARCH_HANDLE hSearchHandle,
|
||
|
LPWSTR lpszPathName,
|
||
|
PADS_SEARCHPREF_INFO *ppSearchPrefs,
|
||
|
PDWORD pdwNumPrefs
|
||
|
);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
UTF8ToUnicodeString(
|
||
|
LPCSTR pUTF8,
|
||
|
LPWSTR *ppUnicode
|
||
|
);
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// The following table needs to be sorted
|
||
|
//
|
||
|
SEARCHENTRY g_aSyntaxSearchTable[] =
|
||
|
{
|
||
|
{ TEXT("AccessPointDN"), LDAPTYPE_ACCESSPOINTDN }, // in NTDS, not in LDAP
|
||
|
{ TEXT("AttributeTypeDescription"), LDAPTYPE_ATTRIBUTETYPEDESCRIPTION },
|
||
|
{ TEXT("Audio"), LDAPTYPE_AUDIO },
|
||
|
{ TEXT("Binary"), LDAPTYPE_OCTETSTRING },
|
||
|
{ TEXT("BitString"), LDAPTYPE_BITSTRING },
|
||
|
{ TEXT("Boolean"), LDAPTYPE_BOOLEAN },
|
||
|
{ TEXT("CaseExactString") ,LDAPTYPE_CASEEXACTSTRING },
|
||
|
{ TEXT("CaseIgnoreString"),LDAPTYPE_CASEIGNORESTRING }, // in NTDS, not in LDAP RFC
|
||
|
{ TEXT("Certificate"), LDAPTYPE_CERTIFICATE },
|
||
|
{ TEXT("CertificateList"), LDAPTYPE_CERTIFICATELIST },
|
||
|
{ TEXT("CertificatePair"), LDAPTYPE_CERTIFICATEPAIR },
|
||
|
{ TEXT("Country"), LDAPTYPE_COUNTRYSTRING },
|
||
|
{ TEXT("DataQualitySyntax"),LDAPTYPE_DATAQUALITYSYNTAX },
|
||
|
{ TEXT("DeliveryMethod"), LDAPTYPE_DELIVERYMETHOD },
|
||
|
{ TEXT("DirectoryString"), LDAPTYPE_DIRECTORYSTRING },
|
||
|
{ TEXT("DN"), LDAPTYPE_DN },
|
||
|
{ TEXT("DSAQualitySyntax"),LDAPTYPE_DSAQUALITYSYNTAX },
|
||
|
{ TEXT("EnhancedGuide"), LDAPTYPE_ENHANCEDGUIDE },
|
||
|
{ TEXT("FacsimileTelephoneNumber"), LDAPTYPE_FACSIMILETELEPHONENUMBER },
|
||
|
{ TEXT("Fax"), LDAPTYPE_FAX },
|
||
|
{ TEXT("GeneralizedTime"), LDAPTYPE_GENERALIZEDTIME },
|
||
|
{ TEXT("Guide"), LDAPTYPE_GUIDE },
|
||
|
{ TEXT("IA5String"), LDAPTYPE_IA5STRING },
|
||
|
{ TEXT("INTEGER"), LDAPTYPE_INTEGER },
|
||
|
{ TEXT("INTEGER8"), LDAPTYPE_INTEGER8 }, // in NTDS, not in LDAP RFC
|
||
|
{ TEXT("JPEG"), LDAPTYPE_JPEG },
|
||
|
{ TEXT("MailPreference"), LDAPTYPE_MAILPREFERENCE },
|
||
|
{ TEXT("NameAndOptionalUID"), LDAPTYPE_NAMEANDOPTIONALUID },
|
||
|
{ TEXT("NumericString"), LDAPTYPE_NUMERICSTRING },
|
||
|
{ TEXT("ObjectClassDescription"), LDAPTYPE_OBJECTCLASSDESCRIPTION },
|
||
|
{ TEXT("ObjectSecurityDescriptor"), LDAPTYPE_SECURITY_DESCRIPTOR},
|
||
|
{ TEXT("OctetString"), LDAPTYPE_OCTETSTRING }, // in NTDS, not in LDAP RFC
|
||
|
{ TEXT("OID"), LDAPTYPE_OID },
|
||
|
{ TEXT("ORAddress"), LDAPTYPE_ORADDRESS },
|
||
|
{ TEXT("ORName"), LDAPTYPE_ORNAME }, // in NTDS, not in LDAP RFC
|
||
|
{ TEXT("OtherMailbox"), LDAPTYPE_OTHERMAILBOX },
|
||
|
{ TEXT("Password"), LDAPTYPE_PASSWORD },
|
||
|
{ TEXT("PostalAddress"), LDAPTYPE_POSTALADDRESS },
|
||
|
{ TEXT("PresentationAddress"), LDAPTYPE_PRESENTATIONADDRESS },
|
||
|
{ TEXT("PrintableString"), LDAPTYPE_PRINTABLESTRING },
|
||
|
{ TEXT("TelephoneNumber"), LDAPTYPE_TELEPHONENUMBER },
|
||
|
{ TEXT("TeletexTerminalIdentifier"), LDAPTYPE_TELETEXTERMINALIDENTIFIER },
|
||
|
{ TEXT("TelexNumber"), LDAPTYPE_TELEXNUMBER },
|
||
|
//
|
||
|
// Allegedly, "Time" started out as a bug in the schema (the correct description
|
||
|
// is "GeneralizedTime"). However, we never delete items from the schema, so it
|
||
|
// is still present in the current Whistler schema
|
||
|
// (4/27/2000), so we'll keep in support for it.
|
||
|
//
|
||
|
{ TEXT("Time"), LDAPTYPE_GENERALIZEDTIME },
|
||
|
{ TEXT("UTCTIME"), LDAPTYPE_UTCTIME }
|
||
|
};
|
||
|
|
||
|
DWORD g_nSyntaxSearchTableSize = ARRAY_SIZE(g_aSyntaxSearchTable );
|
||
|
|
||
|
|
||
|
//
|
||
|
// The following table needs to be sorted (lexicographically) on the first field
|
||
|
//
|
||
|
|
||
|
SEARCHENTRY g_aOidSyntaxSearchTable[] = {
|
||
|
// the type is ORName a type of string -> mapped to string.
|
||
|
{ TEXT("1.2.840.113556.1.4.1221"), LDAPTYPE_CASEIGNORESTRING },
|
||
|
// the type is Undefined syntax in the server, so we are defaulting.
|
||
|
{ TEXT("1.2.840.113556.1.4.1222"), LDAPTYPE_OCTETSTRING},
|
||
|
{ TEXT("1.2.840.113556.1.4.1362"), LDAPTYPE_CASEEXACTSTRING},
|
||
|
{ TEXT("1.2.840.113556.1.4.903"), LDAPTYPE_DNWITHBINARY},
|
||
|
{ TEXT("1.2.840.113556.1.4.904"), LDAPTYPE_DNWITHSTRING},
|
||
|
{ TEXT("1.2.840.113556.1.4.905"), LDAPTYPE_CASEIGNORESTRING },
|
||
|
{ TEXT("1.2.840.113556.1.4.906"), LDAPTYPE_INTEGER8 },
|
||
|
{ TEXT("1.2.840.113556.1.4.907"), LDAPTYPE_SECURITY_DESCRIPTOR },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.10"), LDAPTYPE_CERTIFICATEPAIR },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.11"), LDAPTYPE_COUNTRYSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.12"), LDAPTYPE_DN },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.13"), LDAPTYPE_DATAQUALITYSYNTAX },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.14"), LDAPTYPE_DELIVERYMETHOD },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.15"), LDAPTYPE_DIRECTORYSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.19"), LDAPTYPE_DSAQUALITYSYNTAX },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.2"), LDAPTYPE_ACCESSPOINTDN },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.21"), LDAPTYPE_ENHANCEDGUIDE },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.22"), LDAPTYPE_FACSIMILETELEPHONENUMBER },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.23"), LDAPTYPE_FAX },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.24"), LDAPTYPE_GENERALIZEDTIME },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.25"), LDAPTYPE_GUIDE },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.26"), LDAPTYPE_IA5STRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.27"), LDAPTYPE_INTEGER },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.28"), LDAPTYPE_JPEG },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.3"), LDAPTYPE_ATTRIBUTETYPEDESCRIPTION },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.32"), LDAPTYPE_MAILPREFERENCE },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.33"), LDAPTYPE_ORADDRESS },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.34"), LDAPTYPE_NAMEANDOPTIONALUID },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.36"), LDAPTYPE_NUMERICSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.37"), LDAPTYPE_OBJECTCLASSDESCRIPTION },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.38"), LDAPTYPE_OID },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.39"), LDAPTYPE_OTHERMAILBOX },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.4"), LDAPTYPE_AUDIO },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.40"), LDAPTYPE_OCTETSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.41"), LDAPTYPE_POSTALADDRESS },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.43"), LDAPTYPE_PRESENTATIONADDRESS },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.44"), LDAPTYPE_PRINTABLESTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.5"), LDAPTYPE_OCTETSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.50"), LDAPTYPE_TELEPHONENUMBER },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.51"), LDAPTYPE_TELETEXTERMINALIDENTIFIER },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.52"), LDAPTYPE_TELEXNUMBER },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.53"), LDAPTYPE_UTCTIME },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.6"), LDAPTYPE_BITSTRING },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.7"), LDAPTYPE_BOOLEAN },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.8"), LDAPTYPE_CERTIFICATE },
|
||
|
{ TEXT("1.3.6.1.4.1.1466.115.121.1.9"), LDAPTYPE_CERTIFICATELIST },
|
||
|
};
|
||
|
|
||
|
DWORD g_nOidSyntaxSearchTableSize = ARRAY_SIZE(g_aOidSyntaxSearchTable );
|
||
|
|
||
|
DWORD
|
||
|
GetSyntaxOfAttribute(
|
||
|
LPWSTR pszAttrName,
|
||
|
SCHEMAINFO *pSchemaInfo
|
||
|
)
|
||
|
{
|
||
|
LPWSTR pszTemp = NULL;
|
||
|
|
||
|
// Support for range attributes; for eg., objectClass=Range=0-1 We should
|
||
|
// ignore everything after ';' inclusive.
|
||
|
//
|
||
|
|
||
|
if ((pszTemp = wcschr(pszAttrName, L';')) != NULL ) {
|
||
|
*pszTemp = L'\0';
|
||
|
}
|
||
|
|
||
|
DWORD dwEntry = FindEntryInSearchTable( pszAttrName, pSchemaInfo->aPropertiesSearchTable, pSchemaInfo->nNumOfProperties * 2 );
|
||
|
|
||
|
//
|
||
|
// Put back the ; if we had replaced it.
|
||
|
//
|
||
|
|
||
|
if (pszTemp)
|
||
|
*pszTemp = L';';
|
||
|
|
||
|
if ( dwEntry != -1 )
|
||
|
{
|
||
|
DWORD dwSyntax = FindEntryInSearchTable( pSchemaInfo->aProperties[dwEntry].pszSyntax, g_aSyntaxSearchTable, ARRAY_SIZE(g_aSyntaxSearchTable) );
|
||
|
|
||
|
if ( dwSyntax != -1 )
|
||
|
return dwSyntax;
|
||
|
}
|
||
|
|
||
|
return LDAPTYPE_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
LdapGetSyntaxIdFromName(
|
||
|
LPWSTR pszSyntax
|
||
|
)
|
||
|
{
|
||
|
DWORD dwSyntaxId;
|
||
|
|
||
|
dwSyntaxId = FindEntryInSearchTable(
|
||
|
pszSyntax,
|
||
|
g_aSyntaxSearchTable,
|
||
|
g_nSyntaxSearchTableSize );
|
||
|
|
||
|
if ( dwSyntaxId == -1 ) {
|
||
|
|
||
|
//
|
||
|
// We need to look at the OID table before defaulting
|
||
|
//
|
||
|
dwSyntaxId = FindEntryInSearchTable(
|
||
|
pszSyntax,
|
||
|
g_aOidSyntaxSearchTable,
|
||
|
g_nOidSyntaxSearchTableSize
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (dwSyntaxId == -1 ) {
|
||
|
dwSyntaxId = LDAPTYPE_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
return dwSyntaxId;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
UnMarshallLDAPToLDAPSynID(
|
||
|
LPWSTR pszAttrName,
|
||
|
ADS_LDP *ld,
|
||
|
LDAPMessage *entry,
|
||
|
DWORD dwSyntax,
|
||
|
LDAPOBJECTARRAY *pldapObjectArray
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
DWORD dwStatus = 0;
|
||
|
int nNumberOfValues;
|
||
|
|
||
|
switch ( dwSyntax ) {
|
||
|
|
||
|
// The cases below are binary data
|
||
|
case LDAPTYPE_OCTETSTRING:
|
||
|
case LDAPTYPE_SECURITY_DESCRIPTOR:
|
||
|
case LDAPTYPE_CERTIFICATE:
|
||
|
case LDAPTYPE_CERTIFICATELIST:
|
||
|
case LDAPTYPE_CERTIFICATEPAIR:
|
||
|
case LDAPTYPE_PASSWORD:
|
||
|
case LDAPTYPE_TELETEXTERMINALIDENTIFIER:
|
||
|
case LDAPTYPE_AUDIO:
|
||
|
case LDAPTYPE_JPEG:
|
||
|
case LDAPTYPE_FAX:
|
||
|
case LDAPTYPE_UNKNOWN:
|
||
|
{
|
||
|
struct berval **bValues = NULL;
|
||
|
|
||
|
hr = LdapGetValuesLen( ld, entry, pszAttrName,
|
||
|
&bValues, &nNumberOfValues );
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
pldapObjectArray->fIsString = FALSE;
|
||
|
pldapObjectArray->dwCount = nNumberOfValues;
|
||
|
pldapObjectArray->pLdapObjects = (PLDAPOBJECT) bValues;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
// otherwise it is a string
|
||
|
default:
|
||
|
{
|
||
|
TCHAR **strValues = NULL;
|
||
|
hr = LdapGetValues( ld, entry, pszAttrName,
|
||
|
&strValues, &nNumberOfValues );
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
pldapObjectArray->fIsString = TRUE;
|
||
|
pldapObjectArray->dwCount = nNumberOfValues;
|
||
|
pldapObjectArray->pLdapObjects = (PLDAPOBJECT) strValues;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
// ADsGetSearchPreference code
|
||
|
|
||
|
HRESULT WINAPI
|
||
|
ADsGetSearchPreference(
|
||
|
ADS_SEARCH_HANDLE hSearchHandle,
|
||
|
LPWSTR lpszPathName,
|
||
|
PADS_SEARCHPREF_INFO *ppSearchPrefs,
|
||
|
PDWORD pdwNumPrefs
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
OBJECTINFO ObjectInfo;
|
||
|
POBJECTINFO pObjectInfo = &ObjectInfo;
|
||
|
|
||
|
PLDAP_SEARCHINFO phSearchInfo= (PLDAP_SEARCHINFO) hSearchHandle;
|
||
|
PLDAP_SEARCH_PREF pSearchPref = NULL;
|
||
|
PADS_SEARCHPREF_INFO pADsSearchPref = NULL;
|
||
|
PBYTE pbExtra = NULL;
|
||
|
|
||
|
DWORD dwNumberPrefs = 0;
|
||
|
DWORD dwNumberExtraBytes = 0;
|
||
|
|
||
|
//
|
||
|
// sanity check
|
||
|
//
|
||
|
if (!lpszPathName || !ppSearchPrefs || !phSearchInfo || !pdwNumPrefs)
|
||
|
RRETURN(E_INVALIDARG);
|
||
|
|
||
|
*ppSearchPrefs = NULL;
|
||
|
*pdwNumPrefs = 0;
|
||
|
|
||
|
//
|
||
|
// Make sure we're being called on an LDAP path
|
||
|
//
|
||
|
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
|
||
|
hr = ADsObject(lpszPathName, pObjectInfo);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
if (_tcscmp(pObjectInfo->ProviderName, szProviderName) != 0) {
|
||
|
BAIL_ON_FAILURE(hr = E_NOTIMPL);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// allocate space for the ADS_SEARCHPREF_INFO array we're
|
||
|
// going to build
|
||
|
//
|
||
|
pSearchPref = &(phSearchInfo->_SearchPref);
|
||
|
|
||
|
hr = CalcSpaceForSearchPrefs(pSearchPref, &dwNumberPrefs, &dwNumberExtraBytes);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
// no search prefs were set
|
||
|
if (dwNumberPrefs == 0) {
|
||
|
*ppSearchPrefs = NULL;
|
||
|
FreeObjectInfo(pObjectInfo);
|
||
|
RRETURN(S_OK);
|
||
|
}
|
||
|
|
||
|
|
||
|
pADsSearchPref = (PADS_SEARCHPREF_INFO) AllocADsMem( (dwNumberPrefs * sizeof(ADS_SEARCHPREF_INFO)) + dwNumberExtraBytes);
|
||
|
if (!pADsSearchPref)
|
||
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
||
|
|
||
|
pbExtra = ((PBYTE)pADsSearchPref) + (dwNumberPrefs * sizeof(ADS_SEARCHPREF_INFO));
|
||
|
|
||
|
|
||
|
//
|
||
|
// construct the array of search prefs
|
||
|
//
|
||
|
hr = ConstructSearchPrefArray(pSearchPref, pADsSearchPref, pbExtra);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
*ppSearchPrefs = pADsSearchPref;
|
||
|
*pdwNumPrefs = dwNumberPrefs;
|
||
|
|
||
|
FreeObjectInfo(pObjectInfo);
|
||
|
|
||
|
RRETURN(hr);
|
||
|
|
||
|
error:
|
||
|
|
||
|
if (pADsSearchPref)
|
||
|
FreeADsMem(pADsSearchPref);
|
||
|
|
||
|
if (pObjectInfo) {
|
||
|
FreeObjectInfo(pObjectInfo);
|
||
|
}
|
||
|
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
ConstructSearchPrefArray(
|
||
|
PLDAP_SEARCH_PREF pPrefs,
|
||
|
PADS_SEARCHPREF_INFO pADsSearchPref,
|
||
|
PBYTE pbExtraBytes
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
BOOL fDefault;
|
||
|
|
||
|
LPSTR pUTF8 = NULL;
|
||
|
LPWSTR pUnicode = NULL;
|
||
|
|
||
|
if (!pPrefs || !pADsSearchPref || !pbExtraBytes)
|
||
|
RRETURN(E_INVALIDARG);
|
||
|
|
||
|
|
||
|
// ADS_SEARCHPREF_ASYNCHRONOUS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ASYNCHRONOUS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_BOOLEAN;
|
||
|
pADsSearchPref->vValue.Boolean = pPrefs->_fAsynchronous;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_DEREF_ALIASES
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_DEREF_ALIASES,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_dwDerefAliases;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_SIZE_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SIZE_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_dwSizeLimit;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_TIME_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TIME_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_TIME_LIMIT;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_dwTimeLimit;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_ATTRIBTYPES_ONLY
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ATTRIBTYPES_ONLY,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_BOOLEAN;
|
||
|
pADsSearchPref->vValue.Boolean = pPrefs->_fAttrsOnly;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_SEARCH_SCOPE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SEARCH_SCOPE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
switch(pPrefs->_dwSearchScope) {
|
||
|
case LDAP_SCOPE_SUBTREE:
|
||
|
pADsSearchPref->vValue.Integer = ADS_SCOPE_SUBTREE;
|
||
|
break;
|
||
|
|
||
|
case LDAP_SCOPE_ONELEVEL:
|
||
|
pADsSearchPref->vValue.Integer = ADS_SCOPE_ONELEVEL;
|
||
|
break;
|
||
|
|
||
|
case LDAP_SCOPE_BASE:
|
||
|
pADsSearchPref->vValue.Integer = ADS_SCOPE_BASE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_TIMEOUT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TIMEOUT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_TIMEOUT;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_timeout.tv_sec;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_PAGESIZE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_PAGESIZE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_dwPageSize;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_PAGED_TIME_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_PAGED_TIME_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_PAGED_TIME_LIMIT;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
pADsSearchPref->vValue.Integer = pPrefs->_dwPagedTimeLimit;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_CHASE_REFERRALS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_CHASE_REFERRALS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_INTEGER;
|
||
|
switch(pPrefs->_dwChaseReferrals) {
|
||
|
case (DWORD) (DWORD_PTR)LDAP_OPT_OFF:
|
||
|
pADsSearchPref->vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
|
||
|
break;
|
||
|
|
||
|
case LDAP_CHASE_SUBORDINATE_REFERRALS:
|
||
|
pADsSearchPref->vValue.Integer = ADS_CHASE_REFERRALS_SUBORDINATE;
|
||
|
break;
|
||
|
|
||
|
case LDAP_CHASE_EXTERNAL_REFERRALS:
|
||
|
pADsSearchPref->vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL;
|
||
|
break;
|
||
|
|
||
|
case (DWORD) (DWORD_PTR) LDAP_OPT_ON:
|
||
|
pADsSearchPref->vValue.Integer = ADS_CHASE_REFERRALS_ALWAYS;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_CACHE_RESULTS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_CACHE_RESULTS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_CACHE_RESULTS;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_BOOLEAN;
|
||
|
pADsSearchPref->vValue.Boolean = pPrefs->_fCacheResults;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_TOMBSTONE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TOMBSTONE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_TOMBSTONE;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_BOOLEAN;
|
||
|
pADsSearchPref->vValue.Boolean = pPrefs->_fTombStone;
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_DIRSYNC
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_DIRSYNC,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_DIRSYNC;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_PROV_SPECIFIC;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.dwLength = 0;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.lpValue = NULL;
|
||
|
|
||
|
if (pPrefs->_pProvSpecific && pPrefs->_pProvSpecific->lpValue) {
|
||
|
memcpy(pbExtraBytes, pPrefs->_pProvSpecific->lpValue, pPrefs->_pProvSpecific->dwLength);
|
||
|
|
||
|
pADsSearchPref->vValue.ProviderSpecific.lpValue = pbExtraBytes;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.dwLength = pPrefs->_pProvSpecific->dwLength;
|
||
|
|
||
|
pbExtraBytes += pPrefs->_pProvSpecific->dwLength;
|
||
|
}
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_VLV
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_VLV,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_VLV;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_PROV_SPECIFIC;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.dwLength = sizeof(ADS_VLV);
|
||
|
pADsSearchPref->vValue.ProviderSpecific.lpValue = pbExtraBytes;
|
||
|
|
||
|
PADS_VLV pADsVLV = (PADS_VLV) pbExtraBytes;
|
||
|
pbExtraBytes += sizeof(ADS_VLV);
|
||
|
|
||
|
pADsVLV->dwBeforeCount = pPrefs->_pVLVInfo->ldvlv_before_count;
|
||
|
pADsVLV->dwAfterCount = pPrefs->_pVLVInfo->ldvlv_after_count;
|
||
|
pADsVLV->dwOffset = pPrefs->_pVLVInfo->ldvlv_offset;
|
||
|
pADsVLV->dwContentCount = pPrefs->_pVLVInfo->ldvlv_count;
|
||
|
pADsVLV->pszTarget = NULL;
|
||
|
pADsVLV->lpContextID = NULL;
|
||
|
pADsVLV->dwContextIDLength = 0;
|
||
|
|
||
|
if (pPrefs->_pVLVInfo->ldvlv_attrvalue && pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_val) {
|
||
|
// As stored, the attribute is a non-terminated UTF-8 string.
|
||
|
// We need to return a NULL-terminated Unicode string.
|
||
|
// We do this by constructing a NULL-terminated UTF-8 string, and then
|
||
|
// converting that to a Unicode string.
|
||
|
|
||
|
pUTF8 = (PCHAR) AllocADsMem(pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_len + 1);
|
||
|
if (!pUTF8)
|
||
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
||
|
|
||
|
memcpy(pUTF8,
|
||
|
pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_val,
|
||
|
pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_len);
|
||
|
|
||
|
pUTF8[pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_len] = '\0';
|
||
|
|
||
|
hr = UTF8ToUnicodeString(pUTF8, &pUnicode);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
memcpy(pbExtraBytes,
|
||
|
pUnicode,
|
||
|
(wcslen(pUnicode)+1) * sizeof(WCHAR));
|
||
|
|
||
|
pADsVLV->pszTarget = (LPWSTR) pbExtraBytes;
|
||
|
pbExtraBytes += (wcslen(pUnicode)+1) * sizeof(WCHAR);
|
||
|
}
|
||
|
|
||
|
if (pPrefs->_pVLVInfo->ldvlv_context && pPrefs->_pVLVInfo->ldvlv_context->bv_val) {
|
||
|
memcpy(pbExtraBytes,
|
||
|
pPrefs->_pVLVInfo->ldvlv_context->bv_val,
|
||
|
pPrefs->_pVLVInfo->ldvlv_context->bv_len);
|
||
|
|
||
|
pADsVLV->lpContextID = pbExtraBytes;
|
||
|
pADsVLV->dwContextIDLength = pPrefs->_pVLVInfo->ldvlv_context->bv_len;
|
||
|
pbExtraBytes += pPrefs->_pVLVInfo->ldvlv_context->bv_len;
|
||
|
}
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_SORT_ON
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SORT_ON,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_SORT_ON;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_PROV_SPECIFIC;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY) * pPrefs->_nSortKeys;
|
||
|
pADsSearchPref->vValue.ProviderSpecific.lpValue = pbExtraBytes;
|
||
|
|
||
|
PADS_SORTKEY pSortKeys = (PADS_SORTKEY) pbExtraBytes;
|
||
|
pbExtraBytes += (sizeof(ADS_SORTKEY) * pPrefs->_nSortKeys);
|
||
|
|
||
|
DWORD i;
|
||
|
for (i=0; i < pPrefs->_nSortKeys; i++) {
|
||
|
pSortKeys[i].fReverseorder = pPrefs->_pSortKeys[i].sk_reverseorder;
|
||
|
pSortKeys[i].pszReserved = pPrefs->_pSortKeys[i].sk_matchruleoid;
|
||
|
pSortKeys[i].pszAttrType = (LPWSTR) pbExtraBytes;
|
||
|
memcpy(pbExtraBytes,
|
||
|
pPrefs->_pSortKeys[i].sk_attrtype,
|
||
|
(wcslen(pPrefs->_pSortKeys[i].sk_attrtype)+1) * sizeof(WCHAR)
|
||
|
);
|
||
|
pbExtraBytes += (wcslen(pPrefs->_pSortKeys[i].sk_attrtype)+1) * sizeof(WCHAR);
|
||
|
}
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_ATTRIBUTE_QUERY
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ATTRIBUTE_QUERY,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
pADsSearchPref->dwSearchPref = ADS_SEARCHPREF_ATTRIBUTE_QUERY;
|
||
|
pADsSearchPref->vValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
|
||
|
pADsSearchPref->vValue.CaseIgnoreString = pbExtraBytes;
|
||
|
|
||
|
// copy SourceAttribute
|
||
|
DWORD dwLen = (wcslen(pPrefs->_pAttribScoped) + 1) * sizeof(WCHAR);
|
||
|
|
||
|
memcpy(pbExtraBytes,
|
||
|
pPrefs->_pAttribScoped,
|
||
|
dwLen);
|
||
|
pbExtraBytes += dwLen ;
|
||
|
|
||
|
pADsSearchPref++;
|
||
|
}
|
||
|
|
||
|
|
||
|
error:
|
||
|
|
||
|
if (pUTF8)
|
||
|
FreeADsMem(pUTF8);
|
||
|
|
||
|
if (pUnicode)
|
||
|
FreeADsMem(pUnicode);
|
||
|
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CalcSpaceForSearchPrefs(
|
||
|
PLDAP_SEARCH_PREF pPrefs,
|
||
|
PDWORD pdwNumberPrefs,
|
||
|
PDWORD pdwNumberExtraBytes
|
||
|
)
|
||
|
{
|
||
|
if (!pPrefs || !pdwNumberPrefs || !pdwNumberExtraBytes)
|
||
|
RRETURN(E_INVALIDARG);
|
||
|
|
||
|
*pdwNumberPrefs = 0;
|
||
|
*pdwNumberExtraBytes = 0;
|
||
|
|
||
|
//
|
||
|
// Calculate the number of ADS_SEARCHPREF_INFOs required
|
||
|
// for search prefs that do _not_ require extra space.
|
||
|
// (Currently, only _SORT_ON, _DIRSYNC, _VLV, _ATTRIBUTE_QUERY
|
||
|
// require extra space).
|
||
|
//
|
||
|
// A ADS_SEARCHPREF_INFO is "required" if the corresponding
|
||
|
// search pref is not set to its default value, as determined
|
||
|
// by IsSearchPrefSetToDefault.
|
||
|
//
|
||
|
|
||
|
BOOL fDefault;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// ADS_SEARCHPREF_ASYNCHRONOUS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ASYNCHRONOUS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_DEREF_ALIASES
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_DEREF_ALIASES,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_SIZE_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SIZE_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_TIME_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TIME_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_ATTRIBTYPES_ONLY
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ATTRIBTYPES_ONLY,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_SEARCH_SCOPE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SEARCH_SCOPE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_TIMEOUT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TIMEOUT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_PAGESIZE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_PAGESIZE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_PAGED_TIME_LIMIT
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_PAGED_TIME_LIMIT,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_CHASE_REFERRALS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_CHASE_REFERRALS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_CACHE_RESULTS
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_CACHE_RESULTS,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
// ADS_SEARCHPREF_TOMBSTONE
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_TOMBSTONE,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault)
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
|
||
|
//
|
||
|
// _VLV, _DIRSYNC, _ATTRIBUTE_QUERY, and _SORT_ON require extra space in addition
|
||
|
// to the ADS_SEARCHPREF_INFO structure.
|
||
|
//
|
||
|
|
||
|
// ADS_SEARCHPREF_DIRSYNC
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_DIRSYNC,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
if (pPrefs->_pProvSpecific && pPrefs->_pProvSpecific->dwLength > 0) {
|
||
|
*pdwNumberExtraBytes += pPrefs->_pProvSpecific->dwLength;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_VLV
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_VLV,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
*pdwNumberExtraBytes += sizeof(ADS_VLV);
|
||
|
|
||
|
if (pPrefs->_pVLVInfo->ldvlv_context) {
|
||
|
*pdwNumberExtraBytes += pPrefs->_pVLVInfo->ldvlv_context->bv_len;
|
||
|
}
|
||
|
|
||
|
if (pPrefs->_pVLVInfo->ldvlv_attrvalue) {
|
||
|
// As stored, the string is a UTF-8 string that is not NULL-terminated.
|
||
|
// We need to calculate the size of a NULL-terminated Unicode string.
|
||
|
|
||
|
int cch = MultiByteToWideChar(CP_UTF8,
|
||
|
0,
|
||
|
pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_val,
|
||
|
pPrefs->_pVLVInfo->ldvlv_attrvalue->bv_len,
|
||
|
NULL,
|
||
|
0);
|
||
|
if (!cch)
|
||
|
BAIL_ON_FAILURE(hr = E_FAIL);
|
||
|
|
||
|
// add one WCHAR for NULL terminator
|
||
|
*pdwNumberExtraBytes += ((cch*sizeof(WCHAR)) + sizeof(WCHAR));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_SORT_ON
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_SORT_ON,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
if (!fDefault) {
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
*pdwNumberExtraBytes += (sizeof(ADS_SORTKEY) * pPrefs->_nSortKeys);
|
||
|
|
||
|
DWORD i;
|
||
|
for (i=0; i<pPrefs->_nSortKeys; i++) {
|
||
|
*pdwNumberExtraBytes += ((wcslen(pPrefs->_pSortKeys[i].sk_attrtype)+1) * sizeof(WCHAR));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ADS_SEARCHPREF_ATTRIBUTE_QUERY
|
||
|
BAIL_ON_FAILURE(hr = IsSearchPrefSetToDefault(ADS_SEARCHPREF_ATTRIBUTE_QUERY,
|
||
|
pPrefs,
|
||
|
&fDefault));
|
||
|
|
||
|
if (!fDefault) {
|
||
|
(*pdwNumberPrefs)++;
|
||
|
|
||
|
*pdwNumberExtraBytes += ((wcslen(pPrefs->_pAttribScoped) + 1) * sizeof(WCHAR));
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
error:
|
||
|
RRETURN(hr);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// This function tests whether a given search pref is set
|
||
|
// to it's default value.
|
||
|
//
|
||
|
// Important: This function considers the "default value"
|
||
|
// to be the value currently set in CLDAPGenObject::InitSearchPrefs.
|
||
|
// If you ever change those defaults, update this function.
|
||
|
//
|
||
|
HRESULT
|
||
|
IsSearchPrefSetToDefault(
|
||
|
ADS_SEARCHPREF_ENUM pref,
|
||
|
PLDAP_SEARCH_PREF pPrefs,
|
||
|
PBOOL pfDefault
|
||
|
)
|
||
|
{
|
||
|
|
||
|
if (!pPrefs || !pfDefault)
|
||
|
RRETURN(E_INVALIDARG);
|
||
|
|
||
|
*pfDefault = TRUE;
|
||
|
|
||
|
switch(pref) {
|
||
|
|
||
|
case ADS_SEARCHPREF_ASYNCHRONOUS:
|
||
|
// default: not async
|
||
|
if (pPrefs->_fAsynchronous)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_DEREF_ALIASES:
|
||
|
// default: do not deref
|
||
|
if (pPrefs->_dwDerefAliases)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_SIZE_LIMIT:
|
||
|
// default: no size limit
|
||
|
if (pPrefs->_dwSizeLimit)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_TIME_LIMIT:
|
||
|
// default: no time limit
|
||
|
if (pPrefs->_dwTimeLimit)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_ATTRIBTYPES_ONLY:
|
||
|
// default: not attribtypes only
|
||
|
if (pPrefs->_fAttrsOnly)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_SEARCH_SCOPE:
|
||
|
// default: LDAP_SCOPE_SUBTREE
|
||
|
if (pPrefs->_dwSearchScope != LDAP_SCOPE_SUBTREE)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_TIMEOUT:
|
||
|
// default: no timeout
|
||
|
if (pPrefs->_timeout.tv_sec || pPrefs->_timeout.tv_usec)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_PAGESIZE:
|
||
|
// default: no pagesize
|
||
|
if (pPrefs->_dwPageSize)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_PAGED_TIME_LIMIT:
|
||
|
// default: no paged time limit
|
||
|
if (pPrefs->_dwPagedTimeLimit)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_CHASE_REFERRALS:
|
||
|
// default: ADS_CHASE_REFERRALS_EXTERNAL
|
||
|
if (pPrefs->_dwChaseReferrals != ADS_CHASE_REFERRALS_EXTERNAL)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_SORT_ON:
|
||
|
// default: no sorting
|
||
|
if (pPrefs->_pSortKeys)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_CACHE_RESULTS:
|
||
|
// default: cache results
|
||
|
if (!pPrefs->_fCacheResults)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_DIRSYNC:
|
||
|
// default: not a dirsync search
|
||
|
if (pPrefs->_fDirSync)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_TOMBSTONE:
|
||
|
// default: don't include tombstones
|
||
|
if (pPrefs->_fTombStone)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_VLV:
|
||
|
// default: not a VLV search
|
||
|
if (pPrefs->_pVLVInfo)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
case ADS_SEARCHPREF_ATTRIBUTE_QUERY:
|
||
|
// default: not an attribute-scoped query search
|
||
|
if (pPrefs->_pAttribScoped)
|
||
|
*pfDefault = FALSE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
RRETURN(E_INVALIDARG);
|
||
|
}
|
||
|
|
||
|
RRETURN(S_OK);
|
||
|
}
|
||
|
#endif
|