RemoteDebugger.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Protocols / RemoteDebugger.cs / 1305376 / RemoteDebugger.cs

                            namespace System.Web.Services.Protocols { 
    using System;
    using System.Web.Services;
    using System.Diagnostics;
    using System.Text; 
    using System.Runtime.InteropServices;
    using System.Web.Services.Interop; 
    using System.Reflection; 
    using System.Threading;
    using System.Security.Permissions; 
    using System.Net;
    using System.ComponentModel; // for CompModSwitches
    using System.Web.Services.Diagnostics;
 
    internal class RemoteDebugger : INotifySource2 {
        private static INotifyConnection2 connection; 
        private static bool getConnection = true; 
        private INotifySink2 notifySink;
        private NotifyFilter notifyFilter; 
        private UserThread userThread;

        private const int INPROC_SERVER = 1;
        private static Guid IID_NotifyConnectionClassGuid = new Guid("12A5B9F0-7A1C-4fcb-8163-160A30F519B5"); 
        private static Guid IID_NotifyConnection2Guid = new Guid("1AF04045-6659-4aaa-9F4B-2741AC56224B");
        private static string debuggerHeader = "VsDebuggerCausalityData"; 
 
        private static Object s_InternalSyncObject;
        private static Object InternalSyncObject { 
            get {
                if (s_InternalSyncObject == null) {
                    Object o = new Object();
                    Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); 
                }
                return s_InternalSyncObject; 
            } 
        }
 
        [DebuggerStepThrough]
        [DebuggerHidden]
        internal RemoteDebugger() {
        } 

        ~RemoteDebugger() { 
            Close(); 
        }
 

        internal static bool IsClientCallOutEnabled() {
            bool enabled = false;
 
            try {
                enabled = !CompModSwitches.DisableRemoteDebugging.Enabled && Debugger.IsAttached && Connection != null; 
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw;
                }
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "IsClientCallOutEnabled", e);
            } 
            return enabled;
        } 
 
        internal static bool IsServerCallInEnabled(ServerProtocol protocol, out string stringBuffer) {
            stringBuffer = null; 
            bool enabled = false;
            try {
                if (CompModSwitches.DisableRemoteDebugging.Enabled)
                    return false; 

                enabled = protocol.Context.IsDebuggingEnabled && Connection != null; 
                if (enabled) { 
                    stringBuffer = protocol.Request.Headers[debuggerHeader];
                    enabled = (stringBuffer != null && stringBuffer.Length > 0); 
                }
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw;
                } 
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "IsServerCallInEnabled", e); 
                enabled = false;
            } 
            return enabled;
        }

        private static INotifyConnection2 Connection { 
            get {
                if (connection == null && getConnection) { 
                    lock (InternalSyncObject) { 
                        if (connection == null) {
                            AppDomain.CurrentDomain.DomainUnload += new EventHandler(OnAppDomainUnload); 
                            AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);

                            TraceMethod method = Tracing.On ? new TraceMethod(typeof(RemoteDebugger), "get_Connection") : null;
                            if (Tracing.On) Tracing.Enter("RemoteDebugger", method); 

                            object unk; 
                            int result = UnsafeNativeMethods.CoCreateInstance(ref IID_NotifyConnectionClassGuid, 
                                                                               null,
                                                                               INPROC_SERVER, 
                                                                               ref IID_NotifyConnection2Guid,
                                                                               out unk);

                            if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 

                            if (result >= 0) // success 
                                connection = (INotifyConnection2)unk; 
                            else
                                connection = null; 
                        }
                        getConnection = false;
                    }
                } 
                return connection;
            } 
        } 

 
        private INotifySink2 NotifySink {
            get {
                if (this.notifySink == null && Connection != null) {
                    TraceMethod method = Tracing.On ? new TraceMethod(this, "get_NotifySink") : null; 
                    if (Tracing.On) Tracing.Enter("RemoteDebugger", method);
 
                    this.notifySink = UnsafeNativeMethods.RegisterNotifySource(Connection, this); 

                    if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 
                }
                return this.notifySink;
            }
        } 

        private static void CloseSharedResources() { 
            if (connection != null) { 
                lock (InternalSyncObject) {
                    if (connection != null) { 
                        TraceMethod method = Tracing.On ? new TraceMethod(typeof(RemoteDebugger), "CloseSharedResources") : null;
                        if (Tracing.On) Tracing.Enter("RemoteDebugger", method);

                        try { 
                            Marshal.ReleaseComObject(connection);
                        } 
                        catch (Exception e) { 
                            if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                                throw; 
                            }
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "CloseSharedResources", e);
                        }
                        if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 
                        connection = null;
                    } 
                } 
            }
        } 

        private void Close() {
            if (this.notifySink != null && connection != null) {
                lock (InternalSyncObject) { 
                    if (this.notifySink != null && connection != null) {
                        TraceMethod method = Tracing.On ? new TraceMethod(this, "Close") : null; 
                        if (Tracing.On) Tracing.Enter("RemoteDebugger", method); 

                        try { 
                            UnsafeNativeMethods.UnregisterNotifySource(connection, this);
                        }
                        catch (Exception e) {
                            if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                                throw;
                            } 
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, method, e); 
                        }
                        if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 
                        this.notifySink = null;
                    }
                }
            } 
        }
 
        [DebuggerStepThrough] 
        [DebuggerHidden]
        internal void NotifyClientCallOut(WebRequest request) { 
            try {
                if (NotifySink == null) return;

                IntPtr bufferPtr; 
                int bufferSize = 0;
                CallId callId = new CallId(null, 0, (IntPtr)0, 0, null, request.RequestUri.Host); 
 
                TraceMethod method = Tracing.On ? new TraceMethod(this, "NotifyClientCallOut") : null;
                if (Tracing.On) Tracing.Enter("RemoteDebugger", method); 

                UnsafeNativeMethods.OnSyncCallOut(NotifySink, callId, out bufferPtr, ref bufferSize);

                if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 

                if (bufferPtr == IntPtr.Zero) return; 
                byte[] buffer = null; 
                try {
                    buffer = new byte[bufferSize]; 
                    Marshal.Copy(bufferPtr, buffer, 0, bufferSize);
                }
                finally {
                    Marshal.FreeCoTaskMem(bufferPtr); 
                }
                string bufferString = Convert.ToBase64String(buffer); 
                request.Headers.Add(debuggerHeader, bufferString); 
            }
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw;
                }
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "NotifyClientCallOut", e); 
            }
        } 
 
        [DebuggerStepThrough]
        [DebuggerHidden] 
        internal void NotifyClientCallReturn(WebResponse response) {
            try {
                if (NotifySink == null) return;
 
                byte[] buffer = new byte[0];
                if (response != null) { 
                    string bufferString = response.Headers[debuggerHeader]; 
                    if (bufferString != null && bufferString.Length != 0)
                        buffer = Convert.FromBase64String(bufferString); 
                }
                CallId callId = new CallId(null, 0, (IntPtr)0, 0, null, null);

                TraceMethod method = Tracing.On ? new TraceMethod(this, "NotifyClientCallReturn") : null; 
                if (Tracing.On) Tracing.Enter("RemoteDebugger", method);
 
                UnsafeNativeMethods.OnSyncCallReturn(NotifySink, callId, buffer, buffer.Length); 

                if (Tracing.On) Tracing.Exit("RemoteDebugger", method); 
            }
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "NotifyClientCallReturn", e); 
            } 

            this.Close(); 
        }

        [DebuggerStepThrough]
        [DebuggerHidden] 
        internal void NotifyServerCallEnter(ServerProtocol protocol, string stringBuffer) {
            try { 
                if (NotifySink == null) return; 
                StringBuilder methodBuilder = new StringBuilder();
                methodBuilder.Append(protocol.Type.FullName); 
                methodBuilder.Append('.');
                methodBuilder.Append(protocol.MethodInfo.Name);
                methodBuilder.Append('(');
                ParameterInfo[] parameterInfos = protocol.MethodInfo.Parameters; 
                for (int i = 0; i < parameterInfos.Length; ++i) {
                    if (i != 0) 
                        methodBuilder.Append(','); 

                    methodBuilder.Append(parameterInfos[i].ParameterType.FullName); 
                }
                methodBuilder.Append(')');

                byte[] buffer = Convert.FromBase64String(stringBuffer); 
                CallId callId = new CallId(null, 0, (IntPtr)0, 0, methodBuilder.ToString(), null);
 
                TraceMethod method = Tracing.On ? new TraceMethod(this, "NotifyServerCallEnter") : null; 
                if (Tracing.On) Tracing.Enter("RemoteDebugger", method);
 
                UnsafeNativeMethods.OnSyncCallEnter(NotifySink, callId, buffer, buffer.Length);

                if (Tracing.On) Tracing.Exit("RemoteDebugger", method);
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw; 
                }
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "NotifyServerCallEnter", e); 
            }
        }

        [DebuggerStepThrough] 
        [DebuggerHidden]
        internal void NotifyServerCallExit(HttpResponse response) { 
            try { 
                if (NotifySink == null) return;
 
                IntPtr bufferPtr;
                int bufferSize = 0;
                CallId callId = new CallId(null, 0, (IntPtr)0, 0, null, null);
 
                TraceMethod method = Tracing.On ? new TraceMethod(this, "NotifyServerCallExit") : null;
                if (Tracing.On) Tracing.Enter("RemoteDebugger", method); 
 
                UnsafeNativeMethods.OnSyncCallExit(NotifySink, callId, out bufferPtr, ref bufferSize);
 
                if (Tracing.On) Tracing.Exit("RemoteDebugger", method);

                if (bufferPtr == IntPtr.Zero) return;
                byte[] buffer = null; 
                try {
                    buffer = new byte[bufferSize]; 
                    Marshal.Copy(bufferPtr, buffer, 0, bufferSize); 
                }
                finally { 
                    Marshal.FreeCoTaskMem(bufferPtr);
                }
                string stringBuffer = Convert.ToBase64String(buffer);
                response.AddHeader(debuggerHeader, stringBuffer); 
            }
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                    throw;
                } 
                if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, typeof(RemoteDebugger), "NotifyServerCallExit", e);
            }
            this.Close();
        } 

 
        private static void OnAppDomainUnload(object sender, EventArgs args) { 
            CloseSharedResources();
        } 

        private static void OnProcessExit(object sender, EventArgs args) {
            CloseSharedResources();
        } 

        void INotifySource2.SetNotifyFilter(NotifyFilter in_NotifyFilter, UserThread in_pUserThreadFilter) { 
            notifyFilter = in_NotifyFilter; 
            userThread = in_pUserThreadFilter;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK