|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: ProviderMetadata
**
** Purpose:
** This public class exposes all the metadata for a specific
** Provider. An instance of this class is obtained from
** EventLogManagement and is scoped to a single Locale.
**
============================================================*/
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Security.Permissions;
using Microsoft.Win32;
using System.Diagnostics.CodeAnalysis;
namespace System.Diagnostics.Eventing.Reader {
/// <summary>
/// Exposes all the metadata for a specific event Provider. An instance
/// of this class is obtained from EventLogManagement and is scoped to a
/// single Locale.
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public class ProviderMetadata : IDisposable {
//
// access to the data member reference is safe, while
// invoking methods on it is marked SecurityCritical as appropriate.
//
private EventLogHandle handle = EventLogHandle.Zero;
private EventLogHandle defaultProviderHandle = EventLogHandle.Zero;
private EventLogSession session = null;
private string providerName;
private CultureInfo cultureInfo;
private string logFilePath;
//caching of the IEnumerable<EventLevel>, <EventTask>, <EventKeyword>, <EventOpcode> on the ProviderMetadata
//they do not change with every call.
private IList<EventLevel> levels = null;
private IList<EventOpcode> opcodes = null;
private IList<EventTask> tasks = null;
private IList<EventKeyword> keywords = null;
private IList<EventLevel> standardLevels = null;
private IList<EventOpcode> standardOpcodes = null;
private IList<EventTask> standardTasks = null;
private IList<EventKeyword> standardKeywords = null;
private IList<EventLogLink> channelReferences = null;
private object syncObject;
public ProviderMetadata(string providerName)
: this(providerName, null, null, null) {
}
public ProviderMetadata(string providerName, EventLogSession session, CultureInfo targetCultureInfo)
: this(providerName, session, targetCultureInfo, null) {
}
// SecurityCritical since it allocates SafeHandles.
// Marked TreatAsSafe since we perform the Demand check.
[System.Security.SecuritySafeCritical]
internal ProviderMetadata(string providerName, EventLogSession session, CultureInfo targetCultureInfo, string logFilePath) {
EventLogPermissionHolder.GetEventLogPermission().Demand();
if (targetCultureInfo == null)
targetCultureInfo = CultureInfo.CurrentCulture;
if (session == null)
session = EventLogSession.GlobalSession;
this.session = session;
this.providerName = providerName;
this.cultureInfo = targetCultureInfo;
this.logFilePath = logFilePath;
handle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, this.providerName, this.logFilePath, this.cultureInfo.LCID, 0);
this.syncObject = new object();
}
internal EventLogHandle Handle {
get {
return handle;
}
}
public string Name {
get { return providerName; }
}
public Guid Id {
get {
return (Guid)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherGuid);
}
}
public string MessageFilePath {
get {
return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataMessageFilePath);
}
}
public string ResourceFilePath {
get {
return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataResourceFilePath);
}
}
public string ParameterFilePath {
get {
return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataParameterFilePath);
}
}
public Uri HelpLink {
get {
string helpLinkStr = (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataHelpLink);
if ( helpLinkStr == null || helpLinkStr.Length == 0 )
return null;
return new Uri(helpLinkStr);
}
}
private uint ProviderMessageID {
get {
return (uint)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherMessageID);
}
}
public string DisplayName {
[System.Security.SecurityCritical]
get {
uint msgId = (uint)this.ProviderMessageID;
if ( msgId == 0xffffffff )
return null;
EventLogPermissionHolder.GetEventLogPermission().Demand();
return NativeWrapper.EvtFormatMessage(this.handle, msgId);
}
}
public IList<EventLogLink> LogLinks {
[System.Security.SecurityCritical]
get {
EventLogHandle elHandle = EventLogHandle.Zero;
try {
lock (syncObject) {
if (this.channelReferences != null)
return this.channelReferences;
EventLogPermissionHolder.GetEventLogPermission().Demand();
elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferences);
int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
List<EventLogLink> channelList = new List<EventLogLink>(arraySize);
for (int index = 0; index < arraySize; index++) {
string channelName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferencePath);
uint channelId = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceID);
uint flag = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceFlags);
bool isImported;
if (flag == (int) UnsafeNativeMethods.EvtChannelReferenceFlags.EvtChannelReferenceImported) isImported = true;
else isImported = false;
int channelRefMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceMessageID));
string channelRefDisplayName;
//if channelRefMessageId == -1, we do not have anything in the message table.
if (channelRefMessageId == -1) {
channelRefDisplayName = null;
}
else {
channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.handle, (uint)channelRefMessageId);
}
if (channelRefDisplayName == null && isImported) {
if (String.Compare(channelName, "Application", StringComparison.OrdinalIgnoreCase ) == 0)
channelRefMessageId = 256;
else if ( String.Compare(channelName, "System", StringComparison.OrdinalIgnoreCase ) == 0)
channelRefMessageId = 258;
else if ( String.Compare(channelName, "Security", StringComparison.OrdinalIgnoreCase ) == 0)
channelRefMessageId = 257;
else
channelRefMessageId = -1;
if ( channelRefMessageId != -1 ) {
if ( this.defaultProviderHandle.IsInvalid ) {
this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0);
}
channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.defaultProviderHandle, (uint)channelRefMessageId);
}
}
channelList.Add(new EventLogLink(channelName, isImported, channelRefDisplayName, channelId));
}
this.channelReferences = channelList.AsReadOnly();
}
return this.channelReferences;
}
finally {
elHandle.Close();
}
}
}
internal enum ObjectTypeName {
Level = 0,
Opcode = 1,
Task = 2,
Keyword = 3
}
internal string FindStandardLevelDisplayName(string name, uint value) {
if( this.standardLevels == null )
this.standardLevels = (List<EventLevel>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels);
foreach (EventLevel standardLevel in this.standardLevels){
if (standardLevel.Name == name && standardLevel.Value == value)
return standardLevel.DisplayName;
}
return null;
}
internal string FindStandardOpcodeDisplayName(string name, uint value){
if ( this.standardOpcodes == null )
this.standardOpcodes = (List<EventOpcode>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes);
foreach (EventOpcode standardOpcode in this.standardOpcodes){
if (standardOpcode.Name == name && standardOpcode.Value == value)
return standardOpcode.DisplayName;
}
return null;
}
internal string FindStandardKeywordDisplayName(string name, long value) {
if ( this.standardKeywords == null )
this.standardKeywords = (List<EventKeyword>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords);
foreach (EventKeyword standardKeyword in this.standardKeywords){
if (standardKeyword.Name == name && standardKeyword.Value == value)
return standardKeyword.DisplayName;
}
return null;
}
internal string FindStandardTaskDisplayName(string name, uint value) {
if ( this.standardTasks == null )
this.standardTasks = (List<EventTask>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
foreach (EventTask standardTask in this.standardTasks) {
if (standardTask.Name == name && standardTask.Value == value)
return standardTask.DisplayName;
}
return null;
}
[System.Security.SecuritySafeCritical]
internal object GetProviderListProperty(EventLogHandle providerHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId metadataProperty) {
EventLogHandle elHandle = EventLogHandle.Zero;
EventLogPermissionHolder.GetEventLogPermission().Demand();
try {
UnsafeNativeMethods.EvtPublisherMetadataPropertyId propName;
UnsafeNativeMethods.EvtPublisherMetadataPropertyId propValue;
UnsafeNativeMethods.EvtPublisherMetadataPropertyId propMessageId;
ObjectTypeName objectTypeName;
List<EventLevel> levelList = null;
List<EventOpcode> opcodeList = null;
List<EventKeyword> keywordList = null;
List<EventTask> taskList = null;
elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(providerHandle, metadataProperty);
int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
switch (metadataProperty) {
case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels:
propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelName;
propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelValue;
propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelMessageID;
objectTypeName = ObjectTypeName.Level;
levelList = new List<EventLevel>(arraySize);
break;
case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes:
propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeName;
propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeValue;
propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeMessageID;
objectTypeName = ObjectTypeName.Opcode;
opcodeList = new List<EventOpcode>(arraySize);
break;
case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords:
propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordName;
propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordValue;
propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordMessageID;
objectTypeName = ObjectTypeName.Keyword;
keywordList = new List<EventKeyword>(arraySize);
break;
case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks:
propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskName;
propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskValue;
propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskMessageID;
objectTypeName = ObjectTypeName.Task;
taskList = new List<EventTask>(arraySize);
break;
default:
return null;
}
for (int index = 0; index < arraySize; index++) {
string generalName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propName);
uint generalValue = 0;
long generalValueKeyword = 0;
if (objectTypeName != ObjectTypeName.Keyword) {
generalValue = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue);
}
else {
generalValueKeyword = (long)((ulong)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue));
}
int generalMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propMessageId));
string generalDisplayName = null;
if (generalMessageId == -1) {
if (providerHandle != this.defaultProviderHandle) {
if (this.defaultProviderHandle.IsInvalid) {
this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0);
}
switch (objectTypeName) {
case ObjectTypeName.Level:
generalDisplayName = FindStandardLevelDisplayName( generalName, generalValue );
break;
case ObjectTypeName.Opcode:
generalDisplayName = FindStandardOpcodeDisplayName( generalName, generalValue>>16 );
break;
case ObjectTypeName.Keyword:
generalDisplayName = FindStandardKeywordDisplayName(generalName, generalValueKeyword);
break;
case ObjectTypeName.Task:
generalDisplayName = FindStandardTaskDisplayName(generalName, generalValue);
break;
default:
generalDisplayName = null;
break;
}
}
}
else {
generalDisplayName = NativeWrapper.EvtFormatMessage(providerHandle, (uint)generalMessageId);
}
switch (objectTypeName) {
case ObjectTypeName.Level:
levelList.Add(new EventLevel(generalName, (int)generalValue, generalDisplayName));
break;
case ObjectTypeName.Opcode:
opcodeList.Add(new EventOpcode(generalName, (int)(generalValue>>16), generalDisplayName));
break;
case ObjectTypeName.Keyword:
keywordList.Add(new EventKeyword(generalName, (long)generalValueKeyword, generalDisplayName));
break;
case ObjectTypeName.Task:
Guid taskGuid = (Guid)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskEventGuid);
taskList.Add(new EventTask(generalName, (int)generalValue, generalDisplayName, taskGuid));
break;
default:
return null;
}
}
switch (objectTypeName) {
case ObjectTypeName.Level:
return levelList;
case ObjectTypeName.Opcode:
return opcodeList;
case ObjectTypeName.Keyword:
return keywordList;
case ObjectTypeName.Task:
return taskList;
}
return null;
}
finally {
elHandle.Close();
}
}
public IList<EventLevel> Levels {
get {
List<EventLevel> el;
lock (syncObject) {
if (this.levels != null)
return this.levels;
el = (List<EventLevel>)this.GetProviderListProperty( this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels);
this.levels = el.AsReadOnly();
}
return this.levels;
}
}
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcodes", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")]
public IList<EventOpcode> Opcodes {
get {
List<EventOpcode> eo;
lock (syncObject) {
if (this.opcodes != null)
return this.opcodes;
eo = (List<EventOpcode>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes);
this.opcodes = eo.AsReadOnly();
}
return this.opcodes;
}
}
public IList<EventKeyword> Keywords {
get {
List<EventKeyword> ek;
lock (syncObject) {
if (this.keywords != null)
return this.keywords;
ek = (List<EventKeyword>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords);
this.keywords = ek.AsReadOnly();
}
return this.keywords;
}
}
public IList<EventTask> Tasks {
get {
List<EventTask> et;
lock (syncObject) {
if (this.tasks != null)
return this.tasks;
et = (List<EventTask>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
this.tasks = et.AsReadOnly();
}
return this.tasks;
}
}
public IEnumerable<EventMetadata> Events {
[System.Security.SecurityCritical]
get {
EventLogPermissionHolder.GetEventLogPermission().Demand();
List<EventMetadata> emList = new List<EventMetadata>();
EventLogHandle emEnumHandle = NativeWrapper.EvtOpenEventMetadataEnum(handle, 0);
using (emEnumHandle) {
while (true) {
EventLogHandle emHandle = emHandle = NativeWrapper.EvtNextEventMetadata(emEnumHandle, 0);
if (emHandle == null)
break;
using (emHandle) {
uint emId = (uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventID);
byte emVersion = (byte)((uint)(NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventVersion)));
byte emChannelId = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventChannel));
byte emLevel = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventLevel));
byte emOpcode = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventOpcode));
short emTask = (short)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTask));
long emKeywords = (long)(ulong)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventKeyword);
string emTemplate = (string)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTemplate);
int messageId = (int)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventMessageID));
string emMessage;
if (messageId == -1)
emMessage = null;
else
emMessage = NativeWrapper.EvtFormatMessage(this.handle, (uint)messageId);
EventMetadata em = new EventMetadata(emId, emVersion, emChannelId, emLevel, emOpcode, emTask, emKeywords, emTemplate, emMessage, this);
emList.Add(em);
}
}
return emList.AsReadOnly();
}
}
}
// throws if Provider metadata has been uninstalled since this object was created.
internal void CheckReleased() {
lock (syncObject) {
this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
[System.Security.SecuritySafeCritical]
protected virtual void Dispose(bool disposing) {
if (disposing) {
EventLogPermissionHolder.GetEventLogPermission().Demand();
}
if (handle != null && !handle.IsInvalid)
handle.Dispose();
}
}
}
|