Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Diagnostics / Managed / Microsoft / InfoCards / Diagnostics / InfoCardTrace.cs / 1 / InfoCardTrace.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.InfoCards.Diagnostics { using System; using System.Xml; 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.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 ); // // internal static class InfoCardTrace { [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 DiagnosticUtility.IsFatal( e ); } public static TimerCallback ThunkCallback( TimerCallback callback ) { return DiagnosticUtility.Utility.ThunkCallback( callback ); } public static WaitCallback ThunkCallback( WaitCallback callback ) { return DiagnosticUtility.Utility.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 3.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( TraceCode code ) { TraceInternal( TraceEventType.Verbose, code, null ); } [Conditional( "DEBUG" )] public static void TraceVerbose( TraceCode code, params object[ ] parameters ) { TraceInternal( TraceEventType.Verbose, code, parameters ); } [Conditional( "DEBUG" )] public static void TraceInfo( TraceCode code ) { TraceInternal( TraceEventType.Information, code, null ); } [Conditional( "DEBUG" )] public static void TraceInfo( TraceCode code, params object[ ] parameters ) { TraceInternal( TraceEventType.Information, code, parameters ); } [Conditional( "DEBUG" )] public static void TraceWarning( TraceCode code ) { TraceInternal( TraceEventType.Warning, code, null ); } [Conditional( "DEBUG" )] public static void TraceWarning( TraceCode code, params object[ ] parameters ) { TraceInternal( TraceEventType.Warning, code, parameters ); } [Conditional( "DEBUG" )] public static void TraceError( TraceCode code ) { TraceInternal( TraceEventType.Error, code, null ); } [Conditional( "DEBUG" )] public static void TraceError( TraceCode code, params object[ ] parameters ) { TraceInternal( TraceEventType.Error, code, parameters ); } [Conditional( "DEBUG" )] public static void TraceCritical( TraceCode code ) { TraceInternal( TraceEventType.Critical, code, null ); } [Conditional( "DEBUG" )] public static void TraceCritical( TraceCode code, params object[ ] parameters ) { TraceInternal( TraceEventType.Critical, code, parameters ); } // // Enable the setting of level explicitly. // [Conditional( "DEBUG" )] public static void Trace( TraceEventType level, TraceCode code ) { TraceInternal( level, code, null ); } [Conditional( "DEBUG" )] public static void Trace( TraceEventType level, TraceCode code, params object[ ] parameters ) { TraceInternal( level, code, 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( TraceCode.GeneralInformation.ToString(), message ); DiagnosticUtility.DiagnosticTrace.TraceEvent( TraceEventType.Verbose, TraceCode.GeneralInformation, message, tr ); } #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( TraceCode.GeneralInformation.ToString(), message ); DiagnosticUtility.DiagnosticTrace.TraceEvent( TraceEventType.Verbose, TraceCode.GeneralInformation, message, tr ); } #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, TraceCode code, 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( code.ToString() ); #else string message = SR.GetString( (int)code ); #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: " + code ); TraceException( f ); message = SR.GetString( SR.GeneralTraceMessage, code ); } } // // 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, code, message, new InfoCardTraceRecord( code.ToString(), message ) ); } #endif } } } // 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
- MinimizableAttributeTypeConverter.cs
- XLinq.cs
- BufferAllocator.cs
- WhiteSpaceTrimStringConverter.cs
- StringFreezingAttribute.cs
- SelfIssuedTokenFactoryCredential.cs
- Int32KeyFrameCollection.cs
- NullableLongAverageAggregationOperator.cs
- CommonDialog.cs
- XmlAtomicValue.cs
- Rect3D.cs
- SiteMapNodeItem.cs
- ActivityDelegate.cs
- SqlNode.cs
- Property.cs
- RuleInfoComparer.cs
- ButtonChrome.cs
- DataTemplateKey.cs
- XmlEntityReference.cs
- UInt32Converter.cs
- BooleanAnimationUsingKeyFrames.cs
- PathSegment.cs
- Literal.cs
- VectorKeyFrameCollection.cs
- streamingZipPartStream.cs
- WinFormsUtils.cs
- ServiceModelEnumValidator.cs
- BulletChrome.cs
- WebServiceMethodData.cs
- SecurityManager.cs
- QueryResponse.cs
- typedescriptorpermission.cs
- path.cs
- LogEntryHeaderv1Deserializer.cs
- Line.cs
- NullableBoolConverter.cs
- BitmapEffectInput.cs
- hresults.cs
- OdbcError.cs
- CodeTypeOfExpression.cs
- BindingEditor.xaml.cs
- SQLDateTimeStorage.cs
- SchemaElement.cs
- Activator.cs
- MdbDataFileEditor.cs
- SqlInfoMessageEvent.cs
- FileDialogCustomPlaces.cs
- SharedDp.cs
- RecordConverter.cs
- BooleanStorage.cs
- ToolTip.cs
- DnsPermission.cs
- TypeForwardedToAttribute.cs
- Win32PrintDialog.cs
- NavigationWindowAutomationPeer.cs
- SmiEventSink.cs
- DateTimeValueSerializerContext.cs
- MenuItemStyleCollectionEditor.cs
- MDIClient.cs
- FactoryGenerator.cs
- WebBaseEventKeyComparer.cs
- MimeMapping.cs
- VirtualizingPanel.cs
- ReadOnlyDictionary.cs
- SiteMapNodeItem.cs
- CDSsyncETWBCLProvider.cs
- BinaryEditor.cs
- DecimalAnimationUsingKeyFrames.cs
- EventSinkHelperWriter.cs
- PopupEventArgs.cs
- ReliabilityContractAttribute.cs
- Console.cs
- DependencyObjectType.cs
- Matrix3D.cs
- Visual3DCollection.cs
- PropertyPanel.cs
- ObjectParameterCollection.cs
- AppDomainAttributes.cs
- Validator.cs
- JulianCalendar.cs
- ErrorHandler.cs
- Parameter.cs
- BamlVersionHeader.cs
- WebPageTraceListener.cs
- FragmentQueryKB.cs
- XmlReflectionMember.cs
- XmlSchemaImporter.cs
- WebReferencesBuildProvider.cs
- CounterCreationData.cs
- MessageDesigner.cs
- PeerToPeerException.cs
- StringWriter.cs
- QilUnary.cs
- FirstMatchCodeGroup.cs
- Source.cs
- ToolStripControlHost.cs
- MergeFailedEvent.cs
- XsdDuration.cs
- Bind.cs
- RegexCompilationInfo.cs