1 // Copyright (C) 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
16 using System.Runtime.InteropServices;
\r
18 // ReSharper disable UnusedMember.Local
\r
20 // ReSharper disable InconsistentNaming
\r
22 namespace KancolleSniffer
\r
24 public class SystemProxy
\r
26 private InternetPerConnOptionList orgList;
\r
27 private string _currentUrl;
\r
29 private void SaveSettings()
\r
31 if (orgList.dwSize != 0)
\r
35 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_FLAGS},
\r
36 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL}
\r
38 var list = new InternetPerConnOptionList
\r
40 pOptions = MarshalOptions(opts),
\r
41 pszConnection = IntPtr.Zero,
\r
42 dwOptionCount = opts.Length,
\r
45 var listSize = list.dwSize = Marshal.SizeOf(list);
\r
46 if (InternetQueryOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
\r
47 ref list, ref listSize))
\r
53 public void SetAutoProxyUrl(string url)
\r
56 var flagValue = new InternetPerConnOptionValue {dwValue = (int)PerConnFlags.PROXY_TYPE_AUTO_PROXY_URL};
\r
57 var urlValue = new InternetPerConnOptionValue {pszValue = Marshal.StringToHGlobalAuto(url)};
\r
61 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_FLAGS, Value = flagValue},
\r
62 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL, Value = urlValue}
\r
64 var list = new InternetPerConnOptionList
\r
66 pOptions = MarshalOptions(opts),
\r
67 pszConnection = IntPtr.Zero,
\r
68 dwOptionCount = opts.Length,
\r
71 var listSize = list.dwSize = Marshal.SizeOf(list);
\r
72 var listBuff = Marshal.AllocCoTaskMem(listSize);
\r
73 Marshal.StructureToPtr(list, listBuff, false);
\r
74 InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, listBuff, listSize);
\r
77 Marshal.FreeHGlobal(urlValue.pszValue);
\r
78 Marshal.FreeCoTaskMem(list.pOptions);
\r
79 Marshal.FreeCoTaskMem(listBuff);
\r
82 public void RestoreSettings()
\r
84 if (orgList.dwSize == 0)
\r
86 var size = Marshal.SizeOf(typeof(InternetPerConnOption));
\r
87 var urlOpt = (InternetPerConnOption)
\r
88 Marshal.PtrToStructure((IntPtr)((long)orgList.pOptions + size), typeof(InternetPerConnOption));
\r
89 var orgUrl = Marshal.PtrToStringAuto(urlOpt.Value.pszValue);
\r
90 if (orgUrl == _currentUrl) // The restoration was sikipped or failed at last time.
\r
92 // Unselect the Use automatic configration script check box.
\r
94 (InternetPerConnOption)Marshal.PtrToStructure(orgList.pOptions, typeof(InternetPerConnOption));
\r
95 flagsOpt.Value.dwValue &= ~(int)PerConnFlags.PROXY_TYPE_AUTO_PROXY_URL;
\r
96 Marshal.StructureToPtr(flagsOpt, orgList.pOptions, false);
\r
98 var listSize = orgList.dwSize;
\r
99 var listBuff = Marshal.AllocCoTaskMem(listSize);
\r
100 Marshal.StructureToPtr(orgList, listBuff, false);
\r
101 InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, listBuff, listSize);
\r
104 Marshal.FreeCoTaskMem(listBuff);
\r
105 Marshal.FreeHGlobal(urlOpt.Value.pszValue);
\r
106 Marshal.FreeCoTaskMem(orgList.pOptions);
\r
107 orgList.dwSize = 0;
\r
110 private IntPtr MarshalOptions(InternetPerConnOption[] opts)
\r
112 var buff = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(InternetPerConnOption)) * opts.Length);
\r
113 var size = Marshal.SizeOf(typeof(InternetPerConnOption));
\r
114 for (var i = 0; i < opts.Length; i++)
\r
116 var ptr = (IntPtr)((long)buff + (i * size));
\r
117 Marshal.StructureToPtr(opts[i], ptr, false);
\r
122 public static void Refresh()
\r
124 InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PROXY_SETTINGS_CHANGED, IntPtr.Zero, 0);
\r
127 [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
\r
128 private static extern bool InternetQueryOption(IntPtr hInternet, InternetOption dwOption,
\r
129 ref InternetPerConnOptionList optionList, ref int lpdwBufferLength);
\r
131 [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
\r
132 private static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption,
\r
133 IntPtr lpBuffer, int dwBufferLength);
\r
135 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
\r
136 private struct InternetPerConnOptionList
\r
139 public IntPtr pszConnection;
\r
140 public int dwOptionCount;
\r
141 public int dwOptionError;
\r
142 public IntPtr pOptions;
\r
145 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
\r
146 private struct InternetPerConnOption
\r
148 public PerConnOption dwOption;
\r
149 public InternetPerConnOptionValue Value;
\r
152 [StructLayout(LayoutKind.Explicit)]
\r
153 public struct InternetPerConnOptionValue
\r
155 [FieldOffset(0)] public int dwValue;
\r
156 [FieldOffset(0)] public IntPtr pszValue;
\r
157 [FieldOffset(0)] public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
\r
160 private enum InternetOption : uint
\r
162 INTERNET_OPTION_REFRESH = 0x00000025,
\r
163 INTERNET_OPTION_PER_CONNECTION_OPTION = 0x0000004B,
\r
164 INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 0x0000005F
\r
167 private enum PerConnOption
\r
169 INTERNET_PER_CONN_FLAGS = 1,
\r
170 INTERNET_PER_CONN_PROXY_SERVER = 2,
\r
171 INTERNET_PER_CONN_PROXY_BYPASS = 3,
\r
172 INTERNET_PER_CONN_AUTOCONFIG_URL = 4,
\r
173 INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5
\r
177 private enum PerConnFlags
\r
179 PROXY_TYPE_DIRECT = 0x00000001,
\r
180 PROXY_TYPE_PROXY = 0x00000002,
\r
181 PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,
\r
182 PROXY_TYPE_AUTO_DETECT = 0x00000008
\r