You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,127 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="etwprovider.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace System.Diagnostics.Eventing
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = 16)]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public struct EventDescriptor
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
private ushort m_id;
|
||||
[FieldOffset(2)]
|
||||
private byte m_version;
|
||||
[FieldOffset(3)]
|
||||
private byte m_channel;
|
||||
[FieldOffset(4)]
|
||||
private byte m_level;
|
||||
[FieldOffset(5)]
|
||||
private byte m_opcode;
|
||||
[FieldOffset(6)]
|
||||
private ushort m_task;
|
||||
[FieldOffset(8)]
|
||||
private long m_keywords;
|
||||
|
||||
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")]
|
||||
public EventDescriptor(
|
||||
int id,
|
||||
byte version,
|
||||
byte channel,
|
||||
byte level,
|
||||
byte opcode,
|
||||
int task,
|
||||
long keywords
|
||||
)
|
||||
{
|
||||
if (id < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("id", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNum));
|
||||
}
|
||||
|
||||
if (id > ushort.MaxValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("id", SR.GetString(SR.ArgumentOutOfRange_NeedValidId, 1, ushort.MaxValue));
|
||||
}
|
||||
|
||||
m_id = (ushort)id;
|
||||
m_version = version;
|
||||
m_channel = channel;
|
||||
m_level = level;
|
||||
m_opcode = opcode;
|
||||
m_keywords = keywords;
|
||||
|
||||
if (task < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("task", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNum));
|
||||
}
|
||||
|
||||
if (task > ushort.MaxValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("task", SR.GetString(SR.ArgumentOutOfRange_NeedValidId, 1, ushort.MaxValue));
|
||||
}
|
||||
|
||||
m_task = (ushort)task;
|
||||
}
|
||||
|
||||
public int EventId {
|
||||
get {
|
||||
return m_id;
|
||||
}
|
||||
}
|
||||
|
||||
public byte Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
}
|
||||
|
||||
public byte Channel
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
}
|
||||
public byte Level
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_level;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")]
|
||||
public byte Opcode
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_opcode;
|
||||
}
|
||||
}
|
||||
|
||||
public int Task
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_task;
|
||||
}
|
||||
}
|
||||
|
||||
public long Keywords
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_keywords;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,436 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="EtwListener.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace System.Diagnostics.Eventing{
|
||||
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventProviderTraceListener : TraceListener
|
||||
{
|
||||
//
|
||||
// The listener uses the EtwProvider base class.
|
||||
// Because Listener data is not schematized at the moment the listener will
|
||||
// log events using WriteMessageEvent method.
|
||||
//
|
||||
// Because WriteMessageEvent takes a string as the event payload
|
||||
// all the overriden loging methods convert the arguments into strings.
|
||||
// Event payload is "delimiter" separated, which can be configured
|
||||
//
|
||||
//
|
||||
private EventProvider m_provider;
|
||||
private const string s_nullStringValue = "null";
|
||||
private const string s_nullStringComaValue = "null,";
|
||||
private const string s_nullCStringValue = ": null";
|
||||
private const string s_activityIdString = "activityId=";
|
||||
private const string s_relatedActivityIdString = "relatedActivityId=";
|
||||
private const string s_callStackString = " : CallStack:";
|
||||
private const string s_optionDelimiter = "delimiter";
|
||||
private string m_delimiter = ";";
|
||||
private int m_initializedDelim = 0;
|
||||
private const uint s_keyWordMask = 0xFFFFFF00;
|
||||
private const int s_defaultPayloadSize = 512;
|
||||
private object m_Lock = new object();
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
|
||||
public string Delimiter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_initializedDelim == 0)
|
||||
{
|
||||
lock (m_Lock)
|
||||
{
|
||||
if (m_initializedDelim == 0)
|
||||
{
|
||||
if (Attributes.ContainsKey(s_optionDelimiter))
|
||||
{
|
||||
m_delimiter = Attributes[s_optionDelimiter];
|
||||
|
||||
}
|
||||
m_initializedDelim = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_delimiter == null)
|
||||
throw new ArgumentNullException("Delimiter");
|
||||
|
||||
if (m_delimiter.Length == 0)
|
||||
throw new ArgumentException(SR.GetString(SR.Argument_NeedNonemptyDelimiter));
|
||||
|
||||
}
|
||||
return m_delimiter;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("Delimiter");
|
||||
|
||||
if (value.Length == 0)
|
||||
throw new ArgumentException(SR.GetString(SR.Argument_NeedNonemptyDelimiter));
|
||||
|
||||
lock (m_Lock)
|
||||
{
|
||||
m_delimiter = value;
|
||||
m_initializedDelim = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override string[] GetSupportedAttributes()
|
||||
{
|
||||
return new String[] { s_optionDelimiter };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method creates an instance of the ETW provider.
|
||||
/// The guid argument must be a valid GUID or a format exeption will be
|
||||
/// thrown when creating an instance of the ControlGuid.
|
||||
/// We need to be running on Vista or above. If not an
|
||||
/// PlatformNotSupported exception will be thrown by the EventProvider.
|
||||
/// </summary>
|
||||
public EventProviderTraceListener(string providerId)
|
||||
{
|
||||
InitProvider(providerId);
|
||||
}
|
||||
|
||||
public EventProviderTraceListener(string providerId, string name)
|
||||
: base(name)
|
||||
{
|
||||
InitProvider(providerId);
|
||||
}
|
||||
|
||||
public EventProviderTraceListener(string providerId, string name, string delimiter)
|
||||
: base(name)
|
||||
{
|
||||
if (delimiter == null)
|
||||
throw new ArgumentNullException("delimiter");
|
||||
|
||||
if (delimiter.Length == 0)
|
||||
throw new ArgumentException(SR.GetString(SR.Argument_NeedNonemptyDelimiter));
|
||||
|
||||
m_delimiter = delimiter;
|
||||
m_initializedDelim = 1;
|
||||
InitProvider(providerId);
|
||||
}
|
||||
|
||||
private void InitProvider(string providerId)
|
||||
{
|
||||
|
||||
Guid controlGuid = new Guid(providerId);
|
||||
//
|
||||
// Create The ETW TraceProvider
|
||||
//
|
||||
|
||||
m_provider = new EventProvider(controlGuid);
|
||||
}
|
||||
|
||||
//
|
||||
// override Listener methods
|
||||
//
|
||||
public sealed override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public sealed override bool IsThreadSafe
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
m_provider.Close();
|
||||
}
|
||||
|
||||
public sealed override void Write(string message)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_provider.WriteMessageEvent(message, (byte)TraceEventType.Information, 0);
|
||||
}
|
||||
|
||||
public sealed override void WriteLine(string message)
|
||||
{
|
||||
Write(message);
|
||||
}
|
||||
|
||||
//
|
||||
// For all the methods below the string to be logged contains:
|
||||
// m_delimeter seperated data converted to string
|
||||
// followed by the callstack if any.
|
||||
// "id : Data1, Data2... : callstack : callstack value"
|
||||
//
|
||||
// The source parameter is ignored.
|
||||
//
|
||||
public sealed override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null,null,null,null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder dataString = new StringBuilder(s_defaultPayloadSize);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
dataString.Append(data.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
dataString.Append(s_nullCStringValue);
|
||||
}
|
||||
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
dataString.Append(s_callStackString);
|
||||
dataString.Append(eventCache.Callstack);
|
||||
m_provider.WriteMessageEvent(
|
||||
dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, int id, params object[] data)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int index;
|
||||
StringBuilder dataString = new StringBuilder(s_defaultPayloadSize);
|
||||
|
||||
if ((data != null) && (data.Length > 0) )
|
||||
{
|
||||
for (index = 0; index < (data.Length - 1); index++)
|
||||
{
|
||||
if (data[index] != null)
|
||||
{
|
||||
dataString.Append(data[index].ToString());
|
||||
dataString.Append(Delimiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataString.Append(s_nullStringComaValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (data[index] != null)
|
||||
{
|
||||
dataString.Append(data[index].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
dataString.Append(s_nullStringValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dataString.Append(s_nullStringValue);
|
||||
}
|
||||
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
dataString.Append(s_callStackString);
|
||||
dataString.Append(eventCache.Callstack);
|
||||
m_provider.WriteMessageEvent(
|
||||
dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
m_provider.WriteMessageEvent(s_callStackString + eventCache.Callstack,
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(String.Empty,
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder dataString = new StringBuilder(s_defaultPayloadSize);
|
||||
dataString.Append(message);
|
||||
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
dataString.Append(s_callStackString);
|
||||
dataString.Append(eventCache.Callstack);
|
||||
m_provider.WriteMessageEvent(
|
||||
dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(dataString.ToString(),
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
{
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
m_provider.WriteMessageEvent(format + s_callStackString + eventCache.Callstack,
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(format,
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
m_provider.WriteMessageEvent(String.Format(CultureInfo.InvariantCulture, format, args) + s_callStackString + eventCache.Callstack,
|
||||
(byte)eventType,
|
||||
(long)eventType & s_keyWordMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(String.Format(CultureInfo.InvariantCulture, format, args),
|
||||
(byte)eventType,
|
||||
(long)eventType&s_keyWordMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Fail(string message, string detailMessage)
|
||||
{
|
||||
StringBuilder failMessage = new StringBuilder(message);
|
||||
if (detailMessage != null)
|
||||
{
|
||||
failMessage.Append(" ");
|
||||
failMessage.Append(detailMessage);
|
||||
}
|
||||
|
||||
this.TraceEvent(null, null, TraceEventType.Error, 0, failMessage.ToString());
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public sealed override void TraceTransfer(TraceEventCache eventCache, String source, int id, string message, Guid relatedActivityId)
|
||||
{
|
||||
if (!m_provider.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder dataString = new StringBuilder(s_defaultPayloadSize);
|
||||
object correlationId = Trace.CorrelationManager.ActivityId;
|
||||
|
||||
if (correlationId != null)
|
||||
{
|
||||
Guid activityId = (Guid)correlationId;
|
||||
dataString.Append(s_activityIdString);
|
||||
dataString.Append(activityId.ToString());
|
||||
dataString.Append(Delimiter);
|
||||
}
|
||||
|
||||
|
||||
dataString.Append(s_relatedActivityIdString);
|
||||
dataString.Append(relatedActivityId.ToString());
|
||||
dataString.Append(Delimiter + message);
|
||||
|
||||
if ((eventCache != null) && (TraceOutputOptions & TraceOptions.Callstack) != 0)
|
||||
{
|
||||
dataString.Append(s_callStackString);
|
||||
dataString.Append(eventCache.Callstack);
|
||||
m_provider.WriteMessageEvent(
|
||||
dataString.ToString(),
|
||||
0,
|
||||
(long)TraceEventType.Transfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_provider.WriteMessageEvent(dataString.ToString(),
|
||||
0,
|
||||
(long)TraceEventType.Transfer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: CoTaskMemSafeHandle
|
||||
**
|
||||
** Purpose:
|
||||
** This internal class is a SafeHandle implementation over a
|
||||
** native CoTaskMem allocated via StringToCoTaskMemAuto.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
//
|
||||
// Marked as SecurityCritical due to link demands from inherited
|
||||
// SafeHandle members.
|
||||
//
|
||||
#pragma warning disable 618 // Have not migrated to v4 transparency yet
|
||||
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
|
||||
#pragma warning restore 618
|
||||
internal sealed class CoTaskMemSafeHandle : SafeHandle {
|
||||
|
||||
internal CoTaskMemSafeHandle()
|
||||
: base(IntPtr.Zero, true) {
|
||||
}
|
||||
|
||||
internal void SetMemory(IntPtr handle) {
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
internal IntPtr GetMemory() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
public override bool IsInvalid {
|
||||
get {
|
||||
return IsClosed || handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle() {
|
||||
Marshal.FreeCoTaskMem(handle);
|
||||
handle = IntPtr.Zero;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// DONT compare CoTaskMemSafeHandle with CoTaskMemSafeHandle.Zero
|
||||
// use IsInvalid instead. Zero is provided where a NULL handle needed
|
||||
//
|
||||
|
||||
public static CoTaskMemSafeHandle Zero {
|
||||
get {
|
||||
return new CoTaskMemSafeHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: CoTaskMemUnicodeSafeHandle
|
||||
**
|
||||
** Purpose:
|
||||
** This internal class is a SafeHandle implementation over a
|
||||
** native CoTaskMem allocated via SecureStringToCoTaskMemUnicode.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
//
|
||||
// Marked as SecurityCritical due to link demands from inherited
|
||||
// SafeHandle members.
|
||||
//
|
||||
#pragma warning disable 618 // Have not migrated to v4 transparency yet
|
||||
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
|
||||
#pragma warning restore 618
|
||||
internal sealed class CoTaskMemUnicodeSafeHandle : SafeHandle {
|
||||
|
||||
internal CoTaskMemUnicodeSafeHandle()
|
||||
: base(IntPtr.Zero, true) {
|
||||
}
|
||||
|
||||
internal CoTaskMemUnicodeSafeHandle(IntPtr handle, bool ownsHandle)
|
||||
: base(IntPtr.Zero, ownsHandle) {
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
internal void SetMemory(IntPtr handle) {
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
internal IntPtr GetMemory() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
public override bool IsInvalid {
|
||||
get {
|
||||
return IsClosed || handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle() {
|
||||
Marshal.ZeroFreeCoTaskMemUnicode(handle);
|
||||
handle = IntPtr.Zero;
|
||||
return true;
|
||||
}
|
||||
|
||||
// DONT compare CoTaskMemUnicodeSafeHandle with CoTaskMemUnicodeSafeHandle.Zero
|
||||
// use IsInvalid instead. Zero is provided where a NULL handle needed
|
||||
public static CoTaskMemUnicodeSafeHandle Zero {
|
||||
get {
|
||||
return new CoTaskMemUnicodeSafeHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventBookmark
|
||||
**
|
||||
** Purpose:
|
||||
** This public class represents an opaque Event Bookmark obtained
|
||||
** from an EventRecord. The bookmark denotes a unique identifier
|
||||
** for the event instance as well as marks the location in the
|
||||
** the result set of the EventReader that the event instance was
|
||||
** obtained from.
|
||||
**
|
||||
============================================================*/
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
//
|
||||
// NOTE: This class must be generic enough to be used across
|
||||
// eventing base implementations. Cannot add anything
|
||||
// that ties it to one particular implementation.
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Represents an opaque Event Bookmark obtained from an EventRecord.
|
||||
/// The bookmark denotes a unique identifier for the event instance as
|
||||
/// well as marks the location in the the result set of the EventReader
|
||||
/// that the event instance was obtained from.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventBookmark : ISerializable {
|
||||
string bookmark;
|
||||
|
||||
internal EventBookmark(string bookmarkText) {
|
||||
if (bookmarkText == null)
|
||||
throw new ArgumentNullException("bookmarkText");
|
||||
this.bookmark = bookmarkText;
|
||||
}
|
||||
|
||||
protected EventBookmark(SerializationInfo info, StreamingContext context) {
|
||||
if (info == null)
|
||||
throw new ArgumentNullException("info");
|
||||
this.bookmark = info.GetString("BookmarkText");
|
||||
}
|
||||
|
||||
// SecurityCritical due to inherited link demand for GetObjectData.
|
||||
[System.Security.SecurityCritical,SecurityPermissionAttribute(SecurityAction.LinkDemand,Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
|
||||
GetObjectData( info, context );
|
||||
}
|
||||
|
||||
// SecurityCritical due to inherited link demand for GetObjectData.
|
||||
[System.Security.SecurityCritical,SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||
protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
|
||||
|
||||
if (info == null)
|
||||
throw new ArgumentNullException("info");
|
||||
info.AddValue("BookmarkText", this.bookmark);
|
||||
}
|
||||
|
||||
internal string BookmarkText { get { return bookmark; } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventKeyword
|
||||
**
|
||||
** Purpose:
|
||||
** This public class describes the metadata for a specific Keyword
|
||||
** defined by a Provider. An instance of this class is obtained from
|
||||
** a ProviderMetadata object.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Describes the metadata for a specific Keyword defined by a Provider.
|
||||
/// An instance of this class is obtained from a ProviderMetadata object.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public sealed class EventKeyword {
|
||||
private long value;
|
||||
private string name;
|
||||
private string displayName;
|
||||
private bool dataReady;
|
||||
ProviderMetadata pmReference;
|
||||
object syncObject;
|
||||
|
||||
//called from EventMetadata
|
||||
internal EventKeyword(long value, ProviderMetadata pmReference) {
|
||||
this.value = value;
|
||||
this.pmReference = pmReference;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
//called from ProviderMetadata
|
||||
internal EventKeyword(string name, long value, string displayName) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.dataReady = true;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
internal void PrepareData() {
|
||||
if (dataReady == true) return;
|
||||
|
||||
lock (syncObject) {
|
||||
if (dataReady == true) return;
|
||||
|
||||
IEnumerable<EventKeyword> result = pmReference.Keywords;
|
||||
|
||||
this.name = null;
|
||||
this.displayName = null;
|
||||
this.dataReady = true;
|
||||
|
||||
foreach (EventKeyword key in result) {
|
||||
if (key.Value == this.value) {
|
||||
this.name = key.Name;
|
||||
this.displayName = key.DisplayName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
PrepareData();
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public long Value {
|
||||
get {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName {
|
||||
get {
|
||||
PrepareData();
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLevel
|
||||
**
|
||||
** Purpose:
|
||||
** This public class describes the metadata for a specific Level
|
||||
** defined by a Provider. An instance of this class is obtained from
|
||||
** a ProviderMetadata object.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Describes the metadata for a specific Level defined by a Provider.
|
||||
/// An instance of this class is obtained from a ProviderMetadata object.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public sealed class EventLevel {
|
||||
|
||||
private int value;
|
||||
private string name;
|
||||
private string displayName;
|
||||
private bool dataReady;
|
||||
ProviderMetadata pmReference;
|
||||
object syncObject;
|
||||
|
||||
//called from EventMetadata
|
||||
internal EventLevel(int value, ProviderMetadata pmReference) {
|
||||
this.value = value;
|
||||
this.pmReference = pmReference;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
//called from ProviderMetadata
|
||||
internal EventLevel(string name, int value, string displayName) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.dataReady = true;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
internal void PrepareData() {
|
||||
if (dataReady == true) return;
|
||||
|
||||
lock (syncObject) {
|
||||
if (dataReady == true) return;
|
||||
|
||||
IEnumerable<EventLevel> result = pmReference.Levels;
|
||||
this.name = null;
|
||||
this.displayName = null;
|
||||
this.dataReady = true;
|
||||
foreach (EventLevel lev in result) {
|
||||
if (lev.Value == this.value) {
|
||||
this.name = lev.Name;
|
||||
this.displayName = lev.DisplayName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
PrepareData();
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public int Value {
|
||||
get {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName {
|
||||
get {
|
||||
PrepareData();
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogConfiguration
|
||||
**
|
||||
** Purpose:
|
||||
** This public class allows accessing static channel information and
|
||||
** configures channel publishing and logging properties. An instance
|
||||
** of this class is obtained from EventLogManagement class.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Log Type
|
||||
/// </summary>
|
||||
public enum EventLogType {
|
||||
Administrative = 0,
|
||||
Operational,
|
||||
Analytical,
|
||||
Debug
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log Isolation
|
||||
/// </summary>
|
||||
public enum EventLogIsolation {
|
||||
Application = 0,
|
||||
System,
|
||||
Custom
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log Mode
|
||||
/// </summary>
|
||||
public enum EventLogMode {
|
||||
Circular = 0,
|
||||
AutoBackup,
|
||||
Retain
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to static log information and configures
|
||||
/// log publishing and log file properties.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogConfiguration : 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 EventLogSession session = null;
|
||||
private string channelName;
|
||||
|
||||
public EventLogConfiguration(string logName) : this(logName, null) { }
|
||||
|
||||
// marked as SecurityCritical because allocates SafeHandles.
|
||||
// marked as Safe because performs Demand check.
|
||||
[System.Security.SecurityCritical]
|
||||
public EventLogConfiguration(string logName, EventLogSession session) {
|
||||
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
if (session == null)
|
||||
session = EventLogSession.GlobalSession;
|
||||
|
||||
this.session = session;
|
||||
this.channelName = logName;
|
||||
|
||||
handle = NativeWrapper.EvtOpenChannelConfig(this.session.Handle, this.channelName, 0);
|
||||
}
|
||||
|
||||
public string LogName {
|
||||
get {
|
||||
return channelName;
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogType LogType {
|
||||
get {
|
||||
return (EventLogType)((uint)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigType));
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogIsolation LogIsolation {
|
||||
get {
|
||||
return (EventLogIsolation)((uint)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigIsolation));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnabled {
|
||||
get {
|
||||
return (bool)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigEnabled);
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigEnabled, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClassicLog {
|
||||
get {
|
||||
return (bool)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigClassicEventlog);
|
||||
}
|
||||
}
|
||||
|
||||
public string SecurityDescriptor {
|
||||
get {
|
||||
return (string)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigAccess);
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigAccess, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public string LogFilePath {
|
||||
get {
|
||||
return (string)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigLogFilePath);
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigLogFilePath, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public long MaximumSizeInBytes {
|
||||
get {
|
||||
return (long)((ulong)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigMaxSize));
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigMaxSize, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogMode LogMode {
|
||||
get {
|
||||
object nativeRetentionObject = NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention);
|
||||
object nativeAutoBackupObject = NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup);
|
||||
|
||||
bool nativeRetention = nativeRetentionObject == null ? false : (bool)nativeRetentionObject;
|
||||
bool nativeAutoBackup = nativeAutoBackupObject == null ? false : (bool)nativeAutoBackupObject;
|
||||
|
||||
if (nativeAutoBackup)
|
||||
return EventLogMode.AutoBackup;
|
||||
|
||||
if (nativeRetention)
|
||||
return EventLogMode.Retain;
|
||||
|
||||
return EventLogMode.Circular;
|
||||
}
|
||||
set {
|
||||
|
||||
switch (value) {
|
||||
case EventLogMode.Circular:
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup, (object)false);
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention, (object)false);
|
||||
break;
|
||||
case EventLogMode.AutoBackup:
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup, (object)true);
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention, (object)true);
|
||||
break;
|
||||
case EventLogMode.Retain:
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup, (object)false);
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention, (object)true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string OwningProviderName {
|
||||
get {
|
||||
return (string)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigOwningPublisher);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> ProviderNames {
|
||||
get {
|
||||
return (string[])NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublisherList);
|
||||
}
|
||||
}
|
||||
|
||||
public int? ProviderLevel {
|
||||
get {
|
||||
return (int?)((uint?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigLevel));
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigLevel, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public long? ProviderKeywords {
|
||||
get {
|
||||
return (long?)((ulong?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigKeywords));
|
||||
}
|
||||
set {
|
||||
NativeWrapper.EvtSetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigKeywords, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public int? ProviderBufferSize {
|
||||
get {
|
||||
return (int?)((uint?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
public int? ProviderMinimumNumberOfBuffers {
|
||||
get {
|
||||
return (int?)((uint?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigMinBuffers));
|
||||
}
|
||||
}
|
||||
|
||||
public int? ProviderMaximumNumberOfBuffers {
|
||||
get {
|
||||
return (int?)((uint?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigMaxBuffers));
|
||||
}
|
||||
}
|
||||
|
||||
public int? ProviderLatency {
|
||||
get {
|
||||
return (int?)((uint?)NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigLatency));
|
||||
}
|
||||
}
|
||||
|
||||
public Guid? ProviderControlGuid {
|
||||
get {
|
||||
return (Guid?)(NativeWrapper.EvtGetChannelConfigProperty(this.handle, UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigControlGuid));
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveChanges() {
|
||||
|
||||
NativeWrapper.EvtSaveChannelConfig(this.handle, 0);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogException
|
||||
**
|
||||
** Purpose:
|
||||
** This public class describes an exception thrown from Event
|
||||
** Log related classes.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogException : Exception, ISerializable {
|
||||
internal static void Throw(int errorCode) {
|
||||
switch (errorCode) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 15007:
|
||||
case 15027:
|
||||
case 15028:
|
||||
case 15002:
|
||||
throw new EventLogNotFoundException(errorCode);
|
||||
|
||||
case 13:
|
||||
case 15005:
|
||||
throw new EventLogInvalidDataException(errorCode);
|
||||
|
||||
case 1818: // RPC_S_CALL_CANCELED is converted to ERROR_CANCELLED
|
||||
case 1223:
|
||||
throw new OperationCanceledException();
|
||||
|
||||
case 15037:
|
||||
throw new EventLogProviderDisabledException(errorCode);
|
||||
|
||||
case 5:
|
||||
throw new UnauthorizedAccessException();
|
||||
|
||||
case 15011:
|
||||
case 15012:
|
||||
throw new EventLogReadingException(errorCode);
|
||||
|
||||
default: throw new EventLogException(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogException() { }
|
||||
public EventLogException(string message) : base(message) { }
|
||||
public EventLogException(string message, Exception innerException) : base(message, innerException) { }
|
||||
protected EventLogException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||
protected EventLogException(int errorCode) { this.errorCode = errorCode; }
|
||||
|
||||
// SecurityCritical due to inherited link demand for GetObjectData.
|
||||
[System.Security.SecurityCritical,SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
|
||||
if (info == null)
|
||||
throw new ArgumentNullException("info");
|
||||
info.AddValue("errorCode", errorCode);
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
|
||||
public override string Message {
|
||||
// marked as SecurityCritical because it uses Win32Exception.
|
||||
// marked as TreatAsSafe because it performs Demand.
|
||||
[System.Security.SecurityCritical]
|
||||
get {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
Win32Exception win32Exception = new Win32Exception(errorCode);
|
||||
return win32Exception.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private int errorCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object requested by the operation is not found.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogNotFoundException : EventLogException {
|
||||
public EventLogNotFoundException() { }
|
||||
public EventLogNotFoundException(string message) : base(message) { }
|
||||
public EventLogNotFoundException(string message, Exception innerException) : base(message, innerException) { }
|
||||
protected EventLogNotFoundException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||
internal EventLogNotFoundException(int errorCode) : base(errorCode) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The state of the reader cursor has become invalid, most likely due to the fact
|
||||
/// that the log has been cleared. User needs to obtain a new reader object if
|
||||
/// they wish to continue navigating result set.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogReadingException : EventLogException {
|
||||
public EventLogReadingException() { }
|
||||
public EventLogReadingException(string message) : base(message) { }
|
||||
public EventLogReadingException(string message, Exception innerException) : base(message, innerException) { }
|
||||
protected EventLogReadingException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||
internal EventLogReadingException(int errorCode) : base(errorCode) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provider has been uninstalled while ProviderMetadata operations are being performed.
|
||||
/// Obtain a new ProviderMetadata object, when provider is reinstalled, to continue navigating
|
||||
/// provider's metadata.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogProviderDisabledException : EventLogException {
|
||||
public EventLogProviderDisabledException() { }
|
||||
public EventLogProviderDisabledException(string message) : base(message) { }
|
||||
public EventLogProviderDisabledException(string message, Exception innerException) : base(message, innerException) { }
|
||||
protected EventLogProviderDisabledException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||
internal EventLogProviderDisabledException(int errorCode) : base(errorCode) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data obtained from the eventlog service, for the current operation, is invalid .
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogInvalidDataException : EventLogException {
|
||||
public EventLogInvalidDataException() { }
|
||||
public EventLogInvalidDataException(string message) : base(message) { }
|
||||
public EventLogInvalidDataException(string message, Exception innerException) : base(message, innerException) { }
|
||||
protected EventLogInvalidDataException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||
internal EventLogInvalidDataException(int errorCode) : base(errorCode) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogHandle
|
||||
**
|
||||
** Purpose:
|
||||
** This internal class is a SafeHandle implementation over a
|
||||
** native EVT_HANDLE - obtained from EventLog Native Methods.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
//
|
||||
// Marked as SecurityCritical due to link demands from inherited
|
||||
// SafeHandle members.
|
||||
//
|
||||
|
||||
// marked as Safe since the only real operation that is performed
|
||||
// by this class is NativeWrapper.EvtClose and that is protected
|
||||
// by a full Demand() before doing any work.
|
||||
[System.Security.SecuritySafeCritical]
|
||||
internal sealed class EventLogHandle : SafeHandle {
|
||||
// Called by P/Invoke when returning SafeHandles
|
||||
private EventLogHandle()
|
||||
: base(IntPtr.Zero, true) {
|
||||
}
|
||||
|
||||
internal EventLogHandle(IntPtr handle, bool ownsHandle)
|
||||
: base(IntPtr.Zero, ownsHandle) {
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
public override bool IsInvalid {
|
||||
get {
|
||||
return IsClosed || handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle() {
|
||||
NativeWrapper.EvtClose(handle);
|
||||
handle = IntPtr.Zero;
|
||||
return true;
|
||||
}
|
||||
|
||||
// DONT compare EventLogHandle with EventLogHandle.Zero
|
||||
// use IsInvalid instead. Zero is provided where a NULL handle needed
|
||||
public static EventLogHandle Zero {
|
||||
get {
|
||||
return new EventLogHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogInformation
|
||||
**
|
||||
** Purpose:
|
||||
** The objects of this class allow access to the run-time
|
||||
** properties of logs and external log files. An instance of this
|
||||
** class is obtained from EventLogSession.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32;
|
||||
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Describes the run-time properties of logs and external log files. An instance
|
||||
/// of this class is obtained from EventLogSession.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public sealed class EventLogInformation {
|
||||
DateTime? creationTime;
|
||||
DateTime? lastAccessTime;
|
||||
DateTime? lastWriteTime;
|
||||
long? fileSize;
|
||||
int? fileAttributes;
|
||||
long? recordCount;
|
||||
long? oldestRecordNumber;
|
||||
bool? isLogFull;
|
||||
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
internal EventLogInformation(EventLogSession session, string channelName, PathType pathType) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
EventLogHandle logHandle = NativeWrapper.EvtOpenLog(session.Handle, channelName, pathType);
|
||||
|
||||
using (logHandle) {
|
||||
creationTime = (DateTime?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogCreationTime);
|
||||
lastAccessTime = (DateTime?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogLastAccessTime);
|
||||
lastWriteTime = (DateTime?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogLastWriteTime);
|
||||
fileSize = (long?)((ulong?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogFileSize));
|
||||
fileAttributes = (int?)((uint?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogAttributes));
|
||||
recordCount = (long?)((ulong?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogNumberOfLogRecords));
|
||||
oldestRecordNumber = (long?)((ulong?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogOldestRecordNumber));
|
||||
isLogFull = (bool?)NativeWrapper.EvtGetLogInfo(logHandle, UnsafeNativeMethods.EvtLogPropertyId.EvtLogFull);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? CreationTime { get { return creationTime; } }
|
||||
public DateTime? LastAccessTime { get { return lastAccessTime; } }
|
||||
public DateTime? LastWriteTime { get { return lastWriteTime; } }
|
||||
public long? FileSize { get { return fileSize; } }
|
||||
public int? Attributes { get { return fileAttributes; } }
|
||||
public long? RecordCount { get { return recordCount; } }
|
||||
public long? OldestRecordNumber { get { return oldestRecordNumber; } }
|
||||
public bool? IsLogFull { get { return isLogFull; } }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogLink
|
||||
**
|
||||
** Purpose:
|
||||
** This public class describes the metadata for a specific Log
|
||||
** Reference defined by a Provider. An instance of this class is obtained from
|
||||
** a ProviderMetadata object.
|
||||
**
|
||||
============================================================*/
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Describes the metadata for a specific Log Reference defined
|
||||
/// by a Provider. An instance of this class is obtained from
|
||||
/// a ProviderMetadata object.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public sealed class EventLogLink {
|
||||
private string channelName;
|
||||
private bool isImported;
|
||||
private string displayName;
|
||||
private uint channelId;
|
||||
|
||||
private bool dataReady;
|
||||
ProviderMetadata pmReference;
|
||||
object syncObject;
|
||||
|
||||
internal EventLogLink(uint channelId, ProviderMetadata pmReference) {
|
||||
this.channelId = channelId;
|
||||
this.pmReference = pmReference;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
internal EventLogLink(string channelName, bool isImported, string displayName, uint channelId) {
|
||||
this.channelName = channelName;
|
||||
this.isImported = isImported;
|
||||
this.displayName = displayName;
|
||||
this.channelId = channelId;
|
||||
|
||||
this.dataReady = true;
|
||||
this.syncObject = new object();
|
||||
}
|
||||
|
||||
private void PrepareData() {
|
||||
if (dataReady == true) return;
|
||||
|
||||
lock (syncObject) {
|
||||
if (dataReady == true) return;
|
||||
|
||||
IEnumerable<EventLogLink> result = pmReference.LogLinks;
|
||||
|
||||
this.channelName = null;
|
||||
this.isImported = false;
|
||||
this.displayName = null;
|
||||
this.dataReady = true;
|
||||
|
||||
foreach (EventLogLink ch in result) {
|
||||
if (ch.ChannelId == this.channelId) {
|
||||
this.channelName = ch.LogName;
|
||||
this.isImported = ch.IsImported;
|
||||
this.displayName = ch.DisplayName;
|
||||
|
||||
this.dataReady = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string LogName {
|
||||
get {
|
||||
this.PrepareData();
|
||||
return this.channelName;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsImported {
|
||||
get {
|
||||
this.PrepareData();
|
||||
return this.isImported;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName {
|
||||
get {
|
||||
this.PrepareData();
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
internal uint ChannelId {
|
||||
get {
|
||||
return channelId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogPermissionHolder
|
||||
**
|
||||
** Purpose:
|
||||
** Internal class that defines the permissions that are used
|
||||
** throughout the Event Log classes of this namespace.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
internal class EventLogPermissionHolder {
|
||||
public EventLogPermissionHolder() {
|
||||
}
|
||||
|
||||
public static EventLogPermission GetEventLogPermission() {
|
||||
EventLogPermission logPermission = new EventLogPermission();
|
||||
EventLogPermissionEntry permEntry =
|
||||
new EventLogPermissionEntry(EventLogPermissionAccess.Administer, ".");
|
||||
logPermission.PermissionEntries.Add(permEntry);
|
||||
return logPermission;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogPropertySelector
|
||||
**
|
||||
** Purpose:
|
||||
** Public class that encapsulates the information for fast
|
||||
** access to Event Values of an EventLogRecord. Implements
|
||||
** the EventPropertyContext abstract class. An instance of this
|
||||
** class is constructed and then passed to
|
||||
** EventLogRecord.GetEventPropertyValues.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates the information for fast access to Event Values
|
||||
/// of an EventLogRecord. An instance of this class is constructed
|
||||
/// and then passed to EventLogRecord.GetEventPropertyValues.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogPropertySelector : IDisposable {
|
||||
|
||||
//
|
||||
// access to the data member reference is safe, while
|
||||
// invoking methods on it is marked SecurityCritical as appropriate.
|
||||
//
|
||||
private EventLogHandle renderContextHandleValues;
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public EventLogPropertySelector(IEnumerable<string> propertyQueries) {
|
||||
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
if (propertyQueries == null)
|
||||
throw new ArgumentNullException("propertyQueries");
|
||||
|
||||
string[] paths;
|
||||
|
||||
ICollection<string> coll = propertyQueries as ICollection<string>;
|
||||
if (coll != null) {
|
||||
paths = new string[coll.Count];
|
||||
coll.CopyTo(paths, 0);
|
||||
}
|
||||
else {
|
||||
List<string> queries;
|
||||
queries = new List<string>(propertyQueries);
|
||||
paths = queries.ToArray();
|
||||
}
|
||||
|
||||
renderContextHandleValues = NativeWrapper.EvtCreateRenderContext(paths.Length, paths, UnsafeNativeMethods.EvtRenderContextFlags.EvtRenderContextValues);
|
||||
}
|
||||
|
||||
internal EventLogHandle Handle {
|
||||
// just returning reference to security critical type, the methods
|
||||
// of that type are protected by SecurityCritical as appropriate.
|
||||
get {
|
||||
return renderContextHandleValues;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
protected virtual void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
}
|
||||
if (renderContextHandleValues != null && !renderContextHandleValues.IsInvalid)
|
||||
renderContextHandleValues.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogQuery
|
||||
**
|
||||
** Purpose:
|
||||
** This public class allows a user to define events of interest.
|
||||
** An instance of this class is passed to an EventReader to actually
|
||||
** obtain the EventRecords. The EventLogQuery can be as
|
||||
** simple specifying that all events are of interest, or it can contain
|
||||
** query / xpath expressions that indicate exactly what characteristics
|
||||
** events should have.
|
||||
**
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// Allows a user to define events of interest. An instance of this
|
||||
/// class is passed to an EventReader to actually obtain the EventRecords.
|
||||
/// The EventLogQuery can be as simple specifying that all events are of
|
||||
/// interest, or it can contain query / xpath expressions that indicate exactly
|
||||
/// what characteristics events should have.
|
||||
/// </summary>
|
||||
public class EventLogQuery {
|
||||
|
||||
private string query;
|
||||
private string path;
|
||||
private EventLogSession session;
|
||||
private PathType pathType;
|
||||
private bool tolerateErrors = false;
|
||||
private bool reverseDirection = false;
|
||||
|
||||
public EventLogQuery(string path, PathType pathType)
|
||||
: this(path, pathType, null) {
|
||||
}
|
||||
|
||||
public EventLogQuery(string path, PathType pathType, string query) {
|
||||
|
||||
this.session = EventLogSession.GlobalSession;
|
||||
this.path = path; // can be null
|
||||
this.pathType = pathType;
|
||||
|
||||
if (query == null) {
|
||||
if (path == null)
|
||||
throw new ArgumentNullException("path");
|
||||
}
|
||||
else {
|
||||
this.query = query;
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogSession Session {
|
||||
get {
|
||||
return this.session;
|
||||
}
|
||||
set {
|
||||
this.session = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TolerateQueryErrors {
|
||||
get {
|
||||
return this.tolerateErrors;
|
||||
}
|
||||
set {
|
||||
this.tolerateErrors = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReverseDirection {
|
||||
get {
|
||||
return this.reverseDirection;
|
||||
}
|
||||
set {
|
||||
this.reverseDirection = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Path {
|
||||
get {
|
||||
return this.path;
|
||||
}
|
||||
}
|
||||
|
||||
internal PathType ThePathType {
|
||||
get {
|
||||
return this.pathType;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Query {
|
||||
get {
|
||||
return this.query;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogReader
|
||||
**
|
||||
** Purpose:
|
||||
** This public class is used for reading event records from event log.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
/// <summary>
|
||||
/// This public class is used for reading event records from event log.
|
||||
/// </summary>
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogReader : IDisposable {
|
||||
|
||||
private EventLogQuery eventQuery;
|
||||
|
||||
private int batchSize;
|
||||
|
||||
//
|
||||
// access to the data member reference is safe, while
|
||||
// invoking methods on it is marked SecurityCritical as appropriate.
|
||||
//
|
||||
private EventLogHandle handle;
|
||||
|
||||
/// <summary>
|
||||
/// events buffer holds batched event (handles).
|
||||
/// </summary>
|
||||
private IntPtr[] eventsBuffer;
|
||||
/// <summary>
|
||||
/// The current index where the function GetNextEvent is (inside the eventsBuffer).
|
||||
/// </summary>
|
||||
private int currentIndex;
|
||||
/// <summary>
|
||||
/// The number of events read from the batch into the eventsBuffer
|
||||
/// </summary>
|
||||
private int eventCount;
|
||||
|
||||
/// <summary>
|
||||
/// When the reader finishes (will always return only ERROR_NO_MORE_ITEMS).
|
||||
/// For subscription, this means we need to wait for next event.
|
||||
/// </summary>
|
||||
bool isEof;
|
||||
|
||||
/// <summary>
|
||||
/// Maintains cached display / metadata information returned from
|
||||
/// EventRecords that were obtained from this reader.
|
||||
/// </summary>
|
||||
ProviderMetadataCachedInformation cachedMetadataInformation;
|
||||
|
||||
public EventLogReader(string path)
|
||||
: this(new EventLogQuery(path, PathType.LogName), null) {
|
||||
}
|
||||
|
||||
public EventLogReader(string path, PathType pathType)
|
||||
: this(new EventLogQuery(path, pathType), null) {
|
||||
}
|
||||
|
||||
public EventLogReader(EventLogQuery eventQuery)
|
||||
: this(eventQuery, null) {
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public EventLogReader(EventLogQuery eventQuery, EventBookmark bookmark) {
|
||||
|
||||
if (eventQuery == null)
|
||||
throw new ArgumentNullException("eventQuery");
|
||||
|
||||
string logfile = null;
|
||||
if (eventQuery.ThePathType == PathType.FilePath)
|
||||
logfile = eventQuery.Path;
|
||||
|
||||
this.cachedMetadataInformation = new ProviderMetadataCachedInformation(eventQuery.Session, logfile, 50 );
|
||||
|
||||
//explicit data
|
||||
this.eventQuery = eventQuery;
|
||||
|
||||
//implicit
|
||||
this.batchSize = 64;
|
||||
this.eventsBuffer = new IntPtr[batchSize];
|
||||
|
||||
//
|
||||
// compute the flag.
|
||||
//
|
||||
int flag = 0;
|
||||
|
||||
if (this.eventQuery.ThePathType == PathType.LogName)
|
||||
flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryChannelPath;
|
||||
else
|
||||
flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath;
|
||||
|
||||
if (this.eventQuery.ReverseDirection)
|
||||
flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryReverseDirection;
|
||||
|
||||
if (this.eventQuery.TolerateQueryErrors)
|
||||
flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryTolerateQueryErrors;
|
||||
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
handle = NativeWrapper.EvtQuery(this.eventQuery.Session.Handle,
|
||||
this.eventQuery.Path, this.eventQuery.Query,
|
||||
flag);
|
||||
|
||||
EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark);
|
||||
|
||||
if (!bookmarkHandle.IsInvalid) {
|
||||
using (bookmarkHandle) {
|
||||
NativeWrapper.EvtSeek(handle, 1, bookmarkHandle, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToBookmark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int BatchSize {
|
||||
get {
|
||||
return batchSize;
|
||||
}
|
||||
set {
|
||||
if (value < 1)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
batchSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
private bool GetNextBatch(TimeSpan ts) {
|
||||
|
||||
int timeout;
|
||||
if (ts == TimeSpan.MaxValue)
|
||||
timeout = -1;
|
||||
else
|
||||
timeout = (int)ts.TotalMilliseconds;
|
||||
|
||||
// batchSize was changed by user, reallocate buffer.
|
||||
if (batchSize != eventsBuffer.Length) eventsBuffer = new IntPtr[batchSize];
|
||||
|
||||
int newEventCount = 0;
|
||||
bool results = NativeWrapper.EvtNext(handle, batchSize, eventsBuffer, timeout, 0, ref newEventCount);
|
||||
|
||||
if (!results) {
|
||||
this.eventCount = 0;
|
||||
this.currentIndex = 0;
|
||||
return false; //no more events in the result set
|
||||
}
|
||||
|
||||
this.currentIndex = 0;
|
||||
this.eventCount = newEventCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
public EventRecord ReadEvent() {
|
||||
return ReadEvent(TimeSpan.MaxValue);
|
||||
}
|
||||
|
||||
// security critical because allocates SafeHandle.
|
||||
// marked as safe because performs Demand check.
|
||||
[System.Security.SecurityCritical]
|
||||
public EventRecord ReadEvent(TimeSpan timeout) {
|
||||
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
if (this.isEof)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
if (this.currentIndex >= this.eventCount) {
|
||||
// buffer is empty, get next batch.
|
||||
GetNextBatch(timeout);
|
||||
|
||||
if (this.currentIndex >= this.eventCount) {
|
||||
this.isEof = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
EventLogRecord eventInstance = new EventLogRecord(new EventLogHandle(this.eventsBuffer[currentIndex], true), this.eventQuery.Session, this.cachedMetadataInformation);
|
||||
currentIndex++;
|
||||
return eventInstance;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
protected virtual void Dispose(bool disposing) {
|
||||
|
||||
if (disposing) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
}
|
||||
|
||||
while (this.currentIndex < this.eventCount) {
|
||||
NativeWrapper.EvtClose(eventsBuffer[this.currentIndex]);
|
||||
this.currentIndex++;
|
||||
}
|
||||
|
||||
if (handle != null && !handle.IsInvalid)
|
||||
handle.Dispose();
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
internal void SeekReset() {
|
||||
//
|
||||
//close all unread event handles in the buffer
|
||||
//
|
||||
while (this.currentIndex < this.eventCount) {
|
||||
NativeWrapper.EvtClose(eventsBuffer[this.currentIndex]);
|
||||
this.currentIndex++;
|
||||
}
|
||||
|
||||
//reset the indexes used by Next
|
||||
this.currentIndex = 0;
|
||||
this.eventCount = 0;
|
||||
this.isEof = false;
|
||||
}
|
||||
|
||||
// marked as SecurityCritical because it allocates SafeHandle.
|
||||
[System.Security.SecurityCritical]
|
||||
internal void SeekCommon(long offset) {
|
||||
|
||||
//
|
||||
// modify offset that we're going to send to service to account for the
|
||||
// fact that we've already read some events in our buffer that the user
|
||||
// hasn't seen yet.
|
||||
//
|
||||
offset = offset - (this.eventCount - this.currentIndex);
|
||||
|
||||
SeekReset();
|
||||
|
||||
NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToCurrent);
|
||||
}
|
||||
|
||||
public void Seek(EventBookmark bookmark) {
|
||||
Seek(bookmark, 0);
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public void Seek(EventBookmark bookmark, long offset) {
|
||||
if (bookmark == null)
|
||||
throw new ArgumentNullException("bookmark");
|
||||
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
SeekReset();
|
||||
using (EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark)) {
|
||||
NativeWrapper.EvtSeek(this.handle, offset, bookmarkHandle, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public void Seek(SeekOrigin origin, long offset) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
switch (origin) {
|
||||
case SeekOrigin.Begin:
|
||||
|
||||
SeekReset();
|
||||
NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToFirst);
|
||||
return;
|
||||
|
||||
case SeekOrigin.End:
|
||||
|
||||
SeekReset();
|
||||
NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToLast);
|
||||
return;
|
||||
|
||||
case SeekOrigin.Current:
|
||||
if (offset >= 0) {
|
||||
//we can reuse elements in the batch.
|
||||
if (this.currentIndex + offset < this.eventCount) {
|
||||
//
|
||||
// We don't call Seek here, we can reposition within the batch.
|
||||
//
|
||||
|
||||
// close all event handles between [currentIndex, currentIndex + offset)
|
||||
int index = this.currentIndex;
|
||||
while (index < this.currentIndex + offset) {
|
||||
NativeWrapper.EvtClose(eventsBuffer[index]);
|
||||
index++;
|
||||
}
|
||||
|
||||
this.currentIndex = (int)(this.currentIndex + offset);
|
||||
//leave the eventCount unchanged
|
||||
//leave the same Eof
|
||||
}
|
||||
else {
|
||||
SeekCommon(offset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//if inside the current buffer, we still cannot read the events, as the handles.
|
||||
//may have already been closed.
|
||||
if (currentIndex + offset >= 0) {
|
||||
SeekCommon(offset);
|
||||
}
|
||||
else //outside the current buffer
|
||||
{
|
||||
SeekCommon(offset);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelReading() {
|
||||
|
||||
NativeWrapper.EvtCancel(handle);
|
||||
}
|
||||
|
||||
public IList<EventLogStatus> LogStatus {
|
||||
[System.Security.SecurityCritical]
|
||||
get {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
List<EventLogStatus> list = null;
|
||||
string[] channelNames = null;
|
||||
int[] errorStatuses = null;
|
||||
EventLogHandle queryHandle = this.handle;
|
||||
|
||||
if (queryHandle.IsInvalid)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
channelNames = (string[])NativeWrapper.EvtGetQueryInfo(queryHandle, UnsafeNativeMethods.EvtQueryPropertyId.EvtQueryNames);
|
||||
errorStatuses = (int[])NativeWrapper.EvtGetQueryInfo(queryHandle, UnsafeNativeMethods.EvtQueryPropertyId.EvtQueryStatuses);
|
||||
|
||||
if (channelNames.Length != errorStatuses.Length)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
list = new List<EventLogStatus>(channelNames.Length);
|
||||
for (int i = 0; i < channelNames.Length; i++) {
|
||||
EventLogStatus cs = new EventLogStatus(channelNames[i], errorStatuses[i]);
|
||||
list.Add(cs);
|
||||
}
|
||||
return list.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogRecord
|
||||
**
|
||||
** Purpose:
|
||||
** This public class is an EventLog implementation of EventRecord. An
|
||||
** instance of this is obtained from an EventLogReader.
|
||||
**
|
||||
============================================================*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogRecord : EventRecord {
|
||||
|
||||
private const int SYSTEM_PROPERTY_COUNT = 18;
|
||||
|
||||
//
|
||||
// access to the data member reference is safe, while
|
||||
// invoking methods on it is marked SecurityCritical as appropriate.
|
||||
//
|
||||
[System.Security.SecuritySafeCritical]
|
||||
private EventLogHandle handle;
|
||||
|
||||
private EventLogSession session;
|
||||
|
||||
private NativeWrapper.SystemProperties systemProperties;
|
||||
private string containerChannel;
|
||||
private int[] matchedQueryIds;
|
||||
|
||||
//a dummy object which is used only for the locking.
|
||||
object syncObject;
|
||||
|
||||
//cached DisplayNames for each instance
|
||||
private string levelName = null;
|
||||
private string taskName = null;
|
||||
private string opcodeName = null;
|
||||
private IEnumerable<string> keywordsNames = null;
|
||||
|
||||
//cached DisplayNames for each instance
|
||||
private bool levelNameReady;
|
||||
private bool taskNameReady;
|
||||
private bool opcodeNameReady;
|
||||
|
||||
private ProviderMetadataCachedInformation cachedMetadataInformation;
|
||||
|
||||
// marking as TreatAsSafe because just passing around a reference to an EventLogHandle is safe.
|
||||
[System.Security.SecuritySafeCritical]
|
||||
internal EventLogRecord(EventLogHandle handle, EventLogSession session, ProviderMetadataCachedInformation cachedMetadataInfo) {
|
||||
this.cachedMetadataInformation = cachedMetadataInfo;
|
||||
this.handle = handle;
|
||||
this.session = session;
|
||||
systemProperties = new NativeWrapper.SystemProperties();
|
||||
syncObject = new object();
|
||||
}
|
||||
|
||||
internal EventLogHandle Handle {
|
||||
// just returning reference to security critical type, the methods
|
||||
// of that type are protected by SecurityCritical as appropriate.
|
||||
[System.Security.SecuritySafeCritical]
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal void PrepareSystemData() {
|
||||
|
||||
if (this.systemProperties.filled)
|
||||
return;
|
||||
|
||||
//prepare the System Context, if it is not already initialized.
|
||||
this.session.SetupSystemContext();
|
||||
|
||||
lock (this.syncObject) {
|
||||
if (this.systemProperties.filled == false) {
|
||||
NativeWrapper.EvtRenderBufferWithContextSystem(this.session.renderContextHandleSystem, this.handle, UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues, this.systemProperties, SYSTEM_PROPERTY_COUNT);
|
||||
this.systemProperties.filled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int Id {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
if (this.systemProperties.Id == null)
|
||||
return 0;
|
||||
return (int)this.systemProperties.Id;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte? Version {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.Version;
|
||||
}
|
||||
}
|
||||
|
||||
public override int? Qualifiers {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (int?)(uint?)this.systemProperties.Qualifiers;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte? Level {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.Level;
|
||||
}
|
||||
}
|
||||
|
||||
public override int? Task {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (int?)(uint?)this.systemProperties.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public override short? Opcode {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (short?)(ushort?)this.systemProperties.Opcode;
|
||||
}
|
||||
}
|
||||
|
||||
public override long? Keywords {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (long?)this.systemProperties.Keywords;
|
||||
}
|
||||
}
|
||||
|
||||
public override long? RecordId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (long?)this.systemProperties.RecordId;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ProviderName {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.ProviderName;
|
||||
}
|
||||
}
|
||||
|
||||
public override Guid? ProviderId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.ProviderId;
|
||||
}
|
||||
}
|
||||
|
||||
public override string LogName {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.ChannelName;
|
||||
}
|
||||
}
|
||||
|
||||
public override int? ProcessId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (int?)this.systemProperties.ProcessId;
|
||||
}
|
||||
}
|
||||
|
||||
public override int? ThreadId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return (int?)this.systemProperties.ThreadId;
|
||||
}
|
||||
}
|
||||
|
||||
public override string MachineName {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.ComputerName;
|
||||
}
|
||||
}
|
||||
|
||||
public override System.Security.Principal.SecurityIdentifier UserId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.UserId;
|
||||
}
|
||||
}
|
||||
|
||||
public override DateTime? TimeCreated {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.TimeCreated;
|
||||
}
|
||||
}
|
||||
|
||||
public override Guid? ActivityId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.ActivityId;
|
||||
}
|
||||
}
|
||||
|
||||
public override Guid? RelatedActivityId {
|
||||
get {
|
||||
PrepareSystemData();
|
||||
return this.systemProperties.RelatedActivityId;
|
||||
}
|
||||
}
|
||||
|
||||
public string ContainerLog {
|
||||
get {
|
||||
if (this.containerChannel != null)
|
||||
return this.containerChannel;
|
||||
lock (this.syncObject) {
|
||||
if (this.containerChannel == null) {
|
||||
this.containerChannel = (string)NativeWrapper.EvtGetEventInfo(this.Handle, UnsafeNativeMethods.EvtEventPropertyId.EvtEventPath);
|
||||
}
|
||||
return this.containerChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<int> MatchedQueryIds {
|
||||
get {
|
||||
if (this.matchedQueryIds != null)
|
||||
return this.matchedQueryIds;
|
||||
lock (this.syncObject) {
|
||||
if (this.matchedQueryIds == null) {
|
||||
this.matchedQueryIds = (int[])NativeWrapper.EvtGetEventInfo(this.Handle, UnsafeNativeMethods.EvtEventPropertyId.EvtEventQueryIDs);
|
||||
}
|
||||
return this.matchedQueryIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override EventBookmark Bookmark {
|
||||
[System.Security.SecuritySafeCritical]
|
||||
get {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
EventLogHandle bookmarkHandle = NativeWrapper.EvtCreateBookmark(null);
|
||||
NativeWrapper.EvtUpdateBookmark(bookmarkHandle, this.handle);
|
||||
string bookmarkText = NativeWrapper.EvtRenderBookmark(bookmarkHandle);
|
||||
|
||||
return new EventBookmark(bookmarkText);
|
||||
}
|
||||
}
|
||||
|
||||
public override string FormatDescription() {
|
||||
|
||||
return this.cachedMetadataInformation.GetFormatDescription(this.ProviderName, this.handle);
|
||||
}
|
||||
|
||||
public override string FormatDescription(IEnumerable<object> values) {
|
||||
if (values == null) return this.FormatDescription();
|
||||
|
||||
//copy the value IEnumerable to an array.
|
||||
string[] theValues = new string[0];
|
||||
int i = 0;
|
||||
foreach (object o in values) {
|
||||
if ( theValues.Length == i )
|
||||
Array.Resize( ref theValues, i+1 );
|
||||
theValues[i] = o.ToString();
|
||||
i++;
|
||||
}
|
||||
|
||||
return this.cachedMetadataInformation.GetFormatDescription(this.ProviderName, this.handle, theValues);
|
||||
}
|
||||
|
||||
public override string LevelDisplayName {
|
||||
get {
|
||||
if ( this.levelNameReady )
|
||||
return this.levelName;
|
||||
lock (this.syncObject) {
|
||||
if (this.levelNameReady == false) {
|
||||
this.levelNameReady = true;
|
||||
this.levelName = this.cachedMetadataInformation.GetLevelDisplayName(this.ProviderName, this.handle);
|
||||
}
|
||||
return this.levelName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string OpcodeDisplayName {
|
||||
get {
|
||||
lock (this.syncObject) {
|
||||
if (this.opcodeNameReady == false) {
|
||||
this.opcodeNameReady = true;
|
||||
this.opcodeName = this.cachedMetadataInformation.GetOpcodeDisplayName(this.ProviderName, this.handle);
|
||||
|
||||
}
|
||||
return this.opcodeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string TaskDisplayName {
|
||||
get {
|
||||
if (this.taskNameReady == true)
|
||||
return this.taskName;
|
||||
lock (this.syncObject) {
|
||||
if (this.taskNameReady == false) {
|
||||
this.taskNameReady = true;
|
||||
this.taskName = this.cachedMetadataInformation.GetTaskDisplayName(this.ProviderName, this.handle);
|
||||
}
|
||||
return this.taskName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<string> KeywordsDisplayNames {
|
||||
get {
|
||||
if (this.keywordsNames != null)
|
||||
return this.keywordsNames;
|
||||
lock (this.syncObject) {
|
||||
if (this.keywordsNames == null) {
|
||||
this.keywordsNames = this.cachedMetadataInformation.GetKeywordDisplayNames(this.ProviderName, this.handle);
|
||||
}
|
||||
return this.keywordsNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override IList<EventProperty> Properties {
|
||||
get {
|
||||
this.session.SetupUserContext();
|
||||
IList<object> properties = NativeWrapper.EvtRenderBufferWithContextUserOrValues(this.session.renderContextHandleUser, this.handle);
|
||||
List<EventProperty> list = new List<EventProperty>();
|
||||
foreach (object value in properties) {
|
||||
list.Add(new EventProperty(value));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<object> GetPropertyValues(EventLogPropertySelector propertySelector) {
|
||||
if (propertySelector == null)
|
||||
throw new ArgumentNullException("propertySelector");
|
||||
return NativeWrapper.EvtRenderBufferWithContextUserOrValues(propertySelector.Handle, this.handle);
|
||||
}
|
||||
|
||||
// marked as SecurityCritical because it allocates SafeHandle
|
||||
// marked as TreatAsSafe because it performs Demand.
|
||||
[System.Security.SecuritySafeCritical]
|
||||
public override string ToXml() {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
StringBuilder renderBuffer = new StringBuilder(2000);
|
||||
NativeWrapper.EvtRender(EventLogHandle.Zero, this.handle, UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventXml, renderBuffer);
|
||||
return renderBuffer.ToString();
|
||||
}
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
protected override void Dispose(bool disposing) {
|
||||
try {
|
||||
|
||||
if (disposing) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
}
|
||||
|
||||
if ( this.handle != null && !this.handle.IsInvalid )
|
||||
this.handle.Dispose();
|
||||
}
|
||||
finally {
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
// marked as SecurityCritical because allocates SafeHandle.
|
||||
[System.Security.SecurityCritical]
|
||||
internal static EventLogHandle GetBookmarkHandleFromBookmark(EventBookmark bookmark) {
|
||||
if (bookmark == null)
|
||||
return EventLogHandle.Zero;
|
||||
EventLogHandle handle = NativeWrapper.EvtCreateBookmark(bookmark.BookmarkText);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: EventLogSession
|
||||
**
|
||||
** Purpose:
|
||||
** Defines a session for Event Log operations. The session can
|
||||
** be configured for a remote machine and can use specfic
|
||||
** user credentials.
|
||||
============================================================*/
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32;
|
||||
using System.Globalization;
|
||||
|
||||
namespace System.Diagnostics.Eventing.Reader {
|
||||
/// <summary>
|
||||
/// Session Login Type
|
||||
/// </summary>
|
||||
public enum SessionAuthentication {
|
||||
Default = 0,
|
||||
Negotiate = 1,
|
||||
Kerberos = 2,
|
||||
Ntlm = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type: log / external log file to query
|
||||
/// </summary>
|
||||
public enum PathType
|
||||
{
|
||||
LogName = 1,
|
||||
FilePath = 2
|
||||
}
|
||||
|
||||
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
|
||||
public class EventLogSession : IDisposable {
|
||||
//
|
||||
//the two context handles for rendering (for EventLogRecord).
|
||||
//the system and user context handles. They are both common for all the event instances and can be created only once.
|
||||
//access to the data member references is safe, while
|
||||
//invoking methods on it is marked SecurityCritical as appropriate.
|
||||
//
|
||||
internal EventLogHandle renderContextHandleSystem = EventLogHandle.Zero;
|
||||
internal EventLogHandle renderContextHandleUser = EventLogHandle.Zero;
|
||||
|
||||
//the dummy [....] object for the two contextes.
|
||||
private object syncObject = null;
|
||||
|
||||
private string server;
|
||||
private string user;
|
||||
private string domain;
|
||||
private SessionAuthentication logOnType;
|
||||
//we do not maintain the password here.
|
||||
|
||||
//
|
||||
//access to the data member references is safe, while
|
||||
//invoking methods on it is marked SecurityCritical as appropriate.
|
||||
//
|
||||
private EventLogHandle handle = EventLogHandle.Zero;
|
||||
|
||||
|
||||
//setup the System Context, once for all the EventRecords.
|
||||
[System.Security.SecuritySafeCritical]
|
||||
internal void SetupSystemContext() {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
if (!this.renderContextHandleSystem.IsInvalid)
|
||||
return;
|
||||
lock (this.syncObject) {
|
||||
if (this.renderContextHandleSystem.IsInvalid) {
|
||||
//create the SYSTEM render context
|
||||
//call the EvtCreateRenderContext to get the renderContextHandleSystem, so that we can get the system/values/user properties.
|
||||
this.renderContextHandleSystem = NativeWrapper.EvtCreateRenderContext(0, null, UnsafeNativeMethods.EvtRenderContextFlags.EvtRenderContextSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
internal void SetupUserContext() {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
lock (this.syncObject) {
|
||||
if (this.renderContextHandleUser.IsInvalid) {
|
||||
//create the USER render context
|
||||
this.renderContextHandleUser = NativeWrapper.EvtCreateRenderContext(0, null, UnsafeNativeMethods.EvtRenderContextFlags.EvtRenderContextUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// marked as SecurityCritical because allocates SafeHandle.
|
||||
// marked as TreatAsSafe because performs Demand().
|
||||
[System.Security.SecurityCritical]
|
||||
public EventLogSession() {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
//handle = EventLogHandle.Zero;
|
||||
syncObject = new object();
|
||||
}
|
||||
|
||||
public EventLogSession(string server)
|
||||
:
|
||||
this(server, null, null, (SecureString)null, SessionAuthentication.Default) {
|
||||
}
|
||||
|
||||
// marked as TreatAsSafe because performs Demand().
|
||||
[System.Security.SecurityCritical]
|
||||
public EventLogSession(string server, string domain, string user, SecureString password, SessionAuthentication logOnType) {
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
if (server == null)
|
||||
server = "localhost";
|
||||
|
||||
syncObject = new object();
|
||||
|
||||
this.server = server;
|
||||
this.domain = domain;
|
||||
this.user = user;
|
||||
this.logOnType = logOnType;
|
||||
|
||||
UnsafeNativeMethods.EvtRpcLogin erLogin = new UnsafeNativeMethods.EvtRpcLogin();
|
||||
erLogin.Server = this.server;
|
||||
erLogin.User = this.user;
|
||||
erLogin.Domain = this.domain;
|
||||
erLogin.Flags = (int)this.logOnType;
|
||||
erLogin.Password = CoTaskMemUnicodeSafeHandle.Zero;
|
||||
|
||||
try {
|
||||
if (password != null)
|
||||
erLogin.Password.SetMemory(Marshal.SecureStringToCoTaskMemUnicode(password));
|
||||
//open a session using the erLogin structure.
|
||||
handle = NativeWrapper.EvtOpenSession(UnsafeNativeMethods.EvtLoginClass.EvtRpcLogin, ref erLogin, 0, 0);
|
||||
}
|
||||
finally {
|
||||
erLogin.Password.Close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal EventLogHandle Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
[System.Security.SecuritySafeCritical]
|
||||
protected virtual void Dispose(bool disposing) {
|
||||
|
||||
if (disposing) {
|
||||
if ( this == globalSession )
|
||||
throw new InvalidOperationException();
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
}
|
||||
|
||||
if (this.renderContextHandleSystem != null &&
|
||||
!this.renderContextHandleSystem.IsInvalid)
|
||||
this.renderContextHandleSystem.Dispose();
|
||||
|
||||
if (this.renderContextHandleUser != null &&
|
||||
!this.renderContextHandleUser.IsInvalid)
|
||||
this.renderContextHandleUser.Dispose();
|
||||
|
||||
if (handle != null && !handle.IsInvalid)
|
||||
handle.Dispose();
|
||||
}
|
||||
|
||||
public void CancelCurrentOperations() {
|
||||
|
||||
NativeWrapper.EvtCancel(handle);
|
||||
}
|
||||
|
||||
static EventLogSession globalSession = new EventLogSession();
|
||||
public static EventLogSession GlobalSession {
|
||||
get { return globalSession; }
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public IEnumerable<string> GetProviderNames()
|
||||
{
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
List<string> namesList = new List<string>(100);
|
||||
|
||||
using (EventLogHandle ProviderEnum = NativeWrapper.EvtOpenProviderEnum(this.Handle, 0))
|
||||
{
|
||||
bool finish = false;
|
||||
|
||||
do
|
||||
{
|
||||
string s = NativeWrapper.EvtNextPublisherId(ProviderEnum, ref finish);
|
||||
if (finish == false) namesList.Add(s);
|
||||
}
|
||||
while (finish == false);
|
||||
|
||||
return namesList;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
public IEnumerable<string> GetLogNames()
|
||||
{
|
||||
EventLogPermissionHolder.GetEventLogPermission().Demand();
|
||||
|
||||
List<string> namesList = new List<string>(100);
|
||||
|
||||
using (EventLogHandle channelEnum = NativeWrapper.EvtOpenChannelEnum(this.Handle, 0))
|
||||
{
|
||||
bool finish = false;
|
||||
|
||||
do
|
||||
{
|
||||
string s = NativeWrapper.EvtNextChannelPath(channelEnum, ref finish);
|
||||
if (finish == false) namesList.Add(s);
|
||||
}
|
||||
while (finish == false);
|
||||
|
||||
return namesList;
|
||||
}
|
||||
}
|
||||
|
||||
public EventLogInformation GetLogInformation(string logName, PathType pathType) {
|
||||
if (logName == null)
|
||||
throw new ArgumentNullException("logName");
|
||||
|
||||
return new EventLogInformation(this, logName, pathType);
|
||||
}
|
||||
|
||||
public void ExportLog(string path, PathType pathType, string query, string targetFilePath) {
|
||||
this.ExportLog(path, pathType, query, targetFilePath, false);
|
||||
}
|
||||
|
||||
public void ExportLog(string path, PathType pathType, string query, string targetFilePath, bool tolerateQueryErrors)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
if (targetFilePath == null)
|
||||
throw new ArgumentNullException("targetFilePath");
|
||||
|
||||
UnsafeNativeMethods.EvtExportLogFlags flag;
|
||||
switch (pathType)
|
||||
{
|
||||
case PathType.LogName:
|
||||
flag = UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogChannelPath;
|
||||
break;
|
||||
case PathType.FilePath:
|
||||
flag = UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogFilePath;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("pathType");
|
||||
}
|
||||
|
||||
if (tolerateQueryErrors == false)
|
||||
NativeWrapper.EvtExportLog(this.Handle, path, query, targetFilePath, (int)flag);
|
||||
else
|
||||
NativeWrapper.EvtExportLog(this.Handle, path, query, targetFilePath, (int)flag | (int)UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogTolerateQueryErrors);
|
||||
}
|
||||
|
||||
public void ExportLogAndMessages(string path, PathType pathType, string query, string targetFilePath)
|
||||
{
|
||||
this.ExportLogAndMessages(path, pathType, query, targetFilePath, false, CultureInfo.CurrentCulture );
|
||||
}
|
||||
|
||||
public void ExportLogAndMessages(string path, PathType pathType, string query, string targetFilePath, bool tolerateQueryErrors, CultureInfo targetCultureInfo ) {
|
||||
if (targetCultureInfo == null)
|
||||
targetCultureInfo = CultureInfo.CurrentCulture;
|
||||
ExportLog(path, pathType, query, targetFilePath, tolerateQueryErrors);
|
||||
NativeWrapper.EvtArchiveExportedLog(this.Handle, targetFilePath, targetCultureInfo.LCID, 0);
|
||||
}
|
||||
|
||||
public void ClearLog(string logName)
|
||||
{
|
||||
this.ClearLog(logName, null);
|
||||
}
|
||||
|
||||
public void ClearLog(string logName, string backupPath)
|
||||
{
|
||||
if (logName == null)
|
||||
throw new ArgumentNullException("logName");
|
||||
|
||||
NativeWrapper.EvtClearLog(this.Handle, logName, backupPath, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user