Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / Protocol / WsatEtwTraceListener.cs / 1 / WsatEtwTraceListener.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.Transactions.Wsat.Protocol
{
using System;
using System.ServiceModel.Channels;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Xml;
using Microsoft.Win32;
using Microsoft.Transactions.Bridge;
using Microsoft.Transactions.Wsat.Messaging;
using System.Security;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
class WsatEtwTraceListener : TraceListener
{
public WsatEtwTraceListener()
{
}
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
this.Close();
}
}
finally
{
base.Dispose(disposing);
}
}
void TraceInternal(TraceEventCache eventCache, string xmlApplicationData, int eventId, TraceEventType type)
{
try
{
EtwTrace.Trace(xmlApplicationData, TraceTypeOf(type), eventId);
}
catch(Win32Exception exception)
{
if (DebugTrace.Warning)
{
DebugTrace.Trace(TraceLevel.Warning, "Exception thrown from ETW Trace : {0} ", exception.Message );
}
}
}
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType severity, int id, string format, params object[] args)
{
TraceInternal(eventCache, null == args ? format : String.Format(CultureInfo.CurrentCulture, format, args), id, severity);
}
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType severity, int id, string message)
{
TraceInternal(eventCache, message, id, severity);
}
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType severity, int id, object data)
{
TraceInternal(eventCache, data.ToString(), id, severity);
}
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType severity, int id, params object[] data)
{
NotSupported();
}
public override void TraceTransfer(TraceEventCache eventCache, String source, int id, string message, Guid relatedActivityId)
{
try
{
EtwTrace.TraceTransfer(relatedActivityId);
}
catch(Win32Exception exception)
{
if (DebugTrace.Warning)
{
DebugTrace.Trace(TraceLevel.Warning, "Exception thrown from ETW Trace : {0} ", exception.Message );
}
}
}
static TraceType TraceTypeOf(TraceEventType type)
{
switch (type)
{
case TraceEventType.Transfer:
return TraceType.Transfer;
case TraceEventType.Start:
return TraceType.Start;
case TraceEventType.Stop:
return TraceType.Stop;
case TraceEventType.Suspend:
return TraceType.Suspend;
case TraceEventType.Resume:
return TraceType.Resume;
default:
return TraceType.Trace;
}
}
public override void Write(string text)
{
WriteLine(text);
}
public override void WriteLine(string text)
{
EtwTrace.Trace(text, TraceType.Trace, 0);
}
void NotSupported()
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
}
}
enum EtwStructSizes
{
SizeofMofField = 16,
SizeofGuid = 16,
SizeofEventHeader = 48,
SizeofBaseEvent = 176,
}
//Attempt to be consistent with generic event types from EvnTrace.h
enum TraceType : byte
{
Trace = 0,
Start = 1,
Stop = 2,
Transfer = 5,
Suspend = 10,
Resume = 11,
}
static class EtwTrace
{
static Guid WsatTraceGuid = new Guid("{eb6517d4-090c-48ab-825e-adad366406a2}");
static Guid WsatProviderGuid = new Guid("7f3fe630-462b-47c5-ab07-67ca84934abd");
const int MaxSupportedStringSize = 65486;
static EtwTraceProvider provider;
static object syncRoot = new object();
internal static EtwTraceProvider Provider
{
get
{
if (provider == null)
{
lock (EtwTrace.syncRoot)
{
if (provider == null)
{
provider = new EtwTraceProvider(WsatProviderGuid, WsatTraceGuid);
}
}
}
return provider;
}
}
internal static void Trace(string xml, TraceType type, int eventId)
{
TraceInternal(EtwTrace.GetActivityId(), xml, type, eventId);
}
static Guid GetActivityId()
{
object id = System.Diagnostics.Trace.CorrelationManager.ActivityId;
return id == null ? Guid.Empty : (Guid)id;
}
static internal unsafe uint TraceTransfer(Guid relatedId)
{
return TraceTransfer(GetActivityId(), relatedId);
}
static unsafe uint TraceTransfer(Guid activityId, Guid relatedId)
{
uint result = unchecked((uint)-1);
if (null != Provider && Provider.ShouldTrace)
{
Guid2Event evt = new Guid2Event();
evt.Header.Guid = WsatTraceGuid;
evt.Header.Type = (byte)TraceType.Transfer;
evt.Header.ClientContext = 0;
evt.Header.Flags = WnodeFlags.WnodeFlagTracedGuid;
evt.Header.BufferSize = (ushort)EtwStructSizes.SizeofEventHeader + 2 * (ushort)EtwStructSizes.SizeofGuid;
evt.Guid1 = activityId;
evt.Guid2 = relatedId;
if (null != Provider)
{
result = provider.Trace((MofEvent*)&evt);
}
}
return result;
}
static unsafe uint TraceInternal(Guid guid, string xml, TraceType type, int eventId)
{
uint result = unchecked((uint)-1);
if (null != Provider && Provider.ShouldTrace)
{
int dataLength = (xml.Length + 1) * 2 < MaxSupportedStringSize ? (xml.Length + 1) * 2 : MaxSupportedStringSize;
Mof3Event evt = new Mof3Event();
evt.Header.Guid = WsatTraceGuid;
evt.Header.Type = (byte)type;
evt.Header.ClientContext = 0;
evt.Header.Flags = WnodeFlags.WnodeFlagTracedGuid | WnodeFlags.WnodeFlagUseMofPointer;
evt.Header.BufferSize = (ushort)EtwStructSizes.SizeofEventHeader + 3 * (ushort)EtwStructSizes.SizeofMofField ;
evt.Mof2.Length = (uint)dataLength;
evt.Mof1.Length = 16;
evt.Mof1.Data = (IntPtr)(&guid);
evt.Mof3.Length = sizeof(int);
evt.Mof3.Data = (IntPtr)(&eventId);
fixed (char* pdata = xml)
{
evt.Mof2.Data = (IntPtr)pdata;
if (null != Provider)
{
result = provider.Trace((MofEvent*)&evt);
}
}
}
return result;
}
}
internal unsafe delegate uint EtwTraceCallback([In] uint requestCode,
[In] System.IntPtr requestContext,
[In] System.IntPtr bufferSize,
[In] byte* buffer);
class EtwTraceProvider
{
Guid controlGuid;
Guid eventClassGuid;
EtwTraceCallback etwProc;
EtwHandle registrationHandle;
UInt64 traceHandle;
internal EtwTraceProvider(Guid controlGuid, Guid eventClassGuid)
{
Initialize(controlGuid, eventClassGuid);
}
internal bool ShouldTrace { get { return traceHandle != 0; } }
internal unsafe uint Trace(MofEvent* evt)
{
return EtwNativeMethods.TraceEvent(traceHandle, (char*)evt);
}
unsafe void Initialize(Guid ctlGuid, Guid evtClassGuid)
{
this.controlGuid = ctlGuid;
this.eventClassGuid = evtClassGuid;
TraceGuidRegistration guidReg = new TraceGuidRegistration();
etwProc = new EtwTraceCallback(EtwNotificationCallback);
guidReg.Guid = &evtClassGuid;
guidReg.RegHandle = null;
this.registrationHandle = EtwHandle.RegisterTraceGuids(etwProc, controlGuid, guidReg);
}
unsafe uint EtwNotificationCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte* buffer)
{
if (null == buffer)
{
//note that the return value will be ignored
return uint.MaxValue;
}
if (DebugTrace.Info)
{
DebugTrace.Trace(TraceLevel.Info, "EtwNotificationCallback is called!");
}
EventTraceHeader* eventBuffer = (EventTraceHeader*)buffer;
switch (requestCode)
{
case RequestCodes.EnableEvents:
this.traceHandle = eventBuffer->HistoricalContext;
uint flags = EtwNativeMethods.GetTraceEnableFlags(this.traceHandle);
int level = EtwNativeMethods.GetTraceEnableLevel(this.traceHandle);
if (DebugTrace.Info)
{
DebugTrace.Trace(TraceLevel.Info, "EtwNotificationCallback: EnableEvents: Current DiagnosticTrace Level {0}", DiagnosticUtility.Level);
DebugTrace.Trace(TraceLevel.Info, "EtwNotificationCallback: EnableEvents: flags = {0} , level = {1}", flags, level);
}
using (Process process = Process.GetCurrentProcess())
{
if (flags == process.Id && level > 0)
{
DiagnosticUtility.Level = LevelFromInt(level);
if (DebugTrace.Info)
{
DebugTrace.Trace(TraceLevel.Info, "EtwNotificationCallback: New DiagnosticTrace Level {0}", DiagnosticUtility.Level);
}
}
}
break;
case RequestCodes.DisableEvents:
this.traceHandle = 0;
if (DebugTrace.Info)
{
DebugTrace.Trace(TraceLevel.Info, "EtwNotificationCallback: Disabling Session Handle!!");
}
break;
default:
break;
}
return 0;
}
SourceLevels LevelFromInt(int level)
{
SourceLevels result = SourceLevels.Off;
if(level == 6)
{
result = SourceLevels.Off;
}
else if (level == 5)
{
result = SourceLevels.Verbose;
}
else if (level == 4)
{
result = SourceLevels.Information;
}
else if (level == 3)
{
result = SourceLevels.Warning;
}
else if (level == 2)
{
result = SourceLevels.Error;
}
else
{
result = SourceLevels.Critical;
}
return result;
}
}
internal static class RequestCodes
{
internal const int GetAllData = 0; // Never Used
internal const int GetSingleInstance = 1; // Never Used
internal const int SetSingleInstance = 2; // Never Used
internal const int SetSingleItem = 3; // Never Used
internal const int EnableEvents = 4; // Enable Tracing
internal const int DisableEvents = 5; // Disable Tracing
internal const int EnableCollection = 6; // Never Used
internal const int DisableCollection = 7; // Never Used
internal const int RegInfo = 8; // Never Used
internal const int ExecuteMethod = 9; // Never Used
}
[StructLayout(LayoutKind.Explicit, Size = 48)]
internal struct EventTraceHeader
{
[FieldOffset(0)]
internal ushort BufferSize;
[FieldOffset(4)]
internal byte Type;
[FieldOffset(5)]
internal byte Level;
[FieldOffset(6)]
internal short Version;
[FieldOffset(8)]
internal UInt64 HistoricalContext;
[FieldOffset(16)]
internal Int64 TimeStamp;
[FieldOffset(24)]
internal System.Guid Guid;
[FieldOffset(40)]
internal uint ClientContext;
[FieldOffset(44)]
internal uint Flags;
}
[StructLayout(LayoutKind.Explicit, Size = 64)]
internal struct GuidEvent
{
[FieldOffset(0)]
internal EventTraceHeader Header;
[FieldOffset(48)]
internal Guid Guid;
}
[StructLayout(LayoutKind.Explicit, Size = 80)]
internal struct Guid2Event
{
[FieldOffset(0)]
internal EventTraceHeader Header;
[FieldOffset(48)]
internal Guid Guid1;
[FieldOffset(64)]
internal Guid Guid2;
}
[StructLayout(LayoutKind.Explicit, Size = 64)]
internal struct MofEvent
{
[FieldOffset(0)]
internal EventTraceHeader Header;
[FieldOffset(48)]
internal MofField Mof;
}
[StructLayout(LayoutKind.Explicit, Size = 96)]
internal struct Mof3Event
{
[FieldOffset(0)]
internal EventTraceHeader Header;
[FieldOffset(48)]
internal MofField Mof1;
[FieldOffset(64)]
internal MofField Mof2;
[FieldOffset(80)]
internal MofField Mof3;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct MofField
{
[FieldOffset(0)]
internal IntPtr Data;
[FieldOffset(8)]
internal uint Length;
[FieldOffset(12)]
internal uint Type;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TraceGuidRegistration
{
internal unsafe Guid* Guid;
internal unsafe void* RegHandle;
}
internal static class WnodeFlags
{
internal const uint WnodeFlagTracedGuid = 0x00020000;
internal const uint WnodeFlagLogWnode = 0x00040000;
internal const uint WnodeFlagUseGuidPointer = 0x00080000;
internal const uint WnodeFlagUseMofPointer = 0x00100000;
internal const uint WnodeFlagUseNoHeader = 0x00200000;
}
static class EtwNativeMethods
{
[SuppressUnmanagedCodeSecurity]
[DllImport("advapi32", ExactSpelling = true, EntryPoint = "GetTraceEnableFlags", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern uint GetTraceEnableFlags(UInt64 traceHandle);
[SuppressUnmanagedCodeSecurity]
[DllImport("advapi32", ExactSpelling = true, EntryPoint = "GetTraceEnableLevel", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern byte GetTraceEnableLevel(UInt64 traceHandle);
[SuppressUnmanagedCodeSecurity]
[DllImport("advapi32", ExactSpelling = true, EntryPoint = "TraceEvent", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern unsafe uint TraceEvent(UInt64 traceHandle, char* header);
[SuppressUnmanagedCodeSecurity]
[DllImport("advapi32", ExactSpelling = true, EntryPoint = "RegisterTraceGuidsW", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern unsafe uint RegisterTraceGuids([In]EtwTraceCallback cbFunc, [In]void* context, [In] ref System.Guid controlGuid, [In] uint guidCount, ref TraceGuidRegistration guidReg, [In]string mofImagePath, [In] string mofResourceName, [Out] out UInt64 regHandle);
[SuppressUnmanagedCodeSecurity]
[DllImport("advapi32", ExactSpelling = true, EntryPoint = "UnregisterTraceGuids", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern int UnregisterTraceGuids(UInt64 regHandle);
}
// Can't derive from a 'SafeHandle' class because those types change
// the size of an IntPtr depending on platform (x86/x64). We
// need a handle with constant size of UInt64 to model
// the size of the handle for ETW. Hence, we have to write our own
// derivation of CriticalFinalizerObject.
internal class EtwHandle : CriticalFinalizerObject
{
UInt64 traceHandle;
static unsafe internal EtwHandle RegisterTraceGuids(EtwTraceCallback cbFunc, Guid controlGuid, TraceGuidRegistration registration)
{
EtwHandle retval = null;
UInt64 handle = 0;
uint status = EtwNativeMethods.RegisterTraceGuids(cbFunc,
null,
ref controlGuid,
1,
ref registration,
null,
null,
out handle);
if (status != 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)status));
}
else
{
retval = new EtwHandle(handle);
}
return retval;
}
EtwHandle(UInt64 traceHandle)
{
this.traceHandle = traceHandle;
}
~EtwHandle()
{
#pragma warning suppress 56031 // No need to check return value since we are shutting down
EtwNativeMethods.UnregisterTraceGuids(this.traceHandle);
}
}
}
// 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
- ResumeStoryboard.cs
- Command.cs
- XhtmlBasicObjectListAdapter.cs
- HttpServerUtilityBase.cs
- ConfigXmlCDataSection.cs
- Rect3DValueSerializer.cs
- AttachedPropertyBrowsableAttribute.cs
- TopClause.cs
- TemplateControlCodeDomTreeGenerator.cs
- COM2AboutBoxPropertyDescriptor.cs
- RadioButton.cs
- TcpClientSocketManager.cs
- ToolStripPanelCell.cs
- Ticks.cs
- SettingsPropertyNotFoundException.cs
- RepeatBehaviorConverter.cs
- AutomationEvent.cs
- RequestNavigateEventArgs.cs
- DetailsViewCommandEventArgs.cs
- BinaryKeyIdentifierClause.cs
- ServiceReference.cs
- UICuesEvent.cs
- ComboBoxItem.cs
- MethodCallConverter.cs
- SourceSwitch.cs
- FontSourceCollection.cs
- ReadOnlyCollectionBase.cs
- HttpPostClientProtocol.cs
- TypeProvider.cs
- DataGridCellInfo.cs
- CurrencyManager.cs
- SingleObjectCollection.cs
- WebBrowserNavigatingEventHandler.cs
- FileStream.cs
- TimelineGroup.cs
- ObjectHelper.cs
- DescendantQuery.cs
- AnimatedTypeHelpers.cs
- WindowCollection.cs
- TrackingExtract.cs
- columnmapkeybuilder.cs
- HttpAsyncResult.cs
- OLEDB_Enum.cs
- Evidence.cs
- DependencySource.cs
- AssemblyCache.cs
- ToolStripScrollButton.cs
- BooleanSwitch.cs
- GlyphingCache.cs
- ResourceExpressionBuilder.cs
- SerializerProvider.cs
- ErrorEventArgs.cs
- TreeWalker.cs
- CreateParams.cs
- DataChangedEventManager.cs
- TraceFilter.cs
- TextStore.cs
- AsyncResult.cs
- FixedTextPointer.cs
- XmlSerializerNamespaces.cs
- StringPropertyBuilder.cs
- TabletDevice.cs
- DependencyProperty.cs
- RoleManagerModule.cs
- ColumnResizeAdorner.cs
- TextBoxView.cs
- Solver.cs
- DescendentsWalker.cs
- ViewGenerator.cs
- _ContextAwareResult.cs
- HttpProtocolImporter.cs
- ConfigurationStrings.cs
- HtmlHead.cs
- EdmEntityTypeAttribute.cs
- TaskFileService.cs
- MachineKey.cs
- TileModeValidation.cs
- URLString.cs
- _HelperAsyncResults.cs
- SerializationFieldInfo.cs
- Floater.cs
- PasswordRecovery.cs
- StrokeRenderer.cs
- SecurityTokenValidationException.cs
- AppDomainProtocolHandler.cs
- CursorConverter.cs
- FontStretch.cs
- UniqueIdentifierService.cs
- StateDesigner.TransitionInfo.cs
- StreamInfo.cs
- ColumnTypeConverter.cs
- CollectionBase.cs
- ResXFileRef.cs
- DependencyPropertyDescriptor.cs
- ProcessInfo.cs
- MarkupCompilePass1.cs
- IdentityHolder.cs
- PropertyKey.cs
- CharacterString.cs
- MetadataUtil.cs