PageRenderTime 24ms CodeModel.GetById 1ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

/Visual Studio 2008/CSWebBrowserWithProxy/WinINet.cs

#
C# | 323 lines | 192 code | 53 blank | 78 comment | 13 complexity | dd0642db05b6c75eb48a1c9e1a6cc61e MD5 | raw file
  1/****************************** Module Header ******************************\
  2 Module Name:  WinINet.cs
  3 Project:      CSWebBrowserWithProxy
  4 Copyright (c) Microsoft Corporation.
  5 
  6 This class is used to set the proxy. or restore to the system proxy for the
  7 current application
  8 
  9 This source is subject to the Microsoft Public License.
 10 See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
 11 All other rights reserved.
 12 
 13 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 14 EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 15 WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 16\***************************************************************************/
 17
 18using System;
 19using System.Runtime.InteropServices;
 20using System.Diagnostics;
 21
 22namespace CSWebBrowserWithProxy
 23{
 24    public static class WinINet
 25    {
 26        static string agent = Process.GetCurrentProcess().ProcessName;
 27
 28        /// <summary>
 29        /// Set the LAN connection proxy server for current process.
 30        /// </summary>
 31        /// <param name="proxyServer">
 32        /// The Proxy Server.
 33        /// </param>
 34        /// <returns></returns>
 35        public static bool SetConnectionProxy(bool isMachineSetting, string proxyServer)
 36        {
 37            if (isMachineSetting)
 38            {
 39                return SetConnectionProxy(null, proxyServer);
 40            }
 41            else
 42            {
 43                return SetConnectionProxy(agent, proxyServer);
 44            }
 45        }
 46
 47        /// <summary>
 48        /// Set the LAN connection proxy server.
 49        /// </summary>
 50        /// <param name="agentName">
 51        /// If agentName is null or empty, this function will set the Lan proxy for
 52        /// the machine, else for the current process.
 53        /// </param>
 54        /// <param name="proxyServer">The Proxy Server.</param>
 55        /// <returns></returns>
 56        public static bool SetConnectionProxy(string agentName, string proxyServer)
 57        {
 58            IntPtr hInternet = IntPtr.Zero;
 59            try
 60            {
 61                if (!string.IsNullOrEmpty(agentName))
 62                {
 63                    hInternet = NativeMethods.InternetOpen(
 64                        agentName,
 65                        (int)INTERNET_OPEN_TYPE.INTERNET_OPEN_TYPE_DIRECT,
 66                        null,
 67                        null,
 68                        0);
 69                }
 70
 71                return SetConnectionProxyInternal(hInternet, proxyServer);
 72            }
 73            finally
 74            {
 75                if (hInternet != IntPtr.Zero)
 76                {
 77                    NativeMethods.InternetCloseHandle(hInternet);
 78                }
 79            }
 80        }
 81
 82        /// <summary>
 83        /// Set the proxy server for LAN connection.
 84        /// </summary>
 85        static bool SetConnectionProxyInternal(IntPtr hInternet, string proxyServer)
 86        {
 87
 88            // Create 3 options.
 89            INTERNET_PER_CONN_OPTION[] Options = new INTERNET_PER_CONN_OPTION[3];
 90
 91            // Set PROXY flags.
 92            Options[0] = new INTERNET_PER_CONN_OPTION();
 93            Options[0].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS;
 94            Options[0].Value.dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS.PROXY_TYPE_PROXY;
 95
 96            // Set proxy name.
 97            Options[1] = new INTERNET_PER_CONN_OPTION();
 98            Options[1].dwOption =
 99                (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER;
100            Options[1].Value.pszValue = Marshal.StringToHGlobalAnsi(proxyServer);
101
102            // Set proxy bypass.
103            Options[2] = new INTERNET_PER_CONN_OPTION();
104            Options[2].dwOption =
105                (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS;
106            Options[2].Value.pszValue = Marshal.StringToHGlobalAnsi("local");
107
108            // Allocate a block of memory of the options.
109            System.IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(Options[0])
110                + Marshal.SizeOf(Options[1]) + Marshal.SizeOf(Options[2]));
111
112            System.IntPtr current = buffer;
113
114            // Marshal data from a managed object to an unmanaged block of memory.
115            for (int i = 0; i < Options.Length; i++)
116            {
117                Marshal.StructureToPtr(Options[i], current, false);
118                current = (System.IntPtr)((int)current + Marshal.SizeOf(Options[i]));
119            }
120
121            // Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
122            INTERNET_PER_CONN_OPTION_LIST option_list = new INTERNET_PER_CONN_OPTION_LIST();
123
124            // Point to the allocated memory.
125            option_list.pOptions = buffer;
126
127            // Return the unmanaged size of an object in bytes.
128            option_list.Size = Marshal.SizeOf(option_list);
129
130            // IntPtr.Zero means LAN connection.
131            option_list.Connection = IntPtr.Zero;
132
133            option_list.OptionCount = Options.Length;
134            option_list.OptionError = 0;
135            int size = Marshal.SizeOf(option_list);
136
137            // Allocate memory for the INTERNET_PER_CONN_OPTION_LIST instance.
138            IntPtr intptrStruct = Marshal.AllocCoTaskMem(size);
139
140            // Marshal data from a managed object to an unmanaged block of memory.
141            Marshal.StructureToPtr(option_list, intptrStruct, true);
142
143            // Set internet settings.
144            bool bReturn = NativeMethods.InternetSetOption(
145                hInternet,
146                INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION,
147                intptrStruct, size);
148
149            // Free the allocated memory.
150            Marshal.FreeCoTaskMem(buffer);
151            Marshal.FreeCoTaskMem(intptrStruct);
152
153            // Throw an exception if this operation failed.
154            if (!bReturn)
155            {
156                throw new ApplicationException(" Set Internet Option Failed!");
157            }
158
159            // Notify the system that the registry settings have been changed and cause
160            // the proxy data to be reread from the registry for a handle.
161            NativeMethods.InternetSetOption(
162                hInternet,
163                INTERNET_OPTION.INTERNET_OPTION_SETTINGS_CHANGED,
164                IntPtr.Zero, 0);
165
166            NativeMethods.InternetSetOption(
167                hInternet,
168                INTERNET_OPTION.INTERNET_OPTION_REFRESH,
169                IntPtr.Zero, 0);
170
171            return bReturn;
172        }
173
174        /// <summary>
175        /// Get the current system options for LAN connection.
176        /// Make sure free the memory after restoration. 
177        /// </summary>
178        public static INTERNET_PER_CONN_OPTION_LIST GetSystemProxy()
179        {
180
181            // Query following options. 
182            INTERNET_PER_CONN_OPTION[] Options = new INTERNET_PER_CONN_OPTION[3];
183
184            Options[0] = new INTERNET_PER_CONN_OPTION();
185            Options[0].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS;
186            Options[1] = new INTERNET_PER_CONN_OPTION();
187            Options[1].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER;
188            Options[2] = new INTERNET_PER_CONN_OPTION();
189            Options[2].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS;
190
191            // Allocate a block of memory of the options.
192            System.IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(Options[0])
193                + Marshal.SizeOf(Options[1]) + Marshal.SizeOf(Options[2]));
194
195            System.IntPtr current = (System.IntPtr)buffer;
196
197            // Marshal data from a managed object to an unmanaged block of memory.
198            for (int i = 0; i < Options.Length; i++)
199            {
200                Marshal.StructureToPtr(Options[i], current, false);
201                current = (System.IntPtr)((int)current + Marshal.SizeOf(Options[i]));
202            }
203
204            // Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
205            INTERNET_PER_CONN_OPTION_LIST Request = new INTERNET_PER_CONN_OPTION_LIST();
206
207            // Point to the allocated memory.
208            Request.pOptions = buffer;
209
210            Request.Size = Marshal.SizeOf(Request);
211
212            // IntPtr.Zero means LAN connection.
213            Request.Connection = IntPtr.Zero;
214
215            Request.OptionCount = Options.Length;
216            Request.OptionError = 0;
217            int size = Marshal.SizeOf(Request);
218
219            // Query system internet options. 
220            bool result = NativeMethods.InternetQueryOption(
221                IntPtr.Zero,
222                INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION,
223                ref Request,
224                ref size);
225
226            if (!result)
227            {
228                throw new ApplicationException("Get System Internet Option Failed! ");
229            }
230
231            return Request;
232        }
233
234        /// <summary>
235        /// Restore to the system proxy settings.
236        /// </summary>
237        public static bool RestoreSystemProxy()
238        {
239            return RestoreSystemProxy(agent);
240        }
241
242        /// <summary>
243        /// Restore to the system proxy settings.
244        /// </summary>
245        public static bool RestoreSystemProxy(string agentName)
246        {
247            if (string.IsNullOrEmpty(agentName))
248            {
249                throw new ArgumentNullException("Agent name cannot be null or empty!");
250            }
251
252            IntPtr hInternet = IntPtr.Zero;
253            try
254            {
255                if (!string.IsNullOrEmpty(agentName))
256                {
257                    hInternet = NativeMethods.InternetOpen(
258                        agentName,
259                        (int)INTERNET_OPEN_TYPE.INTERNET_OPEN_TYPE_DIRECT,
260                        null,
261                        null,
262                        0);
263                }
264
265                return RestoreSystemProxyInternal(hInternet);
266            }
267            finally
268            {
269                if (hInternet != IntPtr.Zero)
270                {
271                    NativeMethods.InternetCloseHandle(hInternet);
272                }
273            }
274        }
275
276        /// <summary>
277        /// Restore to the system proxy settings.
278        /// </summary>
279        static bool RestoreSystemProxyInternal(IntPtr hInternet)
280        {
281            var request = GetSystemProxy();
282
283            int size = Marshal.SizeOf(request);
284
285            // Allocate memory. 
286            IntPtr intptrStruct = Marshal.AllocCoTaskMem(size);
287
288            // Convert structure to IntPtr 
289            Marshal.StructureToPtr(request, intptrStruct, true);
290
291            // Set internet options.
292            bool bReturn = NativeMethods.InternetSetOption(
293                hInternet,
294                INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION,
295                intptrStruct,
296                size);
297
298            // Free the allocated memory.
299            Marshal.FreeCoTaskMem(request.pOptions);
300            Marshal.FreeCoTaskMem(intptrStruct);
301
302            if (!bReturn)
303            {
304                throw new ApplicationException(" Set Internet Option Failed! ");
305            }
306
307            // Notify the system that the registry settings have been changed and cause
308            // the proxy data to be reread from the registry for a handle.
309            NativeMethods.InternetSetOption(
310                hInternet,
311                INTERNET_OPTION.INTERNET_OPTION_SETTINGS_CHANGED,
312                IntPtr.Zero,
313                0);
314
315            NativeMethods.InternetSetOption(
316                hInternet,
317                INTERNET_OPTION.INTERNET_OPTION_REFRESH,
318                IntPtr.Zero,
319                0);
320            return bReturn;
321        }
322    }
323}