b1cf7fc07cb793b4fdaa0147bc96f393624ad0c4
[mono.git] / mcs / class / referencesource / System.Core / System / Diagnostics / Eventing / Reader / ProviderMetadata.cs
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;
23
24 namespace System.Diagnostics.Eventing.Reader {
25
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 {
33
34         //
35         // access to the data member reference is safe, while 
36         // invoking methods on it is marked SecurityCritical as appropriate.
37         //
38         private EventLogHandle handle = EventLogHandle.Zero;
39
40         private EventLogHandle defaultProviderHandle = EventLogHandle.Zero;
41
42         private EventLogSession session = null;
43
44         private string providerName;
45         private CultureInfo cultureInfo;
46         private string logFilePath;
47
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;
59
60         private object syncObject;
61
62         public ProviderMetadata(string providerName)
63             : this(providerName, null, null, null) {
64         }
65
66         public ProviderMetadata(string providerName, EventLogSession session, CultureInfo targetCultureInfo)
67             : this(providerName, session, targetCultureInfo, null) {
68         }
69
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) {
74
75             EventLogPermissionHolder.GetEventLogPermission().Demand();
76
77             if (targetCultureInfo == null)
78                 targetCultureInfo = CultureInfo.CurrentCulture;
79
80             if (session == null)
81                 session = EventLogSession.GlobalSession;
82
83             this.session = session;
84             this.providerName = providerName;
85             this.cultureInfo = targetCultureInfo;
86             this.logFilePath = logFilePath;
87
88             handle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, this.providerName, this.logFilePath, this.cultureInfo.LCID, 0);
89
90             this.syncObject = new object();
91         }
92
93         internal EventLogHandle Handle {
94             get {
95                 return handle;
96             }
97         }
98
99         public string Name {
100             get { return providerName; }
101         }
102
103         public Guid Id {
104             get {
105                 return (Guid)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherGuid);
106             }
107         }
108
109         public string MessageFilePath {
110             get {
111                 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataMessageFilePath);
112             }
113         }
114
115         public string ResourceFilePath {
116             get {
117                 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataResourceFilePath);
118             }
119         }
120
121         public string ParameterFilePath {
122             get {
123                 return (string)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataParameterFilePath);
124             }
125         }
126
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);
133             }
134         }
135
136         private uint ProviderMessageID {
137             get {
138                 return (uint)NativeWrapper.EvtGetPublisherMetadataProperty(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataPublisherMessageID);
139             }
140         }
141
142         public string DisplayName {
143             [System.Security.SecurityCritical]
144             get {
145
146                 uint msgId = (uint)this.ProviderMessageID;
147
148                 if ( msgId == 0xffffffff )
149                     return null;
150
151
152                 EventLogPermissionHolder.GetEventLogPermission().Demand();
153
154                 return NativeWrapper.EvtFormatMessage(this.handle, msgId);
155             }
156         }
157
158         public IList<EventLogLink> LogLinks {
159             [System.Security.SecurityCritical]
160             get {
161
162                 EventLogHandle elHandle = EventLogHandle.Zero;
163                 try {
164                     lock (syncObject) {
165
166                         if (this.channelReferences != null)
167                             return this.channelReferences;
168
169                         EventLogPermissionHolder.GetEventLogPermission().Demand();
170
171                         elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(this.handle,  UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferences);
172
173                         int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
174
175                         List<EventLogLink> channelList = new List<EventLogLink>(arraySize);
176
177
178                         for (int index = 0; index < arraySize; index++) {
179
180                             string channelName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferencePath);
181
182                             uint channelId = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceID);
183
184                             uint flag = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceFlags);
185
186                             bool isImported;
187                             if (flag == (int) UnsafeNativeMethods.EvtChannelReferenceFlags.EvtChannelReferenceImported) isImported = true;
188                             else isImported = false;
189
190                             int channelRefMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int) UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferenceMessageID));
191                             string channelRefDisplayName;
192
193                             //if channelRefMessageId == -1, we do not have anything in the message table.
194                             if (channelRefMessageId == -1) {
195                                 channelRefDisplayName = null;
196                             }
197                             else {
198                                 channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.handle, (uint)channelRefMessageId);
199                             }
200
201                             if (channelRefDisplayName == null && isImported) {
202
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;
211
212                                 if ( channelRefMessageId != -1 ) {
213
214                                     if ( this.defaultProviderHandle.IsInvalid ) {
215                                         this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0); 
216                                     }
217
218                                     channelRefDisplayName = NativeWrapper.EvtFormatMessage(this.defaultProviderHandle, (uint)channelRefMessageId);
219                                 }
220                             }
221                                 
222                             channelList.Add(new EventLogLink(channelName, isImported, channelRefDisplayName, channelId));
223                         }
224
225                         this.channelReferences = channelList.AsReadOnly();
226                     }
227
228                     return this.channelReferences;
229                 }
230                 finally {
231                     elHandle.Close();
232                 }
233             }
234         }
235
236         internal enum ObjectTypeName {
237             Level = 0,
238             Opcode = 1,
239             Task = 2,
240             Keyword = 3
241         }
242
243         internal string FindStandardLevelDisplayName(string name, uint value) {
244
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;
250            }
251            return null;    
252         }
253         internal string FindStandardOpcodeDisplayName(string name, uint value){
254
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;
260             }
261             return null;
262         }
263         internal string FindStandardKeywordDisplayName(string name, long value) {
264
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;
270             }
271             return null;
272         }
273         internal string FindStandardTaskDisplayName(string name, uint value) {
274
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;
280             }
281             return null;
282         }
283
284         [System.Security.SecuritySafeCritical]
285         internal object GetProviderListProperty(EventLogHandle providerHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId metadataProperty) {
286             EventLogHandle elHandle = EventLogHandle.Zero;
287
288             EventLogPermissionHolder.GetEventLogPermission().Demand();
289
290
291             try {
292                  UnsafeNativeMethods.EvtPublisherMetadataPropertyId propName;
293                  UnsafeNativeMethods.EvtPublisherMetadataPropertyId propValue;
294                  UnsafeNativeMethods.EvtPublisherMetadataPropertyId propMessageId;
295                 ObjectTypeName objectTypeName;
296
297                 List<EventLevel> levelList = null;
298                 List<EventOpcode> opcodeList = null;
299                 List<EventKeyword> keywordList = null;
300                 List<EventTask> taskList = null;
301
302                 elHandle = NativeWrapper.EvtGetPublisherMetadataPropertyHandle(providerHandle, metadataProperty);
303
304                 int arraySize = NativeWrapper.EvtGetObjectArraySize(elHandle);
305
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;
314
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;
322
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;
330
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;
338
339                     default:
340                         return null;
341                 }
342                 for (int index = 0; index < arraySize; index++) {
343
344                     string generalName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propName);
345
346                     uint generalValue = 0;
347                     long generalValueKeyword = 0;
348                     if (objectTypeName != ObjectTypeName.Keyword) {
349                         generalValue = (uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue);
350                     }
351                     else {
352                         generalValueKeyword = (long)((ulong)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propValue));
353                     }
354
355                     int generalMessageId = (int)((uint)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)propMessageId));
356
357                     string generalDisplayName = null;
358
359                     if (generalMessageId == -1) {
360
361                         if (providerHandle != this.defaultProviderHandle) {
362
363                             if (this.defaultProviderHandle.IsInvalid) {
364                                 this.defaultProviderHandle = NativeWrapper.EvtOpenProviderMetadata(this.session.Handle, null, null, this.cultureInfo.LCID, 0);
365                             }
366
367                             switch (objectTypeName) {
368                             
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;
384                             }
385                         }
386                     }
387                     else {
388                         generalDisplayName = NativeWrapper.EvtFormatMessage(providerHandle, (uint)generalMessageId);
389                     }
390
391
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;
408                     }
409                 }
410
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;
420                 }
421                 return null;
422             }
423             finally {
424                 elHandle.Close();
425             }
426         }
427
428
429         public IList<EventLevel> Levels {
430             get {
431                 List<EventLevel> el;
432                 lock (syncObject) {
433                     if (this.levels != null)
434                         return this.levels;
435
436                     el = (List<EventLevel>)this.GetProviderListProperty( this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataLevels);
437                     this.levels = el.AsReadOnly();
438                 }
439                 return this.levels;
440             }
441         }
442
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;
450
451                     eo = (List<EventOpcode>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataOpcodes);
452                     this.opcodes = eo.AsReadOnly();
453                 }
454                 return this.opcodes;
455             }
456         }
457
458         public IList<EventKeyword> Keywords {
459             get {
460                 List<EventKeyword> ek;
461                 lock (syncObject) {
462                     if (this.keywords != null)
463                         return this.keywords;
464
465                     ek = (List<EventKeyword>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataKeywords);
466                     this.keywords = ek.AsReadOnly();
467                 }
468                 return this.keywords;
469             }
470         }
471
472
473         public IList<EventTask> Tasks {
474             get {
475                 List<EventTask> et;
476                 lock (syncObject) {
477                     if (this.tasks != null)
478                         return this.tasks;
479
480                     et = (List<EventTask>)this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
481                     this.tasks = et.AsReadOnly();
482                 }
483                 return this.tasks;
484             }
485         }
486
487         
488         public IEnumerable<EventMetadata> Events {
489             [System.Security.SecurityCritical]
490             get {
491                 EventLogPermissionHolder.GetEventLogPermission().Demand();
492
493                 List<EventMetadata> emList = new List<EventMetadata>();
494
495                 EventLogHandle emEnumHandle = NativeWrapper.EvtOpenEventMetadataEnum(handle, 0);
496
497                 using (emEnumHandle) {
498                     while (true) {
499                         EventLogHandle emHandle = emHandle = NativeWrapper.EvtNextEventMetadata(emEnumHandle, 0);
500                         if (emHandle == null)
501                             break;
502
503                         using (emHandle) {
504                             uint emId = (uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventID);
505
506                             byte emVersion = (byte)((uint)(NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventVersion)));
507
508                             byte emChannelId = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventChannel));
509
510                             byte emLevel = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventLevel));
511
512                             byte emOpcode = (byte)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventOpcode));
513
514                             short emTask = (short)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTask));
515
516                             long emKeywords = (long)(ulong)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventKeyword);
517
518                             string emTemplate = (string)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventTemplate);
519
520                             int messageId = (int)((uint)NativeWrapper.EvtGetEventMetadataProperty(emHandle,  UnsafeNativeMethods.EvtEventMetadataPropertyId.EventMetadataEventMessageID));
521
522                             string emMessage;
523
524                             if (messageId == -1)
525                                 emMessage = null;
526                             else
527                                 emMessage = NativeWrapper.EvtFormatMessage(this.handle, (uint)messageId);
528
529                             EventMetadata em = new EventMetadata(emId, emVersion, emChannelId, emLevel, emOpcode, emTask, emKeywords, emTemplate, emMessage, this);
530                             emList.Add(em);
531                         }
532                     }
533                     return emList.AsReadOnly();
534                 }
535             }
536         }
537
538         // throws if Provider metadata has been uninstalled since this object was created.
539
540         internal void CheckReleased() {
541             lock (syncObject) {
542                 this.GetProviderListProperty(this.handle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataTasks);
543             }
544         }
545
546         public void Dispose() {
547             Dispose(true);
548             GC.SuppressFinalize(this);
549         }
550
551         [System.Security.SecuritySafeCritical]
552         protected virtual void Dispose(bool disposing) {
553             if (disposing) {
554                 EventLogPermissionHolder.GetEventLogPermission().Demand();
555             }
556             if (handle != null && !handle.IsInvalid)
557                 handle.Dispose();
558         }
559     }
560 }