InfoCardTrace.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / infocard / Diagnostics / Managed / Microsoft / InfoCards / Diagnostics / InfoCardTrace.cs / 1305376 / InfoCardTrace.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards.Diagnostics
{ 
    using System;
    using System.Xml; 
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.ComponentModel;    //win32exception
    using System.Runtime.InteropServices;
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution; 
    using Microsoft.Win32.SafeHandles;
    using System.Security; 
    using System.Security.Principal; 
    using System.Runtime;
    using System.ServiceModel.Diagnostics; 
    using System.Threading;

    //
    // For InfoCardBaseException 
    //
    using System.IdentityModel.Selectors; 
 
    // Summary
    // InfoCardTrace is the main driver class for the managed tracing infrastructure. 
    // Essentially it is a wrapper over the Indigo DiagnosticsAndTracing classes.
    // Externally a facade of simple TraceXXXX calls is provided which
    // internally thunk across to the indigo classes to perform the work.
    // 
    // The trace class also provides support for flowing of correlation ids allowing
    // tracing of requests across process and managed / unmanaged boundaries 
    // See the Infocard Tracing documentation at http://team/sites/infocard for 
    // detail on configuration and usage.
    // 
    // Remarks
    // All functions are thread safe
    //
    // Example usage looks like: 
    // using IDT=Microsoft.InfoCards.Diagnostics.InfoCardTrace
    // IDT.TraceVerbose( InfoCardTraceCode.StoreInvalidKey, myKey ); 
    // IDT.TraceDebug( "Got an infocard {0} with name {1}", card, card.Name ); 
    //
    // 
    static class InfoCardTrace
    {
        static class TraceCode
        { 
            public const int IdentityModelSelectors = 0xD0000;
            public const int GeneralInformation = TraceCode.IdentityModelSelectors | 0X0001; 
            public const int StoreLoading = TraceCode.IdentityModelSelectors | 0X0002; 
            public const int StoreBeginTransaction = TraceCode.IdentityModelSelectors | 0X0003;
            public const int StoreCommitTransaction = TraceCode.IdentityModelSelectors | 0X0004; 
            public const int StoreRollbackTransaction = TraceCode.IdentityModelSelectors | 0X0005;
            public const int StoreClosing = TraceCode.IdentityModelSelectors | 0X0006;
            public const int StoreFailedToOpenStore = TraceCode.IdentityModelSelectors | 0X0007;
            public const int StoreSignatureNotValid = TraceCode.IdentityModelSelectors | 0X0008; 
            public const int StoreDeleting = TraceCode.IdentityModelSelectors | 0X0009;
        } 
 
        static Dictionary traceCodes = new Dictionary(9)
        { 
            { TraceCode.GeneralInformation, "GeneralInformation" },
            { TraceCode.StoreLoading, "StoreLoading" },
            { TraceCode.StoreBeginTransaction, "StoreBeginTransaction" },
            { TraceCode.StoreCommitTransaction, "StoreCommitTransaction" }, 
            { TraceCode.StoreRollbackTransaction, "StoreRollbackTransaction" },
            { TraceCode.StoreClosing, "StoreClosing" }, 
            { TraceCode.StoreFailedToOpenStore, "StoreFailedToOpenStore" }, 
            { TraceCode.StoreSignatureNotValid, "StoreSignatureNotValid" },
            { TraceCode.StoreDeleting, "StoreDeleting" }, 
        };

        static string GetTraceString(int traceCode)
        { 
            return traceCodes[traceCode];
        } 
 
        static string GetMsdnTraceCode(int traceCode)
        { 
            return DiagnosticTrace.GenerateMsdnTraceCode("System.IdentityModel.Selectors", GetTraceString(traceCode));
        }

        [DllImport("advapi32", 
                CharSet = CharSet.Unicode,
                EntryPoint = "ReportEventW", 
                ExactSpelling = true, 
                SetLastError = true)]
        private static extern bool ReportEvent([In] SafeHandle hEventLog, 
                                               [In] short type,
                                               [In] ushort category,
                                               [In] uint eventID,
                                               [In] byte[] userSID, 
                                               [In] short numStrings,
                                               [In] int dataLen, 
                                               [In] HandleRef strings, 
                                               [In] byte[] rawData);
 


        //
        // Summary: 
        // Provides a wrapper over a handle retrieved by RegisterEventSource
        // 
        internal class SafeEventLogHandle : SafeHandle 
        {
 
            [DllImport("advapi32",
                    CharSet = CharSet.Unicode,
                    EntryPoint = "RegisterEventSourceW",
                    ExactSpelling = true, 
                    SetLastError = true)]
            private static extern SafeEventLogHandle RegisterEventSource(string uncServerName, string sourceName); 
 
            [DllImport("advapi32",
                    CharSet = CharSet.Unicode, 
                    EntryPoint = "DeregisterEventSource",
                    ExactSpelling = true,
                    SetLastError = true)]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
            private static extern bool DeregisterEventSource(IntPtr eventLog);
 
            public static SafeEventLogHandle Construct() 
            {
                SafeEventLogHandle h = RegisterEventSource(null, InfoCardTrace.InfoCardEventSource); 

                if (null == h || h.IsInvalid)
                {
                    int error = Marshal.GetLastWin32Error(); 
                    TraceDebug("failed to registereventsource with error {0}", error);
 
                } 
                return h;
            } 
            //
            // Summary:
            // Manages the lifetime of a native handle retrieved by register event source.
            // Parameters: 
            // handle - the handle to wrap.
            // 
            private SafeEventLogHandle() 
                : base(IntPtr.Zero, true)
            { 


            }
 

            public override bool IsInvalid 
            { 
                get
                { 
                    return (IntPtr.Zero == base.handle);
                }
            }
 
            //
            // Summary: 
            // Releases the eventlog handle. 
            //
            protected override bool ReleaseHandle() 
            {
#pragma warning suppress 56523
                return DeregisterEventSource(base.handle);
 
            }
        } 
 
        //
        // Summary: 
        // Returns whether the current exception is fatal.
        // Notes:
        // Currently this delegates to the code in ExceptionUtility.cs
        // 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public static bool IsFatal(Exception e) 
        { 
            return Fx.IsFatal(e);
        } 

        public static TimerCallback ThunkCallback(TimerCallback callback)
        {
            return Fx.ThunkCallback(callback); 
        }
 
        public static WaitCallback ThunkCallback(WaitCallback callback) 
        {
            return Fx.ThunkCallback(callback); 
        }

        public static void CloseInvalidOutSafeHandle(SafeHandle handle)
        { 
            Utility.CloseInvalidOutSafeHandle(handle);
        } 
 
        //
        // The event source we log against. May need to be updated should our name change before rtm 
        //

        const string InfoCardEventSource = "CardSpace 4.0.0.0";
 

        // 
        // Summary: 
        // Writes an audit message to the application's event log
        // 
        public static void Audit(EventCode code)
        {
            LogEvent(code, null, EventLogEntryType.Information);
        } 

        public static void Audit(EventCode code, string message) 
        { 
            LogEvent(code, message, EventLogEntryType.Information);
        } 
        public static void Assert(bool condition, string format, params object[] parameters)
        {

            if (condition) 
            {
                return; 
            } 

            string message = format; 
            if (null != parameters && 0 != parameters.Length)
            {
                message = String.Format(CultureInfo.InvariantCulture, format, parameters);
            } 
            TraceDebug("An assertion fired: {0}", message);
#if DEBUG 
            // 
            // Let DebugAssert handle this for us....
            // If not in debugger,  Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue 
            // If in debugger, will hit a DebugBreak()
            //
            DiagnosticUtility.DebugAssert( false, message );
#else 
            //
            // Retail assert failfasts service 
            // 
            FailFast(message);
#endif 

        }

 
        [Conditional("DEBUG")]
        public static void DebugAssert(bool condition, string format, params object[] parameters) 
        { 
#if DEBUG
            if( condition ) 
            {
                return;
            }
 
            string message = format;
            if( null != parameters && 0 != parameters.Length ) 
            { 
                message = String.Format( CultureInfo.InvariantCulture, format, parameters );
            } 
            TraceDebug( "An assertion fired: {0}", message );
            if( Debugger.IsAttached )
            {
                Debugger.Launch(); 
                Debugger.Break();
            } 
            DiagnosticUtility.DebugAssert( false, message ); 
            FailFast( message );
#endif 
        }


        // 
        // Facade functions to allow simple call semantics.
        // 
        public static void FailFast(string message) 
        {
            DiagnosticUtility.FailFast(message); 
        }
        [Conditional("DEBUG")]
        public static void TraceVerbose(int traceCode)
        { 
            TraceInternal(TraceEventType.Verbose, traceCode, null);
 
        } 
        [Conditional("DEBUG")]
        public static void TraceVerbose(int traceCode, params object[] parameters) 
        {
            TraceInternal(TraceEventType.Verbose, traceCode, parameters);
        }
        [Conditional("DEBUG")] 
        public static void TraceInfo(int traceCode)
        { 
            TraceInternal(TraceEventType.Information, traceCode, null); 
        }
        [Conditional("DEBUG")] 
        public static void TraceInfo(int traceCode, params object[] parameters)
        {
            TraceInternal(TraceEventType.Information, traceCode, parameters);
        } 
        [Conditional("DEBUG")]
        public static void TraceWarning(int traceCode) 
        { 
            TraceInternal(TraceEventType.Warning, traceCode, null);
        } 
        [Conditional("DEBUG")]
        public static void TraceWarning(int traceCode, params object[] parameters)
        {
            TraceInternal(TraceEventType.Warning, traceCode, parameters); 
        }
        [Conditional("DEBUG")] 
        public static void TraceError(int traceCode) 
        {
            TraceInternal(TraceEventType.Error, traceCode, null); 
        }
        [Conditional("DEBUG")]
        public static void TraceError(int traceCode, params object[] parameters)
        { 
            TraceInternal(TraceEventType.Error, traceCode, parameters);
        } 
        [Conditional("DEBUG")] 
        public static void TraceCritical(int traceCode)
        { 
            TraceInternal(TraceEventType.Critical, traceCode, null);
        }
        [Conditional("DEBUG")]
        public static void TraceCritical(int traceCode, params object[] parameters) 
        {
            TraceInternal(TraceEventType.Critical, traceCode, parameters); 
        } 

        // 
        // Enable the setting of level explicitly.
        //
        [Conditional("DEBUG")]
        public static void Trace(TraceEventType level, int traceCode) 
        {
            TraceInternal(level, traceCode, null); 
        } 
        [Conditional("DEBUG")]
        public static void Trace(TraceEventType level, int traceCode, params object[] parameters) 
        {
            TraceInternal(level, traceCode, parameters);
        }
 
        //
        // Summary 
        // DebugTrace is an additional level of tracing, intended for 
        // use by the devleopment team during the product development cycle.
        // The trace funcitons need no localization and can be fed arbitrary strings as 
        // the format specifier.
        //
        // Remarks
        // Will be turned off in RETAIL builds. 
        // All tracing is done at the VERBOSE level.
        // 
        // Parameters 
        // format       - a format string using the standard .net string format specifier syntax
        // parameters   - optional parmaters to be embedded in the format string. 
        //
        [Conditional("DEBUG")]
        public static void TraceDebug(string format, params object[] parameters)
        { 
#if DEBUG
            if( DiagnosticUtility.ShouldTraceVerbose ) 
            { 

 
                // Retrieve the string from resources and build the message.
                //
                string message = format;
 
                if( null != parameters && 0 != parameters.Length )
                { 
                    message = String.Format( CultureInfo.InvariantCulture, format, parameters ); 
                }
 

                //
                // If we were passed a null message, at least flag it
                // 
                if( String.IsNullOrEmpty( message ) )
                { 
                    message = "NULL DEBUG TRACE MESSAGE!"; 
                }
                // 
                // Build a trace message conforming to the ETL trace schema and
                // call down through the diagnostic support classes to trace the call.
                //
                InfoCardTraceRecord tr = new InfoCardTraceRecord( 
                                            GetTraceString(TraceCode.GeneralInformation),
                                            message ); 
 
                DiagnosticUtility.DiagnosticTrace.TraceEvent(
                                    TraceEventType.Verbose, 
                                    TraceCode.GeneralInformation,
                                    SR.GetString(GetTraceString(TraceCode.GeneralInformation)),
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    tr, null, message); 
            }
#endif 
        } 

        [Conditional("DEBUG")] 
        public static void TraceDebug(string message)
        {
#if DEBUG
            if( DiagnosticUtility.ShouldTraceVerbose ) 
            {
 
 

                // 
                // If we were passed a null message, at least flag it
                //
                if( String.IsNullOrEmpty( message ) )
                { 
                    message = "NULL DEBUG TRACE MESSAGE!";
                } 
                // 
                // Build a trace message conforming to the ETL trace schema and
                // call down through the diagnostic support classes to trace the call. 
                //
                InfoCardTraceRecord tr = new InfoCardTraceRecord(
                                            GetTraceString(TraceCode.GeneralInformation),
                                            message ); 

                DiagnosticUtility.DiagnosticTrace.TraceEvent( 
                                    TraceEventType.Verbose, 
                                    TraceCode.GeneralInformation,
                                    SR.GetString(GetTraceString(TraceCode.GeneralInformation)), 
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    tr, null, message);
            }
#endif 
        }
 
        // 
        // Summary:
        // Logs the event for the appropriate infocard error code. This code should 
        // match the entries in messages,mc
        // Parameters:
        // code         - the event code to log
        // Notes: 
        // This code may need to be extended to support an array of string parameters. We will do this if our event
        // log messages require it. 
        // 
        private static void LogEvent(EventCode code, string message, EventLogEntryType type)
        { 



 
            using (SafeEventLogHandle handle = SafeEventLogHandle.Construct())
            { 
                string parameter = message; 
                if (null != handle)
                { 
                    if (String.IsNullOrEmpty(parameter))
                    {
                        parameter = SR.GetString(SR.GeneralExceptionMessage);
                    } 

 
                    // 
                    // Report event expects a LPCTSTR* lpStrings. Use GCHandle, instead
                    // of writing code with unsafe because InfoCard client uses this 
                    // and our client cannot contain any unsafe code.
                    //

                    // 
                    // This is the array of LPCTSTRs
                    // 
                    IntPtr[] stringRoots = new IntPtr[1]; 

                    // 
                    // This is to pin the parameter string itself. Use an array here if you want more than 1 string
                    //
                    GCHandle stringParamHandle = new GCHandle();
 
                    //
                    // This is to pin the pointer to the array of LPCTSTRs 
                    // 
                    GCHandle stringsRootHandle = new GCHandle();
 
                    try
                    {
                        //
                        // Pin the IntPtrs (ie array of LPCTSTRs) 
                        //
                        stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned); 
 
                        //
                        // Pin the parameter string itself 
                        //
                        stringParamHandle = GCHandle.Alloc(parameter, GCHandleType.Pinned);

                        // 
                        // Give the intptr address of the pinned string
                        // 
                        stringRoots[0] = stringParamHandle.AddrOfPinnedObject(); 

                        // 
                        // From msdn: The interop marshaler passes only the handle [2nd arg to constructor in our case]
                        // to unmanaged code, and guarantees that the wrapper (passed as the first parameter
                        // to the constructor of the HandleRef) remains alive for the duration of the [PInvoke] call.
                        // 
                        HandleRef data = new HandleRef(handle, stringsRootHandle.AddrOfPinnedObject());
 
 
                        SecurityIdentifier sid = WindowsIdentity.GetCurrent().User;
                        byte[] sidBA = new byte[sid.BinaryLength]; 
                        sid.GetBinaryForm(sidBA, 0);

                        if (!ReportEvent(
                                 handle, 
                                 (short)type,
                                 (ushort)InfoCardEventCategory.General, 
                                 (uint)code, 
                                 sidBA,
                                 1, 
                                 0,
                                 data,
                                 null))
                        { 
                            //
                            // Errors in the eventlog API should be ignored by applications 
                            // 
                            int error = Marshal.GetLastWin32Error();
                            TraceDebug("Failed to report the event with error {0}", error); 
                        }
                    }
                    finally
                    { 
                        if (stringsRootHandle.IsAllocated)
                        { 
                            stringsRootHandle.Free(); 
                        }
 
                        if (stringParamHandle.IsAllocated)
                        {
                            stringParamHandle.Free();
                        } 
                    }
                } 
            } 

        } 

        public static void TraceAndLogException(Exception e)
        {
            bool shouldLog = false; 
            bool isInformational = false;
            InfoCardBaseException ie = e as InfoCardBaseException; 
 
            //
            // We only log if this is an infocard exception that hasnt been previous logged, 
            // and isnt the user cancelled exception.
            //
            if (null != ie && !(ie is UserCancelledException) && !ie.Logged)
            { 
                shouldLog = true;
            } 
            if (shouldLog) 
            {
                // 
                // If this is the parent of a previously logged exception then log as
                // informational.
                // If one of the children is UserCancelled, don't log at all
                // 
                Exception current = ie.InnerException;
                while (null != current) 
                { 
                    if (current is UserCancelledException)
                    { 
                        shouldLog = false;
                        break;
                    }
                    else if (current is InfoCardBaseException) 
                    {
                        if ((current as InfoCardBaseException).Logged) 
                        { 
                            isInformational = true;
                        } 
                    }
                    current = current.InnerException;
                }
            } 
            if (shouldLog)
            { 
                EventLogEntryType logType = isInformational ? EventLogEntryType.Information : EventLogEntryType.Error; 
                string message = ie.Message;
                if (!isInformational) 
                {
                    message = BuildMessage(ie);
                }
                LogEvent((EventCode)ie.NativeHResult, message, logType); 

            } 
            TraceException(e); 
        }
 
        private static string BuildMessage(InfoCardBaseException ie)
        {

            Exception ex = ie; 
            String errString = ex.Message + "\n";
 
            if (null != ex.InnerException) 
            {
                while (null != ex.InnerException) 
                {
                    errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture,
                                         SR.GetString(SR.InnerExceptionTraceFormat),
                                         ex.InnerException.Message); 
                    ex = ex.InnerException;
                } 
                errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture, 
                                         SR.GetString(SR.CallStackTraceFormat),
                                         ie.ToString()); 

            }
            else
            { 
                if (!String.IsNullOrEmpty(Environment.StackTrace))
                { 
                    errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture, 
                                            SR.GetString(SR.CallStackTraceFormat),
                                            Environment.StackTrace); 
                }
            }

            return errString; 

        } 
        // 
        // Summary:
        // Logs a general exception in the event log 
        // Parameters:
        // e        - the exception to log.
        //
        [Conditional("DEBUG")] 
        public static void TraceException(Exception e)
        { 
            Exception current = e; 
            int indent = 0;
            while (null != current) 
            {
                TraceDebug("{0}Exception: message={1}\n stack trace={2}",
                                new string(' ', indent * 2),
                                e.Message, 
                                e.StackTrace);
                current = current.InnerException; 
                indent++; 
            }
 
        }

        //
        // Summary 
        //  Throw an exception and log an error in the event log
        // 
        public static Exception ThrowHelperError(Exception e) 
        {
            TraceAndLogException(e); 
            return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
        }

 
        //
        // Summary 
        // Throw an exception but don't log in the event log 
        //
        public static Exception ThrowHelperErrorWithNoLogging(Exception e) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
        }
 

        // 
        // Summary 
        //  Throw an exception and log a warning in the event log
        // 
        public static Exception ThrowHelperWarning(Exception e)
        {
            TraceAndLogException(e);
            return DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(e); 
        }
 
        // 
        // Summary
        //  Throw an exception and log a critical event in the event log 
        //
        public static Exception ThrowHelperCritical(Exception e)
        {
            TraceAndLogException(e); 
            return DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(e);
        } 
 
        //
        // Summary: 
        // Throws an infocard argument exception. Currently mapped to a communication exception,
        //
        public static void ThrowInvalidArgumentConditional(bool condition, string argument)
        { 
            if (condition)
            { 
                string message = string.Format( 
                                    System.Globalization.CultureInfo.CurrentUICulture,
                                    SR.GetString(SR.ServiceInvalidArgument), 
                                    argument);
                throw ThrowHelperError(new InfoCardArgumentException(message));
            }
        } 

 
 
        //
        // Summary 
        //  Throw an ArgumentNullException and log an error in the event log
        //
        public static Exception ThrowHelperArgumentNull(string err)
        { 

            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err); 
        } 

        // 
        // Summary
        //  Throw an ArgumentException and log an error in the event log
        //
        public static Exception ThrowHelperArgument(string message) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(message); 
        } 

        // 
        // Summary
        //  Throw an ArgumentNullException and log an error in the event log
        //
        public static Exception ThrowHelperArgumentNull(string err, string message) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err, message); 
        } 

        // 
        // Summary
        // The following series of calls enable finer grained control over tracing in the client
        // All calls simply delegate down to the indigo DiagnosticTrace implementation which
        // triggers it's behaviour based on the currently configured listeners. 
        //
        // Remarks 
        // Typical usage is 
        // if( IDT.ShouldTraceVerbose() )
        // { 
        //     string toTrace = this.SafeDumpState();
        //     IDT.TraceVerbose( InfocardTraceCode.InfoCardCreated, toTrace );
        // }
        // 
        public static bool ShouldTrace(TraceEventType type)
        { 
            return DiagnosticUtility.ShouldTrace(type); 
        }
        public static bool ShouldTraceCritical 
        {
            get { return DiagnosticUtility.ShouldTraceCritical; }
        }
        public static bool ShouldTraceError 
        {
            get { return DiagnosticUtility.ShouldTraceError; } 
        } 
        public static bool ShouldTraceWarning
        { 
            get { return DiagnosticUtility.ShouldTraceWarning; }
        }
        public static bool ShouldTraceInformation
        { 
            get { return DiagnosticUtility.ShouldTraceInformation; }
        } 
        public static bool ShouldTraceVerbose 
        {
            get { return DiagnosticUtility.ShouldTraceVerbose; } 
        }


        // 
        // Summary
        // Expose the activity ids associated with the current flow of activity. 
        // ActivityIDs allow the correlation of events across process and managed / unmanaged bounda 
        // Normally they are managed implicitly. The .net runtime will ensure they flow across thread
        // intra-process ( appdomain ) boundaries, and the indigo runtime will ensure they 
        // flow across indigo interactions ( cross process and cross machine ).
        // We have a couple of responsibilities:
        // When transitioning from mananged to unmanaged code:
        //      grab the activity id 
        //      pass it across to native code through the activityID rpc parameter.
        // When transitioning from unmanaged code 
        //      call SetActivityId passing in the received id. 
        //
        // Remarks 
        // Trace calls automatically attach the activityID on all calls.
        //
        public static Guid GetActivityId()
        { 
            return System.ServiceModel.Diagnostics.DiagnosticTrace.ActivityId;
        } 
        public static void SetActivityId(Guid activityId) 
        {
            // 
            // This will trace by default at level verbose.
            //
            System.ServiceModel.Diagnostics.DiagnosticTrace.ActivityId = activityId;
        } 

        // 
        // Summary 
        // The main trace function. Responsible for extracting the appropriate string
        // from the application's resource file, formatting the string with the set of paramters 
        // if appropriate,
        // and passing the request down to the IndigoDiagnostics classes.
        //
        // Parameters 
        // level        - the level to trace at. verbose <= level <= critical
        // code         - the infocard trace code - a unique numeric / string identifier. 
        // parameters   - an optional set of parameters used to supply additional diagnostic information 
        //
        // Remarks 
        // Trace calls automatically attach the activityID on all calls.
        //
        [Conditional("DEBUG")]
        private static void TraceInternal( 
                            TraceEventType level,
                            int traceCode, 
                            params object[] parameters) 
        {
#if DEBUG 
            if( DiagnosticUtility.ShouldTrace( level ) )
            {
                //
                // Retrieve the string from resources and build the message. 
                //
#if INFOCARD_CLIENT 
                string message = SR.GetString(GetTraceString(traceCode)); 
#else
                string message = SR.GetString(traceCode); 
#endif
                Assert( !String.IsNullOrEmpty( message ), "resource string lookup failed!!!" );

                if( !String.IsNullOrEmpty( message ) && null != parameters ) 
                {
                    try 
                    { 
                        message = String.Format(
                                    System.Globalization.CultureInfo.CurrentUICulture, 
                                    message,
                                    parameters );
                    }
                    catch( FormatException f ) 
                    {
                        Assert( false, "Invalid format: " + traceCode ); 
                        TraceException( f ); 
                        message = SR.GetString( SR.GeneralTraceMessage, traceCode );
 
                    }

                }
 
                //
                // Build a trace message conforming to the ETL trace schema and 
                // call down through the diagnostic support classes to trace the call. 
                //
                DiagnosticUtility.DiagnosticTrace.TraceEvent( level, 
                                            traceCode,
                                    SR.GetString(GetTraceString(traceCode)),
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    new InfoCardTraceRecord( GetTraceString(traceCode), message ), null, message); 

            } 
#endif 
        }
 

    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards.Diagnostics
{ 
    using System;
    using System.Xml; 
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.ComponentModel;    //win32exception
    using System.Runtime.InteropServices;
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution; 
    using Microsoft.Win32.SafeHandles;
    using System.Security; 
    using System.Security.Principal; 
    using System.Runtime;
    using System.ServiceModel.Diagnostics; 
    using System.Threading;

    //
    // For InfoCardBaseException 
    //
    using System.IdentityModel.Selectors; 
 
    // Summary
    // InfoCardTrace is the main driver class for the managed tracing infrastructure. 
    // Essentially it is a wrapper over the Indigo DiagnosticsAndTracing classes.
    // Externally a facade of simple TraceXXXX calls is provided which
    // internally thunk across to the indigo classes to perform the work.
    // 
    // The trace class also provides support for flowing of correlation ids allowing
    // tracing of requests across process and managed / unmanaged boundaries 
    // See the Infocard Tracing documentation at http://team/sites/infocard for 
    // detail on configuration and usage.
    // 
    // Remarks
    // All functions are thread safe
    //
    // Example usage looks like: 
    // using IDT=Microsoft.InfoCards.Diagnostics.InfoCardTrace
    // IDT.TraceVerbose( InfoCardTraceCode.StoreInvalidKey, myKey ); 
    // IDT.TraceDebug( "Got an infocard {0} with name {1}", card, card.Name ); 
    //
    // 
    static class InfoCardTrace
    {
        static class TraceCode
        { 
            public const int IdentityModelSelectors = 0xD0000;
            public const int GeneralInformation = TraceCode.IdentityModelSelectors | 0X0001; 
            public const int StoreLoading = TraceCode.IdentityModelSelectors | 0X0002; 
            public const int StoreBeginTransaction = TraceCode.IdentityModelSelectors | 0X0003;
            public const int StoreCommitTransaction = TraceCode.IdentityModelSelectors | 0X0004; 
            public const int StoreRollbackTransaction = TraceCode.IdentityModelSelectors | 0X0005;
            public const int StoreClosing = TraceCode.IdentityModelSelectors | 0X0006;
            public const int StoreFailedToOpenStore = TraceCode.IdentityModelSelectors | 0X0007;
            public const int StoreSignatureNotValid = TraceCode.IdentityModelSelectors | 0X0008; 
            public const int StoreDeleting = TraceCode.IdentityModelSelectors | 0X0009;
        } 
 
        static Dictionary traceCodes = new Dictionary(9)
        { 
            { TraceCode.GeneralInformation, "GeneralInformation" },
            { TraceCode.StoreLoading, "StoreLoading" },
            { TraceCode.StoreBeginTransaction, "StoreBeginTransaction" },
            { TraceCode.StoreCommitTransaction, "StoreCommitTransaction" }, 
            { TraceCode.StoreRollbackTransaction, "StoreRollbackTransaction" },
            { TraceCode.StoreClosing, "StoreClosing" }, 
            { TraceCode.StoreFailedToOpenStore, "StoreFailedToOpenStore" }, 
            { TraceCode.StoreSignatureNotValid, "StoreSignatureNotValid" },
            { TraceCode.StoreDeleting, "StoreDeleting" }, 
        };

        static string GetTraceString(int traceCode)
        { 
            return traceCodes[traceCode];
        } 
 
        static string GetMsdnTraceCode(int traceCode)
        { 
            return DiagnosticTrace.GenerateMsdnTraceCode("System.IdentityModel.Selectors", GetTraceString(traceCode));
        }

        [DllImport("advapi32", 
                CharSet = CharSet.Unicode,
                EntryPoint = "ReportEventW", 
                ExactSpelling = true, 
                SetLastError = true)]
        private static extern bool ReportEvent([In] SafeHandle hEventLog, 
                                               [In] short type,
                                               [In] ushort category,
                                               [In] uint eventID,
                                               [In] byte[] userSID, 
                                               [In] short numStrings,
                                               [In] int dataLen, 
                                               [In] HandleRef strings, 
                                               [In] byte[] rawData);
 


        //
        // Summary: 
        // Provides a wrapper over a handle retrieved by RegisterEventSource
        // 
        internal class SafeEventLogHandle : SafeHandle 
        {
 
            [DllImport("advapi32",
                    CharSet = CharSet.Unicode,
                    EntryPoint = "RegisterEventSourceW",
                    ExactSpelling = true, 
                    SetLastError = true)]
            private static extern SafeEventLogHandle RegisterEventSource(string uncServerName, string sourceName); 
 
            [DllImport("advapi32",
                    CharSet = CharSet.Unicode, 
                    EntryPoint = "DeregisterEventSource",
                    ExactSpelling = true,
                    SetLastError = true)]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
            private static extern bool DeregisterEventSource(IntPtr eventLog);
 
            public static SafeEventLogHandle Construct() 
            {
                SafeEventLogHandle h = RegisterEventSource(null, InfoCardTrace.InfoCardEventSource); 

                if (null == h || h.IsInvalid)
                {
                    int error = Marshal.GetLastWin32Error(); 
                    TraceDebug("failed to registereventsource with error {0}", error);
 
                } 
                return h;
            } 
            //
            // Summary:
            // Manages the lifetime of a native handle retrieved by register event source.
            // Parameters: 
            // handle - the handle to wrap.
            // 
            private SafeEventLogHandle() 
                : base(IntPtr.Zero, true)
            { 


            }
 

            public override bool IsInvalid 
            { 
                get
                { 
                    return (IntPtr.Zero == base.handle);
                }
            }
 
            //
            // Summary: 
            // Releases the eventlog handle. 
            //
            protected override bool ReleaseHandle() 
            {
#pragma warning suppress 56523
                return DeregisterEventSource(base.handle);
 
            }
        } 
 
        //
        // Summary: 
        // Returns whether the current exception is fatal.
        // Notes:
        // Currently this delegates to the code in ExceptionUtility.cs
        // 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public static bool IsFatal(Exception e) 
        { 
            return Fx.IsFatal(e);
        } 

        public static TimerCallback ThunkCallback(TimerCallback callback)
        {
            return Fx.ThunkCallback(callback); 
        }
 
        public static WaitCallback ThunkCallback(WaitCallback callback) 
        {
            return Fx.ThunkCallback(callback); 
        }

        public static void CloseInvalidOutSafeHandle(SafeHandle handle)
        { 
            Utility.CloseInvalidOutSafeHandle(handle);
        } 
 
        //
        // The event source we log against. May need to be updated should our name change before rtm 
        //

        const string InfoCardEventSource = "CardSpace 4.0.0.0";
 

        // 
        // Summary: 
        // Writes an audit message to the application's event log
        // 
        public static void Audit(EventCode code)
        {
            LogEvent(code, null, EventLogEntryType.Information);
        } 

        public static void Audit(EventCode code, string message) 
        { 
            LogEvent(code, message, EventLogEntryType.Information);
        } 
        public static void Assert(bool condition, string format, params object[] parameters)
        {

            if (condition) 
            {
                return; 
            } 

            string message = format; 
            if (null != parameters && 0 != parameters.Length)
            {
                message = String.Format(CultureInfo.InvariantCulture, format, parameters);
            } 
            TraceDebug("An assertion fired: {0}", message);
#if DEBUG 
            // 
            // Let DebugAssert handle this for us....
            // If not in debugger,  Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue 
            // If in debugger, will hit a DebugBreak()
            //
            DiagnosticUtility.DebugAssert( false, message );
#else 
            //
            // Retail assert failfasts service 
            // 
            FailFast(message);
#endif 

        }

 
        [Conditional("DEBUG")]
        public static void DebugAssert(bool condition, string format, params object[] parameters) 
        { 
#if DEBUG
            if( condition ) 
            {
                return;
            }
 
            string message = format;
            if( null != parameters && 0 != parameters.Length ) 
            { 
                message = String.Format( CultureInfo.InvariantCulture, format, parameters );
            } 
            TraceDebug( "An assertion fired: {0}", message );
            if( Debugger.IsAttached )
            {
                Debugger.Launch(); 
                Debugger.Break();
            } 
            DiagnosticUtility.DebugAssert( false, message ); 
            FailFast( message );
#endif 
        }


        // 
        // Facade functions to allow simple call semantics.
        // 
        public static void FailFast(string message) 
        {
            DiagnosticUtility.FailFast(message); 
        }
        [Conditional("DEBUG")]
        public static void TraceVerbose(int traceCode)
        { 
            TraceInternal(TraceEventType.Verbose, traceCode, null);
 
        } 
        [Conditional("DEBUG")]
        public static void TraceVerbose(int traceCode, params object[] parameters) 
        {
            TraceInternal(TraceEventType.Verbose, traceCode, parameters);
        }
        [Conditional("DEBUG")] 
        public static void TraceInfo(int traceCode)
        { 
            TraceInternal(TraceEventType.Information, traceCode, null); 
        }
        [Conditional("DEBUG")] 
        public static void TraceInfo(int traceCode, params object[] parameters)
        {
            TraceInternal(TraceEventType.Information, traceCode, parameters);
        } 
        [Conditional("DEBUG")]
        public static void TraceWarning(int traceCode) 
        { 
            TraceInternal(TraceEventType.Warning, traceCode, null);
        } 
        [Conditional("DEBUG")]
        public static void TraceWarning(int traceCode, params object[] parameters)
        {
            TraceInternal(TraceEventType.Warning, traceCode, parameters); 
        }
        [Conditional("DEBUG")] 
        public static void TraceError(int traceCode) 
        {
            TraceInternal(TraceEventType.Error, traceCode, null); 
        }
        [Conditional("DEBUG")]
        public static void TraceError(int traceCode, params object[] parameters)
        { 
            TraceInternal(TraceEventType.Error, traceCode, parameters);
        } 
        [Conditional("DEBUG")] 
        public static void TraceCritical(int traceCode)
        { 
            TraceInternal(TraceEventType.Critical, traceCode, null);
        }
        [Conditional("DEBUG")]
        public static void TraceCritical(int traceCode, params object[] parameters) 
        {
            TraceInternal(TraceEventType.Critical, traceCode, parameters); 
        } 

        // 
        // Enable the setting of level explicitly.
        //
        [Conditional("DEBUG")]
        public static void Trace(TraceEventType level, int traceCode) 
        {
            TraceInternal(level, traceCode, null); 
        } 
        [Conditional("DEBUG")]
        public static void Trace(TraceEventType level, int traceCode, params object[] parameters) 
        {
            TraceInternal(level, traceCode, parameters);
        }
 
        //
        // Summary 
        // DebugTrace is an additional level of tracing, intended for 
        // use by the devleopment team during the product development cycle.
        // The trace funcitons need no localization and can be fed arbitrary strings as 
        // the format specifier.
        //
        // Remarks
        // Will be turned off in RETAIL builds. 
        // All tracing is done at the VERBOSE level.
        // 
        // Parameters 
        // format       - a format string using the standard .net string format specifier syntax
        // parameters   - optional parmaters to be embedded in the format string. 
        //
        [Conditional("DEBUG")]
        public static void TraceDebug(string format, params object[] parameters)
        { 
#if DEBUG
            if( DiagnosticUtility.ShouldTraceVerbose ) 
            { 

 
                // Retrieve the string from resources and build the message.
                //
                string message = format;
 
                if( null != parameters && 0 != parameters.Length )
                { 
                    message = String.Format( CultureInfo.InvariantCulture, format, parameters ); 
                }
 

                //
                // If we were passed a null message, at least flag it
                // 
                if( String.IsNullOrEmpty( message ) )
                { 
                    message = "NULL DEBUG TRACE MESSAGE!"; 
                }
                // 
                // Build a trace message conforming to the ETL trace schema and
                // call down through the diagnostic support classes to trace the call.
                //
                InfoCardTraceRecord tr = new InfoCardTraceRecord( 
                                            GetTraceString(TraceCode.GeneralInformation),
                                            message ); 
 
                DiagnosticUtility.DiagnosticTrace.TraceEvent(
                                    TraceEventType.Verbose, 
                                    TraceCode.GeneralInformation,
                                    SR.GetString(GetTraceString(TraceCode.GeneralInformation)),
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    tr, null, message); 
            }
#endif 
        } 

        [Conditional("DEBUG")] 
        public static void TraceDebug(string message)
        {
#if DEBUG
            if( DiagnosticUtility.ShouldTraceVerbose ) 
            {
 
 

                // 
                // If we were passed a null message, at least flag it
                //
                if( String.IsNullOrEmpty( message ) )
                { 
                    message = "NULL DEBUG TRACE MESSAGE!";
                } 
                // 
                // Build a trace message conforming to the ETL trace schema and
                // call down through the diagnostic support classes to trace the call. 
                //
                InfoCardTraceRecord tr = new InfoCardTraceRecord(
                                            GetTraceString(TraceCode.GeneralInformation),
                                            message ); 

                DiagnosticUtility.DiagnosticTrace.TraceEvent( 
                                    TraceEventType.Verbose, 
                                    TraceCode.GeneralInformation,
                                    SR.GetString(GetTraceString(TraceCode.GeneralInformation)), 
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    tr, null, message);
            }
#endif 
        }
 
        // 
        // Summary:
        // Logs the event for the appropriate infocard error code. This code should 
        // match the entries in messages,mc
        // Parameters:
        // code         - the event code to log
        // Notes: 
        // This code may need to be extended to support an array of string parameters. We will do this if our event
        // log messages require it. 
        // 
        private static void LogEvent(EventCode code, string message, EventLogEntryType type)
        { 



 
            using (SafeEventLogHandle handle = SafeEventLogHandle.Construct())
            { 
                string parameter = message; 
                if (null != handle)
                { 
                    if (String.IsNullOrEmpty(parameter))
                    {
                        parameter = SR.GetString(SR.GeneralExceptionMessage);
                    } 

 
                    // 
                    // Report event expects a LPCTSTR* lpStrings. Use GCHandle, instead
                    // of writing code with unsafe because InfoCard client uses this 
                    // and our client cannot contain any unsafe code.
                    //

                    // 
                    // This is the array of LPCTSTRs
                    // 
                    IntPtr[] stringRoots = new IntPtr[1]; 

                    // 
                    // This is to pin the parameter string itself. Use an array here if you want more than 1 string
                    //
                    GCHandle stringParamHandle = new GCHandle();
 
                    //
                    // This is to pin the pointer to the array of LPCTSTRs 
                    // 
                    GCHandle stringsRootHandle = new GCHandle();
 
                    try
                    {
                        //
                        // Pin the IntPtrs (ie array of LPCTSTRs) 
                        //
                        stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned); 
 
                        //
                        // Pin the parameter string itself 
                        //
                        stringParamHandle = GCHandle.Alloc(parameter, GCHandleType.Pinned);

                        // 
                        // Give the intptr address of the pinned string
                        // 
                        stringRoots[0] = stringParamHandle.AddrOfPinnedObject(); 

                        // 
                        // From msdn: The interop marshaler passes only the handle [2nd arg to constructor in our case]
                        // to unmanaged code, and guarantees that the wrapper (passed as the first parameter
                        // to the constructor of the HandleRef) remains alive for the duration of the [PInvoke] call.
                        // 
                        HandleRef data = new HandleRef(handle, stringsRootHandle.AddrOfPinnedObject());
 
 
                        SecurityIdentifier sid = WindowsIdentity.GetCurrent().User;
                        byte[] sidBA = new byte[sid.BinaryLength]; 
                        sid.GetBinaryForm(sidBA, 0);

                        if (!ReportEvent(
                                 handle, 
                                 (short)type,
                                 (ushort)InfoCardEventCategory.General, 
                                 (uint)code, 
                                 sidBA,
                                 1, 
                                 0,
                                 data,
                                 null))
                        { 
                            //
                            // Errors in the eventlog API should be ignored by applications 
                            // 
                            int error = Marshal.GetLastWin32Error();
                            TraceDebug("Failed to report the event with error {0}", error); 
                        }
                    }
                    finally
                    { 
                        if (stringsRootHandle.IsAllocated)
                        { 
                            stringsRootHandle.Free(); 
                        }
 
                        if (stringParamHandle.IsAllocated)
                        {
                            stringParamHandle.Free();
                        } 
                    }
                } 
            } 

        } 

        public static void TraceAndLogException(Exception e)
        {
            bool shouldLog = false; 
            bool isInformational = false;
            InfoCardBaseException ie = e as InfoCardBaseException; 
 
            //
            // We only log if this is an infocard exception that hasnt been previous logged, 
            // and isnt the user cancelled exception.
            //
            if (null != ie && !(ie is UserCancelledException) && !ie.Logged)
            { 
                shouldLog = true;
            } 
            if (shouldLog) 
            {
                // 
                // If this is the parent of a previously logged exception then log as
                // informational.
                // If one of the children is UserCancelled, don't log at all
                // 
                Exception current = ie.InnerException;
                while (null != current) 
                { 
                    if (current is UserCancelledException)
                    { 
                        shouldLog = false;
                        break;
                    }
                    else if (current is InfoCardBaseException) 
                    {
                        if ((current as InfoCardBaseException).Logged) 
                        { 
                            isInformational = true;
                        } 
                    }
                    current = current.InnerException;
                }
            } 
            if (shouldLog)
            { 
                EventLogEntryType logType = isInformational ? EventLogEntryType.Information : EventLogEntryType.Error; 
                string message = ie.Message;
                if (!isInformational) 
                {
                    message = BuildMessage(ie);
                }
                LogEvent((EventCode)ie.NativeHResult, message, logType); 

            } 
            TraceException(e); 
        }
 
        private static string BuildMessage(InfoCardBaseException ie)
        {

            Exception ex = ie; 
            String errString = ex.Message + "\n";
 
            if (null != ex.InnerException) 
            {
                while (null != ex.InnerException) 
                {
                    errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture,
                                         SR.GetString(SR.InnerExceptionTraceFormat),
                                         ex.InnerException.Message); 
                    ex = ex.InnerException;
                } 
                errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture, 
                                         SR.GetString(SR.CallStackTraceFormat),
                                         ie.ToString()); 

            }
            else
            { 
                if (!String.IsNullOrEmpty(Environment.StackTrace))
                { 
                    errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture, 
                                            SR.GetString(SR.CallStackTraceFormat),
                                            Environment.StackTrace); 
                }
            }

            return errString; 

        } 
        // 
        // Summary:
        // Logs a general exception in the event log 
        // Parameters:
        // e        - the exception to log.
        //
        [Conditional("DEBUG")] 
        public static void TraceException(Exception e)
        { 
            Exception current = e; 
            int indent = 0;
            while (null != current) 
            {
                TraceDebug("{0}Exception: message={1}\n stack trace={2}",
                                new string(' ', indent * 2),
                                e.Message, 
                                e.StackTrace);
                current = current.InnerException; 
                indent++; 
            }
 
        }

        //
        // Summary 
        //  Throw an exception and log an error in the event log
        // 
        public static Exception ThrowHelperError(Exception e) 
        {
            TraceAndLogException(e); 
            return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
        }

 
        //
        // Summary 
        // Throw an exception but don't log in the event log 
        //
        public static Exception ThrowHelperErrorWithNoLogging(Exception e) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
        }
 

        // 
        // Summary 
        //  Throw an exception and log a warning in the event log
        // 
        public static Exception ThrowHelperWarning(Exception e)
        {
            TraceAndLogException(e);
            return DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(e); 
        }
 
        // 
        // Summary
        //  Throw an exception and log a critical event in the event log 
        //
        public static Exception ThrowHelperCritical(Exception e)
        {
            TraceAndLogException(e); 
            return DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(e);
        } 
 
        //
        // Summary: 
        // Throws an infocard argument exception. Currently mapped to a communication exception,
        //
        public static void ThrowInvalidArgumentConditional(bool condition, string argument)
        { 
            if (condition)
            { 
                string message = string.Format( 
                                    System.Globalization.CultureInfo.CurrentUICulture,
                                    SR.GetString(SR.ServiceInvalidArgument), 
                                    argument);
                throw ThrowHelperError(new InfoCardArgumentException(message));
            }
        } 

 
 
        //
        // Summary 
        //  Throw an ArgumentNullException and log an error in the event log
        //
        public static Exception ThrowHelperArgumentNull(string err)
        { 

            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err); 
        } 

        // 
        // Summary
        //  Throw an ArgumentException and log an error in the event log
        //
        public static Exception ThrowHelperArgument(string message) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(message); 
        } 

        // 
        // Summary
        //  Throw an ArgumentNullException and log an error in the event log
        //
        public static Exception ThrowHelperArgumentNull(string err, string message) 
        {
            return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err, message); 
        } 

        // 
        // Summary
        // The following series of calls enable finer grained control over tracing in the client
        // All calls simply delegate down to the indigo DiagnosticTrace implementation which
        // triggers it's behaviour based on the currently configured listeners. 
        //
        // Remarks 
        // Typical usage is 
        // if( IDT.ShouldTraceVerbose() )
        // { 
        //     string toTrace = this.SafeDumpState();
        //     IDT.TraceVerbose( InfocardTraceCode.InfoCardCreated, toTrace );
        // }
        // 
        public static bool ShouldTrace(TraceEventType type)
        { 
            return DiagnosticUtility.ShouldTrace(type); 
        }
        public static bool ShouldTraceCritical 
        {
            get { return DiagnosticUtility.ShouldTraceCritical; }
        }
        public static bool ShouldTraceError 
        {
            get { return DiagnosticUtility.ShouldTraceError; } 
        } 
        public static bool ShouldTraceWarning
        { 
            get { return DiagnosticUtility.ShouldTraceWarning; }
        }
        public static bool ShouldTraceInformation
        { 
            get { return DiagnosticUtility.ShouldTraceInformation; }
        } 
        public static bool ShouldTraceVerbose 
        {
            get { return DiagnosticUtility.ShouldTraceVerbose; } 
        }


        // 
        // Summary
        // Expose the activity ids associated with the current flow of activity. 
        // ActivityIDs allow the correlation of events across process and managed / unmanaged bounda 
        // Normally they are managed implicitly. The .net runtime will ensure they flow across thread
        // intra-process ( appdomain ) boundaries, and the indigo runtime will ensure they 
        // flow across indigo interactions ( cross process and cross machine ).
        // We have a couple of responsibilities:
        // When transitioning from mananged to unmanaged code:
        //      grab the activity id 
        //      pass it across to native code through the activityID rpc parameter.
        // When transitioning from unmanaged code 
        //      call SetActivityId passing in the received id. 
        //
        // Remarks 
        // Trace calls automatically attach the activityID on all calls.
        //
        public static Guid GetActivityId()
        { 
            return System.ServiceModel.Diagnostics.DiagnosticTrace.ActivityId;
        } 
        public static void SetActivityId(Guid activityId) 
        {
            // 
            // This will trace by default at level verbose.
            //
            System.ServiceModel.Diagnostics.DiagnosticTrace.ActivityId = activityId;
        } 

        // 
        // Summary 
        // The main trace function. Responsible for extracting the appropriate string
        // from the application's resource file, formatting the string with the set of paramters 
        // if appropriate,
        // and passing the request down to the IndigoDiagnostics classes.
        //
        // Parameters 
        // level        - the level to trace at. verbose <= level <= critical
        // code         - the infocard trace code - a unique numeric / string identifier. 
        // parameters   - an optional set of parameters used to supply additional diagnostic information 
        //
        // Remarks 
        // Trace calls automatically attach the activityID on all calls.
        //
        [Conditional("DEBUG")]
        private static void TraceInternal( 
                            TraceEventType level,
                            int traceCode, 
                            params object[] parameters) 
        {
#if DEBUG 
            if( DiagnosticUtility.ShouldTrace( level ) )
            {
                //
                // Retrieve the string from resources and build the message. 
                //
#if INFOCARD_CLIENT 
                string message = SR.GetString(GetTraceString(traceCode)); 
#else
                string message = SR.GetString(traceCode); 
#endif
                Assert( !String.IsNullOrEmpty( message ), "resource string lookup failed!!!" );

                if( !String.IsNullOrEmpty( message ) && null != parameters ) 
                {
                    try 
                    { 
                        message = String.Format(
                                    System.Globalization.CultureInfo.CurrentUICulture, 
                                    message,
                                    parameters );
                    }
                    catch( FormatException f ) 
                    {
                        Assert( false, "Invalid format: " + traceCode ); 
                        TraceException( f ); 
                        message = SR.GetString( SR.GeneralTraceMessage, traceCode );
 
                    }

                }
 
                //
                // Build a trace message conforming to the ETL trace schema and 
                // call down through the diagnostic support classes to trace the call. 
                //
                DiagnosticUtility.DiagnosticTrace.TraceEvent( level, 
                                            traceCode,
                                    SR.GetString(GetTraceString(traceCode)),
                                    GetMsdnTraceCode(TraceCode.GeneralInformation),
                                    new InfoCardTraceRecord( GetTraceString(traceCode), message ), null, message); 

            } 
#endif 
        }
 

    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

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