Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / SystemNet / Net / PeerToPeer / Collaboration / PeerContact.cs / 2 / PeerContact.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net.PeerToPeer.Collaboration { using System.Net.Mail; using System.Security.Cryptography.X509Certificates; using System.Runtime.InteropServices; using System.Net.PeerToPeer; using System.Text; using System.ComponentModel; using System.Threading; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Runtime.Serialization; using System.Security.Permissions; ////// This is the event args class we give back when /// we have an application change event triggered by native /// public class ApplicationChangedEventArgs : EventArgs { private PeerEndPoint m_peerEndPoint; private PeerContact m_peerContact; private PeerChangeType m_peerChangeType; private PeerApplication m_peerApplication; internal ApplicationChangedEventArgs(PeerEndPoint peerEndPoint, PeerContact peerContact, PeerChangeType peerChangeType, PeerApplication peerApplication) { m_peerEndPoint = peerEndPoint; m_peerContact = peerContact; m_peerChangeType = peerChangeType; m_peerApplication = peerApplication; } public PeerEndPoint PeerEndPoint { get { return m_peerEndPoint; } } public PeerContact PeerContact { get { return m_peerContact; } } public PeerChangeType PeerChangeType { get { return m_peerChangeType; } } public PeerApplication PeerApplication { get { return m_peerApplication; } } } ////// This class incorporates the contact functions of a peer collaboration /// contact /// [Serializable] public class PeerContact : Peer, IEquatable, ISerializable { private PeerName m_peerName; private string m_nickname; private string m_displayName; private MailAddress m_emailAddress; private SubscriptionType m_subscribeAllowed; private bool m_isSubscribed; private X509Certificate2 m_credentials; private string m_contactXml; private bool m_justCreated; public PeerName PeerName { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_peerName; } internal set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_peerName = value; } } public string Nickname { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_nickname; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_nickname = value; } } public string DisplayName { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_displayName; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_displayName = value; } } public MailAddress EmailAddress { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_emailAddress; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_emailAddress = value; } } public SubscriptionType SubscribeAllowed { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return InternalSubscribeAllowedGet(); } set{ if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); InternalSubscribeAllowedSet(value); } } internal virtual SubscriptionType InternalSubscribeAllowedGet() { return m_subscribeAllowed; } internal virtual void InternalSubscribeAllowedSet(SubscriptionType value) { m_subscribeAllowed = value; } public bool IsSubscribed { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return InternalIsSubscribed(); } internal set { m_isSubscribed = value; } } internal virtual bool InternalIsSubscribed() { lock (IsSubscribeLock) return m_isSubscribed; } private object m_isSubscribeLock; internal object IsSubscribeLock { get { if (m_isSubscribeLock == null){ object o = new object(); Interlocked.CompareExchange(ref m_isSubscribeLock, o, null); } return m_isSubscribeLock; } } public X509Certificate2 Credentials { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); return m_credentials; } internal set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_credentials = value; } } internal bool JustCreated { get { return m_justCreated; } set { m_justCreated = value; } } internal string ContactXml { get { return m_contactXml; } set { m_contactXml = value; } } public override PeerEndPointCollection PeerEndPoints { // // [System.Security.SecurityCritical] get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Get PeerEndPoints called."); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 pepCount = 0; int errorCode = 0; try{ SafeCollabMemory safeCredentials = null; try{ // // Get the Endpoint enumeration from native // PEER_CONTACT pc = CollaborationHelperFunctions.ConvertPeerContactToPEER_CONTACT(this, ref safeCredentials); errorCode = UnsafeCollabNativeMethods.PeerCollabEnumEndpoints(ref pc, out handlePeerEnum); } finally{ if (safeCredentials != null) safeCredentials.Dispose(); } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumEndpoints returned with errorcode {0}", errorCode); return peerEndPoints; } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref pepCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); return peerEndPoints; } if (pepCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No endpoints. Get PeerEndPoints returning."); return peerEndPoints; } unsafe{ SafeCollabData epArray; errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref pepCount, out epArray); IntPtr pPEER_ENDPOINT = epArray.DangerousGetHandle(); IntPtr* pEndPoints = (IntPtr*)pPEER_ENDPOINT; // // Loop throught all the endpoints from native // for (ulong i = 0; i < pepCount; i++) { IntPtr pEndPointPtr = (IntPtr)pEndPoints[i]; PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(pEndPointPtr, typeof(PEER_ENDPOINT)); PeerEndPoint peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); peerEndPoints.Add(peerEndPoint); } } } finally{ if (handlePeerEnum != null) handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving Get PeerEndPoints with {0} endpoints.", peerEndPoints.Count); return peerEndPoints; } } //// // // // // // // // // // // // // // [System.Security.SecurityCritical] static PeerContact() { CollaborationHelperFunctions.Initialize(); } //// // [System.Security.SecurityCritical] internal PeerContact() { OnSubscribeCompletedDelegate = new SendOrPostCallback(SubscribeCompletedWaitCallback); } ///// /// Constructor to enable serialization /// [System.Security.SecurityCritical] protected PeerContact(SerializationInfo serializationInfo, StreamingContext streamingContext):this() { m_peerName = (PeerName) serializationInfo.GetValue("_PeerName", typeof(PeerName)); m_nickname = serializationInfo.GetString("_NickName"); m_displayName = serializationInfo.GetString("_DisplayName"); try{ m_emailAddress = new MailAddress(serializationInfo.GetString("_EmailAddress")); } catch (SerializationException) { } m_subscribeAllowed = (SubscriptionType)serializationInfo.GetValue("_SubscribeAllowed", typeof(SubscriptionType)); byte [] rawData = (byte[]) serializationInfo.GetValue("_Credentials", typeof(byte[])); m_credentials = new X509Certificate2(rawData); ; m_contactXml = serializationInfo.GetString("_ContactXml"); m_justCreated = serializationInfo.GetBoolean("_JustCreated"); } //// [System.Security.SecurityCritical] public string ToXml() { string xmlContact = null; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering ToXml()."); if (JustCreated) return ContactXml; int errorCode = UnsafeCollabNativeMethods.PeerCollabExportContact(PeerName.ToString(), ref xmlContact); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabExportContact returned with errorcode {0}.", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ContactToXmlFailed), errorCode); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ToXml() with XML string: {0}", xmlContact); return xmlContact; } //// // // [System.Security.SecurityCritical] public static PeerContact FromXml(string peerContactXml) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering FromXml() with XML string: {0}", peerContactXml); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); if (peerContactXml == null) throw new ArgumentNullException("peerContactXml"); SafeCollabData contact = null; PeerContact peerContact = null; int errorCode; try{ errorCode = UnsafeCollabNativeMethods.PeerCollabParseContact(peerContactXml, out contact); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabParseContact returned with errorcode {0}. Contact already exists.", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ContactFromXmlFailed), errorCode); } PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(contact.DangerousGetHandle(), typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } finally{ if (contact != null) contact.Dispose(); } // // Check to see if this already in the contact manager else we can set the just created field // and set this xml since you cannot get XML for a contact not in the contact manager // try{ contact = null; errorCode = UnsafeCollabNativeMethods.PeerCollabGetContact(peerContact.PeerName.ToString(), out contact); } finally{ if (contact != null) contact.Dispose(); } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Error or contact not found in Contact Manager. ErrorCode {0}", errorCode); // // Mark it as just created and add the xml. This is used when adding the contact or getting // contact xml when contact is not in Contact manager // peerContact.JustCreated = true; peerContact.ContactXml = peerContactXml; } if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving FromXml() with following peercontact"); peerContact.TracePeerContact(); } return peerContact; } // // Updates the fwatch in native contact to indicate that we want to watch this // Contact // public virtual void Subscribe() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering Subscribe()."); if (IsSubscribed){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Already subscribed. Leaving Subscribe()."); return; } InternalSubscribe(false); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving Subscribe()."); } // // Handles Subscribe to a contact // private void InternalSubscribe(object isAsyncObj) { // // Updates the IsSubscribed of the contact in the address book // bool isAsync = (bool)isAsyncObj; Exception ex = null; lock (IsSubscribeLock){ IsSubscribed = true; try{ PeerCollaboration.ContactManager.UpdateContact(this); } catch (Exception e){ IsSubscribed = false; if (!isAsync) throw; ex = e; } } if (isAsync){ SubscribeCompletedEventArgs subscribeArgs; if (ex == null){ subscribeArgs = new SubscribeCompletedEventArgs(null, this, null, false, AsyncOp.UserSuppliedState); } else{ subscribeArgs = new SubscribeCompletedEventArgs(null, null, ex, false, AsyncOp.UserSuppliedState); } this.PrepareToRaiseSubscribeCompletedEvent(AsyncOp, subscribeArgs); } } #region Subscribe Async variables private AsyncOperation m_AsyncOp; internal AsyncOperation AsyncOp { get{ return m_AsyncOp; } set{ m_AsyncOp = value; } } private object m_asyncOpLock; internal object AsyncLock { get{ if (m_asyncOpLock == null){ object o = new object(); Interlocked.CompareExchange(ref m_asyncOpLock, o, null); } return m_asyncOpLock; } } private SendOrPostCallback OnSubscribeCompletedDelegate; #endregion private event EventHandler// // // // // // // // // m_subscribeCompleted; public event EventHandler SubscribeCompleted { add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_subscribeCompleted += value; } remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_subscribeCompleted -= value; } } // // Updates the fwatch in native contact to indicate that we want to watch this // Contact // public virtual void SubscribeAsync(Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (userToken == null) throw new ArgumentNullException("userToken"); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering SubscribeAsync() with user token {0}.", userToken); lock (AsyncLock){ if (AsyncOp != null) throw new PeerToPeerException(SR.GetString(SR.Collab_DuplicateSubscribeAsync)); AsyncOp = AsyncOperationManager.CreateOperation(userToken); } ThreadPool.QueueUserWorkItem(new WaitCallback(InternalSubscribe), true); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving SubscribeAsync()."); } protected void OnSubscribeCompleted(SubscribeCompletedEventArgs e) { EventHandler handlerCopy = m_subscribeCompleted; if (handlerCopy != null){ handlerCopy(this, e); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the subscribe completed event callback."); } } void SubscribeCompletedWaitCallback(object operationState) { AsyncOp = null; OnSubscribeCompleted((SubscribeCompletedEventArgs)operationState); } internal void PrepareToRaiseSubscribeCompletedEvent(AsyncOperation asyncOP, SubscribeCompletedEventArgs args) { asyncOP.PostOperationCompleted(OnSubscribeCompletedDelegate, args); } // // Unsubscribe from getting events from this contact // public virtual void Unsubscribe() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (!IsSubscribed) return; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering UnSubscribe()."); lock (IsSubscribeLock){ IsSubscribed = false; try{ PeerCollaboration.ContactManager.UpdateContact(this); } catch (Exception){ IsSubscribed = true; throw; } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Laaving UnSubscribe()."); } // // [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 // return InternalInviteAllEndPoints(PeerEndPoints, null, null, appGuid); } //// // // [System.Security.SecurityCritical] public override PeerInvitationResponse Invite( PeerApplication applicationToInvite, string message, byte[] invitationData) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (applicationToInvite == null) throw new ArgumentNullException("applicationToInvite"); if (applicationToInvite.Id == Guid.Empty) throw new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError)); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); // // We need at least one endpoint to send invitation to // return InternalInviteAllEndPoints(PeerEndPoints, message, invitationData, applicationToInvite.Id); } //// // [System.Security.SecurityCritical] private PeerInvitationResponse InternalInviteAllEndPoints( PeerEndPointCollection peerEndPoints, string message, byte[] invitationData, Guid applicationId) { if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); bool foundDeclined = false; bool foundExpired = false; // // Call for each endpoint. Return first accepted or last declined. // foreach (PeerEndPoint peerEndPoint in peerEndPoints){ PeerInvitationResponse endPointResponse = InternalInviteEndPoint(applicationId, message, invitationData, peerEndPoint, this); if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Accepted) return endPointResponse; else if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Declined) foundDeclined = true; else if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Expired) foundExpired = true; } if (foundDeclined) return new PeerInvitationResponse(PeerInvitationResponseType.Declined); else if (foundExpired) return new PeerInvitationResponse(PeerInvitationResponseType.Expired); else throw new PeerToPeerException(SR.GetString(SR.Collab_InviteFailed)); } //// // [System.Security.SecurityCritical] public PeerInvitationResponse Invite(PeerEndPoint peerEndPoint) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); // // We need at least one endpoint to send invitation to // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); Guid appGuid = CurrentApplicationGuid; if (appGuid.Equals(Guid.Empty)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoGuidForCurrApp)); PeerInvitationResponse response = InternalInviteEndPoint(appGuid, null, null, peerEndPoint, this); // throw an exception if the response type is ERROR CollaborationHelperFunctions.ThrowIfInvitationResponseInvalid(response); return response; } //// // // [System.Security.SecurityCritical] public PeerInvitationResponse Invite(PeerEndPoint peerEndPoint, 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerInvitationResponse response = InternalInviteEndPoint(applicationToInvite.Id, message, invitationData, peerEndPoint, this); // 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)); // // Call internal async invite // InternalInviteAsync(appGuid, null, null, peerEndPoints, this, 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 (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); 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)); // // Call internal async invite // InternalInviteAsync(applicationToInvite.Id, null, null, peerEndPoints, this, userToken); } //// // [System.Security.SecurityCritical] public void InviteAsync(PeerEndPoint peerEndPoint, 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); peerEndPoints.Add(peerEndPoint); // // Call internal async invite // InternalInviteAsync(appGuid, null, null, peerEndPoints, this, userToken); } //// // // [System.Security.SecurityCritical] public void InviteAsync(PeerEndPoint peerEndPoint, string message, byte [] invitationData, PeerApplication applicationToInvite, Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); peerEndPoints.Add(peerEndPoint); // // Call internal async invite // InternalInviteAsync(applicationToInvite.Id, message, invitationData, peerEndPoints, this, userToken); } // // Gets all applications for all endpoints for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications() { return InternalGetAllApplications(Guid.Empty, false); } // // Gets specfic application for all endpoints for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(Guid applicationId) { return InternalGetAllApplications(applicationId, true); } // // Gets all applications for specific endpoint for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(PeerEndPoint peerEndPoint) { if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetApplications(Guid.Empty, false, peerEndPoint); } // // Gets specific application for specific endpoint for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(PeerEndPoint peerEndPoint, Guid applicationId) { if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetApplications(applicationId, true, peerEndPoint); } //// // [System.Security.SecurityCritical] private PeerApplicationCollection InternalGetAllApplications(Guid applicationId, bool guidSupplied) { Dictionary// mergedApplications = new Dictionary (); PeerApplicationCollection peerApplicationCollection; PeerEndPointCollection peerEndPoints = PeerEndPoints; foreach (PeerEndPoint peerEndPoint in peerEndPoints) { peerApplicationCollection = InternalGetApplications(applicationId, guidSupplied, peerEndPoint); foreach (PeerApplication peerApplication in peerApplicationCollection) { mergedApplications[peerApplication.Id] = peerApplication; } } // // Return the application collection from the dictionary // Dictionary .ValueCollection applications = mergedApplications.Values; peerApplicationCollection = new PeerApplicationCollection(); foreach (PeerApplication peerApplication in applications) { peerApplicationCollection.Add(peerApplication); } return peerApplicationCollection; } // // [System.Security.SecurityCritical] private static PeerApplicationCollection InternalGetApplications(Guid applicationId, bool guidSupplied, PeerEndPoint peerEndPoint) { if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering InternalGetApplications() with the following PeerEndPoint"); peerEndPoint.TracePeerEndPoint(); } PeerApplicationCollection peerAppColl = new PeerApplicationCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 appCount = 0; int errorCode = 0; GCHandle guidHandle = new GCHandle(); IntPtr guidPtr = IntPtr.Zero; if (guidSupplied){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Guid supplied is {0}.", applicationId.ToString()); GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(applicationId); guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned); guidPtr = guidHandle.AddrOfPinnedObject(); } PEER_ENDPOINT pep = new PEER_ENDPOINT(); pep.peerAddress = CollaborationHelperFunctions.ConvertIPEndpointToPEER_ADDRESS(peerEndPoint.EndPoint); // // Pin data to pass to native // GCHandle pepName = GCHandle.Alloc(peerEndPoint.Name, GCHandleType.Pinned); pep.pwzEndpointName = pepName.AddrOfPinnedObject(); GCHandle peerEP = GCHandle.Alloc(pep, GCHandleType.Pinned); IntPtr ptrPeerEP = peerEP.AddrOfPinnedObject(); try { // // Enumerate through the applications for the endpoint // errorCode = UnsafeCollabNativeMethods.PeerCollabEnumApplications(ptrPeerEP, guidPtr, out handlePeerEnum); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumApplications returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref appCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } if (appCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "No PeerApplications found."); return peerAppColl; } unsafe { SafeCollabData appArray; errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref appCount, out appArray); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } IntPtr pPEER_APLICATION = appArray.DangerousGetHandle(); IntPtr* pApps = (IntPtr*)pPEER_APLICATION; // // Loop through the applications array from native // for (ulong i = 0; i < appCount; i++){ PEER_APPLICATION* pPeerApp = (PEER_APPLICATION*)pApps[i]; string description = Marshal.PtrToStringUni(pPeerApp->pwzDescription); byte[] data = null; if (pPeerApp->data.cbData != 0) { data = new byte[pPeerApp->data.cbData]; Marshal.Copy(pPeerApp->data.pbData, data, 0, (int)pPeerApp->data.cbData); } PeerApplication peerApp = new PeerApplication(CollaborationHelperFunctions.ConvertGUIDToGuid(pPeerApp->guid), description, data, null, null, PeerScope.None); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Retrieved following Application"); peerApp.TracePeerApplication(); } peerAppColl.Add(peerApp); } } } finally{ if (guidHandle.IsAllocated) guidHandle.Free(); if (pepName.IsAllocated) pepName.Free(); if (peerEP.IsAllocated) peerEP.Free(); if (handlePeerEnum != null) handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving InternalGetApplications(). " + "Returning collection with {0} applications.", peerAppColl.Count); return peerAppColl; } //// // // // // // // // // // // // // // // // // [System.Security.SecurityCritical] public PeerObjectCollection GetObjects(PeerEndPoint peerEndPoint) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetObjects(Guid.Empty, false, peerEndPoint); } //// // [System.Security.SecurityCritical] public PeerObjectCollection GetObjects(PeerEndPoint peerEndPoint, Guid objectId) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetObjects(objectId, true, peerEndPoint); } internal override void RefreshIfNeeded() { } private event EventHandler// m_applicationChanged; public event EventHandler ApplicationChanged { // // [System.Security.SecurityCritical] add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); AddApplicationChanged(value); } //// // [System.Security.SecurityCritical] remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); RemoveApplicationChanged(value); } } #region Application changed event variables private object m_lockAppChangedEvent; internal object LockAppChangedEvent { get{ if (m_lockAppChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref m_lockAppChangedEvent, o, null); } return m_lockAppChangedEvent; } } private RegisteredWaitHandle m_regAppChangedWaitHandle; internal RegisteredWaitHandle AppChangedWaitHandle { set{ m_regAppChangedWaitHandle = value; } } private AutoResetEvent m_appChangedEvent; internal AutoResetEvent AppChangedEvent { get{ return m_appChangedEvent; } set{ m_appChangedEvent = value; } } internal SafeCollabEvent m_safeAppChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddApplicationChanged(EventHandler// // // // // callback) { // // Register a wait handle if one has not been registered already // Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddApplicationChanged()."); lock (LockAppChangedEvent) { if (m_applicationChanged == null){ m_appChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // AppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_appChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(ApplicationChangedCallback), //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.EndPointApplicationChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( m_appChangedEvent.SafeWaitHandle, 1, ref pcer, out m_safeAppChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode); } } m_applicationChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemoveApplicationChanged(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() called."); lock (LockAppChangedEvent){ m_applicationChanged -= callback; if (m_applicationChanged == null){ CleanContactAppEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactAppEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regAppChangedWaitHandle, ref m_safeAppChangedEvent, ref m_appChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ApplicationChanged variables successful."); } protected virtual void OnApplicationChanged(ApplicationChangedEventArgs appChangedArgs) { EventHandler// // handlerCopy = m_applicationChanged; if (handlerCopy != null){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, appChangedArgs }); else handlerCopy(this, appChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the application changed event callback."); } } // // [System.Security.SecurityCritical] internal virtual void ApplicationChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ApplicationChangedCallback() called."); if (m_Disposed) return; while (true) { ApplicationChangedEventArgs appChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockAppChangedEvent){ if (m_safeAppChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeAppChangedEvent, 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_GetApplicationChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.EndPointApplicationChanged){ PEER_EVENT_APPLICATION_CHANGED_DATA appData = ped.applicationChangedData; PeerContact peerContact = null; if (appData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(appData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if (peerContact != null && Equals(peerContact)){ PEER_APPLICATION pa = (PEER_APPLICATION)Marshal.PtrToStructure(appData.pApplication, typeof(PEER_APPLICATION)); PeerApplication peerApplication = CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(pa); ; PeerEndPoint peerEndPoint = null; if (appData.pEndPoint != IntPtr.Zero){ PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(appData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } appChangedArgs = new ApplicationChangedEventArgs( peerEndPoint, peerContact, appData.changeType, peerApplication); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if(appChangedArgs != null) OnApplicationChanged(appChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ApplicationChangedCallback()."); } 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; internal 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; internal RegisteredWaitHandle ObjChangedWaitHandle { set{ m_regObjChangedWaitHandle = value; } } private AutoResetEvent m_objChangedEvent; internal AutoResetEvent ObjChangedEvent { get{ return m_objChangedEvent; } set{ m_objChangedEvent = value; } } internal SafeCollabEvent m_safeObjChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddObjectChangedEvent(EventHandler// // // // // callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddObjectChangedEvent()."); // // Register a wait handle if one has not been registered already // lock (LockObjChangedEvent){ if (m_objectChanged == null){ m_objChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // ObjChangedWaitHandle = 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; pcer.pInstance = IntPtr.Zero; // // Register event with collab // 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); } } m_objectChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemoveObjectChangedEvent(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() called."); lock (LockObjChangedEvent){ m_objectChanged -= callback; if (m_objectChanged == null){ CleanContactObjEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactObjEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle, ref m_safeObjChangedEvent, ref m_objChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables 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."); } } // // [System.Security.SecurityCritical] internal virtual void ObjectChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called."); if (m_Disposed) return; while (true){ ObjectChangedEventArgs objChangedArgs = 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; PeerContact peerContact = null; if (objData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(objData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if (peerContact != null && Equals(peerContact)){ PeerEndPoint peerEndPoint = null; if (objData.pEndPoint != IntPtr.Zero) { PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(objData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT)); PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po); ; objChangedArgs = new ObjectChangedEventArgs(peerEndPoint, peerContact, objData.changeType, peerObject); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if(objChangedArgs != null) OnObjectChanged(objChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback()."); } private event EventHandler// // // // // // // // // // // m_presenceChanged; public event EventHandler PresenceChanged { // // [System.Security.SecurityCritical] add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); AddPresenceChanged(value); } //// // [System.Security.SecurityCritical] remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); RemovePresenceChanged(value); } } #region Presence changed event variables private object m_lockPresenceChangedEvent; internal object LockPresenceChangedEvent { get { if (m_lockPresenceChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref m_lockPresenceChangedEvent, o, null); } return m_lockPresenceChangedEvent; } } private RegisteredWaitHandle m_regPresenceChangedWaitHandle; internal RegisteredWaitHandle PresenceChangedWaitHandle { set{ m_regPresenceChangedWaitHandle = value; } } private AutoResetEvent m_presenceChangedEvent; internal AutoResetEvent PresenceChangedEvent { get{ return m_presenceChangedEvent; } set{ m_presenceChangedEvent = value; } } internal SafeCollabEvent m_safePresenceChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddPresenceChanged(EventHandler// // // // // callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddPresenceChanged()."); // // Register a wait handle if one has not been registered already // lock (LockPresenceChangedEvent){ if (m_presenceChanged == null){ m_presenceChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // PresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_presenceChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(PresenceChangedCallback), //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.EndPointPresenceChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( m_presenceChangedEvent.SafeWaitHandle, 1, ref pcer, out m_safePresenceChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode); } } m_presenceChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddPresenceChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemovePresenceChanged(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() called."); lock (LockPresenceChangedEvent){ m_presenceChanged -= callback; if (m_presenceChanged == null){ CleanContactPresenceEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactPresenceEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regPresenceChangedWaitHandle, ref m_safePresenceChangedEvent, ref m_presenceChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PresenceChanged variables successful."); } protected virtual void OnPresenceChanged(PresenceChangedEventArgs presenceChangedArgs) { EventHandler// // handlerCopy = m_presenceChanged; if (handlerCopy != null){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, presenceChangedArgs }); else handlerCopy(this, presenceChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the presence changed event callback."); } } // // [System.Security.SecurityCritical] internal virtual void PresenceChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "PresenceChangedCallback() called."); if (m_Disposed) return; while (true){ PresenceChangedEventArgs presenceChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockPresenceChangedEvent){ if (m_safePresenceChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safePresenceChangedEvent, 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_GetPresenceChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.EndPointPresenceChanged){ PEER_EVENT_PRESENCE_CHANGED_DATA presenceData = ped.presenceChangedData; PeerContact peerContact = null; if (presenceData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(presenceData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if ((peerContact != null) && Equals(peerContact)){ PeerEndPoint peerEndPoint = null; if (presenceData.pEndPoint != IntPtr.Zero){ PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(presenceData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } PeerPresenceInfo peerPresenceInfo = null; if (presenceData.pPresenceInfo != IntPtr.Zero){ PEER_PRESENCE_INFO ppi = (PEER_PRESENCE_INFO)Marshal.PtrToStructure(presenceData.pPresenceInfo, typeof(PEER_PRESENCE_INFO)); peerPresenceInfo = new PeerPresenceInfo(); peerPresenceInfo.PresenceStatus = ppi.status; peerPresenceInfo.DescriptiveText = ppi.descText; } presenceChangedArgs = new PresenceChangedEventArgs(peerEndPoint, peerContact, presenceData.changeType, peerPresenceInfo); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if (presenceChangedArgs != null) OnPresenceChanged(presenceChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving PresenceChangedCallback()."); } public bool Equals(PeerContact other) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (other != null){ if (other.PeerName != null){ return other.PeerName.Equals(PeerName); } else if (PeerName == null) return true; } return false; } public override bool Equals(object obj) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerContact comparandPeerContact = obj as PeerContact; if (comparandPeerContact != null){ return Equals(comparandPeerContact); } return false; } public new static bool Equals(object objA, object objB) { PeerContact comparandPeerContact1 = objA as PeerContact; PeerContact comparandPeerContact2 = objB as PeerContact; if ((comparandPeerContact1 != null) && (comparandPeerContact2 != null)) { if (comparandPeerContact1.PeerName != null){ return comparandPeerContact1.PeerName.Equals(comparandPeerContact2.PeerName); } else if (comparandPeerContact2.PeerName == null) return true; } return false; } public override int GetHashCode() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return ((PeerName == null) ? 0 : PeerName.GetHashCode()); } public override string ToString() { return m_displayName; } private bool m_Disposed; //// // // // // // // // // // // [System.Security.SecurityCritical] protected override void Dispose(bool disposing) { if (!m_Disposed){ try{ CleanContactAppEventVars(); CleanContactObjEventVars(); CleanContactPresenceEventVars(); m_Disposed = true; } finally{ base.Dispose(disposing); } } } //// // // // [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 override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("_PeerName", m_peerName); info.AddValue("_NickName", m_nickname); info.AddValue("_DisplayName", m_displayName); if(m_emailAddress != null) info.AddValue("_EmailAddress", m_emailAddress.ToString()); info.AddValue("_SubscribeAllowed", m_subscribeAllowed); info.AddValue("_Credentials", m_credentials.RawData); info.AddValue("_ContactXml", m_contactXml); info.AddValue("_JustCreated", m_justCreated); } // // Tracing information for Peer Contact // internal void TracePeerContact() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Contents of the PeerContact"); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tPeerName: {0}", PeerName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tNickname: {0}", Nickname); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tEmailAddress: {0}", EmailAddress.ToString()); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tSubscribeAllowed: {0}", SubscribeAllowed); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials FriendlyName: {0}", Credentials.FriendlyName); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Verbose)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials raw data:"); Logging.DumpData(Logging.P2PTraceSource, TraceEventType.Verbose, Logging.P2PTraceSource.MaxDataSize, Credentials.RawData, 0, Credentials.RawData.Length); } else{ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials raw data length {0}", Credentials.RawData.Length); } } } // // Manages collection of peer contacts // [Serializable] public class PeerContactCollection : Collection{ internal PeerContactCollection() { } protected override void SetItem(int index, PeerContact item) { // nulls not allowed if (item == null){ throw new ArgumentNullException("item"); } base.SetItem(index, item); } protected override void InsertItem(int index, PeerContact 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 (PeerContact peerContact in this) { if (!first){ builder.Append(", "); } else{ first = false; } builder.Append(peerContact.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.Net.Mail; using System.Security.Cryptography.X509Certificates; using System.Runtime.InteropServices; using System.Net.PeerToPeer; using System.Text; using System.ComponentModel; using System.Threading; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Runtime.Serialization; using System.Security.Permissions; ////// This is the event args class we give back when /// we have an application change event triggered by native /// public class ApplicationChangedEventArgs : EventArgs { private PeerEndPoint m_peerEndPoint; private PeerContact m_peerContact; private PeerChangeType m_peerChangeType; private PeerApplication m_peerApplication; internal ApplicationChangedEventArgs(PeerEndPoint peerEndPoint, PeerContact peerContact, PeerChangeType peerChangeType, PeerApplication peerApplication) { m_peerEndPoint = peerEndPoint; m_peerContact = peerContact; m_peerChangeType = peerChangeType; m_peerApplication = peerApplication; } public PeerEndPoint PeerEndPoint { get { return m_peerEndPoint; } } public PeerContact PeerContact { get { return m_peerContact; } } public PeerChangeType PeerChangeType { get { return m_peerChangeType; } } public PeerApplication PeerApplication { get { return m_peerApplication; } } } ////// This class incorporates the contact functions of a peer collaboration /// contact /// [Serializable] public class PeerContact : Peer, IEquatable, ISerializable { private PeerName m_peerName; private string m_nickname; private string m_displayName; private MailAddress m_emailAddress; private SubscriptionType m_subscribeAllowed; private bool m_isSubscribed; private X509Certificate2 m_credentials; private string m_contactXml; private bool m_justCreated; public PeerName PeerName { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_peerName; } internal set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_peerName = value; } } public string Nickname { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_nickname; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_nickname = value; } } public string DisplayName { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_displayName; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_displayName = value; } } public MailAddress EmailAddress { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return m_emailAddress; } set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_emailAddress = value; } } public SubscriptionType SubscribeAllowed { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return InternalSubscribeAllowedGet(); } set{ if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); InternalSubscribeAllowedSet(value); } } internal virtual SubscriptionType InternalSubscribeAllowedGet() { return m_subscribeAllowed; } internal virtual void InternalSubscribeAllowedSet(SubscriptionType value) { m_subscribeAllowed = value; } public bool IsSubscribed { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return InternalIsSubscribed(); } internal set { m_isSubscribed = value; } } internal virtual bool InternalIsSubscribed() { lock (IsSubscribeLock) return m_isSubscribed; } private object m_isSubscribeLock; internal object IsSubscribeLock { get { if (m_isSubscribeLock == null){ object o = new object(); Interlocked.CompareExchange(ref m_isSubscribeLock, o, null); } return m_isSubscribeLock; } } public X509Certificate2 Credentials { get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); return m_credentials; } internal set { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); m_credentials = value; } } internal bool JustCreated { get { return m_justCreated; } set { m_justCreated = value; } } internal string ContactXml { get { return m_contactXml; } set { m_contactXml = value; } } public override PeerEndPointCollection PeerEndPoints { // // [System.Security.SecurityCritical] get { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Get PeerEndPoints called."); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 pepCount = 0; int errorCode = 0; try{ SafeCollabMemory safeCredentials = null; try{ // // Get the Endpoint enumeration from native // PEER_CONTACT pc = CollaborationHelperFunctions.ConvertPeerContactToPEER_CONTACT(this, ref safeCredentials); errorCode = UnsafeCollabNativeMethods.PeerCollabEnumEndpoints(ref pc, out handlePeerEnum); } finally{ if (safeCredentials != null) safeCredentials.Dispose(); } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumEndpoints returned with errorcode {0}", errorCode); return peerEndPoints; } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref pepCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); return peerEndPoints; } if (pepCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No endpoints. Get PeerEndPoints returning."); return peerEndPoints; } unsafe{ SafeCollabData epArray; errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref pepCount, out epArray); IntPtr pPEER_ENDPOINT = epArray.DangerousGetHandle(); IntPtr* pEndPoints = (IntPtr*)pPEER_ENDPOINT; // // Loop throught all the endpoints from native // for (ulong i = 0; i < pepCount; i++) { IntPtr pEndPointPtr = (IntPtr)pEndPoints[i]; PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(pEndPointPtr, typeof(PEER_ENDPOINT)); PeerEndPoint peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); peerEndPoints.Add(peerEndPoint); } } } finally{ if (handlePeerEnum != null) handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving Get PeerEndPoints with {0} endpoints.", peerEndPoints.Count); return peerEndPoints; } } //// // // // // // // // // // // // // // [System.Security.SecurityCritical] static PeerContact() { CollaborationHelperFunctions.Initialize(); } //// // [System.Security.SecurityCritical] internal PeerContact() { OnSubscribeCompletedDelegate = new SendOrPostCallback(SubscribeCompletedWaitCallback); } ///// /// Constructor to enable serialization /// [System.Security.SecurityCritical] protected PeerContact(SerializationInfo serializationInfo, StreamingContext streamingContext):this() { m_peerName = (PeerName) serializationInfo.GetValue("_PeerName", typeof(PeerName)); m_nickname = serializationInfo.GetString("_NickName"); m_displayName = serializationInfo.GetString("_DisplayName"); try{ m_emailAddress = new MailAddress(serializationInfo.GetString("_EmailAddress")); } catch (SerializationException) { } m_subscribeAllowed = (SubscriptionType)serializationInfo.GetValue("_SubscribeAllowed", typeof(SubscriptionType)); byte [] rawData = (byte[]) serializationInfo.GetValue("_Credentials", typeof(byte[])); m_credentials = new X509Certificate2(rawData); ; m_contactXml = serializationInfo.GetString("_ContactXml"); m_justCreated = serializationInfo.GetBoolean("_JustCreated"); } //// [System.Security.SecurityCritical] public string ToXml() { string xmlContact = null; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering ToXml()."); if (JustCreated) return ContactXml; int errorCode = UnsafeCollabNativeMethods.PeerCollabExportContact(PeerName.ToString(), ref xmlContact); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabExportContact returned with errorcode {0}.", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ContactToXmlFailed), errorCode); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ToXml() with XML string: {0}", xmlContact); return xmlContact; } //// // // [System.Security.SecurityCritical] public static PeerContact FromXml(string peerContactXml) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering FromXml() with XML string: {0}", peerContactXml); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); if (peerContactXml == null) throw new ArgumentNullException("peerContactXml"); SafeCollabData contact = null; PeerContact peerContact = null; int errorCode; try{ errorCode = UnsafeCollabNativeMethods.PeerCollabParseContact(peerContactXml, out contact); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabParseContact returned with errorcode {0}. Contact already exists.", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ContactFromXmlFailed), errorCode); } PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(contact.DangerousGetHandle(), typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } finally{ if (contact != null) contact.Dispose(); } // // Check to see if this already in the contact manager else we can set the just created field // and set this xml since you cannot get XML for a contact not in the contact manager // try{ contact = null; errorCode = UnsafeCollabNativeMethods.PeerCollabGetContact(peerContact.PeerName.ToString(), out contact); } finally{ if (contact != null) contact.Dispose(); } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Error or contact not found in Contact Manager. ErrorCode {0}", errorCode); // // Mark it as just created and add the xml. This is used when adding the contact or getting // contact xml when contact is not in Contact manager // peerContact.JustCreated = true; peerContact.ContactXml = peerContactXml; } if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving FromXml() with following peercontact"); peerContact.TracePeerContact(); } return peerContact; } // // Updates the fwatch in native contact to indicate that we want to watch this // Contact // public virtual void Subscribe() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering Subscribe()."); if (IsSubscribed){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Already subscribed. Leaving Subscribe()."); return; } InternalSubscribe(false); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving Subscribe()."); } // // Handles Subscribe to a contact // private void InternalSubscribe(object isAsyncObj) { // // Updates the IsSubscribed of the contact in the address book // bool isAsync = (bool)isAsyncObj; Exception ex = null; lock (IsSubscribeLock){ IsSubscribed = true; try{ PeerCollaboration.ContactManager.UpdateContact(this); } catch (Exception e){ IsSubscribed = false; if (!isAsync) throw; ex = e; } } if (isAsync){ SubscribeCompletedEventArgs subscribeArgs; if (ex == null){ subscribeArgs = new SubscribeCompletedEventArgs(null, this, null, false, AsyncOp.UserSuppliedState); } else{ subscribeArgs = new SubscribeCompletedEventArgs(null, null, ex, false, AsyncOp.UserSuppliedState); } this.PrepareToRaiseSubscribeCompletedEvent(AsyncOp, subscribeArgs); } } #region Subscribe Async variables private AsyncOperation m_AsyncOp; internal AsyncOperation AsyncOp { get{ return m_AsyncOp; } set{ m_AsyncOp = value; } } private object m_asyncOpLock; internal object AsyncLock { get{ if (m_asyncOpLock == null){ object o = new object(); Interlocked.CompareExchange(ref m_asyncOpLock, o, null); } return m_asyncOpLock; } } private SendOrPostCallback OnSubscribeCompletedDelegate; #endregion private event EventHandler// // // // // // // // // m_subscribeCompleted; public event EventHandler SubscribeCompleted { add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_subscribeCompleted += value; } remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); m_subscribeCompleted -= value; } } // // Updates the fwatch in native contact to indicate that we want to watch this // Contact // public virtual void SubscribeAsync(Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (userToken == null) throw new ArgumentNullException("userToken"); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering SubscribeAsync() with user token {0}.", userToken); lock (AsyncLock){ if (AsyncOp != null) throw new PeerToPeerException(SR.GetString(SR.Collab_DuplicateSubscribeAsync)); AsyncOp = AsyncOperationManager.CreateOperation(userToken); } ThreadPool.QueueUserWorkItem(new WaitCallback(InternalSubscribe), true); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving SubscribeAsync()."); } protected void OnSubscribeCompleted(SubscribeCompletedEventArgs e) { EventHandler handlerCopy = m_subscribeCompleted; if (handlerCopy != null){ handlerCopy(this, e); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the subscribe completed event callback."); } } void SubscribeCompletedWaitCallback(object operationState) { AsyncOp = null; OnSubscribeCompleted((SubscribeCompletedEventArgs)operationState); } internal void PrepareToRaiseSubscribeCompletedEvent(AsyncOperation asyncOP, SubscribeCompletedEventArgs args) { asyncOP.PostOperationCompleted(OnSubscribeCompletedDelegate, args); } // // Unsubscribe from getting events from this contact // public virtual void Unsubscribe() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (!IsSubscribed) return; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering UnSubscribe()."); lock (IsSubscribeLock){ IsSubscribed = false; try{ PeerCollaboration.ContactManager.UpdateContact(this); } catch (Exception){ IsSubscribed = true; throw; } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Laaving UnSubscribe()."); } // // [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 // return InternalInviteAllEndPoints(PeerEndPoints, null, null, appGuid); } //// // // [System.Security.SecurityCritical] public override PeerInvitationResponse Invite( PeerApplication applicationToInvite, string message, byte[] invitationData) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (applicationToInvite == null) throw new ArgumentNullException("applicationToInvite"); if (applicationToInvite.Id == Guid.Empty) throw new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError)); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); // // We need at least one endpoint to send invitation to // return InternalInviteAllEndPoints(PeerEndPoints, message, invitationData, applicationToInvite.Id); } //// // [System.Security.SecurityCritical] private PeerInvitationResponse InternalInviteAllEndPoints( PeerEndPointCollection peerEndPoints, string message, byte[] invitationData, Guid applicationId) { if ((peerEndPoints == null) || (peerEndPoints.Count == 0)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound)); bool foundDeclined = false; bool foundExpired = false; // // Call for each endpoint. Return first accepted or last declined. // foreach (PeerEndPoint peerEndPoint in peerEndPoints){ PeerInvitationResponse endPointResponse = InternalInviteEndPoint(applicationId, message, invitationData, peerEndPoint, this); if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Accepted) return endPointResponse; else if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Declined) foundDeclined = true; else if (endPointResponse.PeerInvitationResponseType == PeerInvitationResponseType.Expired) foundExpired = true; } if (foundDeclined) return new PeerInvitationResponse(PeerInvitationResponseType.Declined); else if (foundExpired) return new PeerInvitationResponse(PeerInvitationResponseType.Expired); else throw new PeerToPeerException(SR.GetString(SR.Collab_InviteFailed)); } //// // [System.Security.SecurityCritical] public PeerInvitationResponse Invite(PeerEndPoint peerEndPoint) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); // // We need at least one endpoint to send invitation to // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); Guid appGuid = CurrentApplicationGuid; if (appGuid.Equals(Guid.Empty)) throw new PeerToPeerException(SR.GetString(SR.Collab_NoGuidForCurrApp)); PeerInvitationResponse response = InternalInviteEndPoint(appGuid, null, null, peerEndPoint, this); // throw an exception if the response type is ERROR CollaborationHelperFunctions.ThrowIfInvitationResponseInvalid(response); return response; } //// // // [System.Security.SecurityCritical] public PeerInvitationResponse Invite(PeerEndPoint peerEndPoint, 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerInvitationResponse response = InternalInviteEndPoint(applicationToInvite.Id, message, invitationData, peerEndPoint, this); // 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)); // // Call internal async invite // InternalInviteAsync(appGuid, null, null, peerEndPoints, this, 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 (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); 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)); // // Call internal async invite // InternalInviteAsync(applicationToInvite.Id, null, null, peerEndPoints, this, userToken); } //// // [System.Security.SecurityCritical] public void InviteAsync(PeerEndPoint peerEndPoint, 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); peerEndPoints.Add(peerEndPoint); // // Call internal async invite // InternalInviteAsync(appGuid, null, null, peerEndPoints, this, userToken); } //// // // [System.Security.SecurityCritical] public void InviteAsync(PeerEndPoint peerEndPoint, string message, byte [] invitationData, PeerApplication applicationToInvite, Object userToken) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (userToken == null) throw new ArgumentException(SR.GetString(SR.NullUserToken)); 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 // if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); if (peerEndPoint.EndPoint == null) throw new ArgumentException(SR.GetString(SR.Collab_NoEndPointInPeerEndPoint)); PeerEndPointCollection peerEndPoints = new PeerEndPointCollection(); peerEndPoints.Add(peerEndPoint); // // Call internal async invite // InternalInviteAsync(applicationToInvite.Id, message, invitationData, peerEndPoints, this, userToken); } // // Gets all applications for all endpoints for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications() { return InternalGetAllApplications(Guid.Empty, false); } // // Gets specfic application for all endpoints for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(Guid applicationId) { return InternalGetAllApplications(applicationId, true); } // // Gets all applications for specific endpoint for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(PeerEndPoint peerEndPoint) { if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetApplications(Guid.Empty, false, peerEndPoint); } // // Gets specific application for specific endpoint for this contact // //// // [System.Security.SecurityCritical] public PeerApplicationCollection GetApplications(PeerEndPoint peerEndPoint, Guid applicationId) { if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetApplications(applicationId, true, peerEndPoint); } //// // [System.Security.SecurityCritical] private PeerApplicationCollection InternalGetAllApplications(Guid applicationId, bool guidSupplied) { Dictionary// mergedApplications = new Dictionary (); PeerApplicationCollection peerApplicationCollection; PeerEndPointCollection peerEndPoints = PeerEndPoints; foreach (PeerEndPoint peerEndPoint in peerEndPoints) { peerApplicationCollection = InternalGetApplications(applicationId, guidSupplied, peerEndPoint); foreach (PeerApplication peerApplication in peerApplicationCollection) { mergedApplications[peerApplication.Id] = peerApplication; } } // // Return the application collection from the dictionary // Dictionary .ValueCollection applications = mergedApplications.Values; peerApplicationCollection = new PeerApplicationCollection(); foreach (PeerApplication peerApplication in applications) { peerApplicationCollection.Add(peerApplication); } return peerApplicationCollection; } // // [System.Security.SecurityCritical] private static PeerApplicationCollection InternalGetApplications(Guid applicationId, bool guidSupplied, PeerEndPoint peerEndPoint) { if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering InternalGetApplications() with the following PeerEndPoint"); peerEndPoint.TracePeerEndPoint(); } PeerApplicationCollection peerAppColl = new PeerApplicationCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 appCount = 0; int errorCode = 0; GCHandle guidHandle = new GCHandle(); IntPtr guidPtr = IntPtr.Zero; if (guidSupplied){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Guid supplied is {0}.", applicationId.ToString()); GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(applicationId); guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned); guidPtr = guidHandle.AddrOfPinnedObject(); } PEER_ENDPOINT pep = new PEER_ENDPOINT(); pep.peerAddress = CollaborationHelperFunctions.ConvertIPEndpointToPEER_ADDRESS(peerEndPoint.EndPoint); // // Pin data to pass to native // GCHandle pepName = GCHandle.Alloc(peerEndPoint.Name, GCHandleType.Pinned); pep.pwzEndpointName = pepName.AddrOfPinnedObject(); GCHandle peerEP = GCHandle.Alloc(pep, GCHandleType.Pinned); IntPtr ptrPeerEP = peerEP.AddrOfPinnedObject(); try { // // Enumerate through the applications for the endpoint // errorCode = UnsafeCollabNativeMethods.PeerCollabEnumApplications(ptrPeerEP, guidPtr, out handlePeerEnum); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumApplications returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref appCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } if (appCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "No PeerApplications found."); return peerAppColl; } unsafe { SafeCollabData appArray; errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref appCount, out appArray); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetAppsFailed), errorCode); } IntPtr pPEER_APLICATION = appArray.DangerousGetHandle(); IntPtr* pApps = (IntPtr*)pPEER_APLICATION; // // Loop through the applications array from native // for (ulong i = 0; i < appCount; i++){ PEER_APPLICATION* pPeerApp = (PEER_APPLICATION*)pApps[i]; string description = Marshal.PtrToStringUni(pPeerApp->pwzDescription); byte[] data = null; if (pPeerApp->data.cbData != 0) { data = new byte[pPeerApp->data.cbData]; Marshal.Copy(pPeerApp->data.pbData, data, 0, (int)pPeerApp->data.cbData); } PeerApplication peerApp = new PeerApplication(CollaborationHelperFunctions.ConvertGUIDToGuid(pPeerApp->guid), description, data, null, null, PeerScope.None); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Retrieved following Application"); peerApp.TracePeerApplication(); } peerAppColl.Add(peerApp); } } } finally{ if (guidHandle.IsAllocated) guidHandle.Free(); if (pepName.IsAllocated) pepName.Free(); if (peerEP.IsAllocated) peerEP.Free(); if (handlePeerEnum != null) handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving InternalGetApplications(). " + "Returning collection with {0} applications.", peerAppColl.Count); return peerAppColl; } //// // // // // // // // // // // // // // // // // [System.Security.SecurityCritical] public PeerObjectCollection GetObjects(PeerEndPoint peerEndPoint) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetObjects(Guid.Empty, false, peerEndPoint); } //// // [System.Security.SecurityCritical] public PeerObjectCollection GetObjects(PeerEndPoint peerEndPoint, Guid objectId) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerEndPoint == null) throw new ArgumentNullException("peerEndPoint"); return InternalGetObjects(objectId, true, peerEndPoint); } internal override void RefreshIfNeeded() { } private event EventHandler// m_applicationChanged; public event EventHandler ApplicationChanged { // // [System.Security.SecurityCritical] add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); AddApplicationChanged(value); } //// // [System.Security.SecurityCritical] remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); RemoveApplicationChanged(value); } } #region Application changed event variables private object m_lockAppChangedEvent; internal object LockAppChangedEvent { get{ if (m_lockAppChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref m_lockAppChangedEvent, o, null); } return m_lockAppChangedEvent; } } private RegisteredWaitHandle m_regAppChangedWaitHandle; internal RegisteredWaitHandle AppChangedWaitHandle { set{ m_regAppChangedWaitHandle = value; } } private AutoResetEvent m_appChangedEvent; internal AutoResetEvent AppChangedEvent { get{ return m_appChangedEvent; } set{ m_appChangedEvent = value; } } internal SafeCollabEvent m_safeAppChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddApplicationChanged(EventHandler// // // // // callback) { // // Register a wait handle if one has not been registered already // Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddApplicationChanged()."); lock (LockAppChangedEvent) { if (m_applicationChanged == null){ m_appChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // AppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_appChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(ApplicationChangedCallback), //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.EndPointApplicationChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( m_appChangedEvent.SafeWaitHandle, 1, ref pcer, out m_safeAppChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode); } } m_applicationChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemoveApplicationChanged(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() called."); lock (LockAppChangedEvent){ m_applicationChanged -= callback; if (m_applicationChanged == null){ CleanContactAppEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactAppEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regAppChangedWaitHandle, ref m_safeAppChangedEvent, ref m_appChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ApplicationChanged variables successful."); } protected virtual void OnApplicationChanged(ApplicationChangedEventArgs appChangedArgs) { EventHandler// // handlerCopy = m_applicationChanged; if (handlerCopy != null){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, appChangedArgs }); else handlerCopy(this, appChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the application changed event callback."); } } // // [System.Security.SecurityCritical] internal virtual void ApplicationChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ApplicationChangedCallback() called."); if (m_Disposed) return; while (true) { ApplicationChangedEventArgs appChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockAppChangedEvent){ if (m_safeAppChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeAppChangedEvent, 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_GetApplicationChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.EndPointApplicationChanged){ PEER_EVENT_APPLICATION_CHANGED_DATA appData = ped.applicationChangedData; PeerContact peerContact = null; if (appData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(appData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if (peerContact != null && Equals(peerContact)){ PEER_APPLICATION pa = (PEER_APPLICATION)Marshal.PtrToStructure(appData.pApplication, typeof(PEER_APPLICATION)); PeerApplication peerApplication = CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(pa); ; PeerEndPoint peerEndPoint = null; if (appData.pEndPoint != IntPtr.Zero){ PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(appData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } appChangedArgs = new ApplicationChangedEventArgs( peerEndPoint, peerContact, appData.changeType, peerApplication); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if(appChangedArgs != null) OnApplicationChanged(appChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ApplicationChangedCallback()."); } 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; internal 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; internal RegisteredWaitHandle ObjChangedWaitHandle { set{ m_regObjChangedWaitHandle = value; } } private AutoResetEvent m_objChangedEvent; internal AutoResetEvent ObjChangedEvent { get{ return m_objChangedEvent; } set{ m_objChangedEvent = value; } } internal SafeCollabEvent m_safeObjChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddObjectChangedEvent(EventHandler// // // // // callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddObjectChangedEvent()."); // // Register a wait handle if one has not been registered already // lock (LockObjChangedEvent){ if (m_objectChanged == null){ m_objChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // ObjChangedWaitHandle = 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; pcer.pInstance = IntPtr.Zero; // // Register event with collab // 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); } } m_objectChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemoveObjectChangedEvent(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() called."); lock (LockObjChangedEvent){ m_objectChanged -= callback; if (m_objectChanged == null){ CleanContactObjEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactObjEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle, ref m_safeObjChangedEvent, ref m_objChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables 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."); } } // // [System.Security.SecurityCritical] internal virtual void ObjectChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called."); if (m_Disposed) return; while (true){ ObjectChangedEventArgs objChangedArgs = 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; PeerContact peerContact = null; if (objData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(objData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if (peerContact != null && Equals(peerContact)){ PeerEndPoint peerEndPoint = null; if (objData.pEndPoint != IntPtr.Zero) { PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(objData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT)); PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po); ; objChangedArgs = new ObjectChangedEventArgs(peerEndPoint, peerContact, objData.changeType, peerObject); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if(objChangedArgs != null) OnObjectChanged(objChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback()."); } private event EventHandler// // // // // // // // // // // m_presenceChanged; public event EventHandler PresenceChanged { // // [System.Security.SecurityCritical] add { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); AddPresenceChanged(value); } //// // [System.Security.SecurityCritical] remove { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); RemovePresenceChanged(value); } } #region Presence changed event variables private object m_lockPresenceChangedEvent; internal object LockPresenceChangedEvent { get { if (m_lockPresenceChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref m_lockPresenceChangedEvent, o, null); } return m_lockPresenceChangedEvent; } } private RegisteredWaitHandle m_regPresenceChangedWaitHandle; internal RegisteredWaitHandle PresenceChangedWaitHandle { set{ m_regPresenceChangedWaitHandle = value; } } private AutoResetEvent m_presenceChangedEvent; internal AutoResetEvent PresenceChangedEvent { get{ return m_presenceChangedEvent; } set{ m_presenceChangedEvent = value; } } internal SafeCollabEvent m_safePresenceChangedEvent; #endregion //// // [System.Security.SecurityCritical] internal virtual void AddPresenceChanged(EventHandler// // // // // callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddPresenceChanged()."); // // Register a wait handle if one has not been registered already // lock (LockPresenceChangedEvent){ if (m_presenceChanged == null){ m_presenceChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // PresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_presenceChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(PresenceChangedCallback), //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.EndPointPresenceChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( m_presenceChangedEvent.SafeWaitHandle, 1, ref pcer, out m_safePresenceChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode); } } m_presenceChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddPresenceChanged() successful."); } // // [System.Security.SecurityCritical] internal virtual void RemovePresenceChanged(EventHandler// callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() called."); lock (LockPresenceChangedEvent){ m_presenceChanged -= callback; if (m_presenceChanged == null){ CleanContactPresenceEventVars(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() successful."); } // // [System.Security.SecurityCritical] internal void CleanContactPresenceEventVars() { CollaborationHelperFunctions.CleanEventVars(ref m_regPresenceChangedWaitHandle, ref m_safePresenceChangedEvent, ref m_presenceChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PresenceChanged variables successful."); } protected virtual void OnPresenceChanged(PresenceChangedEventArgs presenceChangedArgs) { EventHandler// // handlerCopy = m_presenceChanged; if (handlerCopy != null){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, presenceChangedArgs }); else handlerCopy(this, presenceChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the presence changed event callback."); } } // // [System.Security.SecurityCritical] internal virtual void PresenceChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "PresenceChangedCallback() called."); if (m_Disposed) return; while (true){ PresenceChangedEventArgs presenceChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockPresenceChangedEvent){ if (m_safePresenceChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safePresenceChangedEvent, 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_GetPresenceChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.EndPointPresenceChanged){ PEER_EVENT_PRESENCE_CHANGED_DATA presenceData = ped.presenceChangedData; PeerContact peerContact = null; if (presenceData.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(presenceData.pContact, typeof(PEER_CONTACT)); peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } if ((peerContact != null) && Equals(peerContact)){ PeerEndPoint peerEndPoint = null; if (presenceData.pEndPoint != IntPtr.Zero){ PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(presenceData.pEndPoint, typeof(PEER_ENDPOINT)); peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); } PeerPresenceInfo peerPresenceInfo = null; if (presenceData.pPresenceInfo != IntPtr.Zero){ PEER_PRESENCE_INFO ppi = (PEER_PRESENCE_INFO)Marshal.PtrToStructure(presenceData.pPresenceInfo, typeof(PEER_PRESENCE_INFO)); peerPresenceInfo = new PeerPresenceInfo(); peerPresenceInfo.PresenceStatus = ppi.status; peerPresenceInfo.DescriptiveText = ppi.descText; } presenceChangedArgs = new PresenceChangedEventArgs(peerEndPoint, peerContact, presenceData.changeType, peerPresenceInfo); } } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // if (presenceChangedArgs != null) OnPresenceChanged(presenceChangedArgs); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving PresenceChangedCallback()."); } public bool Equals(PeerContact other) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (other != null){ if (other.PeerName != null){ return other.PeerName.Equals(PeerName); } else if (PeerName == null) return true; } return false; } public override bool Equals(object obj) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); PeerContact comparandPeerContact = obj as PeerContact; if (comparandPeerContact != null){ return Equals(comparandPeerContact); } return false; } public new static bool Equals(object objA, object objB) { PeerContact comparandPeerContact1 = objA as PeerContact; PeerContact comparandPeerContact2 = objB as PeerContact; if ((comparandPeerContact1 != null) && (comparandPeerContact2 != null)) { if (comparandPeerContact1.PeerName != null){ return comparandPeerContact1.PeerName.Equals(comparandPeerContact2.PeerName); } else if (comparandPeerContact2.PeerName == null) return true; } return false; } public override int GetHashCode() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); return ((PeerName == null) ? 0 : PeerName.GetHashCode()); } public override string ToString() { return m_displayName; } private bool m_Disposed; //// // // // // // // // // // // [System.Security.SecurityCritical] protected override void Dispose(bool disposing) { if (!m_Disposed){ try{ CleanContactAppEventVars(); CleanContactObjEventVars(); CleanContactPresenceEventVars(); m_Disposed = true; } finally{ base.Dispose(disposing); } } } //// // // // [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 override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("_PeerName", m_peerName); info.AddValue("_NickName", m_nickname); info.AddValue("_DisplayName", m_displayName); if(m_emailAddress != null) info.AddValue("_EmailAddress", m_emailAddress.ToString()); info.AddValue("_SubscribeAllowed", m_subscribeAllowed); info.AddValue("_Credentials", m_credentials.RawData); info.AddValue("_ContactXml", m_contactXml); info.AddValue("_JustCreated", m_justCreated); } // // Tracing information for Peer Contact // internal void TracePeerContact() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Contents of the PeerContact"); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tPeerName: {0}", PeerName); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tNickname: {0}", Nickname); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tEmailAddress: {0}", EmailAddress.ToString()); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tSubscribeAllowed: {0}", SubscribeAllowed); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials FriendlyName: {0}", Credentials.FriendlyName); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Verbose)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials raw data:"); Logging.DumpData(Logging.P2PTraceSource, TraceEventType.Verbose, Logging.P2PTraceSource.MaxDataSize, Credentials.RawData, 0, Credentials.RawData.Length); } else{ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "\tCredentials raw data length {0}", Credentials.RawData.Length); } } } // // Manages collection of peer contacts // [Serializable] public class PeerContactCollection : Collection{ internal PeerContactCollection() { } protected override void SetItem(int index, PeerContact item) { // nulls not allowed if (item == null){ throw new ArgumentNullException("item"); } base.SetItem(index, item); } protected override void InsertItem(int index, PeerContact 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 (PeerContact peerContact in this) { if (!first){ builder.Append(", "); } else{ first = false; } builder.Append(peerContact.ToString()); } return builder.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TypedTableBase.cs
- ClientSession.cs
- PenCursorManager.cs
- DataGridCheckBoxColumn.cs
- wmiprovider.cs
- SuppressMergeCheckAttribute.cs
- TypeDescriptor.cs
- DbFunctionCommandTree.cs
- SourceLocation.cs
- CTreeGenerator.cs
- FunctionNode.cs
- SerTrace.cs
- SqlEnums.cs
- XmlName.cs
- WmlCommandAdapter.cs
- ExpressionPrefixAttribute.cs
- wmiprovider.cs
- FileDialog_Vista.cs
- IntSecurity.cs
- indexingfiltermarshaler.cs
- MimeMapping.cs
- XsltArgumentList.cs
- DataGridViewTextBoxCell.cs
- ParentUndoUnit.cs
- DataGridViewCell.cs
- ErrorsHelper.cs
- RelationshipWrapper.cs
- HtmlFormWrapper.cs
- StringPropertyBuilder.cs
- TokenizerHelper.cs
- DataGridViewColumnHeaderCell.cs
- HyperLinkField.cs
- PersonalizationStateQuery.cs
- Parser.cs
- FakeModelPropertyImpl.cs
- WaitHandleCannotBeOpenedException.cs
- RootBrowserWindowAutomationPeer.cs
- ScopelessEnumAttribute.cs
- SymbolDocumentGenerator.cs
- ObjectListDesigner.cs
- SectionUpdates.cs
- MetadataCache.cs
- ConfigurationValues.cs
- SchemaObjectWriter.cs
- InvalidMessageContractException.cs
- ReliableDuplexSessionChannel.cs
- Image.cs
- ContextMenuStrip.cs
- IdentityModelDictionary.cs
- ModuleBuilder.cs
- BamlReader.cs
- DllHostedComPlusServiceHost.cs
- ChannelManager.cs
- ShaderRenderModeValidation.cs
- DataColumnCollection.cs
- HttpPostLocalhostServerProtocol.cs
- RenderCapability.cs
- WebContentFormatHelper.cs
- PinnedBufferMemoryStream.cs
- Popup.cs
- WebRequestModuleElementCollection.cs
- ReturnType.cs
- DataGrid.cs
- DoubleLink.cs
- MethodBuilderInstantiation.cs
- WebServiceClientProxyGenerator.cs
- CertificateManager.cs
- RelationshipNavigation.cs
- PermissionListSet.cs
- _KerberosClient.cs
- SqlUDTStorage.cs
- ScrollPattern.cs
- SiteMapNode.cs
- ClientBuildManagerCallback.cs
- ObjectAnimationUsingKeyFrames.cs
- SecureStringHasher.cs
- WSSecurityOneDotZeroSendSecurityHeader.cs
- CustomLineCap.cs
- TransformerTypeCollection.cs
- DataListComponentEditor.cs
- ResolvePPIDRequest.cs
- NativeDirectoryServicesQueryAPIs.cs
- EntityTemplateFactory.cs
- AsymmetricSignatureFormatter.cs
- MenuCommand.cs
- Calendar.cs
- SdlChannelSink.cs
- DesignTimeSiteMapProvider.cs
- ProfessionalColors.cs
- ComboBoxAutomationPeer.cs
- BitmapCodecInfo.cs
- DocumentViewerBaseAutomationPeer.cs
- InputBuffer.cs
- CodeCompileUnit.cs
- IgnoreDeviceFilterElement.cs
- NotifyParentPropertyAttribute.cs
- LocatorBase.cs
- Panel.cs
- MouseEvent.cs
- InheritanceAttribute.cs