From 478be44dd6deff328cca51306585779bfba7c535 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Oct 2013 13:13:32 -0400 Subject: [PATCH] create platform-specific network manager implementation --- .../BaseApplicationHost.cs | 5 +- ...MediaBrowser.Common.Implementations.csproj | 4 +- .../NetworkManagement/NetworkManager.cs | 290 ------------------ .../Networking/BaseNetworkManager.cs | 163 ++++++++++ MediaBrowser.Common/Net/INetworkManager.cs | 8 + MediaBrowser.Mono.userprefs | 5 +- .../EntryPoints/LibraryChangedNotifier.cs | 1 + .../Udp/UdpServer.cs | 5 +- .../MediaBrowser.Server.Mono.csproj | 4 +- .../Networking/NetworkManager.cs | 38 +++ .../ApplicationHost.cs | 6 + .../MediaBrowser.ServerApplication.csproj | 3 + .../Networking}/NativeMethods.cs | 2 +- .../Networking/NetworkManager.cs | 136 ++++++++ .../Networking}/NetworkShares.cs | 2 +- 15 files changed, 369 insertions(+), 303 deletions(-) delete mode 100644 MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs create mode 100644 MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs create mode 100644 MediaBrowser.Server.Mono/Networking/NetworkManager.cs rename {MediaBrowser.Common.Implementations/NetworkManagement => MediaBrowser.ServerApplication/Networking}/NativeMethods.cs (97%) create mode 100644 MediaBrowser.ServerApplication/Networking/NetworkManager.cs rename {MediaBrowser.Common.Implementations/NetworkManagement => MediaBrowser.ServerApplication/Networking}/NetworkShares.cs (99%) diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index e202585209..8048a0e121 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -2,7 +2,6 @@ using MediaBrowser.Common.Events; using MediaBrowser.Common.Implementations.Archiving; using MediaBrowser.Common.Implementations.IO; -using MediaBrowser.Common.Implementations.NetworkManagement; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Security; using MediaBrowser.Common.Implementations.Serialization; @@ -335,7 +334,7 @@ namespace MediaBrowser.Common.Implementations HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger, CreateHttpClient); RegisterSingleInstance(HttpClient); - NetworkManager = new NetworkManager(); + NetworkManager = CreateNetworkManager(); RegisterSingleInstance(NetworkManager); SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, NetworkManager); @@ -379,6 +378,8 @@ namespace MediaBrowser.Common.Implementations } } + protected abstract INetworkManager CreateNetworkManager(); + /// /// Creates an instance of type and resolves all constructor dependancies /// diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index af71afcd1b..c2553c1482 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -71,9 +71,7 @@ - - - + diff --git a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs b/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs deleted file mode 100644 index 1ac26cafec..0000000000 --- a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs +++ /dev/null @@ -1,290 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Net; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Runtime.InteropServices; - -namespace MediaBrowser.Common.Implementations.NetworkManagement -{ - /// - /// Class NetUtils - /// - public class NetworkManager : INetworkManager - { - /// - /// Gets the machine's local ip address - /// - /// IPAddress. - public IEnumerable GetLocalIpAddresses() - { - var host = Dns.GetHostEntry(Dns.GetHostName()); - - // Reverse them because the last one is usually the correct one - // It's not fool-proof so ultimately the consumer will have to examine them and decide - return host.AddressList - .Where(i => i.AddressFamily == AddressFamily.InterNetwork) - .Select(i => i.ToString()) - .Reverse(); - } - - /// - /// Gets a random port number that is currently available - /// - /// System.Int32. - public int GetRandomUnusedPort() - { - var listener = new TcpListener(IPAddress.Any, 0); - listener.Start(); - var port = ((IPEndPoint)listener.LocalEndpoint).Port; - listener.Stop(); - return port; - } - - /// - /// Returns MAC Address from first Network Card in Computer - /// - /// [string] MAC Address - public string GetMacAddress() - { - return NetworkInterface.GetAllNetworkInterfaces() - .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) - .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes())) - .FirstOrDefault(); - } - - /// - /// Gets the network shares. - /// - /// The path. - /// IEnumerable{NetworkShare}. - public IEnumerable GetNetworkShares(string path) - { - return new ShareCollection(path).OfType().Select(ToNetworkShare); - } - - /// - /// To the network share. - /// - /// The share. - /// NetworkShare. - private NetworkShare ToNetworkShare(Share share) - { - return new NetworkShare - { - Name = share.NetName, - Path = share.Path, - Remark = share.Remark, - Server = share.Server, - ShareType = ToNetworkShareType(share.ShareType) - }; - } - - /// - /// To the type of the network share. - /// - /// Type of the share. - /// NetworkShareType. - /// Unknown share type - private NetworkShareType ToNetworkShareType(ShareType shareType) - { - if (shareType.HasFlag(ShareType.Special)) - { - return NetworkShareType.Special; - } - if (shareType.HasFlag(ShareType.Device)) - { - return NetworkShareType.Device; - } - if (shareType.HasFlag(ShareType.Disk)) - { - return NetworkShareType.Disk; - } - if (shareType.HasFlag(ShareType.IPC)) - { - return NetworkShareType.Ipc; - } - if (shareType.HasFlag(ShareType.Printer)) - { - return NetworkShareType.Printer; - } - throw new ArgumentException("Unknown share type"); - } - - /// - /// Parses the specified endpointstring. - /// - /// The endpointstring. - /// IPEndPoint. - public IPEndPoint Parse(string endpointstring) - { - return Parse(endpointstring, -1); - } - - /// - /// Parses the specified endpointstring. - /// - /// The endpointstring. - /// The defaultport. - /// IPEndPoint. - /// Endpoint descriptor may not be empty. - /// - private static IPEndPoint Parse(string endpointstring, int defaultport) - { - if (string.IsNullOrEmpty(endpointstring) - || endpointstring.Trim().Length == 0) - { - throw new ArgumentException("Endpoint descriptor may not be empty."); - } - - if (defaultport != -1 && - (defaultport < IPEndPoint.MinPort - || defaultport > IPEndPoint.MaxPort)) - { - throw new ArgumentException(string.Format("Invalid default port '{0}'", defaultport)); - } - - string[] values = endpointstring.Split(new char[] { ':' }); - IPAddress ipaddy; - int port = -1; - - //check if we have an IPv6 or ports - if (values.Length <= 2) // ipv4 or hostname - { - port = values.Length == 1 ? defaultport : GetPort(values[1]); - - //try to use the address as IPv4, otherwise get hostname - if (!IPAddress.TryParse(values[0], out ipaddy)) - ipaddy = GetIPfromHost(values[0]); - } - else if (values.Length > 2) //ipv6 - { - //could [a:b:c]:d - if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]")) - { - string ipaddressstring = string.Join(":", values.Take(values.Length - 1).ToArray()); - ipaddy = IPAddress.Parse(ipaddressstring); - port = GetPort(values[values.Length - 1]); - } - else //[a:b:c] or a:b:c - { - ipaddy = IPAddress.Parse(endpointstring); - port = defaultport; - } - } - else - { - throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); - } - - if (port == -1) - throw new ArgumentException(string.Format("No port specified: '{0}'", endpointstring)); - - return new IPEndPoint(ipaddy, port); - } - - protected static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// Gets the port. - /// - /// The p. - /// System.Int32. - /// - private static int GetPort(string p) - { - int port; - - if (!int.TryParse(p, out port) - || port < IPEndPoint.MinPort - || port > IPEndPoint.MaxPort) - { - throw new FormatException(string.Format("Invalid end point port '{0}'", p)); - } - - return port; - } - - /// - /// Gets the I pfrom host. - /// - /// The p. - /// IPAddress. - /// - private static IPAddress GetIPfromHost(string p) - { - var hosts = Dns.GetHostAddresses(p); - - if (hosts == null || hosts.Length == 0) - throw new ArgumentException(string.Format("Host not found: {0}", p)); - - return hosts[0]; - } - - /// - /// Uses the DllImport : NetServerEnum with all its required parameters - /// (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp - /// for full details or method signature) to retrieve a list of domain SV_TYPE_WORKSTATION - /// and SV_TYPE_SERVER PC's - /// - /// Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER - /// PC's in the Domain - public IEnumerable GetNetworkDevices() - { - //local fields - const int MAX_PREFERRED_LENGTH = -1; - var SV_TYPE_WORKSTATION = 1; - var SV_TYPE_SERVER = 2; - var buffer = IntPtr.Zero; - var tmpBuffer = IntPtr.Zero; - var entriesRead = 0; - var totalEntries = 0; - var resHandle = 0; - var sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100)); - - try - { - //call the DllImport : NetServerEnum with all its required parameters - //see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp - //for full details of method signature - var ret = NativeMethods.NetServerEnum(null, 100, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle); - - //if the returned with a NERR_Success (C++ term), =0 for C# - if (ret == 0) - { - //loop through all SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's - for (var i = 0; i < totalEntries; i++) - { - //get pointer to, Pointer to the buffer that received the data from - //the call to NetServerEnum. Must ensure to use correct size of - //STRUCTURE to ensure correct location in memory is pointed to - tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO)); - //Have now got a pointer to the list of SV_TYPE_WORKSTATION and - //SV_TYPE_SERVER PC's, which is unmanaged memory - //Needs to Marshal data from an unmanaged block of memory to a - //managed object, again using STRUCTURE to ensure the correct data - //is marshalled - var svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure(tmpBuffer, typeof(_SERVER_INFO_100)); - - //add the PC names to the ArrayList - if (!string.IsNullOrEmpty(svrInfo.sv100_name)) - { - yield return svrInfo.sv100_name; - } - } - } - } - finally - { - //The NetApiBufferFree function frees - //the memory that the NetApiBufferAllocate function allocates - NativeMethods.NetApiBufferFree(buffer); - } - } - } - -} diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs new file mode 100644 index 0000000000..ac6b9290ef --- /dev/null +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; + +namespace MediaBrowser.Common.Implementations.Networking +{ + public abstract class BaseNetworkManager + { + /// + /// Gets the machine's local ip address + /// + /// IPAddress. + public IEnumerable GetLocalIpAddresses() + { + var host = Dns.GetHostEntry(Dns.GetHostName()); + + // Reverse them because the last one is usually the correct one + // It's not fool-proof so ultimately the consumer will have to examine them and decide + return host.AddressList + .Where(i => i.AddressFamily == AddressFamily.InterNetwork) + .Select(i => i.ToString()) + .Reverse(); + } + + /// + /// Gets a random port number that is currently available + /// + /// System.Int32. + public int GetRandomUnusedPort() + { + var listener = new TcpListener(IPAddress.Any, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } + + /// + /// Returns MAC Address from first Network Card in Computer + /// + /// [string] MAC Address + public string GetMacAddress() + { + return NetworkInterface.GetAllNetworkInterfaces() + .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) + .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes())) + .FirstOrDefault(); + } + /// + /// Parses the specified endpointstring. + /// + /// The endpointstring. + /// IPEndPoint. + public IPEndPoint Parse(string endpointstring) + { + return Parse(endpointstring, -1); + } + + /// + /// Parses the specified endpointstring. + /// + /// The endpointstring. + /// The defaultport. + /// IPEndPoint. + /// Endpoint descriptor may not be empty. + /// + private static IPEndPoint Parse(string endpointstring, int defaultport) + { + if (String.IsNullOrEmpty(endpointstring) + || endpointstring.Trim().Length == 0) + { + throw new ArgumentException("Endpoint descriptor may not be empty."); + } + + if (defaultport != -1 && + (defaultport < IPEndPoint.MinPort + || defaultport > IPEndPoint.MaxPort)) + { + throw new ArgumentException(String.Format("Invalid default port '{0}'", defaultport)); + } + + string[] values = endpointstring.Split(new char[] { ':' }); + IPAddress ipaddy; + int port = -1; + + //check if we have an IPv6 or ports + if (values.Length <= 2) // ipv4 or hostname + { + port = values.Length == 1 ? defaultport : GetPort(values[1]); + + //try to use the address as IPv4, otherwise get hostname + if (!IPAddress.TryParse(values[0], out ipaddy)) + ipaddy = GetIPfromHost(values[0]); + } + else if (values.Length > 2) //ipv6 + { + //could [a:b:c]:d + if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]")) + { + string ipaddressstring = String.Join(":", values.Take(values.Length - 1).ToArray()); + ipaddy = IPAddress.Parse(ipaddressstring); + port = GetPort(values[values.Length - 1]); + } + else //[a:b:c] or a:b:c + { + ipaddy = IPAddress.Parse(endpointstring); + port = defaultport; + } + } + else + { + throw new FormatException(String.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); + } + + if (port == -1) + throw new ArgumentException(String.Format("No port specified: '{0}'", endpointstring)); + + return new IPEndPoint(ipaddy, port); + } + + protected static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + /// + /// Gets the port. + /// + /// The p. + /// System.Int32. + /// + private static int GetPort(string p) + { + int port; + + if (!Int32.TryParse(p, out port) + || port < IPEndPoint.MinPort + || port > IPEndPoint.MaxPort) + { + throw new FormatException(String.Format("Invalid end point port '{0}'", p)); + } + + return port; + } + + /// + /// Gets the I pfrom host. + /// + /// The p. + /// IPAddress. + /// + private static IPAddress GetIPfromHost(string p) + { + var hosts = Dns.GetHostAddresses(p); + + if (hosts == null || hosts.Length == 0) + throw new ArgumentException(String.Format("Host not found: {0}", p)); + + return hosts[0]; + } + } +} diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index e0171381dd..0d644b9096 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Net; using System.Collections.Generic; +using System.Net; namespace MediaBrowser.Common.Net { @@ -35,5 +36,12 @@ namespace MediaBrowser.Common.Net /// /// PC's in the Domain IEnumerable GetNetworkDevices(); + + /// + /// Parses the specified endpointstring. + /// + /// The endpointstring. + /// IPEndPoint. + IPEndPoint Parse(string endpointstring); } } \ No newline at end of file diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs index f4989cc936..3ab6829ebe 100644 --- a/MediaBrowser.Mono.userprefs +++ b/MediaBrowser.Mono.userprefs @@ -1,9 +1,10 @@  - + - + + diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 8b778f26c3..303109a65f 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -232,6 +232,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints var allRecursiveChildren = user.RootFolder.GetRecursiveChildren(user) .Select(i => i.Id) + .Distinct() .ToDictionary(i => i); return new LibraryUpdateInfo diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index 0aadac9b6c..aca5461c85 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Implementations.NetworkManagement; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Logging; using System; @@ -260,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.Udp throw new ArgumentNullException("remoteEndPoint"); } - await _udpClient.SendAsync(bytes, bytes.Length, new NetworkManager().Parse(remoteEndPoint)).ConfigureAwait(false); + await _udpClient.SendAsync(bytes, bytes.Length, _networkManager.Parse(remoteEndPoint)).ConfigureAwait(false); _logger.Info("Udp message sent to {0}", remoteEndPoint); } diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index 4fd158f4e4..641c306086 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -35,7 +35,6 @@ - @@ -51,6 +50,7 @@ ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll + @@ -84,6 +84,7 @@ + @@ -124,6 +125,7 @@ + diff --git a/MediaBrowser.Server.Mono/Networking/NetworkManager.cs b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs new file mode 100644 index 0000000000..e9f769a3db --- /dev/null +++ b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs @@ -0,0 +1,38 @@ +using MediaBrowser.Common.Implementations.Networking; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Net; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace MediaBrowser.ServerApplication.Networking +{ + /// + /// Class NetUtils + /// + public class NetworkManager : BaseNetworkManager, INetworkManager + { + /// + /// Gets the network shares. + /// + /// The path. + /// IEnumerable{NetworkShare}. + public IEnumerable GetNetworkShares(string path) + { + return new List (); + } + + /// + /// Uses the DllImport : NetServerEnum with all its required parameters + /// (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp + /// for full details or method signature) to retrieve a list of domain SV_TYPE_WORKSTATION + /// and SV_TYPE_SERVER PC's + /// + /// Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER + /// PC's in the Domain + public IEnumerable GetNetworkDevices() + { + return new List (); + } + } +} diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 87bd45e507..50074947da 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -48,6 +48,7 @@ using MediaBrowser.Server.Implementations.Session; using MediaBrowser.Server.Implementations.WebSocket; using MediaBrowser.ServerApplication.FFMpeg; using MediaBrowser.ServerApplication.Native; +using MediaBrowser.ServerApplication.Networking; using MediaBrowser.WebDashboard.Api; using System; using System.Collections.Generic; @@ -296,6 +297,11 @@ namespace MediaBrowser.ServerApplication SetKernelProperties(); } + protected override INetworkManager CreateNetworkManager() + { + return new NetworkManager(); + } + /// /// Registers the media encoder. /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index ecd4891a9b..f0ede70b2e 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -198,6 +198,9 @@ Component + + + SplashWindow.xaml diff --git a/MediaBrowser.Common.Implementations/NetworkManagement/NativeMethods.cs b/MediaBrowser.ServerApplication/Networking/NativeMethods.cs similarity index 97% rename from MediaBrowser.Common.Implementations/NetworkManagement/NativeMethods.cs rename to MediaBrowser.ServerApplication/Networking/NativeMethods.cs index 7c8a094937..20f7ac23d8 100644 --- a/MediaBrowser.Common.Implementations/NetworkManagement/NativeMethods.cs +++ b/MediaBrowser.ServerApplication/Networking/NativeMethods.cs @@ -2,7 +2,7 @@ using System.Runtime.InteropServices; using System.Security; -namespace MediaBrowser.Common.Implementations.NetworkManagement +namespace MediaBrowser.ServerApplication.Networking { /// /// Class NativeMethods diff --git a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs new file mode 100644 index 0000000000..4799dcc723 --- /dev/null +++ b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs @@ -0,0 +1,136 @@ +using MediaBrowser.Common.Implementations.Networking; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Net; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; + +namespace MediaBrowser.ServerApplication.Networking +{ + /// + /// Class NetUtils + /// + public class NetworkManager : BaseNetworkManager, INetworkManager + { + /// + /// Gets the network shares. + /// + /// The path. + /// IEnumerable{NetworkShare}. + public IEnumerable GetNetworkShares(string path) + { + return new ShareCollection(path).OfType().Select(ToNetworkShare); + } + + /// + /// To the network share. + /// + /// The share. + /// NetworkShare. + private NetworkShare ToNetworkShare(Share share) + { + return new NetworkShare + { + Name = share.NetName, + Path = share.Path, + Remark = share.Remark, + Server = share.Server, + ShareType = ToNetworkShareType(share.ShareType) + }; + } + + /// + /// To the type of the network share. + /// + /// Type of the share. + /// NetworkShareType. + /// Unknown share type + private NetworkShareType ToNetworkShareType(ShareType shareType) + { + if (shareType.HasFlag(ShareType.Special)) + { + return NetworkShareType.Special; + } + if (shareType.HasFlag(ShareType.Device)) + { + return NetworkShareType.Device; + } + if (shareType.HasFlag(ShareType.Disk)) + { + return NetworkShareType.Disk; + } + if (shareType.HasFlag(ShareType.IPC)) + { + return NetworkShareType.Ipc; + } + if (shareType.HasFlag(ShareType.Printer)) + { + return NetworkShareType.Printer; + } + throw new ArgumentException("Unknown share type"); + } + + /// + /// Uses the DllImport : NetServerEnum with all its required parameters + /// (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp + /// for full details or method signature) to retrieve a list of domain SV_TYPE_WORKSTATION + /// and SV_TYPE_SERVER PC's + /// + /// Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER + /// PC's in the Domain + public IEnumerable GetNetworkDevices() + { + //local fields + const int MAX_PREFERRED_LENGTH = -1; + var SV_TYPE_WORKSTATION = 1; + var SV_TYPE_SERVER = 2; + var buffer = IntPtr.Zero; + var tmpBuffer = IntPtr.Zero; + var entriesRead = 0; + var totalEntries = 0; + var resHandle = 0; + var sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100)); + + try + { + //call the DllImport : NetServerEnum with all its required parameters + //see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp + //for full details of method signature + var ret = NativeMethods.NetServerEnum(null, 100, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle); + + //if the returned with a NERR_Success (C++ term), =0 for C# + if (ret == 0) + { + //loop through all SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's + for (var i = 0; i < totalEntries; i++) + { + //get pointer to, Pointer to the buffer that received the data from + //the call to NetServerEnum. Must ensure to use correct size of + //STRUCTURE to ensure correct location in memory is pointed to + tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO)); + //Have now got a pointer to the list of SV_TYPE_WORKSTATION and + //SV_TYPE_SERVER PC's, which is unmanaged memory + //Needs to Marshal data from an unmanaged block of memory to a + //managed object, again using STRUCTURE to ensure the correct data + //is marshalled + var svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure(tmpBuffer, typeof(_SERVER_INFO_100)); + + //add the PC names to the ArrayList + if (!string.IsNullOrEmpty(svrInfo.sv100_name)) + { + yield return svrInfo.sv100_name; + } + } + } + } + finally + { + //The NetApiBufferFree function frees + //the memory that the NetApiBufferAllocate function allocates + NativeMethods.NetApiBufferFree(buffer); + } + } + } + +} diff --git a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkShares.cs b/MediaBrowser.ServerApplication/Networking/NetworkShares.cs similarity index 99% rename from MediaBrowser.Common.Implementations/NetworkManagement/NetworkShares.cs rename to MediaBrowser.ServerApplication/Networking/NetworkShares.cs index d06c6b2e22..91bd167b83 100644 --- a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkShares.cs +++ b/MediaBrowser.ServerApplication/Networking/NetworkShares.cs @@ -3,7 +3,7 @@ using System.IO; using System.Collections; using System.Runtime.InteropServices; -namespace MediaBrowser.Common.Implementations.NetworkManagement +namespace MediaBrowser.ServerApplication.Networking { /// /// Type of share