@@ -27,21 +27,26 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
if (global) | 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 | else | ||||
{ | { | ||||
string pacUrl; | string pacUrl; | ||||
if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) | if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) | ||||
{ | |||||
pacUrl = config.pacUrl; | pacUrl = config.pacUrl; | ||||
} | |||||
else | else | ||||
pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{pacSrv.PacSecret}"; | |||||
WinINet.SetIEProxy(true, false, "", pacUrl); | |||||
{ | |||||
pacUrl = | |||||
$"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{pacSrv.PacSecret}"; | |||||
} | |||||
Sysproxy.SetIEProxy(true, false, "", pacUrl); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
WinINet.SetIEProxy(false, false, "", ""); | |||||
Sysproxy.SetIEProxy(false, false, "", ""); | |||||
} | } | ||||
} | } | ||||
catch (ProxyException ex) | catch (ProxyException ex) | ||||
@@ -181,6 +181,26 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | |||||
internal static byte[] sysproxy_exe { | |||||
get { | |||||
object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); | |||||
return ((byte[])(obj)); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 查找 System.Byte[] 类型的本地化资源。 | |||||
/// </summary> | |||||
internal static byte[] sysproxy64_exe { | |||||
get { | |||||
object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); | |||||
return ((byte[])(obj)); | |||||
} | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// 查找类似 ! Put user rules line by line in this file. | /// 查找类似 ! Put user rules line by line in this file. | ||||
///! See https://adblockplus.org/en/filter-cheatsheet | ///! See https://adblockplus.org/en/filter-cheatsheet | ||||
@@ -148,6 +148,12 @@ | |||||
<data name="ssw128" type="System.Resources.ResXFileRef, System.Windows.Forms"> | <data name="ssw128" type="System.Resources.ResXFileRef, System.Windows.Forms"> | ||||
<value>..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | <value>..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | ||||
</data> | </data> | ||||
<data name="sysproxy64_exe" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||||
<value>..\Data\sysproxy64.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</data> | |||||
<data name="sysproxy_exe" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||||
<value>..\Data\sysproxy.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</data> | |||||
<data name="user_rule" type="System.Resources.ResXFileRef, System.Windows.Forms"> | <data name="user_rule" type="System.Resources.ResXFileRef, System.Windows.Forms"> | ||||
<value>..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> | <value>..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> | ||||
</data> | </data> | ||||
@@ -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 | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// Constants used in INTERNET_PER_CONN_OPTION_OptionUnion struct. | |||||
/// </summary> | |||||
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 | |||||
} | |||||
/// <summary> | |||||
/// Constants used in INTERNET_PER_CONN_OPTON struct. | |||||
/// </summary> | |||||
[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 | |||||
} | |||||
/// <summary> | |||||
/// 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 | |||||
/// </summary> | |||||
[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 | |||||
} | |||||
/// <summary> | |||||
/// 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. | |||||
/// </summary> | |||||
[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; | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// Sets an Internet option. | |||||
/// </summary> | |||||
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] | |||||
internal static extern bool InternetSetOption( | |||||
IntPtr hInternet, | |||||
INTERNET_OPTION dwOption, | |||||
IntPtr lpBuffer, | |||||
int lpdwBufferLength); | |||||
} | |||||
} |
@@ -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 | |||||
); | |||||
/// <summary> | |||||
/// Get all entries from RAS | |||||
/// </summary> | |||||
/// <param name="allConns"></param> | |||||
/// <returns> | |||||
/// 0: success with entries | |||||
/// 1: success but no entries found | |||||
/// 2: failed | |||||
/// </returns> | |||||
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; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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} <local>localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*"; | |||||
} | |||||
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); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// Set IE settings. | |||||
/// </summary> | |||||
private static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL, string connName) | |||||
{ | |||||
List<INTERNET_PER_CONN_OPTION> _optionlist = new List<INTERNET_PER_CONN_OPTION>(); | |||||
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("<local>") } | |||||
}); | |||||
} | |||||
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); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -197,13 +197,8 @@ | |||||
<Compile Include="Util\Sockets\SocketUtil.cs" /> | <Compile Include="Util\Sockets\SocketUtil.cs" /> | ||||
<Compile Include="Util\Sockets\Socks5Util.cs" /> | <Compile Include="Util\Sockets\Socks5Util.cs" /> | ||||
<Compile Include="Util\Sockets\WrappedSocket.cs" /> | <Compile Include="Util\Sockets\WrappedSocket.cs" /> | ||||
<Compile Include="Util\SystemProxy\INTERNET_OPTION.cs" /> | |||||
<Compile Include="Util\SystemProxy\INTERNET_PER_CONN_OPTION.cs" /> | |||||
<Compile Include="Util\SystemProxy\INTERNET_PER_CONN_OPTION_LIST.cs" /> | |||||
<Compile Include="Util\SystemProxy\NativeMethods.cs" /> | |||||
<Compile Include="Util\SystemProxy\ProxyException.cs" /> | <Compile Include="Util\SystemProxy\ProxyException.cs" /> | ||||
<Compile Include="Util\SystemProxy\RAS.cs" /> | |||||
<Compile Include="Util\SystemProxy\WinINet.cs" /> | |||||
<Compile Include="Util\SystemProxy\Sysproxy.cs" /> | |||||
<Compile Include="Util\Util.cs" /> | <Compile Include="Util\Util.cs" /> | ||||
<Compile Include="Util\ViewUtils.cs" /> | <Compile Include="Util\ViewUtils.cs" /> | ||||
<Compile Include="View\ConfigForm.cs"> | <Compile Include="View\ConfigForm.cs"> | ||||
@@ -292,6 +287,8 @@ | |||||
<None Include="Data\proxy.pac.txt.gz" /> | <None Include="Data\proxy.pac.txt.gz" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="Data\sysproxy.exe.gz" /> | |||||
<None Include="Data\sysproxy64.exe.gz" /> | |||||
<None Include="packages.config" /> | <None Include="packages.config" /> | ||||
<None Include="Properties\DataSources\Shadowsocks.Model.StatisticsStrategyConfiguration.datasource" /> | <None Include="Properties\DataSources\Shadowsocks.Model.StatisticsStrategyConfiguration.datasource" /> | ||||
<None Include="Properties\Settings.settings"> | <None Include="Properties\Settings.settings"> | ||||
@@ -356,25 +353,25 @@ | |||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" /> | <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" /> | ||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" /> | <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" /> | ||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" /> | <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" /> | ||||
<Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[ | |||||
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault(); | |||||
if (config == null) return true; | |||||
var excludedAssemblies = new List<string>(); | |||||
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); | |||||
<Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[ | |||||
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault(); | |||||
if (config == null) return true; | |||||
var excludedAssemblies = new List<string>(); | |||||
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); | |||||
]]></Code> | ]]></Code> | ||||
</Task> | </Task> | ||||
</UsingTask> | </UsingTask> | ||||
@@ -388,11 +385,11 @@ foreach (var item in filesToCleanup) | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<Error Condition="!Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\dotnet\Fody.targets'))" /> | <Error Condition="!Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\dotnet\Fody.targets'))" /> | ||||
</Target> | </Target> | ||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
Other similar extension points exist, see Microsoft.Common.targets. | |||||
<Target Name="BeforeBuild"> | |||||
</Target> | |||||
<Target Name="AfterBuild"> | |||||
</Target> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
Other similar extension points exist, see Microsoft.Common.targets. | |||||
<Target Name="BeforeBuild"> | |||||
</Target> | |||||
<Target Name="AfterBuild"> | |||||
</Target> | |||||
--> | --> | ||||
</Project> | </Project> |