e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
2080 lines
98 KiB
C#
2080 lines
98 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="Peer.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
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.Diagnostics.CodeAnalysis;
|
|
using System.Runtime.Serialization;
|
|
using System.Security.Permissions;
|
|
|
|
/// <summary>
|
|
/// This is the event args class we give back when
|
|
/// we have an application change event triggered by native
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This class incorporates the contact functions of a peer collaboration
|
|
/// contact
|
|
/// </summary>
|
|
[Serializable]
|
|
public class PeerContact : Peer, IEquatable<PeerContact>, 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
|
|
{
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <UsesUnsafeCode Name="Local pEndPoints of type: IntPtr*" />
|
|
// <UsesUnsafeCode Name="Method: IntPtr.op_Explicit(System.IntPtr):System.Void*" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabEnumEndpoints(System.Net.PeerToPeer.Collaboration.PEER_CONTACT&,System.Net.PeerToPeer.Collaboration.SafeCollabEnum&):System.Int32" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetItemCount(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&):System.Int32" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetNextItem(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local handlePeerEnum of type: SafeCollabEnum" Ring="1" />
|
|
// <ReferencesCritical Name="Local safeCredentials of type: SafeCollabMemory" Ring="1" />
|
|
// <ReferencesCritical Name="Local epArray of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPeerContactToPEER_CONTACT(System.Net.PeerToPeer.Collaboration.PeerContact,System.Net.PeerToPeer.Collaboration.SafeCollabMemory&):System.Net.PeerToPeer.Collaboration.PEER_CONTACT" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
}
|
|
}
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.Initialize():System.Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
static PeerContact()
|
|
{
|
|
CollaborationHelperFunctions.Initialize();
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.Initialize():System.Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal PeerContact() {
|
|
OnSubscribeCompletedDelegate = new SendOrPostCallback(SubscribeCompletedWaitCallback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor to enable serialization
|
|
/// </summary>
|
|
[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");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabExportContact(System.String,System.String&):System.Int32" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabParseContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local contact of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.Initialize():System.Void" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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<SubscribeCompletedEventArgs> m_subscribeCompleted;
|
|
public event EventHandler<SubscribeCompletedEventArgs> 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<SubscribeCompletedEventArgs> 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().");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.get_CurrentApplicationGuid():System.Guid" Ring="1" />
|
|
// <ReferencesCritical Name="Method: InternalInviteAllEndPoints(PeerEndPointCollection, String, Byte[], Guid):PeerInvitationResponse" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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);
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: InternalInviteAllEndPoints(PeerEndPointCollection, String, Byte[], Guid):PeerInvitationResponse" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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);
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteEndPoint(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPoint,System.Net.PeerToPeer.Collaboration.PeerContact):System.Net.PeerToPeer.Collaboration.PeerInvitationResponse" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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));
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.get_CurrentApplicationGuid():System.Guid" Ring="1" />
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteEndPoint(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPoint,System.Net.PeerToPeer.Collaboration.PeerContact):System.Net.PeerToPeer.Collaboration.PeerInvitationResponse" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteEndPoint(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPoint,System.Net.PeerToPeer.Collaboration.PeerContact):System.Net.PeerToPeer.Collaboration.PeerInvitationResponse" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
}
|
|
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.get_CurrentApplicationGuid():System.Guid" Ring="1" />
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteAsync(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPointCollection,System.Net.PeerToPeer.Collaboration.PeerContact,System.Object):System.Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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);
|
|
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteAsync(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPointCollection,System.Net.PeerToPeer.Collaboration.PeerContact,System.Object):System.Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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);
|
|
}
|
|
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.get_CurrentApplicationGuid():System.Guid" Ring="1" />
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteAsync(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPointCollection,System.Net.PeerToPeer.Collaboration.PeerContact,System.Object):System.Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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);
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: Peer.InternalInviteAsync(System.Guid,System.String,System.Byte[],System.Net.PeerToPeer.Collaboration.PeerEndPointCollection,System.Net.PeerToPeer.Collaboration.PeerContact,System.Object):System.Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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
|
|
//
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: InternalGetAllApplications(Guid, Boolean):PeerApplicationCollection" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
public PeerApplicationCollection GetApplications()
|
|
{
|
|
return InternalGetAllApplications(Guid.Empty, false);
|
|
}
|
|
|
|
//
|
|
// Gets specfic application for all endpoints for this contact
|
|
//
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: InternalGetAllApplications(Guid, Boolean):PeerApplicationCollection" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
public PeerApplicationCollection GetApplications(Guid applicationId)
|
|
{
|
|
return InternalGetAllApplications(applicationId, true);
|
|
}
|
|
|
|
//
|
|
// Gets all applications for specific endpoint for this contact
|
|
//
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: InternalGetApplications(Guid, Boolean, PeerEndPoint):PeerApplicationCollection" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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
|
|
//
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: InternalGetApplications(Guid, Boolean, PeerEndPoint):PeerApplicationCollection" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
public PeerApplicationCollection GetApplications(PeerEndPoint peerEndPoint, Guid applicationId)
|
|
{
|
|
if (peerEndPoint == null)
|
|
throw new ArgumentNullException("peerEndPoint");
|
|
|
|
return InternalGetApplications(applicationId, true, peerEndPoint);
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: InternalGetApplications(Guid, Boolean, PeerEndPoint):PeerApplicationCollection" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
private PeerApplicationCollection InternalGetAllApplications(Guid applicationId, bool guidSupplied)
|
|
{
|
|
Dictionary<Guid, PeerApplication> mergedApplications = new Dictionary<Guid, PeerApplication>();
|
|
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<Guid, PeerApplication>.ValueCollection applications = mergedApplications.Values;
|
|
peerApplicationCollection = new PeerApplicationCollection();
|
|
foreach (PeerApplication peerApplication in applications)
|
|
{
|
|
peerApplicationCollection.Add(peerApplication);
|
|
}
|
|
|
|
return peerApplicationCollection;
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <UsesUnsafeCode Name="Local pApps of type: IntPtr*" />
|
|
// <UsesUnsafeCode Name="Local pPeerApp of type: PEER_APPLICATION*" />
|
|
// <UsesUnsafeCode Name="Method: IntPtr.op_Explicit(System.IntPtr):System.Void*" />
|
|
// <SatisfiesLinkDemand Name="GCHandle.Alloc(System.Object,System.Runtime.InteropServices.GCHandleType):System.Runtime.InteropServices.GCHandle" />
|
|
// <SatisfiesLinkDemand Name="GCHandle.AddrOfPinnedObject():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
|
|
// <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
|
|
// <SatisfiesLinkDemand Name="GCHandle.Free():System.Void" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabEnumApplications(System.IntPtr,System.IntPtr,System.Net.PeerToPeer.Collaboration.SafeCollabEnum&):System.Int32" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetItemCount(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&):System.Int32" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetNextItem(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local handlePeerEnum of type: SafeCollabEnum" Ring="1" />
|
|
// <ReferencesCritical Name="Local appArray of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.InternalGetObjects(System.Guid,System.Boolean,System.Net.PeerToPeer.Collaboration.PeerEndPoint):System.Net.PeerToPeer.Collaboration.PeerObjectCollection" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
public PeerObjectCollection GetObjects(PeerEndPoint peerEndPoint)
|
|
{
|
|
PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
|
|
|
|
if (peerEndPoint == null)
|
|
throw new ArgumentNullException("peerEndPoint");
|
|
|
|
return InternalGetObjects(Guid.Empty, false, peerEndPoint);
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: Peer.InternalGetObjects(System.Guid,System.Boolean,System.Net.PeerToPeer.Collaboration.PeerEndPoint):System.Net.PeerToPeer.Collaboration.PeerObjectCollection" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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<ApplicationChangedEventArgs> m_applicationChanged;
|
|
public event EventHandler<ApplicationChangedEventArgs> ApplicationChanged
|
|
{
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: AddApplicationChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.ApplicationChangedEventArgs>):Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
add
|
|
{
|
|
if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
|
|
|
|
PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
|
|
|
|
AddApplicationChanged(value);
|
|
}
|
|
// <SecurityKernel Critical="True" Ring="3">
|
|
// <ReferencesCritical Name="Method: RemoveApplicationChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.ApplicationChangedEventArgs>):Void" Ring="3" />
|
|
// </SecurityKernel>
|
|
[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
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
|
|
// <ReferencesCritical Name="Method: ApplicationChangedCallback(Object, Boolean):Void" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void AddApplicationChanged(EventHandler<ApplicationChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: CleanContactAppEventVars():Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void RemoveApplicationChanged(EventHandler<ApplicationChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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<ApplicationChangedEventArgs> 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.");
|
|
}
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(System.Net.PeerToPeer.Collaboration.PEER_APPLICATION):System.Net.PeerToPeer.Collaboration.PeerApplication" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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<ObjectChangedEventArgs> m_objectChanged;
|
|
public event EventHandler<ObjectChangedEventArgs> ObjectChanged
|
|
{
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: AddObjectChangedEvent(EventHandler`1<System.Net.PeerToPeer.Collaboration.ObjectChangedEventArgs>):Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
add
|
|
{
|
|
if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
|
|
|
|
PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
|
|
|
|
AddObjectChangedEvent(value);
|
|
}
|
|
// <SecurityKernel Critical="True" Ring="3">
|
|
// <ReferencesCritical Name="Method: RemoveObjectChangedEvent(EventHandler`1<System.Net.PeerToPeer.Collaboration.ObjectChangedEventArgs>):Void" Ring="3" />
|
|
// </SecurityKernel>
|
|
[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
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
|
|
// <ReferencesCritical Name="Method: ObjectChangedCallback(Object, Boolean):Void" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void AddObjectChangedEvent(EventHandler<ObjectChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: CleanContactObjEventVars():Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void RemoveObjectChangedEvent(EventHandler<ObjectChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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<ObjectChangedEventArgs> 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.");
|
|
}
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(System.Net.PeerToPeer.Collaboration.PEER_OBJECT):System.Net.PeerToPeer.Collaboration.PeerObject" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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<PresenceChangedEventArgs> m_presenceChanged;
|
|
public event EventHandler<PresenceChangedEventArgs> PresenceChanged
|
|
{
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Method: AddPresenceChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.PresenceChangedEventArgs>):Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
add
|
|
{
|
|
if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
|
|
|
|
PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
|
|
|
|
AddPresenceChanged(value);
|
|
}
|
|
// <SecurityKernel Critical="True" Ring="3">
|
|
// <ReferencesCritical Name="Method: RemovePresenceChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.PresenceChangedEventArgs>):Void" Ring="3" />
|
|
// </SecurityKernel>
|
|
[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
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
|
|
// <ReferencesCritical Name="Method: PresenceChangedCallback(Object, Boolean):Void" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void AddPresenceChanged(EventHandler<PresenceChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: CleanContactPresenceEventVars():Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
internal virtual void RemovePresenceChanged(EventHandler<PresenceChangedEventArgs> 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.");
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="1">
|
|
// <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
|
|
// </SecurityKernel>
|
|
[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<PresenceChangedEventArgs> 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.");
|
|
}
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
|
|
// <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
|
|
// <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
|
|
// <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
|
|
// <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
|
|
// <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
|
|
// <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
|
|
// <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
|
|
// </SecurityKernel>
|
|
[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;
|
|
|
|
// <SecurityKernel Critical="True" Ring="2">
|
|
// <ReferencesCritical Name="Method: CleanContactAppEventVars():Void" Ring="2" />
|
|
// <ReferencesCritical Name="Method: CleanContactObjEventVars():Void" Ring="2" />
|
|
// <ReferencesCritical Name="Method: CleanContactPresenceEventVars():Void" Ring="2" />
|
|
// </SecurityKernel>
|
|
[System.Security.SecurityCritical]
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (!m_Disposed){
|
|
try{
|
|
CleanContactAppEventVars();
|
|
CleanContactObjEventVars();
|
|
CleanContactPresenceEventVars();
|
|
m_Disposed = true;
|
|
}
|
|
finally{
|
|
base.Dispose(disposing);
|
|
}
|
|
}
|
|
}
|
|
|
|
// <SecurityKernel Critical="True" Ring="0">
|
|
// <SatisfiesLinkDemand Name="Peer.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext):System.Void" />
|
|
// </SecurityKernel>
|
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.Net.dll is still using pre-v4 security model and needs this demand")]
|
|
[System.Security.SecurityCritical]
|
|
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter, SerializationFormatter = true)]
|
|
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
GetObjectData(info, context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is made virtual so that derived types can be implemented correctly
|
|
/// </summary>
|
|
[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<PeerContact>
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
}
|