using System; using System.Linq; using System.Management; using Netch.Controllers; using Netch.Models.WinFW; using NETCONLib; namespace Netch.Utils { public static class ICSHelper { public static bool? Enabled { get { AutoSearchTapAdapter(); if (Global.TUNTAP.Adapter == null) return null; foreach (NetworkConnection connection in new NetworkConnectionCollection()) { try { if (connection.DeviceName == Global.TUNTAP.Adapter?.Description) { return connection.SharingEnabled; } } catch (Exception e) { Logging.Warning(e.ToString()); } } return null; } } private static void AutoSearchTapAdapter() { if (Global.TUNTAP.Adapter == null) TUNTAPController.SearchTapAdapter(); } public static bool Enable() { Utils.SearchOutboundAdapter(false); AutoSearchTapAdapter(); if (Global.TUNTAP.Adapter == null || Global.Outbound.Adapter == null) { return false; } try { CleanupWMISharingEntries(); #region Save Outbound IP Config bool dhcpEnabled; string[] ipAddress = null; string[] subnetMask = null; string[] gateway = null; ushort[] gatewayMetric = null; string[] dns = null; var outboundWmi = GetManagementObjectByDeviceNameOrDefault(Global.Outbound.Adapter.Description); if (outboundWmi == null) { return false; } if (!(dhcpEnabled = (bool) outboundWmi["DHCPEnabled"])) { ipAddress = (string[]) outboundWmi["IPAddress"]; subnetMask = (string[]) outboundWmi["IPSubnet"]; gateway = (string[]) outboundWmi["DefaultIPGateway"]; gatewayMetric = (ushort[]) outboundWmi["GatewayCostMetric"]; dns = (string[]) outboundWmi["DNSServerSearchOrder"]; ipAddress = new[] {ipAddress[0]}; subnetMask = new[] {subnetMask[0]}; } #endregion #region Setting ICS foreach (NetworkConnection connection in new NetworkConnectionCollection()) { if (connection.DeviceName == Global.TUNTAP.Adapter.Description) { if (connection.SharingEnabled) connection.DisableSharing(); connection.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PUBLIC); } else if (connection.DeviceName == Global.Outbound.Adapter.Description) { if (connection.SharingEnabled) connection.DisableSharing(); connection.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PRIVATE); } } #endregion #region Reset Outbound IP Config if (dhcpEnabled) { outboundWmi.InvokeMethod("EnableDHCP", null, null); } else { //Set static IP and subnet mask var ip = outboundWmi.GetMethodParameters("EnableStatic"); ip["IPAddress"] = ipAddress; ip["SubnetMask"] = subnetMask; outboundWmi.InvokeMethod("EnableStatic", ip, null); //Set default gateway var newGateway = outboundWmi.GetMethodParameters("SetGateways"); newGateway["DefaultIPGateway"] = gateway; newGateway["GatewayCostMetric"] = gatewayMetric; outboundWmi.InvokeMethod("SetGateways", newGateway, null); //Set dns servers var newDns = outboundWmi.GetMethodParameters("SetDNSServerSearchOrder"); newDns["DNSServerSearchOrder"] = dns; outboundWmi.InvokeMethod("SetDNSServerSearchOrder", newDns, null); } #endregion return true; } catch (Exception e) { try { Disable(); } catch { // ignored } Logging.Error($"网络连接共享设置失败: {e}"); return false; } } public static void Disable() { foreach (NetworkConnection connection in new NetworkConnectionCollection()) { try { if (connection.SharingEnabled) { connection.DisableSharing(); } } catch (Exception e) { Logging.Warning(e.ToString()); } } CleanupWMISharingEntries(); } private static void CleanupWMISharingEntries() { var scope = new ManagementScope("root\\Microsoft\\HomeNet"); scope.Connect(); var searchResults = new ManagementObjectSearcher(scope, new ObjectQuery("SELECT * FROM HNet_ConnectionProperties")); foreach (var o in searchResults.Get()) { var entry = (ManagementObject) o; if ((bool) entry["IsIcsPrivate"]) entry["IsIcsPrivate"] = false; if ((bool) entry["IsIcsPublic"]) entry["IsIcsPublic"] = false; entry.Put(new PutOptions { Type = PutType.UpdateOnly }); } } private static ManagementObject GetManagementObjectByDeviceNameOrDefault(string deviceName) { foreach (var o in new ManagementClass("Win32_NetworkAdapterConfiguration").GetInstances()) { var mo = (ManagementObject) o; if (((string) mo["Caption"]).EndsWith(deviceName)) { return mo; } } return null; } } }