예제 #1
0
        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;
                }
            }
        }
예제 #3
0
        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
            });
        }
    }