diff --git a/shadowsocks-csharp/Controller/System/AutoStartup.cs b/shadowsocks-csharp/Controller/System/AutoStartup.cs index 353056eb..86e1af04 100644 --- a/shadowsocks-csharp/Controller/System/AutoStartup.cs +++ b/shadowsocks-csharp/Controller/System/AutoStartup.cs @@ -1,6 +1,7 @@ using System; using System.Windows.Forms; using Microsoft.Win32; +using Shadowsocks.Util; namespace Shadowsocks.Controller { @@ -14,7 +15,11 @@ namespace Shadowsocks.Controller try { string path = Application.ExecutablePath; - runKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + if ( runKey == null ) { + Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run" ); + return false; + } if (enabled) { runKey.SetValue(Key, path); @@ -47,7 +52,11 @@ namespace Shadowsocks.Controller try { string path = Application.ExecutablePath; - runKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + if (runKey == null) { + Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); + return false; + } string[] runList = runKey.GetValueNames(); foreach (string item in runList) { diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index bf77f999..e3054f3d 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -1,11 +1,10 @@ using System.Windows.Forms; using Microsoft.Win32; using System; -using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Text; using System.IO; using Shadowsocks.Model; +using Shadowsocks.Util; namespace Shadowsocks.Controller { @@ -44,81 +43,86 @@ namespace Shadowsocks.Controller { enabled = false; } - - try - { - var registry = Registry.CurrentUser - .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true); - if (enabled) - { - if (global) - { - registry.SetValue("ProxyEnable", 1); - registry.SetValue("ProxyServer", "127.0.0.1:" + config.localPort.ToString()); - registry.SetValue("AutoConfigURL", ""); - } - else - { + RegistryKey registry = null; + try { + registry = Utils.OpenUserRegKey( @"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true ); + if ( registry == null ) { + Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ); + return; + } + if ( enabled ) { + if ( global ) { + registry.SetValue( "ProxyEnable", 1 ); + registry.SetValue( "ProxyServer", "127.0.0.1:" + config.localPort.ToString() ); + registry.SetValue( "AutoConfigURL", "" ); + } else { string pacUrl; - if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) + if ( config.useOnlinePac && ! config.pacUrl.IsNullOrEmpty() ) pacUrl = config.pacUrl; else - pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}"; - registry.SetValue("ProxyEnable", 0); - var readProxyServer = registry.GetValue("ProxyServer"); - registry.SetValue("ProxyServer", ""); - registry.SetValue("AutoConfigURL", pacUrl); + pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp( DateTime.Now )}"; + registry.SetValue( "ProxyEnable", 0 ); + var readProxyServer = registry.GetValue( "ProxyServer" ); + registry.SetValue( "ProxyServer", "" ); + registry.SetValue( "AutoConfigURL", pacUrl ); } - } - else - { - registry.SetValue("ProxyEnable", 0); - registry.SetValue("ProxyServer", ""); - registry.SetValue("AutoConfigURL", ""); + } else { + registry.SetValue( "ProxyEnable", 0 ); + registry.SetValue( "ProxyServer", "" ); + registry.SetValue( "AutoConfigURL", "" ); } //Set AutoDetectProxy - IEAutoDetectProxy(!enabled); + IEAutoDetectProxy( ! enabled ); NotifyIE(); //Must Notify IE first, or the connections do not chanage CopyProxySettingFromLan(); - } - catch (Exception e) - { - Logging.LogUsefulException(e); + } catch ( Exception e ) { + Logging.LogUsefulException( e ); // TODO this should be moved into views - MessageBox.Show(I18N.GetString("Failed to update registry")); + MessageBox.Show( I18N.GetString( "Failed to update registry" ) ); + } finally { + if ( registry != null ) { + try { registry.Close(); } + catch (Exception e) + { Logging.LogUsefulException(e); } + } } } private static void CopyProxySettingFromLan() { - var registry = Registry.CurrentUser - .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true); - var defaultValue = registry.GetValue("DefaultConnectionSettings"); - try - { + RegistryKey registry = null; + try { + registry = Utils.OpenUserRegKey( @"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true ); + if ( registry == null ) { + Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ); + return; + } + var defaultValue = registry.GetValue( "DefaultConnectionSettings" ); var connections = registry.GetValueNames(); - foreach (var each in connections) - { - switch (each.ToUpperInvariant()) - { + foreach ( var each in connections ) { + switch ( each.ToUpperInvariant() ) { case "DEFAULTCONNECTIONSETTINGS": case "LAN CONNECTION": case "SAVEDLEGACYSETTINGS": continue; default: //set all the connections's proxy as the lan - registry.SetValue(each, defaultValue); + registry.SetValue( each, defaultValue ); continue; } } NotifyIE(); - } - catch (IOException e) - { - Logging.LogUsefulException(e); + } catch ( IOException e ) { + Logging.LogUsefulException( e ); + } finally { + if ( registry != null ) { + try { registry.Close(); } + catch (Exception e) + { Logging.LogUsefulException(e); } + } } } @@ -128,34 +132,44 @@ namespace Shadowsocks.Controller /// Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false' private static void IEAutoDetectProxy(bool set) { - var registry = Registry.CurrentUser - .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true); - var defConnection = (byte[])registry.GetValue("DefaultConnectionSettings"); - var savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings"); + RegistryKey registry = null; + try { + registry = Utils.OpenUserRegKey( @"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true ); + if ( registry == null ) { + Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ); + return; + } + var defConnection = ( byte[] ) registry.GetValue( "DefaultConnectionSettings" ); + var savedLegacySetting = ( byte[] ) registry.GetValue( "SavedLegacySettings" ); - const int versionOffset = 4; - const int optionsOffset = 8; + const int versionOffset = 4; + const int optionsOffset = 8; - if (set) - { - defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] | 8); - savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] | 8); - } - else - { - defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] & ~8); - savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] & ~8); - } + if ( set ) { + defConnection[ optionsOffset ] = ( byte ) ( defConnection[ optionsOffset ] | 8 ); + savedLegacySetting[ optionsOffset ] = ( byte ) ( savedLegacySetting[ optionsOffset ] | 8 ); + } else { + defConnection[ optionsOffset ] = ( byte ) ( defConnection[ optionsOffset ] & ~8 ); + savedLegacySetting[ optionsOffset ] = ( byte ) ( savedLegacySetting[ optionsOffset ] & ~8 ); + } - BitConverter.GetBytes( - unchecked(BitConverter.ToUInt32(defConnection, versionOffset) + 1)) - .CopyTo(defConnection, versionOffset); - BitConverter.GetBytes( - unchecked(BitConverter.ToUInt32(savedLegacySetting, versionOffset) + 1)) - .CopyTo(savedLegacySetting, versionOffset); + BitConverter.GetBytes(unchecked( BitConverter.ToUInt32( defConnection, versionOffset ) + 1 ) ) + .CopyTo( defConnection, versionOffset ); + BitConverter.GetBytes(unchecked( BitConverter.ToUInt32( savedLegacySetting, versionOffset ) + 1 ) ) + .CopyTo( savedLegacySetting, versionOffset ); - registry.SetValue("DefaultConnectionSettings", defConnection); - registry.SetValue("SavedLegacySettings", savedLegacySetting); + registry.SetValue( "DefaultConnectionSettings", defConnection ); + registry.SetValue( "SavedLegacySettings", savedLegacySetting ); + } catch ( Exception e ) { + Logging.LogUsefulException( e ); + } finally { + if (registry != null) + { + try { registry.Close(); } + catch (Exception e) + { Logging.LogUsefulException(e); } + } + } } } } diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index 44ae5e8f..8a3fcc91 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -4,7 +4,7 @@ using System.IO; using System.IO.Compression; using System.Runtime.InteropServices; using System.Windows.Forms; - +using Microsoft.Win32; using Shadowsocks.Controller; namespace Shadowsocks.Util @@ -147,6 +147,21 @@ namespace Shadowsocks.Util return new Tuple(f, unit, scale); } + public static RegistryKey OpenUserRegKey( string name, bool writable ) { + // we are building x86 binary for both x86 and x64, which will + // cause problem when opening registry key + // detect operating system instead of CPU + if ( Environment.Is64BitOperatingSystem ) { + RegistryKey userKey = RegistryKey.OpenBaseKey( RegistryHive.CurrentUser, RegistryView.Registry64 ); + userKey = userKey.OpenSubKey( name, writable ); + return userKey; + } else { + RegistryKey userKey = RegistryKey.OpenBaseKey( RegistryHive.CurrentUser, RegistryView.Registry32 ); + userKey = userKey.OpenSubKey( name, writable ); + return userKey; + } + } + [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetProcessWorkingSetSize(IntPtr process,