Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / WinHttpWebProxyFinder.cs / 1305376 / WinHttpWebProxyFinder.cs
using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices; using Microsoft.Win32; using System.Runtime.CompilerServices; using System.Net.Configuration; namespace System.Net { // This class uses WinHttp APIs only to find, download and execute the PAC file. internal sealed class WinHttpWebProxyFinder : BaseWebProxyFinder { private SafeInternetHandle session; public WinHttpWebProxyFinder(AutoWebProxyScriptEngine engine) : base(engine) { // Don't specify a user agent and dont' specify proxy settings. This is the same behavior WinHttp // uses when downloading the PAC file. session = UnsafeNclNativeMethods.WinHttp.WinHttpOpen(null, UnsafeNclNativeMethods.WinHttp.AccessType.NoProxy, null, null, 0); // Don't throw on error, just log the error information. This is consistent with how auto-proxy // works: we never throw on error (discovery, download, execution errors). if (session == null || session.IsInvalid) { int errorCode = GetLastWin32Error(); if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_cant_open_session, errorCode)); } else { // The default download-timeout is 1 min. // WinHTTP will use the sum of all four timeouts provided in WinHttpSetTimeouts as the // actual timeout. Setting a value to 0 means "infinite". // Since we don't provide the ability to specify finegrained timeouts like WinHttp does, // we simply apply the configured timeout to all four WinHttp timeouts. int timeout = SettingsSectionInternal.Section.DownloadTimeout; if (!UnsafeNclNativeMethods.WinHttp.WinHttpSetTimeouts(session, timeout, timeout, timeout, timeout)) { // We weren't able to set the timeouts. Just log and continue. int errorCode = GetLastWin32Error(); if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_timeout_error, errorCode)); } } } public override bool GetProxies(Uri destination, out IListproxyList) { proxyList = null; if (session == null || session.IsInvalid) { return false; } if (State == AutoWebProxyState.UnrecognizedScheme) { // If a previous call already determined that we don't support the scheme of the script // location, then just return false. return false; } string proxyListString = null; // Set to auto-detect failed. In case auto-detect is turned off and a script-location is available // we'll try downloading the script from that location. int errorCode = (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed; // If auto-detect is turned on, try to execute DHCP/DNS query to get PAC file, then run the script if (Engine.AutomaticallyDetectSettings) { errorCode = GetProxies(destination, null, out proxyListString); if (errorCode == (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme) { // DHCP returned FILE or FTP scheme for the PAC file location: We should stop here // since this is not an error, but a feature WinHttp doesn't currently support. The // caller may be able to handle this case by using another WebProxyFinder. State = AutoWebProxyState.UnrecognizedScheme; return false; } } // If auto-detect failed or was turned off, and a config-script location is available, download // the script from that location and execute it. if ((Engine.AutomaticConfigurationScript != null) && (IsRecoverableAutoProxyError(errorCode))) { errorCode = GetProxies(destination, Engine.AutomaticConfigurationScript, out proxyListString); } State = GetStateFromErrorCode(errorCode); if (State == AutoWebProxyState.Completed) { if (string.IsNullOrEmpty(proxyListString)) { // In this case the PAC file execution returned "DIRECT", i.e. WinHttp returned // 'true' with a 'null' proxy string. This state is represented as a list // containing one element with value 'null'. proxyList = new string[1] { null }; } else { // WinHttp doesn't really clear all whitespaces. It does a pretty good job with // spaces, but e.g. tabs aren't removed. Therefore make sure all whitespaces get // removed. // Note: Even though the PAC script could use space characters as separators, // WinHttp will always use ';' as separator character. E.g. for the PAC result // "PROXY 192.168.0.1 PROXY 192.168.0.2" WinHttp will return "192.168.0.1;192.168.0.2". // WinHttp will also remove trailing ';'. proxyListString = RemoveWhitespaces(proxyListString); proxyList = proxyListString.Split(';'); } return true; } // We get here if something went wrong, or if neither auto-detect nor script-location // were turned on. return false; } public override void Abort() { // WinHttp doesn't support aborts. Therefore we can't do anything here. } protected override void Dispose(bool disposing) { if (disposing) { if (session != null && !session.IsInvalid) { session.Close(); } } } private int GetProxies(Uri destination, Uri scriptLocation, out string proxyListString) { int errorCode = 0; proxyListString = null; UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = new UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS(); // Always try to download the PAC file without authentication. If we turn auth. on, the WinHttp // service will create a new session for every request (performance/memory implications). // Therefore we only turn auto-logon on if it is really needed. autoProxyOptions.AutoLogonIfChallenged = false; if (scriptLocation == null) { // Use auto-discovery to find the script location. autoProxyOptions.Flags = UnsafeNclNativeMethods.WinHttp.AutoProxyFlags.AutoDetect; autoProxyOptions.AutoConfigUrl = null; autoProxyOptions.AutoDetectFlags = UnsafeNclNativeMethods.WinHttp.AutoDetectType.Dhcp | UnsafeNclNativeMethods.WinHttp.AutoDetectType.DnsA; } else { // Use the provided script location for the PAC file. autoProxyOptions.Flags = UnsafeNclNativeMethods.WinHttp.AutoProxyFlags.AutoProxyConfigUrl; autoProxyOptions.AutoConfigUrl = scriptLocation.ToString(); autoProxyOptions.AutoDetectFlags = UnsafeNclNativeMethods.WinHttp.AutoDetectType.None; } if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) { errorCode = GetLastWin32Error(); // If the PAC file can't be downloaded because auth. was required, we check if the // credentials are set; if so, then we try again using auto-logon. // Note that by default webProxy.Credentials will be null. The user needs to set // in the config file, in order for // webProxy.Credentials to be set to DefaultNetworkCredentials. if ((errorCode == (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.LoginFailure) && (Engine.Credentials != null)) { // Now we need to try again, this time by enabling auto-logon. autoProxyOptions.AutoLogonIfChallenged = true; if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) { errorCode = GetLastWin32Error(); } } if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_getproxy_failed, destination, errorCode)); } return errorCode; } private bool WinHttpGetProxyForUrl(string destination, ref UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out string proxyListString) { proxyListString = null; bool success = false; UnsafeNclNativeMethods.WinHttp.WINHTTP_PROXY_INFO proxyInfo = new UnsafeNclNativeMethods.WinHttp.WINHTTP_PROXY_INFO(); // Make sure the strings get cleaned up in a CER (thus unexpected exceptions, like // ThreadAbortException will not interrupt the execution of the finally block, and we'll not // leak resources). RuntimeHelpers.PrepareConstrainedRegions(); try { success = UnsafeNclNativeMethods.WinHttp.WinHttpGetProxyForUrl(session, destination, ref autoProxyOptions, out proxyInfo); if (success) { proxyListString = Marshal.PtrToStringUni(proxyInfo.Proxy); } } finally { Marshal.FreeHGlobal(proxyInfo.Proxy); Marshal.FreeHGlobal(proxyInfo.ProxyBypass); } return success; } private static int GetLastWin32Error() { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == NativeMethods.ERROR_NOT_ENOUGH_MEMORY) { throw new OutOfMemoryException(); } return errorCode; } private static bool IsRecoverableAutoProxyError(int errorCode) { GlobalLog.Assert(errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER, "WinHttpGetProxyForUrl() call: Error code 'Invalid parameter' should not be returned."); // According to WinHttp the following states can be considered "recoverable", i.e. // we should continue trying WinHttpGetProxyForUrl() with the provided script-location // (if available). switch ((UnsafeNclNativeMethods.WinHttp.ErrorCodes)errorCode) { case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AutoProxyServiceError: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.BadAutoProxyScript: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.LoginFailure: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.OperationCancelled: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.Timeout: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnableToDownloadScript: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme: return true; } return false; } private static AutoWebProxyState GetStateFromErrorCode(int errorCode) { if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { return AutoWebProxyState.Completed; } switch ((UnsafeNclNativeMethods.WinHttp.ErrorCodes)errorCode) { case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed: return AutoWebProxyState.DiscoveryFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnableToDownloadScript: return AutoWebProxyState.DownloadFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.BadAutoProxyScript: return AutoWebProxyState.CompilationFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme: return AutoWebProxyState.UnrecognizedScheme; default: // We don't know the exact cause of the failure. Set the state to compilation failure to // indicate that something went wrong. return AutoWebProxyState.CompilationFailure; } } private static string RemoveWhitespaces(string value) { StringBuilder result = new StringBuilder(); foreach (char c in value) { if (!char.IsWhiteSpace(c)) { result.Append(c); } } return result.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices; using Microsoft.Win32; using System.Runtime.CompilerServices; using System.Net.Configuration; namespace System.Net { // This class uses WinHttp APIs only to find, download and execute the PAC file. internal sealed class WinHttpWebProxyFinder : BaseWebProxyFinder { private SafeInternetHandle session; public WinHttpWebProxyFinder(AutoWebProxyScriptEngine engine) : base(engine) { // Don't specify a user agent and dont' specify proxy settings. This is the same behavior WinHttp // uses when downloading the PAC file. session = UnsafeNclNativeMethods.WinHttp.WinHttpOpen(null, UnsafeNclNativeMethods.WinHttp.AccessType.NoProxy, null, null, 0); // Don't throw on error, just log the error information. This is consistent with how auto-proxy // works: we never throw on error (discovery, download, execution errors). if (session == null || session.IsInvalid) { int errorCode = GetLastWin32Error(); if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_cant_open_session, errorCode)); } else { // The default download-timeout is 1 min. // WinHTTP will use the sum of all four timeouts provided in WinHttpSetTimeouts as the // actual timeout. Setting a value to 0 means "infinite". // Since we don't provide the ability to specify finegrained timeouts like WinHttp does, // we simply apply the configured timeout to all four WinHttp timeouts. int timeout = SettingsSectionInternal.Section.DownloadTimeout; if (!UnsafeNclNativeMethods.WinHttp.WinHttpSetTimeouts(session, timeout, timeout, timeout, timeout)) { // We weren't able to set the timeouts. Just log and continue. int errorCode = GetLastWin32Error(); if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_timeout_error, errorCode)); } } } public override bool GetProxies(Uri destination, out IList proxyList) { proxyList = null; if (session == null || session.IsInvalid) { return false; } if (State == AutoWebProxyState.UnrecognizedScheme) { // If a previous call already determined that we don't support the scheme of the script // location, then just return false. return false; } string proxyListString = null; // Set to auto-detect failed. In case auto-detect is turned off and a script-location is available // we'll try downloading the script from that location. int errorCode = (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed; // If auto-detect is turned on, try to execute DHCP/DNS query to get PAC file, then run the script if (Engine.AutomaticallyDetectSettings) { errorCode = GetProxies(destination, null, out proxyListString); if (errorCode == (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme) { // DHCP returned FILE or FTP scheme for the PAC file location: We should stop here // since this is not an error, but a feature WinHttp doesn't currently support. The // caller may be able to handle this case by using another WebProxyFinder. State = AutoWebProxyState.UnrecognizedScheme; return false; } } // If auto-detect failed or was turned off, and a config-script location is available, download // the script from that location and execute it. if ((Engine.AutomaticConfigurationScript != null) && (IsRecoverableAutoProxyError(errorCode))) { errorCode = GetProxies(destination, Engine.AutomaticConfigurationScript, out proxyListString); } State = GetStateFromErrorCode(errorCode); if (State == AutoWebProxyState.Completed) { if (string.IsNullOrEmpty(proxyListString)) { // In this case the PAC file execution returned "DIRECT", i.e. WinHttp returned // 'true' with a 'null' proxy string. This state is represented as a list // containing one element with value 'null'. proxyList = new string[1] { null }; } else { // WinHttp doesn't really clear all whitespaces. It does a pretty good job with // spaces, but e.g. tabs aren't removed. Therefore make sure all whitespaces get // removed. // Note: Even though the PAC script could use space characters as separators, // WinHttp will always use ';' as separator character. E.g. for the PAC result // "PROXY 192.168.0.1 PROXY 192.168.0.2" WinHttp will return "192.168.0.1;192.168.0.2". // WinHttp will also remove trailing ';'. proxyListString = RemoveWhitespaces(proxyListString); proxyList = proxyListString.Split(';'); } return true; } // We get here if something went wrong, or if neither auto-detect nor script-location // were turned on. return false; } public override void Abort() { // WinHttp doesn't support aborts. Therefore we can't do anything here. } protected override void Dispose(bool disposing) { if (disposing) { if (session != null && !session.IsInvalid) { session.Close(); } } } private int GetProxies(Uri destination, Uri scriptLocation, out string proxyListString) { int errorCode = 0; proxyListString = null; UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = new UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS(); // Always try to download the PAC file without authentication. If we turn auth. on, the WinHttp // service will create a new session for every request (performance/memory implications). // Therefore we only turn auto-logon on if it is really needed. autoProxyOptions.AutoLogonIfChallenged = false; if (scriptLocation == null) { // Use auto-discovery to find the script location. autoProxyOptions.Flags = UnsafeNclNativeMethods.WinHttp.AutoProxyFlags.AutoDetect; autoProxyOptions.AutoConfigUrl = null; autoProxyOptions.AutoDetectFlags = UnsafeNclNativeMethods.WinHttp.AutoDetectType.Dhcp | UnsafeNclNativeMethods.WinHttp.AutoDetectType.DnsA; } else { // Use the provided script location for the PAC file. autoProxyOptions.Flags = UnsafeNclNativeMethods.WinHttp.AutoProxyFlags.AutoProxyConfigUrl; autoProxyOptions.AutoConfigUrl = scriptLocation.ToString(); autoProxyOptions.AutoDetectFlags = UnsafeNclNativeMethods.WinHttp.AutoDetectType.None; } if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) { errorCode = GetLastWin32Error(); // If the PAC file can't be downloaded because auth. was required, we check if the // credentials are set; if so, then we try again using auto-logon. // Note that by default webProxy.Credentials will be null. The user needs to set // in the config file, in order for // webProxy.Credentials to be set to DefaultNetworkCredentials. if ((errorCode == (int)UnsafeNclNativeMethods.WinHttp.ErrorCodes.LoginFailure) && (Engine.Credentials != null)) { // Now we need to try again, this time by enabling auto-logon. autoProxyOptions.AutoLogonIfChallenged = true; if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) { errorCode = GetLastWin32Error(); } } if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_proxy_winhttp_getproxy_failed, destination, errorCode)); } return errorCode; } private bool WinHttpGetProxyForUrl(string destination, ref UnsafeNclNativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out string proxyListString) { proxyListString = null; bool success = false; UnsafeNclNativeMethods.WinHttp.WINHTTP_PROXY_INFO proxyInfo = new UnsafeNclNativeMethods.WinHttp.WINHTTP_PROXY_INFO(); // Make sure the strings get cleaned up in a CER (thus unexpected exceptions, like // ThreadAbortException will not interrupt the execution of the finally block, and we'll not // leak resources). RuntimeHelpers.PrepareConstrainedRegions(); try { success = UnsafeNclNativeMethods.WinHttp.WinHttpGetProxyForUrl(session, destination, ref autoProxyOptions, out proxyInfo); if (success) { proxyListString = Marshal.PtrToStringUni(proxyInfo.Proxy); } } finally { Marshal.FreeHGlobal(proxyInfo.Proxy); Marshal.FreeHGlobal(proxyInfo.ProxyBypass); } return success; } private static int GetLastWin32Error() { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == NativeMethods.ERROR_NOT_ENOUGH_MEMORY) { throw new OutOfMemoryException(); } return errorCode; } private static bool IsRecoverableAutoProxyError(int errorCode) { GlobalLog.Assert(errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER, "WinHttpGetProxyForUrl() call: Error code 'Invalid parameter' should not be returned."); // According to WinHttp the following states can be considered "recoverable", i.e. // we should continue trying WinHttpGetProxyForUrl() with the provided script-location // (if available). switch ((UnsafeNclNativeMethods.WinHttp.ErrorCodes)errorCode) { case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AutoProxyServiceError: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.BadAutoProxyScript: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.LoginFailure: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.OperationCancelled: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.Timeout: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnableToDownloadScript: case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme: return true; } return false; } private static AutoWebProxyState GetStateFromErrorCode(int errorCode) { if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { return AutoWebProxyState.Completed; } switch ((UnsafeNclNativeMethods.WinHttp.ErrorCodes)errorCode) { case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed: return AutoWebProxyState.DiscoveryFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnableToDownloadScript: return AutoWebProxyState.DownloadFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.BadAutoProxyScript: return AutoWebProxyState.CompilationFailure; case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme: return AutoWebProxyState.UnrecognizedScheme; default: // We don't know the exact cause of the failure. Set the state to compilation failure to // indicate that something went wrong. return AutoWebProxyState.CompilationFailure; } } private static string RemoveWhitespaces(string value) { StringBuilder result = new StringBuilder(); foreach (char c in value) { if (!char.IsWhiteSpace(c)) { result.Append(c); } } return result.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MachineKeySection.cs
- HttpVersion.cs
- Base64WriteStateInfo.cs
- IOThreadTimer.cs
- DataViewListener.cs
- DataGridDetailsPresenter.cs
- AccessDataSource.cs
- PolygonHotSpot.cs
- Boolean.cs
- WsatTransactionFormatter.cs
- WindowsListViewScroll.cs
- AmbiguousMatchException.cs
- PeerTransportElement.cs
- ObjectTypeMapping.cs
- CompositeScriptReferenceEventArgs.cs
- FrameworkPropertyMetadata.cs
- ItemContainerPattern.cs
- DesignerForm.cs
- AutomationTextAttribute.cs
- IdentitySection.cs
- XhtmlBasicTextBoxAdapter.cs
- UnSafeCharBuffer.cs
- IssuedTokenClientBehaviorsElement.cs
- GenericUriParser.cs
- HtmlInputSubmit.cs
- DataGridToolTip.cs
- TreeViewImageGenerator.cs
- SimpleType.cs
- TreeNodeStyleCollectionEditor.cs
- Variable.cs
- EtwTrace.cs
- PersonalizationAdministration.cs
- ActivityTypeResolver.xaml.cs
- httpapplicationstate.cs
- SystemIPInterfaceStatistics.cs
- HttpModulesSection.cs
- StringFunctions.cs
- SchemaNotation.cs
- DtdParser.cs
- HttpApplicationFactory.cs
- ContainerParaClient.cs
- XmlSchemaImporter.cs
- MailWebEventProvider.cs
- AggregatePushdown.cs
- DbProviderFactoriesConfigurationHandler.cs
- AllMembershipCondition.cs
- InvalidEnumArgumentException.cs
- ReliableInputConnection.cs
- ContextBase.cs
- LineInfo.cs
- MapPathBasedVirtualPathProvider.cs
- ToolStripManager.cs
- EventNotify.cs
- TypeProvider.cs
- SqlCacheDependencySection.cs
- ObjectStateFormatter.cs
- EnvelopedPkcs7.cs
- PassportAuthenticationEventArgs.cs
- Vector3DAnimationUsingKeyFrames.cs
- FullTextLine.cs
- StringValidator.cs
- Message.cs
- ImageMap.cs
- PatternMatcher.cs
- ClientEventManager.cs
- Exceptions.cs
- DataContractSerializerMessageContractImporter.cs
- GraphicsContext.cs
- BooleanStorage.cs
- HTMLTagNameToTypeMapper.cs
- TerminatorSinks.cs
- ImageAttributes.cs
- PropertiesTab.cs
- sitestring.cs
- BamlLocalizabilityResolver.cs
- Point3DConverter.cs
- PtsCache.cs
- NamespaceInfo.cs
- AsyncOperation.cs
- ResourceAssociationSet.cs
- CompositeDataBoundControl.cs
- MenuCommand.cs
- DataControlExtensions.cs
- ExpressionBuilder.cs
- AuthorizationSection.cs
- ContentType.cs
- DataRelationPropertyDescriptor.cs
- SecurityPolicySection.cs
- ExcludePathInfo.cs
- TabPage.cs
- WebEncodingValidator.cs
- VisualProxy.cs
- TdsParserHelperClasses.cs
- WebScriptEndpointElement.cs
- DebuggerService.cs
- ScrollViewerAutomationPeer.cs
- OuterGlowBitmapEffect.cs
- EndpointIdentityExtension.cs
- Set.cs
- AffineTransform3D.cs