PeerObject.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / SystemNet / Net / PeerToPeer / Collaboration / PeerObject.cs / 1 / PeerObject.cs

                            //------------------------------------------------------------------------------ 
// 
//     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.Threading;
    using System.Runtime.InteropServices; 
    using System.Text;
    using System.Diagnostics; 
    using System.ComponentModel; 
    using System.Runtime.Serialization;
    using System.Security.Permissions; 

    /// 
    /// This class handles all the functionality and events associated with the Collaboration
    /// Peer Object 
    /// 
    [Serializable] 
    public class PeerObject : IDisposable, IEquatable, ISerializable 
    {
        private const int c_16K = 16384; 
        private Guid m_id;
        private byte[] m_data;
        private PeerScope m_peerScope;
        private ISynchronizeInvoke m_synchronizingObject; 

        // 
        // Initialize on first access of this class 
        //
 
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        static PeerObject()
        { 
            CollaborationHelperFunctions.Initialize(); 
        }
 
        public PeerObject()
        {
            m_id = Guid.NewGuid();
        } 

        public PeerObject(Guid Id, byte[] data, PeerScope peerScope) 
        { 
            if ((data != null) && (data.Length > c_16K))
                throw new ArgumentException(SR.GetString(SR.Collab_ObjectDataSizeFailed), "data"); 

            m_id = Id;
            m_peerScope = peerScope;
            m_data = data; 
        }
 
        ///  
        /// Constructor to enable serialization
        ///  
        protected PeerObject(SerializationInfo serializationInfo, StreamingContext streamingContext)
        {
            m_id = (Guid) serializationInfo.GetValue("_Id", typeof(Guid));
            m_data = (byte[])serializationInfo.GetValue("_Data", typeof(byte[])); 
            m_peerScope = (PeerScope) serializationInfo.GetInt32("_Scope");
        } 
 
        public 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; 
            }
        } 

        public byte[] Data
        {
            get { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_data; 
            } 
            set {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

                if ((value != null) && (value.Length > c_16K))
                    throw new ArgumentException(SR.GetString(SR.Collab_ObjectDataSizeFailed));
 
                m_data = value;
            } 
        } 

        public PeerScope PeerScope 
        {
            get {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_peerScope; 
            }
            set { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 
                m_peerScope = value;
            } 
        }

        /// 
        /// Gets and set the object used to marshall event handlers calls for stand alone 
        /// events
        ///  
        [Browsable(false), DefaultValue(null), Description(SR.SynchronizingObject)] 
        public ISynchronizeInvoke SynchronizingObject
        { 
            get
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_synchronizingObject; 
            }
            set 
            { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                m_synchronizingObject = value; 
            }
        }

        private event EventHandler m_objectChanged; 
        public event EventHandler ObjectChanged
        { 
            //  
            // 
            //  
            [System.Security.SecurityCritical]
            add
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

                PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); 
                AddObjectChangedEvent(value); 
            }
            //  
            // 
            // 
            [System.Security.SecurityCritical]
            remove 
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 
 
                PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
                RemoveObjectChangedEvent(value); 
            }
        }

        #region Object changed event variables 
        private object m_lockObjChangedEvent;
        private object LockObjChangedEvent 
        { 
            get{
                if (m_lockObjChangedEvent == null){ 
                    object o = new object();
                    Interlocked.CompareExchange(ref m_lockObjChangedEvent, o, null);
                }
                return m_lockObjChangedEvent; 
            }
        } 
        private RegisteredWaitHandle m_regObjChangedWaitHandle; 
        private AutoResetEvent m_objChangedEvent;
        private SafeCollabEvent m_safeObjChangedEvent; 
        #endregion

        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        private void AddObjectChangedEvent(EventHandler callback)
        { 
            // 
            // Register a wait handle if one has not been registered already
            // 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() called.");

            lock (LockObjChangedEvent){ 
                if (m_objectChanged == null){
                    if (m_id.Equals(Guid.Empty)) 
                        throw (new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError))); 

                    m_objChangedEvent = new AutoResetEvent(false); 

                    //
                    // Register callback with a wait handle
                    // 

                    m_regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_objChangedEvent, //Event that triggers the callback 
                                            new WaitOrTimerCallback(ObjectChangedCallback), //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.EndPointObjectChanged; 

                    GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(m_id); 
                    GCHandle guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned); 

                    // 
                    // Register event with collab
                    //

                    pcer.pInstance = guidHandle.AddrOfPinnedObject(); 
                    try{
                        int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                            m_objChangedEvent.SafeWaitHandle, 
                                                                            1,
                                                                            ref pcer, 
                                                                            out m_safeObjChangedEvent);
                        if (errorCode != 0){
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode); 
                        }
                    } 
                    finally{ 
                        if (guidHandle.IsAllocated)
                            guidHandle.Free(); 
                    }
                }
                m_objectChanged += callback;
            } 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful."); 
        } 

        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        private void RemoveObjectChangedEvent(EventHandler callback)
        { 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChanged() called."); 

            lock (LockObjChangedEvent){ 
                m_objectChanged -= callback;
                if (m_objectChanged == null){
                    CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle,
                                                                ref m_safeObjChangedEvent, 
                                                                ref m_objChangedEvent);
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables successful."); 
                } 
            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChanged() successful."); 
        }

        protected virtual void OnObjectChanged(ObjectChangedEventArgs objChangedArgs)
        { 
            EventHandler handlerCopy = m_objectChanged;
 
            if (handlerCopy != null){ 
                if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
                    SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, objChangedArgs }); 
                else
                    handlerCopy(this, objChangedArgs);
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the object changed event callback.");
            } 
        }
 
        // 
        // Handles the callback when there is an object changed event from native collaboration
        // 
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        private void ObjectChangedCallback(object state, bool timedOut) 
        { 
            SafeCollabData eventData = null ;
            int errorCode = 0; 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called.");

            while (true){ 
                ObjectChangedEventArgs objectChangedArgs = null;
 
                // 
                // Get the event data for the fired event
                // 
                try{
                    lock (LockObjChangedEvent){
                        if (m_safeObjChangedEvent.IsInvalid) return;
                        errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeObjChangedEvent, 
                                                                                     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_GetObjectChangedDataFailed), errorCode);
                    } 

                    PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), 
                                                                                                typeof(PEER_COLLAB_EVENT_DATA)); 
                    if (ped.eventType == PeerCollabEventType.EndPointObjectChanged){
                        PEER_EVENT_OBJECT_CHANGED_DATA objData = ped.objectChangedData; 
                        PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT));

                        PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po);
 
                        //
                        // Check if the Guid of the fired app is indeed our guid 
                        // 

                        if (Guid.Equals(m_id, peerObject.Id)){ 
                            PeerContact peerContact = null;
                            PeerEndPoint peerEndPoint = null;

                            if (objData.pContact != IntPtr.Zero){ 
                                PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(objData.pContact, typeof(PEER_CONTACT));
                                peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); 
                            } 

                            if (objData.pEndPoint != IntPtr.Zero){ 
                                PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(objData.pEndPoint, typeof(PEER_ENDPOINT));
                                peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
                            }
 
                            objectChangedArgs = new ObjectChangedEventArgs(peerEndPoint,
                                                                                                    peerContact, 
                                                                                                    objData.changeType, 
                                                                                                    peerObject);
                        } 
                    }
                }
                finally{
                    if (eventData != null) eventData.Dispose(); 
                }
 
                // 
                // Fire the callback with the marshalled event args data
                // 
                if(objectChangedArgs != null)
                    OnObjectChanged(objectChangedArgs);
            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback()."); 
        }
 
        public bool Equals(PeerObject other) 
        {
            if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

            if (other != null){
                return other.Id.Equals(Id);
            } 
            return false;
        } 
 
        public override bool Equals(object obj)
        { 
            if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);

            PeerObject comparandPeerObject = obj as PeerObject;
 
            if (comparandPeerObject != null){
                return comparandPeerObject.Id.Equals(Id); 
            } 
            return false;
        } 

        public new static bool Equals(object objA, object objB)
        {
            PeerObject comparandPeerObject1 = objA as PeerObject; 
            PeerObject comparandPeerObject2 = objB as PeerObject;
 
            if ((comparandPeerObject1 != null) && (comparandPeerObject2 != null)){ 
                return Guid.Equals(comparandPeerObject1.Id, comparandPeerObject2.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 Id.ToString();
        } 
 
        private bool m_Disposed;
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        public void Dispose() 
        {
            Dispose(true); 
            GC.SuppressFinalize(this); 
        }
 
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        protected virtual void Dispose(bool disposing) 
        { 
            if (!m_Disposed){
                CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle, 
                                                            ref m_safeObjChangedEvent,
                                                            ref m_objChangedEvent);
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables successful.");
                m_Disposed = true; 
            }
        } 
 
        // 
        //  
        // 
        [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
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
        protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
        {
            info.AddValue("_Id", m_id); 
            info.AddValue("_Data", m_data); 
            info.AddValue("_Scope", m_peerScope);
        } 

        internal void TracePeerObject()
        {
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Contents of the PeerObject"); 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tGuid: {0}", Id);
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tPeerScope: {0}", PeerScope); 
 
            if (Data != null){
                if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Verbose)){ 
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tObject data:");
                    Logging.DumpData(Logging.P2PTraceSource, TraceEventType.Verbose, Logging.P2PTraceSource.MaxDataSize, Data, 0, Data.Length);
                }
                else{ 
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tObject data length {0}", Data.Length);
                } 
            } 
        }
    } 

    //
    // Manages collection of peer objects
    // 
    [Serializable]
    public class PeerObjectCollection : Collection 
    { 
        internal PeerObjectCollection() { }
 
        protected override void SetItem(int index, PeerObject item)
        {
            // nulls not allowed
            if (item == null){ 
                throw new ArgumentNullException("item");
            } 
            base.SetItem(index, item); 
        }
 
        protected override void InsertItem(int index, PeerObject 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 (PeerObject peerObject in this) 
            { 
                if (!first){
                    builder.Append(", "); 
                }
                else{
                    first = false;
                } 
                builder.Append(peerObject.ToString());
            } 
            return builder.ToString(); 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     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.Threading;
    using System.Runtime.InteropServices; 
    using System.Text;
    using System.Diagnostics; 
    using System.ComponentModel; 
    using System.Runtime.Serialization;
    using System.Security.Permissions; 

    /// 
    /// This class handles all the functionality and events associated with the Collaboration
    /// Peer Object 
    /// 
    [Serializable] 
    public class PeerObject : IDisposable, IEquatable, ISerializable 
    {
        private const int c_16K = 16384; 
        private Guid m_id;
        private byte[] m_data;
        private PeerScope m_peerScope;
        private ISynchronizeInvoke m_synchronizingObject; 

        // 
        // Initialize on first access of this class 
        //
 
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        static PeerObject()
        { 
            CollaborationHelperFunctions.Initialize(); 
        }
 
        public PeerObject()
        {
            m_id = Guid.NewGuid();
        } 

        public PeerObject(Guid Id, byte[] data, PeerScope peerScope) 
        { 
            if ((data != null) && (data.Length > c_16K))
                throw new ArgumentException(SR.GetString(SR.Collab_ObjectDataSizeFailed), "data"); 

            m_id = Id;
            m_peerScope = peerScope;
            m_data = data; 
        }
 
        ///  
        /// Constructor to enable serialization
        ///  
        protected PeerObject(SerializationInfo serializationInfo, StreamingContext streamingContext)
        {
            m_id = (Guid) serializationInfo.GetValue("_Id", typeof(Guid));
            m_data = (byte[])serializationInfo.GetValue("_Data", typeof(byte[])); 
            m_peerScope = (PeerScope) serializationInfo.GetInt32("_Scope");
        } 
 
        public 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; 
            }
        } 

        public byte[] Data
        {
            get { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_data; 
            } 
            set {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

                if ((value != null) && (value.Length > c_16K))
                    throw new ArgumentException(SR.GetString(SR.Collab_ObjectDataSizeFailed));
 
                m_data = value;
            } 
        } 

        public PeerScope PeerScope 
        {
            get {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_peerScope; 
            }
            set { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 
                m_peerScope = value;
            } 
        }

        /// 
        /// Gets and set the object used to marshall event handlers calls for stand alone 
        /// events
        ///  
        [Browsable(false), DefaultValue(null), Description(SR.SynchronizingObject)] 
        public ISynchronizeInvoke SynchronizingObject
        { 
            get
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                return m_synchronizingObject; 
            }
            set 
            { 
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
                m_synchronizingObject = value; 
            }
        }

        private event EventHandler m_objectChanged; 
        public event EventHandler ObjectChanged
        { 
            //  
            // 
            //  
            [System.Security.SecurityCritical]
            add
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

                PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); 
                AddObjectChangedEvent(value); 
            }
            //  
            // 
            // 
            [System.Security.SecurityCritical]
            remove 
            {
                if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 
 
                PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
                RemoveObjectChangedEvent(value); 
            }
        }

        #region Object changed event variables 
        private object m_lockObjChangedEvent;
        private object LockObjChangedEvent 
        { 
            get{
                if (m_lockObjChangedEvent == null){ 
                    object o = new object();
                    Interlocked.CompareExchange(ref m_lockObjChangedEvent, o, null);
                }
                return m_lockObjChangedEvent; 
            }
        } 
        private RegisteredWaitHandle m_regObjChangedWaitHandle; 
        private AutoResetEvent m_objChangedEvent;
        private SafeCollabEvent m_safeObjChangedEvent; 
        #endregion

        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        private void AddObjectChangedEvent(EventHandler callback)
        { 
            // 
            // Register a wait handle if one has not been registered already
            // 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() called.");

            lock (LockObjChangedEvent){ 
                if (m_objectChanged == null){
                    if (m_id.Equals(Guid.Empty)) 
                        throw (new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError))); 

                    m_objChangedEvent = new AutoResetEvent(false); 

                    //
                    // Register callback with a wait handle
                    // 

                    m_regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_objChangedEvent, //Event that triggers the callback 
                                            new WaitOrTimerCallback(ObjectChangedCallback), //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.EndPointObjectChanged; 

                    GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(m_id); 
                    GCHandle guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned); 

                    // 
                    // Register event with collab
                    //

                    pcer.pInstance = guidHandle.AddrOfPinnedObject(); 
                    try{
                        int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                            m_objChangedEvent.SafeWaitHandle, 
                                                                            1,
                                                                            ref pcer, 
                                                                            out m_safeObjChangedEvent);
                        if (errorCode != 0){
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode); 
                        }
                    } 
                    finally{ 
                        if (guidHandle.IsAllocated)
                            guidHandle.Free(); 
                    }
                }
                m_objectChanged += callback;
            } 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful."); 
        } 

        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        private void RemoveObjectChangedEvent(EventHandler callback)
        { 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChanged() called."); 

            lock (LockObjChangedEvent){ 
                m_objectChanged -= callback;
                if (m_objectChanged == null){
                    CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle,
                                                                ref m_safeObjChangedEvent, 
                                                                ref m_objChangedEvent);
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables successful."); 
                } 
            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChanged() successful."); 
        }

        protected virtual void OnObjectChanged(ObjectChangedEventArgs objChangedArgs)
        { 
            EventHandler handlerCopy = m_objectChanged;
 
            if (handlerCopy != null){ 
                if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
                    SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, objChangedArgs }); 
                else
                    handlerCopy(this, objChangedArgs);
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the object changed event callback.");
            } 
        }
 
        // 
        // Handles the callback when there is an object changed event from native collaboration
        // 
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        private void ObjectChangedCallback(object state, bool timedOut) 
        { 
            SafeCollabData eventData = null ;
            int errorCode = 0; 

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called.");

            while (true){ 
                ObjectChangedEventArgs objectChangedArgs = null;
 
                // 
                // Get the event data for the fired event
                // 
                try{
                    lock (LockObjChangedEvent){
                        if (m_safeObjChangedEvent.IsInvalid) return;
                        errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeObjChangedEvent, 
                                                                                     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_GetObjectChangedDataFailed), errorCode);
                    } 

                    PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), 
                                                                                                typeof(PEER_COLLAB_EVENT_DATA)); 
                    if (ped.eventType == PeerCollabEventType.EndPointObjectChanged){
                        PEER_EVENT_OBJECT_CHANGED_DATA objData = ped.objectChangedData; 
                        PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT));

                        PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po);
 
                        //
                        // Check if the Guid of the fired app is indeed our guid 
                        // 

                        if (Guid.Equals(m_id, peerObject.Id)){ 
                            PeerContact peerContact = null;
                            PeerEndPoint peerEndPoint = null;

                            if (objData.pContact != IntPtr.Zero){ 
                                PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(objData.pContact, typeof(PEER_CONTACT));
                                peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); 
                            } 

                            if (objData.pEndPoint != IntPtr.Zero){ 
                                PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(objData.pEndPoint, typeof(PEER_ENDPOINT));
                                peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
                            }
 
                            objectChangedArgs = new ObjectChangedEventArgs(peerEndPoint,
                                                                                                    peerContact, 
                                                                                                    objData.changeType, 
                                                                                                    peerObject);
                        } 
                    }
                }
                finally{
                    if (eventData != null) eventData.Dispose(); 
                }
 
                // 
                // Fire the callback with the marshalled event args data
                // 
                if(objectChangedArgs != null)
                    OnObjectChanged(objectChangedArgs);
            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback()."); 
        }
 
        public bool Equals(PeerObject other) 
        {
            if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); 

            if (other != null){
                return other.Id.Equals(Id);
            } 
            return false;
        } 
 
        public override bool Equals(object obj)
        { 
            if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);

            PeerObject comparandPeerObject = obj as PeerObject;
 
            if (comparandPeerObject != null){
                return comparandPeerObject.Id.Equals(Id); 
            } 
            return false;
        } 

        public new static bool Equals(object objA, object objB)
        {
            PeerObject comparandPeerObject1 = objA as PeerObject; 
            PeerObject comparandPeerObject2 = objB as PeerObject;
 
            if ((comparandPeerObject1 != null) && (comparandPeerObject2 != null)){ 
                return Guid.Equals(comparandPeerObject1.Id, comparandPeerObject2.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 Id.ToString();
        } 
 
        private bool m_Disposed;
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        public void Dispose() 
        {
            Dispose(true); 
            GC.SuppressFinalize(this); 
        }
 
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        protected virtual void Dispose(bool disposing) 
        { 
            if (!m_Disposed){
                CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle, 
                                                            ref m_safeObjChangedEvent,
                                                            ref m_objChangedEvent);
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables successful.");
                m_Disposed = true; 
            }
        } 
 
        // 
        //  
        // 
        [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
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
        protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
        {
            info.AddValue("_Id", m_id); 
            info.AddValue("_Data", m_data); 
            info.AddValue("_Scope", m_peerScope);
        } 

        internal void TracePeerObject()
        {
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Contents of the PeerObject"); 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tGuid: {0}", Id);
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tPeerScope: {0}", PeerScope); 
 
            if (Data != null){
                if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Verbose)){ 
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tObject data:");
                    Logging.DumpData(Logging.P2PTraceSource, TraceEventType.Verbose, Logging.P2PTraceSource.MaxDataSize, Data, 0, Data.Length);
                }
                else{ 
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tObject data length {0}", Data.Length);
                } 
            } 
        }
    } 

    //
    // Manages collection of peer objects
    // 
    [Serializable]
    public class PeerObjectCollection : Collection 
    { 
        internal PeerObjectCollection() { }
 
        protected override void SetItem(int index, PeerObject item)
        {
            // nulls not allowed
            if (item == null){ 
                throw new ArgumentNullException("item");
            } 
            base.SetItem(index, item); 
        }
 
        protected override void InsertItem(int index, PeerObject 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 (PeerObject peerObject in this) 
            { 
                if (!first){
                    builder.Append(", "); 
                }
                else{
                    first = false;
                } 
                builder.Append(peerObject.ToString());
            } 
            return builder.ToString(); 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK