public void ResolveAsync(PeerName peerName, Cloud cloud, int maxRecords, object userState) { //------------------------------------------------- //Check arguments //------------------------------------------------- if (peerName == null) { throw new ArgumentNullException(SR.GetString(SR.Pnrp_PeerNameCantBeNull), "peerName"); } if (cloud == null) { cloud = Cloud.Available; } if (maxRecords <= 0) { throw new ArgumentOutOfRangeException("maxRecords", SR.GetString(SR.Pnrp_MaxRecordsParameterMustBeGreaterThanZero)); } if (m_ResolveCompleted == null) { throw new PeerToPeerException(SR.GetString(SR.Pnrp_AtleastOneEvenHandlerNeeded)); } //--------------------------------------------------- //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(); //---------------------------------------------------- //userToken can't be null //---------------------------------------------------- if (userState == null) { throw new ArgumentNullException(SR.GetString(SR.NullUserToken), "userState"); } PeerNameResolverHelper peerNameResolverHelper = null; //--------------------------------------------------- //The userToken can't be duplicate of what is in the //current list. These are the requriments for the new Async model //that supports multiple outstanding async calls //--------------------------------------------------- int newTraceEventId = NewTraceEventId; lock (m_PeerNameResolverHelperListLock) { if (m_PeerNameResolverHelperList.ContainsKey(userState)) { throw new ArgumentException(SR.GetString(SR.DuplicateUserToken)); } Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, newTraceEventId, "PeerNameResolverHelper is being created with TraceEventId {0}", newTraceEventId); peerNameResolverHelper = new PeerNameResolverHelper(peerName, cloud, maxRecords, userState, this, newTraceEventId); m_PeerNameResolverHelperList[userState] = peerNameResolverHelper; } try { //--------------------------------------------------- //Start resolution on that resolver //--------------------------------------------------- peerNameResolverHelper.StartAsyncResolve(); } catch { //--------------------------------------------------- //If an exception happens clear the userState from the //list so that that token can be reused //--------------------------------------------------- lock (m_PeerNameResolverHelperListLock) { m_PeerNameResolverHelperList.Remove(userState); Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, newTraceEventId, "Removing userState token from pending list {0}", userState.GetHashCode()); } throw; } }
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 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); }
private static void GetCloudOrClouds(string cloudName, bool bGlobalCloudOnly, out CloudCollection clouds, out Cloud cloud) { cloud = null; clouds = null; Logging.Enter(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()"); //------------------------------------------------- //Demand for the Unrestricted Pnrp Permission //------------------------------------------------- PnrpPermission.UnrestrictedPnrpPermission.Demand(); Int32 result = 0; UInt32 numClouds = 0; SafePeerData ArrayOfCloudInfoStructures = null; if (cloudName == null) { //----------------------------------------- //We need the collection only when we are not //getting a specific cloud //----------------------------------------- clouds = new CloudCollection(); } try { //--------------------------------------------------------------- //No perf hit here, real native call happens only one time if it //did not already happen //--------------------------------------------------------------- UnsafeP2PNativeMethods.PnrpStartup(); result = UnsafeP2PNativeMethods.PeerPnrpGetCloudInfo(out numClouds, out ArrayOfCloudInfoStructures); if (result != 0) { throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotEnumerateClouds), result); } if (numClouds != 0) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Number of clouds returned {0}", numClouds); IntPtr pPEER_PNRP_CLOUD_INFO = ArrayOfCloudInfoStructures.DangerousGetHandle(); for (ulong i = 0; i < numClouds; i++) { PEER_PNRP_CLOUD_INFO cloudinfo = (PEER_PNRP_CLOUD_INFO)Marshal.PtrToStructure(pPEER_PNRP_CLOUD_INFO, typeof(PEER_PNRP_CLOUD_INFO)); string nativeCloudName = Marshal.PtrToStringUni(cloudinfo.pwzCloudName); pPEER_PNRP_CLOUD_INFO = (IntPtr)((long)pPEER_PNRP_CLOUD_INFO + Marshal.SizeOf(typeof(PEER_PNRP_CLOUD_INFO))); Cloud c = new Cloud(nativeCloudName, (PnrpScope)((int)cloudinfo.dwScope), (int)cloudinfo.dwScopeId); if (cloudName == null && !bGlobalCloudOnly) { clouds.Add(c); continue; } //If a specific cloud by name is required, then test for name //note that scope is PnrpScope.All but we don't test that now if (cloudName != null && cloudName == nativeCloudName) { cloud = c; break; } if (bGlobalCloudOnly && c.Scope == PnrpScope.Global) { cloud = c; break; } } } else { Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, "No Clouds returned from the native call"); } } finally { if (ArrayOfCloudInfoStructures != null) { ArrayOfCloudInfoStructures.Dispose(); } } if (cloudName != null && cloud == null) { Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "The specific cloud name {0} asked for is not found", cloudName); } Logging.Leave(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()"); }