Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / SocketConnection.cs / 3 / SocketConnection.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- #define WSARECV namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.ServiceModel; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; using System.Runtime.InteropServices; using System.ServiceModel.Diagnostics; using System.Text; class SocketConnection : IConnection #if WSARECV , IDisposable #endif { // common state Socket socket; TimeSpan sendTimeout; TimeSpan receiveTimeout; CloseState closeState; bool isShutdown; bool noDelay = false; bool aborted; TraceEventType exceptionEventType; // read state int asyncReadSize; #if WSARECV static int bytesTransferred; OverlappedContext asyncReadOverlapped; static int socketFlags; OverlappedIOCompleteCallback readCallback; #endif byte[] readBuffer; int asyncReadBufferSize; object asyncReadState; WaitCallback asyncReadCallback; Exception asyncReadException; AsyncCallback onReceive; bool asyncReadPending; bool asyncWritePending; IOThreadTimer receiveTimer; static WaitCallback onReceiveTimeout; IOThreadTimer sendTimer; static WaitCallback onSendTimeout; string timeoutErrorString; TransferOperation timeoutErrorTransferOperation; IPEndPoint remoteEndpoint; public SocketConnection(Socket socket, int asyncReadBufferSize, bool autoBindToCompletionPort) { if (socket == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("socket"); } this.closeState = CloseState.Open; this.exceptionEventType = TraceEventType.Error; this.socket = socket; this.socket.SendBufferSize = this.socket.ReceiveBufferSize = asyncReadBufferSize; this.sendTimeout = this.receiveTimeout = TimeSpan.MaxValue; this.asyncReadBufferSize = asyncReadBufferSize; this.onReceive = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnReceive)); if (autoBindToCompletionPort) { this.socket.UseOnlyOverlappedIO = false; } this.TraceSocketInfo(socket, TraceCode.SocketConnectionCreate, null); } public int AsyncReadBufferSize { get { return asyncReadBufferSize; } } public byte[] AsyncReadBuffer { get { if (readBuffer == null) { lock (ThisLock) { ThrowIfClosed(); if (readBuffer == null) { #if WSARECV asyncReadOverlapped = new OverlappedContext(); #endif readBuffer = DiagnosticUtility.Utility.AllocateByteArray(asyncReadBufferSize); } } } return readBuffer; } } object ThisLock { get { return this; } } public TraceEventType ExceptionEventType { get { return this.exceptionEventType; } set { this.exceptionEventType = value; } } public IPEndPoint RemoteIPEndPoint { get { // this property should only be called on the receive path if (remoteEndpoint == null && this.closeState == CloseState.Open) { try { remoteEndpoint = (IPEndPoint)socket.RemoteEndPoint; } catch (SocketException socketException) { // will never be a timeout error, so TimeSpan.Zero is ok #pragma warning suppress 56503 // Called from Receive path, SocketConnection cannot allow a SocketException to escape. throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertReceiveException(socketException, TimeSpan.Zero), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Undefined); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { #pragma warning suppress 56503 // rethrow throw; } else { #pragma warning suppress 56503 // Called from Receive path, SocketConnection must convert ObjectDisposedException properly. throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } } return remoteEndpoint; } } IOThreadTimer SendTimer { get { if (this.sendTimer == null) { if (onSendTimeout == null) { onSendTimeout = new WaitCallback(OnSendTimeout); } this.sendTimer = new IOThreadTimer(onSendTimeout, this, false); } return this.sendTimer; } } IOThreadTimer ReceiveTimer { get { if (this.receiveTimer == null) { if (onReceiveTimeout == null) { onReceiveTimeout = new WaitCallback(OnReceiveTimeout); } this.receiveTimer = new IOThreadTimer(onReceiveTimeout, this, false); } return this.receiveTimer; } } static void OnReceiveTimeout(object state) { SocketConnection thisPtr = (SocketConnection)state; thisPtr.Abort(SR.GetString(SR.SocketAbortedReceiveTimedOut, thisPtr.receiveTimeout), TransferOperation.Read); } static void OnSendTimeout(object state) { SocketConnection thisPtr = (SocketConnection)state; thisPtr.Abort(TraceEventType.Warning, SR.GetString(SR.SocketAbortedSendTimedOut, thisPtr.sendTimeout), TransferOperation.Write); } public void Abort() { Abort(null, TransferOperation.Undefined); } void Abort(string timeoutErrorString, TransferOperation transferOperation) { TraceEventType traceEventType = TraceEventType.Warning; // we could be timing out a cached connection if (this.ExceptionEventType == TraceEventType.Information) { traceEventType = this.ExceptionEventType; } Abort(traceEventType, timeoutErrorString, transferOperation); } void Abort(TraceEventType traceEventType) { Abort(traceEventType, null, TransferOperation.Undefined); } void Abort(TraceEventType traceEventType, string timeoutErrorString, TransferOperation transferOperation) { lock (ThisLock) { if (closeState == CloseState.Closed) { return; } this.timeoutErrorString = timeoutErrorString; this.timeoutErrorTransferOperation = transferOperation; aborted = true; closeState = CloseState.Closed; #if WSARECV if (!this.asyncReadPending && this.asyncReadOverlapped != null) { this.asyncReadOverlapped.FreeOrDefer(); } #endif if (this.asyncReadPending) { CancelReceiveTimer(); } if (this.asyncWritePending) { CancelSendTimer(); } } if (DiagnosticUtility.ShouldTrace(traceEventType)) { TraceUtility.TraceEvent(traceEventType, TraceCode.SocketConnectionAbort, this); } socket.Close(0); } void AbortRead() { lock (ThisLock) { if (this.asyncReadPending) { if (closeState != CloseState.Closed) { this.asyncReadPending = false; CancelReceiveTimer(); } } } } void CancelReceiveTimer() { // CSDMain 34539: Snapshot the timer so that we don't null ref if there is a race // between calls to CancelReceiveTimer (e.g., Abort, AsyncReadCallback) IOThreadTimer receiveTimerSnapshot = this.receiveTimer; this.receiveTimer = null; if (receiveTimerSnapshot != null) { receiveTimerSnapshot.Cancel(); } } void CancelSendTimer() { if (this.sendTimer != null) { this.sendTimer.Cancel(); this.sendTimer = null; } } public void Close(TimeSpan timeout) { lock (ThisLock) { if (closeState == CloseState.Closing || closeState == CloseState.Closed) { // already closing or closed, so just return return; } this.TraceSocketInfo(this.socket, TraceCode.SocketConnectionClose, timeout.ToString()); closeState = CloseState.Closing; } // first we shutdown our send-side TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); Shutdown(timeoutHelper.RemainingTime()); byte[] dummy = new byte[1]; // then we check for a FIN from the other side (i.e. read zero) int bytesRead; TimeSpan readFinTimeout = timeoutHelper.RemainingTime(); try { bytesRead = ReadCore(dummy, 0, 1, readFinTimeout, true); if (bytesRead > 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( new CommunicationException(SR.GetString(SR.SocketCloseReadReceivedData, socket.RemoteEndPoint)), ExceptionEventType); } } catch (TimeoutException timeoutException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new TimeoutException( SR.GetString(SR.SocketCloseReadTimeout, socket.RemoteEndPoint, readFinTimeout), timeoutException), ExceptionEventType); } // finally we call Close with whatever time is remaining TimeSpan socketCloseTimeout = timeoutHelper.RemainingTime(); // trace if we're effectively aborting if (socketCloseTimeout <= TimeSpan.Zero && DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.SocketConnectionAbortClose, this); } socket.Close(TimeoutHelper.ToMilliseconds(socketCloseTimeout)); lock (ThisLock) { #if WSARECV // Abort could have been called on a separate thread and cleaned up // our buffers/completion here if (!this.asyncReadPending && closeState != CloseState.Closed && this.asyncReadOverlapped != null) { this.asyncReadOverlapped.FreeOrDefer(); } #endif closeState = CloseState.Closed; } } #if WSARECV public void Dispose() { this.Abort(); } #endif public void Shutdown(TimeSpan timeout) { lock (ThisLock) { if (isShutdown) { return; } isShutdown = true; } try { socket.Shutdown(SocketShutdown.Send); } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertSendException(socketException, TimeoutHelper.Infinite), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Undefined); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } } void ThrowIfClosed() { if (closeState == CloseState.Closing || closeState == CloseState.Closed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertObjectDisposedException(new ObjectDisposedException( this.GetType().ToString(), SR.GetString(SR.SocketConnectionDisposed)), TransferOperation.Undefined), ExceptionEventType); } } void TraceSocketInfo(Socket socket, TraceCode traceCode, string timeoutString) { if (DiagnosticUtility.ShouldTraceInformation) { Dictionaryvalues = new Dictionary (4); values["State"] = this.closeState.ToString(); if (timeoutString != null) { values["Timeout"] = timeoutString; } if (socket != null && this.closeState != CloseState.Closing) { if (socket.LocalEndPoint != null) { values["LocalEndpoint"] = socket.LocalEndPoint.ToString(); } if (socket.RemoteEndPoint != null) { values["RemoteEndPoint"] = socket.RemoteEndPoint.ToString(); } } TraceUtility.TraceEvent(TraceEventType.Information, traceCode, new DictionaryTraceRecord(values), this, null); } } public object DuplicateAndClose(int targetProcessId) { object result = socket.DuplicateAndClose(targetProcessId); this.Abort(TraceEventType.Information); return result; } public object GetCoreTransport() { return socket; } public bool Validate(Uri uri) { return true; } Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime) { return ConvertTransferException(socketException, this.sendTimeout, socketException, TransferOperation.Write, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, remainingTime); } Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime) { return ConvertTransferException(socketException, this.receiveTimeout, socketException, TransferOperation.Read, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, remainingTime); } internal static Exception ConvertTransferException(SocketException socketException, TimeSpan timeout, Exception originalException) { return ConvertTransferException(socketException, timeout, originalException, TransferOperation.Undefined, false, null, TransferOperation.Undefined, TimeoutHelper.Infinite); } Exception ConvertObjectDisposedException(ObjectDisposedException originalException, TransferOperation transferOperation) { if (this.timeoutErrorString != null) { return ConvertTimeoutErrorException(originalException, transferOperation, this.timeoutErrorString, this.timeoutErrorTransferOperation); } else if (this.aborted) { return new CommunicationObjectAbortedException(SR.GetString(SR.SocketConnectionDisposed), originalException); } else { return originalException; } } static Exception ConvertTransferException(SocketException socketException, TimeSpan timeout, Exception originalException, TransferOperation transferOperation, bool aborted, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation, TimeSpan remainingTime) { if (socketException.ErrorCode == UnsafeNativeMethods.ERROR_INVALID_HANDLE) { return new CommunicationObjectAbortedException(socketException.Message, socketException); } if (timeoutErrorString != null) { return ConvertTimeoutErrorException(originalException, transferOperation, timeoutErrorString, timeoutErrorTransferOperation); } // 10053 can occur due to our timeout sockopt firing, so map to TimeoutException in that case if (socketException.ErrorCode == UnsafeNativeMethods.WSAECONNABORTED && remainingTime <= TimeSpan.Zero) { return new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout), originalException); } if (socketException.ErrorCode == UnsafeNativeMethods.WSAENETRESET || socketException.ErrorCode == UnsafeNativeMethods.WSAECONNABORTED || socketException.ErrorCode == UnsafeNativeMethods.WSAECONNRESET) { if (aborted) { return new CommunicationObjectAbortedException(SR.GetString(SR.TcpLocalConnectionAborted), originalException); } else { return new CommunicationException(SR.GetString(SR.TcpConnectionResetError, timeout), originalException); } } else if (socketException.ErrorCode == UnsafeNativeMethods.WSAETIMEDOUT) { return new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout), originalException); } else { if (aborted) { return new CommunicationObjectAbortedException(SR.GetString(SR.TcpTransferError, socketException.ErrorCode, socketException.Message), originalException); } else { return new CommunicationException(SR.GetString(SR.TcpTransferError, socketException.ErrorCode, socketException.Message), originalException); } } } static Exception ConvertTimeoutErrorException(Exception originalException, TransferOperation transferOperation, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation) { if (timeoutErrorString == null) { DiagnosticUtility.DebugAssert("Argument timeoutErrorString must not be null."); } if (transferOperation == timeoutErrorTransferOperation) { return new TimeoutException(timeoutErrorString, originalException); } else { return new CommunicationException(timeoutErrorString, originalException); } } public IAsyncResult BeginWrite(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, AsyncCallback callback, object state) { ConnectionUtilities.ValidateBufferBounds(buffer, offset, size); try { lock (ThisLock) { SetImmediate(immediate); SetWriteTimeout(timeout, false); this.asyncWritePending = true; } IAsyncResult result = socket.BeginSend(buffer, offset, size, SocketFlags.None, callback, state); return result; } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertSendException(socketException, TimeoutHelper.Infinite), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Write); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } } public void EndWrite(IAsyncResult result) { try { bool callEnd; CancelSendTimer(); lock (ThisLock) { this.asyncWritePending = false; callEnd = (this.closeState != CloseState.Closed); } // System.Net will throw if EndSend() is called on a disposed socket. Note that we can // still get aborted prior to calling EndSend, so we still need to catch ODE below if (callEnd) { socket.EndSend(result); } } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertSendException(socketException, TimeoutHelper.Infinite), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Write); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } } public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout) { // as per http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b201213 // we shouldn't write more than 64K synchronously to a socket const int maxSocketWrite = 64 * 1024; ConnectionUtilities.ValidateBufferBounds(buffer, offset, size); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); try { SetImmediate(immediate); int bytesToWrite = size; while (bytesToWrite > 0) { SetWriteTimeout(timeoutHelper.RemainingTime(), true); size = Math.Min(bytesToWrite, maxSocketWrite); socket.Send(buffer, offset, size, SocketFlags.None); bytesToWrite -= size; offset += size; timeout = timeoutHelper.RemainingTime(); } } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertSendException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Write); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } } public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, BufferManager bufferManager) { try { Write(buffer, offset, size, immediate, timeout); } finally { bufferManager.ReturnBuffer(buffer); } } public int Read(byte[] buffer, int offset, int size, TimeSpan timeout) { ConnectionUtilities.ValidateBufferBounds(buffer, offset, size); ThrowIfClosed(); return ReadCore(buffer, offset, size, timeout, false); } int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool closing) { int bytesRead = 0; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); try { SetReadTimeout(timeoutHelper.RemainingTime(), true, closing); bytesRead = socket.Receive(buffer, offset, size, SocketFlags.None); } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertReceiveException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } return bytesRead; } protected void SetAsyncBytesRead(int bytesRead) { this.asyncReadSize = bytesRead; } #if !WSARECV public virtual AsyncReadResult BeginRead(int offset, int size, WaitCallback callback, object state) { ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size); lock (ThisLock) { ThrowIfClosed(); asyncReadState = state; asyncReadCallback = callback; asyncReadPending = true; } try { IAsyncResult result = socket.BeginReceive(AsyncReadBuffer, offset, size, SocketFlags.None, onReceive, null); if (!result.CompletedSynchronously) return AsyncReadResult.Queued; asyncReadSize = socket.EndReceive(result); return AsyncReadResult.Completed; } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertReceiveException(socketException, TimeoutHelper.Infinite), ExceptionEventType); } } #else unsafe public virtual AsyncReadResult BeginRead(int offset, int size, TimeSpan timeout, WaitCallback callback, object state) { ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size); lock (ThisLock) { ThrowIfClosed(); asyncReadState = state; asyncReadCallback = callback; this.asyncReadPending = true; SetReadTimeout(timeout, false, false); } bool abortRead = true; try { if (socket.UseOnlyOverlappedIO) { try { IAsyncResult result = socket.BeginReceive(AsyncReadBuffer, offset, size, SocketFlags.None, onReceive, null); if (!result.CompletedSynchronously) { abortRead = false; return AsyncReadResult.Queued; } asyncReadSize = socket.EndReceive(result); abortRead = false; return AsyncReadResult.Completed; } catch (SocketException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertReceiveException(exception, TimeoutHelper.Infinite), ExceptionEventType); } } if (readCallback == null) { // Do this just to get the socket bound to the completion port try { socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, null, null); } catch (SocketException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertReceiveException(exception, TimeoutHelper.Infinite), ExceptionEventType); } readCallback = new OverlappedIOCompleteCallback(AsyncReadCallback); } // Error on the side of leaking (rather than premature free) by only calling Cancel if we know it's safe. bool success = true; try { int wsaRecvError = 0; int error = UnsafeNativeMethods.ERROR_SUCCESS; lock (ThisLock) { ThrowIfClosed(); // This must be done before StartSyncOperation because it causes asyncReadOverlapped to be created. UnsafeNativeMethods.WSABuffer wsaBuffer; wsaBuffer.length = Math.Min(AsyncReadBuffer.Length - offset, size); // Among other things, this pins the buffer. this.asyncReadOverlapped.StartAsyncOperation(AsyncReadBuffer, readCallback, true); wsaBuffer.buffer = (IntPtr) (this.asyncReadOverlapped.BufferPtr + offset); wsaRecvError = UnsafeNativeMethods.WSARecv(socket.Handle, &wsaBuffer, 1, out bytesTransferred, ref socketFlags, this.asyncReadOverlapped.NativeOverlapped, IntPtr.Zero); if (wsaRecvError == -1) { // Get the Win32 error code before doing anything else (including Monitor.Exit()). error = Marshal.GetLastWin32Error(); } } if (wsaRecvError == -1) { if (error != UnsafeNativeMethods.ERROR_IO_PENDING && error != UnsafeNativeMethods.ERROR_MORE_DATA) { success = false; SocketException socketException = new SocketException(error); throw DiagnosticUtility.ExceptionUtility.ThrowHelper( ConvertReceiveException(socketException, TimeoutHelper.Infinite), ExceptionEventType); } } } finally { if (!success) { this.asyncReadOverlapped.CancelAsyncOperation(); } } abortRead = false; } catch (ObjectDisposedException objectDisposedException) { Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read); if (object.ReferenceEquals(exceptionToThrow, objectDisposedException)) { throw; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(exceptionToThrow, ExceptionEventType); } } finally { if (abortRead) { AbortRead(); } } return AsyncReadResult.Queued; } unsafe void AsyncReadCallback(bool haveResult, int error, int bytesRead) { if (!haveResult) { DiagnosticUtility.DebugAssert("Socket OverlappedContext should always be bound."); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } CancelReceiveTimer(); if (error != 0) { // From System.Net:_BaseOverlappedAsyncResult.cs // There are cases where passed errorCode does not reflect the details of the underlined socket error. if (error != UnsafeNativeMethods.ERROR_OPERATION_ABORTED) { // Here we need to call WSAGetOverlappedResult() just so Marshal.GetLastWin32Error() will return the correct error. // and we need to do a manual lock since socket.SafeHandle isn't exposed publicly lock (ThisLock) { if (closeState == CloseState.Closing || closeState == CloseState.Closed) { error = UnsafeNativeMethods.ERROR_OPERATION_ABORTED; } else { uint dummyFlags; bool dummy = UnsafeNativeMethods.WSAGetOverlappedResult( socket.Handle, this.asyncReadOverlapped.NativeOverlapped, out bytesRead, false, out dummyFlags); error = Marshal.GetLastWin32Error(); } } } asyncReadException = ConvertReceiveException(new SocketException(error), TimeoutHelper.Infinite); } asyncReadSize = bytesRead; this.asyncReadOverlapped.FreeIfDeferred(); FinishRead(); } #endif void OnReceive(IAsyncResult result) { CancelReceiveTimer(); if (result.CompletedSynchronously) { return; } try { asyncReadSize = socket.EndReceive(result); } catch (SocketException socketException) { asyncReadException = ConvertReceiveException(socketException, TimeoutHelper.Infinite); } catch (ObjectDisposedException objectDisposedException) { asyncReadException = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read); } #pragma warning suppress 56500 // [....], transferring exception to caller catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) { throw; } asyncReadException = exception; } FinishRead(); } void FinishRead() { WaitCallback asyncReadCallback = this.asyncReadCallback; object asyncReadState = this.asyncReadState; this.asyncReadState = null; this.asyncReadCallback = null; asyncReadCallback(asyncReadState); } public int EndRead() { if (asyncReadException != null) { AbortRead(); throw DiagnosticUtility.ExceptionUtility.ThrowHelper(asyncReadException, ExceptionEventType); } lock (ThisLock) { if (!this.asyncReadPending) { DiagnosticUtility.DebugAssert("SocketConnection.EndRead called with no read pending."); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } this.asyncReadPending = false; #if WSARECV if (closeState == CloseState.Closed && this.asyncReadOverlapped != null) { this.asyncReadOverlapped.FreeOrDefer(); } #endif } return asyncReadSize; } void SetImmediate(bool immediate) { if (immediate != this.noDelay) { lock (ThisLock) { ThrowIfClosed(); socket.NoDelay = immediate; } this.noDelay = immediate; } } void SetReadTimeout(TimeSpan timeout, bool synchronous, bool closing) { if (synchronous) { CancelReceiveTimer(); // 0 == infinite for winsock timeouts, so we should preempt and throw if (timeout <= TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType); } if (UpdateTimeout(this.receiveTimeout, timeout)) { lock (ThisLock) { if (!closing || this.closeState != CloseState.Closing) { ThrowIfClosed(); } this.socket.ReceiveTimeout = TimeoutHelper.ToMilliseconds(timeout); } this.receiveTimeout = timeout; } } else { this.receiveTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelReceiveTimer(); } else { ReceiveTimer.Set(timeout); } } } void SetWriteTimeout(TimeSpan timeout, bool synchronous) { if (synchronous) { CancelSendTimer(); // 0 == infinite for winsock timeouts, so we should preempt and throw if (timeout <= TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType); } if (UpdateTimeout(this.sendTimeout, timeout)) { lock (ThisLock) { ThrowIfClosed(); this.socket.SendTimeout = TimeoutHelper.ToMilliseconds(timeout); } this.sendTimeout = timeout; } } else { this.sendTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelSendTimer(); } else { SendTimer.Set(timeout); } } } bool UpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout) { if (oldTimeout == newTimeout) { return false; } long threshold = oldTimeout.Ticks / 10; long delta = Math.Max(oldTimeout.Ticks, newTimeout.Ticks) - Math.Min(oldTimeout.Ticks, newTimeout.Ticks); return delta > threshold; } enum CloseState { Open, Closing, Closed, } enum TransferOperation { Write, Read, Undefined, } } class SocketConnectionInitiator : IConnectionInitiator { int bufferSize; public SocketConnectionInitiator(int bufferSize) { this.bufferSize = bufferSize; } IConnection CreateConnection(Socket socket) { return new SocketConnection(socket, bufferSize, false); } public static Exception ConvertConnectException(SocketException socketException, Uri remoteUri, TimeSpan timeSpent, Exception innerException) { if (socketException.ErrorCode == UnsafeNativeMethods.ERROR_INVALID_HANDLE) { return new CommunicationObjectAbortedException(socketException.Message, socketException); } if (socketException.ErrorCode == UnsafeNativeMethods.WSAEADDRNOTAVAIL || socketException.ErrorCode == UnsafeNativeMethods.WSAECONNREFUSED || socketException.ErrorCode == UnsafeNativeMethods.WSAENETDOWN || socketException.ErrorCode == UnsafeNativeMethods.WSAENETUNREACH || socketException.ErrorCode == UnsafeNativeMethods.WSAEHOSTDOWN || socketException.ErrorCode == UnsafeNativeMethods.WSAEHOSTUNREACH || socketException.ErrorCode == UnsafeNativeMethods.WSAETIMEDOUT) { if (timeSpent == TimeSpan.MaxValue) { return new EndpointNotFoundException(SR.GetString(SR.TcpConnectError, remoteUri.AbsoluteUri, socketException.ErrorCode, socketException.Message), innerException); } else { return new EndpointNotFoundException(SR.GetString(SR.TcpConnectErrorWithTimeSpan, remoteUri.AbsoluteUri, socketException.ErrorCode, socketException.Message, timeSpent), innerException); } } else if (socketException.ErrorCode == UnsafeNativeMethods.WSAENOBUFS) { return new InsufficientMemoryException(SR.GetString(SR.TcpConnectNoBufs), innerException); } else if (socketException.ErrorCode == UnsafeNativeMethods.ERROR_NOT_ENOUGH_MEMORY || socketException.ErrorCode == UnsafeNativeMethods.ERROR_NO_SYSTEM_RESOURCES || socketException.ErrorCode == UnsafeNativeMethods.ERROR_OUTOFMEMORY) { return new InsufficientMemoryException(SR.GetString(SR.InsufficentMemory), socketException); } else { if (timeSpent == TimeSpan.MaxValue) { return new CommunicationException(SR.GetString(SR.TcpConnectError, remoteUri.AbsoluteUri, socketException.ErrorCode, socketException.Message), innerException); } else { return new CommunicationException(SR.GetString(SR.TcpConnectErrorWithTimeSpan, remoteUri.AbsoluteUri, socketException.ErrorCode, socketException.Message, timeSpent), innerException); } } } static IPAddress[] GetIPAddresses(Uri uri) { if (uri.HostNameType == UriHostNameType.IPv4 || uri.HostNameType == UriHostNameType.IPv6) { IPAddress ipAddress = IPAddress.Parse(uri.DnsSafeHost); return new IPAddress[] { ipAddress }; } IPHostEntry hostEntry = null; try { hostEntry = DnsCache.Resolve(uri.Host); } catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new EndpointNotFoundException(SR.GetString(SR.UnableToResolveHost, uri.Host), socketException)); } if (hostEntry.AddressList.Length == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new EndpointNotFoundException(SR.GetString(SR.UnableToResolveHost, uri.Host))); } return hostEntry.AddressList; } static TimeoutException CreateTimeoutException(Uri uri, TimeSpan timeout, IPAddress[] addresses, int invalidAddressCount, SocketException innerException) { StringBuilder addressStringBuilder = new StringBuilder(); for (int i = 0; i < invalidAddressCount; i++) { if (addresses[i] == null) { continue; } if (addressStringBuilder.Length > 0) { addressStringBuilder.Append(", "); } addressStringBuilder.Append(addresses[i].ToString()); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.GetString(SR.TcpConnectingToViaTimedOut, uri.AbsoluteUri, timeout.ToString(), invalidAddressCount, addresses.Length, addressStringBuilder.ToString()), innerException)); } public IConnection Connect(Uri uri, TimeSpan timeout) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Information, TraceCode.InitiatingTcpConnection, new StringTraceRecord("Uri", uri.ToString()), this, null); } int port = uri.Port; IPAddress[] addresses = SocketConnectionInitiator.GetIPAddresses(uri); Socket socket = null; SocketException lastException = null; if (port == -1) { port = TcpUri.DefaultPort; } int invalidAddressCount = 0; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); for (int i = 0; i < addresses.Length; i++) { if (timeoutHelper.RemainingTime() == TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateTimeoutException(uri, timeoutHelper.OriginalTimeout, addresses, invalidAddressCount, lastException)); } AddressFamily addressFamily = addresses[i].AddressFamily; if (addressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6) { addresses[i] = null; // disregard for exception attempt purposes continue; } DateTime connectStartTime = DateTime.UtcNow; try { socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(addresses[i], port)); lastException = null; break; } catch (SocketException socketException) { invalidAddressCount++; SocketConnectionInitiator.TraceConnectFailure(socket, socketException, uri, DateTime.UtcNow - connectStartTime); lastException = socketException; socket.Close(); } } if (socket == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new EndpointNotFoundException(SR.GetString(SR.NoIPEndpointsFoundForHost, uri.Host))); } if (lastException != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( SocketConnectionInitiator.ConvertConnectException(lastException, uri, timeoutHelper.ElapsedTime(), lastException)); } return CreateConnection(socket); } public IAsyncResult BeginConnect(Uri uri, TimeSpan timeout, AsyncCallback callback, object state) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Information, TraceCode.InitiatingTcpConnection, new StringTraceRecord("Uri", uri.ToString()), this, null); } return new ConnectAsyncResult(uri, timeout, callback, state); } public IConnection EndConnect(IAsyncResult result) { Socket socket = ConnectAsyncResult.End(result); return CreateConnection(socket); } public static void TraceConnectFailure(Socket socket, SocketException socketException, Uri remoteUri, TimeSpan timeSpentInConnect) { if (DiagnosticUtility.ShouldTraceWarning) { Exception traceException = ConvertConnectException(socketException, remoteUri, timeSpentInConnect, socketException); TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.TcpConnectError, socket, traceException); } } class ConnectAsyncResult : AsyncResult { IPAddress[] addresses; int currentIndex; int port; SocketException lastException; TimeSpan timeout; TimeoutHelper timeoutHelper; int invalidAddressCount; DateTime connectStartTime; Socket socket; Uri uri; static WaitCallback startConnectCallback; static AsyncCallback onConnect = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnConnect)); public ConnectAsyncResult(Uri uri, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.uri = uri; addresses = SocketConnectionInitiator.GetIPAddresses(uri); port = uri.Port; if (port == -1) { port = TcpUri.DefaultPort; } currentIndex = 0; this.timeout = timeout; this.timeoutHelper = new TimeoutHelper(timeout); if (Thread.CurrentThread.IsThreadPoolThread) { if(StartConnect()) { base.Complete(true); } } else { // If we're not on a threadpool thread, then we need to post a callback to start our accepting loop // Otherwise if the calling thread aborts then the async I/O will get inadvertantly cancelled if (startConnectCallback == null) { startConnectCallback = StartConnectCallback; } IOThreadScheduler.ScheduleCallback(startConnectCallback, this); } } static void StartConnectCallback(object state) { ConnectAsyncResult connectAsyncResult = (ConnectAsyncResult)state; bool completeSelf = false; Exception completionException = null; try { completeSelf = connectAsyncResult.StartConnect(); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { connectAsyncResult.Complete(false, completionException); } } bool StartConnect() { while (currentIndex < addresses.Length) { if (timeoutHelper.RemainingTime() == TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateTimeoutException(uri, timeoutHelper.OriginalTimeout, addresses, invalidAddressCount, lastException)); } AddressFamily addressFamily = addresses[currentIndex].AddressFamily; if (addressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6) { addresses[currentIndex++] = null; // disregard for exception attempt purposes continue; } this.connectStartTime = DateTime.UtcNow; try { IPEndPoint ipEndPoint = new IPEndPoint(addresses[currentIndex], port); this.socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); IAsyncResult result = socket.BeginConnect(ipEndPoint, onConnect, this); if (!result.CompletedSynchronously) { return false; } socket.EndConnect(result); return true; } catch (SocketException socketException) { invalidAddressCount++; this.TraceConnectFailure(socketException); lastException = socketException; currentIndex++; } } if (socket == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new EndpointNotFoundException(SR.GetString(SR.NoIPEndpointsFoundForHost, uri.Host))); } DiagnosticUtility.DebugAssert(lastException != null, "StartConnect: Can't get here without an exception."); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( SocketConnectionInitiator.ConvertConnectException(lastException, uri, timeoutHelper.ElapsedTime(), lastException)); } void TraceConnectFailure(SocketException exception) { SocketConnectionInitiator.TraceConnectFailure(this.socket, exception, uri, DateTime.UtcNow - connectStartTime); this.socket.Close(); } static void OnConnect(IAsyncResult result) { if (result.CompletedSynchronously) { return; } bool completeSelf = false; Exception completionException = null; ConnectAsyncResult thisPtr = (ConnectAsyncResult)result.AsyncState; try { thisPtr.socket.EndConnect(result); completeSelf = true; } catch (SocketException socketException) { thisPtr.TraceConnectFailure(socketException); thisPtr.lastException = socketException; thisPtr.currentIndex++; try { completeSelf = thisPtr.StartConnect(); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } } if (completeSelf) { thisPtr.Complete(false, completionException); } } public static Socket End(IAsyncResult result) { ConnectAsyncResult thisPtr = AsyncResult.End (result); return thisPtr.socket; } } } internal interface ISocketListenerSettings { int BufferSize { get; } bool TeredoEnabled { get; } int ListenBacklog { get; } } class SocketConnectionListener : IConnectionListener { IPEndPoint localEndpoint; bool isDisposed; bool isListening; Socket listenSocket; ISocketListenerSettings settings; bool useOnlyOverlappedIO; public SocketConnectionListener(Socket listenSocket, ISocketListenerSettings settings, bool useOnlyOverlappedIO) : this(settings, useOnlyOverlappedIO) { this.listenSocket = listenSocket; } public SocketConnectionListener(IPEndPoint localEndpoint, ISocketListenerSettings settings, bool useOnlyOverlappedIO) : this(settings, useOnlyOverlappedIO) { this.localEndpoint = localEndpoint; } SocketConnectionListener(ISocketListenerSettings settings, bool useOnlyOverlappedIO) { this.settings = settings; this.useOnlyOverlappedIO = useOnlyOverlappedIO; } object ThisLock { get { return this; } } public IAsyncResult BeginAccept(AsyncCallback callback, object state) { return new AcceptAsyncResult(this, callback, state); } IAsyncResult InternalBeginAccept(AsyncCallback callback, object state) { lock (ThisLock) { if (isDisposed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().ToString(), SR.GetString(SR.SocketListenerDisposed))); } if (!isListening) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SocketListenerNotListening))); } return listenSocket.BeginAccept(callback, state); } } Socket InternalEndAccept(IAsyncResult result) { Socket socket = null; lock (ThisLock) { // unfortunately, a bad design decision in System.Net v1.0 causes // EndAccept on a disposed socket to throw ObjectDisposedException // rather than returning null. So we have this check. if (!isDisposed) { socket = listenSocket.EndAccept(result); } } return socket; } public IConnection EndAccept(IAsyncResult result) { Socket socket = AcceptAsyncResult.End(result); if (socket == null) return null; if (useOnlyOverlappedIO) { socket.UseOnlyOverlappedIO = true; } return new SocketConnection(socket, settings.BufferSize, false); } public void Dispose() { lock (ThisLock) { if (!isDisposed) { if (listenSocket != null) { listenSocket.Close(); } isDisposed = true; } } } public void Listen() { // If you call listen() on a port, then kill the process, then immediately start a new process and // try to listen() on the same port, you sometimes get WSAEADDRINUSE. Even if nothing was accepted. // Ports don't immediately free themselves on process shutdown. We call listen() in a loop on a delay // for a few iterations for this reason. // TimeSpan listenTimeout = TimeSpan.FromSeconds(1); BackoffTimeoutHelper backoffHelper = new BackoffTimeoutHelper(listenTimeout); lock (ThisLock) { if (this.listenSocket != null) { this.listenSocket.Listen(settings.ListenBacklog); isListening = true; } while (!isListening) { try { this.listenSocket = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (localEndpoint.AddressFamily == AddressFamily.InterNetworkV6 && settings.TeredoEnabled) { this.listenSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)23, 10); } this.listenSocket.Bind(localEndpoint); this.listenSocket.Listen(settings.ListenBacklog); isListening = true; } catch (SocketException socketException) { bool retry = false; if (socketException.ErrorCode == UnsafeNativeMethods.WSAEADDRINUSE) { if (!backoffHelper.IsExpired()) { backoffHelper.WaitAndBackoff(); retry = true; } } if (!retry) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( SocketConnectionListener.ConvertListenException(socketException, this.localEndpoint)); } } } } } public static Exception ConvertListenException(SocketException socketException, IPEndPoint localEndpoint) { if (socketException.ErrorCode == UnsafeNativeMethods.ERROR_INVALID_HANDLE) { return new CommunicationObjectAbortedException(socketException.Message, socketException); } if (socketException.ErrorCode == UnsafeNativeMethods.WSAEADDRINUSE) { return new AddressAlreadyInUseException(SR.GetString(SR.TcpAddressInUse, localEndpoint.ToString()), socketException); } else { return new CommunicationException( SR.GetString(SR.TcpListenError, socketException.ErrorCode, socketException.Message, localEndpoint.ToString()), socketException); } } class AcceptAsyncResult : AsyncResult { SocketConnectionListener listener; Socket socket; static WaitCallback startAccept; static AsyncCallback onAccept = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnAccept)); public AcceptAsyncResult(SocketConnectionListener listener, AsyncCallback callback, object state) : base(callback, state) { this.listener = listener; // If we're going to start up the thread pool eventually anyway, avoid using RegisterWaitForSingleObject if (!Thread.CurrentThread.IsThreadPoolThread) { if (startAccept == null) { startAccept = new WaitCallback(StartAccept); } IOThreadScheduler.ScheduleCallback(startAccept, this); } else { if (StartAccept()) { base.Complete(true); } } } static void StartAccept(object state) { AcceptAsyncResult thisPtr = (AcceptAsyncResult)state; Exception completionException = null; bool completeSelf; try { completeSelf = thisPtr.StartAccept(); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { thisPtr.Complete(false, completionException); } } bool StartAccept() { while (true) { try { IAsyncResult result = listener.InternalBeginAccept(onAccept, this); if (!result.CompletedSynchronously) { return false; } this.socket = listener.InternalEndAccept(result); return true; } catch (SocketException socketException) { if (ShouldAcceptRecover(socketException)) { continue; } else { throw; } } } } static bool ShouldAcceptRecover(SocketException exception) { return ( (exception.ErrorCode == UnsafeNativeMethods.WSAECONNRESET) || (exception.ErrorCode == UnsafeNativeMethods.WSAEMFILE) || (exception.ErrorCode == UnsafeNativeMethods.WSAENOBUFS) || (exception.ErrorCode == UnsafeNativeMethods.WSAETIMEDOUT) ); } static void OnAccept(IAsyncResult result) { if (result.CompletedSynchronously) { return; } AcceptAsyncResult thisPtr = (AcceptAsyncResult)result.AsyncState; Exception completionException = null; bool completeSelf = true; try { bool retryAcceptLoop = false; try { thisPtr.socket = thisPtr.listener.InternalEndAccept(result); completeSelf = true; } catch (SocketException socketException) { if (ShouldAcceptRecover(socketException)) { if (DiagnosticUtility.ShouldTraceWarning) { DiagnosticUtility.ExceptionUtility.TraceHandledException(socketException, TraceEventType.Warning); } retryAcceptLoop = true; } else { completeSelf = true; completionException = socketException; } } if (retryAcceptLoop) { completeSelf = thisPtr.StartAccept(); } } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { thisPtr.Complete(false, completionException); } } public static Socket End(IAsyncResult result) { AcceptAsyncResult thisPtr = AsyncResult.End (result); return thisPtr.socket; } } } } // 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
- IsolatedStorageException.cs
- SessionStateContainer.cs
- baseshape.cs
- Wizard.cs
- PointConverter.cs
- WindowAutomationPeer.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- GuidelineSet.cs
- CqlParserHelpers.cs
- TreeSet.cs
- Bitmap.cs
- EntityContainerEmitter.cs
- Label.cs
- WebHttpSecurityModeHelper.cs
- FailedToStartupUIException.cs
- MouseBinding.cs
- TransformGroup.cs
- Point4D.cs
- OleDbDataReader.cs
- SignatureDescription.cs
- SourceFilter.cs
- ManualWorkflowSchedulerService.cs
- QuaternionAnimationUsingKeyFrames.cs
- CodeGeneratorOptions.cs
- XomlCompilerParameters.cs
- listitem.cs
- SqlServices.cs
- WsdlBuildProvider.cs
- FixUp.cs
- QilFunction.cs
- BindUriHelper.cs
- PathTooLongException.cs
- SQLByte.cs
- SmtpFailedRecipientsException.cs
- LinqDataSourceView.cs
- TextSelectionProcessor.cs
- DbMetaDataCollectionNames.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- CustomAttributeFormatException.cs
- StringFreezingAttribute.cs
- RequestCachePolicyConverter.cs
- InputScope.cs
- NameService.cs
- TogglePattern.cs
- CollectionType.cs
- Message.cs
- StringWriter.cs
- TableLayoutColumnStyleCollection.cs
- ServiceManagerHandle.cs
- ProjectionPath.cs
- ScriptDescriptor.cs
- TreePrinter.cs
- transactioncontext.cs
- TypeSystem.cs
- ConnectionConsumerAttribute.cs
- MultipleViewProviderWrapper.cs
- XPathNode.cs
- FontConverter.cs
- SqlNode.cs
- CloudCollection.cs
- RadioButton.cs
- CapabilitiesUse.cs
- MetadataImporter.cs
- RightsManagementPermission.cs
- PageBreakRecord.cs
- DateTimeSerializationSection.cs
- Type.cs
- SelectionRangeConverter.cs
- ObjectCloneHelper.cs
- ViewLoader.cs
- MenuTracker.cs
- ConditionalBranch.cs
- SqlServer2KCompatibilityCheck.cs
- ChannelTraceRecord.cs
- ReadOnlyTernaryTree.cs
- BitmapEffectInputConnector.cs
- DataKey.cs
- PropertyGridDesigner.cs
- StateBag.cs
- PerspectiveCamera.cs
- SecurityDocument.cs
- validationstate.cs
- SystemIPInterfaceStatistics.cs
- AffineTransform3D.cs
- ObjectDataSourceView.cs
- CookielessData.cs
- ItemDragEvent.cs
- StringConverter.cs
- AvTrace.cs
- SimpleWebHandlerParser.cs
- TypeBuilderInstantiation.cs
- XNodeValidator.cs
- FloaterParagraph.cs
- WorkflowOperationBehavior.cs
- DbExpressionBuilder.cs
- WorkflowValidationFailedException.cs
- DefaultHttpHandler.cs
- SqlFormatter.cs
- PackagingUtilities.cs
- SpellerInterop.cs