Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Core / System / Diagnostics / Eventing / Reader / ProviderMetadata.cs
blobb1cf7fc07cb793b4fdaa0147bc96f393624ad0c4
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 /*============================================================
7 **
8 ** Class: ProviderMetadata
9 **
10 ** Purpose:
11 ** This public class exposes all the metadata for a specific
12 ** Provider. An instance of this class is obtained from
13 ** EventLogManagement and is scoped to a single Locale.
14 **
15 ============================================================*/
16 using System.Globalization;
17 using System.Collections.Generic;
18 using System.Runtime.InteropServices;
19 using System.Text;
20 using System.Security.Permissions;
21 using Microsoft.Win32;
22 using System.Diagnostics.CodeAnalysis;
24 namespace System.Diagnostics.Eventing.Reader {
26 /// <summary>
27 /// Exposes all the metadata for a specific event Provider. An instance
28 /// of this class is obtained from EventLogManagement and is scoped to a
29 /// single Locale.
30 /// </summary>
31 [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
32 public class ProviderMetadata : IDisposable {
35 // access to the data member reference is safe, while
36 // invoking methods on it is marked SecurityCritical as appropriate.
38 private EventLogHandle handle = EventLogHandle.Zero;
40 private EventLogHandle defaultProviderHandle = EventLogHandle.Zero;
42 private EventLogSession session = null;
44 private string providerName;
45 private CultureInfo cultureInfo;
46 private string logFilePath;
48 //caching of the IEnumerable<EventLevel>, <EventTask>, <EventKeyword>, <EventOpcode> on the ProviderMetadata
49 //they do not change with every call.
50 private IList<EventLevel> levels = null;
51 private IList<EventOpcode> opcodes = null;
52 private IList<EventTask> tasks = null;
53 private IList<EventKeyword> keywords = null;
54 private IList<EventLevel> standardLevels = null;
55 private IList<EventOpcode> standardOpcodes = null;
56 private IList<EventTask> standardTasks = null;
57 private IList<EventKeyword> standardKeywords = null;
58 private IList<EventLogLink> channelReferences = null;
60 private object syncObject;
62 public ProviderMetadata(string providerName)
63 : this(providerName, null, null, null) {
66 public ProviderMetadata(string providerName, EventLogSession session, CultureInfo targetCultureInfo)
67 : this(providerName, session, targetCultureInfo, null) {
70 // SecurityCritical since it allocates SafeHandles.
71 // Marked TreatAsSafe since we perform the Demand check.
72 [System.Security.SecuritySafeCritical]
73 internal ProviderMetadata(string providerName, EventLogSession session, CultureInfo targetCultureInfo, string logFilePath) {
75 EventLogPermissionHolder.GetEventLogPermission().Demand();
77 if (targetCultureInfo == null)
78 targetCultureInfo = CultureInfo.CurrentCulture;
80 if (session == null)
81 session = EventLogSession.GlobalSession;
83 this.session = session;
84 this.providerName = providerName;
85 this.cultureInfo = targetCultureInfo;
86 this.logFilePath = logFilePath;
88 handle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, this.providerName, this.logFilePath, this.cultureInfo.LCID, 0);
90 this.syncObject = new object();
93 internal EventLogHandle Handle {
94 get {
95 return handle;
99 public string Name {
100 get { return providerName; }
103 public Guid Id {
104 get {
105 return (Guid)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherGuid);
109 public string MessageFilePath {
110 get {
111 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataMessageFilePath);
115 public string ResourceFilePath {
116 get {
117 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataResourceFilePath);
121 public string ParameterFilePath {
122 get {
123 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataParameterFilePath);
127 public Uri HelpLink {
128 get {
129 string helpLinkStr = (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataHelpLink);
130 if ( helpLinkStr == null || helpLinkStr.Length == 0 )
131 return null;
132 return new Uri(helpLinkStr);
136 private uint ProviderMessageID {
137 get {
138 return (uint)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherMessageID);
142 public string DisplayName {
143 [System.Security.SecurityCritical]
144 get {
146 uint msgId = (uint)this.ProviderMessageID;
148 if ( msgId == 0xffffffff )
149 return null;
152 EventLogPermissionHolder.GetEventLogPermission().Demand();
154 return NativeWrapper.EvtFormatMessage(this.handle, msgId);
158 public IList<EventLogLink> LogLinks {
159 [System.Security.SecurityCritical]
160 get {
162 EventLogHandle elHandle = EventLogHandle.Zero;
163 try {
164 lock (syncObject) {
166 if (this.channelReferences != null)
167 return this.channelReferences;
169 EventLogPermissionHolder.GetEventLogPermission().Demand();
171 elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferences);
173 int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
175 List<EventLogLink> channelList = new List<EventLogLink>(arraySize);
178 for (int index = 0; index < arraySize; index++) {
180 string channelName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferencePath);
182 uint channelId = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceID);
184 uint flag = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceFlags);
186 bool isImported;
187 if (flag == (int) UnsafeNativeMethods.EvtChannelReferenceFlags.EvtChannelReferenceImported) isImported = true;
188 else isImported = false;
190 int channelRefMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceMessageID));
191 string channelRefDisplayName;
193 //if channelRefMessageId == -1, we do not have anything in the message table.
194 if (channelRefMessageId == -1) {
195 channelRefDisplayName = null;
197 else {
198 channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.handle, (uint)channelRefMessageId);
201 if (channelRefDisplayName == null && isImported) {
203 if (String.Compare(channelName, "Application", StringComparison.OrdinalIgnoreCase ) == 0)
204 channelRefMessageId = 256;
205 else if ( String.Compare(channelName, "System", StringComparison.OrdinalIgnoreCase ) == 0)
206 channelRefMessageId = 258;
207 else if ( String.Compare(channelName, "Security", StringComparison.OrdinalIgnoreCase ) == 0)
208 channelRefMessageId = 257;
209 else
210 channelRefMessageId = -1;
212 if ( channelRefMessageId != -1 ) {
214 if ( this.defaultProviderHandle.IsInvalid ) {
215 this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0);
218 channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.defaultProviderHandle, (uint)channelRefMessageId);
222 channelList.Add(new EventLogLink(channelName, isImported, channelRefDisplayName, channelId));
225 this.channelReferences = channelList.AsReadOnly();
228 return this.channelReferences;
230 finally {
231 elHandle.Close();
236 internal enum ObjectTypeName {
237 Level = 0,
238 Opcode = 1,
239 Task = 2,
240 Keyword = 3
243 internal string FindStandardLevelDisplayName(string name, uint value) {
245 if( this.standardLevels == null )
246 this.standardLevels = (List<EventLevel>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels);
247 foreach (EventLevel standardLevel in this.standardLevels){
248 if (standardLevel.Name == name && standardLevel.Value == value)
249 return standardLevel.DisplayName;
251 return null;
253 internal string FindStandardOpcodeDisplayName(string name, uint value){
255 if ( this.standardOpcodes == null )
256 this.standardOpcodes = (List<EventOpcode>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes);
257 foreach (EventOpcode standardOpcode in this.standardOpcodes){
258 if (standardOpcode.Name == name && standardOpcode.Value == value)
259 return standardOpcode.DisplayName;
261 return null;
263 internal string FindStandardKeywordDisplayName(string name, long value) {
265 if ( this.standardKeywords == null )
266 this.standardKeywords = (List<EventKeyword>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords);
267 foreach (EventKeyword standardKeyword in this.standardKeywords){
268 if (standardKeyword.Name == name && standardKeyword.Value == value)
269 return standardKeyword.DisplayName;
271 return null;
273 internal string FindStandardTaskDisplayName(string name, uint value) {
275 if ( this.standardTasks == null )
276 this.standardTasks = (List<EventTask>)GetProviderListProperty(this.defaultProviderHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
277 foreach (EventTask standardTask in this.standardTasks) {
278 if (standardTask.Name == name && standardTask.Value == value)
279 return standardTask.DisplayName;
281 return null;
284 [System.Security.SecuritySafeCritical]
285 internal object GetProviderListProperty(EventLogHandle providerHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId metadataProperty) {
286 EventLogHandle elHandle = EventLogHandle.Zero;
288 EventLogPermissionHolder.GetEventLogPermission().Demand();
291 try {
292 UnsafeNativeMethods.EvtPublisherMetadataPropertyId propName;
293 UnsafeNativeMethods.EvtPublisherMetadataPropertyId propValue;
294 UnsafeNativeMethods.EvtPublisherMetadataPropertyId propMessageId;
295 ObjectTypeName objectTypeName;
297 List<EventLevel> levelList = null;
298 List<EventOpcode> opcodeList = null;
299 List<EventKeyword> keywordList = null;
300 List<EventTask> taskList = null;
302 elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(providerHandle, metadataProperty);
304 int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
306 switch (metadataProperty) {
307 case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels:
308 propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelName;
309 propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelValue;
310 propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevelMessageID;
311 objectTypeName = ObjectTypeName.Level;
312 levelList = new List<EventLevel>(arraySize);
313 break;
315 case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes:
316 propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeName;
317 propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeValue;
318 propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodeMessageID;
319 objectTypeName = ObjectTypeName.Opcode;
320 opcodeList = new List<EventOpcode>(arraySize);
321 break;
323 case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords:
324 propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordName;
325 propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordValue;
326 propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywordMessageID;
327 objectTypeName = ObjectTypeName.Keyword;
328 keywordList = new List<EventKeyword>(arraySize);
329 break;
331 case UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks:
332 propName = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskName;
333 propValue = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskValue;
334 propMessageId = UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskMessageID;
335 objectTypeName = ObjectTypeName.Task;
336 taskList = new List<EventTask>(arraySize);
337 break;
339 default:
340 return null;
342 for (int index = 0; index < arraySize; index++) {
344 string generalName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propName);
346 uint generalValue = 0;
347 long generalValueKeyword = 0;
348 if (objectTypeName != ObjectTypeName.Keyword) {
349 generalValue = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue);
351 else {
352 generalValueKeyword = (long)((ulong)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue));
355 int generalMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propMessageId));
357 string generalDisplayName = null;
359 if (generalMessageId == -1) {
361 if (providerHandle != this.defaultProviderHandle) {
363 if (this.defaultProviderHandle.IsInvalid) {
364 this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0);
367 switch (objectTypeName) {
369 case ObjectTypeName.Level:
370 generalDisplayName = FindStandardLevelDisplayName( generalName, generalValue );
371 break;
372 case ObjectTypeName.Opcode:
373 generalDisplayName = FindStandardOpcodeDisplayName( generalName, generalValue>>16 );
374 break;
375 case ObjectTypeName.Keyword:
376 generalDisplayName = FindStandardKeywordDisplayName(generalName, generalValueKeyword);
377 break;
378 case ObjectTypeName.Task:
379 generalDisplayName = FindStandardTaskDisplayName(generalName, generalValue);
380 break;
381 default:
382 generalDisplayName = null;
383 break;
387 else {
388 generalDisplayName = NativeWrapper.EvtFormatMessage(providerHandle, (uint)generalMessageId);
392 switch (objectTypeName) {
393 case ObjectTypeName.Level:
394 levelList.Add(new EventLevel(generalName, (int)generalValue, generalDisplayName));
395 break;
396 case ObjectTypeName.Opcode:
397 opcodeList.Add(new EventOpcode(generalName, (int)(generalValue>>16), generalDisplayName));
398 break;
399 case ObjectTypeName.Keyword:
400 keywordList.Add(new EventKeyword(generalName, (long)generalValueKeyword, generalDisplayName));
401 break;
402 case ObjectTypeName.Task:
403 Guid taskGuid = (Guid)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTaskEventGuid);
404 taskList.Add(new EventTask(generalName, (int)generalValue, generalDisplayName, taskGuid));
405 break;
406 default:
407 return null;
411 switch (objectTypeName) {
412 case ObjectTypeName.Level:
413 return levelList;
414 case ObjectTypeName.Opcode:
415 return opcodeList;
416 case ObjectTypeName.Keyword:
417 return keywordList;
418 case ObjectTypeName.Task:
419 return taskList;
421 return null;
423 finally {
424 elHandle.Close();
429 public IList<EventLevel> Levels {
430 get {
431 List<EventLevel> el;
432 lock (syncObject) {
433 if (this.levels != null)
434 return this.levels;
436 el = (List<EventLevel>)this.GetProviderListProperty( this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels);
437 this.levels = el.AsReadOnly();
439 return this.levels;
443 [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcodes", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")]
444 public IList<EventOpcode> Opcodes {
445 get {
446 List<EventOpcode> eo;
447 lock (syncObject) {
448 if (this.opcodes != null)
449 return this.opcodes;
451 eo = (List<EventOpcode>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes);
452 this.opcodes = eo.AsReadOnly();
454 return this.opcodes;
458 public IList<EventKeyword> Keywords {
459 get {
460 List<EventKeyword> ek;
461 lock (syncObject) {
462 if (this.keywords != null)
463 return this.keywords;
465 ek = (List<EventKeyword>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords);
466 this.keywords = ek.AsReadOnly();
468 return this.keywords;
473 public IList<EventTask> Tasks {
474 get {
475 List<EventTask> et;
476 lock (syncObject) {
477 if (this.tasks != null)
478 return this.tasks;
480 et = (List<EventTask>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
481 this.tasks = et.AsReadOnly();
483 return this.tasks;
488 public IEnumerable<EventMetadata> Events {
489 [System.Security.SecurityCritical]
490 get {
491 EventLogPermissionHolder.GetEventLogPermission().Demand();
493 List<EventMetadata> emList = new List<EventMetadata>();
495 EventLogHandle emEnumHandle = NativeWrapper.EvtOpenEventMetadataEnum(handle, 0);
497 using (emEnumHandle) {
498 while (true) {
499 EventLogHandle emHandle = emHandle = NativeWrapper.EvtNextEventMetadata(emEnumHandle, 0);
500 if (emHandle == null)
501 break;
503 using (emHandle) {
504 uint emId = (uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventID);
506 byte emVersion = (byte)((uint)(NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventVersion)));
508 byte emChannelId = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventChannel));
510 byte emLevel = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventLevel));
512 byte emOpcode = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventOpcode));
514 short emTask = (short)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTask));
516 long emKeywords = (long)(ulong)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventKeyword);
518 string emTemplate = (string)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTemplate);
520 int messageId = (int)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle, UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventMessageID));
522 string emMessage;
524 if (messageId == -1)
525 emMessage = null;
526 else
527 emMessage = NativeWrapper.EvtFormatMessage(this.handle, (uint)messageId);
529 EventMetadata em = new EventMetadata(emId, emVersion, emChannelId, emLevel, emOpcode, emTask, emKeywords, emTemplate, emMessage, this);
530 emList.Add(em);
533 return emList.AsReadOnly();
538 // throws if Provider metadata has been uninstalled since this object was created.
540 internal void CheckReleased() {
541 lock (syncObject) {
542 this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
546 public void Dispose() {
547 Dispose(true);
548 GC.SuppressFinalize(this);
551 [System.Security.SecuritySafeCritical]
552 protected virtual void Dispose(bool disposing) {
553 if (disposing) {
554 EventLogPermissionHolder.GetEventLogPermission().Demand();
556 if (handle != null && !handle.IsInvalid)
557 handle.Dispose();