Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / _NegotiateClient.cs / 1305376 / _NegotiateClient.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System.Diagnostics; using System.Collections; using System.Net.Sockets; using System.Security.Authentication.ExtendedProtection; using System.Security.Permissions; using System.Globalization; internal class NegotiateClient : ISessionAuthenticationModule { internal const string AuthType = "Negotiate"; private const string negotiateHeader = "Negotiate"; private const string negotiateSignature = "negotiate"; private const string nego2Header = "Nego2"; private const string nego2Signature = "nego2"; // we can't work on non-NT2K platforms or non Win, so we shut off, // NOTE this exception IS caught internally. public NegotiateClient() { if (!ComNetOS.IsWin2K) { throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required)); } } public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("NegotiateClient::Authenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()"); return DoAuthenticate(challenge, webRequest, credentials, false); } private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate) { GlobalLog.Print("NegotiateClient::DoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString()); GlobalLog.Assert(credentials != null, "NegotiateClient::DoAuthenticate()|credentials == null"); if (credentials == null) { return null; } HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::DoAuthenticate()|httpWebRequest == null"); GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NegotiateClient::DoAuthenticate()|httpWebRequest.ChallengedUri == null"); NTAuthentication authSession = null; string incoming = null; bool useNego2 = false; // In case of pre-auth we always use "Negotiate", never "Nego2". if (!preAuthenticate) { int index = GetSignatureIndex(challenge, out useNego2); if (index < 0) { return null; } int blobBegin = index + (useNego2 ? nego2Signature.Length : negotiateSignature.Length); // // there may be multiple challenges. If the next character after the // package name is not a comma then it is challenge data // if (challenge.Length > blobBegin && challenge[blobBegin] != ',') { ++blobBegin; } else { index = -1; } if (index >= 0 && challenge.Length > blobBegin) { // Strip other modules information in case of multiple challenges // i.e do not take ", NTLM" as part of the following Negotiate blob // Negotiate TlRMTVNTUAACAAAADgAOADgAAAA1wo ... MAbwBmAHQALgBjAG8AbQAAAAAA,NTLM index = challenge.IndexOf(',', blobBegin); if (index != -1) incoming = challenge.Substring(blobBegin, index - blobBegin); else incoming = challenge.Substring(blobBegin); } authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("NegotiateClient::DoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); } if (authSession==null) { // Credentials are always set for "Negotiate", never for "Nego2". A customer shouldn't even know // about "Nego2". NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, negotiateSignature); GlobalLog.Print("NegotiateClient::DoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); string username = string.Empty; if (NC == null || (!(NC is SystemNetworkCredential) && (username = NC.InternalGetUserName()).Length == 0)) { return null; } ICredentialPolicy policy = AuthenticationManager.CredentialPolicy; if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this)) return null; string spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); GlobalLog.Print("NegotiateClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( AuthType, NC, spn, httpWebRequest, binding); GlobalLog.Print("NegotiateClient::DoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession)); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this); } string clientResponse = authSession.GetOutgoingBlob(incoming); if (clientResponse==null) { return null; } bool canShareConnection = httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing; if (canShareConnection) { httpWebRequest.LockConnection = true; } // this is the first leg of an NTLM handshake, // set the NtlmKeepAlive override *STRICTLY* only in this case. httpWebRequest.NtlmKeepAlive = incoming==null && authSession.IsValidContext && !authSession.IsKerberos; // If we received a "Nego2" header value from the server, we'll respond with "Nego2" in the "Authorization" // header. If the server sent a "Negotiate" header value or if pre-authenticate is used (i.e. the auth blob // is sent with the first request), we send "Negotiate" in the "Authorization" header. return AuthenticationManager.GetGroupAuthorization(this, (useNego2 ? nego2Header : negotiateHeader) + " " + clientResponse, authSession.IsCompleted, authSession, canShareConnection, authSession.IsKerberos); } public bool CanPreAuthenticate { get { return true; } } public Authorization PreAuthenticate(WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("NegotiateClient::PreAuthenticate() webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()"); return DoAuthenticate(null, webRequest, credentials, true); } public string AuthenticationType { get { return AuthType; } } // // called when getting the final blob on the 200 OK from the server // public bool Update(string challenge, WebRequest webRequest) { GlobalLog.Print("NegotiateClient::Update(): " + challenge); HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::Update()|httpWebRequest == null"); GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NegotiateClient::Update()|httpWebRequest.ChallengedUri == null"); // // try to retrieve the state of the ongoing handshake // NTAuthentication authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("NegotiateClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); if (authSession==null) { GlobalLog.Print("NegotiateClient::Update() null session returning true"); return true; } GlobalLog.Print("NegotiateClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString()); if (!authSession.IsCompleted && httpWebRequest.CurrentAuthenticationState.StatusCodeMatch==httpWebRequest.ResponseStatusCode) { GlobalLog.Print("NegotiateClient::Update() still handshaking (based on status code) returning false"); return false; } // now possibly close the ConnectionGroup after authentication is done. if (!httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing) { GlobalLog.Print("NegotiateClient::Update() releasing ConnectionGroup:" + httpWebRequest.GetConnectionGroupLine()); httpWebRequest.ServicePoint.ReleaseConnectionGroup(httpWebRequest.GetConnectionGroupLine()); } // // the whole point here is to close the Security Context (this will complete the authentication handshake // with server authentication for schemese that support it such as Kerberos) // bool useNego2 = true; int index = challenge==null ? -1 : GetSignatureIndex(challenge, out useNego2); if (index>=0) { int blobBegin = index + (useNego2 ? nego2Signature.Length : negotiateSignature.Length); string incoming = null; // // there may be multiple challenges. If the next character after the // package name is not a comma then it is challenge data // if (challenge.Length > blobBegin && challenge[blobBegin] != ',') { ++blobBegin; } else { index = -1; } if (index >= 0 && challenge.Length > blobBegin) { incoming = challenge.Substring(blobBegin); } GlobalLog.Print("NegotiateClient::Update() this must be a final incoming blob:[" + ValidationHelper.ToString(incoming) + "]"); string clientResponse = authSession.GetOutgoingBlob(incoming); httpWebRequest.CurrentAuthenticationState.Authorization.MutuallyAuthenticated = authSession.IsMutualAuthFlag; GlobalLog.Print("NegotiateClient::Update() GetOutgoingBlob() returns clientResponse:[" + ValidationHelper.ToString(clientResponse) + "] IsCompleted:" + authSession.IsCompleted.ToString()); } // Extract the CBT we used and cache it for future requests that want to do preauth httpWebRequest.ServicePoint.SetCachedChannelBinding(httpWebRequest.ChallengedUri, authSession.ChannelBinding); GlobalLog.Print("NegotiateClient::Update() session removed and ConnectionGroup released returning true"); ClearSession(httpWebRequest); return true; } public void ClearSession(WebRequest webRequest) { HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::ClearSession()|httpWebRequest == null"); httpWebRequest.CurrentAuthenticationState.ClearSession(); } public bool CanUseDefaultCredentials { get { return true; } } private static int GetSignatureIndex(string challenge, out bool useNego2) { // Negotiate supports two header fields "Nego2" and "Negotiate". If we find "Nego2" we use it, // otherwise we fall back to "Negotiate" (if available). useNego2 = true; int index = -1; // Consider Nego2 headers only on Win7 and later. Older OS version don't support LiveSSP. if (ComNetOS.IsWin7) { index = AuthenticationManager.FindSubstringNotInQuotes(challenge, nego2Signature); } if (index < 0) { useNego2 = false; index = AuthenticationManager.FindSubstringNotInQuotes(challenge, negotiateSignature); } return index; } }; // class NegotiateClient } // namespace System.Net // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net { using System.Diagnostics; using System.Collections; using System.Net.Sockets; using System.Security.Authentication.ExtendedProtection; using System.Security.Permissions; using System.Globalization; internal class NegotiateClient : ISessionAuthenticationModule { internal const string AuthType = "Negotiate"; private const string negotiateHeader = "Negotiate"; private const string negotiateSignature = "negotiate"; private const string nego2Header = "Nego2"; private const string nego2Signature = "nego2"; // we can't work on non-NT2K platforms or non Win, so we shut off, // NOTE this exception IS caught internally. public NegotiateClient() { if (!ComNetOS.IsWin2K) { throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required)); } } public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("NegotiateClient::Authenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()"); return DoAuthenticate(challenge, webRequest, credentials, false); } private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate) { GlobalLog.Print("NegotiateClient::DoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString()); GlobalLog.Assert(credentials != null, "NegotiateClient::DoAuthenticate()|credentials == null"); if (credentials == null) { return null; } HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::DoAuthenticate()|httpWebRequest == null"); GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NegotiateClient::DoAuthenticate()|httpWebRequest.ChallengedUri == null"); NTAuthentication authSession = null; string incoming = null; bool useNego2 = false; // In case of pre-auth we always use "Negotiate", never "Nego2". if (!preAuthenticate) { int index = GetSignatureIndex(challenge, out useNego2); if (index < 0) { return null; } int blobBegin = index + (useNego2 ? nego2Signature.Length : negotiateSignature.Length); // // there may be multiple challenges. If the next character after the // package name is not a comma then it is challenge data // if (challenge.Length > blobBegin && challenge[blobBegin] != ',') { ++blobBegin; } else { index = -1; } if (index >= 0 && challenge.Length > blobBegin) { // Strip other modules information in case of multiple challenges // i.e do not take ", NTLM" as part of the following Negotiate blob // Negotiate TlRMTVNTUAACAAAADgAOADgAAAA1wo ... MAbwBmAHQALgBjAG8AbQAAAAAA,NTLM index = challenge.IndexOf(',', blobBegin); if (index != -1) incoming = challenge.Substring(blobBegin, index - blobBegin); else incoming = challenge.Substring(blobBegin); } authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("NegotiateClient::DoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); } if (authSession==null) { // Credentials are always set for "Negotiate", never for "Nego2". A customer shouldn't even know // about "Nego2". NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, negotiateSignature); GlobalLog.Print("NegotiateClient::DoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); string username = string.Empty; if (NC == null || (!(NC is SystemNetworkCredential) && (username = NC.InternalGetUserName()).Length == 0)) { return null; } ICredentialPolicy policy = AuthenticationManager.CredentialPolicy; if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this)) return null; string spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); GlobalLog.Print("NegotiateClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( AuthType, NC, spn, httpWebRequest, binding); GlobalLog.Print("NegotiateClient::DoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession)); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this); } string clientResponse = authSession.GetOutgoingBlob(incoming); if (clientResponse==null) { return null; } bool canShareConnection = httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing; if (canShareConnection) { httpWebRequest.LockConnection = true; } // this is the first leg of an NTLM handshake, // set the NtlmKeepAlive override *STRICTLY* only in this case. httpWebRequest.NtlmKeepAlive = incoming==null && authSession.IsValidContext && !authSession.IsKerberos; // If we received a "Nego2" header value from the server, we'll respond with "Nego2" in the "Authorization" // header. If the server sent a "Negotiate" header value or if pre-authenticate is used (i.e. the auth blob // is sent with the first request), we send "Negotiate" in the "Authorization" header. return AuthenticationManager.GetGroupAuthorization(this, (useNego2 ? nego2Header : negotiateHeader) + " " + clientResponse, authSession.IsCompleted, authSession, canShareConnection, authSession.IsKerberos); } public bool CanPreAuthenticate { get { return true; } } public Authorization PreAuthenticate(WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("NegotiateClient::PreAuthenticate() webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()"); return DoAuthenticate(null, webRequest, credentials, true); } public string AuthenticationType { get { return AuthType; } } // // called when getting the final blob on the 200 OK from the server // public bool Update(string challenge, WebRequest webRequest) { GlobalLog.Print("NegotiateClient::Update(): " + challenge); HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::Update()|httpWebRequest == null"); GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NegotiateClient::Update()|httpWebRequest.ChallengedUri == null"); // // try to retrieve the state of the ongoing handshake // NTAuthentication authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("NegotiateClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); if (authSession==null) { GlobalLog.Print("NegotiateClient::Update() null session returning true"); return true; } GlobalLog.Print("NegotiateClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString()); if (!authSession.IsCompleted && httpWebRequest.CurrentAuthenticationState.StatusCodeMatch==httpWebRequest.ResponseStatusCode) { GlobalLog.Print("NegotiateClient::Update() still handshaking (based on status code) returning false"); return false; } // now possibly close the ConnectionGroup after authentication is done. if (!httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing) { GlobalLog.Print("NegotiateClient::Update() releasing ConnectionGroup:" + httpWebRequest.GetConnectionGroupLine()); httpWebRequest.ServicePoint.ReleaseConnectionGroup(httpWebRequest.GetConnectionGroupLine()); } // // the whole point here is to close the Security Context (this will complete the authentication handshake // with server authentication for schemese that support it such as Kerberos) // bool useNego2 = true; int index = challenge==null ? -1 : GetSignatureIndex(challenge, out useNego2); if (index>=0) { int blobBegin = index + (useNego2 ? nego2Signature.Length : negotiateSignature.Length); string incoming = null; // // there may be multiple challenges. If the next character after the // package name is not a comma then it is challenge data // if (challenge.Length > blobBegin && challenge[blobBegin] != ',') { ++blobBegin; } else { index = -1; } if (index >= 0 && challenge.Length > blobBegin) { incoming = challenge.Substring(blobBegin); } GlobalLog.Print("NegotiateClient::Update() this must be a final incoming blob:[" + ValidationHelper.ToString(incoming) + "]"); string clientResponse = authSession.GetOutgoingBlob(incoming); httpWebRequest.CurrentAuthenticationState.Authorization.MutuallyAuthenticated = authSession.IsMutualAuthFlag; GlobalLog.Print("NegotiateClient::Update() GetOutgoingBlob() returns clientResponse:[" + ValidationHelper.ToString(clientResponse) + "] IsCompleted:" + authSession.IsCompleted.ToString()); } // Extract the CBT we used and cache it for future requests that want to do preauth httpWebRequest.ServicePoint.SetCachedChannelBinding(httpWebRequest.ChallengedUri, authSession.ChannelBinding); GlobalLog.Print("NegotiateClient::Update() session removed and ConnectionGroup released returning true"); ClearSession(httpWebRequest); return true; } public void ClearSession(WebRequest webRequest) { HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::ClearSession()|httpWebRequest == null"); httpWebRequest.CurrentAuthenticationState.ClearSession(); } public bool CanUseDefaultCredentials { get { return true; } } private static int GetSignatureIndex(string challenge, out bool useNego2) { // Negotiate supports two header fields "Nego2" and "Negotiate". If we find "Nego2" we use it, // otherwise we fall back to "Negotiate" (if available). useNego2 = true; int index = -1; // Consider Nego2 headers only on Win7 and later. Older OS version don't support LiveSSP. if (ComNetOS.IsWin7) { index = AuthenticationManager.FindSubstringNotInQuotes(challenge, nego2Signature); } if (index < 0) { useNego2 = false; index = AuthenticationManager.FindSubstringNotInQuotes(challenge, negotiateSignature); } return index; } }; // class NegotiateClient } // namespace System.Net // 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
- DurableInstancingOptions.cs
- XmlNodeReader.cs
- RightNameExpirationInfoPair.cs
- DataGridHyperlinkColumn.cs
- TransportConfigurationTypeElementCollection.cs
- SymmetricKey.cs
- TouchDevice.cs
- HasActivatableWorkflowEvent.cs
- ChangeToolStripParentVerb.cs
- CatalogZone.cs
- QilSortKey.cs
- XmlSchemaNotation.cs
- InkPresenter.cs
- OdbcParameter.cs
- Match.cs
- DataGridCell.cs
- SoapCodeExporter.cs
- InvalidCastException.cs
- ParseHttpDate.cs
- HttpListenerRequestUriBuilder.cs
- ItemsPresenter.cs
- RecognizedWordUnit.cs
- Variant.cs
- newinstructionaction.cs
- FilterQuery.cs
- SymbolDocumentGenerator.cs
- WebPartConnectVerb.cs
- DataGridViewCellParsingEventArgs.cs
- ConditionValidator.cs
- ResizeBehavior.cs
- ButtonField.cs
- InputBinding.cs
- HtmlMeta.cs
- SweepDirectionValidation.cs
- CreatingCookieEventArgs.cs
- Expander.cs
- Vector3DConverter.cs
- SkinBuilder.cs
- Form.cs
- SqlDataSourceCommandParser.cs
- AsymmetricSignatureDeformatter.cs
- MailAddressCollection.cs
- ExecutedRoutedEventArgs.cs
- EventPrivateKey.cs
- WebBrowserUriTypeConverter.cs
- ParameterRetriever.cs
- PackageProperties.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- Journal.cs
- MethodExpr.cs
- ComplexTypeEmitter.cs
- EncodingDataItem.cs
- StandardCommands.cs
- OdbcPermission.cs
- RenderOptions.cs
- OleDbEnumerator.cs
- SamlAttribute.cs
- WindowsMenu.cs
- RowUpdatingEventArgs.cs
- IsolatedStorageFilePermission.cs
- FlagPanel.cs
- MessageQueueKey.cs
- WebBrowserHelper.cs
- JsonObjectDataContract.cs
- ServiceDescription.cs
- PartitionedStream.cs
- ExceptionWrapper.cs
- DesignTimeTemplateParser.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- FileAuthorizationModule.cs
- OrderByBuilder.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- OutOfMemoryException.cs
- ChildTable.cs
- HwndAppCommandInputProvider.cs
- ColumnBinding.cs
- TCEAdapterGenerator.cs
- ReachSerializer.cs
- CompModSwitches.cs
- DetailsViewPagerRow.cs
- DataGridViewTextBoxEditingControl.cs
- COM2IManagedPerPropertyBrowsingHandler.cs
- CapabilitiesPattern.cs
- DrawingContextDrawingContextWalker.cs
- GlyphRun.cs
- keycontainerpermission.cs
- PropertyPushdownHelper.cs
- CachedPathData.cs
- NetPeerTcpBindingCollectionElement.cs
- AdapterDictionary.cs
- RewritingSimplifier.cs
- FocusChangedEventArgs.cs
- ExtensionWindow.cs
- StrokeCollectionDefaultValueFactory.cs
- ItemContainerPattern.cs
- DoubleCollection.cs
- LowerCaseStringConverter.cs
- GestureRecognizer.cs
- TreeViewHitTestInfo.cs
- CombinedGeometry.cs