Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89b7043a4e | ||
|
|
9c438ee745 | ||
|
|
ce26bc15a9 | ||
|
|
4b99a5c210 | ||
|
|
5721769c6d | ||
|
|
1c1cc62235 | ||
|
|
3fe8484b8b | ||
|
|
131114f0c2 | ||
|
|
74ad98d9ce | ||
|
|
90ae73057e |
@@ -1,3 +1,8 @@
|
|||||||
|
3.3.4 2016-10-21
|
||||||
|
- Fix IE dial-up and VPN connection proxy settings
|
||||||
|
not changed since release 3.3.3.
|
||||||
|
- Fix a UI bug
|
||||||
|
|
||||||
3.3.3 2016-10-10
|
3.3.3 2016-10-10
|
||||||
- Add timeout support for server and forward proxy,
|
- Add timeout support for server and forward proxy,
|
||||||
only integer is allowed
|
only integer is allowed
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ port in `Servers -> Edit Servers`
|
|||||||
|
|
||||||
1. You can change PAC rules by editing the PAC file. When you save the PAC file
|
1. You can change PAC rules by editing the PAC file. When you save the PAC file
|
||||||
with any editor, Shadowsocks will notify browsers about the change automatically
|
with any editor, Shadowsocks will notify browsers about the change automatically
|
||||||
2. You can also update PAC file from [GFWList] (maintained by 3rd party)
|
2. You can also update PAC file from [GFWList] \(maintained by 3rd party)
|
||||||
3. You can also use online PAC URL
|
3. You can also use online PAC URL
|
||||||
|
|
||||||
#### Server Auto Switching
|
#### Server Auto Switching
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Shadowsocks.Controller
|
|||||||
public string LatestVersionLocalName;
|
public string LatestVersionLocalName;
|
||||||
public event EventHandler CheckUpdateCompleted;
|
public event EventHandler CheckUpdateCompleted;
|
||||||
|
|
||||||
public const string Version = "3.3.3";
|
public const string Version = "3.3.4";
|
||||||
|
|
||||||
private class CheckUpdateTimer : System.Timers.Timer
|
private class CheckUpdateTimer : System.Timers.Timer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
string path = Application.ExecutablePath;
|
string path = Application.ExecutablePath;
|
||||||
runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
|
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
|
||||||
if ( runKey == null ) {
|
if ( runKey == null ) {
|
||||||
Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run" );
|
Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run" );
|
||||||
return false;
|
return false;
|
||||||
@@ -54,7 +54,7 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
string path = Application.ExecutablePath;
|
string path = Application.ExecutablePath;
|
||||||
runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
|
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
|
||||||
if (runKey == null) {
|
if (runKey == null) {
|
||||||
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
|
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -237,10 +237,10 @@ namespace Shadowsocks.Encryption
|
|||||||
|
|
||||||
protected static void randBytes(byte[] buf, int length)
|
protected static void randBytes(byte[] buf, int length)
|
||||||
{
|
{
|
||||||
byte[] temp = new byte[length];
|
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
|
||||||
RNGCryptoServiceProvider rngServiceProvider = new RNGCryptoServiceProvider();
|
{
|
||||||
rngServiceProvider.GetBytes(temp);
|
rng.GetBytes(buf, 0, length);
|
||||||
temp.CopyTo(buf, 0);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
|
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ namespace Shadowsocks
|
|||||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||||
Application.EnableVisualStyles();
|
Application.EnableVisualStyles();
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
Application.ApplicationExit += (sender, args) => HotKeys.Destroy();
|
|
||||||
|
|
||||||
if (!mutex.WaitOne(0, false))
|
if (!mutex.WaitOne(0, false))
|
||||||
{
|
{
|
||||||
@@ -85,7 +84,7 @@ namespace Shadowsocks
|
|||||||
Logging.Error(e.ExceptionObject?.ToString());
|
Logging.Error(e.ExceptionObject?.ToString());
|
||||||
MessageBox.Show(
|
MessageBox.Show(
|
||||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{e.ExceptionObject?.ToString()}",
|
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{e.ExceptionObject?.ToString()}",
|
||||||
"Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
"Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
Application.Exit();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +95,7 @@ namespace Shadowsocks
|
|||||||
Logging.Error(errorMsg);
|
Logging.Error(errorMsg);
|
||||||
MessageBox.Show(
|
MessageBox.Show(
|
||||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}",
|
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}",
|
||||||
"Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
"Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
Application.Exit();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +149,7 @@ namespace Shadowsocks
|
|||||||
|
|
||||||
private static void Application_ApplicationExit(object sender, EventArgs e)
|
private static void Application_ApplicationExit(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
HotKeys.Destroy();
|
||||||
if (_controller != null)
|
if (_controller != null)
|
||||||
{
|
{
|
||||||
_controller.Stop();
|
_controller.Stop();
|
||||||
|
|||||||
@@ -11,21 +11,7 @@ namespace Shadowsocks.Util.ProcessManagement
|
|||||||
*/
|
*/
|
||||||
public class Job : IDisposable
|
public class Job : IDisposable
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern IntPtr CreateJobObject(IntPtr a, string lpName);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
private static extern bool CloseHandle(IntPtr hObject);
|
|
||||||
|
|
||||||
private IntPtr handle = IntPtr.Zero;
|
private IntPtr handle = IntPtr.Zero;
|
||||||
private bool disposed;
|
|
||||||
|
|
||||||
public Job()
|
public Job()
|
||||||
{
|
{
|
||||||
@@ -62,36 +48,6 @@ namespace Shadowsocks.Util.ProcessManagement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposed) return;
|
|
||||||
disposed = true;
|
|
||||||
|
|
||||||
if (disposing) { }
|
|
||||||
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Close()
|
|
||||||
{
|
|
||||||
if (handle != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
CloseHandle(handle);
|
|
||||||
handle = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Job()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddProcess(IntPtr processHandle)
|
public bool AddProcess(IntPtr processHandle)
|
||||||
{
|
{
|
||||||
var succ = AssignProcessToJobObject(handle, processHandle);
|
var succ = AssignProcessToJobObject(handle, processHandle);
|
||||||
@@ -109,6 +65,56 @@ namespace Shadowsocks.Util.ProcessManagement
|
|||||||
return AddProcess(Process.GetProcessById(processId).Handle);
|
return AddProcess(Process.GetProcessById(processId).Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
private bool disposed;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposed) return;
|
||||||
|
disposed = true;
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
// no managed objects to free
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
handle = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Job()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Interop
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
private static extern IntPtr CreateJobObject(IntPtr a, string lpName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static extern bool CloseHandle(IntPtr hObject);
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Helper classes
|
#region Helper classes
|
||||||
|
|||||||
@@ -30,7 +30,13 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
INTERNET_OPTION_SETTINGS_CHANGED = 39,
|
INTERNET_OPTION_SETTINGS_CHANGED = 39,
|
||||||
|
|
||||||
// Causes the proxy data to be reread from the registry for a handle.
|
// Causes the proxy data to be reread from the registry for a handle.
|
||||||
INTERNET_OPTION_REFRESH = 37
|
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
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Shadowsocks.Util.SystemProxy
|
namespace Shadowsocks.Util.SystemProxy
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable
|
public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable
|
||||||
{
|
{
|
||||||
public int Size;
|
public int Size;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets an Internet option.
|
/// Sets an Internet option.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DllImport("wininet.dll", CharSet = CharSet.Ansi, SetLastError = true)]
|
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
internal static extern bool InternetSetOption(
|
internal static extern bool InternetSetOption(
|
||||||
IntPtr hInternet,
|
IntPtr hInternet,
|
||||||
INTERNET_OPTION dwOption,
|
INTERNET_OPTION dwOption,
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Shadowsocks.Util.SystemProxy
|
||||||
|
{
|
||||||
|
public static class RAS
|
||||||
|
{
|
||||||
|
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(
|
||||||
|
string reserved, // reserved, must be NULL
|
||||||
|
string lpszPhonebook, // pointer to full path and file name of phone-book file
|
||||||
|
[In, Out] RasEntryName[] lprasentryname, // buffer to receive phone-book entries
|
||||||
|
ref int lpcb, // size in bytes of buffer
|
||||||
|
out int lpcEntries // number of entries written to buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/// <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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,19 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Shadowsocks.Controller;
|
||||||
|
|
||||||
namespace Shadowsocks.Util.SystemProxy
|
namespace Shadowsocks.Util.SystemProxy
|
||||||
{
|
{
|
||||||
public static class WinINet
|
public static class WinINet
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set IE settings for LAN connection.
|
/// Set IE settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
|
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>();
|
List<INTERNET_PER_CONN_OPTION> _optionlist = new List<INTERNET_PER_CONN_OPTION>();
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
if (global)
|
if (global)
|
||||||
@@ -38,17 +40,18 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
||||||
{
|
{
|
||||||
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI,
|
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI,
|
||||||
Value = { dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_PROXY }
|
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
|
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
||||||
{
|
{
|
||||||
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER,
|
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER,
|
||||||
Value = { pszValue = Marshal.StringToHGlobalAnsi(proxyServer) }
|
Value = { pszValue = Marshal.StringToHGlobalAuto(proxyServer) }
|
||||||
});
|
});
|
||||||
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
||||||
{
|
{
|
||||||
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS,
|
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS,
|
||||||
Value = { pszValue = Marshal.StringToHGlobalAnsi("<local>") }
|
Value = { pszValue = Marshal.StringToHGlobalAuto("<local>") }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -62,7 +65,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
_optionlist.Add(new INTERNET_PER_CONN_OPTION
|
||||||
{
|
{
|
||||||
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_AUTOCONFIG_URL,
|
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_AUTOCONFIG_URL,
|
||||||
Value = { pszValue = Marshal.StringToHGlobalAnsi(pacURL) }
|
Value = { pszValue = Marshal.StringToHGlobalAuto(pacURL) }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,8 +104,9 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
// Return the unmanaged size of an object in bytes.
|
// Return the unmanaged size of an object in bytes.
|
||||||
optionList.Size = Marshal.SizeOf(optionList);
|
optionList.Size = Marshal.SizeOf(optionList);
|
||||||
|
|
||||||
// IntPtr.Zero means LAN connection.
|
optionList.Connection = connName.IsNullOrEmpty()
|
||||||
optionList.Connection = IntPtr.Zero;
|
? IntPtr.Zero // NULL means LAN
|
||||||
|
: Marshal.StringToHGlobalAuto(connName); // TODO: not working if contains Chinese
|
||||||
|
|
||||||
optionList.OptionCount = _optionlist.Count;
|
optionList.OptionCount = _optionlist.Count;
|
||||||
optionList.OptionError = 0;
|
optionList.OptionError = 0;
|
||||||
@@ -132,15 +136,56 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
|
|
||||||
// Notify the system that the registry settings have been changed and cause
|
// Notify the system that the registry settings have been changed and cause
|
||||||
// the proxy data to be reread from the registry for a handle.
|
// the proxy data to be reread from the registry for a handle.
|
||||||
NativeMethods.InternetSetOption(
|
// bReturn = NativeMethods.InternetSetOption(
|
||||||
IntPtr.Zero,
|
// IntPtr.Zero,
|
||||||
INTERNET_OPTION.INTERNET_OPTION_SETTINGS_CHANGED,
|
// INTERNET_OPTION.INTERNET_OPTION_SETTINGS_CHANGED,
|
||||||
IntPtr.Zero, 0);
|
// IntPtr.Zero, 0);
|
||||||
|
// if ( ! bReturn )
|
||||||
|
// {
|
||||||
|
// Logging.Error("InternetSetOption:INTERNET_OPTION_SETTINGS_CHANGED");
|
||||||
|
// }
|
||||||
|
|
||||||
NativeMethods.InternetSetOption(
|
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,
|
IntPtr.Zero,
|
||||||
INTERNET_OPTION.INTERNET_OPTION_REFRESH,
|
INTERNET_OPTION.INTERNET_OPTION_REFRESH,
|
||||||
IntPtr.Zero, 0);
|
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 = RAS.GetAllConns(ref allConnections);
|
||||||
|
|
||||||
|
if (ret == 2)
|
||||||
|
throw new Exception("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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ namespace Shadowsocks.Util
|
|||||||
return new BandwidthScaleInfo(f, unit, scale);
|
return new BandwidthScaleInfo(f, unit, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegistryKey OpenUserRegKey( string name, bool writable )
|
public static RegistryKey OpenRegKey( string name, bool writable, RegistryHive hive = RegistryHive.CurrentUser )
|
||||||
{
|
{
|
||||||
// we are building x86 binary for both x86 and x64, which will
|
// we are building x86 binary for both x86 and x64, which will
|
||||||
// cause problem when opening registry key
|
// cause problem when opening registry key
|
||||||
@@ -219,7 +219,7 @@ namespace Shadowsocks.Util
|
|||||||
if (name.IsNullOrEmpty()) throw new ArgumentException(nameof(name));
|
if (name.IsNullOrEmpty()) throw new ArgumentException(nameof(name));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RegistryKey userKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser,
|
RegistryKey userKey = RegistryKey.OpenBaseKey(hive,
|
||||||
Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32)
|
Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32)
|
||||||
.OpenSubKey(name, writable);
|
.OpenSubKey(name, writable);
|
||||||
return userKey;
|
return userKey;
|
||||||
@@ -236,7 +236,7 @@ namespace Shadowsocks.Util
|
|||||||
}
|
}
|
||||||
catch (ArgumentException ae)
|
catch (ArgumentException ae)
|
||||||
{
|
{
|
||||||
MessageBox.Show("OpenUserRegKey: " + ae.ToString());
|
MessageBox.Show("OpenRegKey: " + ae.ToString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ namespace Shadowsocks.View
|
|||||||
{
|
{
|
||||||
int index = ServersListBox.SelectedIndex;
|
int index = ServersListBox.SelectedIndex;
|
||||||
Server server = _modifiedConfiguration.configs[index];
|
Server server = _modifiedConfiguration.configs[index];
|
||||||
object item = ServersListBox.SelectedItem;
|
object item = ServersListBox.Items[index];
|
||||||
|
|
||||||
_modifiedConfiguration.configs.Remove(server);
|
_modifiedConfiguration.configs.Remove(server);
|
||||||
_modifiedConfiguration.configs.Insert(index + step, server);
|
_modifiedConfiguration.configs.Insert(index + step, server);
|
||||||
|
|||||||
@@ -190,6 +190,7 @@
|
|||||||
<Compile Include="Util\SystemProxy\INTERNET_PER_CONN_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\INTERNET_PER_CONN_OPTION_LIST.cs" />
|
||||||
<Compile Include="Util\SystemProxy\NativeMethods.cs" />
|
<Compile Include="Util\SystemProxy\NativeMethods.cs" />
|
||||||
|
<Compile Include="Util\SystemProxy\RAS.cs" />
|
||||||
<Compile Include="Util\SystemProxy\WinINet.cs" />
|
<Compile Include="Util\SystemProxy\WinINet.cs" />
|
||||||
<Compile Include="Util\Util.cs" />
|
<Compile Include="Util\Util.cs" />
|
||||||
<Compile Include="View\ConfigForm.cs">
|
<Compile Include="View\ConfigForm.cs">
|
||||||
|
|||||||
Reference in New Issue
Block a user