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(); } }
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); }