Reading in Crimson Logs
Crimson logs can be read in through c# by use of some bindings to the APIs. Crimson is a new logging protocol in Windows Vista.
I will start by including all the bindings to the actual apis, then talk about the specific classes than can wrap around them to get useful information out of Crimson.
This has all the crimson functions divided up into sections, when I go through each part of the session I will talk about what Crimson can support for the various types of logging.
///////////////////////////////////////////////////////////////////////////
///
/// <summary>
/// CrimsonEventLog: The structures and functions using P/Invoke for
/// accessing the CrimsonEventLog (Crimson).
/// </summary>
///
///////////////////////////////////////////////////////////////////////////
internal static class CrimsonEventLog
{
//-----------------------------------------------------------------
#region Cluster channels
internal const string ClusterChannelRoot = "Microsoft-Windows-FailoverClustering";
internal const string ClusterChannelAdmin = "Microsoft-Windows-FailoverClustering/Admin";
internal const string ClusterChannelOperational = "Microsoft-Windows-FailoverClustering/Operational";
#endregion
//-----------------------------------------------------------------
#region Utility routines
[DllImport("wevtapi.dll", EntryPoint = "EvtClose",
CallingConvention = CallingConvention.Winapi,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventClose(IntPtr handlePtr);
#if DEBUG_TEST
[DllImport( "wevtapi.dll", EntryPoint = "EvtGetExtendedStatus",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true )]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventGetExtendedStatus( int size,
StringBuilder buffer,
ref int charsWritten );
#endif
#endregion
//-----------------------------------------------------------------
#region Session routines
public enum EventLoginClass
{
EvtRpcLogin = 1
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct EventRPCLogin
{
// all str params are optional
internal String server;
internal String user;
internal String domain;
internal String password;
internal Int32 flags; // currently must be 0.
}
[DllImport("wevtapi.dll", EntryPoint = "EvtOpenSession",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern IntPtr EventOpenSession(EventLoginClass loginClass,
ref EventRPCLogin Login,
int timeout,
int flags);
#endregion
//-----------------------------------------------------------------
#region Log Maintence routines
[DllImport("wevtapi.dll", EntryPoint = "EvtClearLog",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventClearLog(EventSafeHandle sessionHandle,
string path,
string targetPath,
int flags);
public enum EventExportLogFlags
{
ChannelPath = 1,
LogFilePath = 2
};
[DllImport("wevtapi.dll", EntryPoint = "EvtExportLog",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventExportLog(EventSafeHandle sessionHandle,
string path,
string query,
string targetPath,
[MarshalAs(UnmanagedType.I4)]EventExportLogFlags flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtArchiveExportedLog",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventArchiveLog(EventSafeHandle sessionHandle,
string path,
int lcid,
int flags);
public enum EventLogOpenFlags
{
ChannelPath = 1,
FilePath = 2
};
[DllImport("wevtapi.dll", EntryPoint = "EvtOpenLog",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern IntPtr EventOpenLog(EventSafeHandle sessionHandle,
string path,
[MarshalAs(UnmanagedType.I4)]EventLogOpenFlags flags);
public enum EventLogPropertyId
{
CreationTime = 0,
LastAccessTime = 1,
LastWriteTime = 2,
FileSize = 3,
Attributes = 4,
NumberOfLogRecords = 5,
OldestRecordNumber = 6,
Full = 7
};
[DllImport("wevtapi.dll", EntryPoint = "EvtGetLogInfo",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventGetLogInfo(EventSafeHandle logHandle,
[MarshalAs(UnmanagedType.I4)]EventLogPropertyId propId,
int bufferSize,
ref EventVariant propertyValueBuffer,
ref int propertyValueBufferUsed);
#endregion
//-----------------------------------------------------------------
#region Subscription routines
public enum EventSubscribeFlags
{
EvtSubscribeToFutureEvents = 0x1,
EvtSubscribeStartAtOldestRecord = 0x2,
EvtSubscribeStartAfterBookmark = 0x3,
EvtSubscribeInternal = 0x4
}
public enum EventSubscribeNotifyAction
{
EvtSubscribeActionError = 0x0,
EvtSubscribeActionDeliver = 0x1
}
public enum EventEventPropertyId
{
EvtEventQueryIDs = 0x0,
EvtEventPath = 0x1
}
public delegate Int32 EventSubscribeCallback([MarshalAs(UnmanagedType.I4)]EventSubscribeNotifyAction action,
IntPtr context,
IntPtr eventPtr);
[DllImport("wevtapi.dll", EntryPoint = "EvtSubscribe",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern IntPtr EventSubscribe(EventSafeHandle sessionHandle,
IntPtr signalEvent,
String channelPath,
String query,
IntPtr bookMark,
IntPtr context,
[MarshalAs(UnmanagedType.I4)]EventSubscribeCallback eventCallback,
int flags);
#endregion
//-----------------------------------------------------------------
#region Query routines
public enum EventQueryFlags
{
EvtQueryChannelPath = 0x1,
EvtQueryFilePath = 0x2,
EvtQueryForwardDirection = 0x100,
EvtQueryReverseDirection = 0x200,
}
[DllImport("wevtapi.dll", EntryPoint = "EvtQuery", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr EventQuery(
EventSafeHandle sessionHandle,
String path,
String query,
[MarshalAs(UnmanagedType.I4)]EventQueryFlags flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtNext", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EventNext(
EventSafeHandle resultSet,
int eventsSize,
IntPtr[] events,
int timeout,
int flags,
ref int returned);
#endregion
//-----------------------------------------------------------------
#region Channel enumeration routines
[DllImport("wevtapi.dll", EntryPoint = "EvtOpenChannelEnum", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr EventOpenChannelEnum(
EventSafeHandle session,
int flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtNextChannelPath", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EventNextChannelPath(
EventSafeHandle channelEnum,
int channelPathBufferSize,
StringBuilder channelPathBuffer,
out int channelPathBufferUsed);
#endregion
//-----------------------------------------------------------------
#region Channel config routines
public enum ChannelConfigPropertyID
{
ChannelConfigEnabled = 0,
ChannelConfigIsolation = 1,
ChannelConfigType = 2,
ChannelConfigIsClassicChannel = 3,
ChannelConfigAccess = 4,
ChannelLoggingConfigRetention = 5,
ChannelLoggingConfigAutoBackup = 6,
ChannelLoggingConfigMaxSize = 7,
ChannelLoggingConfigLogFilePath = 8,
ChannelPublishingConfigLevel = 9,
ChannelPublishingConfigKeywords = 10,
ChannelPublishingConfigControlGuid = 11,
ChannelConfigPropertyIdEND
};
public enum ChannelType
{
Admin = 0,
Operational = 1,
Analytic = 2,
Debug = 3,
Unknown = 4
};
[DllImport("wevtapi.dll", EntryPoint = "EvtOpenChannelConfig", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr EventOpenChannelConfig(
EventSafeHandle session,
string channelPath,
int flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtGetChannelConfigProperty", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EventGetChannelConfigProperty(
EventSafeHandle channelConfig,
[MarshalAs(UnmanagedType.I4)]ChannelConfigPropertyID propertyId,
int flags,
int propertyValueBufferSize,
ref EventVariant propertyValueBuffer,
out int propertyValueBufferUsed);
[DllImport("wevtapi.dll", EntryPoint = "EvtSetChannelConfigProperty", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EventSetChannelConfigProperty(
EventSafeHandle channelConfig,
[MarshalAs(UnmanagedType.I4)]ChannelConfigPropertyID propertyId,
int flags,
ref EventVariant propertyValueBuffer);
[DllImport("wevtapi.dll", EntryPoint = "EvtSaveChannelConfig", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EventSaveChannelConfig(
EventSafeHandle channelConfig,
int Flags
);
#endregion
//-----------------------------------------------------------------
#region Rendering routines
public enum EventRenderContextFlags
{
EvtRenderContextValues = 0x0, // Render specific properties
EvtRenderContextSystem = 0x1, // Render all system properties (System)
EvtRenderContextUser = 0x2 // Render all user properties (User/EventData)
}
public enum EventRenderFlags
{
EvtRenderEventValues = 0x0, // Variants
EvtRenderEventXml = 0x1, // System properties, ForwardingInfo, User/EventData
EvtRenderBookmark = 0x2
}
[DllImport("wevtapi.dll", EntryPoint = "EvtCreateRenderContext",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern IntPtr EventCreateRenderContext(Int32 countOfValues,
String[] valuePaths,
Int32 flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtRender",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventRender(IntPtr context,
PushEventHandle eventHandle,
int flags,
int buffSize,
byte[] buffer,
ref int buffUsed,
ref int propCount);
#if DEBUG_TEST
[DllImport( "wevtapi.dll", EntryPoint = "EvtRender",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true )]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventRender( IntPtr context,
PushEventHandle eventHandle,
int flags,
int buffSize,
StringBuilder buffer,
ref int buffUsed,
ref int propCount );
#endif
#endregion
//-----------------------------------------------------------------
#region Formatting routines
public enum EventFormatMessageFlags
{
EvtFormatMessageEvent = 0x1,
EvtFormatMessageLevel = 0x2,
EvtFormatMessageTask = 0x3,
EvtFormatMessageOpcode = 0x4,
EvtFormatMessageKeyword = 0x5
}
[DllImport("wevtapi.dll", EntryPoint = "EvtFormatMessage",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EventFormatMessage(EventSafeHandle publisherHandle,
PushEventHandle eventHandle,
int messageId,
int valueCount,
[In] byte[] valueBuffer,
int flags,
int buffSize,
StringBuilder buffer,
ref int buffUsed);
#endregion
//-----------------------------------------------------------------
#region Publisher routines
internal enum EventPublisherMetadataId
{
EvtPublisherMetadataPublisherGuid = 0, // EvtVarTypeGuid
EvtPublisherMetadataResourceFilePath, // EvtVarTypeString
EvtPublisherMetadataParameterFilePath, // EvtVarTypeString
EvtPublisherMetadataMessageFilePath, // EvtVarTypeString
EvtPublisherMetadataHelpLink, // EvtVarTypeString
EvtPublisherMetadataPublisherMessageID, // EvtVarTypeUInt32
EvtPublisherMetadataChannelReferences, // EvtVarTypeEvtHandle, ObjectArray
EvtPublisherMetadataChannelReferencePath, // EvtVarTypeString
EvtPublisherMetadataChannelReferenceIndex, // EvtVarTypeUInt32
EvtPublisherMetadataChannelReferenceID, // EvtVarTypeUInt32
EvtPublisherMetadataChannelReferenceFlags, // EvtVarTypeUInt32
EvtPublisherMetadataChannelReferenceMessageID, // EvtVarTypeUInt32
EvtPublisherMetadataLevels, // EvtVarTypeEvtHandle, ObjectArray
EvtPublisherMetadataLevelName, // EvtVarTypeString
EvtPublisherMetadataLevelValue, // EvtVarTypeUInt32
EvtPublisherMetadataLevelMessageID, // EvtVarTypeUInt32
EvtPublisherMetadataTasks, // EvtVarTypeEvtHandle, ObjectArray
EvtPublisherMetadataTaskName, // EvtVarTypeString
EvtPublisherMetadataTaskEventGuid, // EvtVarTypeGuid
EvtPublisherMetadataTaskValue, // EvtVarTypeUInt32
EvtPublisherMetadataTaskMessageID, // EvtVarTypeUInt32
EvtPublisherMetadataOpcodes, // EvtVarTypeEvtHandle, ObjectArray
EvtPublisherMetadataOpcodeName, // EvtVarTypeString
EvtPublisherMetadataOpcodeValue, // EvtVarTypeUInt32
EvtPublisherMetadataOpcodeMessageID, // EvtVarTypeUInt32
EvtPublisherMetadataKeywords, // EvtVarTypeEvtHandle, ObjectArray
EvtPublisherMetadataKeywordName, // EvtVarTypeString
EvtPublisherMetadataKeywordValue, // EvtVarTypeUInt64
EvtPublisherMetadataKeywordMessageID, // EvtVarTypeUInt32
};
[DllImport("wevtapi.dll", EntryPoint = "EvtOpenPublisherMetadata",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern IntPtr EventOpenPublisherMetadata(EventSafeHandle sessionHandle,
string publisherId,
string logFilePath,
int locale,
int flags);
[DllImport("wevtapi.dll", EntryPoint = "EvtGetPublisherMetadataProperty",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventGetPublisherMetadataProperty(
EventSafeHandle publisherHandle,
[MarshalAs(UnmanagedType.I4)]EventPublisherMetadataId propId,
int flags,
int buffsize,
ref EventVariant buffer,
ref int buffUsed);
[DllImport("wevtapi.dll", EntryPoint = "EvtGetObjectArraySize",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventGetObjectArraySize(PushEventHandle arrayHandle,
ref int count);
[DllImport("wevtapi.dll", EntryPoint = "EvtGetObjectArrayProperty",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventGetObjectArrayProperty(
PushEventHandle arrayHandle,
[MarshalAs(UnmanagedType.I4)]EventPublisherMetadataId propId,
int arrayIndex,
int flags,
int buffSize,
ref EventVariant buffer,
ref int buffUsed);
[DllImport("wevtapi.dll", EntryPoint = "EvtGetObjectArrayProperty",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool EventGetObjectArrayProperty(
PushEventHandle arrayHandle,
[MarshalAs(UnmanagedType.I4)]EventPublisherMetadataId propId,
int arrayIndex,
int flags,
int buffSize,
ref EventVariantString buffer,
ref int buffUsed);
#endregion
//-----------------------------------------------------------------
#region Variant structures
public enum EventVariantType
{
EvtVarTypeNull = 0,
EvtVarTypeString = 1,
EvtVarTypeAnsiString = 2,
EvtVarTypeSByte = 3,
EvtVarTypeByte = 4,
EvtVarTypeInt16 = 5,
EvtVarTypeUInt16 = 6,
EvtVarTypeInt32 = 7,
EvtVarTypeUInt32 = 8,
EvtVarTypeInt64 = 9,
EvtVarTypeUInt64 = 10,
EvtVarTypeSingle = 11,
EvtVarTypeDouble = 12,
EvtVarTypeBoolean = 13,
EvtVarTypeBinary = 14,
EvtVarTypeGuid = 15,
EvtVarTypeSizeT = 16,
EvtVarTypeFileTime = 17,
EvtVarTypeSysTime = 18,
EvtVarTypeSid = 19,
EvtVarTypeHexInt32 = 20,
EvtVarTypeHexInt64 = 21,
// These types used internally
EvtVarTypeEvtHandle = 32,
EvtVarTypeEvtXml = 35
}
public enum EventVariantTypeMask
{
EvtVarTypeMask = 0x7f,
EvtVarTypeArray = 128
}
//Commenting some members to reduce the number
// of fxcop errors
[ComVisible(false)]
[StructLayout(LayoutKind.Explicit)]
unsafe public struct EventVariant
{
[FieldOffset(0)]
public int BooleanVal;
[FieldOffset(0)]
public sbyte SByteVal;
[FieldOffset(0)]
public Int16 Int16Val;
[FieldOffset(0)]
public Int32 Int32Val;
[FieldOffset(0)]
public Int64 Int64Val;
[FieldOffset(0)]
public byte ByteVal;
[FieldOffset(0)]
public UInt16 UInt16Val;
[FieldOffset(0)]
public UInt32 UInt32Val;
[FieldOffset(0)]
public UInt64 UInt64Val;
[FieldOffset(0)]
public float SingleVal;
[FieldOffset(0)]
public double DoubleVal;
[FieldOffset(0)]
public UInt64 FileTimeVal;
[FieldOffset(0)]
public UInt64 SysTimeVal;
[FieldOffset(0)]
public IntPtr ByteArr;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
[FieldOffset(0)]
public IntPtr StringVal;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
[FieldOffset(0)]
public IntPtr SidVal;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
[FieldOffset(0)]
public IntPtr EvtHandleVal;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
[FieldOffset(8)]
public int ItemCount; // number of elements (not length) in bytes.
[FieldOffset(12)]
public int Type;
}
/// <summary>
/// Use this structure to deal with variants that require strings.
/// </summary>
[ComVisible(false)]
[StructLayout(LayoutKind.Explicit)]
unsafe public struct EventVariantString
{
[FieldOffset(0)]
public EventVariant var;
[FieldOffset(16)]
public fixed byte data[2000];
}
#endregion
//-----------------------------------------------------------------
}