/// <summary> /// Writes an event that did not exist previously into the data stream, The context data (time, process, thread, activity, comes from 'an existing event') is given explicitly /// </summary> public unsafe void WriteEvent(Guid providerId, ref EventDescriptor eventDescriptor, DateTime timeStamp, int processId, int processorIndex, int threadID, Guid activityID, params object[] payload) { // Today we always create 64 bit events on 64 bit OSes. var newEvent = m_relogger.CreateEventInstance(m_traceHandleForFirstStream, (pointerSize == 8) ? TraceEventNativeMethods.EVENT_HEADER_FLAG_64_BIT_HEADER : TraceEventNativeMethods.EVENT_HEADER_FLAG_32_BIT_HEADER); fixed(EventDescriptor *fixedEventDescr = &eventDescriptor) { // The interop assembly has its own def of EventDescriptor, but they are identical, so we use unsafe casting to // bridge the gap. _EVENT_DESCRIPTOR *ptrDescr = (_EVENT_DESCRIPTOR *)fixedEventDescr; newEvent.SetEventDescriptor(ref *ptrDescr); newEvent.SetProviderId(ref providerId); _LARGE_INTEGER fileTimeStamp = new _LARGE_INTEGER(); fileTimeStamp.QuadPart = timeStamp.ToFileTimeUtc(); newEvent.SetTimeStamp(ref fileTimeStamp); newEvent.SetProcessId((uint)processId); newEvent.SetProcessorIndex((uint)processorIndex); newEvent.SetThreadId((uint)threadID); newEvent.SetActivityId(ref activityID); SetPayload(newEvent, payload); m_relogger.Inject(newEvent); } }
// ability to modify events you don't own, which may be useful. /// <summary> /// Writes an event that did not exist previously into the data stream, The context data (time, process, thread, activity, comes from 'an existing event') /// </summary> public unsafe void WriteEvent(Guid providerId, ref EventDescriptor eventDescriptor, TraceEvent template, params object[] payload) { if (template != m_curTraceEvent) { throw new InvalidOperationException("Currently can only write the event being processed by the callback"); } // Make a copy of the template so we can modify it var newEvent = m_curITraceEvent.Clone(); fixed(EventDescriptor *fixedEventDescr = &eventDescriptor) { // The interop assembly has its own def of EventDescriptor, but they are identical, so we use unsafe casting to // bridge the gap. _EVENT_DESCRIPTOR *ptrDescr = (_EVENT_DESCRIPTOR *)fixedEventDescr; newEvent.SetEventDescriptor(ref *ptrDescr); newEvent.SetProviderId(ref providerId); SetPayload(newEvent, payload); m_relogger.Inject(newEvent); } }
internal unsafe void SendManifest(byte[] rawManifest, EventSource eventSource) { ManifestEnvelope envelope = new ManifestEnvelope(); envelope.Format = ManifestEnvelope.ManifestFormats.SimpleXmlFormat; envelope.MajorVersion = 1; envelope.MinorVersion = 0; envelope.Magic = 0x5B; // An unusual number that can be checked for consistancy. int dataLeft = rawManifest.Length; envelope.TotalChunks = (ushort)((dataLeft + (ManifestEnvelope.MaxChunkSize - 1)) / ManifestEnvelope.MaxChunkSize); envelope.ChunkNumber = 0; var manifestDescr = new EventDescriptor(0xFFFE, 1, 0, 0, 0xFE, 0xFFFE, -1); if (m_curITraceEvent == null) { throw new InvalidOperationException("Currently can only write the event being processed by the callback"); } // Make a copy of the template so we can modify it var manifestEvent = m_relogger.CreateEventInstance(m_traceHandleForFirstStream, 0); _EVENT_DESCRIPTOR *ptrDescr = (_EVENT_DESCRIPTOR *)&manifestDescr; manifestEvent.SetEventDescriptor(ref *ptrDescr); // Set the provider to the EventSoruce Guid providerGuid = eventSource.Guid; manifestEvent.SetProviderId(ref providerGuid); // Clone the process ID, thread ID and TimeStamp _EVENT_RECORD *eventRecord = (_EVENT_RECORD *)m_curITraceEvent.GetEventRecord(); manifestEvent.SetThreadId(eventRecord->EventHeader.ThreadId); manifestEvent.SetProcessId(eventRecord->EventHeader.ProcessId); manifestEvent.SetTimeStamp(ref eventRecord->EventHeader.TimeStamp); int bufferSize = sizeof(ManifestEnvelope) + Math.Min(ManifestEnvelope.MaxChunkSize, rawManifest.Length); byte[] buffer = new byte[bufferSize]; int manifestIdx = 0; // Where we are in the manifest. while (dataLeft > 0) { // Copy envelope into buffer byte *envelopePtr = (byte *)&envelope; int bufferIdx = 0; while (bufferIdx < sizeof(ManifestEnvelope)) { buffer[bufferIdx++] = *envelopePtr++; } // Copy chunk of manifest into buffer while (bufferIdx < buffer.Length && manifestIdx < rawManifest.Length) buffer[bufferIdx++] = rawManifest[manifestIdx++]; // write the envelope + chunk. fixed(byte *bufferPtr = buffer) { manifestEvent.SetPayload(ref *bufferPtr, (uint)bufferIdx); m_relogger.Inject(manifestEvent); } envelope.ChunkNumber++; Debug.Assert(envelope.ChunkNumber <= envelope.TotalChunks); dataLeft -= ManifestEnvelope.MaxChunkSize; } Debug.Assert(envelope.ChunkNumber == envelope.TotalChunks); }