Browse Source

create platform-specific network manager implementation

Luke Pulverenti 11 years ago
parent
commit
478be44dd6

+ 3 - 2
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();
+
         /// <summary>
         /// Creates an instance of type and resolves all constructor dependancies
         /// </summary>

+ 1 - 3
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -71,9 +71,7 @@
     <Compile Include="Logging\LogHelper.cs" />
     <Compile Include="Logging\NLogger.cs" />
     <Compile Include="Logging\NlogManager.cs" />
-    <Compile Include="NetworkManagement\NativeMethods.cs" />
-    <Compile Include="NetworkManagement\NetworkManager.cs" />
-    <Compile Include="NetworkManagement\NetworkShares.cs" />
+    <Compile Include="Networking\BaseNetworkManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ScheduledTasks\ScheduledTaskWorker.cs" />
     <Compile Include="ScheduledTasks\TaskManager.cs" />

+ 0 - 290
MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs

@@ -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
-{
-    /// <summary>
-    /// Class NetUtils
-    /// </summary>
-    public class NetworkManager : INetworkManager
-    {
-        /// <summary>
-        /// Gets the machine's local ip address
-        /// </summary>
-        /// <returns>IPAddress.</returns>
-        public IEnumerable<string> 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();
-        }
-
-        /// <summary>
-        /// Gets a random port number that is currently available
-        /// </summary>
-        /// <returns>System.Int32.</returns>
-        public int GetRandomUnusedPort()
-        {
-            var listener = new TcpListener(IPAddress.Any, 0);
-            listener.Start();
-            var port = ((IPEndPoint)listener.LocalEndpoint).Port;
-            listener.Stop();
-            return port;
-        }
-
-        /// <summary>
-        /// Returns MAC Address from first Network Card in Computer
-        /// </summary>
-        /// <returns>[string] MAC Address</returns>
-        public string GetMacAddress()
-        {
-            return NetworkInterface.GetAllNetworkInterfaces()
-                .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
-                .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes()))
-                .FirstOrDefault();
-        }
-
-        /// <summary>
-        /// Gets the network shares.
-        /// </summary>
-        /// <param name="path">The path.</param>
-        /// <returns>IEnumerable{NetworkShare}.</returns>
-        public IEnumerable<NetworkShare> GetNetworkShares(string path)
-        {
-            return new ShareCollection(path).OfType<Share>().Select(ToNetworkShare);
-        }
-
-        /// <summary>
-        /// To the network share.
-        /// </summary>
-        /// <param name="share">The share.</param>
-        /// <returns>NetworkShare.</returns>
-        private NetworkShare ToNetworkShare(Share share)
-        {
-            return new NetworkShare
-            {
-                Name = share.NetName,
-                Path = share.Path,
-                Remark = share.Remark,
-                Server = share.Server,
-                ShareType = ToNetworkShareType(share.ShareType)
-            };
-        }
-
-        /// <summary>
-        /// To the type of the network share.
-        /// </summary>
-        /// <param name="shareType">Type of the share.</param>
-        /// <returns>NetworkShareType.</returns>
-        /// <exception cref="System.ArgumentException">Unknown share type</exception>
-        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");
-        }
-
-        /// <summary>
-        /// Parses the specified endpointstring.
-        /// </summary>
-        /// <param name="endpointstring">The endpointstring.</param>
-        /// <returns>IPEndPoint.</returns>
-        public IPEndPoint Parse(string endpointstring)
-        {
-            return Parse(endpointstring, -1);
-        }
-
-        /// <summary>
-        /// Parses the specified endpointstring.
-        /// </summary>
-        /// <param name="endpointstring">The endpointstring.</param>
-        /// <param name="defaultport">The defaultport.</param>
-        /// <returns>IPEndPoint.</returns>
-        /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception>
-        /// <exception cref="System.FormatException"></exception>
-        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");
-
-        /// <summary>
-        /// Gets the port.
-        /// </summary>
-        /// <param name="p">The p.</param>
-        /// <returns>System.Int32.</returns>
-        /// <exception cref="System.FormatException"></exception>
-        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;
-        }
-
-        /// <summary>
-        /// Gets the I pfrom host.
-        /// </summary>
-        /// <param name="p">The p.</param>
-        /// <returns>IPAddress.</returns>
-        /// <exception cref="System.ArgumentException"></exception>
-        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];
-        }
-
-        /// <summary>
-        /// 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
-        /// </summary>
-        /// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
-        /// PC's in the Domain</returns>
-        public IEnumerable<string> 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);
-            }
-        }
-    }
-
-}

+ 163 - 0
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
+    {
+        /// <summary>
+        /// Gets the machine's local ip address
+        /// </summary>
+        /// <returns>IPAddress.</returns>
+        public IEnumerable<string> 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();
+        }
+
+        /// <summary>
+        /// Gets a random port number that is currently available
+        /// </summary>
+        /// <returns>System.Int32.</returns>
+        public int GetRandomUnusedPort()
+        {
+            var listener = new TcpListener(IPAddress.Any, 0);
+            listener.Start();
+            var port = ((IPEndPoint)listener.LocalEndpoint).Port;
+            listener.Stop();
+            return port;
+        }
+
+        /// <summary>
+        /// Returns MAC Address from first Network Card in Computer
+        /// </summary>
+        /// <returns>[string] MAC Address</returns>
+        public string GetMacAddress()
+        {
+            return NetworkInterface.GetAllNetworkInterfaces()
+                .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
+                .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes()))
+                .FirstOrDefault();
+        }
+        /// <summary>
+        /// Parses the specified endpointstring.
+        /// </summary>
+        /// <param name="endpointstring">The endpointstring.</param>
+        /// <returns>IPEndPoint.</returns>
+        public IPEndPoint Parse(string endpointstring)
+        {
+            return Parse(endpointstring, -1);
+        }
+
+        /// <summary>
+        /// Parses the specified endpointstring.
+        /// </summary>
+        /// <param name="endpointstring">The endpointstring.</param>
+        /// <param name="defaultport">The defaultport.</param>
+        /// <returns>IPEndPoint.</returns>
+        /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception>
+        /// <exception cref="System.FormatException"></exception>
+        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");
+
+        /// <summary>
+        /// Gets the port.
+        /// </summary>
+        /// <param name="p">The p.</param>
+        /// <returns>System.Int32.</returns>
+        /// <exception cref="System.FormatException"></exception>
+        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;
+        }
+
+        /// <summary>
+        /// Gets the I pfrom host.
+        /// </summary>
+        /// <param name="p">The p.</param>
+        /// <returns>IPAddress.</returns>
+        /// <exception cref="System.ArgumentException"></exception>
+        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];
+        }
+    }
+}

+ 8 - 0
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
         /// </summary>
         /// <returns>PC's in the Domain</returns>
         IEnumerable<string> GetNetworkDevices();
+
+        /// <summary>
+        /// Parses the specified endpointstring.
+        /// </summary>
+        /// <param name="endpointstring">The endpointstring.</param>
+        /// <returns>IPEndPoint.</returns>
+        IPEndPoint Parse(string endpointstring);
     }
 }

+ 3 - 2
MediaBrowser.Mono.userprefs

@@ -1,9 +1,10 @@
 <Properties>
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
-  <MonoDevelop.Ide.Workbench ActiveDocument="MediaBrowser.Server.Mono\FFMpeg\FFMpegDownloader.cs">
+  <MonoDevelop.Ide.Workbench ActiveDocument="MediaBrowser.Server.Mono\Networking\NetworkManager.cs">
     <Files>
-      <File FileName="MediaBrowser.Server.Implementations\HttpServer\HttpServer.cs" Line="604" Column="23" />
+      <File FileName="MediaBrowser.Server.Implementations\HttpServer\HttpServer.cs" Line="1" Column="1" />
       <File FileName="MediaBrowser.Server.Mono\FFMpeg\FFMpegDownloader.cs" Line="1" Column="1" />
+      <File FileName="MediaBrowser.Server.Mono\Networking\NetworkManager.cs" Line="39" Column="1" />
     </Files>
   </MonoDevelop.Ide.Workbench>
   <MonoDevelop.Ide.DebuggingService.Breakpoints>

+ 1 - 0
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

+ 2 - 3
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);
         }

+ 3 - 1
MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj

@@ -35,7 +35,6 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
-    <Reference Include="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
     <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
@@ -51,6 +50,7 @@
     <Reference Include="ServiceStack.Interfaces">
       <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
+    <Reference Include="Mono.Posix" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="gtk-gui\gui.stetic">
@@ -84,6 +84,7 @@
     <Compile Include="Native\Assemblies.cs" />
     <Compile Include="Native\NativeApp.cs" />
     <Compile Include="Native\HttpClientFactory.cs" />
+    <Compile Include="Networking\NetworkManager.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
@@ -124,6 +125,7 @@
     <Folder Include="EntryPoints\" />
     <Folder Include="Native\" />
     <Folder Include="FFMpeg\" />
+    <Folder Include="Networking\" />
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />

+ 38 - 0
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
+{
+    /// <summary>
+    /// Class NetUtils
+    /// </summary>
+    public class NetworkManager : BaseNetworkManager, INetworkManager
+    {
+        /// <summary>
+        /// Gets the network shares.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <returns>IEnumerable{NetworkShare}.</returns>
+        public IEnumerable<NetworkShare> GetNetworkShares(string path)
+        {
+			return new List<NetworkShare> ();
+        }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
+        /// PC's in the Domain</returns>
+        public IEnumerable<string> GetNetworkDevices()
+        {
+			return new List<string> ();
+        }
+    }
+}

+ 6 - 0
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();
+        }
+
         /// <summary>
         /// Registers the media encoder.
         /// </summary>

+ 3 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -198,6 +198,9 @@
     <Compile Include="BackgroundServiceInstaller.cs">
       <SubType>Component</SubType>
     </Compile>
+    <Compile Include="Networking\NativeMethods.cs" />
+    <Compile Include="Networking\NetworkManager.cs" />
+    <Compile Include="Networking\NetworkShares.cs" />
     <Compile Include="Splash\SplashWindow.xaml.cs">
       <DependentUpon>SplashWindow.xaml</DependentUpon>
     </Compile>

+ 1 - 1
MediaBrowser.Common.Implementations/NetworkManagement/NativeMethods.cs → 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
 {
     /// <summary>
     /// Class NativeMethods

+ 136 - 0
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
+{
+    /// <summary>
+    /// Class NetUtils
+    /// </summary>
+    public class NetworkManager : BaseNetworkManager, INetworkManager
+    {
+        /// <summary>
+        /// Gets the network shares.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <returns>IEnumerable{NetworkShare}.</returns>
+        public IEnumerable<NetworkShare> GetNetworkShares(string path)
+        {
+            return new ShareCollection(path).OfType<Share>().Select(ToNetworkShare);
+        }
+
+        /// <summary>
+        /// To the network share.
+        /// </summary>
+        /// <param name="share">The share.</param>
+        /// <returns>NetworkShare.</returns>
+        private NetworkShare ToNetworkShare(Share share)
+        {
+            return new NetworkShare
+            {
+                Name = share.NetName,
+                Path = share.Path,
+                Remark = share.Remark,
+                Server = share.Server,
+                ShareType = ToNetworkShareType(share.ShareType)
+            };
+        }
+
+        /// <summary>
+        /// To the type of the network share.
+        /// </summary>
+        /// <param name="shareType">Type of the share.</param>
+        /// <returns>NetworkShareType.</returns>
+        /// <exception cref="System.ArgumentException">Unknown share type</exception>
+        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");
+        }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
+        /// PC's in the Domain</returns>
+        public IEnumerable<string> 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);
+            }
+        }
+    }
+
+}

+ 1 - 1
MediaBrowser.Common.Implementations/NetworkManagement/NetworkShares.cs → 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
 {
     /// <summary>
     /// Type of share