This fix the proxy issue on win10 insider preview.tags/3.4.0
@@ -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) | |||
@@ -215,6 +215,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> | |||
/// 查找类似 ! Put user rules line by line in this file. | |||
///! See https://adblockplus.org/en/filter-cheatsheet | |||
@@ -227,29 +247,29 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// 查找类似 # 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 [字符串的其余部分被截断]"; 的本地化字符串。 | |||
/// </summary> | |||
internal static string zh_tw { | |||
get { | |||
@@ -157,6 +157,12 @@ | |||
<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> | |||
</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"> | |||
<value>..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> | |||
</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; | |||
} | |||
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); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -195,13 +195,8 @@ | |||
<Compile Include="Util\Sockets\LineReader.cs" /> | |||
<Compile Include="Util\Sockets\SocketUtil.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\RAS.cs" /> | |||
<Compile Include="Util\SystemProxy\WinINet.cs" /> | |||
<Compile Include="Util\SystemProxy\Sysproxy.cs" /> | |||
<Compile Include="Util\Util.cs" /> | |||
<Compile Include="Util\ViewUtils.cs" /> | |||
<Compile Include="View\ConfigForm.cs"> | |||
@@ -294,6 +289,8 @@ | |||
<None Include="Data\proxy.pac.txt.gz" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="Data\sysproxy.exe.gz" /> | |||
<None Include="Data\sysproxy64.exe.gz" /> | |||
<None Include="packages.config" /> | |||
<None Include="Properties\DataSources\Shadowsocks.Model.StatisticsStrategyConfiguration.datasource" /> | |||
<None Include="Properties\Settings.settings"> | |||
@@ -359,25 +356,25 @@ | |||
<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.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> | |||
</Task> | |||
</UsingTask> | |||
@@ -391,11 +388,11 @@ foreach (var item in filesToCleanup) | |||
</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'))" /> | |||
</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> |