diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index 92da7784..ac342441 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -27,7 +27,7 @@ namespace Shadowsocks.Controller { if (global) { - WinINet.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), ""); + Sysproxy.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), ""); } else { @@ -36,12 +36,12 @@ namespace Shadowsocks.Controller pacUrl = config.pacUrl; else pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{pacSrv.PacSecret}"; - WinINet.SetIEProxy(true, false, "", pacUrl); + Sysproxy.SetIEProxy(true, false, "", pacUrl); } } else { - WinINet.SetIEProxy(false, false, "", ""); + Sysproxy.SetIEProxy(false, false, "", ""); } } catch (ProxyException ex) diff --git a/shadowsocks-csharp/Data/sysproxy.exe.gz b/shadowsocks-csharp/Data/sysproxy.exe.gz new file mode 100644 index 00000000..6f079603 Binary files /dev/null and b/shadowsocks-csharp/Data/sysproxy.exe.gz differ diff --git a/shadowsocks-csharp/Data/sysproxy64.exe.gz b/shadowsocks-csharp/Data/sysproxy64.exe.gz new file mode 100644 index 00000000..6a2041c1 Binary files /dev/null and b/shadowsocks-csharp/Data/sysproxy64.exe.gz differ diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 79c09912..cb88c84d 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -215,6 +215,26 @@ namespace Shadowsocks.Properties { } } + /// + /// 查找 System.Byte[] 类型的本地化资源。 + /// + internal static byte[] sysproxy_exe { + get { + object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// 查找 System.Byte[] 类型的本地化资源。 + /// + internal static byte[] sysproxy64_exe { + get { + object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// 查找类似 ! Put user rules line by line in this file. ///! See https://adblockplus.org/en/filter-cheatsheet @@ -227,29 +247,29 @@ namespace Shadowsocks.Properties { } /// - /// 查找类似 # translation for Traditional Chinese - /// - ///Shadowsocks=Shadowsocks - /// - ///# Menu items - /// - ///Enable System Proxy=啟用系統代理 - ///Mode=系統代理模式 - ///PAC=PAC 模式 - ///Global=全局模式 - ///Servers=伺服器 - ///Edit Servers...=編輯伺服器... - ///Statistics Config...=統計配置... - ///Start on Boot=開機啟動 - ///Forward Proxy...=正向代理設置... - ///Allow Clients from LAN=允許來自區域網路的連接 - ///Local PAC=使用本地 PAC - ///Online PAC=使用在線 PAC - ///Edit Local PAC File...=編輯本地 PAC 文件... - ///Update Local PAC from GFWList=從 GFWList 更新本地 PAC - ///Edit User Rule for GFWList...=編輯 GFWList 的用戶規則... - ///Show QRCode...=顯示 QR 碼... - ///Scan QRCode from Screen [字符串的其余部分被截断]"; 的本地化字符串。 + /// 查找类似 # translation for Traditional Chinese + /// + ///Shadowsocks=Shadowsocks + /// + ///# Menu items + /// + ///Enable System Proxy=啟用系統代理 + ///Mode=系統代理模式 + ///PAC=PAC 模式 + ///Global=全局模式 + ///Servers=伺服器 + ///Edit Servers...=編輯伺服器... + ///Statistics Config...=統計配置... + ///Start on Boot=開機啟動 + ///Forward Proxy...=正向代理設置... + ///Allow Clients from LAN=允許來自區域網路的連接 + ///Local PAC=使用本地 PAC + ///Online PAC=使用在線 PAC + ///Edit Local PAC File...=編輯本地 PAC 文件... + ///Update Local PAC from GFWList=從 GFWList 更新本地 PAC + ///Edit User Rule for GFWList...=編輯 GFWList 的用戶規則... + ///Show QRCode...=顯示 QR 碼... + ///S [字符串的其余部分被截断]"; 的本地化字符串。 /// internal static string zh_tw { get { diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index 5e4ca247..eaa37bd3 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -157,6 +157,12 @@ ..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Data\sysproxy64.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Data\sysproxy.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 diff --git a/shadowsocks-csharp/Util/SystemProxy/INTERNET_OPTION.cs b/shadowsocks-csharp/Util/SystemProxy/INTERNET_OPTION.cs deleted file mode 100644 index 169d7ebf..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/INTERNET_OPTION.cs +++ /dev/null @@ -1,42 +0,0 @@ -/****************************** Module Header ******************************\ - Module Name: INTERNET_OPTION.cs - Project: CSWebBrowserWithProxy - Copyright (c) Microsoft Corporation. - - This enum contains 4 WinINet constants used in method InternetQueryOption and - InternetSetOption functions. - Visit http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx to get the - whole constants list. - - This source is subject to the Microsoft Public License. - See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. - All other rights reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -namespace Shadowsocks.Util.SystemProxy -{ - public enum INTERNET_OPTION - { - // Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies - // a list of options for a particular connection. - INTERNET_OPTION_PER_CONNECTION_OPTION = 75, - - // Notify the system that the registry settings have been changed so that - // it verifies the settings on the next call to InternetConnect. - INTERNET_OPTION_SETTINGS_CHANGED = 39, - - // Causes the proxy data to be reread from the registry for a handle. - INTERNET_OPTION_REFRESH = 37, - - // Alerts the current WinInet instance that proxy settings have changed - // and that they must update with the new settings. - // To alert all available WinInet instances, set the Buffer parameter of - // InternetSetOption to NULL and BufferLength to 0 when passing this option. - INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95 - - } -} diff --git a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs deleted file mode 100644 index 7a2dbe15..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs +++ /dev/null @@ -1,115 +0,0 @@ -/****************************** Module Header ******************************\ - Module Name: INTERNET_PER_CONN_OPTION.cs - Project: CSWebBrowserWithProxy - Copyright (c) Microsoft Corporation. - - This file defines the struct INTERNET_PER_CONN_OPTION and constants used by it. - The struct INTERNET_PER_CONN_OPTION contains the value of an option that to be - set to internet settings. - Visit http://msdn.microsoft.com/en-us/library/aa385145(VS.85).aspx to get the - detailed description. - - This source is subject to the Microsoft Public License. - See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. - All other rights reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -using System; -using System.Runtime.InteropServices; - -namespace Shadowsocks.Util.SystemProxy -{ - /// - /// Constants used in INTERNET_PER_CONN_OPTION_OptionUnion struct. - /// - public enum INTERNET_PER_CONN_OptionEnum - { - INTERNET_PER_CONN_FLAGS = 1, - INTERNET_PER_CONN_PROXY_SERVER = 2, - INTERNET_PER_CONN_PROXY_BYPASS = 3, - INTERNET_PER_CONN_AUTOCONFIG_URL = 4, - INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5, - INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6, - INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7, - INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8, - INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9, - INTERNET_PER_CONN_FLAGS_UI = 10 - } - - /// - /// Constants used in INTERNET_PER_CONN_OPTON struct. - /// - [Flags] - public enum INTERNET_OPTION_PER_CONN_FLAGS - { - PROXY_TYPE_DIRECT = 0x00000001, // direct to net - PROXY_TYPE_PROXY = 0x00000002, // via named proxy - PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL - PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection - } - - /// - /// Constants used in INTERNET_PER_CONN_OPTON struct. - /// Windows 7 and later: - /// Clients that support Internet Explorer 8 should query the connection type using INTERNET_PER_CONN_FLAGS_UI. - /// If this query fails, then the system is running a previous version of Internet Explorer and the client should - /// query again with INTERNET_PER_CONN_FLAGS. - /// Restore the connection type using INTERNET_PER_CONN_FLAGS regardless of the version of Internet Explorer. - /// XXX: If fails, notify user to upgrade Internet Explorer - /// - [Flags] - public enum INTERNET_OPTION_PER_CONN_FLAGS_UI - { - PROXY_TYPE_DIRECT = 0x00000001, // direct to net - PROXY_TYPE_PROXY = 0x00000002, // via named proxy - PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL - PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection - } - - /// - /// Used in INTERNET_PER_CONN_OPTION. - /// When create a instance of OptionUnion, only one filed will be used. - /// The StructLayout and FieldOffset attributes could help to decrease the struct size. - /// - [StructLayout(LayoutKind.Explicit)] - public struct INTERNET_PER_CONN_OPTION_OptionUnion : IDisposable - { - // A value in INTERNET_OPTION_PER_CONN_FLAGS. - [FieldOffset(0)] - public int dwValue; - [FieldOffset(0)] - public System.IntPtr pszValue; - [FieldOffset(0)] - public System.Runtime.InteropServices.ComTypes.FILETIME ftValue; - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposing) - { - if (pszValue != IntPtr.Zero) - { - Marshal.FreeHGlobal(pszValue); - pszValue = IntPtr.Zero; - } - } - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct INTERNET_PER_CONN_OPTION - { - // A value in INTERNET_PER_CONN_OptionEnum. - public int dwOption; - public INTERNET_PER_CONN_OPTION_OptionUnion Value; - } -} diff --git a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs deleted file mode 100644 index 8541e0b7..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs +++ /dev/null @@ -1,63 +0,0 @@ -/****************************** Module Header ******************************\ - Module Name: INTERNET_PER_CONN_OPTION_LIST.cs - Project: CSWebBrowserWithProxy - Copyright (c) Microsoft Corporation. - - The struct INTERNET_PER_CONN_OPTION contains a list of options that to be - set to internet connection. - Visit http://msdn.microsoft.com/en-us/library/aa385146(VS.85).aspx to get the - detailed description. - - This source is subject to the Microsoft Public License. - See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. - All other rights reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -using System; -using System.Runtime.InteropServices; - -namespace Shadowsocks.Util.SystemProxy -{ - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable - { - public int Size; - - // The connection to be set. NULL means LAN. - public System.IntPtr Connection; - - public int OptionCount; - public int OptionError; - - // List of INTERNET_PER_CONN_OPTIONs. - public System.IntPtr pOptions; - - public void Dispose() - { - Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - if ( disposing ) - { - if ( Connection != IntPtr.Zero ) - { - Marshal.FreeHGlobal( Connection ); - Connection = IntPtr.Zero; - } - - if ( pOptions != IntPtr.Zero ) - { - Marshal.FreeHGlobal( pOptions ); - pOptions = IntPtr.Zero; - } - } - } - } -} diff --git a/shadowsocks-csharp/Util/SystemProxy/NativeMethods.cs b/shadowsocks-csharp/Util/SystemProxy/NativeMethods.cs deleted file mode 100644 index e5dd0578..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/NativeMethods.cs +++ /dev/null @@ -1,36 +0,0 @@ -/****************************** Module Header ******************************\ - Module Name: NativeMethods.cs - Project: CSWebBrowserWithProxy - Copyright (c) Microsoft Corporation. - - This class is a simple .NET wrapper of wininet.dll. It contains 4 extern - methods in wininet.dll. They are InternetOpen, InternetCloseHandle, - InternetSetOption and InternetQueryOption. - - This source is subject to the Microsoft Public License. - See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. - All other rights reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -using System; -using System.Runtime.InteropServices; - -namespace Shadowsocks.Util.SystemProxy -{ - internal static class NativeMethods - { - /// - /// Sets an Internet option. - /// - [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] - internal static extern bool InternetSetOption( - IntPtr hInternet, - INTERNET_OPTION dwOption, - IntPtr lpBuffer, - int lpdwBufferLength); - } -} diff --git a/shadowsocks-csharp/Util/SystemProxy/RAS.cs b/shadowsocks-csharp/Util/SystemProxy/RAS.cs deleted file mode 100644 index 19f6c78b..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/RAS.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Shadowsocks.Util.SystemProxy -{ - internal static class RemoteAccessService - { - private enum RasFieldSizeConstants - { - #region original header - - //#if (WINVER >= 0x400) - //#define RAS_MaxEntryName 256 - //#define RAS_MaxDeviceName 128 - //#define RAS_MaxCallbackNumber RAS_MaxPhoneNumber - //#else - //#define RAS_MaxEntryName 20 - //#define RAS_MaxDeviceName 32 - //#define RAS_MaxCallbackNumber 48 - //#endif - - #endregion - - RAS_MaxEntryName = 256, - RAS_MaxPath = 260 - } - - private const int ERROR_SUCCESS = 0; - private const int RASBASE = 600; - private const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - private struct RasEntryName - { - #region original header - - //#define RASENTRYNAMEW struct tagRASENTRYNAMEW - //RASENTRYNAMEW - //{ - // DWORD dwSize; - // WCHAR szEntryName[RAS_MaxEntryName + 1]; - // - //#if (WINVER >= 0x500) - // // - // // If this flag is REN_AllUsers then its a - // // system phonebook. - // // - // DWORD dwFlags; - // WCHAR szPhonebookPath[MAX_PATH + 1]; - //#endif - //}; - // - //#define RASENTRYNAMEA struct tagRASENTRYNAMEA - //RASENTRYNAMEA - //{ - // DWORD dwSize; - // CHAR szEntryName[RAS_MaxEntryName + 1]; - // - //#if (WINVER >= 0x500) - // DWORD dwFlags; - // CHAR szPhonebookPath[MAX_PATH + 1]; - //#endif - //}; - - #endregion - - public int dwSize; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName + 1)] - public string szEntryName; - - public int dwFlags; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxPath + 1)] - public string szPhonebookPath; - } - - [DllImport("rasapi32.dll", CharSet = CharSet.Auto)] - private static extern uint RasEnumEntries( - // reserved, must be NULL - string reserved, - // pointer to full path and file name of phone-book file - string lpszPhonebook, - // buffer to receive phone-book entries - [In, Out] RasEntryName[] lprasentryname, - // size in bytes of buffer - ref int lpcb, - // number of entries written to buffer - out int lpcEntries - ); - - /// - /// Get all entries from RAS - /// - /// - /// - /// 0: success with entries - /// 1: success but no entries found - /// 2: failed - /// - public static uint GetAllConns(ref string[] allConns) - { - int lpNames = 0; - int entryNameSize = 0; - int lpSize = 0; - uint retval = ERROR_SUCCESS; - RasEntryName[] names = null; - - entryNameSize = Marshal.SizeOf(typeof(RasEntryName)); - - // Windows Vista or later: To determine the required buffer size, call RasEnumEntries - // with lprasentryname set to NULL. The variable pointed to by lpcb should be set to zero. - // The function will return the required buffer size in lpcb and an error code of ERROR_BUFFER_TOO_SMALL. - retval = RasEnumEntries(null, null, null, ref lpSize, out lpNames); - - if (retval == ERROR_BUFFER_TOO_SMALL) - { - names = new RasEntryName[lpNames]; - for (int i = 0; i < names.Length; i++) - { - names[i].dwSize = entryNameSize; - } - - retval = RasEnumEntries(null, null, names, ref lpSize, out lpNames); - } - - if (retval == ERROR_SUCCESS) - { - if (lpNames == 0) - { - // no entries found. - return 1; - } - - allConns = new string[names.Length]; - - for (int i = 0; i < names.Length; i++) - { - allConns[i] = names[i].szEntryName; - } - return 0; - } - else - { - return 2; - } - } - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs new file mode 100644 index 00000000..f0353f46 --- /dev/null +++ b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Shadowsocks.Controller; +using Shadowsocks.Properties; + +namespace Shadowsocks.Util.SystemProxy +{ + public static class Sysproxy + { + + enum RET_ERRORS : int + { + RET_NO_ERROR = 0, + INVALID_FORMAT = 1, + NO_PERMISSION = 2, + SYSCALL_FAILED = 3, + NO_MEMORY = 4, + INVAILD_OPTION_COUNT = 5, + }; + + static Sysproxy() + { + try + { + FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"), + Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe); + } + catch (IOException e) + { + Logging.LogUsefulException(e); + } + } + + public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL) + { + string arguments; + + if (enable) + { + if (global) + { + arguments = "global " + proxyServer; + } + else + { + arguments = "pac " + pacURL; + } + } + else + { + arguments = "off"; + } + + using (var process = new Process()) + { + // Configure the process using the StartInfo properties. + process.StartInfo.FileName = Utils.GetTempPath("sysproxy.exe"); + process.StartInfo.Arguments = arguments; + process.StartInfo.WorkingDirectory = Utils.GetTempPath(); + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.CreateNoWindow = true; + process.Start(); + + var error = process.StandardError.ReadToEnd(); + + process.WaitForExit(); + + var exitCode = process.ExitCode; + if (exitCode != (int) RET_ERRORS.RET_NO_ERROR) + { + throw new ProxyException(error); + } + } + } + } +} diff --git a/shadowsocks-csharp/Util/SystemProxy/WinINet.cs b/shadowsocks-csharp/Util/SystemProxy/WinINet.cs deleted file mode 100644 index 184f47e7..00000000 --- a/shadowsocks-csharp/Util/SystemProxy/WinINet.cs +++ /dev/null @@ -1,183 +0,0 @@ -/****************************** Module Header ******************************\ - Module Name: WinINet.cs - Project: CSWebBrowserWithProxy - Copyright (c) Microsoft Corporation. - - This class is used to set the proxy. or restore to the system proxy for the - current application - - This source is subject to the Microsoft Public License. - See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. - All other rights reserved. - - THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Runtime.InteropServices; -using Shadowsocks.Controller; - -namespace Shadowsocks.Util.SystemProxy -{ - public static class WinINet - { - /// - /// Set IE settings. - /// - private static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL, string connName) - { - List _optionlist = new List(); - - if (enable) - { - if (global) - { - // global proxy - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI, - Value = { dwValue = (int)(INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_PROXY - | INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_DIRECT) } - }); - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER, - Value = { pszValue = Marshal.StringToHGlobalAuto(proxyServer) } - }); - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS, - Value = { pszValue = Marshal.StringToHGlobalAuto("") } - }); - } - else - { - // pac - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI, - Value = { dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_AUTO_PROXY_URL } - }); - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_AUTOCONFIG_URL, - Value = { pszValue = Marshal.StringToHGlobalAuto(pacURL) } - }); - } - } - else - { - // direct - _optionlist.Add(new INTERNET_PER_CONN_OPTION - { - dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI, - Value = { dwValue = (int)(INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_AUTO_DETECT - | INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_DIRECT) } - }); - } - - // Get total length of INTERNET_PER_CONN_OPTIONs - var len = _optionlist.Sum(each => Marshal.SizeOf(each)); - - // Allocate a block of memory of the options. - IntPtr buffer = Marshal.AllocCoTaskMem(len); - - IntPtr current = buffer; - - // Marshal data from a managed object to an unmanaged block of memory. - foreach (INTERNET_PER_CONN_OPTION eachOption in _optionlist) - { - Marshal.StructureToPtr(eachOption, current, false); - current = (IntPtr)((int)current + Marshal.SizeOf(eachOption)); - } - - // Initialize a INTERNET_PER_CONN_OPTION_LIST instance. - INTERNET_PER_CONN_OPTION_LIST optionList = new INTERNET_PER_CONN_OPTION_LIST(); - - // Point to the allocated memory. - optionList.pOptions = buffer; - - // Return the unmanaged size of an object in bytes. - optionList.Size = Marshal.SizeOf(optionList); - - optionList.Connection = connName.IsNullOrEmpty() - ? IntPtr.Zero // NULL means LAN - : Marshal.StringToHGlobalAuto(connName); // TODO: not working if contains Chinese - - optionList.OptionCount = _optionlist.Count; - optionList.OptionError = 0; - int optionListSize = Marshal.SizeOf(optionList); - - // Allocate memory for the INTERNET_PER_CONN_OPTION_LIST instance. - IntPtr intptrStruct = Marshal.AllocCoTaskMem(optionListSize); - - // Marshal data from a managed object to an unmanaged block of memory. - Marshal.StructureToPtr(optionList, intptrStruct, true); - - // Set internet settings. - bool bReturn = NativeMethods.InternetSetOption( - IntPtr.Zero, - INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, - intptrStruct, optionListSize); - - // Free the allocated memory. - Marshal.FreeCoTaskMem(buffer); - Marshal.FreeCoTaskMem(intptrStruct); - - // Throw an exception if this operation failed. - if (!bReturn) - { - throw new ProxyException("InternetSetOption failed.", new Win32Exception()); - } - - // Notify the system that the registry settings have been changed and cause - // the proxy data to be reread from the registry for a handle. - bReturn = NativeMethods.InternetSetOption( - IntPtr.Zero, - INTERNET_OPTION.INTERNET_OPTION_PROXY_SETTINGS_CHANGED, - IntPtr.Zero, 0); - if (!bReturn) - { - Logging.Error("InternetSetOption:INTERNET_OPTION_PROXY_SETTINGS_CHANGED"); - } - - bReturn = NativeMethods.InternetSetOption( - IntPtr.Zero, - INTERNET_OPTION.INTERNET_OPTION_REFRESH, - IntPtr.Zero, 0); - if (!bReturn) - { - Logging.Error("InternetSetOption:INTERNET_OPTION_REFRESH"); - } - } - - public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL) - { - string[] allConnections = null; - var ret = RemoteAccessService.GetAllConns(ref allConnections); - - if (ret == 2) - throw new ProxyException("Cannot get all connections"); - - if (ret == 1) - { - // no entries, only set LAN - SetIEProxy(enable, global, proxyServer, pacURL, null); - } - else if (ret == 0) - { - // found entries, set LAN and each connection - SetIEProxy(enable, global, proxyServer, pacURL, null); - foreach (string connName in allConnections) - { - SetIEProxy(enable, global, proxyServer, pacURL, connName); - } - } - } - } -} diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 8379fe5f..c0156c67 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -195,13 +195,8 @@ - - - - - - + @@ -294,6 +289,8 @@ + + @@ -359,25 +356,25 @@ - (); -var attribute = config.Attribute("ExcludeAssemblies"); -if (attribute != null) - foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty)) - excludedAssemblies.Add(item); -var element = config.Element("ExcludeAssemblies"); -if (element != null) - foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty)) - excludedAssemblies.Add(item); - -var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase)); - -foreach (var item in filesToCleanup) - File.Delete(item); + (); +var attribute = config.Attribute("ExcludeAssemblies"); +if (attribute != null) + foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty)) + excludedAssemblies.Add(item); +var element = config.Element("ExcludeAssemblies"); +if (element != null) + foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty)) + excludedAssemblies.Add(item); + +var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase)); + +foreach (var item in filesToCleanup) + File.Delete(item); ]]> @@ -391,11 +388,11 @@ foreach (var item in filesToCleanup) - \ No newline at end of file