You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Sysproxy.cs 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Text;
  5. using Shadowsocks.Controller;
  6. using Shadowsocks.Properties;
  7. namespace Shadowsocks.Util.SystemProxy
  8. {
  9. public static class Sysproxy
  10. {
  11. private static bool _userSettingsRecorded = false;
  12. // In general, this won't change
  13. // format:
  14. // <flags><CR-LF>
  15. // <proxy-server><CR-LF>
  16. // <bypass-list><CR-LF>
  17. // <pac-url>
  18. private static string[] _userSettings = new string[4];
  19. enum RET_ERRORS : int
  20. {
  21. RET_NO_ERROR = 0,
  22. INVALID_FORMAT = 1,
  23. NO_PERMISSION = 2,
  24. SYSCALL_FAILED = 3,
  25. NO_MEMORY = 4,
  26. INVAILD_OPTION_COUNT = 5,
  27. };
  28. static Sysproxy()
  29. {
  30. try
  31. {
  32. FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
  33. Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
  34. }
  35. catch (IOException e)
  36. {
  37. Logging.LogUsefulException(e);
  38. }
  39. }
  40. public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
  41. {
  42. string str;
  43. if (_userSettingsRecorded == false)
  44. {
  45. // record user settings
  46. ExecSysproxy("query", out str);
  47. ParseQueryStr(str);
  48. _userSettingsRecorded = true;
  49. }
  50. string arguments;
  51. if (enable)
  52. {
  53. arguments = global
  54. ? $"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.*"
  55. : $"pac {pacURL}";
  56. }
  57. else
  58. {
  59. // restore user settings
  60. var flags = _userSettings[0];
  61. var proxy_server = _userSettings[1] ?? "-";
  62. var bypass_list = _userSettings[2] ?? "-";
  63. var pac_url = _userSettings[3] ?? "-";
  64. arguments = $"set {flags} {proxy_server} {bypass_list} {pac_url}";
  65. // have to get new settings
  66. _userSettingsRecorded = false;
  67. }
  68. ExecSysproxy(arguments, out str);
  69. }
  70. private static void ExecSysproxy(string arguments, out string queryStr)
  71. {
  72. using (var process = new Process())
  73. {
  74. // Configure the process using the StartInfo properties.
  75. process.StartInfo.FileName = Utils.GetTempPath("sysproxy.exe");
  76. process.StartInfo.Arguments = arguments;
  77. process.StartInfo.WorkingDirectory = Utils.GetTempPath();
  78. process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
  79. process.StartInfo.UseShellExecute = false;
  80. process.StartInfo.RedirectStandardError = true;
  81. process.StartInfo.RedirectStandardOutput = true;
  82. // Need to provide encoding info, or output/error strings we got will be wrong.
  83. process.StartInfo.StandardOutputEncoding = Encoding.Unicode;
  84. process.StartInfo.StandardErrorEncoding = Encoding.Unicode;
  85. process.StartInfo.CreateNoWindow = true;
  86. process.Start();
  87. var stderr = process.StandardError.ReadToEnd();
  88. var stdout = process.StandardOutput.ReadToEnd();
  89. process.WaitForExit();
  90. var exitCode = process.ExitCode;
  91. if (exitCode != (int)RET_ERRORS.RET_NO_ERROR)
  92. {
  93. throw new ProxyException(stderr);
  94. }
  95. if (arguments == "query" && stdout.IsNullOrWhiteSpace())
  96. {
  97. // we cannot get user settings
  98. throw new ProxyException("failed to query wininet settings");
  99. }
  100. queryStr = stdout;
  101. }
  102. }
  103. private static void ParseQueryStr(string str)
  104. {
  105. _userSettings = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
  106. for (var i = 0; i < 4; i++)
  107. {
  108. // handle output from WinINET
  109. if (_userSettings[i] == "(null)")
  110. _userSettings[i] = null;
  111. }
  112. }
  113. }
  114. }