Click here to Skip to main content
15,898,010 members
Articles / Hosted Services / Serverless

Peer Name Resolution (PNRP)

Rate me:
Please Sign up or sign in to vote.
4.85/5 (25 votes)
27 Oct 20058 min read 92.8K   1.2K   46  
Introduction to Peer Name Resolution and Microsoft's Peer-to-Peer technology.
using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace Peer.NameResolution
{
	public class PeerCloud
	{
		private string name;
		private PNRP_SCOPE scope;
		private uint scopeId;

		internal PeerCloud(string Name, PNRP_SCOPE Scope, uint ScopeId)
		{
			name = Name;
			scope = Scope;
			scopeId = ScopeId;
		}

		public string Name
		{
			get
			{
				return name;
			}
		}

		public PNRP_SCOPE Scope
		{
			get
			{
				return scope;
			}
		}

		public uint ScopeId
		{
			get
			{
				return scopeId;
			}
		}
	}

	public class PeerCloudCollection : IEnumerable
	{
		private static WSAService service = WSAService.Instance;
		private IEnumerator clouds;

		public PeerCloudCollection(PNRP_SCOPE Scope)
		{
			clouds = new PeerCloudEnumerator(Scope);
		}

		public PeerCloudCollection()
		{
			clouds = new PeerCloudEnumerator(PNRP_SCOPE.Any);
		}

		private class PeerCloudEnumerator : IEnumerator
		{
			private static Guid SVCID_PNRPCLOUD = new Guid(0xc2239ce6, 0xc0, 0x4fbf, 0xba, 0xd6, 0x18, 0x13, 0x93, 0x85, 0xa4, 0x9a);
			private IntPtr hLookup;
			private IntPtr pResults;
			private PNRP_SCOPE scope;

			public PeerCloudEnumerator(PNRP_SCOPE Scope)
			{
				scope = Scope;
				Reset();
			}
			~PeerCloudEnumerator()
			{
				if (pResults != IntPtr.Zero) Marshal.FreeHGlobal(pResults);
				if (hLookup != IntPtr.Zero) PnrpNative.WSALookupServiceEnd(hLookup);
			}

			#region IEnumerator Members

			public void Reset()
			{
				int err;
				if (hLookup != IntPtr.Zero)
				{
					err = PnrpNative.WSALookupServiceEnd(hLookup);
					if (err != 0) throw new System.Net.Sockets.SocketException(PnrpNative.WSAGetLastError());
					hLookup = IntPtr.Zero;
					pResults = IntPtr.Zero;
				}

				CSADDR_INFO csaAddr = new CSADDR_INFO();
				PNRPCLOUDINFO pnrpCloudInfo = new PNRPCLOUDINFO();
				BLOB blPnrpData = new BLOB();
				WSAQUERYSET querySet = new WSAQUERYSET();
				
				pnrpCloudInfo.dwSize = Marshal.SizeOf(typeof(PNRPCLOUDINFO));
				pnrpCloudInfo.Cloud.Scope = scope;

				blPnrpData.cbSize = Marshal.SizeOf(typeof(PNRPCLOUDINFO));
				blPnrpData.pBlobData = Marshal.AllocHGlobal(blPnrpData.cbSize);
				Marshal.StructureToPtr(pnrpCloudInfo, blPnrpData.pBlobData, false);

				querySet.dwSize = Marshal.SizeOf(typeof(WSAQUERYSET));
				querySet.dwNameSpace = 39;	// NS_PNRPCLOUD
				querySet.lpServiceClassId = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
				Marshal.StructureToPtr(SVCID_PNRPCLOUD, querySet.lpServiceClassId, false);

				querySet.lpBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BLOB)));
				Marshal.StructureToPtr(blPnrpData, querySet.lpBlob, false);

				IntPtr qryptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WSAQUERYSET)));
				Marshal.StructureToPtr(querySet, qryptr, false);

				err = PnrpNative.WSALookupServiceBegin(qryptr, WSALookup.LUP_RETURN_ALL, out hLookup);
				if (err != 0) throw new System.Net.Sockets.SocketException(PnrpNative.WSAGetLastError());
			}

			public object Current
			{
				get
				{
					WSAQUERYSET querySet = (WSAQUERYSET)Marshal.PtrToStructure(pResults, typeof(WSAQUERYSET));
					BLOB blPnrpData = (BLOB)Marshal.PtrToStructure(querySet.lpBlob, typeof(BLOB));
					PNRPCLOUDINFO pnrpCloudInfo = (PNRPCLOUDINFO)Marshal.PtrToStructure(blPnrpData.pBlobData, typeof(PNRPCLOUDINFO));

					PeerCloud cloud = new PeerCloud(querySet.lpszServiceInstanceName, pnrpCloudInfo.Cloud.Scope, pnrpCloudInfo.Cloud.ScopeId);
					Marshal.FreeHGlobal(pResults);
					return cloud;
				}
			}

			public bool MoveNext()
			{
				int err = Pnrp.LookupServiceNext(hLookup, out pResults);
				if (err != 0) return false;
				return true;
			}

			#endregion
		}

		public IEnumerator GetEnumerator()
		{
			return clouds;
		}

		IEnumerator IEnumerable.GetEnumerator() 
		{
			return GetEnumerator();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
Adrian Moore is the Development Manager for the SCADA Vision system developed by ABB Inc in Calgary, Alberta.

He has been interested in compilers, parsers, real-time database systems and peer-to-peer solutions since the early 90's. In his spare time, he is currently working on a SQL parser for querying .NET DataSets (http://www.queryadataset.com).

Adrian is a Microsoft MVP for Windows Networking.

Comments and Discussions