private ADRawEntry[] GetNextResultCollection() { this.vlvRequestControl.ContextId = base.Cookie; DirectoryControl directoryControl; SearchResultEntryCollection nextResultCollection = base.GetNextResultCollection(typeof(VlvResponseControl), out directoryControl); ADProviderPerf.UpdateProcessCounter(Counter.ProcessRateVlv, UpdateType.Add, 1U); ADProviderPerf.UpdateDCCounter(base.PreferredServerName, Counter.DCRateVlv, UpdateType.Add, 1U); base.Cookie = null; if (directoryControl != null) { VlvResponseControl vlvResponseControl = (VlvResponseControl)directoryControl; base.Cookie = vlvResponseControl.ContextId; this.estimatedRowCount = vlvResponseControl.ContentCount; this.currentRow = vlvResponseControl.TargetPosition; } if (nextResultCollection == null) { return(null); } return(base.Session.ObjectsFromEntries <ADRawEntry>(nextResultCollection, base.PreferredServerName, this.properties, ADVirtualListView.dummyADRawEntry)); }
internal static void TransformControls(DirectoryControl[] controls) { for (int i = 0; i < controls.Length; i++) { Debug.Assert(controls[i] != null); byte[] value = controls[i].GetValue(); if (controls[i].Type == "1.2.840.113556.1.4.319") { // The control is a PageControl. object[] result = BerConverter.Decode("{iO}", value); Debug.Assert((result != null) && (result.Length == 2)); int size = (int)result[0]; // user expects cookie with length 0 as paged search is done. byte[] cookie = (byte[])result[1] ?? Array.Empty <byte>(); PageResultResponseControl pageControl = new PageResultResponseControl(size, cookie, controls[i].IsCritical, controls[i].GetValue()); controls[i] = pageControl; } else if (controls[i].Type == "1.2.840.113556.1.4.1504") { // The control is an AsqControl. object[] o = BerConverter.Decode("{e}", value); Debug.Assert((o != null) && (o.Length == 1)); int result = (int)o[0]; AsqResponseControl asq = new AsqResponseControl(result, controls[i].IsCritical, controls[i].GetValue()); controls[i] = asq; } else if (controls[i].Type == "1.2.840.113556.1.4.841") { // The control is a DirSyncControl. object[] o = BerConverter.Decode("{iiO}", value); Debug.Assert(o != null && o.Length == 3); int moreData = (int)o[0]; int count = (int)o[1]; byte[] dirsyncCookie = (byte[])o[2]; DirSyncResponseControl dirsync = new DirSyncResponseControl(dirsyncCookie, (moreData == 0 ? false : true), count, controls[i].IsCritical, controls[i].GetValue()); controls[i] = dirsync; } else if (controls[i].Type == "1.2.840.113556.1.4.474") { // The control is a SortControl. int result = 0; string attribute = null; object[] o = BerConverter.TryDecode("{ea}", value, out bool decodeSucceeded); // decode might fail as AD for example never returns attribute name, we don't want to unnecessarily throw and catch exception if (decodeSucceeded) { Debug.Assert(o != null && o.Length == 2); result = (int)o[0]; attribute = (string)o[1]; } else { // decoding might fail as attribute is optional o = BerConverter.Decode("{e}", value); Debug.Assert(o != null && o.Length == 1); result = (int)o[0]; } SortResponseControl sort = new SortResponseControl((ResultCode)result, attribute, controls[i].IsCritical, controls[i].GetValue()); controls[i] = sort; } else if (controls[i].Type == "2.16.840.1.113730.3.4.10") { // The control is a VlvResponseControl. int position; int count; int result; byte[] context = null; object[] o = BerConverter.TryDecode("{iieO}", value, out bool decodeSucceeded); if (decodeSucceeded) { Debug.Assert(o != null && o.Length == 4); position = (int)o[0]; count = (int)o[1]; result = (int)o[2]; context = (byte[])o[3]; } else { o = BerConverter.Decode("{iie}", value); Debug.Assert(o != null && o.Length == 3); position = (int)o[0]; count = (int)o[1]; result = (int)o[2]; } VlvResponseControl vlv = new VlvResponseControl(position, count, context, (ResultCode)result, controls[i].IsCritical, controls[i].GetValue()); controls[i] = vlv; } } }
public VlvData GetData(LdapConnection conn, string distinguishedName, string filter, string sortBy, SearchScope scope, int skip, int take, string[] attrs) { string key = string.Join(",", new[] { distinguishedName, filter, scope.ToString(), sortBy }); int contentEstimate; var known = _estimates.TryGetValue(key, out contentEstimate); if (take < 1) { if (known) { return new VlvData { ContentCount = contentEstimate } } ; take = 1; } var req = new SearchRequest(distinguishedName, filter, scope, attrs); req.Controls.Add(new SortRequestControl(sortBy, false)); req.Controls.Add(new VlvRequestControl { EstimateCount = contentEstimate, BeforeCount = 0, AfterCount = take - 1, Offset = skip < 1 ? 1 : skip + 1 }); SearchResponse resp = (SearchResponse)conn.SendRequest(req); VlvResponseControl vlvresp = null; foreach (var control in resp.Controls) { if ((vlvresp = control as VlvResponseControl) != null) { break; } } if (vlvresp == null) { throw new ApplicationException("No VlvResponseControl found in response"); } if (!known) { _estimates[key] = vlvresp.ContentCount; } return(new VlvData { ContentCount = vlvresp.ContentCount, Entries = resp.Entries, VlvContextId = vlvresp.ContextId, IsDone = vlvresp.TargetPosition + take > vlvresp.ContentCount }); } }