Move EventSource to shared CoreLib partition (#23925)
authorFilip Navara <filip.navara@gmail.com>
Tue, 16 Apr 2019 13:52:53 +0000 (15:52 +0200)
committerJan Kotas <jkotas@microsoft.com>
Tue, 16 Apr 2019 13:52:53 +0000 (06:52 -0700)
* Move most of EventSource to shared CoreLib partition

* Reenable some code that can be shared with Microsoft.Diagnostics.Tracing.EventSource.Redist in CoreFX

* Remove unused functions

* Fix placement of #endregion

* Clean up P/Invoke prototypes

* Move remaining code from EventSource_CoreCLR to shared partition (guarded by !CORERT)

* Remove more unnecessary marshalling attributes

* Move remaining CoreRT/ProjectN code to shared partition

* Avoid using Windows errors on non-Windows platforms

20 files changed:
src/System.Private.CoreLib/System.Private.CoreLib.csproj
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.ActivityControl.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EVENT_INFO_CLASS.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EtwEnableCallback.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventActivityIdControl.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventRegister.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventSetInformation.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventTraceGuidsEx.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventUnregister.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteString.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteTransfer.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs
src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/IEventProvider.cs
src/System.Private.CoreLib/src/Microsoft/Win32/UnsafeNativeMethods.cs
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventProvider.cs
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs [deleted file]

index f7df61d..c012ba5 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeMetadataGenerator.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipePayloadDecoder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\RuntimeEventSource.cs" Condition="'$(FeaturePerfTracing)' == 'true'"/>
-    <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource_CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventHandleTable.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\ICustomDebuggerNotification.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\StackFrame.CoreCLR.cs" />
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.ActivityControl.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.ActivityControl.cs
new file mode 100644 (file)
index 0000000..34df748
--- /dev/null
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        internal 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
+        }
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EVENT_INFO_CLASS.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EVENT_INFO_CLASS.cs
new file mode 100644 (file)
index 0000000..a122002
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        internal enum EVENT_INFO_CLASS
+        {
+            BinaryTrackInfo,
+            SetEnableAllKeywords,
+            SetTraits,
+        }
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EtwEnableCallback.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EtwEnableCallback.cs
new file mode 100644 (file)
index 0000000..6bb1575
--- /dev/null
@@ -0,0 +1,33 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        internal const int EVENT_CONTROL_CODE_DISABLE_PROVIDER = 0;
+        internal const int EVENT_CONTROL_CODE_ENABLE_PROVIDER = 1;
+        internal const int EVENT_CONTROL_CODE_CAPTURE_STATE = 2;
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct EVENT_FILTER_DESCRIPTOR
+        {
+            public long Ptr;
+            public int Size;
+            public int Type;
+        }
+
+        internal unsafe delegate void EtwEnableCallback(
+            in Guid sourceId,
+            int isEnabled,
+            byte level,
+            long matchAnyKeywords,
+            long matchAllKeywords,
+            EVENT_FILTER_DESCRIPTOR* filterData,
+            void* callbackContext);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventActivityIdControl.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventActivityIdControl.cs
new file mode 100644 (file)
index 0000000..886ff37
--- /dev/null
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, ExactSpelling = true)]
+        internal static extern int EventActivityIdControl(ActivityControl ControlCode, ref Guid ActivityId);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventRegister.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventRegister.cs
new file mode 100644 (file)
index 0000000..f5d245e
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, ExactSpelling = true)]
+        internal static extern unsafe uint EventRegister(
+            in Guid providerId,
+            EtwEnableCallback enableCallback,
+            void* callbackContext,
+            ref long registrationHandle);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventSetInformation.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventSetInformation.cs
new file mode 100644 (file)
index 0000000..381cb66
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, ExactSpelling = true)]
+        internal static unsafe extern int EventSetInformation(
+            long registrationHandle,
+            EVENT_INFO_CLASS informationClass,
+            void* eventInformation,
+            int informationLength);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventTraceGuidsEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventTraceGuidsEx.cs
new file mode 100644 (file)
index 0000000..c5f6f3b
--- /dev/null
@@ -0,0 +1,59 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        internal enum TRACE_QUERY_INFO_CLASS
+        {
+            TraceGuidQueryList,
+            TraceGuidQueryInfo,
+            TraceGuidQueryProcess,
+            TraceStackTracingInfo,
+            MaxTraceSetInfoClass
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct TRACE_GUID_INFO
+        {
+            public int InstanceCount;
+            public int Reserved;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct TRACE_PROVIDER_INSTANCE_INFO
+        {
+            public int NextOffset;
+            public int EnableCount;
+            public int Pid;
+            public int Flags;
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct TRACE_ENABLE_INFO
+        {
+            public int IsEnabled;
+            public byte Level;
+            public byte Reserved1;
+            public ushort LoggerId;
+            public int EnableProperty;
+            public int Reserved2;
+            public long MatchAnyKeyword;
+            public long MatchAllKeyword;
+        }
+
+        [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true)]
+        internal static unsafe extern int EnumerateTraceGuidsEx(
+            TRACE_QUERY_INFO_CLASS TraceQueryInfoClass,
+            void* InBuffer,
+            int InBufferSize,
+            void* OutBuffer,
+            int OutBufferSize,
+            out int ReturnLength);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventUnregister.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventUnregister.cs
new file mode 100644 (file)
index 0000000..f387b3a
--- /dev/null
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, ExactSpelling = true)]
+        internal static extern uint EventUnregister(long registrationHandle);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteString.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteString.cs
new file mode 100644 (file)
index 0000000..a00a2f3
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, ExactSpelling = true)]
+        internal static extern int EventWriteString(
+            long registrationHandle,
+            byte level,
+            long keyword,
+            string msg);
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteTransfer.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.EventWriteTransfer.cs
new file mode 100644 (file)
index 0000000..2d3f45e
--- /dev/null
@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+#if ES_BUILD_STANDALONE
+using Microsoft.Diagnostics.Tracing;
+#else
+using System.Diagnostics.Tracing;
+#endif
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        /// <summary>
+        ///  Call the ETW native API EventWriteTransfer and checks for invalid argument error. 
+        ///  The implementation of EventWriteTransfer on some older OSes (Windows 2008) does not accept null relatedActivityId.
+        ///  So, for these cases we will retry the call with an empty Guid.
+        /// </summary>
+        internal static unsafe int EventWriteTransfer(
+            long registrationHandle,
+            in EventDescriptor eventDescriptor,
+            Guid* activityId,
+            Guid* relatedActivityId,
+            int userDataCount,
+            EventProvider.EventData* userData)
+        {
+            int HResult = EventWriteTransfer_PInvoke(registrationHandle, in eventDescriptor, activityId, relatedActivityId, userDataCount, userData);
+            if (HResult == Errors.ERROR_INVALID_PARAMETER && relatedActivityId == null)
+            {
+                Guid emptyGuid = Guid.Empty;
+                HResult = EventWriteTransfer_PInvoke(registrationHandle, in eventDescriptor, activityId, &emptyGuid, userDataCount, userData);
+            }
+
+            return HResult;
+        }
+
+        [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventWriteTransfer")]
+        private static unsafe extern int EventWriteTransfer_PInvoke(
+            long registrationHandle,
+            in EventDescriptor eventDescriptor,
+            Guid* activityId,
+            Guid* relatedActivityId,
+            int userDataCount,
+            EventProvider.EventData* userData);
+    }
+}
index 1a95db3..2e4683d 100644 (file)
@@ -18,6 +18,7 @@ internal partial class Interop
         internal const int ERROR_NOT_READY = 0x15;
         internal const int ERROR_SHARING_VIOLATION = 0x20;
         internal const int ERROR_HANDLE_EOF = 0x26;
+        internal const int ERROR_NOT_SUPPORTED = 0x32;
         internal const int ERROR_FILE_EXISTS = 0x50;
         internal const int ERROR_INVALID_PARAMETER = 0x57;
         internal const int ERROR_BROKEN_PIPE = 0x6D;
index 716dc56..e51a210 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Void.cs" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.ActivityControl.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EtwEnableCallback.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EVENT_INFO_CLASS.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\ActivityTracker.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\DiagnosticCounter.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\CounterGroup.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector_Operations.cs" />
   </ItemGroup>
   <ItemGroup Condition="$(TargetsWindows)">
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventActivityIdControl.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventRegister.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventSetInformation.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventTraceGuidsEx.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventUnregister.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventWriteString.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.EventWriteTransfer.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.LookupAccountNameW.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\BCrypt\Interop.BCryptGenRandom.GetRandomBytes.cs" />
index 345a9cf..a8622a8 100644 (file)
@@ -63,7 +63,7 @@ namespace System.Diagnostics.Tracing
 #if ES_BUILD_STANDALONE
     [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
 #endif
-    internal partial class EventProvider : IDisposable
+    internal class EventProvider : IDisposable
     {
         // This is the windows EVENT_DATA_DESCRIPTOR structure.  We expose it because this is what
         // subclasses of EventProvider use when creating efficient (but unsafe) version of
@@ -92,10 +92,8 @@ namespace System.Diagnostics.Tracing
             { sessionIdBit = sessionIdBit_; etwSessionId = etwSessionId_; }
         }
 
-        private static bool m_setInformationMissing;
-
         internal IEventProvider m_eventProvider;         // The interface that implements the specific logging mechanism functions.
-        UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback;     // Trace Callback function
+        Interop.Advapi32.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
@@ -165,14 +163,14 @@ namespace System.Diagnostics.Tracing
         /// reason the ETW Register call failed a NotSupported exception will be thrown. 
         /// </summary>
         // <SecurityKernel Critical="True" Ring="0">
-        // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventRegister(System.Guid&,Microsoft.Win32.UnsafeNativeMethods.ManifestEtw+EtwEnableCallback,System.Void*,System.Int64&):System.UInt32" />
+        // <CallsSuppressUnmanagedCode Name="Interop.Advapi32.EventRegister(System.Guid&,Microsoft.Win32.Interop.Advapi32+EtwEnableCallback,System.Void*,System.Int64&):System.UInt32" />
         // <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32)" />
         // <ReferencesCritical Name="Method: EtwEnableCallBack(Guid&, Int32, Byte, Int64, Int64, Void*, Void*):Void" Ring="1" />
         // </SecurityKernel>
         internal unsafe void Register(EventSource eventSource)
         {
             uint status;
-            m_etwCallback = new UnsafeNativeMethods.ManifestEtw.EtwEnableCallback(EtwEnableCallBack);
+            m_etwCallback = new Interop.Advapi32.EtwEnableCallback(EtwEnableCallBack);
 
             status = EventRegister(eventSource, m_etwCallback);
             if (status != 0)
@@ -264,13 +262,13 @@ namespace System.Diagnostics.Tracing
         // <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
         // </SecurityKernel>
         unsafe void EtwEnableCallBack(
-                        [In] ref System.Guid sourceId,
-                        [In] int controlCode,
-                        [In] byte setLevel,
-                        [In] long anyKeyword,
-                        [In] long allKeyword,
-                        [In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
-                        [In] void* callbackContext
+                        in System.Guid sourceId,
+                        int controlCode,
+                        byte setLevel,
+                        long anyKeyword,
+                        long allKeyword,
+                        Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData,
+                        void* callbackContext
                         )
         {
             // This is an optional callback API. We will therefore ignore any failures that happen as a 
@@ -281,7 +279,7 @@ namespace System.Diagnostics.Tracing
                 ControllerCommand command = ControllerCommand.Update;
                 IDictionary<string, string> args = null;
                 bool skipFinalOnControllerCommand = false;
-                if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
+                if (controlCode == Interop.Advapi32.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
                 {
                     m_enabled = true;
                     m_level = setLevel;
@@ -342,7 +340,7 @@ namespace System.Diagnostics.Tracing
                         OnControllerCommand(command, args, (bEnabling ? sessionChanged : -sessionChanged), etwSessionId);
                     }
                 }
-                else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_DISABLE_PROVIDER)
+                else if (controlCode == Interop.Advapi32.EVENT_CONTROL_CODE_DISABLE_PROVIDER)
                 {
                     m_enabled = false;
                     m_level = 0;
@@ -350,7 +348,7 @@ namespace System.Diagnostics.Tracing
                     m_allKeywordMask = 0;
                     m_liveSessions = null;
                 }
-                else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_CAPTURE_STATE)
+                else if (controlCode == Interop.Advapi32.EVENT_CONTROL_CODE_CAPTURE_STATE)
                 {
                     command = ControllerCommand.SendManifest;
                 }
@@ -491,24 +489,24 @@ namespace System.Diagnostics.Tracing
 
                 fixed (Guid* provider = &m_providerId)
                 {
-                    hr = UnsafeNativeMethods.ManifestEtw.EnumerateTraceGuidsEx(UnsafeNativeMethods.ManifestEtw.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
-                        provider, sizeof(Guid), buffer, buffSize, ref buffSize);
+                    hr = Interop.Advapi32.EnumerateTraceGuidsEx(Interop.Advapi32.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
+                        provider, sizeof(Guid), buffer, buffSize, out buffSize);
                 }
                 if (hr == 0)
                     break;
-                if (hr != 122 /* ERROR_INSUFFICIENT_BUFFER */)
+                if (hr != Interop.Errors.ERROR_INSUFFICIENT_BUFFER)
                     return;
             }
 
-            var providerInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_GUID_INFO*)buffer;
-            var providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
+            var providerInfos = (Interop.Advapi32.TRACE_GUID_INFO*)buffer;
+            var providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
             int processId = unchecked((int)Interop.Kernel32.GetCurrentProcessId());
             // iterate over the instances of the EventProvider in all processes
             for (int i = 0; i < providerInfos->InstanceCount; i++)
             {
                 if (providerInstance->Pid == processId)
                 {
-                    var enabledInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_ENABLE_INFO*)&providerInstance[1];
+                    var enabledInfos = (Interop.Advapi32.TRACE_ENABLE_INFO*)&providerInstance[1];
                     // iterate over the list of active ETW sessions "listening" to the current provider
                     for (int j = 0; j < providerInstance->EnableCount; j++)
                         action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
@@ -517,7 +515,7 @@ namespace System.Diagnostics.Tracing
                     break;
                 Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
                 var structBase = (byte*)providerInstance;
-                providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
+                providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
             }
 #else
 #if !ES_BUILD_PCL && PLATFORM_WINDOWS  // TODO command arguments don't work on PCL builds...
@@ -602,7 +600,7 @@ namespace System.Diagnostics.Tracing
         /// starts, and the command being issued associated with that data.  
         /// </summary>
         private unsafe bool GetDataFromController(int etwSessionId,
-                UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
+                Interop.Advapi32.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
         {
             data = null;
             dataStart = 0;
@@ -704,18 +702,9 @@ namespace System.Diagnostics.Tracing
         //
         // Helper function to set the last error on the thread
         //
-        private static void SetLastError(int error)
+        private static void SetLastError(WriteEventErrorCode error)
         {
-            switch (error)
-            {
-                case UnsafeNativeMethods.ManifestEtw.ERROR_ARITHMETIC_OVERFLOW:
-                case UnsafeNativeMethods.ManifestEtw.ERROR_MORE_DATA:
-                    s_returnCode = WriteEventErrorCode.EventTooBig;
-                    break;
-                case UnsafeNativeMethods.ManifestEtw.ERROR_NOT_ENOUGH_MEMORY:
-                    s_returnCode = WriteEventErrorCode.NoFreeBuffers;
-                    break;
-            }
+            s_returnCode = error;
         }
 
         // <SecurityKernel Critical="True" Ring="0">
@@ -961,7 +950,7 @@ namespace System.Diagnostics.Tracing
         /// Payload for the ETW event. 
         /// </param>
         // <SecurityKernel Critical="True" Ring="0">
-        // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
+        // <CallsSuppressUnmanagedCode Name="Interop.Advapi32.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
         // <UsesUnsafeCode Name="Local dataBuffer of type: Byte*" />
         // <UsesUnsafeCode Name="Local pdata of type: Char*" />
         // <UsesUnsafeCode Name="Local userData of type: EventData*" />
@@ -981,7 +970,7 @@ namespace System.Diagnostics.Tracing
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
         internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, IntPtr eventHandle, Guid* activityID, Guid* childActivityID, params object[] eventPayload)
         {
-            int status = 0;
+            WriteEventErrorCode status = WriteEventErrorCode.NoError;
 
             if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords))
             {
@@ -1109,7 +1098,7 @@ namespace System.Diagnostics.Tracing
                                 userDataPtr[refObjPosition[7]].Ptr = (ulong)v7;
                             }
 
-                            status = m_eventProvider.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, eventHandle, activityID, childActivityID, argCount, userData);
+                            status = m_eventProvider.EventWriteTransfer(m_regHandle, in eventDescriptor, eventHandle, activityID, childActivityID, argCount, userData);
                         }
                     }
                     else
@@ -1135,7 +1124,7 @@ namespace System.Diagnostics.Tracing
                             }
                         }
 
-                        status = m_eventProvider.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, eventHandle, activityID, childActivityID, argCount, userData);
+                        status = m_eventProvider.EventWriteTransfer(m_regHandle, in eventDescriptor, eventHandle, activityID, childActivityID, argCount, userData);
 
                         for (int i = 0; i < refObjIndex; ++i)
                         {
@@ -1145,9 +1134,9 @@ namespace System.Diagnostics.Tracing
                 }
             }
 
-            if (status != 0)
+            if (status != WriteEventErrorCode.NoError)
             {
-                SetLastError((int)status);
+                SetLastError(status);
                 return false;
             }
 
@@ -1174,7 +1163,7 @@ namespace System.Diagnostics.Tracing
         /// pointer  do the event data
         /// </param>
         // <SecurityKernel Critical="True" Ring="0">
-        // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
+        // <CallsSuppressUnmanagedCode Name="Interop.Advapi32.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
         // </SecurityKernel>
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
         internal protected unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, IntPtr eventHandle, Guid* activityID, Guid* childActivityID, int dataCount, IntPtr data)
@@ -1188,7 +1177,7 @@ namespace System.Diagnostics.Tracing
                                 (EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
             }
 
-            int status = m_eventProvider.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, eventHandle, activityID, childActivityID, dataCount, (EventData*)data);
+            WriteEventErrorCode status = m_eventProvider.EventWriteTransfer(m_regHandle, in eventDescriptor, eventHandle, activityID, childActivityID, dataCount, (EventData*)data);
 
             if (status != 0)
             {
@@ -1207,29 +1196,30 @@ namespace System.Diagnostics.Tracing
             int dataCount,
             IntPtr data)
         {
-            int status;
+            WriteEventErrorCode status;
 
-            status = m_eventProvider.EventWriteTransferWrapper(
+            status = m_eventProvider.EventWriteTransfer(
                 m_regHandle,
-                ref eventDescriptor,
+                in eventDescriptor,
                 eventHandle,
                 activityID,
                 relatedActivityID,
                 dataCount,
                 (EventData*)data);
 
-            if (status != 0)
+            if (status != WriteEventErrorCode.NoError)
             {
                 SetLastError(status);
                 return false;
             }
+
             return true;
         }
 
 
         // These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
         // either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).  
-        private unsafe uint EventRegister(EventSource eventSource, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
+        private unsafe uint EventRegister(EventSource eventSource, Interop.Advapi32.EtwEnableCallback enableCallback)
         {
             m_providerName = eventSource.Name;
             m_providerId = eventSource.Guid;
@@ -1241,6 +1231,36 @@ namespace System.Diagnostics.Tracing
         {
             return m_eventProvider.EventUnregister(registrationHandle);
         }
+
+#if PLATFORM_WINDOWS
+        private static bool m_setInformationMissing;
+
+        internal unsafe int SetInformation(
+            Interop.Advapi32.EVENT_INFO_CLASS eventInfoClass,
+            IntPtr data,
+            uint dataSize)
+        {
+            int status = Interop.Errors.ERROR_NOT_SUPPORTED;
+
+            if (!m_setInformationMissing)
+            {
+                try
+                {
+                    status = Interop.Advapi32.EventSetInformation(
+                        m_regHandle,
+                        eventInfoClass,
+                        (void*)data,
+                        (int)dataSize);
+                }
+                catch (TypeLoadException)
+                {
+                    m_setInformationMissing = true;
+                }
+            }
+
+            return status;
+        }
+#endif
     }
 
 #if PLATFORM_WINDOWS
@@ -1251,13 +1271,13 @@ namespace System.Diagnostics.Tracing
         // Register an event provider.
         unsafe uint IEventProvider.EventRegister(
             EventSource eventSource,
-            UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback,
+            Interop.Advapi32.EtwEnableCallback enableCallback,
             void* callbackContext,
             ref long registrationHandle)
         {
             Guid providerId = eventSource.Guid;
-            return UnsafeNativeMethods.ManifestEtw.EventRegister(
-                ref providerId,
+            return Interop.Advapi32.EventRegister(
+                in providerId,
                 enableCallback,
                 callbackContext,
                 ref registrationHandle);
@@ -1266,32 +1286,43 @@ namespace System.Diagnostics.Tracing
         // Unregister an event provider.
         uint IEventProvider.EventUnregister(long registrationHandle)
         {
-            return UnsafeNativeMethods.ManifestEtw.EventUnregister(registrationHandle);
+            return Interop.Advapi32.EventUnregister(registrationHandle);
         }
 
         // Write an event.
-        unsafe int IEventProvider.EventWriteTransferWrapper(
+        unsafe EventProvider.WriteEventErrorCode IEventProvider.EventWriteTransfer(
             long registrationHandle,
-            ref EventDescriptor eventDescriptor,
+            in EventDescriptor eventDescriptor,
             IntPtr eventHandle,
             Guid* activityId,
             Guid* relatedActivityId,
             int userDataCount,
             EventProvider.EventData* userData)
         {
-            return UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(
+            int error = Interop.Advapi32.EventWriteTransfer(
                 registrationHandle,
-                ref eventDescriptor,
+                in eventDescriptor,
                 activityId,
                 relatedActivityId,
                 userDataCount,
                 userData);
+
+            switch (error)
+            {
+                case Interop.Errors.ERROR_ARITHMETIC_OVERFLOW:
+                case Interop.Errors.ERROR_MORE_DATA:
+                    return EventProvider.WriteEventErrorCode.EventTooBig;
+                case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+                    return EventProvider.WriteEventErrorCode.NoFreeBuffers;
+            }
+
+            return EventProvider.WriteEventErrorCode.NoError;
         }
 
         // Get or set the per-thread activity ID.
-        int IEventProvider.EventActivityIdControl(UnsafeNativeMethods.ManifestEtw.ActivityControl ControlCode, ref Guid ActivityId)
+        int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId)
         {
-            return UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
+            return Interop.Advapi32.EventActivityIdControl(
                 ControlCode,
                 ref ActivityId);
         }
@@ -1308,7 +1339,7 @@ namespace System.Diagnostics.Tracing
     {
         unsafe uint IEventProvider.EventRegister(
             EventSource eventSource,
-            UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback,
+            Interop.Advapi32.EtwEnableCallback enableCallback,
             void* callbackContext,
             ref long registrationHandle)
         {
@@ -1320,19 +1351,19 @@ namespace System.Diagnostics.Tracing
             return 0;
         }
 
-        unsafe int IEventProvider.EventWriteTransferWrapper(
+        unsafe EventProvider.WriteEventErrorCode IEventProvider.EventWriteTransfer(
             long registrationHandle,
-            ref EventDescriptor eventDescriptor,
+            in EventDescriptor eventDescriptor,
             IntPtr eventHandle,
             Guid* activityId,
             Guid* relatedActivityId,
             int userDataCount,
             EventProvider.EventData* userData)
         {
-            return 0;
+            return EventProvider.WriteEventErrorCode.NoError;
         }
 
-        int IEventProvider.EventActivityIdControl(UnsafeNativeMethods.ManifestEtw.ActivityControl ControlCode, ref Guid ActivityId)
+        int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId)
         {
             return 0;
         }
index 95ac1da..50343b4 100644 (file)
 //             where it will write it to 
 //
 //    All ETW writes eventually call
-//      EventWriteTransfer (native PINVOKE wrapper)
-//      EventWriteTransferWrapper (fixes compat problem if you pass null as the related activityID)
+//      EventWriteTransfer
 //         EventProvider.WriteEventRaw   - sets last error
 //         EventSource.WriteEventRaw     - Does EventSource exception handling logic
 //            WriteMultiMerge
@@ -499,6 +498,123 @@ namespace System.Diagnostics.Tracing
             }
         }
 
+#region ActivityID
+
+        /// <summary>
+        /// When a thread starts work that is on behalf of 'something else' (typically another 
+        /// thread or network request) it should mark the thread as working on that other work.
+        /// This API marks the current thread as working on activity 'activityID'. This API
+        /// should be used when the caller knows the thread's current activity (the one being
+        /// overwritten) has completed. Otherwise, callers should prefer the overload that
+        /// return the oldActivityThatWillContinue (below).
+        /// 
+        /// All events created with the EventSource on this thread are also tagged with the 
+        /// activity ID of the thread. 
+        /// 
+        /// It is common, and good practice after setting the thread to an activity to log an event
+        /// with a 'start' opcode to indicate that precise time/thread where the new activity 
+        /// started.
+        /// </summary>
+        /// <param name="activityId">A Guid that represents the new activity with which to mark 
+        /// the current thread</param>
+        public static void SetCurrentThreadActivityId(Guid activityId)
+        {
+            if (TplEventSource.Log != null)
+                TplEventSource.Log.SetActivityId(activityId);
+
+            // We ignore errors to keep with the convention that EventSources do not throw errors.
+            // Note we can't access m_throwOnWrites because this is a static method.  
+#if FEATURE_MANAGED_ETW
+#if FEATURE_PERFTRACING
+            // Set the activity id via EventPipe.
+            EventPipeInternal.EventActivityIdControl(
+                (uint)Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
+                ref activityId);
+#endif // FEATURE_PERFTRACING
+#if PLATFORM_WINDOWS
+            // Set the activity id via ETW.
+            Interop.Advapi32.EventActivityIdControl(
+                Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
+                ref activityId);
+#endif // PLATFORM_WINDOWS
+#endif // FEATURE_MANAGED_ETW
+        }
+
+        /// <summary>
+        /// Retrieves the ETW activity ID associated with the current thread.
+        /// </summary>
+        public static Guid CurrentThreadActivityId
+        {
+            get
+            {
+                // We ignore errors to keep with the convention that EventSources do not throw 
+                // errors. Note we can't access m_throwOnWrites because this is a static method.
+                Guid retVal = new Guid();
+#if FEATURE_MANAGED_ETW
+#if PLATFORM_WINDOWS
+                Interop.Advapi32.EventActivityIdControl(
+                    Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
+                    ref retVal);
+#elif FEATURE_PERFTRACING
+                EventPipeInternal.EventActivityIdControl(
+                    (uint)Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
+                    ref retVal);
+#endif // PLATFORM_WINDOWS
+#endif // FEATURE_MANAGED_ETW
+                return retVal;
+            }
+        }
+
+        /// <summary>
+        /// When a thread starts work that is on behalf of 'something else' (typically another 
+        /// thread or network request) it should mark the thread as working on that other work.
+        /// This API marks the current thread as working on activity 'activityID'. It returns 
+        /// whatever activity the thread was previously marked with. There is a convention that
+        /// callers can assume that callees restore this activity mark before the callee returns. 
+        /// To encourage this, this API returns the old activity, so that it can be restored later.
+        /// 
+        /// All events created with the EventSource on this thread are also tagged with the 
+        /// activity ID of the thread. 
+        /// 
+        /// It is common, and good practice after setting the thread to an activity to log an event
+        /// with a 'start' opcode to indicate that precise time/thread where the new activity 
+        /// started.
+        /// </summary>
+        /// <param name="activityId">A Guid that represents the new activity with which to mark 
+        /// the current thread</param>
+        /// <param name="oldActivityThatWillContinue">The Guid that represents the current activity  
+        /// which will continue at some point in the future, on the current thread</param>
+        public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue)
+        {
+            oldActivityThatWillContinue = activityId;
+#if FEATURE_MANAGED_ETW
+            // We ignore errors to keep with the convention that EventSources do not throw errors.
+            // Note we can't access m_throwOnWrites because this is a static method.  
+
+#if FEATURE_PERFTRACING && PLATFORM_WINDOWS
+            EventPipeInternal.EventActivityIdControl(
+                (uint)Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
+                    ref oldActivityThatWillContinue);
+#elif FEATURE_PERFTRACING
+            EventPipeInternal.EventActivityIdControl(
+                (uint)Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
+                    ref oldActivityThatWillContinue);
+#endif // FEATURE_PERFTRACING && PLATFORM_WINDOWS
+
+#if PLATFORM_WINDOWS
+            Interop.Advapi32.EventActivityIdControl(
+                Interop.Advapi32.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
+                    ref oldActivityThatWillContinue);
+#endif // PLATFORM_WINDOWS
+#endif // FEATURE_MANAGED_ETW
+
+            // We don't call the activityDying callback here because the caller has declared that
+            // it is not dying.  
+            if (TplEventSource.Log != null)
+                TplEventSource.Log.SetActivityId(activityId);
+        }
+#endregion
+
 #region protected
         /// <summary>
         /// This is the constructor that most users will use to create their eventSource.   It takes 
@@ -1390,7 +1506,7 @@ namespace System.Diagnostics.Tracing
                     IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
 
                     setInformationResult = m_etwProvider.SetInformation(
-                        UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
+                        Interop.Advapi32.EVENT_INFO_CLASS.SetTraits,
                         providerMetadata,
                         (uint)this.providerMetadata.Length);
 
@@ -2321,12 +2437,40 @@ namespace System.Diagnostics.Tracing
          root them and modify shared library definition to force export them.
          */
 #if ES_BUILD_PN
-       public
+        public
 #else
-       internal
+        internal
 #endif
         partial struct EventMetadata
         {
+#if ES_BUILD_PN
+            public EventMetadata(EventDescriptor descriptor,
+                EventTags tags,
+                bool enabledForAnyListener,
+                bool enabledForETW,
+                string name,
+                string message,
+                EventParameterType[] parameterTypes)
+            {
+                this.Descriptor = descriptor;
+                this.Tags = tags;
+                this.EnabledForAnyListener = enabledForAnyListener;
+                this.EnabledForETW = enabledForETW;
+#if FEATURE_PERFTRACING
+                this.EnabledForEventPipe = false;
+#endif
+                this.TriggersActivityTracking = 0;
+                this.Name = name;
+                this.Message = message;
+                this.Parameters = null;
+                this.TraceLoggingEventTypes = null;
+                this.ActivityOptions = EventActivityOptions.None;
+                this.ParameterTypes = parameterTypes;
+                this.HasRelatedActivityID = false;
+                this.EventHandle = IntPtr.Zero;
+            }
+#endif
+
             public EventDescriptor Descriptor;
             public IntPtr EventHandle;              // EventPipeEvent handle.
             public EventTags Tags;
@@ -2352,6 +2496,114 @@ namespace System.Diagnostics.Tracing
 #endif
         };
 
+#if !ES_BUILD_PN
+        private int GetParameterCount(EventMetadata eventData)
+        {
+            return eventData.Parameters.Length;
+        }
+
+        private Type GetDataType(EventMetadata eventData, int parameterId)
+        {
+            return eventData.Parameters[parameterId].ParameterType;
+        }
+
+        private static readonly bool m_EventSourcePreventRecursion = false;
+#else
+        private int GetParameterCount(EventMetadata eventData)
+        {
+            int paramCount;
+            if(eventData.Parameters == null)
+            {
+                paramCount = eventData.ParameterTypes.Length;
+            }
+            else
+            {
+                paramCount = eventData.Parameters.Length;
+            }
+
+            return paramCount;
+        }
+
+        private Type GetDataType(EventMetadata eventData, int parameterId)
+        {
+            Type dataType;
+            if(eventData.Parameters == null)
+            {
+                dataType = EventTypeToType(eventData.ParameterTypes[parameterId]);
+            }
+            else
+            {
+                dataType = eventData.Parameters[parameterId].ParameterType;
+            }
+
+            return dataType;
+        }
+
+        private static readonly bool m_EventSourcePreventRecursion = true;
+
+        public enum EventParameterType
+        {
+            Boolean,
+            Byte,
+            SByte,
+            Char,
+            Int16,
+            UInt16,
+            Int32,
+            UInt32,
+            Int64,
+            UInt64,
+            IntPtr,
+            Single,
+            Double,
+            Decimal,
+            Guid,
+            String
+        }
+
+        private Type EventTypeToType(EventParameterType type)
+        {
+            switch (type)
+            {
+                case EventParameterType.Boolean:
+                    return typeof(bool);
+                case EventParameterType.Byte:
+                    return typeof(byte);
+                case EventParameterType.SByte:
+                    return typeof(sbyte);
+                case EventParameterType.Char:
+                    return typeof(char);
+                case EventParameterType.Int16:
+                    return typeof(short);
+                case EventParameterType.UInt16:
+                    return typeof(ushort);
+                case EventParameterType.Int32:
+                    return typeof(int);
+                case EventParameterType.UInt32:
+                    return typeof(uint);
+                case EventParameterType.Int64:
+                    return typeof(long);
+                case EventParameterType.UInt64:
+                    return typeof(ulong);
+                case EventParameterType.IntPtr:
+                    return typeof(IntPtr);
+                case EventParameterType.Single:
+                    return typeof(float);
+                case EventParameterType.Double:
+                    return typeof(double);
+                case EventParameterType.Decimal:
+                    return typeof(decimal);
+                case EventParameterType.Guid:
+                    return typeof(Guid);
+                case EventParameterType.String:
+                    return typeof(string);
+                default:
+                    // TODO: should I throw an exception here?
+                    return null;
+            }
+        }
+#endif
+
         // This is the internal entry point that code:EventListeners call when wanting to send a command to a
         // eventSource. The logic is as follows
         // 
@@ -5102,7 +5354,7 @@ namespace System.Diagnostics.Tracing
     /// ManifestBuilder is designed to isolate the details of the message of the event from the
     /// rest of EventSource.  This one happens to create XML. 
     /// </summary>
-    internal partial class ManifestBuilder
+    internal class ManifestBuilder
     {
         /// <summary>
         /// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'.
@@ -5839,7 +6091,46 @@ namespace System.Diagnostics.Tracing
                 return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned.  
             }
 
-            return GetTypeNameHelper(type);
+            switch (type.GetTypeCode())
+            {
+                case TypeCode.Boolean:
+                    return "win:Boolean";
+                case TypeCode.Byte:
+                    return "win:UInt8";
+                case TypeCode.Char:
+                case TypeCode.UInt16:
+                    return "win:UInt16";
+                case TypeCode.UInt32:
+                    return "win:UInt32";
+                case TypeCode.UInt64:
+                    return "win:UInt64";
+                case TypeCode.SByte:
+                    return "win:Int8";
+                case TypeCode.Int16:
+                    return "win:Int16";
+                case TypeCode.Int32:
+                    return "win:Int32";
+                case TypeCode.Int64:
+                    return "win:Int64";
+                case TypeCode.String:
+                    return "win:UnicodeString";
+                case TypeCode.Single:
+                    return "win:Float";
+                case TypeCode.Double:
+                    return "win:Double";
+                case TypeCode.DateTime:
+                    return "win:FILETIME";
+                default:
+                    if (type == typeof(Guid))
+                        return "win:GUID";
+                    else if (type == typeof(IntPtr))
+                        return "win:Pointer";
+                    else if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
+                        return "win:Binary";
+
+                    ManifestError(SR.Format(SR.EventSource_UnsupportedEventTypeInManifest, type.Name), true);
+                    return string.Empty;
+            }
         }
 
         private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count)
index 9bbebc7..bc7ab9a 100644 (file)
@@ -17,7 +17,7 @@ namespace System.Diagnostics.Tracing
         // Register an event provider.
         unsafe uint EventRegister(
             EventSource eventSource,
-            UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback,
+            Interop.Advapi32.EtwEnableCallback enableCallback,
             void* callbackContext,
             ref long registrationHandle);
 
@@ -25,9 +25,9 @@ namespace System.Diagnostics.Tracing
         uint EventUnregister(long registrationHandle);
 
         // Write an event.
-        unsafe int EventWriteTransferWrapper(
+        unsafe EventProvider.WriteEventErrorCode EventWriteTransfer(
             long registrationHandle,
-            ref EventDescriptor eventDescriptor,
+            in EventDescriptor eventDescriptor,
             IntPtr eventHandle,
             Guid* activityId,
             Guid* relatedActivityId,
@@ -35,7 +35,7 @@ namespace System.Diagnostics.Tracing
             EventProvider.EventData* userData);
 
         // Get or set the per-thread activity ID.
-        int EventActivityIdControl(UnsafeNativeMethods.ManifestEtw.ActivityControl ControlCode, ref Guid ActivityId);
+        int EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId);
 
         // Define an EventPipeEvent handle.
         unsafe IntPtr DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte *pMetadata, uint metadataLength);
index 2f69f63..25e382b 100644 (file)
@@ -14,181 +14,6 @@ namespace Microsoft.Win32
 
     internal static class UnsafeNativeMethods
     {
-        internal static unsafe class ManifestEtw
-        {
-            //
-            // Constants error coded returned by ETW APIs
-            //
-
-            // The event size is larger than the allowed maximum (64k - header).
-            internal const int ERROR_ARITHMETIC_OVERFLOW = 534;
-
-            // Occurs when filled buffers are trying to flush to disk, 
-            // but disk IOs are not happening fast enough. 
-            // This happens when the disk is slow and event traffic is heavy. 
-            // Eventually, there are no more free (empty) buffers and the event is dropped.
-            internal const int ERROR_NOT_ENOUGH_MEMORY = 8;
-
-            internal const int ERROR_MORE_DATA = 0xEA;
-            internal const int ERROR_NOT_SUPPORTED = 50;
-            internal const int ERROR_INVALID_PARAMETER = 0x57;
-
-            //
-            // ETW Methods
-            //
-
-            internal const int EVENT_CONTROL_CODE_DISABLE_PROVIDER = 0;
-            internal const int EVENT_CONTROL_CODE_ENABLE_PROVIDER = 1;
-            internal const int EVENT_CONTROL_CODE_CAPTURE_STATE = 2;
-
-            //
-            // Callback
-            //
-            internal delegate void EtwEnableCallback(
-                [In] ref Guid sourceId,
-                [In] int isEnabled,
-                [In] byte level,
-                [In] long matchAnyKeywords,
-                [In] long matchAllKeywords,
-                [In] EVENT_FILTER_DESCRIPTOR* filterData,
-                [In] void* callbackContext
-                );
-
-            //
-            // Registration APIs
-            //
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventRegister", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern unsafe uint EventRegister(
-                        [In] ref Guid providerId,
-                        [In]EtwEnableCallback enableCallback,
-                        [In]void* callbackContext,
-                        [In][Out]ref long registrationHandle
-                        );
-
-            // 
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventUnregister", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern uint EventUnregister([In] long registrationHandle);
-
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventWriteString", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern int EventWriteString(
-                    [In] long registrationHandle,
-                    [In] byte level,
-                    [In] long keyword,
-                    [In] string msg
-                    );
-
-            [StructLayout(LayoutKind.Sequential)]
-            internal struct EVENT_FILTER_DESCRIPTOR
-            {
-                public long Ptr;
-                public int Size;
-                public int Type;
-            };
-
-            /// <summary>
-            ///  Call the ETW native API EventWriteTransfer and checks for invalid argument error. 
-            ///  The implementation of EventWriteTransfer on some older OSes (Windows 2008) does not accept null relatedActivityId.
-            ///  So, for these cases we will retry the call with an empty Guid.
-            /// </summary>
-            internal static int EventWriteTransferWrapper(long registrationHandle,
-                                                         ref EventDescriptor eventDescriptor,
-                                                         Guid* activityId,
-                                                         Guid* relatedActivityId,
-                                                         int userDataCount,
-                                                         EventProvider.EventData* userData)
-            {
-                int HResult = EventWriteTransfer(registrationHandle, ref eventDescriptor, activityId, relatedActivityId, userDataCount, userData);
-                if (HResult == ERROR_INVALID_PARAMETER && relatedActivityId == null)
-                {
-                    Guid emptyGuid = Guid.Empty;
-                    HResult = EventWriteTransfer(registrationHandle, ref eventDescriptor, activityId, &emptyGuid, userDataCount, userData);
-                }
-
-                return HResult;
-            }
-
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventWriteTransfer", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            private static extern int EventWriteTransfer(
-                    [In] long registrationHandle,
-                    [In] ref EventDescriptor eventDescriptor,
-                    [In] Guid* activityId,
-                    [In] Guid* relatedActivityId,
-                    [In] int userDataCount,
-                    [In] EventProvider.EventData* userData
-                    );
-
-            internal 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
-            };
-
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventActivityIdControl", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern int EventActivityIdControl([In] ActivityControl ControlCode, [In][Out] ref Guid ActivityId);
-
-            internal enum EVENT_INFO_CLASS
-            {
-                BinaryTrackInfo,
-                SetEnableAllKeywords,
-                SetTraits,
-            }
-
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EventSetInformation", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern int EventSetInformation(
-                [In] long registrationHandle,
-                [In] EVENT_INFO_CLASS informationClass,
-                [In] void* eventInformation,
-                [In] int informationLength);
-
-            // Support for EnumerateTraceGuidsEx
-            internal enum TRACE_QUERY_INFO_CLASS
-            {
-                TraceGuidQueryList,
-                TraceGuidQueryInfo,
-                TraceGuidQueryProcess,
-                TraceStackTracingInfo,
-                MaxTraceSetInfoClass
-            };
-
-            internal struct TRACE_GUID_INFO
-            {
-                public int InstanceCount;
-                public int Reserved;
-            };
-
-            internal struct TRACE_PROVIDER_INSTANCE_INFO
-            {
-                public int NextOffset;
-                public int EnableCount;
-                public int Pid;
-                public int Flags;
-            };
-
-            internal struct TRACE_ENABLE_INFO
-            {
-                public int IsEnabled;
-                public byte Level;
-                public byte Reserved1;
-                public ushort LoggerId;
-                public int EnableProperty;
-                public int Reserved2;
-                public long MatchAnyKeyword;
-                public long MatchAllKeyword;
-            };
-
-            [DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, EntryPoint = "EnumerateTraceGuidsEx", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
-            internal static extern int EnumerateTraceGuidsEx(
-                TRACE_QUERY_INFO_CLASS TraceQueryInfoClass,
-                void* InBuffer,
-                int InBufferSize,
-                void* OutBuffer,
-                int OutBufferSize,
-                ref int ReturnLength);
-        }
-
 #if FEATURE_COMINTEROP
         [DllImport("api-ms-win-core-winrt-l1-1-0.dll", PreserveSig = true)]
         internal static extern int RoGetActivationFactory(
index 763e78c..d44ac64 100644 (file)
@@ -216,7 +216,7 @@ namespace System.Diagnostics.Tracing
         // These PInvokes are used by EventSource to interact with the EventPipe.
         //
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
-        internal static extern IntPtr CreateProvider(string providerName, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback callbackFunc);
+        internal static extern IntPtr CreateProvider(string providerName, Interop.Advapi32.EtwEnableCallback callbackFunc);
 
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
         internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, long keywords, uint eventVersion, uint level, void *pMetadata, uint metadataLength);
index 214788e..16903c8 100644 (file)
@@ -19,7 +19,7 @@ namespace System.Diagnostics.Tracing
         // Register an event provider.
         unsafe uint IEventProvider.EventRegister(
             EventSource eventSource,
-            UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback,
+            Interop.Advapi32.EtwEnableCallback enableCallback,
             void* callbackContext,
             ref long registrationHandle)
         {
@@ -48,9 +48,9 @@ namespace System.Diagnostics.Tracing
         }
 
         // Write an event.
-        unsafe int IEventProvider.EventWriteTransferWrapper(
+        unsafe EventProvider.WriteEventErrorCode IEventProvider.EventWriteTransfer(
             long registrationHandle,
-            ref EventDescriptor eventDescriptor,
+            in EventDescriptor eventDescriptor,
             IntPtr eventHandle,
             Guid* activityId,
             Guid* relatedActivityId,
@@ -63,7 +63,7 @@ namespace System.Diagnostics.Tracing
                 if (userDataCount == 0)
                 {
                     EventPipeInternal.WriteEventData(eventHandle, eventID, null, 0, activityId, relatedActivityId);
-                    return 0;
+                    return EventProvider.WriteEventErrorCode.NoError;
                 }
 
                 // If Channel == 11, this is a TraceLogging event.
@@ -77,11 +77,11 @@ namespace System.Diagnostics.Tracing
                 }
                 EventPipeInternal.WriteEventData(eventHandle, eventID, userData, (uint) userDataCount, activityId, relatedActivityId);
             }
-            return 0;
+            return EventProvider.WriteEventErrorCode.NoError;
         }
 
         // Get or set the per-thread activity ID.
-        int IEventProvider.EventActivityIdControl(UnsafeNativeMethods.ManifestEtw.ActivityControl ControlCode, ref Guid ActivityId)
+        int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId)
         {
             return EventPipeInternal.EventActivityIdControl((uint)ControlCode, ref ActivityId);
         }
diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
deleted file mode 100644 (file)
index ae8650e..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using Microsoft.Reflection;
-using Microsoft.Win32;
-
-namespace System.Diagnostics.Tracing
-{
-    public partial class EventSource
-    {
-        // ActivityID support (see also WriteEventWithRelatedActivityIdCore)
-        /// <summary>
-        /// When a thread starts work that is on behalf of 'something else' (typically another 
-        /// thread or network request) it should mark the thread as working on that other work.
-        /// This API marks the current thread as working on activity 'activityID'. This API
-        /// should be used when the caller knows the thread's current activity (the one being
-        /// overwritten) has completed. Otherwise, callers should prefer the overload that
-        /// return the oldActivityThatWillContinue (below).
-        /// 
-        /// All events created with the EventSource on this thread are also tagged with the 
-        /// activity ID of the thread. 
-        /// 
-        /// It is common, and good practice after setting the thread to an activity to log an event
-        /// with a 'start' opcode to indicate that precise time/thread where the new activity 
-        /// started.
-        /// </summary>
-        /// <param name="activityId">A Guid that represents the new activity with which to mark 
-        /// the current thread</param>
-        public static void SetCurrentThreadActivityId(Guid activityId)
-        {
-            if (TplEventSource.Log != null)
-                TplEventSource.Log.SetActivityId(activityId);
-
-            // We ignore errors to keep with the convention that EventSources do not throw errors.
-            // Note we can't access m_throwOnWrites because this is a static method.  
-#if FEATURE_MANAGED_ETW
-#if FEATURE_PERFTRACING
-            // Set the activity id via EventPipe.
-            EventPipeInternal.EventActivityIdControl(
-                (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
-                ref activityId);
-#endif // FEATURE_PERFTRACING
-#if PLATFORM_WINDOWS
-            // Set the activity id via ETW.
-            UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
-                UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
-                ref activityId);
-#endif // PLATFORM_WINDOWS
-#endif // FEATURE_MANAGED_ETW
-        }
-
-        /// <summary>
-        /// When a thread starts work that is on behalf of 'something else' (typically another 
-        /// thread or network request) it should mark the thread as working on that other work.
-        /// This API marks the current thread as working on activity 'activityID'. It returns 
-        /// whatever activity the thread was previously marked with. There is a convention that
-        /// callers can assume that callees restore this activity mark before the callee returns. 
-        /// To encourage this, this API returns the old activity, so that it can be restored later.
-        /// 
-        /// All events created with the EventSource on this thread are also tagged with the 
-        /// activity ID of the thread. 
-        /// 
-        /// It is common, and good practice after setting the thread to an activity to log an event
-        /// with a 'start' opcode to indicate that precise time/thread where the new activity 
-        /// started.
-        /// </summary>
-        /// <param name="activityId">A Guid that represents the new activity with which to mark 
-        /// the current thread</param>
-        /// <param name="oldActivityThatWillContinue">The Guid that represents the current activity  
-        /// which will continue at some point in the future, on the current thread</param>
-        public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue)
-        {
-            oldActivityThatWillContinue = activityId;
-#if FEATURE_MANAGED_ETW
-            // We ignore errors to keep with the convention that EventSources do not throw errors.
-            // Note we can't access m_throwOnWrites because this is a static method.  
-
-#if FEATURE_PERFTRACING && PLATFORM_WINDOWS
-            EventPipeInternal.EventActivityIdControl(
-                (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_SET_ID,
-                    ref oldActivityThatWillContinue);
-#elif FEATURE_PERFTRACING
-            EventPipeInternal.EventActivityIdControl(
-                (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
-                    ref oldActivityThatWillContinue);
-#endif // FEATURE_PERFTRACING && PLATFORM_WINDOWS
-
-#if PLATFORM_WINDOWS
-            UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
-                UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
-                    ref oldActivityThatWillContinue);
-#endif // PLATFORM_WINDOWS
-#endif // FEATURE_MANAGED_ETW
-
-            // We don't call the activityDying callback here because the caller has declared that
-            // it is not dying.  
-            if (TplEventSource.Log != null)
-                TplEventSource.Log.SetActivityId(activityId);
-        }
-
-        /// <summary>
-        /// Retrieves the ETW activity ID associated with the current thread.
-        /// </summary>
-        public static Guid CurrentThreadActivityId
-        {
-            get
-            {
-                // We ignore errors to keep with the convention that EventSources do not throw 
-                // errors. Note we can't access m_throwOnWrites because this is a static method.
-                Guid retVal = new Guid();
-#if FEATURE_MANAGED_ETW
-#if PLATFORM_WINDOWS
-                UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
-                    UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
-                    ref retVal);
-#elif FEATURE_PERFTRACING
-                EventPipeInternal.EventActivityIdControl(
-                    (uint)UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
-                    ref retVal);
-#endif // PLATFORM_WINDOWS
-#endif // FEATURE_MANAGED_ETW
-                return retVal;
-            }
-        }
-
-        private int GetParameterCount(EventMetadata eventData)
-        {
-            return eventData.Parameters.Length;
-        }
-
-        private Type GetDataType(EventMetadata eventData, int parameterId)
-        {
-            return eventData.Parameters[parameterId].ParameterType;
-        }
-
-        private static string GetResourceString(string key, params object[] args)
-        {
-            return SR.Format(SR.GetResourceString(key), args);
-        }
-
-        private static readonly bool m_EventSourcePreventRecursion = false;
-    }
-
-    internal partial class ManifestBuilder
-    {
-        private string GetTypeNameHelper(Type type)
-        {
-            switch (type.GetTypeCode())
-            {
-                case TypeCode.Boolean:
-                    return "win:Boolean";
-                case TypeCode.Byte:
-                    return "win:UInt8";
-                case TypeCode.Char:
-                case TypeCode.UInt16:
-                    return "win:UInt16";
-                case TypeCode.UInt32:
-                    return "win:UInt32";
-                case TypeCode.UInt64:
-                    return "win:UInt64";
-                case TypeCode.SByte:
-                    return "win:Int8";
-                case TypeCode.Int16:
-                    return "win:Int16";
-                case TypeCode.Int32:
-                    return "win:Int32";
-                case TypeCode.Int64:
-                    return "win:Int64";
-                case TypeCode.String:
-                    return "win:UnicodeString";
-                case TypeCode.Single:
-                    return "win:Float";
-                case TypeCode.Double:
-                    return "win:Double";
-                case TypeCode.DateTime:
-                    return "win:FILETIME";
-                default:
-                    if (type == typeof(Guid))
-                        return "win:GUID";
-                    else if (type == typeof(IntPtr))
-                        return "win:Pointer";
-                    else if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
-                        return "win:Binary";
-
-                    ManifestError(Resources.GetResourceString("EventSource_UnsupportedEventTypeInManifest", type.Name), true);
-                    return string.Empty;
-            }
-        }
-    }
-
-    internal partial class EventProvider
-    {
-        internal unsafe int SetInformation(
-            UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS eventInfoClass,
-            IntPtr data,
-            uint dataSize)
-        {
-            int status = UnsafeNativeMethods.ManifestEtw.ERROR_NOT_SUPPORTED;
-
-            if (!m_setInformationMissing)
-            {
-                try
-                {
-                    status = UnsafeNativeMethods.ManifestEtw.EventSetInformation(
-                        m_regHandle,
-                        eventInfoClass,
-                        (void*)data,
-                        (int)dataSize);
-                }
-                catch (TypeLoadException)
-                {
-                    m_setInformationMissing = true;
-                }
-            }
-
-            return status;
-        }
-    }
-
-    internal static class Resources
-    {
-        internal static string GetResourceString(string key, params object[] args)
-        {
-            return SR.Format(SR.GetResourceString(key), args);
-        }
-    }
-}