You've already forked linux-packaging-mono
Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
@ -128,18 +128,18 @@ namespace System.Net.NetworkInformation {
|
||||
}
|
||||
}
|
||||
|
||||
class LinuxGatewayIPAddressInformationCollection : GatewayIPAddressInformationCollection
|
||||
class UnixGatewayIPAddressInformationCollection : GatewayIPAddressInformationCollection
|
||||
{
|
||||
public static readonly LinuxGatewayIPAddressInformationCollection Empty = new LinuxGatewayIPAddressInformationCollection (true);
|
||||
public static readonly UnixGatewayIPAddressInformationCollection Empty = new UnixGatewayIPAddressInformationCollection (true);
|
||||
|
||||
bool is_readonly;
|
||||
|
||||
private LinuxGatewayIPAddressInformationCollection (bool isReadOnly)
|
||||
private UnixGatewayIPAddressInformationCollection (bool isReadOnly)
|
||||
{
|
||||
this.is_readonly = isReadOnly;
|
||||
}
|
||||
|
||||
public LinuxGatewayIPAddressInformationCollection (IPAddressCollection col)
|
||||
public UnixGatewayIPAddressInformationCollection (IPAddressCollection col)
|
||||
{
|
||||
foreach (IPAddress a in col)
|
||||
Add (new GatewayIPAddressInformationImpl (a));
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Authors:
|
||||
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
||||
// Atsushi Enomoto (atsushi@ximian.com)
|
||||
// Marek Safar (marek.safar@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
|
||||
//
|
||||
@ -43,6 +44,9 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
public static IPGlobalProperties GetIPGlobalProperties ()
|
||||
{
|
||||
#if MONODROID
|
||||
return new AndroidIPGlobalProperties ();
|
||||
#else
|
||||
switch (Environment.OSVersion.Platform) {
|
||||
case PlatformID.Unix:
|
||||
MibIPGlobalProperties impl = null;
|
||||
@ -56,10 +60,16 @@ namespace System.Net.NetworkInformation {
|
||||
if (File.Exists (impl.StatisticsFile))
|
||||
return impl;
|
||||
}
|
||||
throw new NotSupportedException ("This platform is not supported");
|
||||
return new UnixIPGlobalProperties ();
|
||||
default:
|
||||
return new Win32IPGlobalProperties ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static IPGlobalProperties InternalGetIPGlobalProperties()
|
||||
{
|
||||
return GetIPGlobalProperties ();
|
||||
}
|
||||
|
||||
public abstract TcpConnectionInformation [] GetActiveTcpConnections ();
|
||||
@ -81,11 +91,7 @@ namespace System.Net.NetworkInformation {
|
||||
public abstract NetBiosNodeType NodeType { get; }
|
||||
}
|
||||
|
||||
// It expects /proc/net/snmp (or /usr/compat/linux/proc/net/snmp),
|
||||
// formatted like:
|
||||
// http://www.linuxdevcenter.com/linux/2000/11/16/example5.html
|
||||
// http://www.linuxdevcenter.com/linux/2000/11/16/example2.html
|
||||
class MibIPGlobalProperties : IPGlobalProperties
|
||||
abstract class CommonUnixIPGlobalProperties : IPGlobalProperties
|
||||
{
|
||||
[DllImport ("libc")]
|
||||
static extern int gethostname ([MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] name, int len);
|
||||
@ -93,6 +99,112 @@ namespace System.Net.NetworkInformation {
|
||||
[DllImport ("libc")]
|
||||
static extern int getdomainname ([MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] name, int len);
|
||||
|
||||
public override string DhcpScopeName {
|
||||
get { return String.Empty; }
|
||||
}
|
||||
|
||||
public override string DomainName {
|
||||
get {
|
||||
byte [] bytes = new byte [256];
|
||||
if (getdomainname (bytes, 256) != 0)
|
||||
throw new NetworkInformationException ();
|
||||
int len = Array.IndexOf<byte> (bytes, 0);
|
||||
return Encoding.ASCII.GetString (bytes, 0, len < 0 ? 256 : len);
|
||||
}
|
||||
}
|
||||
|
||||
public override string HostName {
|
||||
get {
|
||||
byte [] bytes = new byte [256];
|
||||
if (gethostname (bytes, 256) != 0)
|
||||
throw new NetworkInformationException ();
|
||||
int len = Array.IndexOf<byte> (bytes, 0);
|
||||
return Encoding.ASCII.GetString (bytes, 0, len < 0 ? 256 : len);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsWinsProxy {
|
||||
get { return false; } // no WINS
|
||||
}
|
||||
|
||||
public override NetBiosNodeType NodeType {
|
||||
get { return NetBiosNodeType.Unknown; } // no NetBios
|
||||
}
|
||||
}
|
||||
|
||||
class UnixIPGlobalProperties : CommonUnixIPGlobalProperties
|
||||
{
|
||||
public override TcpConnectionInformation [] GetActiveTcpConnections ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IPEndPoint [] GetActiveTcpListeners ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IPEndPoint [] GetActiveUdpListeners ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IcmpV4Statistics GetIcmpV4Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IcmpV6Statistics GetIcmpV6Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IPGlobalStatistics GetIPv4GlobalStatistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override IPGlobalStatistics GetIPv6GlobalStatistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override TcpStatistics GetTcpIPv4Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override TcpStatistics GetTcpIPv6Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override UdpStatistics GetUdpIPv4Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override UdpStatistics GetUdpIPv6Statistics ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AndroidIPGlobalProperties : UnixIPGlobalProperties
|
||||
{
|
||||
public override string DomainName {
|
||||
get {
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It expects /proc/net/snmp (or /usr/compat/linux/proc/net/snmp),
|
||||
// formatted like:
|
||||
// http://www.linuxdevcenter.com/linux/2000/11/16/example5.html
|
||||
// http://www.linuxdevcenter.com/linux/2000/11/16/example2.html
|
||||
class MibIPGlobalProperties : UnixIPGlobalProperties
|
||||
{
|
||||
public const string ProcDir = "/proc";
|
||||
public const string CompatProcDir = "/usr/compat/linux/proc";
|
||||
|
||||
@ -289,38 +401,6 @@ namespace System.Net.NetworkInformation {
|
||||
{
|
||||
return new MibUdpStatistics (GetProperties6 ("Udp6"));
|
||||
}
|
||||
|
||||
public override string DhcpScopeName {
|
||||
get { return String.Empty; }
|
||||
}
|
||||
|
||||
public override string DomainName {
|
||||
get {
|
||||
byte [] bytes = new byte [256];
|
||||
if (getdomainname (bytes, 256) != 0)
|
||||
throw new NetworkInformationException ();
|
||||
int len = Array.IndexOf<byte> (bytes, 0);
|
||||
return Encoding.ASCII.GetString (bytes, 0, len < 0 ? 256 : len);
|
||||
}
|
||||
}
|
||||
|
||||
public override string HostName {
|
||||
get {
|
||||
byte [] bytes = new byte [256];
|
||||
if (gethostname (bytes, 256) != 0)
|
||||
throw new NetworkInformationException ();
|
||||
int len = Array.IndexOf<byte> (bytes, 0);
|
||||
return Encoding.ASCII.GetString (bytes, 0, len < 0 ? 256 : len);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsWinsProxy {
|
||||
get { return false; } // no WINS
|
||||
}
|
||||
|
||||
public override NetBiosNodeType NodeType {
|
||||
get { return NetBiosNodeType.Unknown; } // no NetBios
|
||||
}
|
||||
}
|
||||
|
||||
class Win32IPGlobalProperties : IPGlobalProperties
|
||||
|
@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace System.Net.NetworkInformation {
|
||||
@ -59,7 +60,6 @@ namespace System.Net.NetworkInformation {
|
||||
protected UnixNetworkInterface iface;
|
||||
List <IPAddress> addresses;
|
||||
IPAddressCollection dns_servers;
|
||||
IPAddressCollection gateways;
|
||||
string dns_suffix;
|
||||
DateTime last_parse;
|
||||
|
||||
@ -74,38 +74,6 @@ namespace System.Net.NetworkInformation {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
void ParseRouteInfo (string iface)
|
||||
{
|
||||
try {
|
||||
gateways = new IPAddressCollection ();
|
||||
using (StreamReader reader = new StreamReader ("/proc/net/route")) {
|
||||
string line;
|
||||
reader.ReadLine (); // Ignore first line
|
||||
while ((line = reader.ReadLine ()) != null) {
|
||||
line = line.Trim ();
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
string [] parts = line.Split ('\t');
|
||||
if (parts.Length < 3)
|
||||
continue;
|
||||
string gw_address = parts [2].Trim ();
|
||||
byte [] ipbytes = new byte [4];
|
||||
if (gw_address.Length == 8 && iface.Equals (parts [0], StringComparison.OrdinalIgnoreCase)) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!Byte.TryParse (gw_address.Substring (i * 2, 2), NumberStyles.HexNumber, null, out ipbytes [3 - i]))
|
||||
continue;
|
||||
}
|
||||
IPAddress ip = new IPAddress (ipbytes);
|
||||
if (!ip.Equals (IPAddress.Any))
|
||||
gateways.Add (ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
|
||||
static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
|
||||
void ParseResolvConf ()
|
||||
@ -188,16 +156,6 @@ namespace System.Net.NetworkInformation {
|
||||
return dns_suffix;
|
||||
}
|
||||
}
|
||||
|
||||
public override GatewayIPAddressInformationCollection GatewayAddresses {
|
||||
get {
|
||||
ParseRouteInfo (this.iface.Name.ToString());
|
||||
if (gateways.Count > 0)
|
||||
return new LinuxGatewayIPAddressInformationCollection (gateways);
|
||||
else
|
||||
return LinuxGatewayIPAddressInformationCollection.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
[MonoTODO ("Always returns true")]
|
||||
public override bool IsDnsEnabled {
|
||||
@ -260,6 +218,8 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
|
||||
{
|
||||
IPAddressCollection gateways;
|
||||
|
||||
public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
|
||||
: base (iface, addresses)
|
||||
{
|
||||
@ -272,10 +232,54 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
return ipv4iface_properties;
|
||||
}
|
||||
|
||||
void ParseRouteInfo (string iface)
|
||||
{
|
||||
try {
|
||||
using (StreamReader reader = new StreamReader ("/proc/net/route")) {
|
||||
string line;
|
||||
reader.ReadLine (); // Ignore first line
|
||||
while ((line = reader.ReadLine ()) != null) {
|
||||
line = line.Trim ();
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
string [] parts = line.Split ('\t');
|
||||
if (parts.Length < 3)
|
||||
continue;
|
||||
string gw_address = parts [2].Trim ();
|
||||
byte [] ipbytes = new byte [4];
|
||||
if (gw_address.Length == 8 && iface.Equals (parts [0], StringComparison.OrdinalIgnoreCase)) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!Byte.TryParse (gw_address.Substring (i * 2, 2), NumberStyles.HexNumber, null, out ipbytes [3 - i]))
|
||||
continue;
|
||||
}
|
||||
IPAddress ip = new IPAddress (ipbytes);
|
||||
if (!ip.Equals (IPAddress.Any) && !gateways.Contains (ip))
|
||||
gateways.Add (ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
public override GatewayIPAddressInformationCollection GatewayAddresses {
|
||||
get {
|
||||
gateways = new IPAddressCollection ();
|
||||
ParseRouteInfo (this.iface.Name.ToString());
|
||||
if (gateways.Count > 0)
|
||||
return new UnixGatewayIPAddressInformationCollection (gateways);
|
||||
else
|
||||
return UnixGatewayIPAddressInformationCollection.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
|
||||
{
|
||||
IPAddressCollection gateways;
|
||||
|
||||
public MacOsIPInterfaceProperties (MacOsNetworkInterface iface, List <IPAddress> addresses)
|
||||
: base (iface, addresses)
|
||||
{
|
||||
@ -288,6 +292,37 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
return ipv4iface_properties;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
||||
private extern static bool ParseRouteInfo_internal(string iface, out string[] gw_addr_list);
|
||||
|
||||
public override GatewayIPAddressInformationCollection GatewayAddresses {
|
||||
get {
|
||||
gateways = new IPAddressCollection ();
|
||||
string[] gw_addrlist;
|
||||
if (!ParseRouteInfo_internal (this.iface.Name.ToString(), out gw_addrlist))
|
||||
return UnixGatewayIPAddressInformationCollection.Empty;
|
||||
|
||||
for(int i=0; i<gw_addrlist.Length; i++) {
|
||||
try {
|
||||
IPAddress ip = IPAddress.Parse(gw_addrlist[i]);
|
||||
if (!ip.Equals (IPAddress.Any) && !gateways.Contains (ip))
|
||||
gateways.Add (ip);
|
||||
} catch (ArgumentNullException) {
|
||||
/* Ignore this, as the
|
||||
* internal call might have
|
||||
* left some blank entries at
|
||||
* the end of the array
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (gateways.Count > 0)
|
||||
return new UnixGatewayIPAddressInformationCollection (gateways);
|
||||
else
|
||||
return UnixGatewayIPAddressInformationCollection.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Win32IPInterfaceProperties2 : IPInterfaceProperties
|
||||
|
@ -55,7 +55,7 @@ namespace System.Net.NetworkInformation {
|
||||
}
|
||||
|
||||
public override int Index {
|
||||
get { return UnixNetworkInterface.IfNameToIndex (iface.Name); }
|
||||
get { return iface.NameIndex; }
|
||||
}
|
||||
|
||||
// TODO: how to discover that?
|
||||
@ -90,7 +90,7 @@ namespace System.Net.NetworkInformation {
|
||||
string iface_path = "/proc/sys/net/ipv4/conf/" + iface.Name + "/forwarding";
|
||||
|
||||
if (File.Exists (iface_path)) {
|
||||
string val = NetworkInterface.ReadLine (iface_path);
|
||||
string val = LinuxNetworkInterface.ReadLine (iface_path);
|
||||
|
||||
return val != "0";
|
||||
}
|
||||
@ -105,7 +105,7 @@ namespace System.Net.NetworkInformation {
|
||||
int ret = 0;
|
||||
|
||||
if (File.Exists (iface_path)) {
|
||||
string val = NetworkInterface.ReadLine (iface_path);
|
||||
string val = LinuxNetworkInterface.ReadLine (iface_path);
|
||||
|
||||
try {
|
||||
ret = Int32.Parse (val);
|
||||
|
@ -120,7 +120,7 @@ namespace System.Net.NetworkInformation {
|
||||
long Read (string file)
|
||||
{
|
||||
try {
|
||||
return long.Parse (NetworkInterface.ReadLine (linux.IfacePath + file));
|
||||
return long.Parse (LinuxNetworkInterface.ReadLine (linux.IfacePath + file));
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,10 +36,8 @@ using System.Net.Sockets;
|
||||
using System.Security.Principal;
|
||||
using System.Security.Cryptography;
|
||||
using System.Runtime.InteropServices;
|
||||
#if NET_4_5
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
|
||||
namespace System.Net.NetworkInformation {
|
||||
[MonoTODO ("IPv6 support is missing")]
|
||||
@ -83,9 +81,7 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
BackgroundWorker worker;
|
||||
object user_async_state;
|
||||
#if NET_4_5
|
||||
CancellationTokenSource cts;
|
||||
#endif
|
||||
|
||||
public event PingCompletedEventHandler PingCompleted;
|
||||
|
||||
@ -155,9 +151,7 @@ namespace System.Net.NetworkInformation {
|
||||
{
|
||||
user_async_state = null;
|
||||
worker = null;
|
||||
#if NET_4_5
|
||||
cts = null;
|
||||
#endif
|
||||
|
||||
if (PingCompleted != null)
|
||||
PingCompleted (this, e);
|
||||
@ -292,7 +286,7 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
private PingReply SendUnprivileged (IPAddress address, int timeout, byte [] buffer, PingOptions options)
|
||||
{
|
||||
DateTime sentTime = DateTime.Now;
|
||||
DateTime sentTime = DateTime.UtcNow;
|
||||
|
||||
Process ping = new Process ();
|
||||
string args = BuildPingArgs (address, timeout, options);
|
||||
@ -307,6 +301,7 @@ namespace System.Net.NetworkInformation {
|
||||
ping.StartInfo.RedirectStandardOutput = true;
|
||||
ping.StartInfo.RedirectStandardError = true;
|
||||
|
||||
IPStatus status = IPStatus.Unknown;
|
||||
try {
|
||||
ping.Start ();
|
||||
|
||||
@ -315,23 +310,21 @@ namespace System.Net.NetworkInformation {
|
||||
string stderr = ping.StandardError.ReadToEnd ();
|
||||
#pragma warning restore 219
|
||||
|
||||
trip_time = (long) (DateTime.Now - sentTime).TotalMilliseconds;
|
||||
trip_time = (long) (DateTime.UtcNow - sentTime).TotalMilliseconds;
|
||||
if (!ping.WaitForExit (timeout) || (ping.HasExited && ping.ExitCode == 2))
|
||||
return new PingReply (address, buffer, options, trip_time, IPStatus.TimedOut);
|
||||
|
||||
if (ping.ExitCode == 1)
|
||||
return new PingReply (address, buffer, options, trip_time, IPStatus.TtlExpired);
|
||||
} catch (Exception) {
|
||||
return new PingReply (address, buffer, options, trip_time, IPStatus.Unknown);
|
||||
status = IPStatus.TimedOut;
|
||||
else if (ping.ExitCode == 0)
|
||||
status = IPStatus.Success;
|
||||
else if (ping.ExitCode == 1)
|
||||
status = IPStatus.TtlExpired;
|
||||
} catch {
|
||||
} finally {
|
||||
if (ping != null) {
|
||||
if (!ping.HasExited)
|
||||
ping.Kill ();
|
||||
ping.Dispose ();
|
||||
}
|
||||
if (!ping.HasExited)
|
||||
ping.Kill ();
|
||||
ping.Dispose ();
|
||||
}
|
||||
|
||||
return new PingReply (address, buffer, options, trip_time, IPStatus.Success);
|
||||
return new PingReply (address, buffer, options, trip_time, status);
|
||||
}
|
||||
|
||||
// Async
|
||||
@ -374,13 +367,8 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
public void SendAsync (IPAddress address, int timeout, byte [] buffer, PingOptions options, object userToken)
|
||||
{
|
||||
#if NET_4_5
|
||||
if ((worker != null) || (cts != null))
|
||||
throw new InvalidOperationException ("Another SendAsync operation is in progress");
|
||||
#else
|
||||
if (worker != null)
|
||||
throw new InvalidOperationException ("Another SendAsync operation is in progress");
|
||||
#endif
|
||||
|
||||
worker = new BackgroundWorker ();
|
||||
worker.DoWork += delegate (object o, DoWorkEventArgs ea) {
|
||||
@ -403,12 +391,10 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
public void SendAsyncCancel ()
|
||||
{
|
||||
#if NET_4_5
|
||||
if (cts != null) {
|
||||
cts.Cancel ();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (worker == null)
|
||||
throw new InvalidOperationException ("SendAsync operation is not in progress");
|
||||
@ -534,7 +520,7 @@ namespace System.Net.NetworkInformation {
|
||||
CultureInfo culture = CultureInfo.InvariantCulture;
|
||||
StringBuilder args = new StringBuilder ();
|
||||
uint t = Convert.ToUInt32 (Math.Floor ((timeout + 1000) / 1000.0));
|
||||
bool is_mac = ((int) Environment.OSVersion.Platform == 6);
|
||||
bool is_mac = Platform.IsMacOS;
|
||||
if (!is_mac)
|
||||
args.AppendFormat (culture, "-q -n -c {0} -w {1} -t {2} -M ", DefaultCount, t, options.Ttl);
|
||||
else
|
||||
@ -549,7 +535,6 @@ namespace System.Net.NetworkInformation {
|
||||
return args.ToString ();
|
||||
}
|
||||
|
||||
#if NET_4_5
|
||||
public Task<PingReply> SendPingAsync (IPAddress address, int timeout, byte [] buffer)
|
||||
{
|
||||
return SendPingAsync (address, default_timeout, default_buffer, new PingOptions ());
|
||||
@ -605,7 +590,6 @@ namespace System.Net.NetworkInformation {
|
||||
|
||||
return task;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user