public void Update()
        {
            //-------------------------------------------------
            //Check for the dead object
            //-------------------------------------------------
            if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName);

            //-------------------------------------------------
            //If there is no existing registration to update
            //get out
            //-------------------------------------------------
            if (!IsRegistered())
            {
                throw new InvalidOperationException(SR.GetString(SR.Pnrp_CallRegisterBeforeUpdate));
            }

            //-------------------------------------------------
            //Check for parameters
            //-------------------------------------------------
            if (m_PeerNameRecord.PeerName == null)
            {
                throw new ArgumentNullException(SR.GetString(SR.Pnrp_InvalidPeerName));
            }

            //-------------------------------------------------
            //If the current PeerName associated with the 
            //current registration is not the same as the 
            //PeerName given now - throw
            //-------------------------------------------------
            if (!m_RegisteredPeerName.Equals(m_PeerNameRecord.PeerName))
            {
                throw new InvalidOperationException(SR.GetString(SR.Pnrp_CantChangePeerNameAfterRegistration));
            }

            //------------------------------------------
            //If auto address selection is turned off
            //then there must be atleast Data or Endpoints
            //specified 
            //------------------------------------------
            if (!m_UseAutoEndPointSelection)
            {
                if ((EndPointCollection.Count == 0) ||
                     (Data == null || Data.Length <= 0))
                {
                    throw new PeerToPeerException(SR.GetString(SR.Pnrp_BlobOrEndpointListNeeded));
                }
            }

            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            //---------------------------------------------------------------
            //Log trace info
            //---------------------------------------------------------------
            if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information))
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Update() is called with the following Info");
                m_PeerNameRecord.TracePeerNameRecord();
            }

            PEER_PNRP_REGISTRATION_INFO regInfo = new PEER_PNRP_REGISTRATION_INFO();
            //-------------------------------------------------
            //Set data
            //-------------------------------------------------
            if (m_PeerNameRecord.Data != null)
            {
                regInfo.payLoad.cbPayload = (UInt32)m_PeerNameRecord.Data.Length;
                //Marshal.All
                //regInfo.payLoad.pbPayload = m_PeerNameRecord.Data;
                GCHandle handle = GCHandle.Alloc(m_PeerNameRecord.Data, GCHandleType.Pinned);
                regInfo.payLoad.pbPayload = handle.AddrOfPinnedObject(); //m_PeerNameRecord.Data;
                handle.Free();
            };
            //-------------------------------------------------
            //Set comment
            //-------------------------------------------------
            if (m_PeerNameRecord.Comment != null && m_PeerNameRecord.Comment.Length > 0)
            {
                regInfo.pwszComment = m_PeerNameRecord.Comment;
            }
            //-------------------------------------------------
            //Set cloud name
            //-------------------------------------------------
            regInfo.pwszCloudName = null;
            if (m_Cloud != null)
            {
                regInfo.pwszCloudName = m_Cloud.InternalName;
            }

            if (m_PeerNameRecord.EndPointCollection.Count == 0)
            {
                //-------------------------------------------------
                //Set port only if the addresses are null
                //and then set the selection to auto addresses
                //-------------------------------------------------
                regInfo.wport = (ushort)m_Port;
                regInfo.cAddresses = PEER_PNRP_AUTO_ADDRESSES;

                int result = UnsafeP2PNativeMethods.PeerPnrpUpdateRegistration(m_RegistrationHandle, ref regInfo);
                if (result != 0)
                {
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                }
                return;
            }
            else
            {
                //-------------------------------------------------
                //Set the Endpoint List
                //-------------------------------------------------
                int numAddresses = m_PeerNameRecord.EndPointCollection.Count;
                int cbRequriedBytes = numAddresses * Marshal.SizeOf(typeof(IntPtr));
                IntPtr pSocketAddrList = Marshal.AllocHGlobal(cbRequriedBytes);
                GCHandle[] GCHandles = new GCHandle[numAddresses];
                try
                {
                    unsafe
                    {
                        IntPtr* pAddress = (IntPtr*)pSocketAddrList;
                        for (int i = 0; i < m_PeerNameRecord.EndPointCollection.Count; i++)
                        {
                            byte[] sockaddr = SystemNetHelpers.SOCKADDRFromIPEndPoint(m_PeerNameRecord.EndPointCollection[i]);
                            GCHandles[i] = GCHandle.Alloc(sockaddr, GCHandleType.Pinned);
                            IntPtr psockAddr = GCHandles[i].AddrOfPinnedObject();
                            pAddress[i] = psockAddr;
                        }
                    }
                    regInfo.ArrayOfSOCKADDRIN6Pointers = pSocketAddrList;
                    regInfo.cAddresses = (UInt32)numAddresses;
                    int result = UnsafeP2PNativeMethods.PeerPnrpUpdateRegistration(m_RegistrationHandle, ref regInfo);
                    if (result != 0)
                    {
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                    }
                }
                finally
                {
                    if (pSocketAddrList != IntPtr.Zero)
                        Marshal.FreeHGlobal(pSocketAddrList);

                    for (int i = 0; i < GCHandles.Length; i++)
                    {
                        if (GCHandles[i].IsAllocated)
                            GCHandles[i].Free();
                    }
                }

                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Update of existing registration is successful. The handle is {0}", m_RegistrationHandle.DangerousGetHandle());
            }

        }
        public void Update()
        {
            //-------------------------------------------------
            //Check for the dead object
            //-------------------------------------------------
            if (m_Disposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            //-------------------------------------------------
            //If there is no existing registration to update
            //get out
            //-------------------------------------------------
            if (!IsRegistered())
            {
                throw new InvalidOperationException(SR.GetString(SR.Pnrp_CallRegisterBeforeUpdate));
            }

            //-------------------------------------------------
            //Check for parameters
            //-------------------------------------------------
            if (m_PeerNameRecord.PeerName == null)
            {
                throw new ArgumentNullException(SR.GetString(SR.Pnrp_InvalidPeerName));
            }

            //-------------------------------------------------
            //If the current PeerName associated with the
            //current registration is not the same as the
            //PeerName given now - throw
            //-------------------------------------------------
            if (!m_RegisteredPeerName.Equals(m_PeerNameRecord.PeerName))
            {
                throw new InvalidOperationException(SR.GetString(SR.Pnrp_CantChangePeerNameAfterRegistration));
            }

            //------------------------------------------
            //If auto address selection is turned off
            //then there must be atleast Data or Endpoints
            //specified
            //------------------------------------------
            if (!m_UseAutoEndPointSelection)
            {
                if ((EndPointCollection.Count == 0) ||
                    (Data == null || Data.Length <= 0))
                {
                    throw new PeerToPeerException(SR.GetString(SR.Pnrp_BlobOrEndpointListNeeded));
                }
            }

            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            //---------------------------------------------------------------
            //Log trace info
            //---------------------------------------------------------------
            if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information))
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Update() is called with the following Info");
                m_PeerNameRecord.TracePeerNameRecord();
            }

            PEER_PNRP_REGISTRATION_INFO regInfo = new PEER_PNRP_REGISTRATION_INFO();

            //-------------------------------------------------
            //Set data
            //-------------------------------------------------
            if (m_PeerNameRecord.Data != null)
            {
                regInfo.payLoad.cbPayload = (UInt32)m_PeerNameRecord.Data.Length;
                //Marshal.All
                //regInfo.payLoad.pbPayload = m_PeerNameRecord.Data;
                GCHandle handle = GCHandle.Alloc(m_PeerNameRecord.Data, GCHandleType.Pinned);
                regInfo.payLoad.pbPayload = handle.AddrOfPinnedObject(); //m_PeerNameRecord.Data;
                handle.Free();
            }
            ;
            //-------------------------------------------------
            //Set comment
            //-------------------------------------------------
            if (m_PeerNameRecord.Comment != null && m_PeerNameRecord.Comment.Length > 0)
            {
                regInfo.pwszComment = m_PeerNameRecord.Comment;
            }
            //-------------------------------------------------
            //Set cloud name
            //-------------------------------------------------
            regInfo.pwszCloudName = null;
            if (m_Cloud != null)
            {
                regInfo.pwszCloudName = m_Cloud.InternalName;
            }

            if (m_PeerNameRecord.EndPointCollection.Count == 0)
            {
                //-------------------------------------------------
                //Set port only if the addresses are null
                //and then set the selection to auto addresses
                //-------------------------------------------------
                regInfo.wport      = (ushort)m_Port;
                regInfo.cAddresses = PEER_PNRP_AUTO_ADDRESSES;

                int result = UnsafeP2PNativeMethods.PeerPnrpUpdateRegistration(m_RegistrationHandle, ref regInfo);
                if (result != 0)
                {
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                }
                return;
            }
            else
            {
                //-------------------------------------------------
                //Set the Endpoint List
                //-------------------------------------------------
                int        numAddresses    = m_PeerNameRecord.EndPointCollection.Count;
                int        cbRequriedBytes = numAddresses * Marshal.SizeOf(typeof(IntPtr));
                IntPtr     pSocketAddrList = Marshal.AllocHGlobal(cbRequriedBytes);
                GCHandle[] GCHandles       = new GCHandle[numAddresses];
                try
                {
                    unsafe
                    {
                        IntPtr *pAddress = (IntPtr *)pSocketAddrList;
                        for (int i = 0; i < m_PeerNameRecord.EndPointCollection.Count; i++)
                        {
                            byte[] sockaddr = SystemNetHelpers.SOCKADDRFromIPEndPoint(m_PeerNameRecord.EndPointCollection[i]);
                            GCHandles[i] = GCHandle.Alloc(sockaddr, GCHandleType.Pinned);
                            IntPtr psockAddr = GCHandles[i].AddrOfPinnedObject();
                            pAddress[i] = psockAddr;
                        }
                    }
                    regInfo.ArrayOfSOCKADDRIN6Pointers = pSocketAddrList;
                    regInfo.cAddresses = (UInt32)numAddresses;
                    int result = UnsafeP2PNativeMethods.PeerPnrpUpdateRegistration(m_RegistrationHandle, ref regInfo);
                    if (result != 0)
                    {
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                    }
                }
                finally
                {
                    if (pSocketAddrList != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(pSocketAddrList);
                    }

                    for (int i = 0; i < GCHandles.Length; i++)
                    {
                        if (GCHandles[i].IsAllocated)
                        {
                            GCHandles[i].Free();
                        }
                    }
                }

                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Update of existing registration is successful. The handle is {0}", m_RegistrationHandle.DangerousGetHandle());
            }
        }
        private void InternalRegister()
        {
            //------------------------------------------
            //If we already registered, get out this place
            //------------------------------------------
            if (m_IsRegistered)
            {
                throw new PeerToPeerException(SR.GetString(SR.Pnrp_UseUpdateInsteadOfRegister));
            }

            //------------------------------------------
            //Make sure you have the required info
            //------------------------------------------
            if (m_PeerNameRecord.PeerName == null)
            {
                throw new ArgumentNullException("PeerName");
            }

            //------------------------------------------
            //If auto address selection is turned off
            //then there must be atleast Data or Endpoints
            //specified 
            //------------------------------------------
            if (!m_UseAutoEndPointSelection)
            {
                if ((EndPointCollection.Count == 0) &&
                     (Data == null || Data.Length <= 0))
                {
                    throw new PeerToPeerException(SR.GetString(SR.Pnrp_BlobOrEndpointListNeeded));
                }
            }


            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            //---------------------------------------------------------------
            //No perf hit here, real native call happens only one time if it 
            //did not already happen
            //---------------------------------------------------------------
            UnsafeP2PNativeMethods.PnrpStartup();

            //---------------------------------------------------------------
            //Log trace info
            //---------------------------------------------------------------
            if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information))
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "InternalRegister() is called with the following Info");
                m_PeerNameRecord.TracePeerNameRecord();
            }

            PEER_PNRP_REGISTRATION_INFO regInfo = new PEER_PNRP_REGISTRATION_INFO();
            GCHandle handle;
            //-------------------------------------------------
            //Set data
            //-------------------------------------------------
            if (m_PeerNameRecord.Data != null)
            {
                regInfo.payLoad.cbPayload = (UInt32)m_PeerNameRecord.Data.Length;
                handle = GCHandle.Alloc(m_PeerNameRecord.Data, GCHandleType.Pinned);
                regInfo.payLoad.pbPayload = handle.AddrOfPinnedObject(); //m_PeerNameRecord.Data;
            }
            else
            {
                handle = new GCHandle();
            }
            //-------------------------------------------------
            //Set comment
            //-------------------------------------------------
            if (m_PeerNameRecord.Comment != null && m_PeerNameRecord.Comment.Length > 0)
            {
                regInfo.pwszComment = m_PeerNameRecord.Comment;
            }
            //-------------------------------------------------
            //Set cloud name
            //-------------------------------------------------
            if (m_Cloud != null)
            {
                regInfo.pwszCloudName = m_Cloud.InternalName;
            }
            try
            {
                if (m_PeerNameRecord.EndPointCollection.Count == 0)
                {
                    //-------------------------------------------------
                    //Set port only if the addresses are null
                    //and then set the selection to auto addresses
                    //-------------------------------------------------
                    regInfo.wport = (ushort)m_Port;

                    if(m_UseAutoEndPointSelection)
                        regInfo.cAddresses = PEER_PNRP_AUTO_ADDRESSES;

                    //-------------------------------------------------
                    //Call the native API to register
                    //-------------------------------------------------
                    int result = UnsafeP2PNativeMethods.PeerPnrpRegister(m_PeerNameRecord.PeerName.ToString(),
                                        ref regInfo,
                                        out m_RegistrationHandle);
                    if (result != 0)
                    {
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                    }
                }
                else
                {
                    //-------------------------------------------------
                    //Set the Endpoint List
                    //-------------------------------------------------
                    int numAddresses = m_PeerNameRecord.EndPointCollection.Count;
                    int cbRequriedBytes = numAddresses * Marshal.SizeOf(typeof(IntPtr));
                    IntPtr pSocketAddrList = Marshal.AllocHGlobal(cbRequriedBytes);
                    GCHandle[] GCHandles = new GCHandle[numAddresses];
                    try
                    {
                        unsafe
                        {
                            IntPtr* pAddress = (IntPtr*)pSocketAddrList;
                            for (int i = 0; i < m_PeerNameRecord.EndPointCollection.Count; i++)
                            {
                                byte[] sockaddr = SystemNetHelpers.SOCKADDRFromIPEndPoint(m_PeerNameRecord.EndPointCollection[i]);
                                GCHandles[i] = GCHandle.Alloc(sockaddr, GCHandleType.Pinned);
                                IntPtr psockAddr = GCHandles[i].AddrOfPinnedObject();
                                pAddress[i] = psockAddr;
                            }
                        }
                        regInfo.ArrayOfSOCKADDRIN6Pointers = pSocketAddrList;
                        regInfo.cAddresses = (UInt32)numAddresses;
                        int result = UnsafeP2PNativeMethods.PeerPnrpRegister(m_PeerNameRecord.PeerName.ToString(),
                                            ref regInfo,
                                            out m_RegistrationHandle);
                        if (result != 0)
                        {
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                        }
                    }
                    finally
                    {
                        if (pSocketAddrList != IntPtr.Zero)
                            Marshal.FreeHGlobal(pSocketAddrList);

                        for (int i = 0; i < GCHandles.Length; i++)
                        {
                            if (GCHandles[i].IsAllocated)
                                GCHandles[i].Free();
                        }
                    }
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }

            }
            m_RegisteredPeerName = m_PeerNameRecord.PeerName;
            m_IsRegistered = true;
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Registration is successful. The handle is {0}", m_RegistrationHandle.DangerousGetHandle());
        }
        private void InternalRegister()
        {
            //------------------------------------------
            //If we already registered, get out this place
            //------------------------------------------
            if (m_IsRegistered)
            {
                throw new PeerToPeerException(SR.GetString(SR.Pnrp_UseUpdateInsteadOfRegister));
            }

            //------------------------------------------
            //Make sure you have the required info
            //------------------------------------------
            if (m_PeerNameRecord.PeerName == null)
            {
                throw new ArgumentNullException("PeerName");
            }

            //------------------------------------------
            //If auto address selection is turned off
            //then there must be atleast Data or Endpoints
            //specified
            //------------------------------------------
            if (!m_UseAutoEndPointSelection)
            {
                if ((EndPointCollection.Count == 0) &&
                    (Data == null || Data.Length <= 0))
                {
                    throw new PeerToPeerException(SR.GetString(SR.Pnrp_BlobOrEndpointListNeeded));
                }
            }


            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            //---------------------------------------------------------------
            //No perf hit here, real native call happens only one time if it
            //did not already happen
            //---------------------------------------------------------------
            UnsafeP2PNativeMethods.PnrpStartup();

            //---------------------------------------------------------------
            //Log trace info
            //---------------------------------------------------------------
            if (Logging.P2PTraceSource.Switch.ShouldTrace(TraceEventType.Information))
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "InternalRegister() is called with the following Info");
                m_PeerNameRecord.TracePeerNameRecord();
            }

            PEER_PNRP_REGISTRATION_INFO regInfo = new PEER_PNRP_REGISTRATION_INFO();
            GCHandle handle;

            //-------------------------------------------------
            //Set data
            //-------------------------------------------------
            if (m_PeerNameRecord.Data != null)
            {
                regInfo.payLoad.cbPayload = (UInt32)m_PeerNameRecord.Data.Length;
                handle = GCHandle.Alloc(m_PeerNameRecord.Data, GCHandleType.Pinned);
                regInfo.payLoad.pbPayload = handle.AddrOfPinnedObject(); //m_PeerNameRecord.Data;
            }
            else
            {
                handle = new GCHandle();
            }
            //-------------------------------------------------
            //Set comment
            //-------------------------------------------------
            if (m_PeerNameRecord.Comment != null && m_PeerNameRecord.Comment.Length > 0)
            {
                regInfo.pwszComment = m_PeerNameRecord.Comment;
            }
            //-------------------------------------------------
            //Set cloud name
            //-------------------------------------------------
            if (m_Cloud != null)
            {
                regInfo.pwszCloudName = m_Cloud.InternalName;
            }
            try
            {
                if (m_PeerNameRecord.EndPointCollection.Count == 0)
                {
                    //-------------------------------------------------
                    //Set port only if the addresses are null
                    //and then set the selection to auto addresses
                    //-------------------------------------------------
                    regInfo.wport = (ushort)m_Port;

                    if (m_UseAutoEndPointSelection)
                    {
                        regInfo.cAddresses = PEER_PNRP_AUTO_ADDRESSES;
                    }

                    //-------------------------------------------------
                    //Call the native API to register
                    //-------------------------------------------------
                    int result = UnsafeP2PNativeMethods.PeerPnrpRegister(m_PeerNameRecord.PeerName.ToString(),
                                                                         ref regInfo,
                                                                         out m_RegistrationHandle);
                    if (result != 0)
                    {
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                    }
                }
                else
                {
                    //-------------------------------------------------
                    //Set the Endpoint List
                    //-------------------------------------------------
                    int        numAddresses    = m_PeerNameRecord.EndPointCollection.Count;
                    int        cbRequriedBytes = numAddresses * Marshal.SizeOf(typeof(IntPtr));
                    IntPtr     pSocketAddrList = Marshal.AllocHGlobal(cbRequriedBytes);
                    GCHandle[] GCHandles       = new GCHandle[numAddresses];
                    try
                    {
                        unsafe
                        {
                            IntPtr *pAddress = (IntPtr *)pSocketAddrList;
                            for (int i = 0; i < m_PeerNameRecord.EndPointCollection.Count; i++)
                            {
                                byte[] sockaddr = SystemNetHelpers.SOCKADDRFromIPEndPoint(m_PeerNameRecord.EndPointCollection[i]);
                                GCHandles[i] = GCHandle.Alloc(sockaddr, GCHandleType.Pinned);
                                IntPtr psockAddr = GCHandles[i].AddrOfPinnedObject();
                                pAddress[i] = psockAddr;
                            }
                        }
                        regInfo.ArrayOfSOCKADDRIN6Pointers = pSocketAddrList;
                        regInfo.cAddresses = (UInt32)numAddresses;
                        int result = UnsafeP2PNativeMethods.PeerPnrpRegister(m_PeerNameRecord.PeerName.ToString(),
                                                                             ref regInfo,
                                                                             out m_RegistrationHandle);
                        if (result != 0)
                        {
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotRegisterPeerName), result);
                        }
                    }
                    finally
                    {
                        if (pSocketAddrList != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(pSocketAddrList);
                        }

                        for (int i = 0; i < GCHandles.Length; i++)
                        {
                            if (GCHandles[i].IsAllocated)
                            {
                                GCHandles[i].Free();
                            }
                        }
                    }
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }
            m_RegisteredPeerName = m_PeerNameRecord.PeerName;
            m_IsRegistered       = true;
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Registration is successful. The handle is {0}", m_RegistrationHandle.DangerousGetHandle());
        }
 public extern static Int32 PeerPnrpUpdateRegistration(SafePeerNameUnregister hRegistration,
                                             ref PEER_PNRP_REGISTRATION_INFO registrationInfo);
 public extern static Int32 PeerPnrpRegister(string pcwzPeerName,
                                             ref PEER_PNRP_REGISTRATION_INFO registrationInfo,
                                             out SafePeerNameUnregister handle);
 public extern static Int32 PeerPnrpUpdateRegistration(SafePeerNameUnregister hRegistration,
                                                       ref PEER_PNRP_REGISTRATION_INFO registrationInfo);
 public extern static Int32 PeerPnrpRegister(string pcwzPeerName,
                                             ref PEER_PNRP_REGISTRATION_INFO registrationInfo,
                                             out SafePeerNameUnregister handle);