/// <summary>
        /// De-serializes the user data associated with each ETW event in this session.
        /// </summary>
        /// <param name="eventTrace">ETW native representation of the event</param>
        /// <remarks>
        /// This method is called by ETW for each event in this session.
        /// </remarks>
        private unsafe void OnTraceEvent(ref NativeMethods.EventTrace eventTrace)
        {
            var pData  = (byte *)eventTrace.MofData;
            var length = (int)eventTrace.MofLength;

            if (pData != null)
            {
                using (var stream = new UnmanagedMemoryStream(pData, length, length, FileAccess.Read))
                {
                    var breader = new BinaryReader(stream);

                    int traceFunc;
                    breader.BaseStream.Position = 0;

                    // 130623 not sure if this always the case but citrix user traces have func id
                    // in first two bytes and appear to have 'Type' 255
                    if (eventTrace.Type == 255)
                    {
                        // this works for user traces
                        traceFunc = BitConverter.ToInt16(breader.ReadBytes(2), 0); //.ReadByte();
                    }
                    else
                    {
                        // this works for kernel traces
                        traceFunc = eventTrace.Type;
                    }

                    byte[] eventStringBytes = breader.ReadBytes((int)(breader.BaseStream.Length)); // / 2);

                    RaiseEventRead(eventTrace.Guid, eventTrace, eventStringBytes, traceFunc);
                    breader.Close();
                }
            }
        }
 /// <summary>
 /// ctor.
 /// </summary>
 /// <param name="eventGuid">The event GUID.</param>
 /// <param name="eventTrace">The event trace.</param>
 /// <param name="eventStringBytes">The event string bytes.</param>
 /// <param name="traceFunc">The trace func.</param>
 public EventReadEventArgs(Guid eventGuid,
                           NativeMethods.EventTrace eventTrace, byte[] eventStringBytes, int traceFunc)
 {
     _eventGuid        = eventGuid;
     _eventStringBytes = eventStringBytes;
     _eventTrace       = eventTrace;
     _traceFunc        = traceFunc;
 }
        /// <summary>
        /// Raises the EventRead event.
        /// </summary>
        /// <param name="eventGuid">Guid associated with the event</param>
        /// <param name="eventTrace">The event trace.</param>
        /// <param name="eventStringBytes">The event string bytes.</param>
        /// <param name="traceFunc">The trace func.</param>
        private void RaiseEventRead(Guid eventGuid, NativeMethods.EventTrace eventTrace, byte[] eventStringBytes,
                                    int traceFunc)
        {
            _onRaiseEventReadCount++;
            EventHandler <EventReadEventArgs> eventRead = EventRead;

            if (eventRead != null)
            {
                eventRead(this, new EventReadEventArgs(eventGuid, eventTrace, eventStringBytes, traceFunc));
            }
        }