Adding reference source for System.Net
[mono.git] / mcs / class / referencesource / System / net / System / Net / _WinHttpWebProxyDataBuilder.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 using System.Runtime.CompilerServices;
6
7 namespace System.Net
8 {
9     internal sealed class WinHttpWebProxyBuilder : WebProxyDataBuilder
10     {
11         protected override void BuildInternal()
12         {
13             GlobalLog.Enter("WinHttpWebProxyBuilder#" + ValidationHelper.HashString(this) + "::BuildInternal()");
14
15             UnsafeNclNativeMethods.WinHttp.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig =
16                 new UnsafeNclNativeMethods.WinHttp.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG();
17
18             // Make sure the native strings get freed, even if some unexpected exception occurs.
19             RuntimeHelpers.PrepareConstrainedRegions();
20             try
21             {
22                 if (UnsafeNclNativeMethods.WinHttp.WinHttpGetIEProxyConfigForCurrentUser(ref ieProxyConfig))
23                 {
24                     string proxy = null;
25                     string proxyByPass = null;
26                     string autoConfigUrl = null;
27
28                     proxy = Marshal.PtrToStringUni(ieProxyConfig.Proxy);
29                     proxyByPass = Marshal.PtrToStringUni(ieProxyConfig.ProxyBypass);
30                     autoConfigUrl = Marshal.PtrToStringUni(ieProxyConfig.AutoConfigUrl);
31
32                     // note that ieProxyConfig.Proxy will be null if "use a proxy server" flag is turned off, even if
33                     // the user specified a proxy address. When we read directly from the Registry we need to check
34                     // for ProxyTypeFlags.PROXY_TYPE_PROXY. WinHttp does this for us and if the flag is not set, 
35                     // ieProxyConfig.Proxy will be null.
36                     SetProxyAndBypassList(proxy, proxyByPass);
37
38                     SetAutoDetectSettings(ieProxyConfig.AutoDetect);
39
40                     // similar to comment above: ieProxyConfig.AutoConfigUrl will only be set if "automatically detect
41                     // settings" flag is set. We don't need to check ProxyTypeFlags.PROXY_TYPE_AUTO_PROXY_URL; WinHttp
42                     // takes care of it and sets AutoConfigUrl to null if the flag is not set, regardless of the actual
43                     // config script string.
44                     SetAutoProxyUrl(autoConfigUrl);
45                 }
46                 else
47                 {
48                     int errorCode = Marshal.GetLastWin32Error();
49
50                     if (errorCode == Microsoft.Win32.NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
51                     {
52                         throw new OutOfMemoryException();
53                     }
54
55                     // if API call fails, rely on automatic detection
56                     SetAutoDetectSettings(true);
57                 }
58             }
59             finally
60             {
61                 Marshal.FreeHGlobal(ieProxyConfig.Proxy);
62                 Marshal.FreeHGlobal(ieProxyConfig.ProxyBypass);
63                 Marshal.FreeHGlobal(ieProxyConfig.AutoConfigUrl);
64             }
65
66             GlobalLog.Leave("WinHttpWebProxyBuilder#" + ValidationHelper.HashString(this) + "::BuildInternal()");
67         }
68     }
69 }