217 lines
7.7 KiB
C#
217 lines
7.7 KiB
C#
using Microsoft.SharePoint.Administration;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
namespace SPSolutions.SharePoint.Logging
|
|
{
|
|
public static class TraceProvider
|
|
{
|
|
private static class NativeMethods
|
|
{
|
|
internal enum TraceFlags
|
|
{
|
|
TRACE_FLAG_START = 1,
|
|
TRACE_FLAG_END,
|
|
TRACE_FLAG_MIDDLE,
|
|
TRACE_FLAG_ID_AS_ASCII
|
|
}
|
|
internal struct EVENT_TRACE_HEADER_CLASS
|
|
{
|
|
internal byte Type;
|
|
internal byte Level;
|
|
internal ushort Version;
|
|
}
|
|
internal struct EVENT_TRACE_HEADER
|
|
{
|
|
internal ushort Size;
|
|
internal ushort FieldTypeFlags;
|
|
internal TraceProvider.NativeMethods.EVENT_TRACE_HEADER_CLASS Class;
|
|
internal uint ThreadId;
|
|
internal uint ProcessId;
|
|
internal long TimeStamp;
|
|
internal Guid Guid;
|
|
internal uint ClientContext;
|
|
internal uint Flags;
|
|
}
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
internal struct ULSTraceHeader
|
|
{
|
|
internal ushort Size;
|
|
internal uint dwVersion;
|
|
internal uint Id;
|
|
internal Guid correlationID;
|
|
internal TraceProvider.NativeMethods.TraceFlags dwFlags;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
internal string wzExeName;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
internal string wzProduct;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
internal string wzCategory;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 800)]
|
|
internal string wzMessage;
|
|
}
|
|
internal struct ULSTrace
|
|
{
|
|
internal TraceProvider.NativeMethods.EVENT_TRACE_HEADER Header;
|
|
internal TraceProvider.NativeMethods.ULSTraceHeader ULSHeader;
|
|
}
|
|
internal enum WMIDPREQUESTCODE
|
|
{
|
|
WMI_GET_ALL_DATA,
|
|
WMI_GET_SINGLE_INSTANCE,
|
|
WMI_SET_SINGLE_INSTANCE,
|
|
WMI_SET_SINGLE_ITEM,
|
|
WMI_ENABLE_EVENTS,
|
|
WMI_DISABLE_EVENTS,
|
|
WMI_ENABLE_COLLECTION,
|
|
WMI_DISABLE_COLLECTION,
|
|
WMI_REGINFO,
|
|
WMI_EXECUTE_METHOD
|
|
}
|
|
internal unsafe delegate uint EtwProc(TraceProvider.NativeMethods.WMIDPREQUESTCODE requestCode, IntPtr requestContext, uint* bufferSize, IntPtr buffer);
|
|
internal const int TRACE_VERSION_CURRENT = 1;
|
|
internal const int ERROR_SUCCESS = 0;
|
|
internal const int ERROR_INVALID_PARAMETER = 87;
|
|
internal const int WNODE_FLAG_TRACED_GUID = 131072;
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
|
|
internal unsafe static extern uint RegisterTraceGuids([In] TraceProvider.NativeMethods.EtwProc cbFunc, [In] void* context, [In] ref Guid controlGuid, [In] uint guidCount, IntPtr guidReg, [In] string mofImagePath, [In] string mofResourceName, out ulong regHandle);
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
|
|
internal static extern uint UnregisterTraceGuids([In] ulong regHandle);
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
|
|
internal static extern ulong GetTraceLoggerHandle([In] IntPtr Buffer);
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
internal static extern uint TraceEvent([In] ulong traceHandle, [In] ref TraceProvider.NativeMethods.ULSTrace evnt);
|
|
}
|
|
public enum TraceSeverity
|
|
{
|
|
Unassigned,
|
|
CriticalEvent,
|
|
WarningEvent,
|
|
InformationEvent,
|
|
Exception,
|
|
Assert = 7,
|
|
Unexpected = 10,
|
|
Monitorable = 15,
|
|
High = 20,
|
|
Medium = 50,
|
|
Verbose = 100
|
|
}
|
|
private static ulong hTraceLog;
|
|
private static ulong hTraceReg;
|
|
public static void WriteTrace(uint tag, TraceProvider.TraceSeverity level, Guid correlationGuid, string exeName, string productName, string categoryName, string message)
|
|
{
|
|
TraceProvider.NativeMethods.ULSTrace uLSTrace = default(TraceProvider.NativeMethods.ULSTrace);
|
|
uLSTrace.Header.Size = (ushort)Marshal.SizeOf(typeof(TraceProvider.NativeMethods.ULSTrace));
|
|
uLSTrace.Header.Flags = 131072u;
|
|
uLSTrace.ULSHeader.dwVersion = 1u;
|
|
uLSTrace.ULSHeader.dwFlags = TraceProvider.NativeMethods.TraceFlags.TRACE_FLAG_ID_AS_ASCII;
|
|
uLSTrace.ULSHeader.Size = (ushort)Marshal.SizeOf(typeof(TraceProvider.NativeMethods.ULSTraceHeader));
|
|
uLSTrace.ULSHeader.Id = tag;
|
|
uLSTrace.Header.Class.Level = (byte)level;
|
|
uLSTrace.ULSHeader.wzExeName = exeName;
|
|
uLSTrace.ULSHeader.wzProduct = productName;
|
|
uLSTrace.ULSHeader.wzCategory = categoryName;
|
|
uLSTrace.ULSHeader.wzMessage = message;
|
|
uLSTrace.ULSHeader.correlationID = correlationGuid;
|
|
if (message.Length < 800)
|
|
{
|
|
ushort num = (ushort)((800 - (message.Length + 1)) * 2);
|
|
uLSTrace.Header.Size = (ushort)(uLSTrace.Header.Size - num);
|
|
uLSTrace.ULSHeader.Size = (ushort)(uLSTrace.ULSHeader.Size - num);
|
|
}
|
|
if (TraceProvider.hTraceLog != 0uL)
|
|
{
|
|
TraceProvider.NativeMethods.TraceEvent(TraceProvider.hTraceLog, ref uLSTrace);
|
|
}
|
|
}
|
|
public static void WriteMultiLineTrace(uint tag, TraceProvider.TraceSeverity level, Guid correlationGuid, string exeName, string productName, string categoryName, string message)
|
|
{
|
|
int num = 700;
|
|
int i = 0;
|
|
int num2 = 1;
|
|
if (message.Length <= num)
|
|
{
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, message);
|
|
return;
|
|
}
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, string.Format("{0}", message.Substring(i, num)));
|
|
int num3;
|
|
for (i = num + 1; i < message.Length; i += num3)
|
|
{
|
|
if (message.Length - i >= num)
|
|
{
|
|
num3 = num;
|
|
}
|
|
else
|
|
{
|
|
num3 = message.Length - i;
|
|
}
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, string.Format("{0}...{1}", num2, message.Substring(i, num3)));
|
|
num2++;
|
|
}
|
|
}
|
|
public static void WriteMultiLineTrace(uint tag, TraceProvider.TraceSeverity level, Guid correlationGuid, string exeName, string productName, string categoryName, string lineheader, string message)
|
|
{
|
|
int num = 700;
|
|
int i = 0;
|
|
int num2 = 1;
|
|
if (message.Length <= num)
|
|
{
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, message);
|
|
return;
|
|
}
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, string.Format("{0}0...{1}", lineheader, message.Substring(i, num)));
|
|
int num3;
|
|
for (i = num + 1; i < message.Length; i += num3)
|
|
{
|
|
if (message.Length - i >= num)
|
|
{
|
|
num3 = num;
|
|
}
|
|
else
|
|
{
|
|
num3 = message.Length - i;
|
|
}
|
|
TraceProvider.WriteTrace(tag, level, correlationGuid, exeName, productName, categoryName, string.Format("{0}{1}...{2}", lineheader, num2, message.Substring(i, num3)));
|
|
num2++;
|
|
}
|
|
}
|
|
public static void RegisterTraceProvider()
|
|
{
|
|
SPFarm local = SPFarm.Local;
|
|
Guid traceSessionGuid = local.TraceSessionGuid;
|
|
unsafe
|
|
{
|
|
TraceProvider.NativeMethods.RegisterTraceGuids(new TraceProvider.NativeMethods.EtwProc(TraceProvider.ControlCallback), null, ref traceSessionGuid, 0u, IntPtr.Zero, null, null, out TraceProvider.hTraceReg);
|
|
}
|
|
}
|
|
public static void UnregisterTraceProvider()
|
|
{
|
|
TraceProvider.NativeMethods.UnregisterTraceGuids(TraceProvider.hTraceReg);
|
|
}
|
|
public static uint TagFromString(string wzTag)
|
|
{
|
|
return (uint)((uint)wzTag[0] << 24 | (uint)wzTag[1] << 16 | (uint)wzTag[2] << 8 | wzTag[3]);
|
|
}
|
|
private unsafe static uint ControlCallback(TraceProvider.NativeMethods.WMIDPREQUESTCODE RequestCode, IntPtr Context, uint* InOutBufferSize, IntPtr Buffer)
|
|
{
|
|
uint result;
|
|
switch (RequestCode)
|
|
{
|
|
case TraceProvider.NativeMethods.WMIDPREQUESTCODE.WMI_ENABLE_EVENTS:
|
|
TraceProvider.hTraceLog = TraceProvider.NativeMethods.GetTraceLoggerHandle(Buffer);
|
|
result = 0u;
|
|
break;
|
|
case TraceProvider.NativeMethods.WMIDPREQUESTCODE.WMI_DISABLE_EVENTS:
|
|
TraceProvider.hTraceLog = 0uL;
|
|
result = 0u;
|
|
break;
|
|
default:
|
|
result = 87u;
|
|
break;
|
|
}
|
|
*InOutBufferSize = 0u;
|
|
return result;
|
|
}
|
|
}
|
|
}
|