internal unsafe uint MyCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte *byteBuffer) { try { BaseEvent *buffer = (BaseEvent *)byteBuffer; switch (requestCode) { case RequestCodes.EnableEvents: _traceHandle = buffer->HistoricalContext; _flags = (uint)EtwTrace.GetTraceEnableFlags((ulong)buffer->HistoricalContext); _level = EtwTrace.GetTraceEnableLevel((ulong)buffer->HistoricalContext); _enabled = true; break; case RequestCodes.DisableEvents: _enabled = false; _traceHandle = 0; _level = 0; _flags = 0; break; default: _enabled = false; _traceHandle = 0; break; } return(0); } catch (Exception e) { // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. // // This should be CriticalExceptions.IsCriticalException, but that requires // linking to WindowsBase, which is a heavy requirement for "shared" code. // if ((e is NullReferenceException) || (e is System.Runtime.InteropServices.SEHException)) { throw; } else { return(0); } } }
private unsafe uint Register(Guid controlGuid) { uint status; ulong registrationHandle; EtwTrace.TraceGuidRegistration guidReg = new EtwTrace.TraceGuidRegistration(); Guid dummyGuid = new Guid(0xb4955bf0, 0x3af1, 0x4740, 0xb4, 0x75, 0x99, 0x05, 0x5d, 0x3f, 0xe9, 0xaa); _etwProc = new EtwTrace.EtwProc(MyCallback); // This dummyGuid is there for ETW backward compat issues guidReg.Guid = &dummyGuid; guidReg.RegHandle = null; status = EtwTrace.RegisterTraceGuids(_etwProc, null, ref controlGuid, 1, ref guidReg, null, null, out registrationHandle); _registrationHandle = registrationHandle; return(status); }
private unsafe uint TraceEvent( EventTrace.Level level, Guid eventGuid, byte evtype, object data0, object data1, object data2, object data3, object data4, object data5, object data6, object data7, object data8) { uint status = 0; BaseEvent ev; // Takes up 304 bytes on the stack // The largest possible item stored in this buffer from each of data0 // through data8 will be a decimal (strings are logged as pointers) const uint bufferSize = sizeof(decimal) * 9; char * buffer = stackalloc char[(int)bufferSize]; uint offset = 0; char * ptr = buffer; string s0, s1, s2, s3, s4, s5, s6, s7, s8; int stringMask = 0; uint argCount = 0; int mofIndex = 0; s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = ""; ev.ClientContext = 0; ev.Flags = 0x00120000; // define Constants ev.Guid = eventGuid; ev.EventType = evtype; ev.Level = level; ev.Version = _version; MofField *be = null; if (data0 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; if ((s0 = ProcessOneObject(data0, be, ptr, ref offset)) != null) { stringMask |= 0x00000001; mofIndex++; // Leave a slot for the String Pointer } } if (data1 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s1 = ProcessOneObject(data1, be, ptr, ref offset)) != null) { stringMask |= 0x00000002; mofIndex++; // Leave a slot for the String Pointer } } if (data2 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s2 = ProcessOneObject(data2, be, ptr, ref offset)) != null) { stringMask |= 0x00000004; mofIndex++; // Leave a slot for the String Pointer } } if (data3 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s3 = ProcessOneObject(data3, be, ptr, ref offset)) != null) { stringMask |= 0x00000008; mofIndex++; // Leave a slot for the String Pointer } } if (data4 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s4 = ProcessOneObject(data4, be, ptr, ref offset)) != null) { stringMask |= 0x00000010; mofIndex++; // Leave a slot for the String Pointer } } if (data5 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s5 = ProcessOneObject(data5, be, ptr, ref offset)) != null) { stringMask |= 0x00000020; mofIndex++; // Leave a slot for the String Pointer } } if (data6 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s6 = ProcessOneObject(data6, be, ptr, ref offset)) != null) { stringMask |= 0x00000040; mofIndex++; // Leave a slot for the String Pointer } } if (data7 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s7 = ProcessOneObject(data7, be, ptr, ref offset)) != null) { stringMask |= 0x00000080; mofIndex++; // Leave a slot for the String Pointer } } if (data8 != null) { argCount++; be = &(&ev.UserData)[mofIndex++]; ptr = buffer + offset; if ((s8 = ProcessOneObject(data8, be, ptr, ref offset)) != null) { stringMask |= 0x00000100; mofIndex++; // Leave a slot for the String Pointer } } // Assert we haven't exceeded the buffer size Debug.Assert(ptr - buffer <= bufferSize); // Now pin all the strings and use the stringMask to pass them over through mofField fixed(char *vptr0 = s0, vptr1 = s1, vptr2 = s2, vptr3 = s3, vptr4 = s4, vptr5 = s5, vptr6 = s6, vptr7 = s7, vptr8 = s8) { int i = 0; if ((stringMask & 0x00000001) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s0.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr0; } i++; if ((stringMask & 0x00000002) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s1.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr1; } i++; if ((stringMask & 0x00000004) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s2.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr2; } i++; if ((stringMask & 0x00000008) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s3.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr3; } i++; if ((stringMask & 0x00000010) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s4.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr4; } i++; if ((stringMask & 0x00000020) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s5.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr5; } i++; if ((stringMask & 0x00000040) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s6.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr6; } i++; if ((stringMask & 0x00000080) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s7.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr7; } i++; if ((stringMask & 0x00000100) != 0) { i++; (&ev.UserData)[i].DataLength = (uint)s8.Length * 2; (&ev.UserData)[i].DataPointer = (void *)vptr8; } ev.BufferSize = 48 + (uint)mofIndex * (uint)sizeof(MofField); status = EtwTrace.TraceEvent(_traceHandle, (char *)&ev); } return(status); }