public PeerNameRecordCollection Resolve(PeerName peerName, Cloud cloud, int maxRecords) { //--------------------------------------------------- //Check arguments //--------------------------------------------------- if (peerName == null) { throw new ArgumentNullException(SR.GetString(SR.Pnrp_PeerNameCantBeNull), "peerName"); } if (maxRecords <= 0) { throw new ArgumentOutOfRangeException("maxRecords", SR.GetString(SR.Pnrp_MaxRecordsParameterMustBeGreaterThanZero)); } //--------------------------------------------------- //Assume all clouds if the clould passed is null? //--------------------------------------------------- if (cloud == null) { cloud = Cloud.Available; } //--------------------------------------------------- //Demand CAS permissions //--------------------------------------------------- PnrpPermission.UnrestrictedPnrpPermission.Demand(); //--------------------------------------------------------------- //No perf hit here, real native call happens only one time if it //did not already happen //--------------------------------------------------------------- UnsafeP2PNativeMethods.PnrpStartup(); //--------------------------------------------------------------- //Trace log //--------------------------------------------------------------- Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Sync Resolve called with PeerName: {0}, Cloud: {1}, MaxRecords {2}", peerName, cloud, maxRecords); SafePeerData shEndPointInfoArray; string NativeCloudName = cloud.InternalName; UInt32 ActualCountOfEndPoints = (UInt32)maxRecords; int result = UnsafeP2PNativeMethods.PeerPnrpResolve(peerName.ToString(), NativeCloudName, ref ActualCountOfEndPoints, out shEndPointInfoArray); if (result != 0) { throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotStartNameResolution), result); } //--------------------------------------------------- //If there are no endpoints returned, return //an empty PeerNameRecord Collection //--------------------------------------------------- PeerNameRecordCollection PeerNameRecords = new PeerNameRecordCollection(); if (ActualCountOfEndPoints != 0) { try { unsafe { IntPtr pEndPointInfoArray = shEndPointInfoArray.DangerousGetHandle(); PEER_PNRP_ENDPOINT_INFO *pEndPoints = (PEER_PNRP_ENDPOINT_INFO *)pEndPointInfoArray; for (int i = 0; i < ActualCountOfEndPoints; i++) { PeerNameRecord record = new PeerNameRecord(); PEER_PNRP_ENDPOINT_INFO *pEndPointInfo = &pEndPoints[i]; record.PeerName = new PeerName(Marshal.PtrToStringUni(pEndPointInfo->pwszPeerName)); string comment = Marshal.PtrToStringUni(pEndPointInfo->pwszComment); if (comment != null && comment.Length > 0) { record.Comment = comment; } if (pEndPointInfo->payLoad.cbPayload != 0) { record.Data = new byte[pEndPointInfo->payLoad.cbPayload]; Marshal.Copy(pEndPointInfo->payLoad.pbPayload, record.Data, 0, (int)pEndPointInfo->payLoad.cbPayload); } //record.EndPointList = new IPEndPoint[pEndPointInfo->cAddresses]; IntPtr ppSOCKADDRs = pEndPointInfo->ArrayOfSOCKADDRIN6Pointers; for (UInt32 j = 0; j < pEndPointInfo->cAddresses; j++) { IntPtr pSOCKADDR = Marshal.ReadIntPtr(ppSOCKADDRs); byte[] AddressFamilyBuffer = new byte[2]; Marshal.Copy(pSOCKADDR, AddressFamilyBuffer, 0, 2); int addressFamily = 0; #if BIGENDIAN addressFamily = AddressFamilyBuffer[1] + ((int)AddressFamilyBuffer[0] << 8); #else addressFamily = AddressFamilyBuffer[0] + ((int)AddressFamilyBuffer[1] << 8); #endif byte[] buffer = new byte[((AddressFamily)addressFamily == AddressFamily.InterNetwork) ? SystemNetHelpers.IPv4AddressSize : SystemNetHelpers.IPv6AddressSize]; Marshal.Copy(pSOCKADDR, buffer, 0, buffer.Length); IPEndPoint ipe = SystemNetHelpers.IPEndPointFromSOCKADDRBuffer(buffer); record.EndPointCollection.Add(ipe); ppSOCKADDRs = (IntPtr)((long)ppSOCKADDRs + Marshal.SizeOf(typeof(IntPtr))); } //---------------------------------- //Dump for trace //---------------------------------- record.TracePeerNameRecord(); //---------------------------------- //Add to collection //---------------------------------- PeerNameRecords.Add(record); } } } finally { shEndPointInfoArray.Dispose(); } } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Sync Resolve returnig with PeerNameRecord count :{0}", PeerNameRecords.Count); return(PeerNameRecords); }
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 EndPointInfoAvailableCallback(object state, bool timedOut) { //------------------------------------------ //This callback is called whenever there is an endpoint info //available or the resultion is completed //------------------------------------------ Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "EndPointInfoAvailableCallback called"); PeerNameRecord record = null; SafePeerData shEndPointInfo; Int32 result = 0; PeerNameResolver parent = null; if (m_Cancelled) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Detected that the async operation is already canceled - before entering the lock"); return; } lock (m_Lock) { if (m_Cancelled) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Detected that the async operation is already canceled - after entering the lock"); return; } result = UnsafeP2PNativeMethods.PeerPnrpGetEndpoint(m_SafePeerNameEndResolve.DangerousGetHandle(), out shEndPointInfo); if (result != 0) { if (result == PEER_E_NO_MORE) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Native API returned that there are no more records - resolve completed successfully"); } m_CompletedOrException = true; m_SafePeerNameEndResolve.Dispose(); } else { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Proceeding to retrieve the endpoint information from incremental resolve"); try { unsafe { PEER_PNRP_ENDPOINT_INFO *pEndPointInfo = (PEER_PNRP_ENDPOINT_INFO *)shEndPointInfo.DangerousGetHandle(); record = new PeerNameRecord(); record.PeerName = new PeerName(Marshal.PtrToStringUni(pEndPointInfo->pwszPeerName)); string comment = Marshal.PtrToStringUni(pEndPointInfo->pwszComment); if (comment != null && comment.Length > 0) { record.Comment = comment; } if (pEndPointInfo->payLoad.cbPayload != 0) { record.Data = new byte[pEndPointInfo->payLoad.cbPayload]; Marshal.Copy(pEndPointInfo->payLoad.pbPayload, record.Data, 0, (int)pEndPointInfo->payLoad.cbPayload); } //record.EndPointList = new IPEndPoint[pEndPointInfo->cAddresses]; IntPtr ppSOCKADDRs = pEndPointInfo->ArrayOfSOCKADDRIN6Pointers; for (UInt32 j = 0; j < pEndPointInfo->cAddresses; j++) { IntPtr pSOCKADDR = Marshal.ReadIntPtr(ppSOCKADDRs); byte[] AddressFamilyBuffer = new byte[2]; Marshal.Copy(pSOCKADDR, AddressFamilyBuffer, 0, 2); int addressFamily = 0; #if BIGENDIAN addressFamily = AddressFamilyBuffer[1] + ((int)AddressFamilyBuffer[0] << 8); #else addressFamily = AddressFamilyBuffer[0] + ((int)AddressFamilyBuffer[1] << 8); #endif byte[] buffer = new byte[((AddressFamily)addressFamily == AddressFamily.InterNetwork) ? SystemNetHelpers.IPv4AddressSize : SystemNetHelpers.IPv6AddressSize]; Marshal.Copy(pSOCKADDR, buffer, 0, buffer.Length); IPEndPoint ipe = SystemNetHelpers.IPEndPointFromSOCKADDRBuffer(buffer); record.EndPointCollection.Add(ipe); ppSOCKADDRs = (IntPtr)((long)ppSOCKADDRs + Marshal.SizeOf(typeof(IntPtr))); } } } finally { shEndPointInfo.Dispose(); } record.TracePeerNameRecord(); m_PeerNameRecordCollection.Add(record); ResolveProgressChangedEventArgs resolveProgressChangedEventArgs = new ResolveProgressChangedEventArgs( record, m_AsyncOp.UserSuppliedState); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Proceeding to call progress changed event callback"); parent = m_PeerNameResolverWeakReference.Target as PeerNameResolver; if (parent != null) { parent.PrepareToRaiseProgressChangedEvent(m_AsyncOp, resolveProgressChangedEventArgs); } return; } } ResolveCompletedEventArgs resolveCompletedEventArgs; if (result == PEER_E_NO_MORE) { resolveCompletedEventArgs = new ResolveCompletedEventArgs(m_PeerNameRecordCollection, null, false, m_AsyncOp.UserSuppliedState); } else { PeerToPeerException ex = PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_ExceptionWhileResolvingAPeerName), result); Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Exception occurred when the native API is called to harvest an incremental resolve notification"); resolveCompletedEventArgs = new ResolveCompletedEventArgs(null, ex, false, m_AsyncOp.UserSuppliedState); } parent = m_PeerNameResolverWeakReference.Target as PeerNameResolver; if (parent != null) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, m_TraceEventId, "Proceeding to call the ResolveCompleted callback"); parent.PrepareToRaiseCompletedEvent(m_AsyncOp, resolveCompletedEventArgs); } return; }
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()); }