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
- ChannelManager.cs
- ConnectionManagementSection.cs
- ContainerSelectorBehavior.cs
- ComEventsMethod.cs
- XmlSchemaAttribute.cs
- OracleBinary.cs
- AnnotationComponentManager.cs
- App.cs
- CryptoProvider.cs
- OutOfProcStateClientManager.cs
- TreeNodeCollectionEditorDialog.cs
- Missing.cs
- BaseTemplateBuildProvider.cs
- ToolboxItemCollection.cs
- CharStorage.cs
- InfoCardKeyedHashAlgorithm.cs
- HostExecutionContextManager.cs
- XmlCharType.cs
- ObfuscateAssemblyAttribute.cs
- SQLBytes.cs
- Registry.cs
- AttributeProviderAttribute.cs
- Image.cs
- ContainerUtilities.cs
- IndexedString.cs
- LocalizabilityAttribute.cs
- ExpressionVisitorHelpers.cs
- SourceLocationProvider.cs
- IdentityNotMappedException.cs
- mediapermission.cs
- UnlockCardRequest.cs
- Vector3DValueSerializer.cs
- AsymmetricAlgorithm.cs
- XmlSchemaChoice.cs
- CallContext.cs
- DataFieldConverter.cs
- SQLString.cs
- BindingExpressionBase.cs
- StrokeNode.cs
- FixedSOMTable.cs
- BindingCollection.cs
- _HeaderInfo.cs
- FormsAuthenticationConfiguration.cs
- Range.cs
- WeakReference.cs
- CommandArguments.cs
- SqlErrorCollection.cs
- RelatedView.cs
- DataGridTextBox.cs
- ScrollPatternIdentifiers.cs
- SafeRightsManagementQueryHandle.cs
- CompensationHandlingFilter.cs
- MiniConstructorInfo.cs
- StretchValidation.cs
- ModifierKeysValueSerializer.cs
- XmlFormatReaderGenerator.cs
- ScrollViewerAutomationPeer.cs
- DeclarationUpdate.cs
- CopyAttributesAction.cs
- WebRequestModuleElement.cs
- ClientConfigurationHost.cs
- VisualStyleElement.cs
- Point4DConverter.cs
- InheritanceRules.cs
- WebPartActionVerb.cs
- EngineSiteSapi.cs
- DbUpdateCommandTree.cs
- ListControlStringCollectionEditor.cs
- ToolBarTray.cs
- ObjectRef.cs
- EventDescriptor.cs
- RootBrowserWindowProxy.cs
- NullableLongMinMaxAggregationOperator.cs
- WindowsListViewGroup.cs
- PropertyInfoSet.cs
- MemberAssignment.cs
- WorkflowInvoker.cs
- ClientApiGenerator.cs
- ColorBlend.cs
- EditorZoneAutoFormat.cs
- SqlDelegatedTransaction.cs
- WebBrowser.cs
- SmiGettersStream.cs
- ScrollChangedEventArgs.cs
- DataGridTablesFactory.cs
- OleDbRowUpdatingEvent.cs
- DataGridViewCellParsingEventArgs.cs
- TextDecorationUnitValidation.cs
- FloaterBaseParagraph.cs
- DataBoundControlAdapter.cs
- HttpWebRequest.cs
- TextElementCollection.cs
- EdmMember.cs
- ModuleBuilderData.cs
- Authorization.cs
- Literal.cs
- WebContext.cs
- LogWriteRestartAreaAsyncResult.cs
- InternalConfigEventArgs.cs
- ResourceDescriptionAttribute.cs