Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Diagnostics / Eventing / EventProvider.cs / 1305376 / EventProvider.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using Microsoft.Win32; using System.Globalization; using System.ComponentModel; using System.Collections.Generic; using System.Threading; using System.Security.Permissions; using System.Security; using System.Diagnostics.CodeAnalysis; namespace System.Diagnostics.Eventing{ [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public class EventProvider : IDisposable { UnsafeNativeMethods.EtwEnableCallback m_etwCallback; // Trace Callback function private long m_regHandle; // Trace Registration Handle private byte m_level; // Tracing Level private long m_anyKeywordMask; // Trace Enable Flags private long m_allKeywordMask; // Match all keyword private int m_enabled; // Enabled flag from Trace callback private Guid m_providerId; // Control Guid private int m_disposed; // when 1, provider has unregister private static LocalDataStoreSlot s_returnCodeSlot; // thread slot to keep last error private static bool s_platformNotSupported = (Environment.OSVersion.Version.Major < 6); private static bool s_preWin7 = (Environment.OSVersion.Version.Major < 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 1)); private const int s_basicTypeAllocationBufferSize = 16; private const int s_etwMaxMumberArguments = 32; private const int s_etwAPIMaxStringCount = 8; private const int s_maxEventDataDescriptors = 128; private const int s_traceEventMaximumSize = 65482; private const int s_traceEventMaximumStringSize = 32724; [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")] public enum WriteEventErrorCode : int { //check mapping to runtime codes NoError = 0, NoFreeBuffers = 1, EventTooBig = 2 } [StructLayout(LayoutKind.Explicit, Size = 16)] private struct EventData { [FieldOffset(0)] internal ulong DataPointer; [FieldOffset(8)] internal uint Size; [FieldOffset(12)] internal int Reserved; } private enum ActivityControl : uint { EVENT_ACTIVITY_CTRL_GET_ID = 1, EVENT_ACTIVITY_CTRL_SET_ID = 2, EVENT_ACTIVITY_CTRL_CREATE_ID = 3, EVENT_ACTIVITY_CTRL_GET_SET_ID = 4, EVENT_ACTIVITY_CTRL_CREATE_SET_ID = 5 } ////// Constructor for EventProvider class. /// /// /// Unique GUID among all trace sources running on a system /// //// [System.Security.SecurityCritical] [PermissionSet(SecurityAction.Demand, Unrestricted = true)] [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")] public EventProvider(Guid providerGuid) { m_providerId = providerGuid; s_returnCodeSlot = Thread.AllocateDataSlot(); Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.NoError); // // EtwRegister the ProviderId with ETW // EtwRegister(); } ///// /// This method registers the controlGuid of this class with ETW. /// We need to be running on Vista or above. If not an /// PlatformNotSupported exception will be thrown. /// If for some reason the ETW EtwRegister call failed /// a NotSupported exception will be thrown. /// //// [System.Security.SecurityCritical] private unsafe void EtwRegister() { uint status; // // Check only the mayor version // if (s_platformNotSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.NotSupported_DownLevelVista)); } m_etwCallback = new UnsafeNativeMethods.EtwEnableCallback(EtwEnableCallBack); status = UnsafeNativeMethods.EventRegister(ref m_providerId, m_etwCallback, null, ref m_regHandle); if (status != 0) { throw new Win32Exception((int)status); } } // // implement Dispose Pattern to early deregister from ETW insted of waiting for // the finalizer to call deregistration. // Once the user is done with the provider it needs to call Close() or Dispose() // If neither are called the finalizer will unregister the provider anyway // public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } //// // // // [System.Security.SecuritySafeCritical] protected virtual void Dispose(bool disposing) { // // explicit cleanup is done by calling Dispose with true from // Dispose() or Close(). The disposing arguement is ignored because there // are no unmanaged resources. // The finalizer calls Dispose with false. // // // check if the object has been allready disposed // if (m_disposed == 1) return; if (Interlocked.Exchange(ref m_disposed, 1) != 0) { // somebody is allready disposing the provider return; } // // Disables Tracing in the provider, then unregister // m_enabled = 0; Deregister(); } ///// /// This method deregisters the controlGuid of this class with ETW. /// /// public virtual void Close() { Dispose(); } ~EventProvider() { Dispose(false); } ////// This method un-registers from ETW. /// //// [System.Security.SecurityCritical] private unsafe void Deregister() { // // Unregister from ETW using the RegHandle saved from // the register call. // if (m_regHandle != 0) { UnsafeNativeMethods.EventUnregister(m_regHandle); m_regHandle = 0; } } //// // [System.Security.SecurityCritical] unsafe void EtwEnableCallBack( [In] ref System.Guid sourceId, [In] int isEnabled, [In] byte setLevel, [In] long anyKeyword, [In] long allKeyword, [In] void* filterData, [In] void* callbackContext ) { m_enabled = isEnabled; m_level = setLevel; m_anyKeywordMask = anyKeyword; m_allKeywordMask = allKeyword; return; } ///// // /// IsEnabled, method used to test if provider is enabled /// public bool IsEnabled() { return (m_enabled != 0) ? true : false; } ////// IsEnabled, method used to test if event is enabled /// /// /// Level to test /// /// /// Keyword to test /// public bool IsEnabled(byte level, long keywords) { // // If not enabled at all, return false. // if (m_enabled == 0) { return false; } // This also covers the case of Level == 0. if ((level <= m_level) || (m_level == 0)) { // // Check if Keyword is enabled // if ((keywords == 0) || (((keywords & m_anyKeywordMask) != 0) && ((keywords & m_allKeywordMask) == m_allKeywordMask))) { return true; } } return false; } public static WriteEventErrorCode GetLastWriteEventError() { object lastError = Thread.GetData(s_returnCodeSlot); if (lastError == null) { return WriteEventErrorCode.NoError; } else { return (WriteEventErrorCode)(int)lastError; } } // // Helper function to set the last error on the thread // private static void SetLastError(int error){ switch (error) { case UnsafeNativeMethods.ERROR_ARITHMETIC_OVERFLOW: case UnsafeNativeMethods.ERROR_MORE_DATA: Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.EventTooBig); break; case UnsafeNativeMethods.ERROR_NOT_ENOUGH_MEMORY: Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.NoFreeBuffers); break; } } //// [System.Security.SecurityCritical] private static unsafe string EncodeObject(ref object data, EventData* dataDescriptor, byte* dataBuffer) /*++ Routine Description: This routine is used by WriteEvent to unbox the object type and to fill the passed in ETW data descriptor. Arguments: data - argument to be decoded dataDescriptor - pointer to the descriptor to be filled dataBuffer - storage buffer for storing user data, needed because cant get the address of the object Return Value: null if the object is a basic type other than string. String otherwise --*/ { dataDescriptor->Reserved = 0; string sRet = data as string; if (sRet != null) { dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return sRet; } if (data == null) { dataDescriptor->Size = 0; dataDescriptor->DataPointer = 0; } else if (data is IntPtr) { dataDescriptor->Size = (uint)sizeof(IntPtr); IntPtr* intptrPtr = (IntPtr*)dataBuffer; *intptrPtr = (IntPtr)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is int) { dataDescriptor->Size = (uint)sizeof(int); int* intptrPtr = (int*)dataBuffer; *intptrPtr = (int)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is long) { dataDescriptor->Size = (uint)sizeof(long); long* longptr = (long*)dataBuffer; *longptr = (long)data; dataDescriptor->DataPointer = (ulong)longptr; } else if (data is uint) { dataDescriptor->Size = (uint)sizeof(uint); uint* uintptr = (uint*)dataBuffer; *uintptr = (uint)data; dataDescriptor->DataPointer = (ulong)uintptr; } else if (data is UInt64) { dataDescriptor->Size = (uint)sizeof(ulong); UInt64* ulongptr = (ulong*)dataBuffer; *ulongptr = (ulong)data; dataDescriptor->DataPointer = (ulong)ulongptr; } else if (data is char) { dataDescriptor->Size = (uint)sizeof(char); char* charptr = (char*)dataBuffer; *charptr = (char)data; dataDescriptor->DataPointer = (ulong)charptr; } else if (data is byte) { dataDescriptor->Size = (uint)sizeof(byte); byte* byteptr = (byte*)dataBuffer; *byteptr = (byte)data; dataDescriptor->DataPointer = (ulong)byteptr; } else if (data is short) { dataDescriptor->Size = (uint)sizeof(short); short* shortptr = (short*)dataBuffer; *shortptr = (short)data; dataDescriptor->DataPointer = (ulong)shortptr; } else if (data is sbyte) { dataDescriptor->Size = (uint)sizeof(sbyte); sbyte* sbyteptr = (sbyte*)dataBuffer; *sbyteptr = (sbyte)data; dataDescriptor->DataPointer = (ulong)sbyteptr; } else if (data is ushort) { dataDescriptor->Size = (uint)sizeof(ushort); ushort* ushortptr = (ushort*)dataBuffer; *ushortptr = (ushort)data; dataDescriptor->DataPointer = (ulong)ushortptr; } else if (data is float) { dataDescriptor->Size = (uint)sizeof(float); float* floatptr = (float*)dataBuffer; *floatptr = (float)data; dataDescriptor->DataPointer = (ulong)floatptr; } else if (data is double) { dataDescriptor->Size = (uint)sizeof(double); double* doubleptr = (double*)dataBuffer; *doubleptr = (double)data; dataDescriptor->DataPointer = (ulong)doubleptr; } else if (data is bool) { dataDescriptor->Size = (uint)sizeof(bool); bool* boolptr = (bool*)dataBuffer; *boolptr = (bool)data; dataDescriptor->DataPointer = (ulong)boolptr; } else if (data is Guid) { dataDescriptor->Size = (uint)sizeof(Guid); Guid* guidptr = (Guid*)dataBuffer; *guidptr = (Guid)data; dataDescriptor->DataPointer = (ulong)guidptr; } else if (data is decimal) { dataDescriptor->Size = (uint)sizeof(decimal); decimal* decimalptr = (decimal*)dataBuffer; *decimalptr = (decimal)data; dataDescriptor->DataPointer = (ulong)decimalptr; } else if (data is Boolean) { dataDescriptor->Size = (uint)sizeof(Boolean); Boolean* booleanptr = (Boolean*)dataBuffer; *booleanptr = (Boolean)data; dataDescriptor->DataPointer = (ulong)booleanptr; } else { //To our eyes, everything else is a just a string sRet = data.ToString(); dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return sRet; } return null; } ///// // // // // // // // // // // // // // // // // // /// WriteMessageEvent, method to write a string with level and Keyword. /// The activity ID will be propagated only if the call stays on the same native thread as SetActivityId(). /// /// /// Level to test /// /// /// Keyword to test /// //// [System.Security.SecurityCritical] public bool WriteMessageEvent(string eventMessage, byte eventLevel, long eventKeywords) { int status = 0; if (eventMessage == null) { throw new ArgumentNullException("eventMessage"); } if (IsEnabled(eventLevel, eventKeywords)) { if (eventMessage.Length > s_traceEventMaximumStringSize) { Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.EventTooBig); return false; } unsafe { fixed (char* pdata = eventMessage) { status = (int)UnsafeNativeMethods.EventWriteString(m_regHandle, eventLevel, eventKeywords, pdata); } if (status != 0) { SetLastError(status); return false; } } } return true; } ///// // /// WriteMessageEvent, method to write a string with level=0 and Keyword=0 /// The activity ID will be propagated only if the call stays on the same native thread as SetActivityId(). /// /// /// Message to log /// public bool WriteMessageEvent(string eventMessage) { return WriteMessageEvent(eventMessage, 0, 0); } ////// WriteEvent method to write parameters with event schema properties /// /// /// Event Descriptor for this event. /// public bool WriteEvent(ref EventDescriptor eventDescriptor, params object[] eventPayload) { return WriteTransferEvent(ref eventDescriptor, Guid.Empty, eventPayload); } ////// WriteEvent, method to write a string with event schema properties /// /// /// Event Descriptor for this event. /// /// /// string to log. /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] public bool WriteEvent(ref EventDescriptor eventDescriptor, string data) { uint status = 0; if (data == null) { throw new ArgumentNullException("dataString"); } if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) { if (data.Length > s_traceEventMaximumStringSize) { Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.EventTooBig); return false; } EventData userData; userData.Size = (uint)((data.Length +1)* 2); userData.Reserved = 0; unsafe { fixed (char* pdata = data) { Guid activityId = GetActivityId(); userData.DataPointer = (ulong)pdata; if (s_preWin7) { status = UnsafeNativeMethods.EventWrite(m_regHandle, ref eventDescriptor, 1, &userData); } else { status = UnsafeNativeMethods.EventWriteTransfer(m_regHandle, ref eventDescriptor, (activityId == Guid.Empty) ? null : &activityId, null, 1, &userData); } } } } if (status != 0) { SetLastError((int)status); return false; } return true; } ///// // // /// WriteEvent, method to be used by generated code on a derived class /// /// /// Event Descriptor for this event. /// /// /// number of event descriptors /// /// /// pointer do the event data /// //// [System.Security.SecurityCritical] protected bool WriteEvent(ref EventDescriptor eventDescriptor, int dataCount, IntPtr data) { uint status = 0; unsafe { if (s_preWin7) { status = UnsafeNativeMethods.EventWrite( m_regHandle, ref eventDescriptor, (uint)dataCount, (void*)data); } else { Guid activityId = GetActivityId(); status = UnsafeNativeMethods.EventWriteTransfer( m_regHandle, ref eventDescriptor, (activityId == Guid.Empty) ? null : &activityId, null, (uint)dataCount, (void*)data); } } if (status != 0) { SetLastError((int)status); return false; } return true; } ///// // /// WriteTransferEvent, method to write a parameters with event schema properties /// /// /// Event Descriptor for this event. /// //// [System.Security.SecurityCritical] public bool WriteTransferEvent(ref EventDescriptor eventDescriptor, Guid relatedActivityId, params object[] eventPayload) { uint status = 0; if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) { Guid activityId = GetActivityId(); unsafe { int argCount = 0; EventData* userDataPtr = null; if ((eventPayload != null) && (eventPayload.Length != 0)) { argCount = eventPayload.Length; if (argCount > s_etwMaxMumberArguments) { // //too many arguments to log // throw new ArgumentOutOfRangeException("eventPayload", SR.GetString(SR.ArgumentOutOfRange_MaxArgExceeded, s_etwMaxMumberArguments)); } uint totalEventSize = 0; int index; int stringIndex = 0; int[] stringPosition = new int[s_etwAPIMaxStringCount]; //used to keep the position of strings in the eventPayload parameter string[] dataString = new string[s_etwAPIMaxStringCount]; // string arrays from the eventPayload parameter EventData* userData = stackalloc EventData[argCount]; // allocation for the data descriptors userDataPtr = (EventData*)userData; byte* dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize * argCount]; // 16 byte for unboxing non-string argument byte* currentBuffer = dataBuffer; // // The loop below goes through all the arguments and fills in the data // descriptors. For strings save the location in the dataString array. // Caculates the total size of the event by adding the data descriptor // size value set in EncodeObjec method. // for (index = 0; index < eventPayload.Length; index++) { string isString; isString = EncodeObject(ref eventPayload[index], userDataPtr, currentBuffer); currentBuffer += s_basicTypeAllocationBufferSize; totalEventSize += userDataPtr->Size; userDataPtr++; if (isString != null) { if (stringIndex < s_etwAPIMaxStringCount) { dataString[stringIndex] = isString; stringPosition[stringIndex] = index; stringIndex++; } else { throw new ArgumentOutOfRangeException("eventPayload", SR.GetString(SR.ArgumentOutOfRange_MaxStringsExceeded, s_etwAPIMaxStringCount)); } } } if (totalEventSize > s_traceEventMaximumSize) { Thread.SetData(s_returnCodeSlot, (int)WriteEventErrorCode.EventTooBig); return false; } fixed (char* v0 = dataString[0], v1 = dataString[1], v2 = dataString[2], v3 = dataString[3], v4 = dataString[4], v5 = dataString[5], v6 = dataString[6], v7 = dataString[7]) { userDataPtr = (EventData*)userData; if (dataString[0] != null) { userDataPtr[stringPosition[0]].DataPointer = (ulong)v0; } if (dataString[1] != null) { userDataPtr[stringPosition[1]].DataPointer = (ulong)v1; } if (dataString[2] != null) { userDataPtr[stringPosition[2]].DataPointer = (ulong)v2; } if (dataString[3] != null) { userDataPtr[stringPosition[3]].DataPointer = (ulong)v3; } if (dataString[4] != null) { userDataPtr[stringPosition[4]].DataPointer = (ulong)v4; } if (dataString[5] != null) { userDataPtr[stringPosition[5]].DataPointer = (ulong)v5; } if (dataString[6] != null) { userDataPtr[stringPosition[6]].DataPointer = (ulong)v6; } if (dataString[7] != null) { userDataPtr[stringPosition[7]].DataPointer = (ulong)v7; } } } if (relatedActivityId == Guid.Empty && s_preWin7) { // If relatedActivityId is Guid.Empty, this is not a real transfer: just call EventWrite(). // For pre-Win7 platforms we cannot set the activityId from CorrelationManager // because we cannot set relatedActivityId to null (Win7 bug 116784) status = UnsafeNativeMethods.EventWrite (m_regHandle, ref eventDescriptor, (uint)argCount, userDataPtr); } else { status = UnsafeNativeMethods.EventWriteTransfer (m_regHandle, ref eventDescriptor, (activityId == Guid.Empty) ? null : &activityId, (relatedActivityId == Guid.Empty && !s_preWin7)? null : &relatedActivityId, (uint)argCount, userDataPtr); } } } if (status != 0) { SetLastError((int)status); return false; } return true; } //// // // // // // // // // // // // // // // // [System.Security.SecurityCritical] protected bool WriteTransferEvent(ref EventDescriptor eventDescriptor, Guid relatedActivityId, int dataCount, IntPtr data) { uint status = 0; Guid activityId = GetActivityId(); unsafe { status = UnsafeNativeMethods.EventWriteTransfer( m_regHandle, ref eventDescriptor, (activityId == Guid.Empty) ? null : &activityId, &relatedActivityId, (uint)dataCount, (void*)data); } if (status != 0) { SetLastError((int)status); return false; } return true; } //// // // [System.Security.SecurityCritical] private static Guid GetActivityId() { return Trace.CorrelationManager.ActivityId; } //// // [System.Security.SecurityCritical] public static void SetActivityId(ref Guid id) { Trace.CorrelationManager.ActivityId = id; UnsafeNativeMethods.EventActivityIdControl((int)ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID, ref id); } //// // [System.Security.SecurityCritical] public static Guid CreateActivityId() { Guid newId = new Guid(); UnsafeNativeMethods.EventActivityIdControl((int)ActivityControl.EVENT_ACTIVITY_CTRL_CREATE_ID, ref newId); return newId; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.//
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RolePrincipal.cs
- Int32CAMarshaler.cs
- ToolboxItemLoader.cs
- ChannelEndpointElementCollection.cs
- UrlAuthFailedErrorFormatter.cs
- Blend.cs
- ExternalCalls.cs
- MustUnderstandBehavior.cs
- RawKeyboardInputReport.cs
- XmlNodeChangedEventManager.cs
- ImageSource.cs
- ClientSideQueueItem.cs
- BaseServiceProvider.cs
- FloaterBaseParagraph.cs
- ImageClickEventArgs.cs
- ADConnectionHelper.cs
- Itemizer.cs
- DesignOnlyAttribute.cs
- WebPartCancelEventArgs.cs
- Quad.cs
- FormsIdentity.cs
- VBIdentifierDesigner.xaml.cs
- ResXResourceReader.cs
- Simplifier.cs
- ProvidePropertyAttribute.cs
- RayMeshGeometry3DHitTestResult.cs
- WorkflowApplicationUnloadedException.cs
- QilGenerator.cs
- TreeViewImageKeyConverter.cs
- EmptyStringExpandableObjectConverter.cs
- ClientSettingsSection.cs
- Animatable.cs
- SafeRegistryHandle.cs
- DiscoveryClient.cs
- HttpProfileGroupBase.cs
- RuntimeWrappedException.cs
- InheritedPropertyChangedEventArgs.cs
- VisualTreeUtils.cs
- ImplicitInputBrush.cs
- ValueConversionAttribute.cs
- PreviewPrintController.cs
- SizeLimitedCache.cs
- ColorMatrix.cs
- Match.cs
- DesignerCategoryAttribute.cs
- AxParameterData.cs
- DateTimeParse.cs
- XsltQilFactory.cs
- DataGridViewBindingCompleteEventArgs.cs
- RsaSecurityToken.cs
- NestedContainer.cs
- UpdatePanelTrigger.cs
- IntAverageAggregationOperator.cs
- ImageMap.cs
- DESCryptoServiceProvider.cs
- ProviderBase.cs
- UnwrappedTypesXmlSerializerManager.cs
- ProgressBarRenderer.cs
- XmlSchemaInclude.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- NumberFormatter.cs
- Boolean.cs
- BaseHashHelper.cs
- IntSumAggregationOperator.cs
- QueryStringHandler.cs
- PointConverter.cs
- ProtocolsConfigurationHandler.cs
- panel.cs
- DesignerMetadata.cs
- WithParamAction.cs
- IdentifierService.cs
- URL.cs
- ObjectListField.cs
- DataGridItemCollection.cs
- PenCursorManager.cs
- CssTextWriter.cs
- Propagator.JoinPropagator.JoinPredicateVisitor.cs
- DataGridViewDesigner.cs
- LogSwitch.cs
- Exceptions.cs
- EdmItemError.cs
- ByteConverter.cs
- BamlVersionHeader.cs
- GuidelineCollection.cs
- SqlDataSourceQuery.cs
- CheckBoxField.cs
- SchemaMapping.cs
- InternalException.cs
- ThemeableAttribute.cs
- XamlReaderHelper.cs
- ModuleBuilderData.cs
- CompositeControlDesigner.cs
- OleDbParameter.cs
- OneOfTypeConst.cs
- ArraySet.cs
- BStrWrapper.cs
- TableLayout.cs
- ModulesEntry.cs
- BooleanFunctions.cs
- DateTimeFormatInfo.cs