使用 IADs::GetInfoEx 进行范围检索
IADs.GetInfoEx 方法可用于检索一系列属性值。 要检索的值的范围在传递给该方法的属性名称数组中指定。
属性查询的范围说明符需采用以下形式:
<property name>;range=<low range>-<high range>
其中 "<property name>" 是属性的 ldapDisplayName,"<low range>"是要检索的第一个属性值的从零开始的索引,"<high range>"是要检索的最后一个属性值的从零开始的索引。 零会用于“<低范围>”,以便指定第一个条目。 通配符字符 (*) 可用于“<高范围>”,以便指定所有剩余条目。
以下代码示例包含一个函数,该函数显示如何对 IADs::GetInfoEx 使用范围检索来枚举组的成员。
HRESULT EnumGroupWithGetInfoEx(LPCWSTR pwszGroupDN,
LPCWSTR pwszUsername,
LPCWSTR pwszPassword)
{
if(NULL == pwszGroupDN)
{
return E_POINTER;
}
HRESULT hr;
IADs *pads;
hr = ADsOpenObject( pwszGroupDN,
pwszUsername,
pwszPassword,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pads);
if(SUCCEEDED(hr))
{
const DWORD dwStep = 1000;
DWORD dwLowRange;
DWORD dwHighRange;
WCHAR wszAttr[MAX_PATH];
LPWSTR rgAttrs[1];
rgAttrs[0] = wszAttr;
dwLowRange = 0;
dwHighRange = dwLowRange + (dwStep - 1);
do
{
VARIANT var;
// Perform this query with the "range=<lowRange>-<highRange>" range.
swprintf_s(wszAttr, L"member;range=%d-%d", dwLowRange, dwHighRange);
hr = ADsBuildVarArrayStr(rgAttrs, 1, &var);
if(SUCCEEDED(hr))
{
hr = pads->GetInfoEx(var, 0);
VariantClear(&var);
if(SUCCEEDED(hr))
{
hr = pads->Get(CComBSTR("member"), &var);
if(SUCCEEDED(hr))
{
if(var.vt == (VT_VARIANT | VT_ARRAY))
{
VARIANT *pVar;
long lLBound, lUBound;
// Get the array of VARIANTs.
hr = SafeArrayAccessData((SAFEARRAY*)(var.pparray), (void HUGEP* FAR*)&pVar);
if(SUCCEEDED(hr))
{
// Get the bounds for the array.
hr = SafeArrayGetLBound((SAFEARRAY*)(var.pparray), 1, &lLBound);
hr = SafeArrayGetUBound((SAFEARRAY*)(var.pparray), 1, &lUBound);
// Get the number of elements.
long cElements = lUBound - lLBound + 1;
// Enumerate the elements.
for(long i = 0; i < cElements; i++)
{
switch(pVar[i].vt)
{
case VT_BSTR:
wprintf(pVar[i].bstrVal);
wprintf(L"\n");
break;
}
}
// Release the array.
SafeArrayUnaccessData((SAFEARRAY*)(var.pparray));
}
}
// This occurs only if one element is retrieved.
else if (var.vt == VT_BSTR)
{
wprintf(var.bstrVal);
wprintf(L"\n");
}
VariantClear(&var);
}
// Increment the high and low ranges to query for the next block of objects.
dwLowRange = dwHighRange + 1;
dwHighRange = dwLowRange + (dwStep - 1);
}
}
}while(SUCCEEDED(hr));
pads->Release();
}
return hr;
}
以下代码示例包含一个函数,该函数显示如何对 IADs.GetInfoEx 使用范围检索来枚举组的成员。
Private Sub EnumGroupMembersWithGetInfoEx(strGroupDN As String, strUsername As String, strPassword As String)
Dim oGroup As IADs
Dim dso As IADsOpenDSObject
On Error GoTo quit
strPath = "LDAP://" & strGroupDN
If "" <> strUsername Then
' Bind to the group with the specified user name and password.
Set dso = GetObject("LDAP:")
Set oGroup = dso.OpenDSObject(strPath, strUsername, strPassword, 1)
Else
' Bind to the group with the current credentials.
Set oGroup = GetObject(strPath)
End If
' For compatibility with all operating systems, the number of objects
' retrieved by each query should not exceed 999. The number of objects
' to retrieve should be as close as possible to 999 to reduce the number
' of round trips to the server necessary to retrieve the objects.
rangeStep = 999
lowRange = 0
highRange = lowRange + rangeStep
Do
' Use the "member;range=<lowRange>-<highRange>" syntax.
strCommandText = "member;range=" & lowRange & "-" & highRange
Debug.Print "Current search command: " & strCommandText
' Load the specified range of members into the local cache. This will
' throw an error if the range exceeds the properties contained in the
' object. The "On Error GoTo quit" error handler will cause the loop
' to terminate when this happens.
On Error GoTo quit
oGroup.GetInfoEx Array(strCommandText), 0
' Enumerate the retrieved members.
oMembers = oGroup.Get("member")
If vbArray And VarType(oMembers) Then
For Each oMember In oMembers
' Add the member.
Debug.Print oMember
nRetrieved = nRetrieved + 1
Next
Else
' oGroup.Get returned only one member, so add it to the list.
Debug.Print oMembers
nRetrieved = nRetrieved + 1
End If
' Increment the high and low ranges to query for the next block of objects.
lowRange = highRange + 1
highRange = lowRange + rangeStep
Loop While True
quit:
End Sub