EventProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / 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.
//------------------------------------------------------------------------------ 
// 
//     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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK