//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ namespace System.Net.PeerToPeer.Collaboration { using System; using System.Collections.ObjectModel; using System.Runtime.InteropServices; using System.Net.Mail; using System.Security.Cryptography.X509Certificates; using System.Diagnostics; using System.Threading; using System.ComponentModel; /// /// This class handles all the collaboration platform functions /// public static class PeerCollaboration { public static PeerPresenceInfo LocalPresenceInfo { // // // // // // // // [System.Security.SecurityCritical] get { SafeCollabData safePresenceInfo = null; PeerPresenceInfo peerPresenceInfo = null; try{ CollaborationHelperFunctions.Initialize(); int errorCode = UnsafeCollabNativeMethods.PeerCollabGetPresenceInfo(IntPtr.Zero, out safePresenceInfo); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetPresenceInfo returned with errorcode {0}", errorCode); return null; } IntPtr ptrPeerPresenceInfo = safePresenceInfo.DangerousGetHandle(); PEER_PRESENCE_INFO ppi = (PEER_PRESENCE_INFO)Marshal.PtrToStructure(ptrPeerPresenceInfo, typeof(PEER_PRESENCE_INFO)); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Retrieved a PeerPresenceInfo with PresenceStatus {0}, Desc {1}", ppi.status, ppi.descText); peerPresenceInfo = new PeerPresenceInfo(); peerPresenceInfo.PresenceStatus = ppi.status; peerPresenceInfo.DescriptiveText = ppi.descText; } catch (Exception e){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetPresenceInfo had exception {0}", e.Message); throw; } finally{ if(safePresenceInfo != null) safePresenceInfo.Dispose(); } return peerPresenceInfo; } // // // // // [System.Security.SecurityCritical] set { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); if (value == null) throw new ArgumentNullException("value"); if (value.PresenceStatus == PeerPresenceStatus.Offline) throw new PeerToPeerException(SR.GetString(SR.Collab_SetPresenceOffline)); PEER_PRESENCE_INFO ppi; ppi.status = value.PresenceStatus; ppi.descText = value.DescriptiveText; int errorCode = UnsafeCollabNativeMethods.PeerCollabSetPresenceInfo(ref ppi); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSetPresenceInfo returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_SetLocalPresenceFailed), errorCode)); } } } public static string LocalEndPointName { // // // [System.Security.SecurityCritical] get { string localEndPointName = null; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "LocalEndPointName get called."); // // Call native to get users endpoint name // try{ int errorCode = UnsafeCollabNativeMethods.PeerCollabGetEndpointName(ref localEndPointName); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetEndpointName returned with errorcode {0}", errorCode); } } catch (Exception e){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "LocalEndPointName threw exception {0}", e.ToString()); throw; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "LocalEndPointName get returning {0}.", localEndPointName); return localEndPointName; } // // // // [System.Security.SecurityCritical] set { // // Call native to set users endpoint name // Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "LocalEndPointName set called with {0}.", value); int errorCode = UnsafeCollabNativeMethods.PeerCollabSetEndpointName(value); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSetEndpointName returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_SetLocalEndPointNameFailed), errorCode); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving LocalEndPointName set."); } } public static PeerScope SignInScope { // // // // [System.Security.SecurityCritical] get { PeerScope peerScope = PeerScope.None; CollaborationHelperFunctions.Initialize(); int errorCode = UnsafeCollabNativeMethods.PeerCollabGetSigninOptions(ref peerScope); if(errorCode != 0) Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetSigninOptions returned with errorcode {0}", errorCode); return peerScope; } } // // Lock to ensure only one Contact Manager is instantiated // static object s_contactManagerSyncObject; internal static object ContactManagerSyncObject { get{ if (s_contactManagerSyncObject == null){ object o = new object(); Interlocked.CompareExchange(ref s_contactManagerSyncObject, o, null); } return s_contactManagerSyncObject; } } static volatile ContactManager s_contactManager; // // Returns the contact manager instance. Only one is created. // public static ContactManager ContactManager { // // // [System.Security.SecurityCritical] get{ if (s_contactManager == null){ lock (ContactManagerSyncObject){ if (s_contactManager == null){ s_contactManager = new ContactManager(); } } } return s_contactManager; } } public static PeerApplicationLaunchInfo ApplicationLaunchInfo { // // // // // // // // [System.Security.SecurityCritical] get { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetApplicationLaunchInfo."); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); PeerApplicationLaunchInfo peerAppLaunchInfo = null; SafeCollabData appLaunchInfoData = null; int errorCode = UnsafeCollabNativeMethods.PeerCollabGetAppLaunchInfo(out appLaunchInfoData); // // Special case. No Data found, return null. // if (errorCode == UnsafeCollabReturnCodes.PEER_E_NOT_FOUND){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No Application launch info available."); return peerAppLaunchInfo; } if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetAppLaunchInfo returned with errorcode {0}", errorCode); return peerAppLaunchInfo; } // // Marshal individual Launch info elements // try{ PEER_APP_LAUNCH_INFO pali = (PEER_APP_LAUNCH_INFO)Marshal.PtrToStructure(appLaunchInfoData.DangerousGetHandle(), typeof(PEER_APP_LAUNCH_INFO)); peerAppLaunchInfo = new PeerApplicationLaunchInfo(); if (pali.pContact != IntPtr.Zero){ PEER_CONTACT pc = (PEER_CONTACT)Marshal.PtrToStructure(pali.pContact, typeof(PEER_CONTACT)); peerAppLaunchInfo.PeerContact = CollaborationHelperFunctions.ConvertPEER_CONTACTToPeerContact(pc); } PEER_INVITATION pi = (PEER_INVITATION)Marshal.PtrToStructure(pali.pInvitation, typeof(PEER_INVITATION)); peerAppLaunchInfo.PeerApplication = new PeerApplication(CollaborationHelperFunctions.ConvertGUIDToGuid(pi.applicationId), null, null, null, null, PeerScope.None); peerAppLaunchInfo.Message = pi.pwzMessage; byte[] data = null; if (pi.applicationData.cbData != 0){ data = new byte[pi.applicationData.cbData]; Marshal.Copy(pi.applicationData.pbData, data, 0, (int)pi.applicationData.cbData); } peerAppLaunchInfo.Data = data; PEER_ENDPOINT pe = (PEER_ENDPOINT)Marshal.PtrToStructure(pali.pEndpoint, typeof(PEER_ENDPOINT)); peerAppLaunchInfo.PeerEndPoint = CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "GetApplicationLaunchInfo successful."); } catch (Exception e){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "GetApplicationLaunchInfo threw error {0}.", e.ToString()); throw; } finally{ if (appLaunchInfoData != null) appLaunchInfoData.Dispose(); } return peerAppLaunchInfo; } } static volatile ISynchronizeInvoke s_synchronizingObject; /// /// Gets and set the object used to marshall event handlers calls for stand alone /// events /// [Browsable(false), DefaultValue(null), Description(SR.SynchronizingObject)] public static ISynchronizeInvoke SynchronizingObject { get{ return s_synchronizingObject; } set{ s_synchronizingObject = value; } } // // // // // [System.Security.SecurityCritical] public static void SignIn(PeerScope peerScope) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering SignIn with peerscope {0}.", peerScope); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if ((peerScope < PeerScope.None) || (peerScope > PeerScope.All)) throw new ArgumentOutOfRangeException("peerScope"); if (peerScope == PeerScope.None) throw new ArgumentException(SR.GetString(SR.Collab_SignInWithNone), "peerScope"); CollaborationHelperFunctions.Initialize(); int errorCode = UnsafeCollabNativeMethods.PeerCollabSignin(IntPtr.Zero, peerScope); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSignin returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_SignInFailed), errorCode)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Signed into {0}.", peerScope); } // // // // // [System.Security.SecurityCritical] public static void SignOut(PeerScope peerScope) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering SignOut with peerscope {0}.", peerScope); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); if ((peerScope < PeerScope.None) || (peerScope > PeerScope.All)) throw new ArgumentOutOfRangeException("peerScope"); if (peerScope != PeerScope.None){ int errorCode = UnsafeCollabNativeMethods.PeerCollabSignout(peerScope); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSignout returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_SignOutFailed), errorCode)); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Signed out of {0}.", peerScope); } // // Gives you all the peers on the same subnet as you // // // // // // // // // // // // // // // // // [System.Security.SecurityCritical] public static PeerNearMeCollection GetPeersNearMe() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetPeersNearMeGetPeersNearMe."); CollaborationHelperFunctions.Initialize(); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); PeerNearMeCollection pnmc = new PeerNearMeCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 pnmCount = 0; int errorCode = 0; try{ // // Call native to get the enumeration of peers near // errorCode = UnsafeCollabNativeMethods.PeerCollabEnumPeopleNearMe(out handlePeerEnum); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumPeopleNearMe returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetPeersNearMeFailed), errorCode); } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref pnmCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetPeersNearMeFailed), errorCode); } if (pnmCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "No peers found. \nLeaving GetPeersNearMe()"); return pnmc; } unsafe{ SafeCollabData appArray; errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref pnmCount, out appArray); IntPtr pPEER_PEOPLE_NEAR_ME = appArray.DangerousGetHandle(); IntPtr* pPeersNearMe = (IntPtr*)pPEER_PEOPLE_NEAR_ME; // // Loops through individual native structures and makes peers from them // for (ulong i = 0; i < pnmCount; i++){ IntPtr pContactPtr = (IntPtr)pPeersNearMe[i]; PEER_PEOPLE_NEAR_ME pnm = (PEER_PEOPLE_NEAR_ME)Marshal.PtrToStructure(pContactPtr, typeof(PEER_PEOPLE_NEAR_ME)); PeerNearMe peerNearMe = new PeerNearMe(); peerNearMe.Id = CollaborationHelperFunctions.ConvertGUIDToGuid(pnm.id); peerNearMe.Nickname = Marshal.PtrToStringUni(pnm.pwzNickname); ; PEER_ENDPOINT pe = pnm.endpoint; peerNearMe.PeerEndPoints.Add(CollaborationHelperFunctions.ConvertPEER_ENDPOINTToPeerEndPoint(pe)); pnmc.Add(peerNearMe); } } } finally{ if (handlePeerEnum != null) handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving GetPeersNearMeGetPeersNearMe with {0} peers.", pnmc.Count); return pnmc; } // // // // // // // // // // // // // [System.Security.SecurityCritical] public static void RegisterApplication(PeerApplication application, PeerApplicationRegistrationType type) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (application == null){ throw new ArgumentNullException("application"); } if (application.Path == null){ throw new ArgumentException(SR.GetString(SR.Collab_AppRegNoPathError)); } if ((type < PeerApplicationRegistrationType.CurrentUser) || (type > PeerApplicationRegistrationType.AllUsers)){ throw new ArgumentOutOfRangeException("type"); } CollaborationHelperFunctions.Initialize(); int errorCode = 0; // // Convert PeerApplication.Guid into native GUID struct // PEER_APPLICATION_REGISTRATION_INFO appRegInfo = new PEER_APPLICATION_REGISTRATION_INFO(); appRegInfo.application.guid = CollaborationHelperFunctions.ConvertGuidToGUID(application.Id); appRegInfo.pwzApplicationArguments = application.CommandLineArgs; appRegInfo.pwzApplicationToLaunch = application.Path; appRegInfo.dwPublicationScope = (uint)application.PeerScope; if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RegisterApplication() is called with the following Info"); application.TracePeerApplication(); } unsafe{ SafeCollabMemory data = null; appRegInfo.application.data.cbData = (application.Data!=null) ? (UInt32)application.Data.Length : 0; GCHandle descHandle = new GCHandle(); try{ // // Marshal any data to send to native call // if ((application.Data!=null) && (application.Data.Length > 0)) { data = new SafeCollabMemory(application.Data.Length); appRegInfo.application.data.pbData = data.DangerousGetHandle(); Marshal.Copy(application.Data, 0, appRegInfo.application.data.pbData, application.Data.Length); } else appRegInfo.application.data.pbData = IntPtr.Zero; descHandle = GCHandle.Alloc(application.Description, GCHandleType.Pinned); appRegInfo.application.pwzDescription = descHandle.AddrOfPinnedObject(); errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterApplication(ref appRegInfo, type); } finally{ if (descHandle.IsAllocated) descHandle.Free(); if (data != null) data.Dispose(); } } if (errorCode == UnsafeCollabReturnCodes.PEER_E_ALREADY_EXISTS){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterApplication returned with errorcode {0}. Application already registered.", errorCode); throw new ArgumentException(SR.GetString(SR.Collab_AppRegFailed) + " " + SR.GetString(SR.Collab_AppExists)); } else if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterApplication returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_AppRegFailed), errorCode)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "RegisterApplication successful"); } // // // // // [System.Security.SecurityCritical] public static void UnregisterApplication(PeerApplication application, PeerApplicationRegistrationType type) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (application == null){ throw new ArgumentNullException("application"); } if (application.Id.Equals(Guid.Empty)){ throw new ArgumentException(SR.GetString(SR.Collab_EmptyGuidError)); } if ((type < PeerApplicationRegistrationType.CurrentUser) || (type > PeerApplicationRegistrationType.AllUsers)){ throw new ArgumentOutOfRangeException("type"); } CollaborationHelperFunctions.Initialize(); // // Convert PeerApplication.Guid into native GUID struct // GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(application.Id); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "UnregisterApplication() is called with the following Info"); application.TracePeerApplication(); } int errorCode = UnsafeCollabNativeMethods.PeerCollabUnregisterApplication(ref guid, type); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabUnregisterApplication returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_AppUnregFailed), errorCode)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "UnregisterApplication successful"); } // // Gets all applications registered to collab on this machine // public static PeerApplicationCollection GetLocalRegisteredApplications() { PeerApplicationCollection allUsersColl = GetLocalRegisteredApplications(PeerApplicationRegistrationType.AllUsers); PeerApplicationCollection localUsersColl = GetLocalRegisteredApplications(PeerApplicationRegistrationType.CurrentUser); if ((allUsersColl == null) || (allUsersColl.Count == 0)){ return localUsersColl; } else if ((localUsersColl == null) || (localUsersColl.Count == 0)){ return allUsersColl; } else{ // // Merge the two to remove dupes // foreach (PeerApplication peerApplicationLocal in localUsersColl){ PeerApplication peerAppToRemove = null; foreach (PeerApplication peerApplicationAll in allUsersColl){ if (peerApplicationAll.Id.Equals(peerApplicationLocal.Id)){ peerAppToRemove = peerApplicationAll; } } if (peerAppToRemove != null) allUsersColl.Remove(peerAppToRemove); } foreach (PeerApplication peerApplicationAll in allUsersColl){ localUsersColl.Add(peerApplicationAll); } return localUsersColl; } } // // Gets all applications registered to collab for specific user on this machine // // // // // // // // // // // // // // // // // // // // // // // [System.Security.SecurityCritical] public static PeerApplicationCollection GetLocalRegisteredApplications(PeerApplicationRegistrationType type) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetLocalRegisteredApplications."); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if ((type < PeerApplicationRegistrationType.CurrentUser) || (type > PeerApplicationRegistrationType.AllUsers)){ throw new ArgumentOutOfRangeException("type"); } CollaborationHelperFunctions.Initialize(); PeerApplicationCollection peerAppColl = new PeerApplicationCollection(); SafeCollabEnum handlePeerEnum = new SafeCollabEnum(); UInt32 appCount = 0; int errorCode = 0; // // Enumerate and get all the registered applications from native // try{ errorCode = UnsafeCollabNativeMethods.PeerCollabEnumApplications(IntPtr.Zero, IntPtr.Zero, out handlePeerEnum); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumApplications returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalAppsFailed), 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_GetLocalAppsFailed), errorCode)); } if (appCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "No local registered PeerApplications found."); return peerAppColl; } unsafe{ SafeCollabData appArray = null; try{ errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref appCount, out appArray); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetNextItem returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalAppsFailed), errorCode)); } // // Marshal each application from the array // IntPtr pPEER_APLICATION = appArray.DangerousGetHandle(); IntPtr* pApps = (IntPtr*)pPEER_APLICATION; 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); peerAppColl.Add(peerApp); } } finally{ appArray.Dispose(); } } } finally{ handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Got all local registered Applications. Start filtering"); PeerApplicationCollection peerAppCollFiltered = new PeerApplicationCollection(); // // Filter the apps according to the Registration type the user wants // foreach (PeerApplication peerApplication in peerAppColl) { GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(peerApplication.Id); SafeCollabData safeAppRegInfo = new SafeCollabData(); try{ errorCode = UnsafeCollabNativeMethods.PeerCollabGetApplicationRegistrationInfo(ref guid, type, out safeAppRegInfo); if (errorCode != 0) Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetApplicationRegistrationInfo returned with errorcode {0}", errorCode); if (!safeAppRegInfo.IsInvalid){ PEER_APPLICATION_REGISTRATION_INFO pari = (PEER_APPLICATION_REGISTRATION_INFO) Marshal.PtrToStructure(safeAppRegInfo.DangerousGetHandle(), typeof(PEER_APPLICATION_REGISTRATION_INFO)); peerApplication.Path = pari.pwzApplicationToLaunch; peerApplication.CommandLineArgs = pari.pwzApplicationArguments; peerApplication.PeerScope = (PeerScope)pari.dwPublicationScope; peerAppCollFiltered.Add(peerApplication); } } finally{ safeAppRegInfo.Dispose(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Filtering successful. Returning collection with {0} applications", peerAppCollFiltered.Count); return peerAppCollFiltered; } // // // // // // // // // // [System.Security.SecurityCritical] public static void SetObject(PeerObject peerObject) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerObject == null){ throw new ArgumentNullException("peerObject"); } CollaborationHelperFunctions.Initialize(); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "SetObject() is called with the following info"); peerObject.TracePeerObject(); } PEER_OBJECT po = new PEER_OBJECT(); int errorCode = 0; // // Create the native PEER_OBJECT struct // po.guid = CollaborationHelperFunctions.ConvertGuidToGUID(peerObject.Id); po.dwPublicationScope = (uint)peerObject.PeerScope; SafeCollabMemory data = null; try{ if ((peerObject.Data != null) && (peerObject.Data.Length > 0)){ data = new SafeCollabMemory(peerObject.Data.Length); po.data.pbData = data.DangerousGetHandle(); po.data.cbData = (UInt32)peerObject.Data.Length; Marshal.Copy(peerObject.Data, 0, po.data.pbData, peerObject.Data.Length); } else{ po.data.pbData = IntPtr.Zero; po.data.cbData = 0; } errorCode = UnsafeCollabNativeMethods.PeerCollabSetObject(ref po); } finally{ if (data != null) data.Dispose(); } if (errorCode == UnsafeCollabReturnCodes.PEER_E_ALREADY_EXISTS){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSetObject returned with errorcode {0}. Object already set.", errorCode); throw new ArgumentException(SR.GetString(SR.Collab_ObjectSetFailed) + " " + SR.GetString(SR.Collab_ObjectExists)); } else if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabSetObject returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectSetFailed), errorCode)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Set Object successful."); } // // // // // [System.Security.SecurityCritical] public static void DeleteObject(PeerObject peerObject) { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); if (peerObject == null){ throw new ArgumentNullException("peerObject"); } CollaborationHelperFunctions.Initialize(); if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information)){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "DeleteObject() is called with the following info"); peerObject.TracePeerObject(); } GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(peerObject.Id); int errorCode = UnsafeCollabNativeMethods.PeerCollabDeleteObject(ref guid); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabDeleteObject returned with errorcode {0}", errorCode); throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectDeleteFailed), errorCode)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Delete Object successful."); } // // // // // // // // // // // // // // // [System.Security.SecurityCritical] public static PeerObjectCollection GetLocalSetObjects() { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetLocalSetObjects."); PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); PeerObjectCollection peerObjectColl = new PeerObjectCollection(); SafeCollabEnum handlePeerEnum = null; UInt32 objectCount = 0; int errorCode = 0; // // Enumerate through all the objects from native // try{ errorCode = UnsafeCollabNativeMethods.PeerCollabEnumObjects(IntPtr.Zero, IntPtr.Zero, out handlePeerEnum); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumObjects returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalObjectsFailed), errorCode); } errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref objectCount); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalObjectsFailed), errorCode); } if (objectCount == 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "No local PeerObjects found."); return peerObjectColl; } unsafe{ SafeCollabData objectArray = null; try{ errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref objectCount, out objectArray); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetNextItem returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalObjectsFailed), errorCode); } // // Marshal each object from the array // IntPtr pPEER_OBJECT = objectArray.DangerousGetHandle(); IntPtr* pObjects = (IntPtr*)pPEER_OBJECT; for (ulong i = 0; i < objectCount; i++){ PEER_OBJECT* pPeerObject = (PEER_OBJECT*)pObjects[i]; byte[] data = null; if (pPeerObject->data.cbData != 0){ data = new byte[pPeerObject->data.cbData]; Marshal.Copy(pPeerObject->data.pbData, data, 0, (int)pPeerObject->data.cbData); } PeerObject peerObject = new PeerObject(CollaborationHelperFunctions.ConvertGUIDToGuid(pPeerObject->guid), data, (PeerScope)pPeerObject->dwPublicationScope); peerObjectColl.Add(peerObject); } } finally{ objectArray.Dispose(); } } } finally{ handlePeerEnum.Dispose(); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Returning collection with {0} objects", peerObjectColl.Count); return peerObjectColl; } private static event EventHandler s_nameChanged; public static event EventHandler LocalNameChanged { // // // // [System.Security.SecurityCritical] add { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); AddNameChanged(value); } // // // // [System.Security.SecurityCritical] remove { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); RemoveNameChanged(value); } } #region Name changed event variables private static object s_lockNameChangedEvent; private static object LockNameChangedEvent { get{ if (s_lockNameChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref s_lockNameChangedEvent, o, null); } return s_lockNameChangedEvent; } } private static RegisteredWaitHandle s_regNameChangedWaitHandle; private static AutoResetEvent s_nameChangedEvent; private static SafeCollabEvent s_safeNameChangedEvent; #endregion // // // // // // // [System.Security.SecurityCritical] private static void AddNameChanged(EventHandler callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering AddNameChanged()."); // // Register a wait handle if one has not been registered already // lock (LockNameChangedEvent) { if (s_nameChanged == null){ s_nameChangedEvent = new AutoResetEvent(false); // // Register callback with a wait handle // s_regNameChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(s_nameChangedEvent, //Event that triggers the callback new WaitOrTimerCallback(NameChangedCallback), //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.MyEndPointChanged; pcer.pInstance = IntPtr.Zero; // // Register event with collab // int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( s_nameChangedEvent.SafeWaitHandle, 1, ref pcer, out s_safeNameChangedEvent); if (errorCode != 0){ Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_NameChangedRegFailed), errorCode); } } s_nameChanged += callback; } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddNameChanged() successful."); } // // // // [System.Security.SecurityCritical] private static void RemoveNameChanged(EventHandler callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveNameChanged() called."); lock (LockNameChangedEvent){ s_nameChanged -= callback; if (s_nameChanged == null){ CollaborationHelperFunctions.CleanEventVars(ref s_regNameChangedWaitHandle, ref s_safeNameChangedEvent, ref s_nameChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean NameChangedEvent variables successful."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveNameChanged() successful."); } // // // // // // // // // // [System.Security.SecurityCritical] private static void NameChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "NameChangedCallback() called."); while (true){ NameChangedEventArgs nameChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockNameChangedEvent) { if (s_safeNameChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(s_safeNameChangedEvent, 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_GetNameChangedDataFailed), errorCode); } PEER_COLLAB_EVENT_DATA ped = (PEER_COLLAB_EVENT_DATA)Marshal.PtrToStructure(eventData.DangerousGetHandle(), typeof(PEER_COLLAB_EVENT_DATA)); if (ped.eventType == PeerCollabEventType.MyEndPointChanged){ if (ped.endpointChangedData.pEndPoint != IntPtr.Zero){ // // This means its an endpoint on my contact which is not on the local machine // so we dont care // return; } string newName = PeerCollaboration.LocalEndPointName; nameChangedArgs = new NameChangedEventArgs( null, null, newName); } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // EventHandler handlerCopy = s_nameChanged; if ((nameChangedArgs != null) && (handlerCopy != null)){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { null, nameChangedArgs }); else handlerCopy(null, nameChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the name changed event callback."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving NameChangedCallback()."); } static event EventHandler s_presenceChanged; public static event EventHandler LocalPresenceChanged { // // // // [System.Security.SecurityCritical] add { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); AddPresenceChanged(value); } // // // // [System.Security.SecurityCritical] remove { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); RemovePresenceChanged(value); } } #region Presence changed event variables static object s_lockPresenceChangedEvent; static object LockPresenceChangedEvent { get{ if (s_lockPresenceChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref s_lockPresenceChangedEvent, o, null); } return s_lockPresenceChangedEvent; } } static RegisteredWaitHandle s_regPresenceChangedWaitHandle; static AutoResetEvent s_presenceChangedEvent; static SafeCollabEvent s_safePresenceChangedEvent; #endregion // // // // // [System.Security.SecurityCritical] static void AddPresenceChanged(EventHandler callback) { CollaborationHelperFunctions.AddMyPresenceChanged(callback, ref s_presenceChanged, LockPresenceChangedEvent, ref s_regPresenceChangedWaitHandle, ref s_presenceChangedEvent, ref s_safePresenceChangedEvent, new WaitOrTimerCallback(PresenceChangedCallback)); } // // // // [System.Security.SecurityCritical] static void RemovePresenceChanged(EventHandler callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() called."); lock (LockPresenceChangedEvent){ s_presenceChanged -= callback; if (s_presenceChanged == null){ CollaborationHelperFunctions.CleanEventVars(ref s_regPresenceChangedWaitHandle, ref s_safePresenceChangedEvent, ref s_presenceChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean PresenceChanged variables successful."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemovePresenceChanged() successful."); } // // // // // // // // // // [System.Security.SecurityCritical] static void PresenceChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "PresenceChangedCallback() called."); while (true) { PresenceChangedEventArgs presenceChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockPresenceChangedEvent){ if (s_safePresenceChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(s_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.MyPresenceChanged){ PEER_EVENT_PRESENCE_CHANGED_DATA presenceData = ped.presenceChangedData; 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; } if (presenceData.pEndPoint != IntPtr.Zero){ // // This means its an endpoint on my contact which is not on the local machine // so we dont care // return; } presenceChangedArgs = new PresenceChangedEventArgs( null, null, presenceData.changeType, peerPresenceInfo); } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // EventHandler handlerCopy = s_presenceChanged; if ((presenceChangedArgs != null) && (handlerCopy != null)){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { null, presenceChangedArgs }); else handlerCopy(null, presenceChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the presence changed event callback."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving PresenceChangedCallback()."); } static EventHandler s_objectChanged; public static event EventHandler LocalObjectChanged { // // // // [System.Security.SecurityCritical] add { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); AddObjectChangedEvent(value); } // // // // [System.Security.SecurityCritical] remove { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); RemoveObjectChangedEvent(value); } } #region Object changed event variables static object s_lockObjChangedEvent; static object LockObjChangedEvent { get{ if (s_lockObjChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref s_lockObjChangedEvent, o, null); } return s_lockObjChangedEvent; } } static RegisteredWaitHandle s_regObjChangedWaitHandle; static AutoResetEvent s_objChangedEvent; static SafeCollabEvent s_safeObjChangedEvent; #endregion // // // // // [System.Security.SecurityCritical] static void AddObjectChangedEvent(EventHandler callback) { CollaborationHelperFunctions.AddMyObjectChanged(callback, ref s_objectChanged, LockObjChangedEvent, ref s_regObjChangedWaitHandle, ref s_objChangedEvent, ref s_safeObjChangedEvent, new WaitOrTimerCallback(ObjectChangedCallback)); } // // // // [System.Security.SecurityCritical] static void RemoveObjectChangedEvent(EventHandler callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() called."); lock (LockObjChangedEvent){ s_objectChanged -= callback; if (s_objectChanged == null){ CollaborationHelperFunctions.CleanEventVars(ref s_regObjChangedWaitHandle, ref s_safeObjChangedEvent, ref s_objChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ObjectChangedEvent variables successful."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveObjectChangedEvent() successful."); } // // // // // // // // // // // // [System.Security.SecurityCritical] static void ObjectChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ObjectChangedCallback() called."); while (true) { ObjectChangedEventArgs objChangedArgs = null; // // Get the event data for the fired event // try { lock (LockObjChangedEvent){ if (s_safeObjChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(s_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.MyObjectChanged){ PEER_EVENT_OBJECT_CHANGED_DATA objData = ped.objectChangedData; PEER_OBJECT po = (PEER_OBJECT)Marshal.PtrToStructure(objData.pObject, typeof(PEER_OBJECT)); PeerObject peerObject = CollaborationHelperFunctions.ConvertPEER_OBJECTToPeerObject(po); ; 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); } objChangedArgs = new ObjectChangedEventArgs(peerEndPoint, null, objData.changeType, peerObject); } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // EventHandler handlerCopy = s_objectChanged; if ((objChangedArgs != null) && (handlerCopy != null)){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { null, objChangedArgs }); else handlerCopy(null, objChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the object changed event callback."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ObjectChangedCallback()."); } static event EventHandler s_applicationChanged; public static event EventHandler LocalApplicationChanged { // // // // [System.Security.SecurityCritical] add { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); AddApplicationChanged(value); } // // // // [System.Security.SecurityCritical] remove { PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand(); CollaborationHelperFunctions.Initialize(); RemoveApplicationChanged(value); } } #region Application changed event variables static object s_lockAppChangedEvent; static object LockAppChangedEvent { get{ if (s_lockAppChangedEvent == null){ object o = new object(); Interlocked.CompareExchange(ref s_lockAppChangedEvent, o, null); } return s_lockAppChangedEvent; } } static RegisteredWaitHandle s_regAppChangedWaitHandle; static AutoResetEvent s_appChangedEvent; static SafeCollabEvent s_safeAppChangedEvent; #endregion // // // // // [System.Security.SecurityCritical] static void AddApplicationChanged(EventHandler callback) { CollaborationHelperFunctions.AddMyApplicationChanged(callback, ref s_applicationChanged, LockAppChangedEvent, ref s_regAppChangedWaitHandle, ref s_appChangedEvent, ref s_safeAppChangedEvent, new WaitOrTimerCallback(ApplicationChangedCallback)); } // // // // [System.Security.SecurityCritical] static void RemoveApplicationChanged(EventHandler callback) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() called."); lock (LockAppChangedEvent){ s_applicationChanged -= callback; if (s_applicationChanged == null){ CollaborationHelperFunctions.CleanEventVars(ref s_regAppChangedWaitHandle, ref s_safeAppChangedEvent, ref s_appChangedEvent); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Clean ApplicationChangEvent variables successful."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "RemoveApplicationChanged() successful."); } // // // // // // // // // // // [System.Security.SecurityCritical] static void ApplicationChangedCallback(object state, bool timedOut) { SafeCollabData eventData = null; int errorCode = 0; Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "ApplicationChangedCallback() called."); while (true){ ApplicationChangedEventArgs appChangedArgs = null; // // Get the event data for the fired event // try{ lock (LockAppChangedEvent){ if (s_safeAppChangedEvent.IsInvalid) return; errorCode = UnsafeCollabNativeMethods.PeerCollabGetEventData(s_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.MyApplicationChanged){ PEER_EVENT_APPLICATION_CHANGED_DATA appData = ped.applicationChangedData; PEER_APPLICATION pa = (PEER_APPLICATION)Marshal.PtrToStructure(appData.pApplication, typeof(PEER_APPLICATION)); PeerApplication peerApplication = CollaborationHelperFunctions.ConvertPEER_APPLICATIONToPeerApplication(pa); ; if (appData.pEndPoint != IntPtr.Zero){ // // This means its an endpoint on my contact which is not on the local machine // so we dont care // return; } appChangedArgs = new ApplicationChangedEventArgs( null, null, appData.changeType, peerApplication); } } finally{ if (eventData != null) eventData.Dispose(); } // // Fire the callback with the marshalled event args data // EventHandler handlerCopy = s_applicationChanged; if ((appChangedArgs != null) && (handlerCopy != null)){ if (SynchronizingObject != null && SynchronizingObject.InvokeRequired) SynchronizingObject.BeginInvoke(handlerCopy, new object[] { null, appChangedArgs }); else handlerCopy(null, appChangedArgs); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Fired the application changed event callback."); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Leaving ApplicationChangedCallback()."); } } }