예제 #1
0
        private void ProviderSelected(object sender, SelectionChangedEventArgs e)
        {
            var selectedItem = ProviderNameListBox.SelectedItem;

            if (selectedItem != null)
            {
                m_selectedProvider = selectedItem.ToString();
                m_keys             = new Dictionary <string, ProviderDataItem>();
                foreach (var keyword in TraceEventProviders.GetProviderKeywords(TraceEventProviders.GetProviderGuidByName(m_selectedProvider)))
                {
                    m_keys.Add(keyword.Name.ToString(), keyword);
                }
                m_keyStrings = new List <String>();
                foreach (var key in m_keys.Keys)
                {
                    m_keyStrings.Add(m_keys[key].Name.ToString());
                }
                KeyNameListBox.ItemsSource = m_keyStrings;
                m_selectedKeys             = new List <string>();
                updateDisplays();
            }
        }
예제 #2
0
        public static EtwManifest ParseWmiEventTraceClass(Guid provider)
        {
            // we make a best effort attempt to fit the metadata of this Legacy (MOF) provider into the instrumentation manifest format

            // we need to find the EventTrace class where the Guid class qualifier matches our provider Guid
            // afaik you can't query for qualifiers...just classes and properties.  :-/
            // so we loop through all of the EventTrace classes and compare
            var             providerSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = 'EventTrace'", null);
            ManagementClass providerClass    = null;

            foreach (ManagementClass candidateProviderClass in providerSearcher.Get())
            {
                foreach (QualifierData qd in candidateProviderClass.Qualifiers)
                {
                    if (qd.Name.ToLower() == "guid" && new Guid((string)qd.Value) == provider)
                    {
                        providerClass = candidateProviderClass;
                        break; // found
                    }
                }

                if (providerClass != null)
                {
                    break; // found
                }
            }

            if (providerClass == null)
            {
                throw new ApplicationException($"Provider {provider} has no corresponding EventTrace class in WMI Repository"); // not found
            }
            var manifest = new EtwManifest(string.Empty)
            {
                ProviderGuid   = provider,
                ProviderSymbol = (string)providerClass["__CLASS"]
            };

            var events      = new SortedDictionary <string, EtwEvent>();
            var templates   = new List <EtwTemplate>();
            var stringTable = new Dictionary <string, string>();

            // the provider name is usually in the Description Qualifier for the EventTrace class (but not always?)
            // and the keywords are properties for the EventTrace class
            // but we can already get both of these easily from Microsoft.Diagnostics.Tracing
            manifest.ProviderName = TraceEventProviders.GetProviderName(provider);
            manifest.Keywords     = TraceEventProviders.GetProviderKeywords(provider).Select(info => new EtwKeyword
            {
                Name    = info.Name,
                Mask    = info.Value,
                Message = info.Description
            }).ToArray();

            // event details are in the grandchildren of the top-level (EventTrace) provider class
            // WMI EventTrace children ~ a versioned category grouping
            // WMI EventTrace grandchildren ~ instrumentation manifest templates
            // note - event version can be set on the category and/or the event
            var templateNames = new SortedSet <string>();
            var taskSearcher  = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{providerClass["__CLASS"]}'", null);

            foreach (ManagementClass categoryVersionClass in taskSearcher.Get())
            {
                var categoryVersion     = 0;
                var category            = string.Empty;
                var categoryDescription = string.Empty;
                var displayName         = string.Empty;
                foreach (QualifierData qd in categoryVersionClass.Qualifiers)
                {
                    if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion")
                    {
                        categoryVersion = (Int32)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "guid")
                    {
                        category = (string)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description")
                    {
                        categoryDescription = (string)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "displayname")
                    {
                        displayName = (string)qd.Value;
                    }
                }

                var templateSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{categoryVersionClass["__CLASS"]}'", null);
                foreach (ManagementClass templateClass in templateSearcher.Get())
                {
                    // EventTypeName qualifier ~ OpCode
                    var template    = (string)templateClass["__CLASS"];
                    var eventType   = string.Empty;
                    var version     = categoryVersion;
                    var description = categoryDescription;
                    foreach (QualifierData qd in templateClass.Qualifiers)
                    {
                        if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion")
                        {
                            version = (Int32)qd.Value; // override category version with specific event version
                        }
                        else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "eventtypename")
                        {
                            eventType = (string)qd.Value;
                        }
                        else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description")
                        {
                            description = (string)qd.Value;
                        }
                    }
                    if (!string.IsNullOrEmpty(categoryDescription))
                    {
                        stringTable.Add(template, categoryDescription);
                    }

                    // EventType -> id(s)
                    var ids = new SortedSet <Int32>();
                    foreach (QualifierData qd in templateClass.Qualifiers)
                    {
                        if (qd.Name.ToLower() == "eventtype")
                        {
                            if (qd.Value.GetType() == typeof(Int32))
                            {
                                ids.Add((Int32)qd.Value);
                            }
                            else if (qd.Value.GetType().IsArray)
                            {
                                foreach (var element in (Array)qd.Value)
                                {
                                    if (element.GetType() == typeof(Int32))
                                    {
                                        ids.Add((Int32)element);
                                    }
                                }
                            }
                            break;
                        }
                    }

                    // sort by category, id, version
                    foreach (var id in ids)
                    {
                        events.Add($"{category}{id,6}{version,6}",
                                   new EtwEvent
                        {
                            Value    = id,
                            Symbol   = template,
                            Opcode   = eventType,
                            Version  = version,
                            Template = template,
                            Keyword  = description,
                            Task     = category
                        });
                    }

                    // create a template from the properties
                    var templateData = new SortedDictionary <int, EtwTemplateData>();
                    foreach (PropertyData pd in templateClass.Properties)
                    {
                        foreach (QualifierData qd in pd.Qualifiers)
                        {
                            if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "wmidataid")
                            {
                                var id = (int)qd.Value;
                                templateData[id] = new EtwTemplateData
                                {
                                    Name = pd.Name,
                                    Type = pd.Type.ToString()
                                };
                                break;
                            }
                        }
                    }

                    templates.Add(new EtwTemplate(template, templateData.Values.ToArray()));
                }
            }

            manifest.Events      = events.Values.ToArray();
            manifest.Templates   = templates.ToArray();
            manifest.StringTable = stringTable;

            return(manifest);
        }