OSDN Git Service

水上爆撃機の改修値を爆撃に反映する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / SystemProxy.cs
1 // Copyright (C) 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\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
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\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
14 \r
15 using System;\r
16 using System.Runtime.InteropServices;\r
17 \r
18 // ReSharper disable UnusedMember.Local\r
19 \r
20 // ReSharper disable InconsistentNaming\r
21 \r
22 namespace KancolleSniffer\r
23 {\r
24     public class SystemProxy\r
25     {\r
26         private InternetPerConnOptionList orgList;\r
27         private string _currentUrl;\r
28 \r
29         private void SaveSettings()\r
30         {\r
31             if (orgList.dwSize != 0)\r
32                 return;\r
33             var opts = new[]\r
34             {\r
35                 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_FLAGS},\r
36                 new InternetPerConnOption {dwOption = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL}\r
37             };\r
38             var list = new InternetPerConnOptionList\r
39             {\r
40                 pOptions = MarshalOptions(opts),\r
41                 pszConnection = IntPtr.Zero,\r
42                 dwOptionCount = opts.Length,\r
43                 dwOptionError = 0\r
44             };\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
48             {\r
49                 orgList = list;\r
50             }\r
51         }\r
52 \r
53         public void SetAutoProxyUrl(string url)\r
54         {\r
55             SaveSettings();\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
58             _currentUrl = url;\r
59             var opts = new[]\r
60             {\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
63             };\r
64             var list = new InternetPerConnOptionList\r
65             {\r
66                 pOptions = MarshalOptions(opts),\r
67                 pszConnection = IntPtr.Zero,\r
68                 dwOptionCount = opts.Length,\r
69                 dwOptionError = 0\r
70             };\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
75             Refresh();\r
76 \r
77             Marshal.FreeHGlobal(urlValue.pszValue);\r
78             Marshal.FreeCoTaskMem(list.pOptions);\r
79             Marshal.FreeCoTaskMem(listBuff);\r
80         }\r
81 \r
82         public void RestoreSettings()\r
83         {\r
84             if (orgList.dwSize == 0)\r
85                 return;\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
91             {\r
92                 // Unselect the Use automatic configration script check box.\r
93                 var flagsOpt =\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
97             }\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
102             Refresh();\r
103 \r
104             Marshal.FreeCoTaskMem(listBuff);\r
105             Marshal.FreeHGlobal(urlOpt.Value.pszValue);\r
106             Marshal.FreeCoTaskMem(orgList.pOptions);\r
107             orgList.dwSize = 0;\r
108         }\r
109 \r
110         private IntPtr MarshalOptions(InternetPerConnOption[] opts)\r
111         {\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
115             {\r
116                 var ptr = (IntPtr)((long)buff + (i * size));\r
117                 Marshal.StructureToPtr(opts[i], ptr, false);\r
118             }\r
119             return buff;\r
120         }\r
121 \r
122         public static void Refresh()\r
123         {\r
124             InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PROXY_SETTINGS_CHANGED, IntPtr.Zero, 0);\r
125         }\r
126 \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
130 \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
134 \r
135         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\r
136         private struct InternetPerConnOptionList\r
137         {\r
138             public int dwSize;\r
139             public IntPtr pszConnection;\r
140             public int dwOptionCount;\r
141             public int dwOptionError;\r
142             public IntPtr pOptions;\r
143         };\r
144 \r
145         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\r
146         private struct InternetPerConnOption\r
147         {\r
148             public PerConnOption dwOption;\r
149             public InternetPerConnOptionValue Value;\r
150         }\r
151 \r
152         [StructLayout(LayoutKind.Explicit)]\r
153         public struct InternetPerConnOptionValue\r
154         {\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
158         }\r
159 \r
160         private enum InternetOption : uint\r
161         {\r
162             INTERNET_OPTION_REFRESH = 0x00000025,\r
163             INTERNET_OPTION_PER_CONNECTION_OPTION = 0x0000004B,\r
164             INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 0x0000005F\r
165         }\r
166 \r
167         private enum PerConnOption\r
168         {\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
174         }\r
175 \r
176         [Flags]\r
177         private enum PerConnFlags\r
178         {\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
183         }\r
184     }\r
185 }