2007-09-03 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Mon, 3 Sep 2007 08:29:38 +0000 (08:29 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Mon, 3 Sep 2007 08:29:38 +0000 (08:29 -0000)
* IPGlobalStatistics.cs : Mib-* class is nonpublic.
* Win32NetworkInterfaceMarshal.cs IPv4InterfaceProperties.cs
  IPGlobalProperties.cs IPInterfaceProperties.cs
  NetworkInterface.cs : move Win32NetworkInterfaceMarshal.FixedInfo to
  Win32_FIXED_INFO.Instance and share it with Win32IPGlobalProperties.
  Fixed GetUdp[6]Table() / GetTcp[6]Table() marshalling issue.

svn path=/trunk/mcs/; revision=85207

mcs/class/System/System.Net.NetworkInformation/ChangeLog
mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs
mcs/class/System/System.Net.NetworkInformation/IPGlobalStatistics.cs
mcs/class/System/System.Net.NetworkInformation/IPInterfaceProperties.cs
mcs/class/System/System.Net.NetworkInformation/IPv4InterfaceProperties.cs
mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
mcs/class/System/System.Net.NetworkInformation/Win32NetworkInterfaceMarshal.cs

index a89d87452d1c93e52fa7f3d24e78c8f18f3fcd97..5ff6866266d56ed779e438ebcdeb6f836b9914a7 100644 (file)
@@ -1,3 +1,12 @@
+2007-09-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPGlobalStatistics.cs : Mib-* class is nonpublic.
+       * Win32NetworkInterfaceMarshal.cs IPv4InterfaceProperties.cs
+         IPGlobalProperties.cs IPInterfaceProperties.cs
+         NetworkInterface.cs : move Win32NetworkInterfaceMarshal.FixedInfo to
+         Win32_FIXED_INFO.Instance and share it with Win32IPGlobalProperties.
+         Fixed GetUdp[6]Table() / GetTcp[6]Table() marshalling issue.
+
 2007-08-29  Atsushi Enomoto  <atsushi@ximian.com>
 
        * NetworkInterface.cs,
index 89d80fdba1cfff7986c29e996a206638c6773d78..c2afafa2cc899d9a804335970701cd8a37cfb206 100644 (file)
@@ -41,7 +41,7 @@ namespace System.Net.NetworkInformation {
                {
                }
 
-               [MonoTODO ("Properties are not implemented in every platform. A marshalling issue on Windows")]
+               [MonoTODO ("Properties are not implemented on non-Windows platform. A marshalling issue on Windows")]
                public static IPGlobalProperties GetIPGlobalProperties ()
                {
                        switch (Environment.OSVersion.Platform) {
@@ -279,23 +279,23 @@ namespace System.Net.NetworkInformation {
                }
 
                public override string DhcpScopeName {
-                       get { throw new NotImplementedException (); }
+                       get { return Win32_FIXED_INFO.Instance.ScopeId; }
                }
 
                public override string DomainName {
-                       get { throw new NotImplementedException (); }
+                       get { return Win32_FIXED_INFO.Instance.DomainName; }
                }
 
                public override string HostName {
-                       get { throw new NotImplementedException (); }
+                       get { return Win32_FIXED_INFO.Instance.HostName; }
                }
 
                public override bool IsWinsProxy {
-                       get { throw new NotImplementedException (); }
+                       get { return Win32_FIXED_INFO.Instance.EnableProxy != 0; }
                }
 
                public override NetBiosNodeType NodeType {
-                       get { throw new NotImplementedException (); }
+                       get { return Win32_FIXED_INFO.Instance.NodeType; }
                }
        }
 
@@ -304,72 +304,132 @@ namespace System.Net.NetworkInformation {
                public const int AF_INET = 2;
                public const int AF_INET6 = 23;
 
-               // FIXME: fails at some marshaling stage
-               void FillTcpTable (out Win32_MIB_TCPTABLE tab4, out Win32_MIB_TCP6TABLE tab6)
+               // FIXME: it might be getting wrong table. I'm getting
+               // different results from .NET 2.0.
+               unsafe void FillTcpTable (out List<Win32_MIB_TCPROW> tab4, out List<Win32_MIB_TCP6ROW> tab6)
                {
-                       tab4 = null;
+                       tab4 = new List<Win32_MIB_TCPROW> ();
                        int size4 = 0;
-                       GetTcpTable (ref tab4, ref size4, false); // get size
-                       tab4 = new Win32_MIB_TCPTABLE (size4);
-                       GetTcpTable (ref tab4, ref size4, false); // get list
-                       tab6 = null;
-                       int size6 = 0;
-                       GetTcp6Table (ref tab6, ref size6, false); // get size
-                       tab6 = new Win32_MIB_TCP6TABLE (size6);
-                       GetTcp6Table (ref tab6, ref size6, false); // get list
+                       GetTcpTable (null, ref size4, true); // get size
+                       byte [] bytes4 = new byte [size4];
+                       GetTcpTable (bytes4, ref size4, true); // get list
+
+                       int structSize4 = Marshal.SizeOf (typeof (Win32_MIB_TCPROW));
+
+                       fixed (byte* ptr = bytes4) {
+                               int count = Marshal.ReadInt32 ((IntPtr) ptr);
+                               for (int i = 0; i < count; i++) {
+                                       Win32_MIB_TCPROW row = new Win32_MIB_TCPROW ();
+                                       Marshal.PtrToStructure ((IntPtr) (ptr + i * structSize4 + 4), row);
+                                       tab4.Add (row);
+                               }
+                       }
 
+                       tab6 = new List<Win32_MIB_TCP6ROW> ();
+                       if (Environment.OSVersion.Version.Major >= 6) { // Vista
+                               int size6 = 0;
+                               GetTcp6Table (null, ref size6, true); // get size
+                               byte [] bytes6 = new byte [size6];
+                               GetTcp6Table (bytes6, ref size6, true); // get list
+
+                               int structSize6 = Marshal.SizeOf (typeof (Win32_MIB_TCP6ROW));
+
+                               fixed (byte* ptr = bytes6) {
+                                       int count = Marshal.ReadInt32 ((IntPtr) ptr);
+                                       for (int i = 0; i < count; i++) {
+                                               Win32_MIB_TCP6ROW row = new Win32_MIB_TCP6ROW ();
+                                               Marshal.PtrToStructure ((IntPtr) (ptr + i * structSize6 + 4), row);
+                                               tab6.Add (row);
+                                       }
+                               }
+                       }
+               }
+
+               bool IsListenerState (TcpState state)
+               {
+                       switch (state) {
+                       case TcpState.SynSent:
+                       case TcpState.Listen:
+                       case TcpState.FinWait1:
+                       case TcpState.FinWait2:
+                       case TcpState.CloseWait:
+                               return true;
+                       }
+                       return false;
                }
 
                public override TcpConnectionInformation [] GetActiveTcpConnections ()
                {
-                       Win32_MIB_TCPTABLE tab4 = null;
-                       Win32_MIB_TCP6TABLE tab6 = null;
+                       List<Win32_MIB_TCPROW> tab4 = null;
+                       List<Win32_MIB_TCP6ROW> tab6 = null;
                        FillTcpTable (out tab4, out tab6);
-                       int size4 = tab4.Table.Length;
+                       int size4 = tab4.Count;
 
-                       TcpConnectionInformation [] ret = new TcpConnectionInformation [size4 + tab6.Table.Length];
+                       TcpConnectionInformation [] ret = new TcpConnectionInformation [size4 + tab6.Count];
                        for (int i = 0; i < size4; i++)
-                               ret [i] = tab4.Table [i].TcpInfo;
-                       for (int i = 0; i < tab6.Table.Length; i++)
-                               ret [size4 + i] = tab6.Table [i].TcpInfo;
+                               ret [i] = tab4 [i].TcpInfo;
+                       for (int i = 0; i < tab6.Count; i++)
+                               ret [size4 + i] = tab6 [i].TcpInfo;
                        return ret;
                }
 
                public override IPEndPoint [] GetActiveTcpListeners ()
                {
-                       Win32_MIB_TCPTABLE tab4 = null;
-                       Win32_MIB_TCP6TABLE tab6 = null;
+                       List<Win32_MIB_TCPROW> tab4 = null;
+                       List<Win32_MIB_TCP6ROW> tab6 = null;
                        FillTcpTable (out tab4, out tab6);
-                       int size4 = tab4.Table.Length;
 
-                       IPEndPoint [] ret = new IPEndPoint [size4 + tab6.Table.Length];
-                       for (int i = 0; i < size4; i++)
-                               ret [i] = tab4.Table [i].LocalEndPoint;
-                       for (int i = 0; i < tab6.Table.Length; i++)
-                               ret [size4 + i] = tab6.Table [i].LocalEndPoint;
-                       return ret;
+                       List<IPEndPoint> ret = new List<IPEndPoint> ();
+                       for (int i = 0, count = tab4.Count; i < count; i++)
+                               if (IsListenerState (tab4 [i].State))
+                                       ret.Add (tab4 [i].LocalEndPoint);
+                       for (int i = 0, count = tab6.Count; i < count; i++)
+                               if (IsListenerState (tab6 [i].State))
+                                       ret.Add (tab6 [i].LocalEndPoint);
+                       return ret.ToArray ();
                }
 
-               // FIXME: fails at some marshaling stage
-               public override IPEndPoint [] GetActiveUdpListeners ()
+               public unsafe override IPEndPoint [] GetActiveUdpListeners ()
                {
-                       Win32_MIB_UDPTABLE tab4 = null;
+                       List<IPEndPoint> list = new List<IPEndPoint> ();
+
+                       byte [] bytes4 = null;
                        int size4 = 0;
-                       GetUdpTable (ref tab4, ref size4, false); // get size
-                       tab4 = new Win32_MIB_UDPTABLE (size4);
-                       GetUdpTable (ref tab4, ref size4, false); // get list
-                       Win32_MIB_UDP6TABLE tab6 = null;
-                       int size6 = 0;
-                       GetUdp6Table (ref tab6, ref size6, false); // get size
-                       tab6 = new Win32_MIB_UDP6TABLE (size6);
-                       GetUdp6Table (ref tab6, ref size6, false); // get list
-
-                       IPEndPoint [] ret = new IPEndPoint [size4 + size6];
-                       for (int i = 0; i < size4; i++)
-                               ret [i] = tab4.Table [i].LocalEndPoint;
-                       for (int i = 0; i < size6; i++)
-                               ret [size4 + i] = tab6.Table [i].LocalEndPoint;
-                       return ret;
+                       GetUdpTable (null, ref size4, true); // get size
+                       bytes4 = new byte [size4];
+                       GetUdpTable (bytes4, ref size4, true); // get list
+
+                       int structSize4 = Marshal.SizeOf (typeof (Win32_MIB_UDPROW));
+
+                       fixed (byte* ptr = bytes4) {
+                               int count = Marshal.ReadInt32 ((IntPtr) ptr);
+                               for (int i = 0; i < count; i++) {
+                                       Win32_MIB_UDPROW row = new Win32_MIB_UDPROW ();
+                                       Marshal.PtrToStructure ((IntPtr) (ptr + i * structSize4 + 4), row);
+                                       list.Add (row.LocalEndPoint);
+                               }
+                       }
+
+                       if (Environment.OSVersion.Version.Major >= 6) { // Vista
+                               byte [] bytes6 = null;
+                               int size6 = 0;
+                               GetUdp6Table (null, ref size6, true); // get size
+                               bytes6 = new byte [size6];
+                               GetUdp6Table (bytes6, ref size6, true); // get list
+
+                               int structSize6 = Marshal.SizeOf (typeof (Win32_MIB_UDP6ROW));
+
+                               fixed (byte* ptr = bytes6) {
+                                       int count = Marshal.ReadInt32 ((IntPtr) ptr);
+                                       for (int i = 0; i < count; i++) {
+                                               Win32_MIB_UDP6ROW row = new Win32_MIB_UDP6ROW ();
+                                               Marshal.PtrToStructure ((IntPtr) (ptr + i * structSize6 + 4), row);
+                                               list.Add (row.LocalEndPoint);
+                                       }
+                               }
+                       }
+
+                       return list.ToArray ();
                }
 
                public override IcmpV4Statistics GetIcmpV4Statistics ()
@@ -467,16 +527,16 @@ namespace System.Net.NetworkInformation {
                // PInvokes
 
                [DllImport ("Iphlpapi.dll")]
-               static extern int GetTcpTable (ref Win32_MIB_TCPTABLE pTcpTable, ref int pdwSize, bool bOrder);
+               static extern int GetTcpTable (byte [] pTcpTable, ref int pdwSize, bool bOrder);
 
                [DllImport ("Iphlpapi.dll")]
-               static extern int GetTcp6Table (ref Win32_MIB_TCP6TABLE TcpTable, ref int SizePointer, bool Order);
+               static extern int GetTcp6Table (byte [] TcpTable, ref int SizePointer, bool Order);
 
                [DllImport ("Iphlpapi.dll")]
-               static extern int GetUdpTable (ref Win32_MIB_UDPTABLE pUdpTable, ref int pdwSize, bool bOrder);
+               static extern int GetUdpTable (byte [] pUdpTable, ref int pdwSize, bool bOrder);
 
                [DllImport ("Iphlpapi.dll")]
-               static extern int GetUdp6Table (ref Win32_MIB_UDP6TABLE Udp6Table, ref int SizePointer, bool Order);
+               static extern int GetUdp6Table (byte [] Udp6Table, ref int SizePointer, bool Order);
 
                [DllImport ("Iphlpapi.dll")]
                static extern int GetTcpStatisticsEx (out Win32_MIB_TCPSTATS pStats, int dwFamily);
@@ -510,22 +570,7 @@ namespace System.Net.NetworkInformation {
                }
 
                [StructLayout (LayoutKind.Sequential)]
-               class Win32_MIB_TCPTABLE
-               {
-                       public int NumEntries;
-                       // FIXME: looks like it is wrong
-                       [MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_USERDEFINED, SafeArrayUserDefinedSubType = typeof (Win32_MIB_TCPROW))]
-                       public Win32_MIB_TCPROW [] Table;
-
-                       public Win32_MIB_TCPTABLE (int size)
-                       {
-                               NumEntries = size;
-                               Table = new Win32_MIB_TCPROW [size];
-                       }
-               }
-
-               [StructLayout (LayoutKind.Sequential)]
-               struct Win32_MIB_TCPROW
+               class Win32_MIB_TCPROW
                {
                        public TcpState State;
                        public uint LocalAddr;
@@ -547,22 +592,7 @@ namespace System.Net.NetworkInformation {
                }
 
                [StructLayout (LayoutKind.Sequential)]
-               class Win32_MIB_TCP6TABLE
-               {
-                       public int NumEntries;
-                       // FIXME: looks like it is wrong
-                       [MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_USERDEFINED, SafeArrayUserDefinedSubType = typeof (Win32_MIB_TCP6ROW))]
-                       public Win32_MIB_TCP6ROW [] Table;
-
-                       public Win32_MIB_TCP6TABLE (int size)
-                       {
-                               NumEntries = size;
-                               Table = new Win32_MIB_TCP6ROW [size];
-                       }
-               }
-
-               [StructLayout (LayoutKind.Sequential)]
-               struct Win32_MIB_TCP6ROW
+               class Win32_MIB_TCP6ROW
                {
                        public TcpState State;
                        public Win32_IN6_ADDR LocalAddr;
@@ -586,22 +616,7 @@ namespace System.Net.NetworkInformation {
                }
 
                [StructLayout (LayoutKind.Sequential)]
-               class Win32_MIB_UDPTABLE
-               {
-                       public int NumEntries;
-                       // FIXME: looks like it is wrong
-                       [MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_USERDEFINED, SafeArrayUserDefinedSubType = typeof (Win32_MIB_UDPROW))]
-                       public Win32_MIB_UDPROW [] Table;
-
-                       public Win32_MIB_UDPTABLE (int size)
-                       {
-                               NumEntries = size;
-                               Table = new Win32_MIB_UDPROW [size];
-                       }
-               }
-
-               [StructLayout (LayoutKind.Sequential)]
-               struct Win32_MIB_UDPROW
+               class Win32_MIB_UDPROW
                {
                        public uint LocalAddr;
                        public int LocalPort;
@@ -612,22 +627,7 @@ namespace System.Net.NetworkInformation {
                }
 
                [StructLayout (LayoutKind.Sequential)]
-               class Win32_MIB_UDP6TABLE
-               {
-                       public int NumEntries;
-                       // FIXME: looks like it is wrong
-                       [MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_USERDEFINED, SafeArrayUserDefinedSubType = typeof (Win32_MIB_UDP6ROW))]
-                       public Win32_MIB_UDP6ROW [] Table;
-
-                       public Win32_MIB_UDP6TABLE (int size)
-                       {
-                               NumEntries = size;
-                               Table = new Win32_MIB_UDP6ROW [size];
-                       }
-               }
-
-               [StructLayout (LayoutKind.Sequential)]
-               struct Win32_MIB_UDP6ROW
+               class Win32_MIB_UDP6ROW
                {
                        public Win32_IN6_ADDR LocalAddr;
                        public uint LocalScopeId;
index fd0f52c1110a702215ff3b586195f662cc97310f..2ba59ef1a52b6b7677bdf8b2b9d2a1cb31618f63 100644 (file)
@@ -60,7 +60,7 @@ namespace System.Net.NetworkInformation {
                public abstract long ReceivedPacketsWithUnknownProtocol { get; }
        }
 
-       public class MibIPGlobalStatistics : IPGlobalStatistics
+       class MibIPGlobalStatistics : IPGlobalStatistics
        {
                StringDictionary dic;
 
index 91ade8af5d0960f6dbc87d2a5f0f93857e08fa05..c80ce1e4520b351aee5592f70f9ba9ad33d531c8 100644 (file)
@@ -101,7 +101,7 @@ namespace System.Net.NetworkInformation {
                }
 
                public override bool IsDnsEnabled {
-                       get { return Win32NetworkInterface2.FixedInfo.EnableDns != 0; }
+                       get { return Win32_FIXED_INFO.Instance.EnableDns != 0; }
                }
 
                public override bool IsDynamicDnsEnabled {
index ef95c4a32d13bb1417c69758eccdea9c11c0d93c..8899a9c70c787a26b1ff87e1bef2b0a0853b7464 100644 (file)
@@ -85,7 +85,7 @@ namespace System.Net.NetworkInformation {
 
                public override bool IsForwardingEnabled {
                        // Is it the right answer? In Vista there is MIB_IPINTERFACEROW.ForwardingEnabled, but not in former versions.
-                       get { return Win32NetworkInterface2.FixedInfo.EnableRouting != 0; }
+                       get { return Win32_FIXED_INFO.Instance.EnableRouting != 0; }
                }
 
                public override int Mtu {
index 064246de288ac7422938abdf0ff1a29d6a04c1cd..201e98758fb981a54dc332fa130bbd6af54b3476 100644 (file)
@@ -80,9 +80,6 @@ namespace System.Net.NetworkInformation {
 
        class Win32NetworkInterface2 : NetworkInterface
        {
-               [DllImport ("iphlpapi.dll", SetLastError = true)]
-               static extern int GetNetworkParams (byte [] bytes, ref int size);
-
                [DllImport ("iphlpapi.dll", SetLastError = true)]
                static extern int GetAdaptersInfo (byte [] info, ref int size);
 
@@ -92,32 +89,6 @@ namespace System.Net.NetworkInformation {
                [DllImport ("iphlpapi.dll", SetLastError = true)]
                static extern int GetIfEntry (ref Win32_MIB_IFROW row);
 
-               static Win32_FIXED_INFO fixed_info;
-
-               public static Win32_FIXED_INFO FixedInfo {
-                       get {
-                               if (fixed_info == null)
-                                       fixed_info = GetFixedInfo ();
-                               return fixed_info;
-                       }
-               }
-
-               static Win32_FIXED_INFO GetFixedInfo ()
-               {
-                       int len = 0;
-                       byte [] bytes = null;
-                       GetNetworkParams (null, ref len);
-                       bytes = new byte [len];
-                       GetNetworkParams (bytes, ref len);
-                       Win32_FIXED_INFO info = new Win32_FIXED_INFO ();
-                       unsafe {
-                               fixed (byte* ptr = bytes) {
-                                       Marshal.PtrToStructure ((IntPtr) ptr, info);
-                               }
-                       }
-                       return info;
-               }
-
                public static NetworkInterface [] GetAllNetworkInterfaces ()
                {
                        Win32_IP_ADAPTER_INFO [] ai = GetAdaptersInfo ();
index bccfcb5f14da7840f4eeffa9bde8e4652bc3100b..f7ead0a4e3837dc7b1d59416333a3b1b714beb13 100644 (file)
@@ -40,6 +40,35 @@ namespace System.Net.NetworkInformation
        [StructLayout (LayoutKind.Sequential)]
        class Win32_FIXED_INFO
        {
+               [DllImport ("iphlpapi.dll", SetLastError = true)]
+               static extern int GetNetworkParams (byte [] bytes, ref int size);
+
+               static Win32_FIXED_INFO fixed_info;
+
+               public static Win32_FIXED_INFO Instance {
+                       get {
+                               if (fixed_info == null)
+                                       fixed_info = GetInstance ();
+                               return fixed_info;
+                       }
+               }
+
+               static Win32_FIXED_INFO GetInstance ()
+               {
+                       int len = 0;
+                       byte [] bytes = null;
+                       GetNetworkParams (null, ref len);
+                       bytes = new byte [len];
+                       GetNetworkParams (bytes, ref len);
+                       Win32_FIXED_INFO info = new Win32_FIXED_INFO ();
+                       unsafe {
+                               fixed (byte* ptr = bytes) {
+                                       Marshal.PtrToStructure ((IntPtr) ptr, info);
+                               }
+                       }
+                       return info;
+               }
+
                const int MAX_HOSTNAME_LEN = 128;
                const int MAX_DOMAIN_NAME_LEN = 128;
                const int MAX_SCOPE_ID_LEN = 256;
@@ -50,7 +79,7 @@ namespace System.Net.NetworkInformation
                public string DomainName;
                public IntPtr CurrentDnsServer; // to Win32IP_ADDR_STRING
                public Win32_IP_ADDR_STRING DnsServerList;
-               public uint NodeType;
+               public NetBiosNodeType NodeType;
                [MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_SCOPE_ID_LEN + 4)]
                public string ScopeId;
                public uint EnableRouting;