Listing 1

[StructLayout(LayoutKind.Sequential)]
    public class WSAData
    {
        public Int16 wVersion;
        public Int16 wHighVersion;
        public String szDescription;
        public String szSystemStatus;
        public Int16 iMaxSockets;
        public Int16 iMaxUdpDg;
        public IntPtr lpVendorInfo;
    }

    [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto )]
    public class WSAQUERYSET
    {
        public Int32 dwSize = 0;
        public String szServiceInstanceName = null;
        public IntPtr lpServiceClassId;
        public IntPtr lpVersion;
        public String lpszComment;
        public Int32 dwNameSpace;
        public IntPtr lpNSProviderId;
        public String lpszContext;
        public Int32 dwNumberOfProtocols;
        public IntPtr lpafpProtocols;
        public String lpszQueryString;
        public Int32 dwNumberOfCsAddrs;
        public IntPtr lpcsaBuffer;
        public Int32 dwOutputFlags;
        public IntPtr lpBlob;
    }

[DllImport("Ws2_32.DLL", CharSet = CharSet.Auto,
SetLastError=true)]
private extern static
        Int32 WSAStartup( Int16 wVersionRequested, WSAData wsaData );

[DllImport("Ws2_32.DLL", CharSet = CharSet.Auto,
SetLastError=true)]
private extern static
        Int32 WSACleanup();

[DllImport("Ws2_32.dll", CharSet = CharSet.Auto, 
SetLastError=true)]
private extern static
        Int32 WSALookupServiceBegin(WSAQUERYSET
			qsRestrictions,
            Int32 dwControlFlags, ref Int32 lph	Lookup);


[DllImport("Ws2_32.dll", CharSet = CharSet.Auto,
SetLastError=true)]
private extern static
        Int32 WSALookupServiceNext(Int32 hLookup,
            Int32 dwControlFlags,
            ref Int32 lpdwBufferLength,
            IntPtr pqsResults);

[DllImport("Ws2_32.dll", CharSet = CharSet.Auto,
SetLastError=true)]
private extern static
        Int32 WSALookupServiceEnd(Int32 hLookup);


Listing 2

public virtual ArrayList GetConnectedNetworks()
    {
        ArrayList networkConnections = new ArrayList();
        WSAQUERYSET qsRestrictions;
        Int32 dwControlFlags;
        Int32 valHandle = 0;
        qsRestrictions = new WSAQUERYSET();
        qsRestrictions.dwSize = Marshal.SizeOf(typeof(WSAQUERYSET));
        qsRestrictions.dwNameSpace = 0; //NS_ALL;
        dwControlFlags = 0x0FF0; //LUP_RETURN_ALL;

       int result = WSALookupServiceBegin(qsRestrictions,
            dwControlFlags, ref valHandle);

        CheckResult(result);
		
        while (0 == result)
        {
            Int32 dwBuffer = = 0x10000;
            IntPtr pBuffer = Marshal.AllocHGlobal(dwBuffer);
			
            WSAQUERYSET qsResult = new WSAQUERYSET() ;

            result = WSALookupServiceNext(valHandle, dwControlFlags,
                    ref dwBuffer, pBuffer);

            if (0==result)
            {
              Marshal.PtrToStructure(pBuffer, qsResult);
                networkConnections.Add(qsResult.szServiceInstanceName);
            }
            else
            {
                CheckResult(result);
            }
            Marshal.FreeHGlobal(pBuffer);
        }

        result = WSALookupServiceEnd(valHandle);

        return networkConnections;
    }


Listing 3

[DllImport("Ws2_32.dll", CharSet = CharSet.Auto,
SetLastError=true)]
private extern static Int32 WSANSPIoctl(
        Int32 hLookup,
        UInt32 dwControlCode,
        IntPtr lpvInBuffer,
        Int32 cbInBuffer,
        IntPtr lpvOutBuffer,
        Int32 cbOutBuffer,
        ref Int32 lpcbBytesReturned,
        IntPtr lpCompletion );

    public delegate void NetworkChangedEventHandler (object sender,
        NetworkChangedEventArgs e);

    private Int32 monitorLookup = 0;

    protected void WaitForNetworkChanges()
    {
        WSAQUERYSET qsRestrictions = new WSAQUERYSET();
        Int32 dwControlFlags;

        qsRestrictions.dwSize = Marshal.SizeOf(typeof(WSAQUERYSET));
        qsRestrictions.dwNameSpace = 0; //NS_ALL;

        dwControlFlags = 0x0FF0; //LUP_RETURN_ALL;

      int nResult = WSALookupServiceBegin(qsRestrictions,
                dwControlFlags, ref monitorLookup);

        Int32 dwBytesReturned = 0;
       UInt32 cCode = 2281701401; //SIO_NSP_NOTIFY_CHANGE
        nResult = WSANSPIoctl(monitorLookup, cCode,
                new IntPtr(), 0, new IntPtr(), 0,
                ref dwBytesReturned,
                new IntPtr());

        if (0 != nResult)
        {
            CheckResult(nResult);
        }

        nResult = WSALookupServiceEnd(monitorLookup);
        monitorLookup=0;
    }

    public event NetworkChangedEventHandlerNetworkChanged;

    protected void NetworkMonitor()
    {
        int nResult = 0;

        while (0 == nResult)
        {
            WaitForNetworkChanges();

            ArrayList networks = GetConnectedNetworks();

            NetworkChangedEventArgs eventArgs =
                new NetworkChangedEventArgs(network

            try
            {
                NetworkChanged(this, eventArgs);
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.ToString());
            }
        }
    }

    public virtual void StartNetworkMonitor()
    {
        monitorThread = new Thread(new ThreadStart(this.NetworkMonitor) );
        monitorThread.Name = "Network Monitor";
        monitorThread.IsBackground = true;
        monitorThread.Start();
    }