Пример #1
0
        /// <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;
        }
Пример #2
0
 public void ProviderEnableParameters(string providerName, Guid providerGuid, TraceEventLevel level, ulong keywords, TraceEventOptions options)
 {
     WriteEvent(14, providerName, providerGuid, (int)level, keywords, (int)options);
 }
Пример #3
0
 /// <summary>
 /// Add an additional USER MODE provider prepresented by 'providerGuid' (a list of
 /// providers is available by using 'logman query providers').
 /// </summary>
 /// <param name="providerGuid">
 /// The GUID that represents the event provider to turn on. Use 'logman query providers' or
 /// for a list of possible providers. Note that additional user mode (but not kernel mode)
 /// providers can be added to the session by using EnableProvider.</param>
 /// <param name="providerLevel">The verbosity to turn on</param>
 /// <param name="matchAnyKeywords">A bitvector representing the areas to turn on. Only the
 /// low 32 bits are used by classic providers and passed as the 'flags' value.  Zero
 /// is a special value which is a provider defined default, which is usuall 'everything'</param>
 /// <param name="matchAllKeywords">A bitvector representing keywords of an event that must
 /// be on for a particular event for the event to be logged.  A value of zero means
 /// that no keyword must be on, which effectively ignores this value.  </param>
 /// <param name="options">Additional options for the provider (e.g. taking a stack trace)</param>
 /// <param name="values">This is set of key-value strings that are passed to the provider
 /// for provider-specific interpretation. Can be null if no additional args are needed.  
 /// If the special key-value pair 'Command'='SendManifest' is provided, then the 'SendManifest'
 /// command will be sent (which causes EventSources to redump their manifest to the ETW log.  </param>
 /// <returns>true if the session already existed and needed to be restarted.</returns>
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel = TraceEventLevel.Verbose, ulong matchAnyKeywords = ulong.MaxValue, ulong matchAllKeywords = 0, TraceEventOptions options = 0, IEnumerable<KeyValuePair<string, string>> values = null)
 {
     byte[] valueData = null;
     int valueDataSize = 0;
     int valueDataType = 0;
     if (values != null)
     {
         valueDataType = 0; // ControllerCommand.Update  // TODO use enumeration
         valueData = new byte[1024];
         foreach (KeyValuePair<string, string> keyValue in values)
         {
             if (keyValue.Key == "Command")
             {
                 if (keyValue.Value == "SendManifest")
                     valueDataType = -1; // ControllerCommand.SendManifest
                 else
                 {
                     int val;
                     if (int.TryParse(keyValue.Value, out val))
                         valueDataType = val;
                 }
             }
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Key, 0, keyValue.Key.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message. 
             valueData[valueDataSize++] = 0;
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Value, 0, keyValue.Value.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message. 
             valueData[valueDataSize++] = 0;
         }
     }
     return EnableProvider(providerGuid, providerLevel, matchAnyKeywords, matchAllKeywords, options, valueDataType, valueData, valueDataSize);
 }