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
- TypeExtension.cs
- HtmlContainerControl.cs
- WindowProviderWrapper.cs
- ManagementQuery.cs
- DataGridViewRowPostPaintEventArgs.cs
- ProxyFragment.cs
- BitmapFrameDecode.cs
- ZoneMembershipCondition.cs
- BufferCache.cs
- InlineUIContainer.cs
- CodeTypeParameter.cs
- SRDisplayNameAttribute.cs
- InternalConfigSettingsFactory.cs
- WebContentFormatHelper.cs
- RelationshipConverter.cs
- NamedPipeAppDomainProtocolHandler.cs
- M3DUtil.cs
- MergeLocalizationDirectives.cs
- MimeWriter.cs
- CompilerCollection.cs
- RightsManagementPermission.cs
- _DomainName.cs
- ProcessInputEventArgs.cs
- DateTimeOffset.cs
- Transform3DGroup.cs
- AxisAngleRotation3D.cs
- DataObjectEventArgs.cs
- Sql8ConformanceChecker.cs
- CompilerScope.cs
- StandardOleMarshalObject.cs
- SharedConnectionInfo.cs
- TypeSchema.cs
- DictionaryContent.cs
- AppManager.cs
- GridItemPattern.cs
- GradientSpreadMethodValidation.cs
- Int32KeyFrameCollection.cs
- ComplexLine.cs
- DbTransaction.cs
- RotateTransform3D.cs
- SpotLight.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- Documentation.cs
- ErrorsHelper.cs
- PageAsyncTaskManager.cs
- TextShapeableCharacters.cs
- RelationshipEnd.cs
- DynamicField.cs
- RemotingConfiguration.cs
- DeclarationUpdate.cs
- CryptoConfig.cs
- Signature.cs
- XmlSchemaNotation.cs
- Geometry3D.cs
- SqlCacheDependencyDatabase.cs
- ConnectionManagementSection.cs
- QilTernary.cs
- ExpressionsCollectionEditor.cs
- XmlDocumentFragment.cs
- ClientTarget.cs
- filewebresponse.cs
- StylusOverProperty.cs
- ForceCopyBuildProvider.cs
- SafeLocalMemHandle.cs
- MethodBuilder.cs
- BitmapCache.cs
- ContentIterators.cs
- DocumentReference.cs
- DisplayInformation.cs
- SqlMethods.cs
- QueryExpression.cs
- Lasso.cs
- DataViewListener.cs
- CachedBitmap.cs
- FormDesigner.cs
- SessionEndingEventArgs.cs
- UnsafeNativeMethods.cs
- DispatcherEventArgs.cs
- DBConnection.cs
- InputQueueChannel.cs
- EntityFrameworkVersions.cs
- WorkflowApplicationAbortedEventArgs.cs
- MaskDescriptor.cs
- ListViewGroupConverter.cs
- sqlmetadatafactory.cs
- ForceCopyBuildProvider.cs
- WindowPatternIdentifiers.cs
- XmlProcessingInstruction.cs
- ContextStack.cs
- HttpModuleActionCollection.cs
- ColorMap.cs
- UIElementCollection.cs
- PartitionerStatic.cs
- CompilerResults.cs
- Graphics.cs
- WebPartTransformerAttribute.cs
- safelink.cs
- CheckBoxFlatAdapter.cs
- TransportChannelFactory.cs
- COM2PictureConverter.cs