3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
8 ** Class: ProviderMetadata
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.
15 ============================================================*/
16 using System
.Globalization
;
17 using System
.Collections
.Generic
;
18 using System
.Runtime
.InteropServices
;
20 using System
.Security
.Permissions
;
21 using Microsoft
.Win32
;
22 using System
.Diagnostics
.CodeAnalysis
;
24 namespace System
.Diagnostics
.Eventing
.Reader
{
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
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
;
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
{
100 get { return providerName; }
105 return (Guid
)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataPublisherGuid
);
109 public string MessageFilePath
{
111 return (string)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataMessageFilePath
);
115 public string ResourceFilePath
{
117 return (string)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataResourceFilePath
);
121 public string ParameterFilePath
{
123 return (string)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataParameterFilePath
);
127 public Uri HelpLink
{
129 string helpLinkStr
= (string)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataHelpLink
);
130 if ( helpLinkStr
== null || helpLinkStr
.Length
== 0 )
132 return new Uri(helpLinkStr
);
136 private uint ProviderMessageID
{
138 return (uint)NativeWrapper
.EvtGetPublisherMetadataProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataPublisherMessageID
);
142 public string DisplayName
{
143 [System
.Security
.SecurityCritical
]
146 uint msgId
= (uint)this.ProviderMessageID
;
148 if ( msgId
== 0xffffffff )
152 EventLogPermissionHolder
.GetEventLogPermission().Demand();
154 return NativeWrapper
.EvtFormatMessage(this.handle
, msgId
);
158 public IList
<EventLogLink
> LogLinks
{
159 [System
.Security
.SecurityCritical
]
162 EventLogHandle elHandle
= EventLogHandle
.Zero
;
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
);
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;
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;
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
;
236 internal enum ObjectTypeName
{
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
;
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
;
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
;
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
;
284 [System
.Security
.SecuritySafeCritical
]
285 internal object GetProviderListProperty(EventLogHandle providerHandle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId metadataProperty
) {
286 EventLogHandle elHandle
= EventLogHandle
.Zero
;
288 EventLogPermissionHolder
.GetEventLogPermission().Demand();
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
);
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
);
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
);
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
);
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
);
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
);
372 case ObjectTypeName
.Opcode
:
373 generalDisplayName
= FindStandardOpcodeDisplayName( generalName
, generalValue
>>16 );
375 case ObjectTypeName
.Keyword
:
376 generalDisplayName
= FindStandardKeywordDisplayName(generalName
, generalValueKeyword
);
378 case ObjectTypeName
.Task
:
379 generalDisplayName
= FindStandardTaskDisplayName(generalName
, generalValue
);
382 generalDisplayName
= null;
388 generalDisplayName
= NativeWrapper
.EvtFormatMessage(providerHandle
, (uint)generalMessageId
);
392 switch (objectTypeName
) {
393 case ObjectTypeName
.Level
:
394 levelList
.Add(new EventLevel(generalName
, (int)generalValue
, generalDisplayName
));
396 case ObjectTypeName
.Opcode
:
397 opcodeList
.Add(new EventOpcode(generalName
, (int)(generalValue
>>16), generalDisplayName
));
399 case ObjectTypeName
.Keyword
:
400 keywordList
.Add(new EventKeyword(generalName
, (long)generalValueKeyword
, generalDisplayName
));
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
));
411 switch (objectTypeName
) {
412 case ObjectTypeName
.Level
:
414 case ObjectTypeName
.Opcode
:
416 case ObjectTypeName
.Keyword
:
418 case ObjectTypeName
.Task
:
429 public IList
<EventLevel
> Levels
{
433 if (this.levels
!= null)
436 el
= (List
<EventLevel
>)this.GetProviderListProperty( this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataLevels
);
437 this.levels
= el
.AsReadOnly();
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
{
446 List
<EventOpcode
> eo
;
448 if (this.opcodes
!= null)
451 eo
= (List
<EventOpcode
>)this.GetProviderListProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataOpcodes
);
452 this.opcodes
= eo
.AsReadOnly();
458 public IList
<EventKeyword
> Keywords
{
460 List
<EventKeyword
> ek
;
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
{
477 if (this.tasks
!= null)
480 et
= (List
<EventTask
>)this.GetProviderListProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataTasks
);
481 this.tasks
= et
.AsReadOnly();
488 public IEnumerable
<EventMetadata
> Events
{
489 [System
.Security
.SecurityCritical
]
491 EventLogPermissionHolder
.GetEventLogPermission().Demand();
493 List
<EventMetadata
> emList
= new List
<EventMetadata
>();
495 EventLogHandle emEnumHandle
= NativeWrapper
.EvtOpenEventMetadataEnum(handle
, 0);
497 using (emEnumHandle
) {
499 EventLogHandle emHandle
= emHandle
= NativeWrapper
.EvtNextEventMetadata(emEnumHandle
, 0);
500 if (emHandle
== null)
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
));
527 emMessage
= NativeWrapper
.EvtFormatMessage(this.handle
, (uint)messageId
);
529 EventMetadata em
= new EventMetadata(emId
, emVersion
, emChannelId
, emLevel
, emOpcode
, emTask
, emKeywords
, emTemplate
, emMessage
, this);
533 return emList
.AsReadOnly();
538 // throws if Provider metadata has been uninstalled since this object was created.
540 internal void CheckReleased() {
542 this.GetProviderListProperty(this.handle
, UnsafeNativeMethods
.EvtPublisherMetadataPropertyId
.EvtPublisherMetadataTasks
);
546 public void Dispose() {
548 GC
.SuppressFinalize(this);
551 [System
.Security
.SecuritySafeCritical
]
552 protected virtual void Dispose(bool disposing
) {
554 EventLogPermissionHolder
.GetEventLogPermission().Demand();
556 if (handle
!= null && !handle
.IsInvalid
)