NetworkManager.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using MediaBrowser.Common.Implementations.Networking;
  2. using MediaBrowser.Common.Net;
  3. using MediaBrowser.Model.IO;
  4. using MediaBrowser.Model.Net;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Net;
  11. using System.Runtime.InteropServices;
  12. namespace MediaBrowser.ServerApplication.Networking
  13. {
  14. /// <summary>
  15. /// Class NetUtils
  16. /// </summary>
  17. public class NetworkManager : BaseNetworkManager, INetworkManager
  18. {
  19. /// <summary>
  20. /// Gets the network shares.
  21. /// </summary>
  22. /// <param name="path">The path.</param>
  23. /// <returns>IEnumerable{NetworkShare}.</returns>
  24. public IEnumerable<NetworkShare> GetNetworkShares(string path)
  25. {
  26. return new ShareCollection(path).OfType<Share>().Select(ToNetworkShare);
  27. }
  28. /// <summary>
  29. /// To the network share.
  30. /// </summary>
  31. /// <param name="share">The share.</param>
  32. /// <returns>NetworkShare.</returns>
  33. private NetworkShare ToNetworkShare(Share share)
  34. {
  35. return new NetworkShare
  36. {
  37. Name = share.NetName,
  38. Path = share.Path,
  39. Remark = share.Remark,
  40. Server = share.Server,
  41. ShareType = ToNetworkShareType(share.ShareType)
  42. };
  43. }
  44. public bool IsInLocalNetwork(string endpoint)
  45. {
  46. if (string.IsNullOrWhiteSpace(endpoint))
  47. {
  48. throw new ArgumentNullException("endpoint");
  49. }
  50. IPAddress address;
  51. if (!IPAddress.TryParse(endpoint, out address))
  52. {
  53. return true;
  54. }
  55. const int lengthMatch = 4;
  56. if (endpoint.Length >= lengthMatch)
  57. {
  58. var prefix = endpoint.Substring(0, lengthMatch);
  59. if (GetLocalIpAddresses()
  60. .Any(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
  61. {
  62. return true;
  63. }
  64. }
  65. // Private address space:
  66. // http://en.wikipedia.org/wiki/Private_network
  67. return
  68. // If url was requested with computer name, we may see this
  69. endpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 ||
  70. endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) ||
  71. endpoint.StartsWith("192.", StringComparison.OrdinalIgnoreCase) ||
  72. endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase) ||
  73. endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
  74. }
  75. /// <summary>
  76. /// To the type of the network share.
  77. /// </summary>
  78. /// <param name="shareType">Type of the share.</param>
  79. /// <returns>NetworkShareType.</returns>
  80. /// <exception cref="System.ArgumentException">Unknown share type</exception>
  81. private NetworkShareType ToNetworkShareType(ShareType shareType)
  82. {
  83. if (shareType.HasFlag(ShareType.Special))
  84. {
  85. return NetworkShareType.Special;
  86. }
  87. if (shareType.HasFlag(ShareType.Device))
  88. {
  89. return NetworkShareType.Device;
  90. }
  91. if (shareType.HasFlag(ShareType.Disk))
  92. {
  93. return NetworkShareType.Disk;
  94. }
  95. if (shareType.HasFlag(ShareType.IPC))
  96. {
  97. return NetworkShareType.Ipc;
  98. }
  99. if (shareType.HasFlag(ShareType.Printer))
  100. {
  101. return NetworkShareType.Printer;
  102. }
  103. throw new ArgumentException("Unknown share type");
  104. }
  105. /// <summary>
  106. /// Uses the DllImport : NetServerEnum with all its required parameters
  107. /// (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
  108. /// for full details or method signature) to retrieve a list of domain SV_TYPE_WORKSTATION
  109. /// and SV_TYPE_SERVER PC's
  110. /// </summary>
  111. /// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
  112. /// PC's in the Domain</returns>
  113. private IEnumerable<string> GetNetworkDevicesInternal()
  114. {
  115. //local fields
  116. const int MAX_PREFERRED_LENGTH = -1;
  117. var SV_TYPE_WORKSTATION = 1;
  118. var SV_TYPE_SERVER = 2;
  119. var buffer = IntPtr.Zero;
  120. var tmpBuffer = IntPtr.Zero;
  121. var entriesRead = 0;
  122. var totalEntries = 0;
  123. var resHandle = 0;
  124. var sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100));
  125. try
  126. {
  127. //call the DllImport : NetServerEnum with all its required parameters
  128. //see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
  129. //for full details of method signature
  130. var ret = NativeMethods.NetServerEnum(null, 100, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle);
  131. //if the returned with a NERR_Success (C++ term), =0 for C#
  132. if (ret == 0)
  133. {
  134. //loop through all SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's
  135. for (var i = 0; i < totalEntries; i++)
  136. {
  137. //get pointer to, Pointer to the buffer that received the data from
  138. //the call to NetServerEnum. Must ensure to use correct size of
  139. //STRUCTURE to ensure correct location in memory is pointed to
  140. tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO));
  141. //Have now got a pointer to the list of SV_TYPE_WORKSTATION and
  142. //SV_TYPE_SERVER PC's, which is unmanaged memory
  143. //Needs to Marshal data from an unmanaged block of memory to a
  144. //managed object, again using STRUCTURE to ensure the correct data
  145. //is marshalled
  146. var svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure(tmpBuffer, typeof(_SERVER_INFO_100));
  147. //add the PC names to the ArrayList
  148. if (!string.IsNullOrEmpty(svrInfo.sv100_name))
  149. {
  150. yield return svrInfo.sv100_name;
  151. }
  152. }
  153. }
  154. }
  155. finally
  156. {
  157. //The NetApiBufferFree function frees
  158. //the memory that the NetApiBufferAllocate function allocates
  159. NativeMethods.NetApiBufferFree(buffer);
  160. }
  161. }
  162. /// <summary>
  163. /// Gets available devices within the domain
  164. /// </summary>
  165. /// <returns>PC's in the Domain</returns>
  166. public IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
  167. {
  168. return GetNetworkDevicesInternal().Select(c => new FileSystemEntryInfo
  169. {
  170. Name = c,
  171. Path = NetworkPrefix + c,
  172. Type = FileSystemEntryType.NetworkComputer
  173. });
  174. }
  175. /// <summary>
  176. /// Gets the network prefix.
  177. /// </summary>
  178. /// <value>The network prefix.</value>
  179. private string NetworkPrefix
  180. {
  181. get
  182. {
  183. var separator = Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture);
  184. return separator + separator;
  185. }
  186. }
  187. }
  188. }