1 //------------------------------------------------------------------------------
2 // <copyright file="ContactManager.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Net.PeerToPeer.Collaboration
10 using System.Net.Sockets;
11 using System.Collections.Specialized;
12 using System.Collections.Generic;
14 using System.Runtime.InteropServices;
15 using System.Net.Mail;
16 using System.Security.Cryptography.X509Certificates;
17 using System.ComponentModel;
18 using System.Threading;
19 using System.Diagnostics;
22 /// This is the event args class we give back when
23 /// we have completed the createcontactasync call
25 public class CreateContactCompletedEventArgs : AsyncCompletedEventArgs
27 private PeerContact m_peerContact;
28 internal CreateContactCompletedEventArgs( PeerContact peerContact,
32 : base(error, cancelled, userToken)
34 m_peerContact = peerContact;
37 public PeerContact PeerContact
46 /// This is the event args class we give back when
47 /// we have a subscription changed event from native
49 public class SubscriptionListChangedEventArgs : EventArgs
51 private PeerEndPoint m_peerEndPoint;
52 private PeerContact m_peerContact;
53 private PeerChangeType m_peerChangeType;
55 internal SubscriptionListChangedEventArgs(PeerEndPoint peerEndPoint, PeerContact peerContact,
56 PeerChangeType peerChangeType)
58 m_peerEndPoint = peerEndPoint;
59 m_peerContact = peerContact;
60 m_peerChangeType = peerChangeType;
63 public PeerEndPoint PeerEndPoint
67 return m_peerEndPoint;
71 public PeerContact PeerContact
79 public PeerChangeType PeerChangeType
83 return m_peerChangeType;
90 /// This class handles all the operation related to contacts and thier storage in the
91 /// Windows Address Book
93 public sealed class ContactManager : IDisposable
95 private ISynchronizeInvoke m_synchronizingObject;
97 // <SecurityKernel Critical="True" Ring="1">
98 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.Initialize():System.Void" Ring="1" />
100 [System.Security.SecurityCritical]
101 internal ContactManager()
103 CollaborationHelperFunctions.Initialize();
105 OnCreateContactCompletedDelegate = new SendOrPostCallback(CreateContactCompletedWaitCallback);
109 // Returns the peer collaboration users' contact
111 public static PeerContact LocalContact
113 // <SecurityKernel Critical="True" Ring="0">
114 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
115 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
116 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
117 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
118 // <ReferencesCritical Name="Local contact of type: SafeCollabData" Ring="1" />
119 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.Initialize():System.Void" Ring="1" />
120 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT,System.Boolean):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="1" />
122 [System.Security.SecurityCritical]
125 SafeCollabData contact = null;
129 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Get MyContact called.");
131 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
132 CollaborationHelperFunctions.Initialize();
136 // Get my contact from native with null peer name
139 int errorCode = UnsafeCollabNativeMethods.PeerCollabGetContact(null, out contact);
141 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0,
142 "PeerCollabGetContact returned with errorcode {0}", errorCode);
145 pc = (PEER_CONTACT)Marshal.PtrToStructure(contact.DangerousGetHandle(), typeof(PEER_CONTACT));
146 myContact = (MyContact) CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc, true);
149 if (contact != null) contact.Dispose();
152 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Get MyContact successful.");
159 /// Gets and set the object used to marshall event handlers calls for stand alone
162 [Browsable(false), DefaultValue(null), Description(SR.SynchronizingObject)]
163 public ISynchronizeInvoke SynchronizingObject
167 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
168 return m_synchronizingObject;
172 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
173 m_synchronizingObject = value;
177 private event EventHandler<SubscriptionListChangedEventArgs> m_subscriptionListChanged;
178 public event EventHandler<SubscriptionListChangedEventArgs> SubscriptionListChanged
180 // <SecurityKernel Critical="True" Ring="1">
181 // <ReferencesCritical Name="Method: AddSubscriptionListChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.SubscriptionListChangedEventArgs>):Void" Ring="1" />
183 [System.Security.SecurityCritical]
186 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
188 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
190 AddSubscriptionListChanged(value);
192 // <SecurityKernel Critical="True" Ring="2">
193 // <ReferencesCritical Name="Method: RemoveSubscriptionListChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.SubscriptionListChangedEventArgs>):Void" Ring="2" />
195 [System.Security.SecurityCritical]
198 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
200 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
202 RemoveSubscriptionListChanged(value);
206 #region Subcription list changed event variables
207 private object m_lockSubLstChangedEvent;
208 private object LockSubLstChangedEvent
211 if (m_lockSubLstChangedEvent == null){
212 object o = new object();
213 Interlocked.CompareExchange(ref m_lockSubLstChangedEvent, o, null);
215 return m_lockSubLstChangedEvent;
219 private RegisteredWaitHandle m_regSubLstChangedWaitHandle;
220 private AutoResetEvent m_subLstChangedEvent;
221 private SafeCollabEvent m_safeSubLstChangedEvent;
224 // <SecurityKernel Critical="True" Ring="0">
225 // <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" />
226 // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
227 // <ReferencesCritical Name="Method: SubListChangedCallback(Object, Boolean):Void" Ring="1" />
228 // <ReferencesCritical Name="Field: m_safeSubLstChangedEvent" Ring="1" />
229 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
231 [System.Security.SecurityCritical]
232 private void AddSubscriptionListChanged(EventHandler<SubscriptionListChangedEventArgs> callback)
235 // Register a wait handle if one has not been registered already
238 lock (LockSubLstChangedEvent){
239 if (m_subscriptionListChanged == null){
240 m_subLstChangedEvent = new AutoResetEvent(false);
243 // Register callback with a wait handle
246 m_regSubLstChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_subLstChangedEvent, //Event that triggers the callback
247 new WaitOrTimerCallback(SubListChangedCallback), //callback to be called
248 null, //state to be passed
249 -1, //Timeout - aplicable only for timers
250 false //call us everytime the event is set
252 PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
254 pcer.eventType = PeerCollabEventType.WatchListChanged;
255 pcer.pInstance = IntPtr.Zero;
258 // Register event with collab
261 int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
262 m_subLstChangedEvent.SafeWaitHandle,
265 out m_safeSubLstChangedEvent);
267 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
268 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_SubListChangedRegFailed), errorCode);
271 m_subscriptionListChanged += callback;
274 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddSubscriptionListChanged() successful.");
277 // <SecurityKernel Critical="True" Ring="1">
278 // <ReferencesCritical Name="Field: m_safeSubLstChangedEvent" Ring="1" />
279 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
281 [System.Security.SecurityCritical]
282 private void RemoveSubscriptionListChanged(EventHandler<SubscriptionListChangedEventArgs> callback)
284 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveSubscriptionListChanged() called.");
286 lock (LockSubLstChangedEvent){
287 m_subscriptionListChanged -= callback;
288 if (m_subscriptionListChanged == null){
289 CollaborationHelperFunctions.CleanEventVars(ref m_regSubLstChangedWaitHandle,
290 ref m_safeSubLstChangedEvent,
291 ref m_subLstChangedEvent);
292 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean SubscriptionListChanged variables successful.");
295 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveSubscriptionListChanged() successful.");
298 // <SecurityKernel Critical="True" Ring="0">
299 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
300 // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
301 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
302 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
303 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
304 // <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
305 // <ReferencesCritical Name="Field: m_safeSubLstChangedEvent" Ring="1" />
306 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
307 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
309 [System.Security.SecurityCritical]
310 private void SubListChangedCallback(object state, bool timedOut)
312 SafeCollabData eventData = null;
315 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "SubListChangedCallback() called.");
318 SubscriptionListChangedEventArgs subListChangedArgs = null;
321 // Get the event data for the fired event
324 lock (LockSubLstChangedEvent){
325 if (m_safeSubLstChangedEvent.IsInvalid) return;
326 errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeSubLstChangedEvent,
330 if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA)
332 else if (errorCode != 0){
333 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode);
334 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetSubListChangedDataFailed), errorCode);
337 PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(),
338 typeof(PEER_COLLAB_EVENT_DATA));
340 if (ped.eventType == PeerCollabEventType.WatchListChanged){
341 PEER_EVENT_WATCHLIST_CHANGED_DATA watchlistData = ped.watchListChangedData;
343 PeerContact peerContact = null;
345 if (watchlistData.pContact != IntPtr.Zero){
346 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(watchlistData.pContact, typeof(PEER_CONTACT));
347 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
351 subListChangedArgs = new SubscriptionListChangedEventArgs(null,
353 watchlistData.changeType);
358 if (eventData != null) eventData.Dispose();
362 // Fire the callback with the marshalled event args data
365 EventHandler<SubscriptionListChangedEventArgs> handlerCopy = m_subscriptionListChanged;
367 if ((subListChangedArgs != null) && (handlerCopy != null)){
368 if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
369 SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, subListChangedArgs });
371 handlerCopy(this, subListChangedArgs);
372 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the subscription list changed event callback.");
375 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving SubListChangedCallback().");
378 private event EventHandler<NameChangedEventArgs> m_nameChanged;
379 public event EventHandler<NameChangedEventArgs> NameChanged
381 // <SecurityKernel Critical="True" Ring="1">
382 // <ReferencesCritical Name="Method: AddNameChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.NameChangedEventArgs>):Void" Ring="1" />
384 [System.Security.SecurityCritical]
387 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
389 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
391 AddNameChanged(value);
393 // <SecurityKernel Critical="True" Ring="2">
394 // <ReferencesCritical Name="Method: RemoveNameChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.NameChangedEventArgs>):Void" Ring="2" />
396 [System.Security.SecurityCritical]
399 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
401 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
403 RemoveNameChanged(value);
407 #region Name changed event variables
408 private object m_lockNameChangedEvent;
409 private object LockNameChangedEvent
412 if (m_lockNameChangedEvent == null){
413 object o = new object();
414 Interlocked.CompareExchange(ref m_lockNameChangedEvent, o, null);
416 return m_lockNameChangedEvent;
419 private RegisteredWaitHandle m_regNameChangedWaitHandle;
420 private AutoResetEvent m_nameChangedEvent;
421 private SafeCollabEvent m_safeNameChangedEvent;
424 // <SecurityKernel Critical="True" Ring="0">
425 // <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" />
426 // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
427 // <ReferencesCritical Name="Method: NameChangedCallback(Object, Boolean):Void" Ring="1" />
428 // <ReferencesCritical Name="Field: m_safeNameChangedEvent" Ring="1" />
429 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
431 [System.Security.SecurityCritical]
432 private void AddNameChanged(EventHandler<NameChangedEventArgs> callback)
435 // Register a wait handle if one has not been registered already
438 lock (LockNameChangedEvent){
439 if (m_nameChanged == null){
441 m_nameChangedEvent = new AutoResetEvent(false);
444 // Register callback with a wait handle
447 m_regNameChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_nameChangedEvent, //Event that triggers the callback
448 new WaitOrTimerCallback(NameChangedCallback), //callback to be called
449 null, //state to be passed
450 -1, //Timeout - aplicable only for timers
451 false //call us everytime the event is set
453 PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
455 pcer.eventType = PeerCollabEventType.EndPointChanged;
456 pcer.pInstance = IntPtr.Zero;
459 // Register event with collab
462 int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
463 m_nameChangedEvent.SafeWaitHandle,
466 out m_safeNameChangedEvent);
468 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
469 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_NameChangedRegFailed), errorCode);
472 m_nameChanged += callback;
475 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddNameChanged() successful.");
478 // <SecurityKernel Critical="True" Ring="1">
479 // <ReferencesCritical Name="Field: m_safeNameChangedEvent" Ring="1" />
480 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
482 [System.Security.SecurityCritical]
483 private void RemoveNameChanged(EventHandler<NameChangedEventArgs> callback)
485 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveNameChanged() called.");
486 lock (LockNameChangedEvent){
487 m_nameChanged -= callback;
488 if (m_nameChanged == null){
489 CollaborationHelperFunctions.CleanEventVars(ref m_regNameChangedWaitHandle,
490 ref m_safeNameChangedEvent,
491 ref m_nameChangedEvent);
492 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean NameChanged variables successful.");
495 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveNameChanged() successful.");
498 // <SecurityKernel Critical="True" Ring="0">
499 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
500 // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
501 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
502 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
503 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
504 // <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
505 // <ReferencesCritical Name="Field: m_safeNameChangedEvent" Ring="1" />
506 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
507 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
508 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
510 [System.Security.SecurityCritical]
511 private void NameChangedCallback(object state, bool timedOut)
513 SafeCollabData eventData = null;
516 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "NameChangedCallback() called.");
519 NameChangedEventArgs nameChangedArgs = null;
522 // Get the event data for the fired event
525 lock (LockNameChangedEvent){
526 if (m_safeNameChangedEvent.IsInvalid) return;
527 errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeNameChangedEvent,
530 if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA)
532 else if (errorCode != 0){
533 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode);
534 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetNameChangedDataFailed), errorCode);
537 PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(),
538 typeof(PEER_COLLAB_EVENT_DATA));
540 if (ped.eventType == PeerCollabEventType.EndPointChanged){
541 PEER_EVENT_ENDPOINT_CHANGED_DATA endpointData = ped.endpointChangedData;
543 PeerContact peerContact = null;
544 PeerEndPoint peerEndPoint = null;
545 string newName = null;
547 if (endpointData.pContact != IntPtr.Zero){
548 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(endpointData.pContact, typeof(PEER_CONTACT));
549 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
552 if (endpointData.pEndPoint != IntPtr.Zero){
553 PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(endpointData.pEndPoint, typeof(PEER_ENDPOINT));
554 peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
555 newName = peerEndPoint.Name;
558 nameChangedArgs = new NameChangedEventArgs(peerEndPoint,
564 if(eventData != null) eventData.Dispose();
569 // Fire the callback with the marshalled event args data
572 EventHandler<NameChangedEventArgs> handlerCopy = m_nameChanged;
574 if ((nameChangedArgs != null) && (handlerCopy != null)){
575 if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
576 SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, nameChangedArgs });
578 handlerCopy(this, nameChangedArgs);
579 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the name changed event callback.");
582 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving NameChangedCallback().");
585 private event EventHandler<PresenceChangedEventArgs> m_presenceChanged;
586 public event EventHandler<PresenceChangedEventArgs> PresenceChanged
588 // <SecurityKernel Critical="True" Ring="1">
589 // <ReferencesCritical Name="Method: AddPresenceChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.PresenceChangedEventArgs>):Void" Ring="1" />
591 [System.Security.SecurityCritical]
594 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
596 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
598 AddPresenceChanged(value);
600 // <SecurityKernel Critical="True" Ring="2">
601 // <ReferencesCritical Name="Method: RemovePresenceChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.PresenceChangedEventArgs>):Void" Ring="2" />
603 [System.Security.SecurityCritical]
606 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
608 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
610 RemovePresenceChanged(value);
614 #region Presence changed event variables
615 private object m_lockPresenceChangedEvent;
616 private object LockPresenceChangedEvent
619 if (m_lockPresenceChangedEvent == null){
620 object o = new object();
621 Interlocked.CompareExchange(ref m_lockPresenceChangedEvent, o, null);
623 return m_lockPresenceChangedEvent;
626 private RegisteredWaitHandle m_regPresenceChangedWaitHandle;
627 private AutoResetEvent m_presenceChangedEvent;
628 private SafeCollabEvent m_safePresenceChangedEvent;
631 // <SecurityKernel Critical="True" Ring="0">
632 // <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" />
633 // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
634 // <ReferencesCritical Name="Method: PresenceChangedCallback(Object, Boolean):Void" Ring="1" />
635 // <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
636 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
638 [System.Security.SecurityCritical]
639 private void AddPresenceChanged(EventHandler<PresenceChangedEventArgs> callback)
642 // Register a wait handle if one has not been registered already
645 lock (LockPresenceChangedEvent){
646 if (m_presenceChanged == null){
648 m_presenceChangedEvent = new AutoResetEvent(false);
651 // Register callback with a wait handle
654 m_regPresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_presenceChangedEvent, //Event that triggers the callback
655 new WaitOrTimerCallback(PresenceChangedCallback), //callback to be called
656 null, //state to be passed
657 -1, //Timeout - aplicable only for timers
658 false //call us everytime the event is set
660 PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
661 pcer.eventType = PeerCollabEventType.EndPointPresenceChanged;
662 pcer.pInstance = IntPtr.Zero;
665 // Register event with collab
668 int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
669 m_presenceChangedEvent.SafeWaitHandle,
672 out m_safePresenceChangedEvent);
674 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
675 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode);
678 m_presenceChanged += callback;
681 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddPresenceChanged() successful.");
684 // <SecurityKernel Critical="True" Ring="1">
685 // <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
686 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
688 [System.Security.SecurityCritical]
689 private void RemovePresenceChanged(EventHandler<PresenceChangedEventArgs> callback)
691 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() called.");
693 lock (LockPresenceChangedEvent){
694 m_presenceChanged -= callback;
695 if (m_presenceChanged == null){
696 CollaborationHelperFunctions.CleanEventVars(ref m_regPresenceChangedWaitHandle,
697 ref m_safePresenceChangedEvent,
698 ref m_presenceChangedEvent);
699 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PresenceChanged variables successful.");
703 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() successful.");
706 // <SecurityKernel Critical="True" Ring="0">
707 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
708 // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
709 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
710 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
711 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
712 // <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
713 // <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
714 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
715 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
716 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
718 [System.Security.SecurityCritical]
719 private void PresenceChangedCallback(object state, bool timedOut)
721 SafeCollabData eventData = null;
724 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "PresenceChangedCallback() called.");
727 PresenceChangedEventArgs presenceChangedArgs = null;
729 // Get the event data for the fired event
732 lock (LockPresenceChangedEvent){
733 if (m_safePresenceChangedEvent.IsInvalid) return;
734 errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safePresenceChangedEvent,
737 if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA)
739 else if (errorCode != 0){
740 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode);
741 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetPresenceChangedDataFailed), errorCode);
744 PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(),
745 typeof(PEER_COLLAB_EVENT_DATA));
748 if (ped.eventType == PeerCollabEventType.EndPointPresenceChanged){
749 PEER_EVENT_PRESENCE_CHANGED_DATA presenceData = ped.presenceChangedData;
751 PeerPresenceInfo peerPresenceInfo = null;
752 if (presenceData.pPresenceInfo != IntPtr.Zero){
753 PEER_PRESENCE_INFO ppi = (PEER_PRESENCE_INFO)Marshal.PtrToStructure(presenceData.pPresenceInfo, typeof(PEER_PRESENCE_INFO));
754 peerPresenceInfo = new PeerPresenceInfo();
755 peerPresenceInfo.PresenceStatus = ppi.status;
756 peerPresenceInfo.DescriptiveText = ppi.descText;
759 PeerContact peerContact = null;
760 PeerEndPoint peerEndPoint = null;
762 if (presenceData.pContact != IntPtr.Zero){
763 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(presenceData.pContact, typeof(PEER_CONTACT));
764 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
767 if (presenceData.pEndPoint != IntPtr.Zero){
768 PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(presenceData.pEndPoint, typeof(PEER_ENDPOINT));
769 peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
772 presenceChangedArgs = new PresenceChangedEventArgs(peerEndPoint,
774 presenceData.changeType,
779 if(eventData != null) eventData.Dispose();
783 // Fire the callback with the marshalled event args data
786 EventHandler<PresenceChangedEventArgs> handlerCopy = m_presenceChanged;
788 if ((presenceChangedArgs != null) && (handlerCopy != null)){
789 if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
790 SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, presenceChangedArgs });
792 handlerCopy(this, presenceChangedArgs);
793 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the presence changed event callback.");
796 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving PresenceChangedCallback().");
799 private event EventHandler<ApplicationChangedEventArgs> m_applicationChanged;
800 public event EventHandler<ApplicationChangedEventArgs> ApplicationChanged
802 // <SecurityKernel Critical="True" Ring="1">
803 // <ReferencesCritical Name="Method: AddApplicationChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.ApplicationChangedEventArgs>):Void" Ring="1" />
805 [System.Security.SecurityCritical]
807 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
809 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
811 AddApplicationChanged(value);
813 // <SecurityKernel Critical="True" Ring="2">
814 // <ReferencesCritical Name="Method: RemoveApplicationChanged(EventHandler`1<System.Net.PeerToPeer.Collaboration.ApplicationChangedEventArgs>):Void" Ring="2" />
816 [System.Security.SecurityCritical]
818 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
820 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
822 RemoveApplicationChanged(value);
826 #region Application changed event variables
827 private object m_lockAppChangedEvent;
828 private object LockAppChangedEvent
831 if (m_lockAppChangedEvent == null){
832 object o = new object();
833 Interlocked.CompareExchange(ref m_lockAppChangedEvent, o, null);
835 return m_lockAppChangedEvent;
838 private RegisteredWaitHandle m_regAppChangedWaitHandle;
839 private AutoResetEvent m_appChangedEvent;
840 private SafeCollabEvent m_safeAppChangedEvent;
843 // <SecurityKernel Critical="True" Ring="0">
844 // <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" />
845 // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
846 // <ReferencesCritical Name="Method: ApplicationChangedCallback(Object, Boolean):Void" Ring="1" />
847 // <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
848 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
850 [System.Security.SecurityCritical]
851 private void AddApplicationChanged(EventHandler<ApplicationChangedEventArgs> callback)
854 // Register a wait handle if one has not been registered already
857 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() called.");
859 lock (LockAppChangedEvent){
860 if (m_applicationChanged == null){
862 m_appChangedEvent = new AutoResetEvent(false);
865 // Register callback with a wait handle
868 m_regAppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_appChangedEvent, //Event that triggers the callback
869 new WaitOrTimerCallback(ApplicationChangedCallback), //callback to be called
870 null, //state to be passed
871 -1, //Timeout - aplicable only for timers
872 false //call us everytime the event is set
874 PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
875 pcer.eventType = PeerCollabEventType.EndPointApplicationChanged;
876 pcer.pInstance = IntPtr.Zero;
879 // Register event with collab
882 int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
883 m_appChangedEvent.SafeWaitHandle,
886 out m_safeAppChangedEvent);
888 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
889 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode);
892 m_applicationChanged += callback;
895 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful.");
898 // <SecurityKernel Critical="True" Ring="1">
899 // <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
900 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
902 [System.Security.SecurityCritical]
903 private void RemoveApplicationChanged(EventHandler<ApplicationChangedEventArgs> callback)
905 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() called.");
907 lock (LockAppChangedEvent){
908 m_applicationChanged -= callback;
909 if (m_applicationChanged == null){
910 CollaborationHelperFunctions.CleanEventVars(ref m_regAppChangedWaitHandle,
911 ref m_safeAppChangedEvent,
912 ref m_appChangedEvent);
913 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ApplicationChanged variables successful.");
917 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() successful.");
920 // <SecurityKernel Critical="True" Ring="0">
921 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
922 // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
923 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
924 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
925 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
926 // <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
927 // <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
928 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
929 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(System.Net.PeerToPeer.Collaboration.PEER_APPLICATION):System.Net.PeerToPeer.Collaboration.PeerApplication" Ring="1" />
930 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
931 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
933 [System.Security.SecurityCritical]
934 private void ApplicationChangedCallback(object state, bool timedOut)
936 SafeCollabData eventData = null;
939 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ApplicationChangedCallback() called.");
943 ApplicationChangedEventArgs appChangedArgs = null;
946 // Get the event data for the fired event
950 lock (LockAppChangedEvent){
951 if (m_safeAppChangedEvent.IsInvalid) return;
952 errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeAppChangedEvent,
956 if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA)
958 else if (errorCode != 0){
959 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode);
960 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetApplicationChangedDataFailed), errorCode);
963 PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(),
964 typeof(PEER_COLLAB_EVENT_DATA));
965 if (ped.eventType == PeerCollabEventType.EndPointApplicationChanged){
966 PEER_EVENT_APPLICATION_CHANGED_DATA appData = ped.applicationChangedData;
967 PEER_APPLICATION pa = (PEER_APPLICATION)Marshal.PtrToStructure(appData.pApplication, typeof(PEER_APPLICATION));
969 PeerApplication peerApplication = CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(pa); ;
971 PeerContact peerContact = null;
972 PeerEndPoint peerEndPoint = null;
974 if (appData.pContact != IntPtr.Zero){
975 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(appData.pContact, typeof(PEER_CONTACT));
976 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
979 if (appData.pEndPoint != IntPtr.Zero){
980 PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(appData.pEndPoint, typeof(PEER_ENDPOINT));
981 peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
984 appChangedArgs = new ApplicationChangedEventArgs(peerEndPoint,
991 if(eventData != null) eventData.Dispose();
995 // Fire the callback with the marshalled event args data
998 EventHandler<ApplicationChangedEventArgs> handlerCopy = m_applicationChanged;
1000 if ((appChangedArgs != null) && (handlerCopy != null)){
1001 if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
1002 SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, appChangedArgs });
1004 handlerCopy(this, appChangedArgs);
1005 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the application changed event callback.");
1008 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ApplicationChangedCallback().");
1011 private event EventHandler<ObjectChangedEventArgs> m_objectChanged;
1012 public event EventHandler<ObjectChangedEventArgs> ObjectChanged
1014 // <SecurityKernel Critical="True" Ring="1">
1015 // <ReferencesCritical Name="Method: AddObjectChangedEvent(EventHandler`1<System.Net.PeerToPeer.Collaboration.ObjectChangedEventArgs>):Void" Ring="1" />
1016 // </SecurityKernel>
1017 [System.Security.SecurityCritical]
1020 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1022 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1024 AddObjectChangedEvent(value);
1026 // <SecurityKernel Critical="True" Ring="2">
1027 // <ReferencesCritical Name="Method: RemoveObjectChangedEvent(EventHandler`1<System.Net.PeerToPeer.Collaboration.ObjectChangedEventArgs>):Void" Ring="2" />
1028 // </SecurityKernel>
1029 [System.Security.SecurityCritical]
1032 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1034 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1036 RemoveObjectChangedEvent(value);
1040 #region Object changed event variables
1041 private object m_lockObjChangedEvent;
1042 private object LockObjChangedEvent
1045 if (m_lockObjChangedEvent == null){
1046 object o = new object();
1047 Interlocked.CompareExchange(ref m_lockObjChangedEvent, o, null);
1049 return m_lockObjChangedEvent;
1052 private RegisteredWaitHandle m_regObjChangedWaitHandle;
1053 private AutoResetEvent m_objChangedEvent;
1054 private SafeCollabEvent m_safeObjChangedEvent;
1057 // <SecurityKernel Critical="True" Ring="0">
1058 // <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" />
1059 // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
1060 // <ReferencesCritical Name="Method: ObjectChangedCallback(Object, Boolean):Void" Ring="1" />
1061 // <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
1062 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1063 // </SecurityKernel>
1064 [System.Security.SecurityCritical]
1065 private void AddObjectChangedEvent(EventHandler<ObjectChangedEventArgs> callback)
1068 // Register a wait handle if one has not been registered already
1071 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChangedEvent() called.");
1073 lock (LockObjChangedEvent){
1074 if (m_objectChanged == null){
1076 m_objChangedEvent = new AutoResetEvent(false);
1079 // Register callback with a wait handle
1082 m_regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_objChangedEvent, //Event that triggers the callback
1083 new WaitOrTimerCallback(ObjectChangedCallback), //callback to be called
1084 null, //state to be passed
1085 -1, //Timeout - aplicable only for timers
1086 false //call us everytime the event is set
1088 PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
1089 pcer.eventType = PeerCollabEventType.EndPointObjectChanged;
1090 pcer.pInstance = IntPtr.Zero;
1093 // Register event with collab
1096 int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
1097 m_objChangedEvent.SafeWaitHandle,
1100 out m_safeObjChangedEvent);
1101 if (errorCode != 0){
1102 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
1103 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode);
1106 m_objectChanged += callback;
1109 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful.");
1112 // <SecurityKernel Critical="True" Ring="1">
1113 // <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
1114 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
1115 // </SecurityKernel>
1116 [System.Security.SecurityCritical]
1117 private void RemoveObjectChangedEvent(EventHandler<ObjectChangedEventArgs> callback)
1119 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() called.");
1121 lock (LockObjChangedEvent){
1122 m_objectChanged -= callback;
1123 if (m_objectChanged == null){
1124 CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle,
1125 ref m_safeObjChangedEvent,
1126 ref m_objChangedEvent);
1127 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChanged variables successful.");
1131 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() successful.");
1134 // <SecurityKernel Critical="True" Ring="0">
1135 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetEventData(System.Net.PeerToPeer.Collaboration.SafeCollabEvent,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
1136 // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
1137 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
1138 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
1139 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1140 // <ReferencesCritical Name="Local eventData of type: SafeCollabData" Ring="1" />
1141 // <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
1142 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1143 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(System.Net.PeerToPeer.Collaboration.PEER_OBJECT):System.Net.PeerToPeer.Collaboration.PeerObject" Ring="1" />
1144 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(System.Net.PeerToPeer.Collaboration.PEER_ENDPOINT):System.Net.PeerToPeer.Collaboration.PeerEndPoint" Ring="1" />
1145 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
1146 // </SecurityKernel>
1147 [System.Security.SecurityCritical]
1148 private void ObjectChangedCallback(object state, bool timedOut)
1150 SafeCollabData eventData = null;
1153 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called.");
1157 ObjectChangedEventArgs objectChangedArgs = null;
1160 // Get the event data for the fired event
1163 lock (LockObjChangedEvent){
1164 if (m_safeObjChangedEvent.IsInvalid) return;
1165 errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(m_safeObjChangedEvent,
1168 if (errorCode == UnsafeCollabReturnCodes.PEER_S_NO_EVENT_DATA)
1170 else if (errorCode != 0){
1171 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEventData returned with errorcode {0}", errorCode);
1172 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetObjectChangedDataFailed), errorCode);
1175 PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(),
1176 typeof(PEER_COLLAB_EVENT_DATA));
1178 if (ped.eventType == PeerCollabEventType.EndPointObjectChanged){
1179 PEER_EVENT_OBJECT_CHANGED_DATA objData = ped.objectChangedData;
1180 PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT));
1182 PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po);
1184 PeerContact peerContact = null;
1185 PeerEndPoint peerEndPoint = null;
1187 if (objData.pContact != IntPtr.Zero){
1188 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(objData.pContact, typeof(PEER_CONTACT));
1189 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
1192 if (objData.pEndPoint != IntPtr.Zero){
1193 PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(objData.pEndPoint, typeof(PEER_ENDPOINT));
1194 peerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe);
1197 objectChangedArgs = new ObjectChangedEventArgs(peerEndPoint,
1204 if(eventData != null) eventData.Dispose();
1208 // Fire the callback with the marshalled event args data
1211 EventHandler<ObjectChangedEventArgs> handlerCopy = m_objectChanged;
1213 if ((objectChangedArgs != null) && (handlerCopy != null)){
1214 if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
1215 SynchronizingObject.BeginInvoke(handlerCopy, new object[] { this, objectChangedArgs });
1217 handlerCopy(this, objectChangedArgs);
1218 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the object changed event callback.");
1221 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback().");
1225 // Grabs all the contacts from the users windows address book
1227 // <SecurityKernel Critical="True" Ring="0">
1228 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabEnumContacts(System.Net.PeerToPeer.Collaboration.SafeCollabEnum&):System.Int32" />
1229 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetItemCount(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&):System.Int32" />
1230 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerGetNextItem(System.Net.PeerToPeer.Collaboration.SafeCollabEnum,System.UInt32&,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
1231 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
1232 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
1233 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1234 // <UsesUnsafeCode Name="Local pContacts of type: IntPtr*" />
1235 // <UsesUnsafeCode Name="Method: IntPtr.op_Explicit(System.IntPtr):System.Void*" />
1236 // <ReferencesCritical Name="Local handlePeerEnum of type: SafeCollabEnum" Ring="1" />
1237 // <ReferencesCritical Name="Local contactArray of type: SafeCollabData" Ring="1" />
1238 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1239 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
1240 // </SecurityKernel>
1241 [System.Security.SecurityCritical]
1242 public PeerContactCollection GetContacts()
1244 PeerContactCollection peerContactColl = new PeerContactCollection();
1245 SafeCollabEnum handlePeerEnum = null;
1246 UInt32 contactCount = 0;
1249 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1251 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1253 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetContacts()");
1257 // Get contacts array from native
1260 errorCode = UnsafeCollabNativeMethods.PeerCollabEnumContacts(out handlePeerEnum);
1261 if (errorCode != 0){
1262 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumContacts returned with errorcode {0}", errorCode);
1263 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetContactsFailed), errorCode);
1266 errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref contactCount);
1267 if (errorCode != 0){
1268 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode);
1269 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetContactsFailed), errorCode);
1272 if (contactCount == 0){
1273 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No contacts found. \nLeaving GetContacts()");
1274 return peerContactColl;
1277 SafeCollabData contactArray = null;
1279 errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref contactCount, out contactArray);
1280 if (errorCode != 0){
1281 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetNextItem returned with errorcode {0}", errorCode);
1282 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetContactsFailed), errorCode);
1286 // Loop through the contacts array to build PeerContact collection
1289 IntPtr pPEER_CONTACT = contactArray.DangerousGetHandle();
1290 IntPtr* pContacts = (IntPtr*)pPEER_CONTACT;
1291 for (ulong i = 0; i < contactCount; i++){
1292 IntPtr pContactPtr = (IntPtr)pContacts[i];
1293 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(pContactPtr, typeof(PEER_CONTACT));
1295 PeerContact peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
1296 peerContactColl.Add(peerContact);
1300 contactArray.Dispose();
1305 handlePeerEnum.Dispose();
1308 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1309 "Returning collections with {0} contacts. \nLeaving GetContacts()");
1311 return peerContactColl;
1315 // Gets specific contact from the users windows address book
1317 // <SecurityKernel Critical="True" Ring="0">
1318 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabGetContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
1319 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
1320 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
1321 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1322 // <ReferencesCritical Name="Local safeContact of type: SafeCollabData" Ring="1" />
1323 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1324 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
1325 // </SecurityKernel>
1326 [System.Security.SecurityCritical]
1327 public PeerContact GetContact(PeerName peerName)
1329 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1331 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1332 if (peerName == null)
1333 throw new ArgumentNullException("peerName");
1336 SafeCollabData safeContact = null;
1337 PeerContact peerContact = null;
1339 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1340 "Entering GetContact() with peername {0}", peerName.ToString());
1343 errorCode = UnsafeCollabNativeMethods.PeerCollabGetContact(peerName.ToString(),
1345 if (errorCode == UnsafeCollabReturnCodes.PEER_E_CONTACT_NOT_FOUND){
1346 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Contact not found in Contact Manager");
1347 throw new PeerToPeerException(SR.GetString(SR.Collab_ContactNotFound));
1349 else if (errorCode != 0){
1350 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetContact returned with errorcode {0}", errorCode);
1351 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetContactFailed), errorCode);
1354 if (!safeContact.DangerousGetHandle().Equals(IntPtr.Zero)){
1355 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Found contact.");
1356 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(safeContact.DangerousGetHandle(), typeof(PEER_CONTACT));
1357 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
1360 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No contact found.");
1364 safeContact.Dispose();
1366 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving GetContact()");
1371 // <SecurityKernel Critical="True" Ring="0">
1372 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabQueryContactData(System.IntPtr,System.String&):System.Int32" />
1373 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabParseContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
1374 // <SatisfiesLinkDemand Name="GCHandle.Alloc(System.Object,System.Runtime.InteropServices.GCHandleType):System.Runtime.InteropServices.GCHandle" />
1375 // <SatisfiesLinkDemand Name="GCHandle.AddrOfPinnedObject():System.IntPtr" />
1376 // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
1377 // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
1378 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1379 // <SatisfiesLinkDemand Name="GCHandle.Free():System.Void" />
1380 // <ReferencesCritical Name="Local contact of type: SafeCollabData" Ring="1" />
1381 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1382 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT):System.Net.PeerToPeer.Collaboration.PeerContact" Ring="2" />
1383 // </SecurityKernel>
1384 [System.Security.SecurityCritical]
1385 public PeerContact CreateContact(PeerNearMe peerNearMe)
1387 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1389 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1391 if (peerNearMe == null)
1392 throw new ArgumentNullException("peerNearMe");
1394 if ((peerNearMe.PeerEndPoints == null) || (peerNearMe.PeerEndPoints.Count == 0) || (peerNearMe.PeerEndPoints[0].EndPoint == null))
1395 throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound));
1397 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering CreateContact() with peernearme", peerNearMe.ToString());
1399 PeerEndPoint peerEndPoint = peerNearMe.PeerEndPoints[0];
1401 PEER_ENDPOINT pe = new PEER_ENDPOINT();
1402 pe.peerAddress = CollaborationHelperFunctions.ConvertIPEndpointToPEER_ADDRESS(peerEndPoint.EndPoint);
1405 // Pin all the data to pass to native
1407 GCHandle pepName = new GCHandle();
1409 if (peerEndPoint.Name != null){
1410 pepName = GCHandle.Alloc(peerEndPoint.Name, GCHandleType.Pinned);
1411 pe.pwzEndpointName = pepName.AddrOfPinnedObject();
1414 GCHandle peerEP = GCHandle.Alloc(pe, GCHandleType.Pinned);
1415 IntPtr ptrPeerEP = peerEP.AddrOfPinnedObject();
1417 string contactData = null;
1421 // Refresh end point data if it not subscribed
1423 peerNearMe.RefreshData();
1425 errorCode = UnsafeCollabNativeMethods.PeerCollabQueryContactData(ptrPeerEP, ref contactData);
1426 if (errorCode != 0){
1427 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetContact returned with errorcode {0}", errorCode);
1428 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CreateContactFailed), errorCode);
1431 SafeCollabData contact = null;
1432 PeerContact peerContact = null;
1435 errorCode = UnsafeCollabNativeMethods.PeerCollabParseContact(contactData, out contact);
1436 if (errorCode != 0){
1437 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetContact returned with errorcode {0}", errorCode);
1438 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CreateContactFailed), errorCode);
1441 PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(contact.DangerousGetHandle(), typeof(PEER_CONTACT));
1442 peerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc);
1445 // Mark it as just created and add the xml. This is used when adding the contact or getting
1446 // contact xml when contact is not added
1448 peerContact.JustCreated = true;
1449 peerContact.ContactXml = contactData;
1452 if (contact != null) contact.Dispose();
1456 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving CreateContact().");
1461 SendOrPostCallback OnCreateContactCompletedDelegate;
1462 object m_createContactAsyncListLock;
1463 object CreateContactAsyncListLock
1466 if (m_createContactAsyncListLock == null){
1467 object o = new object();
1468 Interlocked.CompareExchange(ref m_createContactAsyncListLock, o, null);
1470 return m_createContactAsyncListLock;
1473 Dictionary<object, AsyncOperation> m_createContactAsyncList = new Dictionary<object, AsyncOperation>();
1475 private event EventHandler<CreateContactCompletedEventArgs> m_createContactCompleted;
1476 public event EventHandler<CreateContactCompletedEventArgs> CreateContactCompleted
1480 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1482 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1484 m_createContactCompleted += value;
1488 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1490 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1492 m_createContactCompleted -= value;
1498 // Stores state to pass to the create contact async helper
1500 private class CreateContactAsyncState
1502 PeerNearMe m_peerNearMe;
1504 internal CreateContactAsyncState(PeerNearMe peerNearMe, Object userToken){
1505 m_peerNearMe = peerNearMe;
1506 m_userToken = userToken;
1508 internal PeerNearMe PeerNearMe
1510 get { return m_peerNearMe; }
1512 internal Object UserToken
1514 get { return m_userToken; }
1518 public void CreateContactAsync(PeerNearMe peerNearMe, Object userToken)
1520 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1522 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1524 if (peerNearMe == null)
1525 throw new ArgumentNullException("PeerNearMe");
1527 if ((peerNearMe.PeerEndPoints == null) || (peerNearMe.PeerEndPoints.Count == 0) || (peerNearMe.PeerEndPoints[0].EndPoint == null))
1528 throw new PeerToPeerException(SR.GetString(SR.Collab_NoEndpointFound));
1530 if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){
1531 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering CreateContactAsync() with token {0} and following peernearme" , userToken);
1532 peerNearMe.TracePeerNearMe();
1536 // Add to list of usertokens
1538 lock (CreateContactAsyncListLock){
1539 if (m_createContactAsyncList.ContainsKey(userToken)){
1540 throw new ArgumentException(SR.GetString(SR.DuplicateUserToken));
1542 AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userToken);
1543 m_createContactAsyncList[userToken] = asyncOp;
1546 ThreadPool.QueueUserWorkItem(new WaitCallback(CreateContactAsyncHelper), new CreateContactAsyncState(peerNearMe, userToken));
1548 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving CreateContactAsync().");
1553 // Used to create a contact async'ally
1555 private void CreateContactAsyncHelper(object state)
1557 Exception ex = null;
1558 PeerContact peerContact = null;
1559 CreateContactAsyncState createAsyncState = state as CreateContactAsyncState;
1560 PeerNearMe peerNearMe = createAsyncState.PeerNearMe;
1561 object userToken = createAsyncState.UserToken;
1564 // Call the sync version of createcontact
1567 peerContact = CreateContact(peerNearMe);
1569 catch (ObjectDisposedException e){
1570 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "CreateContactAsyncHelper caught error {0}", e.Message);
1573 catch (PeerToPeerException e){
1574 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "CreateContactAsyncHelper caught error {0}", e.Message);
1578 CreateContactCompletedEventArgs createContactCompletedArgs;
1580 createContactCompletedArgs = new CreateContactCompletedEventArgs(peerContact, null, false, userToken);
1583 createContactCompletedArgs = new CreateContactCompletedEventArgs(peerContact, ex, false, userToken);
1586 PrepareToRaiseCreateContactCompletedEvent(m_createContactAsyncList[userToken], createContactCompletedArgs);
1589 void OnCreateContactCompleted(CreateContactCompletedEventArgs e)
1591 EventHandler<CreateContactCompletedEventArgs> handlerCopy = m_createContactCompleted;
1592 if (handlerCopy != null){
1593 handlerCopy(this, e);
1594 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the create contact completed event callback.");
1598 void CreateContactCompletedWaitCallback(object operationState)
1600 CreateContactCompletedEventArgs args = (CreateContactCompletedEventArgs) operationState;
1602 // Remove from usertoken list
1604 m_createContactAsyncList.Remove(args.UserState);
1606 OnCreateContactCompleted(args);
1609 internal void PrepareToRaiseCreateContactCompletedEvent(AsyncOperation asyncOP, CreateContactCompletedEventArgs args)
1611 asyncOP.PostOperationCompleted(OnCreateContactCompletedDelegate, args);
1615 // Adds a contacts to the users windows address book
1617 // <SecurityKernel Critical="True" Ring="0">
1618 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabAddContact(System.String,System.Net.PeerToPeer.Collaboration.SafeCollabData&):System.Int32" />
1619 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1620 // <ReferencesCritical Name="Local contact of type: SafeCollabData" Ring="1" />
1621 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1622 // </SecurityKernel>
1623 [System.Security.SecurityCritical]
1624 public void AddContact(PeerContact peerContact)
1626 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1628 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1630 if (peerContact == null)
1631 throw new ArgumentNullException("peerContact");
1633 string contactXml = null;
1635 if (peerContact.ContactXml == null){
1637 contactXml = peerContact.ToXml();
1639 catch (PeerToPeerException e){
1640 throw new PeerToPeerException(SR.GetString(SR.Collab_AddContactFailedNoXml), e.InnerException);
1644 contactXml = peerContact.ContactXml;
1647 if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){
1648 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddContact() with following peercontact");
1649 peerContact.TracePeerContact();
1652 SafeCollabData contact = null;
1656 errorCode = UnsafeCollabNativeMethods.PeerCollabAddContact(contactXml, out contact);
1659 if(contact != null) contact.Dispose();
1662 if (errorCode == UnsafeCollabReturnCodes.PEER_E_ALREADY_EXISTS){
1663 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabAddContact returned with errorcode {0}. Contact already exists.", errorCode);
1664 throw new ArgumentException(SR.GetString(SR.Collab_AddContactFailed) + " " + SR.GetString(SR.Collab_ContactExists));
1666 else if (errorCode != 0){
1667 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabAddContact returned with errorcode {0}", errorCode);
1668 throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_AddContactFailed), errorCode);
1671 peerContact.JustCreated = false;
1672 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1673 "Leaving AddContact() successfully.");
1678 // Deletes a contact from the users windows address book
1680 public void DeleteContact(PeerContact peerContact)
1682 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1683 "Entering DeleteContact().");
1685 if (peerContact == null)
1686 throw new ArgumentNullException("peerContact");
1688 DeleteContact(peerContact.PeerName);
1689 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1690 "Leaving DeleteContact() successfully.");
1695 // Deletes a contact from the users windows address book
1697 // <SecurityKernel Critical="True" Ring="0">
1698 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabDeleteContact(System.String):System.Int32" />
1699 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1700 // </SecurityKernel>
1701 [System.Security.SecurityCritical]
1702 public void DeleteContact(PeerName peerName)
1704 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1705 "Entering DeleteContact().");
1707 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1709 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1710 if (peerName == null)
1711 throw new ArgumentNullException("peerName");
1713 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1714 "Peername is {0}", peerName.ToString());
1716 int errorCode = UnsafeCollabNativeMethods.PeerCollabDeleteContact(peerName.ToString());
1718 if (errorCode == UnsafeCollabReturnCodes.PEER_E_CONTACT_NOT_FOUND){
1719 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Contact not found in Contact Manager");
1720 throw new ArgumentException(SR.GetString(SR.Collab_ContactNotFound), "peerName");
1722 else if (errorCode != 0){
1723 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabDeleteContact returned with errorcode {0}", errorCode);
1724 throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_DeleteContactFailed), errorCode));
1726 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1727 "Leaving DeleteContact() successfully.");
1731 // Updates a contact from the users windows address book
1733 // <SecurityKernel Critical="True" Ring="0">
1734 // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabUpdateContact(System.Net.PeerToPeer.Collaboration.PEER_CONTACT&):System.Int32" />
1735 // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
1736 // <ReferencesCritical Name="Local safeCredentials of type: SafeCollabMemory" Ring="1" />
1737 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.ConvertPeerContactToPEER_CONTACT(System.Net.PeerToPeer.Collaboration.PeerContact,System.Net.PeerToPeer.Collaboration.SafeCollabMemory&):System.Net.PeerToPeer.Collaboration.PEER_CONTACT" Ring="1" />
1738 // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
1739 // </SecurityKernel>
1740 [System.Security.SecurityCritical]
1741 public void UpdateContact(PeerContact peerContact)
1743 if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);
1745 PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();
1746 if (peerContact == null)
1747 throw new ArgumentNullException("peerContact");
1749 if (peerContact.PeerName == null)
1750 throw new ArgumentException(SR.GetString(SR.Collab_NoPeerNameInContact));
1752 if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){
1753 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering UpdateContact() with following peercontact");
1754 peerContact.TracePeerContact();
1757 SafeCollabMemory safeCredentials = null;
1761 PEER_CONTACT pc = CollaborationHelperFunctions.ConvertPeerContactToPEER_CONTACT(peerContact, ref safeCredentials);
1763 errorCode = UnsafeCollabNativeMethods.PeerCollabUpdateContact(ref pc);
1766 if (safeCredentials != null) safeCredentials.Dispose();
1769 if (errorCode == UnsafeCollabReturnCodes.PEER_E_CONTACT_NOT_FOUND){
1770 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Contact not found in Contact Manager");
1771 throw new ArgumentException(SR.GetString(SR.Collab_ContactNotFound), "peerContact");
1773 else if (errorCode != 0){
1774 Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabUpdateContact returned with errorcode {0}", errorCode);
1775 throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_UpdateContactFailed), errorCode));
1777 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0,
1778 "Leaving UpdateContact() successfully.");
1781 private bool m_Disposed;
1783 // <SecurityKernel Critical="True" Ring="2">
1784 // <ReferencesCritical Name="Method: Dispose(Boolean):Void" Ring="2" />
1785 // </SecurityKernel>
1786 [System.Security.SecurityCritical]
1787 public void Dispose()
1790 GC.SuppressFinalize(this);
1793 // <SecurityKernel Critical="True" Ring="1">
1794 // <ReferencesCritical Name="Field: m_safeSubLstChangedEvent" Ring="1" />
1795 // <ReferencesCritical Name="Method: CollaborationHelperFunctions.CleanEventVars(System.Threading.RegisteredWaitHandle&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&,System.Threading.AutoResetEvent&):System.Void" Ring="1" />
1796 // <ReferencesCritical Name="Field: m_safeNameChangedEvent" Ring="1" />
1797 // <ReferencesCritical Name="Field: m_safePresenceChangedEvent" Ring="1" />
1798 // <ReferencesCritical Name="Field: m_safeAppChangedEvent" Ring="1" />
1799 // <ReferencesCritical Name="Field: m_safeObjChangedEvent" Ring="1" />
1800 // </SecurityKernel>
1801 [System.Security.SecurityCritical]
1802 void Dispose(bool disposing)
1805 CollaborationHelperFunctions.CleanEventVars(ref m_regSubLstChangedWaitHandle,
1806 ref m_safeSubLstChangedEvent,
1807 ref m_subLstChangedEvent);
1808 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean SubscriptionListChanged variables successful.");
1810 CollaborationHelperFunctions.CleanEventVars(ref m_regNameChangedWaitHandle,
1811 ref m_safeNameChangedEvent,
1812 ref m_nameChangedEvent);
1813 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean NameChanged variables successful.");
1815 CollaborationHelperFunctions.CleanEventVars(ref m_regPresenceChangedWaitHandle,
1816 ref m_safePresenceChangedEvent,
1817 ref m_presenceChangedEvent);
1818 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PresenceChanged variables successful.");
1820 CollaborationHelperFunctions.CleanEventVars(ref m_regAppChangedWaitHandle,
1821 ref m_safeAppChangedEvent,
1822 ref m_appChangedEvent);
1823 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ApplicationChanged variables successful.");
1825 CollaborationHelperFunctions.CleanEventVars(ref m_regObjChangedWaitHandle,
1826 ref m_safeObjChangedEvent,
1827 ref m_objChangedEvent);
1828 Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChanged variables successful.");