PeerCollaboration.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / SystemNet / Net / PeerToPeer / Collaboration / PeerCollaboration.cs / 1305376 / PeerCollaboration.cs

                            //------------------------------------------------------------------------------ 
// 
//     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 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 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()."); 
        }


    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Net.PeerToPeer.Collaboration 
{ 
    using System;
    using System.Collections.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 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 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()."); 
        }


    } 
}

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

                        

Link Menu

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