/// <summary> /// Sends the CAPUTURE_STATE command to the provider /// /// This routine only works Win7 and above, since previous versions don't have this concept. The providers also has /// to support it. /// /// You can use KernelTraceEventParser.ProviderGuid here to cause rundown for the system. /// </summary> /// <param name="providerGuid">The GUID that identifies the provider to send the CaptureState command to</param> /// <param name="matchAnyKeywords">The Keywords to send as part of the command (can influnced what is sent back)</param> /// <param name="filterType">if non-zero, this is passed along to the provider as type of the filter data.</param> /// <param name="data">If non-null this is either an int, or a byte array and is passed along as filter data.</param> public void CaptureState(Guid providerGuid, ulong matchAnyKeywords = ulong.MaxValue, int filterType = 0, object data = null) { var parameters = new TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS(); var filter = new TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR(); parameters.Version = TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS_VERSION; byte[] asArray = data as byte[]; if (data is int) { int intVal = (int)data; asArray = new byte[4]; asArray[0] = (byte)intVal; asArray[1] = (byte)(intVal >> 8); asArray[2] = (byte)(intVal >> 16); asArray[3] = (byte)(intVal >> 24); } fixed (byte* filterDataPtr = asArray) { if (asArray != null) { parameters.EnableFilterDesc = &filter; filter.Type = filterType; filter.Size = asArray.Length; filter.Ptr = filterDataPtr; } int hr = TraceEventNativeMethods.EnableTraceEx2( m_SessionHandle, ref providerGuid, TraceEventNativeMethods.EVENT_CONTROL_CODE_CAPTURE_STATE, (byte)TraceEventLevel.Verbose, matchAnyKeywords, 0, 0, ref parameters); Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr)); } }
/// <summary> /// Do intialization common to the contructors. /// </summary> private bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel, ulong matchAnyKeywords, ulong matchAllKeywords, TraceEventOptions options, int providerDataType, byte[] providerData, int providerDataSize) { if (m_SessionName == KernelTraceEventParser.KernelSessionName) throw new NotSupportedException("Can only enable kernel events on a kernel session."); bool ret = InsureStarted(); TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR* dataDescrPtr = null; fixed (byte* providerDataPtr = providerData) { string regKeyName = @"Software\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + providerGuid + "}"; byte[] registryData = null; // If this is an update operation, remember the data in registry so that even providers // that have not yet started will get the data. We don't do this for any other kind of command (providerDataType) // since we don't know that they are desired 'on startup'. if (providerData != null && providerDataType == 0) { TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR dataDescr = new TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR(); dataDescr.Ptr = null; dataDescr.Size = providerDataSize; dataDescr.Type = providerDataType; dataDescrPtr = &dataDescr; if (providerData == null) providerData = new byte[0]; else dataDescr.Ptr = providerDataPtr; // Set the registry key so providers get the information even if they are not active now registryData = new byte[providerDataSize + 4]; // providerDataType is always zero, but older versions assume it is here, so we put the redundant value here for compatibility. registryData[0] = (byte)(providerDataType); registryData[1] = (byte)(providerDataType >> 8); registryData[2] = (byte)(providerDataType >> 16); registryData[3] = (byte)(providerDataType >> 24); Array.Copy(providerData, 0, registryData, 4, providerDataSize); } SetOrDelete(regKeyName, "ControllerData", registryData); int hr; try { try { // Try the Win7 API TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS parameters = new TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS(); parameters.Version = TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS_VERSION; if ((options & TraceEventOptions.Stacks) != 0) parameters.EnableProperty = TraceEventNativeMethods.EVENT_ENABLE_PROPERTY_STACK_TRACE; parameters.EnableFilterDesc = dataDescrPtr; hr = TraceEventNativeMethods.EnableTraceEx2(m_SessionHandle, ref providerGuid, TraceEventNativeMethods.EVENT_CONTROL_CODE_ENABLE_PROVIDER, (byte)providerLevel, matchAnyKeywords, matchAllKeywords, 0, ref parameters); } catch (EntryPointNotFoundException) { // OK that did not work, try the VISTA API hr = TraceEventNativeMethods.EnableTraceEx(ref providerGuid, null, m_SessionHandle, 1, (byte)providerLevel, matchAnyKeywords, matchAllKeywords, 0, dataDescrPtr); } } catch (EntryPointNotFoundException) { // Try with the old pre-vista API hr = TraceEventNativeMethods.EnableTrace(1, (int)matchAnyKeywords, (int)providerLevel, ref providerGuid, m_SessionHandle); } Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr)); } m_IsActive = true; return ret; }
/// <summary> /// Disables a provider completely /// </summary> public void DisableProvider(Guid providerGuid) { int hr; try { try { // Try the Win7 API var parameters = new TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS { Version = TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS_VERSION }; hr = TraceEventNativeMethods.EnableTraceEx2( m_SessionHandle, ref providerGuid, TraceEventNativeMethods.EVENT_CONTROL_CODE_DISABLE_PROVIDER, 0, 0, 0, 0, ref parameters); } catch (EntryPointNotFoundException) { // OK that did not work, try the VISTA API hr = TraceEventNativeMethods.EnableTraceEx(ref providerGuid, null, m_SessionHandle, 0, 0, 0, 0, 0, null); } } catch (EntryPointNotFoundException) { // Try with the old pre-vista API hr = TraceEventNativeMethods.EnableTrace(0, 0, 0, ref providerGuid, m_SessionHandle); } Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr)); }