// pack the argv data and emit the event using TraceEvent internal unsafe override uint EventWrite(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level, int argc, EventData *argv) { ClassicEtw.EVENT_HEADER header; header.Header.ClientContext = 0; header.Header.Flags = ClassicEtw.WNODE_FLAG_TRACED_GUID | ClassicEtw.WNODE_FLAG_USE_MOF_PTR; header.Header.Guid = EventTrace.GetGuidForEvent(eventID); header.Header.Level = (byte)level; header.Header.Type = (byte)EventTrace.GetOpcodeForEvent(eventID); header.Header.Version = (ushort)EventTrace.GetVersionForEvent(eventID); // Extra copy on XP to move argv to the end of the EVENT_HEADER EventData *eventData = &header.Data; if (argc > ClassicEtw.MAX_MOF_FIELDS) { // Data will be lost on XP argc = ClassicEtw.MAX_MOF_FIELDS; } header.Header.Size = (ushort)(argc * sizeof(EventData) + 48); for (int x = 0; x < argc; x++) { eventData[x].Ptr = argv[x].Ptr; eventData[x].Size = argv[x].Size; } return(ClassicEtw.TraceEvent(_traceHandle, &header)); }
internal unsafe override uint EventWrite(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level, int argc, EventData *argv) { ManifestEtw.EventDescriptor eventDescriptor; eventDescriptor.Id = (ushort)eventID; eventDescriptor.Version = EventTrace.GetVersionForEvent(eventID); eventDescriptor.Channel = 0x10; // Since Channel isn't supported on XP we only use a single default channel. eventDescriptor.Level = (byte)level; eventDescriptor.Opcode = EventTrace.GetOpcodeForEvent(eventID); eventDescriptor.Task = EventTrace.GetTaskForEvent(eventID); eventDescriptor.Keywords = (long)keywords; if (argc == 0) { argv = null; } return(ManifestEtw.EventWrite(_registrationHandle.Value, ref eventDescriptor, (uint)argc, argv)); }
// Optimization for 0-1 arguments internal unsafe uint TraceEvent(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level, object eventData) { // It is the responsibility of the caller to check that flags/keywords are enabled before calling this method Debug.Assert(IsEnabled(keywords, level)); uint status = 0; int argCount = 0; EventData userData; userData.Size = 0; string dataString = null; byte * dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize]; if (eventData != null) { dataString = EncodeObject(ref eventData, &userData, dataBuffer); argCount = 1; } if (userData.Size > s_traceEventMaximumSize) { return(ErrorEventTooBig); } if (dataString != null) { fixed(char *pdata = dataString) { userData.Ptr = (ulong)pdata; status = EventWrite(eventID, keywords, level, argCount, &userData); } } else { status = EventWrite(eventID, keywords, level, argCount, &userData); } return(status); }
internal static void EmitEvent(EventTrace.Event evt) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXPS, EventTrace.Level.Info, evt); }
internal uint TraceEvent(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level) { // Optimization for 0-1 arguments return(TraceEvent(eventID, keywords, level, (object)null)); }
internal unsafe abstract uint EventWrite(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level, int argc, EventData *argv);
internal unsafe uint TraceEvent(EventTrace.Event eventID, EventTrace.Keyword keywords, EventTrace.Level level, params object[] eventPayload) { // It is the responsibility of the caller to check that flags/keywords are enabled before calling this method Debug.Assert(IsEnabled(keywords, level)); int argCount = eventPayload.Length; Debug.Assert(argCount <= s_etwMaxNumberArguments); uint totalEventSize = 0; int stringIndex = 0; int[] stringPosition = new int[s_etwAPIMaxStringCount]; string [] dataString = new string[s_etwAPIMaxStringCount]; EventData *userData = stackalloc EventData[argCount]; EventData *userDataPtr = userData; byte * dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize * argCount]; byte * currentBuffer = dataBuffer; for (int index = 0; index < argCount; index++) { if (eventPayload[index] != null) { string isString = EncodeObject(ref eventPayload[index], userDataPtr, currentBuffer); currentBuffer += s_basicTypeAllocationBufferSize; totalEventSize = userDataPtr->Size; userDataPtr++; if (isString != null) { Debug.Assert(stringIndex < s_etwAPIMaxStringCount); // need to increase string count or emit fewer strings dataString[stringIndex] = isString; stringPosition[stringIndex] = index; stringIndex++; } } } if (totalEventSize > s_traceEventMaximumSize) { return(ErrorEventTooBig); } fixed(char *s0 = dataString[0], s1 = dataString[1], s2 = dataString[2], s3 = dataString[3], s4 = dataString[4], s5 = dataString[5], s6 = dataString[6], s7 = dataString[7]) { userDataPtr = userData; if (dataString[0] != null) { userDataPtr[stringPosition[0]].Ptr = (ulong)s0; } if (dataString[1] != null) { userDataPtr[stringPosition[1]].Ptr = (ulong)s1; } if (dataString[2] != null) { userDataPtr[stringPosition[2]].Ptr = (ulong)s2; } if (dataString[3] != null) { userDataPtr[stringPosition[3]].Ptr = (ulong)s3; } if (dataString[4] != null) { userDataPtr[stringPosition[4]].Ptr = (ulong)s4; } if (dataString[5] != null) { userDataPtr[stringPosition[5]].Ptr = (ulong)s5; } if (dataString[6] != null) { userDataPtr[stringPosition[6]].Ptr = (ulong)s6; } if (dataString[7] != null) { userDataPtr[stringPosition[7]].Ptr = (ulong)s7; } return(EventWrite(eventID, keywords, level, argCount, userData)); } }