TraceProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Shared / MS / Utility / TraceProvider.cs / 1 / TraceProvider.cs

                            //---------------------------------------------------------------------------- 
// File: TraceProvider
//
// A Managed wrapper for Event Tracing for Windows
// Based on TraceEvent.cs found in nt\base\wmi\trace.net 
// Provides an internal Avalon API to replace Microsoft.Windows.EventTracing.dll
// 
//--------------------------------------------------------------------------- 
using System;
using MS.Win32; 
using MS.Internal;
using System.Runtime.InteropServices;
using System.Security;
using System.Globalization; //for CultureInfo 

#pragma warning disable 1634, 1691  //disable warnings about unknown pragma 
 
#if WINDOWS_BASE
    using MS.Internal.WindowsBase; 
#elif PRESENTATION_CORE
    using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
    using MS.Internal.PresentationFramework; 
#elif DRT
    using MS.Internal.Drt; 
#else 
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName; 
#endif

namespace MS.Utility
{ 
    #region TraceProvider
 
    [Guid("748004CA-4959-409a-887C-6546438CF48E")] 
    [FriendAccessAllowed]
    internal class TraceProvider 
    {
        private const ushort _version = 2;
        private UnsafeNativeMethods.EtwTrace.EtwProc _etwProc;   // Trace Callback function
        private SecurityCriticalDataForSet _registrationHandle;                       // Trace Registration Handle 
        private ulong _traceHandle;                              // Trace Logger Handle from callback
        private byte _level;                                     // Tracing Level 
        private uint _flags;                                     // Trace Enable Flags 
        private bool _enabled;                                   // Enabled flag from Trace callback
 
        ///
        /// Critical:  This calls critical code in TraceProvider (Register)
        ///
        [SecurityCritical] 
        internal TraceProvider(string _applicationName, Guid controlGuid)
        { 
            _level = 0; 
            _flags = 0;
            _enabled = false; 
            _traceHandle = 0;
            _registrationHandle = new SecurityCriticalDataForSet(0);

            // Register the controlGuid with ETW 
            Register(controlGuid);
        } 
 
        ///
        /// Critical:  This calls critical code in EtwTrace 
        /// TreatAsSafe: the registration handle this passes in to UnregisterTraceGuids
        /// was generated by the ETW unmanaged API and can't be tampered with from our side
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        ~TraceProvider()
        { 
            // 
            // Unregister from ETW using the _registrationHandle saved from
            // the register call.  We don't care what UnregisterTraceGuids returns. 
            // If the call fails there's nothing the finalizer can do anyway
            //

            #pragma warning suppress 6031  //presharp suppression 
            UnsafeNativeMethods.EtwTrace.UnregisterTraceGuids(_registrationHandle.Value);
            GC.KeepAlive(_etwProc); 
        } 

        internal uint Flags 
        {
            get
            {
                return _flags; 
            }
        } 
 
        internal byte Level
        { 
            get
            {
                return _level;
            } 
        }
 
        internal bool IsEnabled 
        {
            get 
            {
                return _enabled;
            }
        } 

        // 
        // This callback function is called by ETW to enable or disable 
        // Tracing dynamically
        // 
        ///
        /// Critical:  This calls critical code in EtwTrace
        /// TreatAsSafe:  This callback is called by the ETW unmanaged API when tracing has been enabled.
        /// This method does nothing insecure with the data passed into it. The registration of this callback 
        /// is covered by the Register method
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal unsafe uint MyCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte* byteBuffer)
        { 
            try
            {
                BaseEvent* buffer = (BaseEvent*)byteBuffer;
                switch (requestCode) 
                {
                    case RequestCodes.EnableEvents: 
                        _traceHandle = buffer->HistoricalContext; 
                        _flags = (uint)UnsafeNativeMethods.EtwTrace.GetTraceEnableFlags((ulong)buffer->HistoricalContext);
                        _level = UnsafeNativeMethods.EtwTrace.GetTraceEnableLevel((ulong)buffer->HistoricalContext); 
                        _enabled = true;
                        break;
                    case RequestCodes.DisableEvents:
                        _enabled = false; 
                        _traceHandle = 0;
                        _level = 0; 
                        _flags = 0; 
                        break;
                    default: 
                        _enabled = false;
                        _traceHandle = 0;
                        break;
                } 

                return 0; 
            } 
            catch(Exception e)
            { 
                // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
                //
                // This should be CriticalExceptions.IsCriticalException, but that requires
                // linking to WindowsBase, which is a heavy requirement for "shared" code. 
                //
                if ((e is NullReferenceException) || (e is System.Runtime.InteropServices.SEHException)) 
                { 
                   throw;
                } 
                else
                {
                    return 0;
                } 
            }
        } 
 
        //
        // Registers the controlGuid with an inbuilt callback 
        //
        ///
        /// Critical:  This calls critical code in UnsafeNativeMethods.EtwTrace
        /// and sets critical for set field _registrationHandle 
        ///
        [SecurityCritical] 
        private unsafe uint Register(Guid controlGuid) 
        {
            uint status; 
            ulong registrationHandle;
            UnsafeNativeMethods.EtwTrace.TraceGuidRegistration guidReg = new UnsafeNativeMethods.EtwTrace.TraceGuidRegistration();

            Guid dummyGuid = new Guid(0xb4955bf0, 
                                      0x3af1,
                                      0x4740, 
                                      0xb4,0x75, 
                                      0x99,0x05,0x5d,0x3f,0xe9,0xaa);
 
            _etwProc = new UnsafeNativeMethods.EtwTrace.EtwProc(MyCallback);

            // This dummyGuid is there for ETW backward compat issues
            guidReg.Guid = &dummyGuid; 
            guidReg.RegHandle = null;
 
            status = UnsafeNativeMethods.EtwTrace.RegisterTraceGuids(_etwProc, null, ref controlGuid, 1, ref guidReg, null, null, out registrationHandle); 
            _registrationHandle.Value = registrationHandle;
 
            return status;
        }

        // All of the following TraceEvent overloads are used in the codebase.  To keep FxCop happy 
        // we don't keep around unused ones.  If another overload is needed it is trivial to add.
 
        // No arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, null, null);
        }

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType) 
        {
            TraceEvent(level, eventGuid, eventType, null, null); 
        } 

        // 1 argument 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0)
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, null);
        } 

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0) 
        { 
            TraceEvent(level, eventGuid, eventType, data0, null);
        } 

        // 2 arguments
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1);
        } 
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, null, null, null, null, null, null, null);
        }

        // 3 arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2); 
        }
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2)
        {
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, null, null, null, null, null, null);
        } 

        // 4 arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3) 
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3); 
        }

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, null, null, null, null, null);
        } 
 
        // 5 arguments
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4) 
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3, data4);
        }
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, null, null, null, null); 
        }
 
        ///
        /// Critical:  This calls critical code in UnsaveNativeMethods.EtwTrace
        /// TreatAsSafe:  The arguments are serialized and sent to the unmanaged ETW API as a packet with a verified size
        /// the unmanaged ETW code stores this in a buffer which is later picked up by post-processing tools - the data cannot 
        /// be executed
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal unsafe uint TraceEvent(
            EventTrace.Level level, Guid eventGuid, byte evtype, 
            object data0, object data1, object data2, object data3, object data4, object data5, object data6, object data7, object data8)
        {
            uint status = 0;
            BaseEvent ev;      // Takes up 304 bytes on the stack 

            // The largest possible item stored in this buffer from each of data0 
            // through data8 will be a decimal (strings are logged as pointers) 
            const uint bufferSize = sizeof(decimal) * 9;
            char* buffer = stackalloc char[(int)bufferSize]; 
            uint offset = 0;
            char* ptr = buffer;
            string s0, s1, s2, s3, s4, s5, s6, s7, s8;
            int stringMask = 0; 
            uint argCount = 0;
            int mofIndex = 0; 
 
            s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = "";
 
            ev.ClientContext = 0;
            ev.Flags = 0x00120000; // define Constants
            ev.Guid = eventGuid;
            ev.EventType = evtype; 
            ev.Level = level;
            ev.Version = _version; 
            MofField* be = null; 

            if (data0 != null) 
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++];
                if ((s0 = ProcessOneObject(data0, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000001; 
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            } 
            if (data1 != null)
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s1 = ProcessOneObject(data1, be, ptr, ref offset)) != null) 
                { 
                    stringMask |= 0x00000002;
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            }
            if (data2 != null)
            { 
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset; 
                if ((s2 = ProcessOneObject(data2, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000004;
                    mofIndex++; // Leave a slot for the String Pointer
                }
            } 
            if (data3 != null)
            { 
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s3 = ProcessOneObject(data3, be, ptr, ref offset)) != null)
                {
                    stringMask |= 0x00000008;
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            } 
            if (data4 != null) 
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset;
                if ((s4 = ProcessOneObject(data4, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000010;
                    mofIndex++; // Leave a slot for the String Pointer 
                } 
            }
            if (data5 != null) 
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s5 = ProcessOneObject(data5, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000020; 
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            }
            if (data6 != null)
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s6 = ProcessOneObject(data6, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000040; 
                    mofIndex++; // Leave a slot for the String Pointer
                }
            }
            if (data7 != null) 
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s7 = ProcessOneObject(data7, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000080;
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            }
            if (data8 != null) 
            { 
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s8 = ProcessOneObject(data8, be, ptr, ref offset)) != null)
                {
                    stringMask |= 0x00000100; 
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            } 

            // Assert we haven't exceeded the buffer size 
            Invariant.Assert(ptr - buffer <= bufferSize);

            // Now pin all the strings and use the stringMask to pass them over through mofField
            fixed (char* vptr0 = s0, vptr1 = s1, vptr2 = s2, vptr3 = s3, vptr4 = s4, vptr5 = s5, vptr6 = s6, vptr7 = s7, vptr8 = s8) 
            {
                int i = 0; 
                if ((stringMask & 0x00000001) != 0) 
                {
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s0.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr0;
                }
                i++; 
                if ((stringMask & 0x00000002) != 0)
                { 
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s1.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr1; 
                }
                i++;
                if ((stringMask & 0x00000004) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s2.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr2; 
                }
                i++; 
                if ((stringMask & 0x00000008) != 0)
                {
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s3.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr3;
                } 
                i++; 
                if ((stringMask & 0x00000010) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s4.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr4;
 
                }
                i++; 
                if ((stringMask & 0x00000020) != 0) 
                {
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s5.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr5;
                }
                i++; 
                if ((stringMask & 0x00000040) != 0)
                { 
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s6.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr6; 
                }
                i++;
                if ((stringMask & 0x00000080) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s7.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr7; 
                }
                i++; 
                if ((stringMask & 0x00000100) != 0)
                {
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s8.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr8;
                } 
 
                ev.BufferSize = 48 + (uint)mofIndex * (uint)sizeof(MofField);
                status = UnsafeNativeMethods.EtwTrace.TraceEvent(_traceHandle, (char*)&ev); 
            }

            return status;
        } 

        /// 
        ///Critical - unsafe pointers 
        ///
        [SecurityCritical] 
        private unsafe string ProcessOneObject(object data, MofField* mofField, char* ptr, ref uint offSet)
        {
            return EncodeObject(data, mofField, ptr, ref offSet, (byte*)null);
        } 

        // 
 

 

        [SecurityCritical]
        private unsafe string EncodeObject(object data, MofField* mofField, char* ptr, ref uint offSet, byte* ptrArgInfo)
        { 
            if (data == null)
            { 
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)0; //NULL type, WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)0;
                }
                mofField->DataLength = 0;
                mofField->DataPointer = (void*)null; //WIN64 Changes (?) 
                return null;
            } 
 
            // if the data is an enum we'll convert it to its underlying type
            Type dataType = data.GetType(); 

            if (dataType.IsEnum)
            {
                data = Convert.ChangeType(data, Enum.GetUnderlyingType(dataType), CultureInfo.InvariantCulture); 
            }
 
            string sRet = data as string; 

            if (sRet != null) 
            {
                if (ptrArgInfo != null)
                {
                    *ptrArgInfo = (byte)2; //WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
                } 
                else 
                { // TraceEvent path. Need counted strings.
                    mofField->DataLength = sizeof(ushort); 
                    ushort* ushortptr = (ushort*)ptr;
                    *ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
                    mofField->DataPointer = (void*)ushortptr;
                    offSet += sizeof(ushort); 
                }
 
                return sRet; 
            }
            if (data is sbyte) 
            {
                mofField->DataLength = sizeof(sbyte);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)3; //WIN64 Changes
                } 
                sbyte* sbyteptr = (sbyte*)ptr; 
                *sbyteptr = (sbyte)data; //WIN64 Changes
                mofField->DataPointer = (void*)sbyteptr; 
                offSet += sizeof(sbyte);
            }
            else if (data is byte)
            { 
                mofField->DataLength = sizeof(byte);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)4; //WIN64 Changes
                } 
                byte* byteptr = (byte*)ptr;
                *byteptr = (byte)data; //WIN64 Changes
                mofField->DataPointer = (void*)byteptr;
                offSet += sizeof(byte); 
            }
            else if (data is short) 
            { 
                mofField->DataLength = sizeof(short);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)5; //WIN64 Changes
                }
                short* shortptr = (short*)ptr; 
                *shortptr = (short)data; //WIN64 Changes
                mofField->DataPointer = (void*)shortptr; 
                offSet += sizeof(short); 
            }
            else if (data is ushort) 
            {
                mofField->DataLength = sizeof(ushort);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)6; //WIN64 Changes
                } 
                ushort* ushortptr = (ushort*)ptr; 
                *ushortptr = (ushort)data; //WIN64 Changes
                mofField->DataPointer = (void*)ushortptr; 
                offSet += sizeof(ushort);
            }
            else if (data is int)
            { 
                mofField->DataLength = sizeof(int);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)7; //WIN64 Changes
                } 
                int* intptr = (int*)ptr;
                *intptr = (int)data; //WIN64 Changes
                mofField->DataPointer = (void*)intptr;
                offSet += sizeof(int); 
            }
            else if (data is uint) 
            { 
                mofField->DataLength = sizeof(uint);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)8; //WIN64 Changes
                }
                uint* uintptr = (uint*)ptr; 
                *uintptr = (uint)data; //WIN64 Changes
                mofField->DataPointer = (void*)uintptr; 
                offSet += sizeof(uint); 
            }
            else if (data is long) 
            {
                mofField->DataLength = sizeof(long);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)9; //WIN64 Changes
                } 
                long* longptr = (long*)ptr; 
                *longptr = (long)data; //WIN64 Changes
                mofField->DataPointer = (void*)longptr; 
                offSet += sizeof(long);
            }
            else if (data is ulong)
            { 
                mofField->DataLength = sizeof(ulong);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)10; //WIN64 Changes
                } 
                ulong* ulongptr = (ulong*)ptr;
                *ulongptr = (ulong)data; //WIN64 Changes
                mofField->DataPointer = (void*)ulongptr;
                offSet += sizeof(ulong); 
            }
            else if (data is char) 
            { 
                mofField->DataLength = sizeof(char);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)11; //WIN64 Changes
                }
                char* charptr = (char*)ptr; 
                *charptr = (char)data; //WIN64 Changes
                mofField->DataPointer = (void*)charptr; 
                offSet += sizeof(char); 
            }
            else if (data is float) 
            {
                mofField->DataLength = sizeof(float);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)12; //WIN64 Changes
                } 
                float* floatptr = (float*)ptr; 
                *floatptr = (float)data; //WIN64 Changes
                mofField->DataPointer = (void*)floatptr; 
                offSet += sizeof(float);
            }
            else if (data is double)
            { 
                mofField->DataLength = sizeof(double);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)13; //WIN64 Changes
                } 
                double* doubleptr = (double*)ptr;
                *doubleptr = (double)data; //WIN64 Changes
                mofField->DataPointer = (void*)doubleptr;
                offSet += sizeof(double); 
            }
            else if (data is bool) 
            { 
                mofField->DataLength = sizeof(bool);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)14; //WIN64 Changes
                }
                bool* boolptr = (bool*)ptr; 
                *boolptr = (bool)data; //WIN64 Changes
                mofField->DataPointer = (void*)boolptr; 
                offSet += sizeof(bool); 
            }
            else if (data is decimal) 
            {
                mofField->DataLength = (uint)sizeof(decimal);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)15; //WIN64 Changes
                } 
                decimal* decimalptr = (decimal*)ptr; 
                *decimalptr = (decimal)data; //WIN64 Changes
                mofField->DataPointer = (void*)decimalptr; 
                offSet += (uint)sizeof(decimal);
            }
            else
            { 
                //To our eyes, everything else is a just a string
                sRet = data.ToString(); 
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)2; //WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
                }
                else
                { // TraceEvent path. Need counted strings. 
                    mofField->DataLength = sizeof(ushort);
                    ushort* ushortptr = (ushort*)ptr; 
                    *ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535); 
                    mofField->DataPointer = (void*)ushortptr;
                    offSet += sizeof(ushort); 
                }

                return sRet;
            } 
            if (ptrArgInfo != null)
            { 
                *(ushort*)(ptrArgInfo + 1) = (ushort)(mofField->DataLength); //WIN64 Changes (?) 
            }
 
            return sRet;
        }

        // 
        // Enumerations
        // 
 
        internal sealed class RequestCodes
        { 
            // Ensure class cannot be instantiated
            private RequestCodes() { }
            internal const uint GetAllData = 0;                 // Never Used
            internal const uint GetSingleInstance = 1;          // Never Used 
            internal const uint SetSingleInstance = 2;          // Never Used
            internal const uint SetSingleItem = 3;              // Never Used 
            internal const uint EnableEvents = 4;               // Enable Tracing 
            internal const uint DisableEvents = 5;              // Disable Tracing
            internal const uint EnableCollection = 6;           // Never Used 
            internal const uint DisableCollection = 7;          // Never Used
            internal const uint RegInfo = 8;                    // Registration Information
            internal const uint ExecuteMethod = 9;              // Never Used
        } 

        // 
        // Structures 
        //
 
        [StructLayout(LayoutKind.Explicit, Size = 16)]
        internal struct MofField
        {
            [FieldOffset(0)] 
            internal unsafe void* DataPointer;
            [FieldOffset(8)] 
            internal uint DataLength; 
            [FieldOffset(12)]
            internal uint DataType; 
        }

        [StructLayout(LayoutKind.Explicit, Size = 304)]
        internal struct BaseEvent 
        {
            [FieldOffset(0)] 
            internal uint BufferSize; 
            [FieldOffset(4)]
            internal byte EventType;  // EventType.xx constant or a custom event subtype 
            [FieldOffset(5)]
            internal EventTrace.Level Level;
            [FieldOffset(6)]
            internal ushort Version; 
            [FieldOffset(8)]
            internal ulong HistoricalContext; 
            [FieldOffset(16)] 
            internal Int64 TimeStamp;
            [FieldOffset(24)] 
            internal System.Guid Guid;
            [FieldOffset(40)]
            internal uint ClientContext;
            [FieldOffset(44)] 
            internal uint Flags;
            [FieldOffset(48)] 
            internal MofField UserData;  // We have allocated enough space for 16 MOF_FIELD structures at the bottom 
        }
    } 
    #endregion //TraceProvider
}

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
// File: TraceProvider
//
// A Managed wrapper for Event Tracing for Windows
// Based on TraceEvent.cs found in nt\base\wmi\trace.net 
// Provides an internal Avalon API to replace Microsoft.Windows.EventTracing.dll
// 
//--------------------------------------------------------------------------- 
using System;
using MS.Win32; 
using MS.Internal;
using System.Runtime.InteropServices;
using System.Security;
using System.Globalization; //for CultureInfo 

#pragma warning disable 1634, 1691  //disable warnings about unknown pragma 
 
#if WINDOWS_BASE
    using MS.Internal.WindowsBase; 
#elif PRESENTATION_CORE
    using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
    using MS.Internal.PresentationFramework; 
#elif DRT
    using MS.Internal.Drt; 
#else 
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName; 
#endif

namespace MS.Utility
{ 
    #region TraceProvider
 
    [Guid("748004CA-4959-409a-887C-6546438CF48E")] 
    [FriendAccessAllowed]
    internal class TraceProvider 
    {
        private const ushort _version = 2;
        private UnsafeNativeMethods.EtwTrace.EtwProc _etwProc;   // Trace Callback function
        private SecurityCriticalDataForSet _registrationHandle;                       // Trace Registration Handle 
        private ulong _traceHandle;                              // Trace Logger Handle from callback
        private byte _level;                                     // Tracing Level 
        private uint _flags;                                     // Trace Enable Flags 
        private bool _enabled;                                   // Enabled flag from Trace callback
 
        ///
        /// Critical:  This calls critical code in TraceProvider (Register)
        ///
        [SecurityCritical] 
        internal TraceProvider(string _applicationName, Guid controlGuid)
        { 
            _level = 0; 
            _flags = 0;
            _enabled = false; 
            _traceHandle = 0;
            _registrationHandle = new SecurityCriticalDataForSet(0);

            // Register the controlGuid with ETW 
            Register(controlGuid);
        } 
 
        ///
        /// Critical:  This calls critical code in EtwTrace 
        /// TreatAsSafe: the registration handle this passes in to UnregisterTraceGuids
        /// was generated by the ETW unmanaged API and can't be tampered with from our side
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        ~TraceProvider()
        { 
            // 
            // Unregister from ETW using the _registrationHandle saved from
            // the register call.  We don't care what UnregisterTraceGuids returns. 
            // If the call fails there's nothing the finalizer can do anyway
            //

            #pragma warning suppress 6031  //presharp suppression 
            UnsafeNativeMethods.EtwTrace.UnregisterTraceGuids(_registrationHandle.Value);
            GC.KeepAlive(_etwProc); 
        } 

        internal uint Flags 
        {
            get
            {
                return _flags; 
            }
        } 
 
        internal byte Level
        { 
            get
            {
                return _level;
            } 
        }
 
        internal bool IsEnabled 
        {
            get 
            {
                return _enabled;
            }
        } 

        // 
        // This callback function is called by ETW to enable or disable 
        // Tracing dynamically
        // 
        ///
        /// Critical:  This calls critical code in EtwTrace
        /// TreatAsSafe:  This callback is called by the ETW unmanaged API when tracing has been enabled.
        /// This method does nothing insecure with the data passed into it. The registration of this callback 
        /// is covered by the Register method
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal unsafe uint MyCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte* byteBuffer)
        { 
            try
            {
                BaseEvent* buffer = (BaseEvent*)byteBuffer;
                switch (requestCode) 
                {
                    case RequestCodes.EnableEvents: 
                        _traceHandle = buffer->HistoricalContext; 
                        _flags = (uint)UnsafeNativeMethods.EtwTrace.GetTraceEnableFlags((ulong)buffer->HistoricalContext);
                        _level = UnsafeNativeMethods.EtwTrace.GetTraceEnableLevel((ulong)buffer->HistoricalContext); 
                        _enabled = true;
                        break;
                    case RequestCodes.DisableEvents:
                        _enabled = false; 
                        _traceHandle = 0;
                        _level = 0; 
                        _flags = 0; 
                        break;
                    default: 
                        _enabled = false;
                        _traceHandle = 0;
                        break;
                } 

                return 0; 
            } 
            catch(Exception e)
            { 
                // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
                //
                // This should be CriticalExceptions.IsCriticalException, but that requires
                // linking to WindowsBase, which is a heavy requirement for "shared" code. 
                //
                if ((e is NullReferenceException) || (e is System.Runtime.InteropServices.SEHException)) 
                { 
                   throw;
                } 
                else
                {
                    return 0;
                } 
            }
        } 
 
        //
        // Registers the controlGuid with an inbuilt callback 
        //
        ///
        /// Critical:  This calls critical code in UnsafeNativeMethods.EtwTrace
        /// and sets critical for set field _registrationHandle 
        ///
        [SecurityCritical] 
        private unsafe uint Register(Guid controlGuid) 
        {
            uint status; 
            ulong registrationHandle;
            UnsafeNativeMethods.EtwTrace.TraceGuidRegistration guidReg = new UnsafeNativeMethods.EtwTrace.TraceGuidRegistration();

            Guid dummyGuid = new Guid(0xb4955bf0, 
                                      0x3af1,
                                      0x4740, 
                                      0xb4,0x75, 
                                      0x99,0x05,0x5d,0x3f,0xe9,0xaa);
 
            _etwProc = new UnsafeNativeMethods.EtwTrace.EtwProc(MyCallback);

            // This dummyGuid is there for ETW backward compat issues
            guidReg.Guid = &dummyGuid; 
            guidReg.RegHandle = null;
 
            status = UnsafeNativeMethods.EtwTrace.RegisterTraceGuids(_etwProc, null, ref controlGuid, 1, ref guidReg, null, null, out registrationHandle); 
            _registrationHandle.Value = registrationHandle;
 
            return status;
        }

        // All of the following TraceEvent overloads are used in the codebase.  To keep FxCop happy 
        // we don't keep around unused ones.  If another overload is needed it is trivial to add.
 
        // No arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, null, null);
        }

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType) 
        {
            TraceEvent(level, eventGuid, eventType, null, null); 
        } 

        // 1 argument 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0)
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, null);
        } 

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0) 
        { 
            TraceEvent(level, eventGuid, eventType, data0, null);
        } 

        // 2 arguments
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1);
        } 
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, null, null, null, null, null, null, null);
        }

        // 3 arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2)
        { 
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2); 
        }
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2)
        {
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, null, null, null, null, null, null);
        } 

        // 4 arguments 
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3) 
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3); 
        }

        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, null, null, null, null, null);
        } 
 
        // 5 arguments
        internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4) 
        {
            TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3, data4);
        }
 
        internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
        { 
            TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, null, null, null, null); 
        }
 
        ///
        /// Critical:  This calls critical code in UnsaveNativeMethods.EtwTrace
        /// TreatAsSafe:  The arguments are serialized and sent to the unmanaged ETW API as a packet with a verified size
        /// the unmanaged ETW code stores this in a buffer which is later picked up by post-processing tools - the data cannot 
        /// be executed
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal unsafe uint TraceEvent(
            EventTrace.Level level, Guid eventGuid, byte evtype, 
            object data0, object data1, object data2, object data3, object data4, object data5, object data6, object data7, object data8)
        {
            uint status = 0;
            BaseEvent ev;      // Takes up 304 bytes on the stack 

            // The largest possible item stored in this buffer from each of data0 
            // through data8 will be a decimal (strings are logged as pointers) 
            const uint bufferSize = sizeof(decimal) * 9;
            char* buffer = stackalloc char[(int)bufferSize]; 
            uint offset = 0;
            char* ptr = buffer;
            string s0, s1, s2, s3, s4, s5, s6, s7, s8;
            int stringMask = 0; 
            uint argCount = 0;
            int mofIndex = 0; 
 
            s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = "";
 
            ev.ClientContext = 0;
            ev.Flags = 0x00120000; // define Constants
            ev.Guid = eventGuid;
            ev.EventType = evtype; 
            ev.Level = level;
            ev.Version = _version; 
            MofField* be = null; 

            if (data0 != null) 
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++];
                if ((s0 = ProcessOneObject(data0, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000001; 
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            } 
            if (data1 != null)
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s1 = ProcessOneObject(data1, be, ptr, ref offset)) != null) 
                { 
                    stringMask |= 0x00000002;
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            }
            if (data2 != null)
            { 
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset; 
                if ((s2 = ProcessOneObject(data2, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000004;
                    mofIndex++; // Leave a slot for the String Pointer
                }
            } 
            if (data3 != null)
            { 
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s3 = ProcessOneObject(data3, be, ptr, ref offset)) != null)
                {
                    stringMask |= 0x00000008;
                    mofIndex++; // Leave a slot for the String Pointer 
                }
            } 
            if (data4 != null) 
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset;
                if ((s4 = ProcessOneObject(data4, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000010;
                    mofIndex++; // Leave a slot for the String Pointer 
                } 
            }
            if (data5 != null) 
            {
                argCount++;
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s5 = ProcessOneObject(data5, be, ptr, ref offset)) != null)
                { 
                    stringMask |= 0x00000020; 
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            }
            if (data6 != null)
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++];
                ptr = buffer + offset; 
                if ((s6 = ProcessOneObject(data6, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000040; 
                    mofIndex++; // Leave a slot for the String Pointer
                }
            }
            if (data7 != null) 
            {
                argCount++; 
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s7 = ProcessOneObject(data7, be, ptr, ref offset)) != null) 
                {
                    stringMask |= 0x00000080;
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            }
            if (data8 != null) 
            { 
                argCount++;
                be = &(&ev.UserData)[mofIndex++]; 
                ptr = buffer + offset;
                if ((s8 = ProcessOneObject(data8, be, ptr, ref offset)) != null)
                {
                    stringMask |= 0x00000100; 
                    mofIndex++; // Leave a slot for the String Pointer
                } 
            } 

            // Assert we haven't exceeded the buffer size 
            Invariant.Assert(ptr - buffer <= bufferSize);

            // Now pin all the strings and use the stringMask to pass them over through mofField
            fixed (char* vptr0 = s0, vptr1 = s1, vptr2 = s2, vptr3 = s3, vptr4 = s4, vptr5 = s5, vptr6 = s6, vptr7 = s7, vptr8 = s8) 
            {
                int i = 0; 
                if ((stringMask & 0x00000001) != 0) 
                {
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s0.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr0;
                }
                i++; 
                if ((stringMask & 0x00000002) != 0)
                { 
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s1.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr1; 
                }
                i++;
                if ((stringMask & 0x00000004) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s2.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr2; 
                }
                i++; 
                if ((stringMask & 0x00000008) != 0)
                {
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s3.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr3;
                } 
                i++; 
                if ((stringMask & 0x00000010) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s4.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr4;
 
                }
                i++; 
                if ((stringMask & 0x00000020) != 0) 
                {
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s5.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr5;
                }
                i++; 
                if ((stringMask & 0x00000040) != 0)
                { 
                    i++; 
                    (&ev.UserData)[i].DataLength = (uint)s6.Length * 2;
                    (&ev.UserData)[i].DataPointer = (void*)vptr6; 
                }
                i++;
                if ((stringMask & 0x00000080) != 0)
                { 
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s7.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr7; 
                }
                i++; 
                if ((stringMask & 0x00000100) != 0)
                {
                    i++;
                    (&ev.UserData)[i].DataLength = (uint)s8.Length * 2; 
                    (&ev.UserData)[i].DataPointer = (void*)vptr8;
                } 
 
                ev.BufferSize = 48 + (uint)mofIndex * (uint)sizeof(MofField);
                status = UnsafeNativeMethods.EtwTrace.TraceEvent(_traceHandle, (char*)&ev); 
            }

            return status;
        } 

        /// 
        ///Critical - unsafe pointers 
        ///
        [SecurityCritical] 
        private unsafe string ProcessOneObject(object data, MofField* mofField, char* ptr, ref uint offSet)
        {
            return EncodeObject(data, mofField, ptr, ref offSet, (byte*)null);
        } 

        // 
 

 

        [SecurityCritical]
        private unsafe string EncodeObject(object data, MofField* mofField, char* ptr, ref uint offSet, byte* ptrArgInfo)
        { 
            if (data == null)
            { 
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)0; //NULL type, WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)0;
                }
                mofField->DataLength = 0;
                mofField->DataPointer = (void*)null; //WIN64 Changes (?) 
                return null;
            } 
 
            // if the data is an enum we'll convert it to its underlying type
            Type dataType = data.GetType(); 

            if (dataType.IsEnum)
            {
                data = Convert.ChangeType(data, Enum.GetUnderlyingType(dataType), CultureInfo.InvariantCulture); 
            }
 
            string sRet = data as string; 

            if (sRet != null) 
            {
                if (ptrArgInfo != null)
                {
                    *ptrArgInfo = (byte)2; //WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
                } 
                else 
                { // TraceEvent path. Need counted strings.
                    mofField->DataLength = sizeof(ushort); 
                    ushort* ushortptr = (ushort*)ptr;
                    *ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
                    mofField->DataPointer = (void*)ushortptr;
                    offSet += sizeof(ushort); 
                }
 
                return sRet; 
            }
            if (data is sbyte) 
            {
                mofField->DataLength = sizeof(sbyte);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)3; //WIN64 Changes
                } 
                sbyte* sbyteptr = (sbyte*)ptr; 
                *sbyteptr = (sbyte)data; //WIN64 Changes
                mofField->DataPointer = (void*)sbyteptr; 
                offSet += sizeof(sbyte);
            }
            else if (data is byte)
            { 
                mofField->DataLength = sizeof(byte);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)4; //WIN64 Changes
                } 
                byte* byteptr = (byte*)ptr;
                *byteptr = (byte)data; //WIN64 Changes
                mofField->DataPointer = (void*)byteptr;
                offSet += sizeof(byte); 
            }
            else if (data is short) 
            { 
                mofField->DataLength = sizeof(short);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)5; //WIN64 Changes
                }
                short* shortptr = (short*)ptr; 
                *shortptr = (short)data; //WIN64 Changes
                mofField->DataPointer = (void*)shortptr; 
                offSet += sizeof(short); 
            }
            else if (data is ushort) 
            {
                mofField->DataLength = sizeof(ushort);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)6; //WIN64 Changes
                } 
                ushort* ushortptr = (ushort*)ptr; 
                *ushortptr = (ushort)data; //WIN64 Changes
                mofField->DataPointer = (void*)ushortptr; 
                offSet += sizeof(ushort);
            }
            else if (data is int)
            { 
                mofField->DataLength = sizeof(int);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)7; //WIN64 Changes
                } 
                int* intptr = (int*)ptr;
                *intptr = (int)data; //WIN64 Changes
                mofField->DataPointer = (void*)intptr;
                offSet += sizeof(int); 
            }
            else if (data is uint) 
            { 
                mofField->DataLength = sizeof(uint);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)8; //WIN64 Changes
                }
                uint* uintptr = (uint*)ptr; 
                *uintptr = (uint)data; //WIN64 Changes
                mofField->DataPointer = (void*)uintptr; 
                offSet += sizeof(uint); 
            }
            else if (data is long) 
            {
                mofField->DataLength = sizeof(long);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)9; //WIN64 Changes
                } 
                long* longptr = (long*)ptr; 
                *longptr = (long)data; //WIN64 Changes
                mofField->DataPointer = (void*)longptr; 
                offSet += sizeof(long);
            }
            else if (data is ulong)
            { 
                mofField->DataLength = sizeof(ulong);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)10; //WIN64 Changes
                } 
                ulong* ulongptr = (ulong*)ptr;
                *ulongptr = (ulong)data; //WIN64 Changes
                mofField->DataPointer = (void*)ulongptr;
                offSet += sizeof(ulong); 
            }
            else if (data is char) 
            { 
                mofField->DataLength = sizeof(char);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)11; //WIN64 Changes
                }
                char* charptr = (char*)ptr; 
                *charptr = (char)data; //WIN64 Changes
                mofField->DataPointer = (void*)charptr; 
                offSet += sizeof(char); 
            }
            else if (data is float) 
            {
                mofField->DataLength = sizeof(float);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)12; //WIN64 Changes
                } 
                float* floatptr = (float*)ptr; 
                *floatptr = (float)data; //WIN64 Changes
                mofField->DataPointer = (void*)floatptr; 
                offSet += sizeof(float);
            }
            else if (data is double)
            { 
                mofField->DataLength = sizeof(double);
                if (ptrArgInfo != null) 
                { 
                    *ptrArgInfo = (byte)13; //WIN64 Changes
                } 
                double* doubleptr = (double*)ptr;
                *doubleptr = (double)data; //WIN64 Changes
                mofField->DataPointer = (void*)doubleptr;
                offSet += sizeof(double); 
            }
            else if (data is bool) 
            { 
                mofField->DataLength = sizeof(bool);
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)14; //WIN64 Changes
                }
                bool* boolptr = (bool*)ptr; 
                *boolptr = (bool)data; //WIN64 Changes
                mofField->DataPointer = (void*)boolptr; 
                offSet += sizeof(bool); 
            }
            else if (data is decimal) 
            {
                mofField->DataLength = (uint)sizeof(decimal);
                if (ptrArgInfo != null)
                { 
                    *ptrArgInfo = (byte)15; //WIN64 Changes
                } 
                decimal* decimalptr = (decimal*)ptr; 
                *decimalptr = (decimal)data; //WIN64 Changes
                mofField->DataPointer = (void*)decimalptr; 
                offSet += (uint)sizeof(decimal);
            }
            else
            { 
                //To our eyes, everything else is a just a string
                sRet = data.ToString(); 
                if (ptrArgInfo != null) 
                {
                    *ptrArgInfo = (byte)2; //WIN64 Changes 
                    *(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
                }
                else
                { // TraceEvent path. Need counted strings. 
                    mofField->DataLength = sizeof(ushort);
                    ushort* ushortptr = (ushort*)ptr; 
                    *ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535); 
                    mofField->DataPointer = (void*)ushortptr;
                    offSet += sizeof(ushort); 
                }

                return sRet;
            } 
            if (ptrArgInfo != null)
            { 
                *(ushort*)(ptrArgInfo + 1) = (ushort)(mofField->DataLength); //WIN64 Changes (?) 
            }
 
            return sRet;
        }

        // 
        // Enumerations
        // 
 
        internal sealed class RequestCodes
        { 
            // Ensure class cannot be instantiated
            private RequestCodes() { }
            internal const uint GetAllData = 0;                 // Never Used
            internal const uint GetSingleInstance = 1;          // Never Used 
            internal const uint SetSingleInstance = 2;          // Never Used
            internal const uint SetSingleItem = 3;              // Never Used 
            internal const uint EnableEvents = 4;               // Enable Tracing 
            internal const uint DisableEvents = 5;              // Disable Tracing
            internal const uint EnableCollection = 6;           // Never Used 
            internal const uint DisableCollection = 7;          // Never Used
            internal const uint RegInfo = 8;                    // Registration Information
            internal const uint ExecuteMethod = 9;              // Never Used
        } 

        // 
        // Structures 
        //
 
        [StructLayout(LayoutKind.Explicit, Size = 16)]
        internal struct MofField
        {
            [FieldOffset(0)] 
            internal unsafe void* DataPointer;
            [FieldOffset(8)] 
            internal uint DataLength; 
            [FieldOffset(12)]
            internal uint DataType; 
        }

        [StructLayout(LayoutKind.Explicit, Size = 304)]
        internal struct BaseEvent 
        {
            [FieldOffset(0)] 
            internal uint BufferSize; 
            [FieldOffset(4)]
            internal byte EventType;  // EventType.xx constant or a custom event subtype 
            [FieldOffset(5)]
            internal EventTrace.Level Level;
            [FieldOffset(6)]
            internal ushort Version; 
            [FieldOffset(8)]
            internal ulong HistoricalContext; 
            [FieldOffset(16)] 
            internal Int64 TimeStamp;
            [FieldOffset(24)] 
            internal System.Guid Guid;
            [FieldOffset(40)]
            internal uint ClientContext;
            [FieldOffset(44)] 
            internal uint Flags;
            [FieldOffset(48)] 
            internal MofField UserData;  // We have allocated enough space for 16 MOF_FIELD structures at the bottom 
        }
    } 
    #endregion //TraceProvider
}

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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