Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / _ProxyRegBlob.cs / 2 / _ProxyRegBlob.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System; using System.Security.Permissions; using System.Globalization; using System.Text; using System.Text.RegularExpressions; using System.Collections; using System.Collections.Specialized; using System.Net.Sockets; using System.Threading; using System.Runtime.InteropServices; #if USE_WINIET_AUTODETECT_CACHE #if !FEATURE_PAL using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; #endif // !FEATURE_PAL #endif using Microsoft.Win32; using System.Runtime.Versioning; internal class ProxyRegBlob { #if !FEATURE_PAL // // Allows us to grob through the registry and read the // IE binary format, note that this should be replaced, // by code that calls Wininet directly, but it can be // expensive to load wininet, in order to do this. // [Flags] private enum ProxyTypeFlags { PROXY_TYPE_DIRECT = 0x00000001, // direct to net PROXY_TYPE_PROXY = 0x00000002, // via named proxy PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL PROXY_TYPE_AUTO_DETECT = 0x00000008, // use autoproxy detection } internal const string PolicyKey = @"SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings"; internal const string ProxyKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"; private const string DefaultConnectionSettings = "DefaultConnectionSettings"; private const string ProxySettingsPerUser = "ProxySettingsPerUser"; #if USE_WINIET_AUTODETECT_CACHE // Get the number of MilliSeconds in 7 days and then multiply by 10 because // FILETIME stores data stores time in 100-nanosecond intervals. // internal static UInt64 s_lkgScriptValidTime = (UInt64)(new TimeSpan(7, 0, 0, 0).Ticks); // 7 days #endif const int IE50StrucSize = 60; private byte[] m_RegistryBytes; private int m_ByteOffset; // returns true - on successful read of proxy registry settings [RegistryPermission(SecurityAction.Assert, Read=@"HKEY_LOCAL_MACHINE\" + PolicyKey)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private bool ReadRegSettings(string connectoid, SafeRegistryHandle hkcu) { SafeRegistryHandle key = null; RegistryKey lmKey = null; try { bool isPerUser = true; lmKey = Registry.LocalMachine.OpenSubKey(PolicyKey); if (lmKey != null) { object perUser = lmKey.GetValue(ProxySettingsPerUser); if (perUser != null && perUser.GetType() == typeof(int) && 0 == (int) perUser) { isPerUser = false; } } uint errorCode; if (isPerUser) { if (hkcu != null) { errorCode = hkcu.RegOpenKeyEx(ProxyKey, 0, UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out key); } else { errorCode = UnsafeNclNativeMethods.ErrorCodes.ERROR_NOT_FOUND; } } else { errorCode = SafeRegistryHandle.RegOpenKeyEx(UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE, ProxyKey, 0, UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out key); } if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { key = null; } if (key != null) { // When reading settings from the registry, if connectoid key is missing, the connectoid // was never configured. In this case we have no settings (this is equivalent to always go direct). object data; errorCode = key.QueryValue(connectoid != null ? connectoid : DefaultConnectionSettings, out data); if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { m_RegistryBytes = (byte[]) data; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; } finally { if (lmKey != null) lmKey.Close(); if(key != null) key.RegCloseKey(); } return m_RegistryBytes != null; } #if USE_WINIET_AUTODETECT_CACHE public FILETIME ReadFileTime() { FILETIME ft = new FILETIME(); ft.dwLowDateTime = ReadInt32(); ft.dwHighDateTime = ReadInt32(); return ft; } #endif // // Reads a string from the byte buffer, cached // inside this object, and then updates the // offset, NOTE: Must be in the correct offset // before reading, or will error // public string ReadString() { string stringOut = null; int stringSize = ReadInt32(); if (stringSize>0) { // prevent reading too much int actualSize = m_RegistryBytes.Length - m_ByteOffset; if (stringSize >= actualSize) { stringSize = actualSize; } stringOut = Encoding.UTF8.GetString(m_RegistryBytes, m_ByteOffset, stringSize); m_ByteOffset += stringSize; } return stringOut; } // // Reads a DWORD into a Int32, used to read // a int from the byte buffer. // internal unsafe int ReadInt32() { int intValue = 0; int actualSize = m_RegistryBytes.Length - m_ByteOffset; // copy bytes and increment offset if (actualSize>=sizeof(int)) { fixed (byte* pBuffer = m_RegistryBytes) { if (sizeof(IntPtr)==4) { intValue = *((int*)(pBuffer + m_ByteOffset)); } else { intValue = Marshal.ReadInt32((IntPtr)pBuffer, m_ByteOffset); } } m_ByteOffset += sizeof(int); } // tell caller what we actually read return intValue; } #else // !FEATURE_PAL private static string ReadConfigString(string ConfigName) { const int parameterValueLength = 255; StringBuilder parameterValue = new StringBuilder(parameterValueLength); bool rc = UnsafeNclNativeMethods.FetchConfigurationString(true, ConfigName, parameterValue, parameterValueLength); if (rc) { return parameterValue.ToString(); } return ""; } #endif // !FEATURE_PAL // // Parses out a string from IE and turns it into a URI // private static Uri ParseProxyUri(string proxyString, bool validate) { if (validate) { if (proxyString.Length == 0) { return null; } if (proxyString.IndexOf('=') != -1) { return null; } } if (proxyString.IndexOf("://") == -1) { proxyString = "http://" + proxyString; } return new Uri(proxyString); } // // Builds a hashtable containing the protocol and proxy URI to use for it. // private static Hashtable ParseProtocolProxies(string proxyListString) { if (proxyListString.Length == 0) { return null; } // parse something like "http=http://http-proxy;https=http://https-proxy;ftp=http://ftp-proxy" char[] splitChars = new char[] { ';', '=' }; string[] proxyListStrings = proxyListString.Split(splitChars); bool protocolPass = true; string protocolString = null; Hashtable proxyListHashTable = new Hashtable(CaseInsensitiveAscii.StaticInstance); foreach (string elementString in proxyListStrings) { string elementString2 = elementString.Trim().ToLower(CultureInfo.InvariantCulture); if (protocolPass) { protocolString = elementString2; } else { proxyListHashTable[protocolString] = ParseProxyUri(elementString2, false); } protocolPass = !protocolPass; } if (proxyListHashTable.Count == 0) { return null; } return proxyListHashTable; } // // Converts a simple IE regular expresion string into one // that is compatible with Regex escape sequences. // private static string BypassStringEscape(string rawString) { // Break up raw string into scheme, host, port. // This regular expression is used to get the three components. // Scheme and port are optional. // If Match fails just assume whole string is the host. Regex parser = new Regex("^(?.*://)?(? [^:]*)(? :[0-9]{1,5})?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); Match results = parser.Match(rawString); string scheme, host, port; if (results.Success) { scheme = results.Groups["scheme"].Value; host = results.Groups["host"].Value; port = results.Groups["port"].Value; } else { // Match method failed - set host to whole bypass string scheme = string.Empty; host = rawString; port = string.Empty; } // Escape any regex reserved chars before constructing final regex. scheme = ConvertRegexReservedChars(scheme); host = ConvertRegexReservedChars(host); port = ConvertRegexReservedChars(port); // If scheme or port not specified use regular // expression "wildcards" for them. if (scheme == string.Empty) { // match any leading scheme plus separator // but don't require it scheme = "(?:.*://)?"; } if (port == string.Empty) { // match a port but don't require it port = "(?::[0-9]{1,5})?"; } // Construct and return final regular expression // with start-of-line and end-of-line anchors. return "^" + scheme + host + port + "$"; } private const string regexReserved = "#$()+.?[\\^{|"; private static string ConvertRegexReservedChars(string rawString) { // Regular expressions reserve // (1) "#$()+.?[\^{|" as special chars. // (2) "*" as a special char. // (3) whitespace as a special char. // Convert any char "c" in above list to "\c". // Convert reserved char "*" to ".*". // Leave whitespace as-is. if (rawString.Length == 0) return rawString; StringBuilder builder = new StringBuilder(); foreach (char c in rawString) { if (regexReserved.IndexOf(c) != -1) { builder.Append('\\'); } else if (c == '*') { builder.Append('.'); } builder.Append(c); } return builder.ToString(); } // // Parses out a string of bypass list entries and coverts it to Regex's that can be used // to match against. // private static ArrayList ParseBypassList(string bypassListString, out bool bypassOnLocal) { char[] splitChars = new char[] {';'}; string[] bypassListStrings = bypassListString.Split(splitChars); bypassOnLocal = false; if (bypassListStrings.Length == 0) { return null; } ArrayList bypassList = null; foreach (string bypassString in bypassListStrings) { if (bypassString!=null) { string bypassString2 = bypassString.Trim(); if (bypassString2.Length>0) { if (string.Compare(bypassString2, " ", StringComparison.OrdinalIgnoreCase)==0) { bypassOnLocal = true; } else { bypassString2 = BypassStringEscape(bypassString2); if (bypassList==null) { bypassList = new ArrayList(); } GlobalLog.Print("ProxyRegBlob::ParseBypassList() bypassList.Count:" + bypassList.Count + " adding:" + ValidationHelper.ToString(bypassString2)); if (!bypassList.Contains(bypassString2)) { bypassList.Add(bypassString2); GlobalLog.Print("ProxyRegBlob::ParseBypassList() bypassList.Count:" + bypassList.Count + " added:" + ValidationHelper.ToString(bypassString2)); } } } } } return bypassList; } // // Updates an instance of WbeProxy with the proxy settings from IE for: // the current user and a given connectoid. // [ResourceExposure(ResourceScope.Machine)] // Check scoping on this SafeRegistryHandle [ResourceConsumption(ResourceScope.Machine)] #if !FEATURE_PAL internal static WebProxyData GetWebProxyData(string connectoid, SafeRegistryHandle hkcu) #else // !FEATURE_PAL internal static WebProxyData GetWebProxyData(string connectoid) #endif // !FEATURE_PAL { GlobalLog.Print("ProxyRegBlob::GetWebProxyData() connectoid:" + ValidationHelper.ToString(connectoid)); WebProxyData webProxyData = new WebProxyData(); Hashtable proxyHashTable = null; Uri address = null; #if !FEATURE_PAL ProxyRegBlob proxyIE5Settings = new ProxyRegBlob(); // DON'T TOUCH THE ORDERING OF THE CALLS TO THE INSTANCE OF ProxyRegBlob bool success = proxyIE5Settings.ReadRegSettings(connectoid, hkcu); if (success) { success = proxyIE5Settings.ReadInt32()>=ProxyRegBlob.IE50StrucSize; } if (!success) { // if registry access fails rely on automatic detection webProxyData.automaticallyDetectSettings = true; return webProxyData; } // read the rest of the items out proxyIE5Settings.ReadInt32(); // incremental version# of current settings (ignored) ProxyTypeFlags proxyFlags = (ProxyTypeFlags)proxyIE5Settings.ReadInt32(); // flags GlobalLog.Print("ProxyRegBlob::GetWebProxyData() proxyFlags:" + ValidationHelper.ToString(proxyFlags)); string addressString = proxyIE5Settings.ReadString(); // proxy name string proxyBypassString = proxyIE5Settings.ReadString(); // proxy bypass GlobalLog.Print("ProxyRegBlob::GetWebProxyData() proxyAddressString:" + ValidationHelper.ToString(addressString) + " proxyBypassString:" + ValidationHelper.ToString(proxyBypassString)); // // Once we verify that the flag for proxy is enabled, // Parse UriString that is stored, may be in the form, // of "http=http://http-proxy;ftp="ftp=http://..." must // handle this case along with just a URI. // if ((proxyFlags & ProxyTypeFlags.PROXY_TYPE_PROXY)!=0) { try { //VSWHIDBEY: 583058 //When the "manual" proxy check box is checked and there is no proxy string //present, the ReadString above returns null. //Which means thet when we call the ParseProxyUri, there will be an //Aceess Violation since we try to compute the length of the string //The fix is to not do any more processing if the addresString is null if(addressString != null) { address = ParseProxyUri(addressString, true); if ( address == null ) { proxyHashTable = ParseProtocolProxies(addressString); } if ((address != null || proxyHashTable != null) && proxyBypassString != null) { // reuse success for bypassOnLocal webProxyData.bypassList = ParseBypassList(proxyBypassString, out success); webProxyData.bypassOnLocal = success; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; } } #else // !FEATURE_PAL string proxyAddressString = ReadConfigString("ProxyUri"); string proxyBypassString = ReadConfigString("ProxyBypass"); try { if(proxyAddressString != null) { address = ParseProxyUri(proxyAddressString, true); if ( address == null ) { proxyHashTable = ParseProtocolProxies(proxyAddressString); } if ((address != null || proxyHashTable != null) && proxyBypassString != null ) { webProxyData.bypassList = ParseBypassList(proxyBypassString, out webProxyData.bypassOnLocal); } } // success if we reach here } catch { } #endif // !FEATURE_PAL if (proxyHashTable!=null) { address = proxyHashTable["http"] as Uri; } webProxyData.proxyAddress = address; #if !FEATURE_PAL webProxyData.automaticallyDetectSettings = (proxyFlags & ProxyTypeFlags.PROXY_TYPE_AUTO_DETECT)!=0; // reuse addressString for scriptLocationString addressString = proxyIE5Settings.ReadString(); // autoconfig url GlobalLog.Print("ProxyRegBlob::GetWebProxyData() scriptLocation:" + ValidationHelper.ToString(addressString)); if ((proxyFlags & ProxyTypeFlags.PROXY_TYPE_AUTO_PROXY_URL)!=0) { // reuse addressString for scriptLocation if (Uri.TryCreate(addressString, UriKind.Absolute, out address)) { webProxyData.scriptLocation = address; } } // The final straw against attempting to use the WinInet LKG script location was, it's invalid when IPs have changed even if the // connectoid hadn't. Doing that validation didn't seem worth it (error-prone, expensive, unsupported). #if USE_WINIET_AUTODETECT_CACHE proxyIE5Settings.ReadInt32(); // autodetect flags (ignored) // reuse addressString for lkgScriptLocationString addressString = proxyIE5Settings.ReadString(); // last known good auto-proxy url // read ftLastKnownDetectTime FILETIME ftLastKnownDetectTime = proxyIE5Settings.ReadFileTime(); // Verify if this lkgScriptLocationString has timed out // if (IsValidTimeForLkgScriptLocation(ftLastKnownDetectTime)) { // reuse address for lkgScriptLocation GlobalLog.Print("ProxyRegBlob::GetWebProxyData() lkgScriptLocation:" + ValidationHelper.ToString(addressString)); if (Uri.TryCreate(addressString, UriKind.Absolute, out address)) { webProxyData.lkgScriptLocation = address; } } else { #if TRAVE SYSTEMTIME st = new SYSTEMTIME(); bool f = SafeNclNativeMethods.FileTimeToSystemTime(ref ftLastKnownDetectTime, ref st); if (f) GlobalLog.Print("ProxyRegBlob::GetWebProxyData() ftLastKnownDetectTime:" + ValidationHelper.ToString(st)); #endif // TRAVE GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Ignoring Timed out lkgScriptLocation:" + ValidationHelper.ToString(addressString)); // Now rely on automatic detection settings set above // based on the proxy flags (webProxyData.automaticallyDetectSettings). // } #endif /* // This is some of the rest of the proxy reg key blob parsing. // // Read Inte---- IPs int iftCount = proxyIE5Settings.ReadInt32(); for (int ift = 0; ift < iftCount; ++ift) { proxyIE5Settings.ReadInt32(); } // Read lpszAutoconfigSecondaryUrl string autoconfigSecondaryUrl = proxyIE5Settings.ReadString(); // Read dwAutoconfigReloadDelayMins int autoconfigReloadDelayMins = proxyIE5Settings.ReadInt32(); */ #endif return webProxyData; } #if USE_WINIET_AUTODETECT_CACHE #if !FEATURE_PAL internal unsafe static bool IsValidTimeForLkgScriptLocation(FILETIME ftLastKnownDetectTime) { // Get Current System Time. FILETIME ftCurrentTime = new FILETIME(); SafeNclNativeMethods.GetSystemTimeAsFileTime(ref ftCurrentTime); UInt64 ftDetect = (UInt64)ftLastKnownDetectTime.dwHighDateTime; ftDetect <<= (sizeof(int) * 8); ftDetect |= (UInt64)(uint)ftLastKnownDetectTime.dwLowDateTime; UInt64 ftCurrent = (UInt64)ftCurrentTime.dwHighDateTime; ftCurrent <<= (sizeof(int) * 8); ftCurrent |= (UInt64)(uint)ftCurrentTime.dwLowDateTime; GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Detect Time:" + ValidationHelper.ToString(ftDetect)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Current Time:" + ValidationHelper.ToString(ftCurrent)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() 7 days:" + ValidationHelper.ToString(s_lkgScriptValidTime)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Delta Time:" + ValidationHelper.ToString((UInt64)(ftCurrent - ftDetect))); return (ftCurrent - ftDetect) < s_lkgScriptValidTime; } #endif // !FEATURE_PAL #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System; using System.Security.Permissions; using System.Globalization; using System.Text; using System.Text.RegularExpressions; using System.Collections; using System.Collections.Specialized; using System.Net.Sockets; using System.Threading; using System.Runtime.InteropServices; #if USE_WINIET_AUTODETECT_CACHE #if !FEATURE_PAL using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; #endif // !FEATURE_PAL #endif using Microsoft.Win32; using System.Runtime.Versioning; internal class ProxyRegBlob { #if !FEATURE_PAL // // Allows us to grob through the registry and read the // IE binary format, note that this should be replaced, // by code that calls Wininet directly, but it can be // expensive to load wininet, in order to do this. // [Flags] private enum ProxyTypeFlags { PROXY_TYPE_DIRECT = 0x00000001, // direct to net PROXY_TYPE_PROXY = 0x00000002, // via named proxy PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL PROXY_TYPE_AUTO_DETECT = 0x00000008, // use autoproxy detection } internal const string PolicyKey = @"SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings"; internal const string ProxyKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"; private const string DefaultConnectionSettings = "DefaultConnectionSettings"; private const string ProxySettingsPerUser = "ProxySettingsPerUser"; #if USE_WINIET_AUTODETECT_CACHE // Get the number of MilliSeconds in 7 days and then multiply by 10 because // FILETIME stores data stores time in 100-nanosecond intervals. // internal static UInt64 s_lkgScriptValidTime = (UInt64)(new TimeSpan(7, 0, 0, 0).Ticks); // 7 days #endif const int IE50StrucSize = 60; private byte[] m_RegistryBytes; private int m_ByteOffset; // returns true - on successful read of proxy registry settings [RegistryPermission(SecurityAction.Assert, Read=@"HKEY_LOCAL_MACHINE\" + PolicyKey)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private bool ReadRegSettings(string connectoid, SafeRegistryHandle hkcu) { SafeRegistryHandle key = null; RegistryKey lmKey = null; try { bool isPerUser = true; lmKey = Registry.LocalMachine.OpenSubKey(PolicyKey); if (lmKey != null) { object perUser = lmKey.GetValue(ProxySettingsPerUser); if (perUser != null && perUser.GetType() == typeof(int) && 0 == (int) perUser) { isPerUser = false; } } uint errorCode; if (isPerUser) { if (hkcu != null) { errorCode = hkcu.RegOpenKeyEx(ProxyKey, 0, UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out key); } else { errorCode = UnsafeNclNativeMethods.ErrorCodes.ERROR_NOT_FOUND; } } else { errorCode = SafeRegistryHandle.RegOpenKeyEx(UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE, ProxyKey, 0, UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out key); } if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { key = null; } if (key != null) { // When reading settings from the registry, if connectoid key is missing, the connectoid // was never configured. In this case we have no settings (this is equivalent to always go direct). object data; errorCode = key.QueryValue(connectoid != null ? connectoid : DefaultConnectionSettings, out data); if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { m_RegistryBytes = (byte[]) data; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; } finally { if (lmKey != null) lmKey.Close(); if(key != null) key.RegCloseKey(); } return m_RegistryBytes != null; } #if USE_WINIET_AUTODETECT_CACHE public FILETIME ReadFileTime() { FILETIME ft = new FILETIME(); ft.dwLowDateTime = ReadInt32(); ft.dwHighDateTime = ReadInt32(); return ft; } #endif // // Reads a string from the byte buffer, cached // inside this object, and then updates the // offset, NOTE: Must be in the correct offset // before reading, or will error // public string ReadString() { string stringOut = null; int stringSize = ReadInt32(); if (stringSize>0) { // prevent reading too much int actualSize = m_RegistryBytes.Length - m_ByteOffset; if (stringSize >= actualSize) { stringSize = actualSize; } stringOut = Encoding.UTF8.GetString(m_RegistryBytes, m_ByteOffset, stringSize); m_ByteOffset += stringSize; } return stringOut; } // // Reads a DWORD into a Int32, used to read // a int from the byte buffer. // internal unsafe int ReadInt32() { int intValue = 0; int actualSize = m_RegistryBytes.Length - m_ByteOffset; // copy bytes and increment offset if (actualSize>=sizeof(int)) { fixed (byte* pBuffer = m_RegistryBytes) { if (sizeof(IntPtr)==4) { intValue = *((int*)(pBuffer + m_ByteOffset)); } else { intValue = Marshal.ReadInt32((IntPtr)pBuffer, m_ByteOffset); } } m_ByteOffset += sizeof(int); } // tell caller what we actually read return intValue; } #else // !FEATURE_PAL private static string ReadConfigString(string ConfigName) { const int parameterValueLength = 255; StringBuilder parameterValue = new StringBuilder(parameterValueLength); bool rc = UnsafeNclNativeMethods.FetchConfigurationString(true, ConfigName, parameterValue, parameterValueLength); if (rc) { return parameterValue.ToString(); } return ""; } #endif // !FEATURE_PAL // // Parses out a string from IE and turns it into a URI // private static Uri ParseProxyUri(string proxyString, bool validate) { if (validate) { if (proxyString.Length == 0) { return null; } if (proxyString.IndexOf('=') != -1) { return null; } } if (proxyString.IndexOf("://") == -1) { proxyString = "http://" + proxyString; } return new Uri(proxyString); } // // Builds a hashtable containing the protocol and proxy URI to use for it. // private static Hashtable ParseProtocolProxies(string proxyListString) { if (proxyListString.Length == 0) { return null; } // parse something like "http=http://http-proxy;https=http://https-proxy;ftp=http://ftp-proxy" char[] splitChars = new char[] { ';', '=' }; string[] proxyListStrings = proxyListString.Split(splitChars); bool protocolPass = true; string protocolString = null; Hashtable proxyListHashTable = new Hashtable(CaseInsensitiveAscii.StaticInstance); foreach (string elementString in proxyListStrings) { string elementString2 = elementString.Trim().ToLower(CultureInfo.InvariantCulture); if (protocolPass) { protocolString = elementString2; } else { proxyListHashTable[protocolString] = ParseProxyUri(elementString2, false); } protocolPass = !protocolPass; } if (proxyListHashTable.Count == 0) { return null; } return proxyListHashTable; } // // Converts a simple IE regular expresion string into one // that is compatible with Regex escape sequences. // private static string BypassStringEscape(string rawString) { // Break up raw string into scheme, host, port. // This regular expression is used to get the three components. // Scheme and port are optional. // If Match fails just assume whole string is the host. Regex parser = new Regex("^(?.*://)?(? [^:]*)(? :[0-9]{1,5})?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); Match results = parser.Match(rawString); string scheme, host, port; if (results.Success) { scheme = results.Groups["scheme"].Value; host = results.Groups["host"].Value; port = results.Groups["port"].Value; } else { // Match method failed - set host to whole bypass string scheme = string.Empty; host = rawString; port = string.Empty; } // Escape any regex reserved chars before constructing final regex. scheme = ConvertRegexReservedChars(scheme); host = ConvertRegexReservedChars(host); port = ConvertRegexReservedChars(port); // If scheme or port not specified use regular // expression "wildcards" for them. if (scheme == string.Empty) { // match any leading scheme plus separator // but don't require it scheme = "(?:.*://)?"; } if (port == string.Empty) { // match a port but don't require it port = "(?::[0-9]{1,5})?"; } // Construct and return final regular expression // with start-of-line and end-of-line anchors. return "^" + scheme + host + port + "$"; } private const string regexReserved = "#$()+.?[\\^{|"; private static string ConvertRegexReservedChars(string rawString) { // Regular expressions reserve // (1) "#$()+.?[\^{|" as special chars. // (2) "*" as a special char. // (3) whitespace as a special char. // Convert any char "c" in above list to "\c". // Convert reserved char "*" to ".*". // Leave whitespace as-is. if (rawString.Length == 0) return rawString; StringBuilder builder = new StringBuilder(); foreach (char c in rawString) { if (regexReserved.IndexOf(c) != -1) { builder.Append('\\'); } else if (c == '*') { builder.Append('.'); } builder.Append(c); } return builder.ToString(); } // // Parses out a string of bypass list entries and coverts it to Regex's that can be used // to match against. // private static ArrayList ParseBypassList(string bypassListString, out bool bypassOnLocal) { char[] splitChars = new char[] {';'}; string[] bypassListStrings = bypassListString.Split(splitChars); bypassOnLocal = false; if (bypassListStrings.Length == 0) { return null; } ArrayList bypassList = null; foreach (string bypassString in bypassListStrings) { if (bypassString!=null) { string bypassString2 = bypassString.Trim(); if (bypassString2.Length>0) { if (string.Compare(bypassString2, " ", StringComparison.OrdinalIgnoreCase)==0) { bypassOnLocal = true; } else { bypassString2 = BypassStringEscape(bypassString2); if (bypassList==null) { bypassList = new ArrayList(); } GlobalLog.Print("ProxyRegBlob::ParseBypassList() bypassList.Count:" + bypassList.Count + " adding:" + ValidationHelper.ToString(bypassString2)); if (!bypassList.Contains(bypassString2)) { bypassList.Add(bypassString2); GlobalLog.Print("ProxyRegBlob::ParseBypassList() bypassList.Count:" + bypassList.Count + " added:" + ValidationHelper.ToString(bypassString2)); } } } } } return bypassList; } // // Updates an instance of WbeProxy with the proxy settings from IE for: // the current user and a given connectoid. // [ResourceExposure(ResourceScope.Machine)] // Check scoping on this SafeRegistryHandle [ResourceConsumption(ResourceScope.Machine)] #if !FEATURE_PAL internal static WebProxyData GetWebProxyData(string connectoid, SafeRegistryHandle hkcu) #else // !FEATURE_PAL internal static WebProxyData GetWebProxyData(string connectoid) #endif // !FEATURE_PAL { GlobalLog.Print("ProxyRegBlob::GetWebProxyData() connectoid:" + ValidationHelper.ToString(connectoid)); WebProxyData webProxyData = new WebProxyData(); Hashtable proxyHashTable = null; Uri address = null; #if !FEATURE_PAL ProxyRegBlob proxyIE5Settings = new ProxyRegBlob(); // DON'T TOUCH THE ORDERING OF THE CALLS TO THE INSTANCE OF ProxyRegBlob bool success = proxyIE5Settings.ReadRegSettings(connectoid, hkcu); if (success) { success = proxyIE5Settings.ReadInt32()>=ProxyRegBlob.IE50StrucSize; } if (!success) { // if registry access fails rely on automatic detection webProxyData.automaticallyDetectSettings = true; return webProxyData; } // read the rest of the items out proxyIE5Settings.ReadInt32(); // incremental version# of current settings (ignored) ProxyTypeFlags proxyFlags = (ProxyTypeFlags)proxyIE5Settings.ReadInt32(); // flags GlobalLog.Print("ProxyRegBlob::GetWebProxyData() proxyFlags:" + ValidationHelper.ToString(proxyFlags)); string addressString = proxyIE5Settings.ReadString(); // proxy name string proxyBypassString = proxyIE5Settings.ReadString(); // proxy bypass GlobalLog.Print("ProxyRegBlob::GetWebProxyData() proxyAddressString:" + ValidationHelper.ToString(addressString) + " proxyBypassString:" + ValidationHelper.ToString(proxyBypassString)); // // Once we verify that the flag for proxy is enabled, // Parse UriString that is stored, may be in the form, // of "http=http://http-proxy;ftp="ftp=http://..." must // handle this case along with just a URI. // if ((proxyFlags & ProxyTypeFlags.PROXY_TYPE_PROXY)!=0) { try { //VSWHIDBEY: 583058 //When the "manual" proxy check box is checked and there is no proxy string //present, the ReadString above returns null. //Which means thet when we call the ParseProxyUri, there will be an //Aceess Violation since we try to compute the length of the string //The fix is to not do any more processing if the addresString is null if(addressString != null) { address = ParseProxyUri(addressString, true); if ( address == null ) { proxyHashTable = ParseProtocolProxies(addressString); } if ((address != null || proxyHashTable != null) && proxyBypassString != null) { // reuse success for bypassOnLocal webProxyData.bypassList = ParseBypassList(proxyBypassString, out success); webProxyData.bypassOnLocal = success; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; } } #else // !FEATURE_PAL string proxyAddressString = ReadConfigString("ProxyUri"); string proxyBypassString = ReadConfigString("ProxyBypass"); try { if(proxyAddressString != null) { address = ParseProxyUri(proxyAddressString, true); if ( address == null ) { proxyHashTable = ParseProtocolProxies(proxyAddressString); } if ((address != null || proxyHashTable != null) && proxyBypassString != null ) { webProxyData.bypassList = ParseBypassList(proxyBypassString, out webProxyData.bypassOnLocal); } } // success if we reach here } catch { } #endif // !FEATURE_PAL if (proxyHashTable!=null) { address = proxyHashTable["http"] as Uri; } webProxyData.proxyAddress = address; #if !FEATURE_PAL webProxyData.automaticallyDetectSettings = (proxyFlags & ProxyTypeFlags.PROXY_TYPE_AUTO_DETECT)!=0; // reuse addressString for scriptLocationString addressString = proxyIE5Settings.ReadString(); // autoconfig url GlobalLog.Print("ProxyRegBlob::GetWebProxyData() scriptLocation:" + ValidationHelper.ToString(addressString)); if ((proxyFlags & ProxyTypeFlags.PROXY_TYPE_AUTO_PROXY_URL)!=0) { // reuse addressString for scriptLocation if (Uri.TryCreate(addressString, UriKind.Absolute, out address)) { webProxyData.scriptLocation = address; } } // The final straw against attempting to use the WinInet LKG script location was, it's invalid when IPs have changed even if the // connectoid hadn't. Doing that validation didn't seem worth it (error-prone, expensive, unsupported). #if USE_WINIET_AUTODETECT_CACHE proxyIE5Settings.ReadInt32(); // autodetect flags (ignored) // reuse addressString for lkgScriptLocationString addressString = proxyIE5Settings.ReadString(); // last known good auto-proxy url // read ftLastKnownDetectTime FILETIME ftLastKnownDetectTime = proxyIE5Settings.ReadFileTime(); // Verify if this lkgScriptLocationString has timed out // if (IsValidTimeForLkgScriptLocation(ftLastKnownDetectTime)) { // reuse address for lkgScriptLocation GlobalLog.Print("ProxyRegBlob::GetWebProxyData() lkgScriptLocation:" + ValidationHelper.ToString(addressString)); if (Uri.TryCreate(addressString, UriKind.Absolute, out address)) { webProxyData.lkgScriptLocation = address; } } else { #if TRAVE SYSTEMTIME st = new SYSTEMTIME(); bool f = SafeNclNativeMethods.FileTimeToSystemTime(ref ftLastKnownDetectTime, ref st); if (f) GlobalLog.Print("ProxyRegBlob::GetWebProxyData() ftLastKnownDetectTime:" + ValidationHelper.ToString(st)); #endif // TRAVE GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Ignoring Timed out lkgScriptLocation:" + ValidationHelper.ToString(addressString)); // Now rely on automatic detection settings set above // based on the proxy flags (webProxyData.automaticallyDetectSettings). // } #endif /* // This is some of the rest of the proxy reg key blob parsing. // // Read Inte---- IPs int iftCount = proxyIE5Settings.ReadInt32(); for (int ift = 0; ift < iftCount; ++ift) { proxyIE5Settings.ReadInt32(); } // Read lpszAutoconfigSecondaryUrl string autoconfigSecondaryUrl = proxyIE5Settings.ReadString(); // Read dwAutoconfigReloadDelayMins int autoconfigReloadDelayMins = proxyIE5Settings.ReadInt32(); */ #endif return webProxyData; } #if USE_WINIET_AUTODETECT_CACHE #if !FEATURE_PAL internal unsafe static bool IsValidTimeForLkgScriptLocation(FILETIME ftLastKnownDetectTime) { // Get Current System Time. FILETIME ftCurrentTime = new FILETIME(); SafeNclNativeMethods.GetSystemTimeAsFileTime(ref ftCurrentTime); UInt64 ftDetect = (UInt64)ftLastKnownDetectTime.dwHighDateTime; ftDetect <<= (sizeof(int) * 8); ftDetect |= (UInt64)(uint)ftLastKnownDetectTime.dwLowDateTime; UInt64 ftCurrent = (UInt64)ftCurrentTime.dwHighDateTime; ftCurrent <<= (sizeof(int) * 8); ftCurrent |= (UInt64)(uint)ftCurrentTime.dwLowDateTime; GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Detect Time:" + ValidationHelper.ToString(ftDetect)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Current Time:" + ValidationHelper.ToString(ftCurrent)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() 7 days:" + ValidationHelper.ToString(s_lkgScriptValidTime)); GlobalLog.Print("ProxyRegBlob::GetWebProxyData() Delta Time:" + ValidationHelper.ToString((UInt64)(ftCurrent - ftDetect))); return (ftCurrent - ftDetect) < s_lkgScriptValidTime; } #endif // !FEATURE_PAL #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SaveFileDialogDesigner.cs
- EqualityComparer.cs
- GlyphingCache.cs
- CommandDevice.cs
- JulianCalendar.cs
- EditingCoordinator.cs
- Span.cs
- PerformanceCounterTraceRecord.cs
- SecurityTokenResolver.cs
- XmlSchemaAny.cs
- ResourcesBuildProvider.cs
- AlphabeticalEnumConverter.cs
- CallContext.cs
- SR.cs
- MachineKeyConverter.cs
- InfoCardMetadataExchangeClient.cs
- HttpApplicationStateBase.cs
- mongolianshape.cs
- IdentityValidationException.cs
- FileDataSourceCache.cs
- SelectionItemPattern.cs
- XamlTypeMapper.cs
- ETagAttribute.cs
- DesignTimeTemplateParser.cs
- ListViewDeletedEventArgs.cs
- DataObjectAttribute.cs
- IOException.cs
- Decorator.cs
- Run.cs
- SqlVisitor.cs
- DataColumnMapping.cs
- unitconverter.cs
- TransactionContextValidator.cs
- SerializationInfo.cs
- Parser.cs
- DataGridViewCheckBoxColumn.cs
- SqlAliaser.cs
- MemberExpressionHelper.cs
- PathSegmentCollection.cs
- SafeNativeMethods.cs
- ObfuscationAttribute.cs
- MetadataArtifactLoaderCompositeFile.cs
- CustomBindingElementCollection.cs
- HelpEvent.cs
- DeploymentExceptionMapper.cs
- Panel.cs
- CookieParameter.cs
- XmlMemberMapping.cs
- RuntimeCompatibilityAttribute.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- ViewLoader.cs
- ConfigXmlComment.cs
- RenderTargetBitmap.cs
- Encoder.cs
- AutoFocusStyle.xaml.cs
- SqlConnectionHelper.cs
- SerializationFieldInfo.cs
- Activation.cs
- LookupBindingPropertiesAttribute.cs
- EventArgs.cs
- CodeSubDirectoriesCollection.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- RuntimeConfig.cs
- Vector3dCollection.cs
- AttachedAnnotation.cs
- CryptoConfig.cs
- XAMLParseException.cs
- Profiler.cs
- DatePickerDateValidationErrorEventArgs.cs
- DataGridViewCheckBoxCell.cs
- ResXResourceSet.cs
- DynamicVirtualDiscoSearcher.cs
- Attributes.cs
- EventNotify.cs
- MemberRestriction.cs
- ListenerElementsCollection.cs
- TransformedBitmap.cs
- FigureHelper.cs
- InvokePatternIdentifiers.cs
- DataFieldConverter.cs
- SQLStringStorage.cs
- FixedSOMImage.cs
- XmlILAnnotation.cs
- FormsAuthenticationModule.cs
- XmlStreamStore.cs
- PointLightBase.cs
- RSAPKCS1SignatureFormatter.cs
- WmlPhoneCallAdapter.cs
- StylusPointPropertyId.cs
- TextParaLineResult.cs
- RotateTransform3D.cs
- CodeValidator.cs
- shaperfactoryquerycacheentry.cs
- XmlValidatingReaderImpl.cs
- RequestDescription.cs
- ConcurrentQueue.cs
- Trace.cs
- AnimationException.cs
- CustomAttributeFormatException.cs
- BinaryCommonClasses.cs