public override ReadOnlyCollection<PeerNodeAddress> Resolve(string meshId, int maxAddresses, TimeSpan timeout)
 {
     UnsafePnrpNativeMethods.PeerNameResolver resolver;
     this.ThrowIfNoPnrp();
     List<UnsafePnrpNativeMethods.PeerNameResolver> list = new List<UnsafePnrpNativeMethods.PeerNameResolver>();
     List<PnrpRegistration> results = new List<PnrpRegistration>();
     List<PnrpRegistration> list3 = new List<PnrpRegistration>();
     List<PnrpRegistration> list4 = new List<PnrpRegistration>();
     List<WaitHandle> list5 = new List<WaitHandle>();
     Dictionary<uint, string> siteCloudNames = new Dictionary<uint, string>();
     Dictionary<uint, string> linkCloudNames = new Dictionary<uint, string>();
     UnsafePnrpNativeMethods.PnrpResolveCriteria nearestNonCurrentProcess = UnsafePnrpNativeMethods.PnrpResolveCriteria.NearestNonCurrentProcess;
     TimeoutHelper helper = new TimeoutHelper((TimeSpan.Compare(timeout, MaxResolveTimeout) <= 0) ? timeout : MaxResolveTimeout);
     if (!HasPeerNodeForMesh(meshId))
     {
         nearestNonCurrentProcess = UnsafePnrpNativeMethods.PnrpResolveCriteria.Any;
     }
     PnrpResolveScope scope = this.EnumerateClouds(true, linkCloudNames, siteCloudNames);
     if (this.remoteExtension != null)
     {
         meshId = meshId + this.remoteExtension;
     }
     string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", new object[] { meshId });
     if ((scope & PnrpResolveScope.Global) != PnrpResolveScope.None)
     {
         resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, 0, "Global_", helper.RemainingTime(), results);
         list5.Add(resolver.AsyncWaitHandle);
         list.Add(resolver);
     }
     if ((scope & PnrpResolveScope.LinkLocal) != PnrpResolveScope.None)
     {
         foreach (KeyValuePair<uint, string> pair in linkCloudNames)
         {
             resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, pair.Key, pair.Value, helper.RemainingTime(), list3);
             list5.Add(resolver.AsyncWaitHandle);
             list.Add(resolver);
         }
     }
     if ((scope & PnrpResolveScope.SiteLocal) != PnrpResolveScope.None)
     {
         foreach (KeyValuePair<uint, string> pair2 in siteCloudNames)
         {
             resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, pair2.Key, pair2.Value, helper.RemainingTime(), list4);
             list5.Add(resolver.AsyncWaitHandle);
             list.Add(resolver);
         }
     }
     if (list5.Count == 0)
     {
         if (DiagnosticUtility.ShouldTraceWarning)
         {
             Exception exception = new InvalidOperationException(System.ServiceModel.SR.GetString("PnrpNoClouds"));
             PnrpResolveExceptionTraceRecord extendedData = new PnrpResolveExceptionTraceRecord(meshId, string.Empty, exception);
             TraceUtility.TraceEvent(TraceEventType.Warning, 0x4004a, System.ServiceModel.SR.GetString("TraceCodePnrpResolvedAddresses"), extendedData, this, null);
         }
         return new ReadOnlyCollection<PeerNodeAddress>(new List<PeerNodeAddress>());
     }
     Exception exception2 = null;
     foreach (UnsafePnrpNativeMethods.PeerNameResolver resolver2 in list)
     {
         try
         {
             resolver2.End();
         }
         catch (SocketException exception3)
         {
             DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Information);
             exception2 = exception3;
         }
     }
     List<PeerNodeAddress> nodeAddressList = new List<PeerNodeAddress>();
     this.MergeResults(nodeAddressList, results, list3, list4);
     if ((exception2 != null) && (nodeAddressList.Count == 0))
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2);
     }
     if (DiagnosticUtility.ShouldTraceInformation)
     {
         PnrpPeerResolverTraceRecord record2 = new PnrpPeerResolverTraceRecord(meshId, nodeAddressList);
         TraceUtility.TraceEvent(TraceEventType.Information, 0x4004a, System.ServiceModel.SR.GetString("TraceCodePnrpResolvedAddresses"), record2, this, null);
     }
     return new ReadOnlyCollection<PeerNodeAddress>(nodeAddressList);
 }
        public override ReadOnlyCollection<PeerNodeAddress> Resolve(string meshId, int maxAddresses, TimeSpan timeout)
        {
            ThrowIfNoPnrp();
            UnsafePnrpNativeMethods.PeerNameResolver resolver;
            List<UnsafePnrpNativeMethods.PeerNameResolver> resolvers = new List<UnsafePnrpNativeMethods.PeerNameResolver>();
            List<PnrpRegistration> globalRegistrations = new List<PnrpRegistration>();
            List<PnrpRegistration> linkRegistrations = new List<PnrpRegistration>();
            List<PnrpRegistration> siteRegistrations = new List<PnrpRegistration>();
            List<WaitHandle> handles = new List<WaitHandle>();
            Dictionary<uint, string> SiteCloudNames = new Dictionary<uint, string>();
            Dictionary<uint, string> LinkCloudNames = new Dictionary<uint, string>();
            UnsafePnrpNativeMethods.PnrpResolveCriteria targetScope = resolutionScope;
            TimeoutHelper timeoutHelper = new TimeoutHelper(TimeSpan.Compare(timeout, MaxResolveTimeout) <= 0 ? timeout : MaxResolveTimeout);

            if (!HasPeerNodeForMesh(meshId))
                targetScope = UnsafePnrpNativeMethods.PnrpResolveCriteria.Any;
            PnrpResolveScope currentScope = EnumerateClouds(true, LinkCloudNames, SiteCloudNames);

            if (remoteExtension != null)
                meshId += remoteExtension;

            // prepend a 0. for unsecured peername
            string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", meshId);
            if ((currentScope & PnrpResolveScope.Global) != 0)
            {
                resolver = new UnsafePnrpNativeMethods.PeerNameResolver(
                                    peerName, maxAddresses, targetScope, 0, GlobalCloudName, timeoutHelper.RemainingTime(), globalRegistrations);
                handles.Add(resolver.AsyncWaitHandle);
                resolvers.Add(resolver);
            }

            if ((currentScope & PnrpResolveScope.LinkLocal) != 0)
            {
                foreach (KeyValuePair<uint, string> linkEntry in LinkCloudNames)
                {
                    resolver = new UnsafePnrpNativeMethods.PeerNameResolver(
                                    peerName, maxAddresses, targetScope, linkEntry.Key, linkEntry.Value, timeoutHelper.RemainingTime(), linkRegistrations);
                    handles.Add(resolver.AsyncWaitHandle);
                    resolvers.Add(resolver);
                }
            }

            if ((currentScope & PnrpResolveScope.SiteLocal) != 0)
            {
                foreach (KeyValuePair<uint, string> siteEntry in SiteCloudNames)
                {
                    resolver = new UnsafePnrpNativeMethods.PeerNameResolver(
                                    peerName, maxAddresses, targetScope, siteEntry.Key, siteEntry.Value, timeoutHelper.RemainingTime(), siteRegistrations);
                    handles.Add(resolver.AsyncWaitHandle);
                    resolvers.Add(resolver);
                }
            }
            if (handles.Count == 0)
            {
                //could not find any clouds.
                if (DiagnosticUtility.ShouldTraceWarning)
                {
                    Exception exception = new InvalidOperationException(SR.GetString(SR.PnrpNoClouds));
                    PnrpResolveExceptionTraceRecord record = new PnrpResolveExceptionTraceRecord(meshId, string.Empty, exception);
                    TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.PnrpResolvedAddresses,
                        SR.GetString(SR.TraceCodePnrpResolvedAddresses),
                        record, this, null);
                }
                return new ReadOnlyCollection<PeerNodeAddress>(new List<PeerNodeAddress>());
            }

            Exception lastException = null;
            foreach (UnsafePnrpNativeMethods.PeerNameResolver handle in resolvers)
            {
                try
                {
                    handle.End();
                }
                catch (SocketException e)
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                    lastException = e;
                }
            }

            List<PeerNodeAddress> nodeAddressList = new List<PeerNodeAddress>();
            MergeResults(nodeAddressList, globalRegistrations, linkRegistrations, siteRegistrations);
            if ((lastException != null) && (nodeAddressList.Count == 0))
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(lastException);
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                PnrpPeerResolverTraceRecord record = new PnrpPeerResolverTraceRecord(meshId, nodeAddressList);
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PnrpResolvedAddresses,
                    SR.GetString(SR.TraceCodePnrpResolvedAddresses),
                    record, this, null);
            }
            return new ReadOnlyCollection<PeerNodeAddress>(nodeAddressList);
        }
                public void SyncEnumeration(object state)
                {
                    PnrpPeerResolver.UnsafePnrpNativeMethods.CriticalLookupHandle handle;
                    int num = 0;
                    PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySetSafe safeQuerySet = PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet.ToWsaQuerySetSafe(this.resolveQuery);
                    using (safeQuerySet)
                    {
                        num = PnrpPeerResolver.UnsafePnrpNativeMethods.WSALookupServiceBegin(PnrpPeerResolver.UnsafePnrpNativeMethods.CriticalAllocHandleWsaQuerySetSafe.FromWsaQuerySetSafe(safeQuerySet), PnrpPeerResolver.UnsafePnrpNativeMethods.WsaNspControlFlags.ReturnAll, out handle);
                    }
                    if (num != 0)
                    {
                        this.lastException = new PnrpPeerResolver.PnrpException(PnrpPeerResolver.UnsafePnrpNativeMethods.WSAGetLastError(), this.resolveQuery.Context);
                        Utility.CloseInvalidOutCriticalHandle(handle);
                        base.Complete(false, this.lastException);
                    }
                    else
                    {
                        PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet set = new PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet();
                        int size = Marshal.SizeOf(typeof(PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySetSafe)) + 400;
                        CriticalAllocHandle handle3 = CriticalAllocHandle.FromSize(size);
                        try
                        {
                            using (handle)
                            {
                            Label_0090:
                                if (this.timeoutHelper.RemainingTime() != TimeSpan.Zero)
                                {
                                    if (PnrpPeerResolver.UnsafePnrpNativeMethods.WSALookupServiceNext(handle, 0, ref size, (IntPtr) handle3) != 0)
                                    {
                                        int errorCode = PnrpPeerResolver.UnsafePnrpNativeMethods.WSAGetLastError();
                                        switch (errorCode)
                                        {
                                            case 0x2776:
                                            case 0x277e:
                                                return;

                                            case 0x271e:
                                                handle3 = CriticalAllocHandle.FromSize(size);
                                                goto Label_0090;
                                        }
                                        PeerExceptionHelper.ThrowPnrpError(errorCode, set.Context);
                                        goto Label_0090;
                                    }
                                    if (handle3 == IntPtr.Zero)
                                    {
                                        goto Label_0090;
                                    }
                                    set = MarshalWsaQuerySetNativeToWsaQuerySet((IntPtr) handle3, this.scopeId);
                                    PnrpPeerResolver.PnrpRegistration item = new PnrpPeerResolver.PnrpRegistration {
                                        CloudName = set.Context,
                                        Comment = set.Comment,
                                        PeerName = set.ServiceInstanceName,
                                        Addresses = new IPEndPoint[set.CsAddrInfos.Length]
                                    };
                                    for (int i = 0; i < set.CsAddrInfos.Length; i++)
                                    {
                                        item.Addresses[i] = set.CsAddrInfos[i].LocalAddr;
                                    }
                                    lock (this.results)
                                    {
                                        this.results.Add(item);
                                        goto Label_0090;
                                    }
                                }
                            }
                        }
                        catch (Exception exception)
                        {
                            if (Fx.IsFatal(exception))
                            {
                                throw;
                            }
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                            if (DiagnosticUtility.ShouldTraceInformation)
                            {
                                PnrpResolveExceptionTraceRecord extendedData = new PnrpResolveExceptionTraceRecord(this.resolveQuery.ServiceInstanceName, this.resolveQuery.Context, exception);
                                if (DiagnosticUtility.ShouldTraceError)
                                {
                                    TraceUtility.TraceEvent(TraceEventType.Error, 0x4004b, System.ServiceModel.SR.GetString("TraceCodePnrpResolveException"), extendedData, this, null);
                                }
                            }
                            this.lastException = exception;
                        }
                        finally
                        {
                            base.Complete(false, this.lastException);
                        }
                    }
                }
                public void SyncEnumeration(object state)
                {
                    int retval = 0;
                    CriticalLookupHandle hLookup;
                    WsaQuerySetSafe native = WsaQuerySet.ToWsaQuerySetSafe(resolveQuery);
                    using (native)
                    {
                        CriticalAllocHandle handle = CriticalAllocHandleWsaQuerySetSafe.FromWsaQuerySetSafe(native);
                        retval = WSALookupServiceBegin(handle, WsaNspControlFlags.ReturnAll, out hLookup);
                    }
                    if (retval != 0)
                    {
                        lastException = new PnrpException(WSAGetLastError(), resolveQuery.Context);
                        Utility.CloseInvalidOutCriticalHandle(hLookup);
                        Complete(false, lastException);
                        return;
                    }
                    WsaQuerySet querySet = new WsaQuerySet();

                    // start with a sensible default size
                    int size = Marshal.SizeOf(typeof(WsaQuerySetSafe)) + 400;
                    CriticalAllocHandle nativeQuerySetPtr = CriticalAllocHandle.FromSize(size);
                    try
                    {
                        using (hLookup)
                        {
                            while (true)
                            {
                                if (timeoutHelper.RemainingTime() == TimeSpan.Zero)
                                {
                                    break;
                                }
                                retval = WSALookupServiceNext(hLookup, 0, ref size, (IntPtr)nativeQuerySetPtr);
                                if (retval != 0)
                                {
                                    int error = WSAGetLastError();
                                    if (error == (int)WsaError.WSAENOMORE || error == (int)WsaError.WSA_E_NO_MORE)
                                    {
                                        // no more
                                        break;
                                    }

                                    if (error == (int)WsaError.WSAEFAULT)
                                    {
                                        nativeQuerySetPtr = CriticalAllocHandle.FromSize(size);
                                        continue;
                                    }

                                    // unexpected error
                                    PeerExceptionHelper.ThrowPnrpError(error, querySet.Context);
                                }
                                else
                                {
                                    if (nativeQuerySetPtr != IntPtr.Zero)
                                    {
                                        // marshal the results into something useful
                                        querySet = MarshalWsaQuerySetNativeToWsaQuerySet(nativeQuerySetPtr, scopeId);

                                        // allocate the friendly PnrpRegistration and fill it in
                                        PnrpRegistration pnrpRegistration = new PnrpRegistration();
                                        pnrpRegistration.CloudName = querySet.Context;
                                        pnrpRegistration.Comment = querySet.Comment;
                                        pnrpRegistration.PeerName = querySet.ServiceInstanceName;
                                        pnrpRegistration.Addresses = new IPEndPoint[querySet.CsAddrInfos.Length];
                                        for (int i = 0; i < querySet.CsAddrInfos.Length; i++)
                                            pnrpRegistration.Addresses[i] = querySet.CsAddrInfos[i].LocalAddr;

                                        // add it to the list to return later.
                                        // all cloud enumeratos in the same scope will reference the same list and hence the lock.
                                        lock (results)
                                        {
                                            results.Add(pnrpRegistration);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            PnrpResolveExceptionTraceRecord record = new PnrpResolveExceptionTraceRecord(resolveQuery.ServiceInstanceName, resolveQuery.Context, e);
                            if (DiagnosticUtility.ShouldTraceError)
                            {
                                TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.PnrpResolveException,
                                    SR.GetString(SR.TraceCodePnrpResolveException), record, this, null);
                            }
                        }
                        lastException = e;
                    }
                    finally
                    {
                        Complete(false, lastException);
                    }
                }