//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ namespace System.Net.PeerToPeer.Collaboration { using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.InteropServices; using System.Threading; using System.ComponentModel; using System.Text; using System.Net.Mail; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; using System.Security.Permissions; /// /// This is the event args class we give back when /// we have a peer near me change event triggered by native /// public class PeerNearMeChangedEventArgs : EventArgs { private PeerNearMe m_peerNearMe; private PeerChangeType m_peerChangeType; internal PeerNearMeChangedEventArgs(PeerNearMe peerNearMe, PeerChangeType peerChangeType) { m_peerNearMe = peerNearMe; m_peerChangeType = peerChangeType; } public PeerNearMe PeerNearMe { get{ return m_peerNearMe; } } public PeerChangeType PeerChangeType { get{ return m_peerChangeType; } } } /// /// This class contains the functionality of the people near me concept /// in windows collaboration i.e. people on the same subnet /// [Serializable] public class PeerNearMe : Peer, IEquatable, ISerializable { private string m_nickname; private Guid m_id; // // // [System.Security.SecurityCritical] static PeerNearMe(){ CollaborationHelperFunctions.Initialize(); } public PeerNearMe(){ OnRefreshDataCompletedDelegate = new SendOrPostCallback(RefreshDataCompletedWaitCallback); } /// /// Constructor to enable serialization /// [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] protected PeerNearMe(SerializationInfo serializationInfo, StreamingContext streamingContext) :base(serializationInfo, streamingContext) { m_id = (Guid) serializationInfo.GetValue("_Id", typeof(Guid)); m_nickname = serializationInfo.GetString("_NickName"); OnRefreshDataCompletedDelegate = new SendOrPostCallback(RefreshDataCompletedWaitCallback); } public string Nickname { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_nickname; } internal set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_nickname = value; } } internal Guid Id { get{ if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_id; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_id = value; } } // // Adds this peer to the contact manager // public PeerContact AddToContactManager() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddToContactManager."); PeerContact peerContact = null; try{ peerContact = PeerCollaboration.ContactManager.CreateContact(this); PeerCollaboration.ContactManager.AddContact(peerContact); } catch (Exception e){ throw new PeerToPeerException(SR.GetString(SR.Collab_AddToContactMgrFailed), (e.InnerException != null ? e.InnerException : e)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving AddToContactManager."); return peerContact; } // // Adds this peer to the contact manager // public PeerContact AddToContactManager(string displayName, string nickname, MailAddress emailAddress) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddToContactManager with Display name: {0}" + " Nickname: {1} and Email Address: {2}", displayName, nickname, emailAddress); PeerContact peerContact = null; try{ peerContact = PeerCollaboration.ContactManager.CreateContact(this); PeerCollaboration.ContactManager.AddContact(peerContact); } catch (Exception e){ throw new PeerToPeerException(SR.GetString(SR.Collab_AddToContactMgrFailed), (e.InnerException != null ? e.InnerException : e)); } peerContact.DisplayName = displayName; peerContact.Nickname = nickname; peerContact.EmailAddress = emailAddress; try{ PeerCollaboration.ContactManager.UpdateContact(peerContact); } catch (Exception e){ throw new PeerToPeerException(SR.GetString(SR.Collab_AddToContactMgrFailed) + " " + SR.GetString(SR.Collab_AddToContactMgrFailedUpdate), (e.InnerException != null ? e.InnerException : e)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving AddToContactManager."); return peerContact; } // // // [System.Security.SecurityCritical] public static PeerNearMe CreateFromPeerEndPoint(PeerEndPoint peerEndPoint) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering CreateFromPeerEndPoint."); CollaborationHelperFunctions.Initialize(); if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerNearMeCollection peers = PeerCollaboration.GetPeersNearMe(); PeerNearMe peer = null; foreach (PeerNearMe peerNearMe in peers){ PeerEndPointCollection peerEndPoints = peerNearMe.PeerEndPoints; if ((peerEndPoints != null) && (peerEndPoints.Count != 0) && (peerEndPoints[0].Equals(peerEndPoint))) peer = peerNearMe; } if (peer == null){ // // No peer found, throw // throw new PeerToPeerException(SR.GetString(SR.Collab_EndPointNotAPeerNearMe)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving CreateFromPeerEndPoint."); return peer; } // // Checks if we need refreshing of an unsubscribed peer near me // internal override void RefreshIfNeeded() { RefreshData(); } // // Refresh the endpoint with new data from collab // // // // [System.Security.SecurityCritical] public void RefreshData() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); InternalRefreshData(false); } // // // // // // // // // // // // [System.Security.SecurityCritical] internal protected void InternalRefreshData(object state) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "InternalRefreshEndpointData called."); int errorCode = 0; bool isAsync = (bool)state; Exception exception = null; AutoResetEvent refreshedEPDataEvent = new AutoResetEvent(false); SafeCollabEvent safeRefreshedEPDataEvent; PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); pcer.eventType = PeerCollabEventType.RequestStatusChanged; pcer.pInstance = IntPtr.Zero; // // Register to receive status changed event from collab // errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( refreshedEPDataEvent.SafeWaitHandle, 1, ref pcer, out safeRefreshedEPDataEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); exception = PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ReqStatusChangedRegFailed), errorCode); if (!isAsync) throw exception; } PeerEndPointCollection peerEndPoints = PeerEndPoints; if (peerEndPoints.Count == 0) return; try{ InternalRefreshData(peerEndPoints[0]); } catch (Exception e){ if (!isAsync) throw; else exception = e; } // // Wait till all the endpoints are refreshed // while (exception == null){ refreshedEPDataEvent.WaitOne(); SafeCollabData eventData; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(safeRefreshedEPDataEvent, out eventData); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode); exception = PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_RefreshDataFailed), errorCode); if (!isAsync) throw exception; else break; } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.RequestStatusChanged){ PEER_EVENT_REQUEST_STATUS_CHANGED_DATA statusData = ped.requestStatusChangedData; PeerEndPoint peerEndPoint = null; if (statusData.pEndPoint != IntPtr.Zero){ PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(statusData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } if (statusData.hrChange < 0){ exception = PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_RefreshDataFailed), statusData.hrChange); } if (exception != null){ // // Throw exception for sync but call callback for async with exception // if (!isAsync) throw exception; } // // Check if this is our endpoint // if (PeerEndPoints[0].Equals(peerEndPoint)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Found endpoint match in Request status changed."); // // For async call the callback and for sync just return // if (isAsync){ RefreshDataCompletedEventArgs args = new RefreshDataCompletedEventArgs( peerEndPoint, null, false, m_refreshDataAsyncOp.UserSuppliedState); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Firing RefreshDataCompleted event with folloding peer endpoint."); peerEndPoint.TracePeerEndPoint(); } this.PrepareToRaiseRefreshDataCompletedEvent(m_refreshDataAsyncOp, args); } break; } } } // // Async case with exception fire callback here // Sync would have already thrown this by now // if (exception != null){ RefreshDataCompletedEventArgs args = new RefreshDataCompletedEventArgs(null, exception, false, m_refreshDataAsyncOp.UserSuppliedState); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Firing RefreshDataCompleted event with exception {0}.", exception); this.PrepareToRaiseRefreshDataCompletedEvent(m_refreshDataAsyncOp, args); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving InternalRefreshEndpointData."); } // // Refreshes on endpoint // // // // // // // // [System.Security.SecurityCritical] internal static void InternalRefreshData(PeerEndPoint peerEndPoint) { int errorCode; PEER_ENDPOINT pep = new PEER_ENDPOINT(); pep.peerAddress = CollaborationHelperFunctions.ConvertIPEndpointToPEER_ADDRESS(peerEndPoint.EndPoint); GCHandle pepName = GCHandle.Alloc(peerEndPoint.Name, GCHandleType.Pinned); pep.pwzEndpointName = pepName.AddrOfPinnedObject(); GCHandle peerEP = GCHandle.Alloc(pep, GCHandleType.Pinned); IntPtr ptrPeerEP = peerEP.AddrOfPinnedObject(); try{ errorCode = UnsafeCollabNativeMethods.PeerCollabRefreshEndpointData(ptrPeerEP); } finally{ if (pepName.IsAllocated) pepName.Free(); if (peerEP.IsAllocated) peerEP.Free(); } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRefreshEndpointData returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_RefreshDataFailed), errorCode); } } #region RefreshEndpoint Async variables AsyncOperation m_refreshDataAsyncOp; private object m_refreshDataAsyncOpLock; private object RefreshDataAsyncOpLock { get{ if (m_refreshDataAsyncOpLock == null){ object o = new object(); Interlocked.CompareExchange(ref m_refreshDataAsyncOpLock, o, null); } return m_refreshDataAsyncOpLock; } } SendOrPostCallback OnRefreshDataCompletedDelegate; #endregion private event EventHandler m_refreshDataCompleted; public event EventHandler RefreshDataCompleted { add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_refreshDataCompleted += value; } remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_refreshDataCompleted -= value; } } // // Async refresh endpoint data // // // // [System.Security.SecurityCritical] public void RefreshDataAsync(object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (userToken == null) throw new ArgumentNullException("userToken"); lock (RefreshDataAsyncOpLock){ if (m_refreshDataAsyncOp != null) throw new PeerToPeerException(SR.GetString(SR.Collab_DuplicateRefreshAsync)); m_refreshDataAsyncOp = AsyncOperationManager.CreateOperation(userToken); } ThreadPool.QueueUserWorkItem(new WaitCallback(InternalRefreshData), true); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving RefreshDataAsync()."); } protected void OnRefreshDataCompleted(RefreshDataCompletedEventArgs e) { EventHandler handlerCopy = m_refreshDataCompleted; if (handlerCopy != null){ handlerCopy(this, e); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the refresh endpoint completed event callback."); } } void RefreshDataCompletedWaitCallback(object operationState) { m_refreshDataAsyncOp = null; OnRefreshDataCompleted((RefreshDataCompletedEventArgs)operationState); } internal void PrepareToRaiseRefreshDataCompletedEvent(AsyncOperation asyncOP, RefreshDataCompletedEventArgs args) { asyncOP.PostOperationCompleted(OnRefreshDataCompletedDelegate, args); } private static event EventHandler s_peerNearMeChanged; public static event EventHandler PeerNearMeChanged { // // // // [System.Security.SecurityCritical] add { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); AddPeerNearMeChanged(value); } // // // // [System.Security.SecurityCritical] remove { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); RemovePeerNearMeChanged(value); } } #region PeerNearMe changed event variables private static object s_lockPNMChangedEvent; private static object LockPNMChangedEvent { get{ if (s_lockPNMChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref s_lockPNMChangedEvent, o, null); } return s_lockPNMChangedEvent; } } private static RegisteredWaitHandle s_registeredPNMWaitHandle; private static AutoResetEvent s_peerNearMeChangedEvent; private static SafeCollabEvent s_safePeerNearMeChangedEvent; #endregion // // // // // // // [System.Security.SecurityCritical] private static void AddPeerNearMeChanged(EventHandler cb) { // // Register a wait handle if one has not been registered already // Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddPeerNearMeChanged()."); lock (LockPNMChangedEvent){ if (s_peerNearMeChanged == null){ s_peerNearMeChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // s_registeredPNMWaitHandle = ThreadPool.RegisterWaitForSingleObject(s_peerNearMeChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(PeerNearMeChangedCallback), //callback to be called null, //state to be passed -1, //Timeout - aplicable only for timers false //call us everytime the event is set ); PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); pcer.eventType = PeerCollabEventType.PeopleNearMeChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( s_peerNearMeChangedEvent.SafeWaitHandle, 1, ref pcer, out s_safePeerNearMeChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PeerNearMeChangedRegFailed), errorCode); } } s_peerNearMeChanged += cb; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddPeerNearMeChanged() successful."); } // // // // [System.Security.SecurityCritical] private static void RemovePeerNearMeChanged(EventHandler cb) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePeerNearMeChanged() called."); lock (LockPNMChangedEvent){ s_peerNearMeChanged -= cb; if (s_peerNearMeChanged == null){ CollaborationHelperFunctions.CleanEventVars(ref s_registeredPNMWaitHandle, ref s_safePeerNearMeChangedEvent, ref s_peerNearMeChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PeerNearMeChanged variables successful."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePeerNearMeChanged() successful."); } // // // // // // // // // // // [System.Security.SecurityCritical] private static void PeerNearMeChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "PeerNearMeChangedCallback() called."); while (true){ PeerNearMeChangedEventArgs peerNearMeChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockPNMChangedEvent){ if (s_safePeerNearMeChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(s_safePeerNearMeChangedEvent, out eventData); } if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA) break; else if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetPeerNearMeChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.PeopleNearMeChanged){ PEER_EVENT_PEOPLE_NEAR_ME_CHANGED_DATA pnmData = ped.peopleNearMeChangedData; PeerNearMe peerNearMe = null; if (pnmData.pPeopleNearMe != IntPtr.Zero){ PEER_PEOPLE_NEAR_ME pnm = (PEER_PEOPLE_NEAR_ME)Marshal.PtrToStructure(pnmData.pPeopleNearMe, typeof(PEER_PEOPLE_NEAR_ME)); peerNearMe = CollaborationHelperFunctions.PEER_PEOPLE_NEAR_METoPeerNearMe(pnm); } peerNearMeChangedArgs = new PeerNearMeChangedEventArgs(peerNearMe, pnmData.changeType); } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // EventHandler handlerCopy = s_peerNearMeChanged; if ((peerNearMeChangedArgs != null) && (handlerCopy != null)){ handlerCopy(null, peerNearMeChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the peer near me changed event callback."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving PeerNearMeChangedCallback()."); } // // // [System.Security.SecurityCritical] public override PeerInvitationResponse Invite(PeerApplication applicationToInvite, string message, byte[] invitationData) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (applicationToInvite == null) throw new ArgumentNullException("applicationToInvite"); if (applicationToInvite.Id == Guid.Empty) throw new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError)); // // We need at least one endpoint to send invitation to // PeerEndPointCollection peerEndPoints = PeerEndPoints; if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); PeerEndPoint peerEndPoint = PeerEndPoints[0]; PeerInvitationResponse response = InternalInviteEndPoint(applicationToInvite.Id, message, invitationData, peerEndPoint, null); // throw an exception if the response type is ERROR CollaborationHelperFunctions.ThrowIfInvitationResponseInvalid(response); return response; } // // // // [System.Security.SecurityCritical] public override PeerInvitationResponse Invite() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); Guid appGuid = CurrentApplicationGuid; if (appGuid.Equals(Guid.Empty)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoGuidForCurrApp)); // // We need at least one endpoint to send invitation to // PeerEndPointCollection peerEndPoints = PeerEndPoints; if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); PeerEndPoint peerEndPoint = PeerEndPoints[0]; PeerInvitationResponse response = InternalInviteEndPoint(appGuid, null, null, peerEndPoint, null); // throw an exception if the response type is ERROR CollaborationHelperFunctions.ThrowIfInvitationResponseInvalid(response); return response; } // // // // [System.Security.SecurityCritical] public override void InviteAsync(Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); Guid appGuid = CurrentApplicationGuid; if (appGuid.Equals(Guid.Empty)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoGuidForCurrApp)); // // We need at least one endpoint to send invitation to // PeerEndPointCollection peerEndPoints = PeerEndPoints; if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); InternalInviteAsync(appGuid, null, null, PeerEndPoints, null, userToken); } // // // [System.Security.SecurityCritical] public override void InviteAsync( PeerApplication applicationToInvite, string message, byte[] invitationData, Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (applicationToInvite == null) throw new ArgumentNullException("applicationToInvite"); if (applicationToInvite.Id == Guid.Empty) throw new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError)); if (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); // // We need at least one endpoint to send invitation to // PeerEndPointCollection peerEndPoints = PeerEndPoints; if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); InternalInviteAsync(applicationToInvite.Id, message, invitationData, peerEndPoints, null, userToken); } public bool Equals(PeerNearMe other) { if (other == null) throw new ArgumentNullException("other"); return other.Id.Equals(Id); } public override bool Equals(object obj) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerNearMe comparandPeerNearMe = obj as PeerNearMe; if (comparandPeerNearMe != null){ return Guid.Equals(comparandPeerNearMe.Id, Id); } return false; } public new static bool Equals(object objA, object objB) { PeerNearMe comparandPeerNearMe1 = objA as PeerNearMe; PeerNearMe comparandPeerNearMe2 = objB as PeerNearMe; if ((comparandPeerNearMe1 != null) && (comparandPeerNearMe2 != null)){ return Guid.Equals(comparandPeerNearMe1.Id, comparandPeerNearMe2.Id); } return false; } public override int GetHashCode() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return Id.GetHashCode(); } public override string ToString() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return Nickname; } private bool m_Disposed; protected override void Dispose(bool disposing) { if (!m_Disposed){ try{ m_Disposed = true; } finally{ base.Dispose(disposing); } } } // // // [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.Net.dll is still using pre-v4 security model and needs this demand")] [System.Security.SecurityCritical] [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter, SerializationFormatter = true)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { GetObjectData(info, context); } /// /// This is made virtual so that derived types can be implemented correctly /// // // // [System.Security.SecurityCritical] [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)] protected override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("_Id", m_id); info.AddValue("_NickName", m_nickname); } // // Tracing information for Peer Near Me // internal void TracePeerNearMe() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Contents of the PeerNearMe"); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tNickname: {0}", Nickname); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tID: {0}", Id); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tNumber of Endpoints: {0}", PeerEndPoints.Count); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Verbose)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tEndPoints:"); foreach (PeerEndPoint peerEndPoint in PeerEndPoints) peerEndPoint.TracePeerEndPoint(); } } } // // Manages collection of peer near me classes // [Serializable] public class PeerNearMeCollection : Collection { internal PeerNearMeCollection() { } protected override void SetItem(int index, PeerNearMe item) { // nulls not allowed if (item == null){ throw new ArgumentNullException("item"); } base.SetItem(index, item); } protected override void InsertItem(int index, PeerNearMe item) { // nulls not allowed if (item == null){ throw new ArgumentNullException("item"); } base.InsertItem(index, item); } public override string ToString() { bool first = true; StringBuilder builder = new StringBuilder(); foreach (PeerNearMe peerNearMe in this){ if (!first){ builder.Append(", "); } else{ first = false; } builder.Append(peerNearMe.ToString()); } return builder.ToString(); } } }