コード例 #1
0
        private void StopTrace2()
        {
            int count;

            IntPtr[] a = new IntPtr[64];
            for (int i = 0; i < a.Length; i++)
            {
                int size;
                a[i] = BuildProperties(true, out size);
            }

            int hr = QueryAllTraces(a, a.Length, out count);

            if (hr == 0)
            {
                for (int i = 0; i < count; i++)
                {
                    EVENT_TRACE_PROPERTIES propi = (EVENT_TRACE_PROPERTIES)Marshal.PtrToStructure(a[i], typeof(EVENT_TRACE_PROPERTIES));
                    if (propi.Wnode.Guid == ProviderGuid)
                    {
                        StopTrace(propi.Wnode.HistoricalContext, null, a[i]);
                    }
                }
            }

            for (int i = 0; i < a.Length; i++)
            {
                Marshal.FreeCoTaskMem(a[i]);
            }
        }
コード例 #2
0
            public static IEnumerable <EVENT_TRACE_PROPERTIES> QueryAllTraces()
            {
                const int len      = 64;
                var       props    = new List <SafeHGlobalHandle>(len);
                var       loadProp = EVENT_TRACE_PROPERTIES.Create();

                for (var i = 0; i < len; i++)
                {
                    props.Add(SafeHGlobalHandle.CreateFromStructure(loadProp));
                }
                try
                {
                    var pprops = props.Select(p => (IntPtr)p).ToArray();
                    AdvApi32.QueryAllTraces(pprops, len, out var count).ThrowIfFailed();
                    for (var i = 0; i < count; i++)
                    {
                        yield return(props[i].ToStructure <EVENT_TRACE_PROPERTIES>());
                    }
                }
                finally
                {
                    for (var i = 0; i < props.Count; i++)
                    {
                        props[i].Dispose();
                    }
                }
            }
コード例 #3
0
        private IntPtr BuildProperties(bool stopping, out int size)
        {
            IntPtr properties;
            var    prop = new EVENT_TRACE_PROPERTIES();

            if (stopping)
            {
                size       = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (1024 + 1) * 2;
                properties = Marshal.AllocCoTaskMem(size);
                RtlZeroMemory(properties, (IntPtr)size);
                prop.Wnode.Guid       = ProviderGuid;
                prop.Wnode.BufferSize = size;
            }
            else
            {
                size       = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (SessionName.Length + 1) * 2;
                properties = Marshal.AllocCoTaskMem(size);
                RtlZeroMemory(properties, (IntPtr)size);
                prop.Wnode.Guid       = ProviderGuid;
                prop.Wnode.Flags      = WNODE_FLAG_TRACED_GUID;
                prop.Wnode.BufferSize = size;
                prop.LogFileMode      = EVENT_TRACE_REAL_TIME_MODE;
            }

            prop.LoggerNameOffset = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES));
            Marshal.StructureToPtr(prop, properties, false);
            return(properties);
        }
コード例 #4
0
ファイル: EvnTraceTests.cs プロジェクト: sasqwatch/Vanara
        public void QueryTraceTest()
        {
            var sess = EventTraceSession.ActiveSessions.First();
            var prop = EVENT_TRACE_PROPERTIES.Create();

            Assert.That(QueryTrace(sess.TraceSessionHandle, null, ref prop), ResultIs.Successful);
            prop.WriteValues();
        }
コード例 #5
0
        static void Main(string[] args)
        {
            Guid triggerProvider;
            uint triggerLevel   = (uint)EventLevel.Error;
            uint triggerKeyword = 0;
            int  res            = 0;

            try
            {
                triggerProvider     = Guid.Parse(args[0]);
                circularSessionName = args[1];
                logFileName         = args.Length > 2 ? args[2] : "Flush.etl";
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
                Help();
                return;
            }

            Console.WriteLine($"Start {triggerSessionName}");
            Console.CancelKeyPress += (s, a) => StopTrace();
            var triggerProperties = new EVENT_TRACE_PROPERTIES()
            {
                LogFileMode = LogFileMode.REAL_TIME_MODE | LogFileMode.USE_MS_FLUSH_TIMER,
                FlushTimer  = 1,
            };

            res = Native.StartTrace(out var triggerSessionHandle, triggerSessionName, triggerProperties);
            if (res != 0)
            {
                throw new Win32Exception(res);
            }
            res = Native.EnableTrace(1, triggerKeyword, triggerLevel, triggerProvider, triggerSessionHandle);

            Console.WriteLine($"Process {triggerSessionName}");
            var triggerLog = new EVENT_TRACE_LOGFILEW
            {
                LoggerName          = triggerSessionName,
                ProcessTraceMode    = ProcessTraceMode.REAL_TIME | ProcessTraceMode.EVENT_RECORD,
                EventRecordCallback = EventRecordCallback,
            };
            var triggerLogHandle = Native.OpenTraceW(ref triggerLog);

            res = Native.ProcessTrace(new[] { triggerLogHandle }, 1, 0, 0);
            if (res != 0)
            {
                Console.WriteLine(new Win32Exception(res).Message);
            }
            Native.CloseTrace(triggerLogHandle);
            StopTrace();
        }
コード例 #6
0
        public void FlushTrace()
        {
            if (IsValid)
            {
                EVENT_TRACE_PROPERTIES properties = CommonEvenTraceProperties();
                uint status = NativeMethods.ControlTrace(0, this.setting.Name, ref properties, (ulong)EventTraceControl.FLUSH);

                if (status != NativeMethods.ERROR_SUCCESS)
                {
                    throw new Win32Exception((int)status);
                }
            }
        }
コード例 #7
0
        private void GetSessionHandle()
        {
            EVENT_TRACE_PROPERTIES properties = CommonEvenTraceProperties();
            uint status = NativeMethods.ControlTrace(0, this.setting.Name, ref properties, (ulong)EventTraceControl.QUERY);

            if (status == NativeMethods.ERROR_SUCCESS)
            {
                _handle = properties.WNode.ContextVersion.HistoricalContext;
            }
            else
            {
                _handle = 0;
            }
        }
コード例 #8
0
        public void UpdateLogFileName(string newpath)
        {
            if (setting.RealTimeSession || setting.UseNewFileMode)
            {
                throw new NotSupportedException("Updating session log file name is not supported for real-time session or EVENT_TRACE_FILE_MODE_NEWFILE mode");
            }

            EVENT_TRACE_PROPERTIES properties = CommonEvenTraceProperties();

            // Set LogFileNameOffset member if you want to switch to another log file.
            properties.LogFileNameOffset = EventTracePropertiesMarshalSize.StructSize + EventTracePropertiesMarshalSize.StringSize1;
            properties.LogFileName       = newpath;

            uint status = NativeMethods.ControlTrace(0, this.setting.Name, ref properties, (ulong)EventTraceControl.UPDATE);
        }
コード例 #9
0
        /// <summary>
        /// Create an ETW session
        /// </summary>
        public void StartTrace()
        {
            if (_handle == 0)
            {
                EVENT_TRACE_PROPERTIES properties = CommonEvenTraceProperties();
                properties.WNode.Flags         = WNodeFlags.TracedGuid;
                properties.WNode.ClientContext = 1; //QPC clock resolution
                properties.BufferSize          = (uint)setting.BufferSize;
                properties.MinimumBuffers      = (uint)setting.MinBuffers;
                properties.MaximumBuffers      = (uint)setting.MaxBuffers;
                if (setting.RealTimeSession)
                {
                    // real time mode
                    properties.LogFileMode = EventTraceFileMode.RealTime;
                }
                else if (setting.UseNewFileMode)
                {
                    // NewFile mode
                    properties.LogFileMode     = EventTraceFileMode.NewFile;
                    properties.MaximumFileSize = (uint)this.setting.MaxFileSize;
                    properties.FlushTimer      = (uint)this.setting.FlushTimer;
                }
                else
                {
                    // rolling file hourly.
                    properties.LogFileMode     = EventTraceFileMode.FileSequential;
                    properties.MaximumFileSize = 0;
                    properties.FlushTimer      = (uint)this.setting.FlushTimer;
                }

                // From MSDN:
                // Uses paged memory. This setting is recommended so that events do not use up the nonpaged memory.
                // Kernel-mode providers cannot log events to sessions that specify this logging mode.
                if (setting.UsePagedMemory)
                {
                    properties.LogFileMode |= EventTraceFileMode.UsePagedMemory;
                }

                uint processResult = NativeMethods.StartTrace(out _handle, setting.Name, ref properties);
                if (processResult != NativeMethods.ERROR_SUCCESS &&
                    processResult != NativeMethods.ERROR_ALREADY_EXISTS)
                {
                    throw new Win32Exception((int)processResult);
                }
            }
            // if _handle != 0, the session has already been created
        }
コード例 #10
0
        public void EventAccessTest()
        {
            var etp = EVENT_TRACE_PROPERTIES.Create(Guid.NewGuid());

            etp.LogFileMode     = LogFileMode.EVENT_TRACE_FILE_MODE_SEQUENTIAL;
            etp.MaximumFileSize = 1;
            etp.LogFileName     = logfilePath;
            etp.LoggerName      = "MySession";
            var sess = new EventTraceSession(etp);

            var sz = 1024U;

            using var sd = new SafePSECURITY_DESCRIPTOR((int)sz);
            Assert.That(EventAccessQuery(sess.ProviderGuid, sd, ref sz), ResultIs.Successful);
            Assert.That(EventAccessControl(sess.ProviderGuid, EVENTSECURITYOPERATION.EventSecurityAddDACL, SafePSID.Current, TRACELOG_RIGHTS.WMIGUID_QUERY, true), ResultIs.Successful);
            Assert.That(EventAccessRemove(sess.ProviderGuid), ResultIs.Successful);
        }
コード例 #11
0
        /// <summary>
        /// Stops and delete the session
        /// </summary>
        public void StopTrace()
        {
            if (_handle != 0)
            {
                EVENT_TRACE_PROPERTIES properties = CommonEvenTraceProperties();

                uint processResult = NativeMethods.StopTrace(_handle, setting.Name, ref properties);

                if (processResult != NativeMethods.ERROR_SUCCESS &&
                    processResult != NativeMethods.ERROR_CANCELLED &&
                    processResult != NativeMethods.ERROR_WMI_INSTANCE_NOT_FOUND) // It is expected that the ETW session might not exist
                {
                    throw new Win32Exception((int)processResult);
                }
                _handle = 0;
            }
        }
コード例 #12
0
        private EVENT_TRACE_PROPERTIES CommonEvenTraceProperties()
        {
            EVENT_TRACE_PROPERTIES properties = new EVENT_TRACE_PROPERTIES();

            properties.WNode.BufferSize = EventTracePropertiesMarshalSize.StructSize + EventTracePropertiesMarshalSize.StringSize1 + EventTracePropertiesMarshalSize.StringSize2;
            properties.WNode.Flags      = WNodeFlags.TracedGuid;
            properties.LoggerNameOffset = EventTracePropertiesMarshalSize.StructSize;
            if (this.setting.LogFilePath == null)
            {
                // real time session
                properties.LogFileNameOffset = 0;
            }
            else
            {
                // file mode
                // copy the log file path
                properties.LogFileNameOffset = EventTracePropertiesMarshalSize.StructSize + EventTracePropertiesMarshalSize.StringSize1;
                properties.LogFileName       = setting.LogFilePath;
            }
            return(properties);
        }
コード例 #13
0
        private IntPtr BuildProperties(bool stopping, out int size)
        {
            IntPtr properties;
            EVENT_TRACE_PROPERTIES prop = new EVENT_TRACE_PROPERTIES();
            if (stopping)
            {
                size = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (1024 + 1) * 2;
                properties = Marshal.AllocCoTaskMem(size);
                RtlZeroMemory(properties, (IntPtr)size);
                prop.Wnode.Guid = ProviderGuid;
                prop.Wnode.BufferSize = size;
            }
            else
            {
                size = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (SessionName.Length + 1) * 2;
                properties = Marshal.AllocCoTaskMem(size);
                RtlZeroMemory(properties, (IntPtr)size);
                prop.Wnode.Guid = ProviderGuid;
                prop.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
                prop.Wnode.BufferSize = size;
                prop.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
            }

            prop.LoggerNameOffset = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES));
            Marshal.StructureToPtr(prop, properties, false);
            return properties;
        }
コード例 #14
0
 internal extern static int StartKernelTrace(
     out UInt64 TraceHandle,
     EVENT_TRACE_PROPERTIES* Properties,
     STACK_TRACING_EVENT_ID* StackTracingEventIds,       // Actually an array of  code:STACK_TRACING_EVENT_ID
     int cStackTracingEventIds);
コード例 #15
0
 internal static extern int ControlTrace(
     ulong sessionHandle,
     string sessionName,
     EVENT_TRACE_PROPERTIES* properties,
     uint controlCode);
コード例 #16
0
 internal extern static int StartTraceW(
     [Out] out UInt64 sessionHandle,
     [In] string sessionName,
     EVENT_TRACE_PROPERTIES* properties);
コード例 #17
0
        static void StopTrace()
        {
            var stopProperties = new EVENT_TRACE_PROPERTIES();

            Native.StopTrace(0, triggerSessionName, stopProperties);
        }
コード例 #18
0
        private void StartSession()
        {
            int status = 0;

            string path = LogFilePath;

            // Allocate memory for the session properties. The memory must
            // be large enough to include the log file name and session name,
            // which get appended to the end of the session properties structure.

            uint structSize      = (uint)Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES));
            uint pathSize        = (uint)(sizeof(char) * path.Length) + 1;
            uint sessionNameSize = (uint)(sizeof(char) * this.eventLogSessionName.Length) + 1;
            uint bufferSize      = structSize + pathSize + sessionNameSize;
            EVENT_TRACE_PROPERTIES pSessionProperties = new EVENT_TRACE_PROPERTIES();

            this.traceProperties = Marshal.AllocCoTaskMem((int)bufferSize);
            if (this.traceProperties == IntPtr.Zero)
            {
                throw new OutOfMemoryException();
            }

            try
            {
                // Set the session properties. You only append the log file name
                // to the properties structure; the StartTrace function appends
                // the session name for you.
                const int WNODE_FLAG_TRACED_GUID     = 0x00020000;
                const int EVENT_TRACE_REAL_TIME_MODE = 0x00000100;
                const int ERROR_ALREADY_EXISTS       = 183;

                pSessionProperties.Wnode.BufferSize    = bufferSize;
                pSessionProperties.Wnode.Flags         = WNODE_FLAG_TRACED_GUID;
                pSessionProperties.Wnode.ClientContext = 1;                          //QPC clock resolution
                pSessionProperties.Wnode.Guid          = sessionGuid;
                pSessionProperties.LogFileMode         = EVENT_TRACE_REAL_TIME_MODE; //  EVENT_TRACE_FILE_MODE_SEQUENTIAL;
                pSessionProperties.MaximumFileSize     = 1;                          // 1 MB
                pSessionProperties.LoggerNameOffset    = structSize;
                pSessionProperties.LogFileNameOffset   = structSize + pathSize;

                // Copy the data to the buffer
                Marshal.StructureToPtr(pSessionProperties, this.traceProperties, false);
                CopyString(path, new IntPtr((long)this.traceProperties + structSize));
                CopyString(this.eventLogSessionName, new IntPtr((long)this.traceProperties + structSize + pathSize));

                this.sessionHandle = 0;
                // Create the trace session.
                status = NativeMethods.StartTrace(out sessionHandle, this.eventLogSessionName, this.traceProperties);
                if (status == ERROR_ALREADY_EXISTS)
                {
                    // close unclosed previous trace.
                    StopTrace();
                    status = NativeMethods.StartTrace(out sessionHandle, this.eventLogSessionName, this.traceProperties);
                }

                if (0 != status)
                {
                    throw new System.ComponentModel.Win32Exception(status);
                }
            }
            finally
            {
            }
        }