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
- PtsHelper.cs
- RegularExpressionValidator.cs
- ExceptionValidationRule.cs
- SocketInformation.cs
- CursorConverter.cs
- AnimationClock.cs
- CompilerTypeWithParams.cs
- XAMLParseException.cs
- ComboBox.cs
- Point4DValueSerializer.cs
- DataReceivedEventArgs.cs
- UnsafeNativeMethods.cs
- HttpHandlersSection.cs
- XmlAttributeOverrides.cs
- Reference.cs
- SortedDictionary.cs
- LogEntryHeaderSerializer.cs
- WaitHandle.cs
- EtwTrace.cs
- Region.cs
- SpeakInfo.cs
- FileDialogCustomPlace.cs
- MemberPathMap.cs
- ClientData.cs
- EventHandlerList.cs
- DataDesignUtil.cs
- GeometryDrawing.cs
- SerializationStore.cs
- ZipIOLocalFileHeader.cs
- HasCopySemanticsAttribute.cs
- EncoderBestFitFallback.cs
- xmlfixedPageInfo.cs
- SqlDataAdapter.cs
- HyperLinkStyle.cs
- PowerStatus.cs
- AuthenticationModuleElement.cs
- TitleStyle.cs
- ViewManager.cs
- BitmapEffectCollection.cs
- SchemaMapping.cs
- SkewTransform.cs
- DesignTimeParseData.cs
- KeyValuePairs.cs
- ListBindableAttribute.cs
- CrossSiteScriptingValidation.cs
- Table.cs
- DirectoryInfo.cs
- BitmapSourceSafeMILHandle.cs
- OleDbSchemaGuid.cs
- IOException.cs
- BuilderPropertyEntry.cs
- ConfigurationElementCollection.cs
- ExpressionBuilderCollection.cs
- CodeEventReferenceExpression.cs
- MailWebEventProvider.cs
- CodeSnippetExpression.cs
- complextypematerializer.cs
- UnitySerializationHolder.cs
- infer.cs
- DependencyPropertyAttribute.cs
- ButtonRenderer.cs
- DataGridViewRowStateChangedEventArgs.cs
- AttributeTable.cs
- TreeNodeSelectionProcessor.cs
- ArglessEventHandlerProxy.cs
- PrintingPermission.cs
- NumericExpr.cs
- HtmlInputCheckBox.cs
- TabRenderer.cs
- OracleRowUpdatedEventArgs.cs
- EntitySetBaseCollection.cs
- HtmlInputControl.cs
- DefaultTextStore.cs
- HtmlSelect.cs
- RegexCompilationInfo.cs
- HMACSHA512.cs
- ReadWriteSpinLock.cs
- MediaTimeline.cs
- OleDbPermission.cs
- DefaultTextStore.cs
- NavigatorInvalidBodyAccessException.cs
- MethodToken.cs
- TreeBuilder.cs
- DeviceContext2.cs
- BitmapCodecInfo.cs
- MinimizableAttributeTypeConverter.cs
- HttpVersion.cs
- SubclassTypeValidatorAttribute.cs
- Material.cs
- TransactionBridge.cs
- ISessionStateStore.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- ColorAnimation.cs
- SchemaCollectionCompiler.cs
- filewebresponse.cs
- QuaternionKeyFrameCollection.cs
- OdbcException.cs
- OpCellTreeNode.cs
- ReflectionPermission.cs
- ContentElementAutomationPeer.cs