|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Net;
- using System.Net.NetworkInformation;
- using System.Runtime.InteropServices;
- using System.Text;
-
- using Shadowsocks.Model;
- using Shadowsocks.Properties;
- using Shadowsocks.Util;
-
- namespace Shadowsocks.Controller
- {
- class PolipoRunner
- {
- private Process _process;
- private int _runningPort;
-
- static PolipoRunner()
- {
- try
- {
- FileManager.UncompressFile(Utils.GetTempPath("ss_privoxy.exe"), Resources.privoxy_exe);
- FileManager.UncompressFile(Utils.GetTempPath("mgwz.dll"), Resources.mgwz_dll);
- }
- catch (IOException e)
- {
- Logging.LogUsefulException(e);
- }
- }
-
- public int RunningPort
- {
- get
- {
- return _runningPort;
- }
- }
-
- public void Start(Configuration configuration)
- {
- Server server = configuration.GetCurrentServer();
- if (_process == null)
- {
- Process[] existingPolipo = Process.GetProcessesByName("ss_privoxy");
- foreach (Process p in existingPolipo)
- {
- try
- {
- p.CloseMainWindow();
- p.WaitForExit(100);
- if (!p.HasExited)
- {
- p.Kill();
- p.WaitForExit();
- }
- }
- catch (Exception e)
- {
- Logging.LogUsefulException(e);
- }
- }
- string polipoConfig = Resources.privoxy_conf;
- _runningPort = this.GetFreePort();
- polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString());
- polipoConfig = polipoConfig.Replace("__POLIPO_BIND_PORT__", _runningPort.ToString());
- polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1");
- FileManager.ByteArrayToFile(Utils.GetTempPath("privoxy.conf"), Encoding.UTF8.GetBytes(polipoConfig));
-
- _process = new Process();
- // Configure the process using the StartInfo properties.
- _process.StartInfo.FileName = "ss_privoxy.exe";
- _process.StartInfo.Arguments = "privoxy.conf";
- _process.StartInfo.WorkingDirectory = Utils.GetTempPath();
- _process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
- _process.StartInfo.UseShellExecute = true;
- _process.StartInfo.CreateNoWindow = true;
- _process.Start();
- }
- RefreshTrayArea();
- }
-
- public void Stop()
- {
- if (_process != null)
- {
- try
- {
- _process.Kill();
- _process.WaitForExit();
- }
- catch (Exception e)
- {
- Logging.LogUsefulException(e);
- }
- _process = null;
- }
- RefreshTrayArea();
- }
-
- private int GetFreePort()
- {
- int defaultPort = 8123;
- try
- {
- IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
- IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners();
-
- List<int> usedPorts = new List<int>();
- foreach (IPEndPoint endPoint in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())
- {
- usedPorts.Add(endPoint.Port);
- }
- for (int port = defaultPort; port <= 65535; port++)
- {
- if (!usedPorts.Contains(port))
- {
- return port;
- }
- }
- }
- catch (Exception e)
- {
- // in case access denied
- Logging.LogUsefulException(e);
- return defaultPort;
- }
- throw new Exception("No free port found.");
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int left;
- public int top;
- public int right;
- public int bottom;
- }
- [DllImport("user32.dll")]
- public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
- [DllImport("user32.dll")]
- public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
- [DllImport("user32.dll")]
- public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
- [DllImport("user32.dll")]
- public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
-
- public void RefreshTrayArea()
- {
- IntPtr systemTrayContainerHandle = FindWindow("Shell_TrayWnd", null);
- IntPtr systemTrayHandle = FindWindowEx(systemTrayContainerHandle, IntPtr.Zero, "TrayNotifyWnd", null);
- IntPtr sysPagerHandle = FindWindowEx(systemTrayHandle, IntPtr.Zero, "SysPager", null);
- IntPtr notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32", "Notification Area");
- if (notificationAreaHandle == IntPtr.Zero)
- {
- notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32", "User Promoted Notification Area");
- IntPtr notifyIconOverflowWindowHandle = FindWindow("NotifyIconOverflowWindow", null);
- IntPtr overflowNotificationAreaHandle = FindWindowEx(notifyIconOverflowWindowHandle, IntPtr.Zero, "ToolbarWindow32", "Overflow Notification Area");
- RefreshTrayArea(overflowNotificationAreaHandle);
- }
- RefreshTrayArea(notificationAreaHandle);
- }
-
- private static void RefreshTrayArea(IntPtr windowHandle)
- {
- const uint wmMousemove = 0x0200;
- RECT rect;
- GetClientRect(windowHandle, out rect);
- for (var x = 0; x < rect.right; x += 5)
- for (var y = 0; y < rect.bottom; y += 5)
- SendMessage(windowHandle, wmMousemove, 0, (y << 16) + x);
- }
- }
- }
|