Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Services / Monitoring / system / Diagnosticts / EventLogEntry.cs / 1 / EventLogEntry.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Diagnostics { using System.Text; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.ComponentModel; using System.Diagnostics; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System; using System.Security; using System.Security.Permissions; using System.IO; using System.Globalization; using System.Runtime.Versioning; ////// [ ToolboxItem(false), DesignTimeVisible(false), Serializable, ] public sealed class EventLogEntry : Component, ISerializable { internal byte[] dataBuf; internal int bufOffset; private EventLog owner; private string category; private string message; // make sure only others in this package can create us internal EventLogEntry(byte[] buf, int offset, EventLog log) { this.dataBuf = buf; this.bufOffset = offset; this.owner = log; GC.SuppressFinalize(this); } ////// ////// encapsulates a single record in the NT event log. /// /// ///private EventLogEntry(SerializationInfo info, StreamingContext context) { dataBuf = (byte[])info.GetValue("DataBuffer", typeof(byte[])); string logName = info.GetString("LogName"); string machineName = info.GetString("MachineName"); owner = new EventLog(logName, machineName, ""); GC.SuppressFinalize(this); } /// /// [MonitoringDescription(SR.LogEntryMachineName)] public string MachineName { get { // first skip over the source name int pos = bufOffset + FieldOffsets.RAWDATA; while (CharFrom(dataBuf, pos) != '\0') pos += 2; pos += 2; char ch = CharFrom(dataBuf, pos); StringBuilder buf = new StringBuilder(); while (ch != '\0') { buf.Append(ch); pos += 2; ch = CharFrom(dataBuf, pos); } return buf.ToString(); } } ////// Gets the name of the computer on which this entry was generated. /// /// ////// [ MonitoringDescription(SR.LogEntryData) ] public byte[] Data { get { int dataLen = IntFrom(dataBuf, bufOffset + FieldOffsets.DATALENGTH); byte[] data = new byte[dataLen]; Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.DATAOFFSET), data, 0, dataLen); return data; } } /* ////// Gets the binary data associated with the entry. /// /// ////// ////// Copies the binary data in the ///member into an /// array. /// /// ////// An array of type ///. /// public Byte[] getDataBytes() { Byte[] data = new Byte[rec.dataLength]; for (int i = 0; i < data.Length; i++) data[i] = new Byte(rec.buf[i]); return data; } */ /// /// [MonitoringDescription(SR.LogEntryIndex)] public int Index { get { return IntFrom(dataBuf, bufOffset + FieldOffsets.RECORDNUMBER); } } ////// Gets the index of this entry in the event /// log. /// ////// [MonitoringDescription(SR.LogEntryCategory)] public string Category { get { if (category == null) { string dllName = GetMessageLibraryNames("CategoryMessageFile"); string cat = owner.FormatMessageWrapper(dllName, (uint) CategoryNumber, null); if (cat == null) category = "(" + CategoryNumber.ToString(CultureInfo.CurrentCulture) + ")"; else category = cat; } return category; } } ////// Gets the text associated with the ///for this entry. /// /// /// [ MonitoringDescription(SR.LogEntryCategoryNumber) ] public short CategoryNumber { get { return ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTCATEGORY); } } ////// Gets the application-specific category number for this entry /// /// ////// [ MonitoringDescription(SR.LogEntryEventID), Obsolete("This property has been deprecated. Please use System.Diagnostics.EventLogEntry.InstanceId instead. http://go.microsoft.com/fwlink/?linkid=14202") ] public int EventID { get { // Apparently the top 2 bits of this number are not // always 0. Strip them so the number looks nice to the user. // The problem is, if the user were to want to call FormatMessage(), // they'd need these two bits. return IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID) & 0x3FFFFFFF; } } ////// Gets the application-specific event indentifier of this entry. /// /// ////// [MonitoringDescription(SR.LogEntryEntryType)] public EventLogEntryType EntryType { get { return(EventLogEntryType) ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTTYPE); } } ////// /// Gets the type /// of this entry. /// /// ////// [ MonitoringDescription(SR.LogEntryMessage), Editor("System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing) ] public string Message { get { if (message == null) { string dllNames = GetMessageLibraryNames("EventMessageFile"); int msgId = IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID); string msg = owner.FormatMessageWrapper(dllNames, (uint)msgId, ReplacementStrings); if (msg == null) { StringBuilder msgBuf = new StringBuilder(SR.GetString(SR.MessageNotFormatted, msgId, Source)); string[] strings = ReplacementStrings; for (int i = 0; i < strings.Length; i++) { if (i != 0) msgBuf.Append(", "); msgBuf.Append("'"); msgBuf.Append(strings[i]); msgBuf.Append("'"); } msg = msgBuf.ToString(); } else msg = ReplaceMessageParameters( msg, ReplacementStrings ); message = msg; } return message; } } ////// Gets the localized message corresponding to this event entry. /// /// ////// [MonitoringDescription(SR.LogEntrySource)] public string Source { get { StringBuilder buf = new StringBuilder(); int pos = bufOffset + FieldOffsets.RAWDATA; char ch = CharFrom(dataBuf, pos); while (ch != '\0') { buf.Append(ch); pos += 2; ch = CharFrom(dataBuf, pos); } return buf.ToString(); } } ////// Gets the name of the application that generated this event. /// ////// [MonitoringDescription(SR.LogEntryReplacementStrings)] public string[] ReplacementStrings { get { string[] strings = new string[ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS)]; int i = 0; int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET); StringBuilder buf = new StringBuilder(); while (i < strings.Length) { char ch = CharFrom(dataBuf, bufpos); if (ch != '\0') buf.Append(ch); else { strings[i] = buf.ToString(); i++; buf = new StringBuilder(); } bufpos += 2; } return strings; } } [ MonitoringDescription(SR.LogEntryResourceId), ComVisible(false) ] public Int64 InstanceId { get { return (UInt32)IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID); } } #if false internal string StringsBuffer { get { StringBuilder buf = new StringBuilder(); int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET); int i = 0; int numStrings = ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS); while (i < numStrings) { char ch = CharFrom(dataBuf, bufpos); buf.Append(ch); bufpos += 2; if (ch == '\0') i++; } return buf.ToString(); } } #endif ////// Gets the replacement strings /// associated with the entry. /// /// ////// [MonitoringDescription(SR.LogEntryTimeGenerated)] public DateTime TimeGenerated { get { return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEGENERATED)).ToLocalTime(); } } ////// Gets the time at which this event was generated, in local time. /// /// ////// [MonitoringDescription(SR.LogEntryTimeWritten)] public DateTime TimeWritten { get { return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEWRITTEN)).ToLocalTime(); } } ////// Gets /// the time at which this event was written to the log, in local time. /// /// ////// [MonitoringDescription(SR.LogEntryUserName)] public string UserName { get { int sidLen = IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDLENGTH); if (sidLen == 0) return null; byte[] sid = new byte[sidLen]; Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDOFFSET), sid, 0, sid.Length); int[] nameUse = new int[1]; char[] name = new char[1024]; char[] refDomName = new char[1024]; int[] nameLen = new int[] {1024}; int[] refDomNameLen = new int[] {1024}; bool success = UnsafeNativeMethods.LookupAccountSid(MachineName, sid, name, nameLen, refDomName, refDomNameLen, nameUse); if (!success) { return ""; // NOTE, [....]: it would be nice to return error info, but the only right way to do that // is to throw an exception. People don't want exceptions thrown in the property though. #if false if (Marshal.GetLastWin32Error() == ERROR_NONE_MAPPED) // There are some SIDs (evidently rare) that are legitimate SIDs but don't // have a mapping to a name. return ""; else throw new InvalidOperationException(SR.GetString(SR.NoAccountInfo), SharedUtils.CreateSafeWin32Exception()); #endif } StringBuilder username = new StringBuilder(); username.Append(refDomName, 0, refDomNameLen[0]); username.Append("\\"); username.Append(name, 0, nameLen[0]); return username.ToString(); } } private char CharFrom(byte[] buf, int offset) { return(char) ShortFrom(buf, offset); } ////// Gets the name /// of the user responsible for this event. /// ////// public bool Equals(EventLogEntry otherEntry) { if (otherEntry == null) return false; int ourLen = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH); int theirLen = IntFrom(otherEntry.dataBuf, otherEntry.bufOffset + FieldOffsets.LENGTH); if (ourLen != theirLen) { return false; } int min = bufOffset; int max = bufOffset + ourLen; int j = otherEntry.bufOffset; for (int i = min; i < max; i++, j++) if (dataBuf[i] != otherEntry.dataBuf[j]) { return false; } return true; } private int IntFrom(byte[] buf, int offset) { // assumes Little Endian byte order. return(unchecked((int)0xFF000000) & (buf[offset+3] << 24)) | (0xFF0000 & (buf[offset+2] << 16)) | (0xFF00 & (buf[offset+1] << 8)) | (0xFF & (buf[offset])); } // Replacing parameters '%n' in formated message using 'ParameterMessageFile' registry key. internal string ReplaceMessageParameters( String msg, string[] insertionStrings ) { int percentIdx = msg.IndexOf('%'); if ( percentIdx < 0 ) return msg; // no '%' at all int startCopyIdx = 0; // start idx of last [....] msg chars to copy int msgLength = msg.Length; StringBuilder buf = new StringBuilder(); string paramDLLNames = GetMessageLibraryNames("ParameterMessageFile"); while ( percentIdx >= 0 ) { string param = null; // Convert numeric string after '%' to paramMsgID number. int lasNumIdx = percentIdx + 1; while ( lasNumIdx < msgLength && Char.IsDigit(msg, lasNumIdx) ) lasNumIdx++; uint paramMsgID = 0; // If we can't parse it, leave the paramMsgID as zero. We'll skip the replacement and just put // the %xxxx into the final message. if (lasNumIdx != percentIdx + 1 ) UInt32.TryParse( msg.Substring(percentIdx + 1, lasNumIdx - percentIdx - 1), out paramMsgID); if ( paramMsgID != 0 ) param = owner.FormatMessageWrapper( paramDLLNames, paramMsgID, insertionStrings); if ( param != null ) { if ( percentIdx > startCopyIdx ) buf.Append(msg, startCopyIdx, percentIdx - startCopyIdx); // original chars from msg buf.Append(param); startCopyIdx = lasNumIdx; } percentIdx = msg.IndexOf('%', percentIdx + 1); } if ( msgLength - startCopyIdx > 0 ) buf.Append(msg, startCopyIdx, msgLength - startCopyIdx); // last span of original msg return buf.ToString(); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private static RegistryKey GetSourceRegKey(string logName, string source, string machineName) { RegistryKey eventKey = null; RegistryKey logKey = null; try { eventKey = EventLog.GetEventLogRegKey(machineName, false); if (eventKey == null) return null; if (logName == null) logKey = eventKey.OpenSubKey("Application", /*writable*/false); else logKey = eventKey.OpenSubKey(logName, /*writable*/false); if (logKey == null) return null; return logKey.OpenSubKey(source, /*writable*/false); } finally { if (eventKey != null) eventKey.Close(); if (logKey != null) logKey.Close(); } } // ----------------------------------------------------------------------------- // Returns DLL names list. // libRegKey can be: "EventMessageFile", "CategoryMessageFile", "ParameterMessageFile" private string GetMessageLibraryNames(string libRegKey ) { // get the value stored in the registry string fileName = null; RegistryKey regKey = null; try { regKey = GetSourceRegKey(owner.Log, Source, owner.MachineName); if (regKey != null) { if (owner.MachineName == ".") fileName = (string)regKey.GetValue(libRegKey); else fileName = (string)regKey.GetValue(libRegKey, null, RegistryValueOptions.DoNotExpandEnvironmentNames); } } finally { if (regKey != null) regKey.Close(); } if (fileName == null) return null; // convert any environment variables to their current values // (the key might have something like %systemroot% in it.) // if we're looking at a remote machine, just try to replace %systemroot% at the beginning if (owner.MachineName != ".") { if (fileName.EndsWith(EventLog.DllName, StringComparison.Ordinal)) { // if it's our EventLogMessages.dll, just use the local copy return EventLog.GetDllPath("."); } else if (String.Compare(fileName, 0, "%systemroot%", 0, 12, StringComparison.OrdinalIgnoreCase) == 0) { // the final length is: // fileName.Length + owner.MachineName.Length // + 2 for the double slash // + 7 for the \admin$ // - 12 for the %systemroot% we're removing. StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length - 3); result.Append(@"\\"); result.Append(owner.MachineName); result.Append(@"\admin$"); result.Append(fileName, 12, fileName.Length - 12); return result.ToString(); } else if (fileName[1] == ':') { StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length + 3); result.Append(@"\\"); result.Append(owner.MachineName); result.Append(@"\"); result.Append(fileName[0]); result.Append("$"); result.Append(fileName, 2, fileName.Length - 2); return result.ToString(); } else return null; } else { // no need to expand environment variables, since this is done automatically by RegistryKey.GetValue() return fileName; } } private short ShortFrom(byte[] buf, int offset) { // assumes little Endian byte order. return(short) ((0xFF00 & (buf[offset+1] << 8)) | (0xFF & buf[offset])); } ////// Performs a comparison between two event log entries. /// /// ////// /// void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { int len = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH); byte[] buf = new byte[len]; Array.Copy(dataBuf, bufOffset, buf, 0, len); info.AddValue("DataBuffer", buf, typeof(byte[])); info.AddValue("LogName", owner.Log); info.AddValue("MachineName", owner.MachineName); } ////// Saves an entry as a stream of data. /// ////// Stores the offsets from the beginning of the record to fields within the record. /// private static class FieldOffsets { /** int */ internal const int LENGTH = 0; /** int */ internal const int RESERVED = 4; /** int */ internal const int RECORDNUMBER = 8; /** int */ internal const int TIMEGENERATED = 12; /** int */ internal const int TIMEWRITTEN = 16; /** int */ internal const int EVENTID = 20; /** short */ internal const int EVENTTYPE = 24; /** short */ internal const int NUMSTRINGS = 26; /** short */ internal const int EVENTCATEGORY = 28; /** short */ internal const int RESERVEDFLAGS = 30; /** int */ internal const int CLOSINGRECORDNUMBER = 32; /** int */ internal const int STRINGOFFSET = 36; /** int */ internal const int USERSIDLENGTH = 40; /** int */ internal const int USERSIDOFFSET = 44; /** int */ internal const int DATALENGTH = 48; /** int */ internal const int DATAOFFSET = 52; /** bytes */ internal const int RAWDATA = 56; } // times in the struct are # seconds from midnight 1/1/1970. private static readonly DateTime beginningOfTime = new DateTime(1970, 1, 1, 0, 0, 0); // offsets in the struct are specified from the beginning, but we have to reference // them from the beginning of the array. This is the size of the members before that. private const int OFFSETFIXUP = 4+4+4+4+4+4+2+2+2+2+4+4+4+4+4+4; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Diagnostics { using System.Text; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.ComponentModel; using System.Diagnostics; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System; using System.Security; using System.Security.Permissions; using System.IO; using System.Globalization; using System.Runtime.Versioning; ////// [ ToolboxItem(false), DesignTimeVisible(false), Serializable, ] public sealed class EventLogEntry : Component, ISerializable { internal byte[] dataBuf; internal int bufOffset; private EventLog owner; private string category; private string message; // make sure only others in this package can create us internal EventLogEntry(byte[] buf, int offset, EventLog log) { this.dataBuf = buf; this.bufOffset = offset; this.owner = log; GC.SuppressFinalize(this); } ////// ////// encapsulates a single record in the NT event log. /// /// ///private EventLogEntry(SerializationInfo info, StreamingContext context) { dataBuf = (byte[])info.GetValue("DataBuffer", typeof(byte[])); string logName = info.GetString("LogName"); string machineName = info.GetString("MachineName"); owner = new EventLog(logName, machineName, ""); GC.SuppressFinalize(this); } /// /// [MonitoringDescription(SR.LogEntryMachineName)] public string MachineName { get { // first skip over the source name int pos = bufOffset + FieldOffsets.RAWDATA; while (CharFrom(dataBuf, pos) != '\0') pos += 2; pos += 2; char ch = CharFrom(dataBuf, pos); StringBuilder buf = new StringBuilder(); while (ch != '\0') { buf.Append(ch); pos += 2; ch = CharFrom(dataBuf, pos); } return buf.ToString(); } } ////// Gets the name of the computer on which this entry was generated. /// /// ////// [ MonitoringDescription(SR.LogEntryData) ] public byte[] Data { get { int dataLen = IntFrom(dataBuf, bufOffset + FieldOffsets.DATALENGTH); byte[] data = new byte[dataLen]; Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.DATAOFFSET), data, 0, dataLen); return data; } } /* ////// Gets the binary data associated with the entry. /// /// ////// ////// Copies the binary data in the ///member into an /// array. /// /// ////// An array of type ///. /// public Byte[] getDataBytes() { Byte[] data = new Byte[rec.dataLength]; for (int i = 0; i < data.Length; i++) data[i] = new Byte(rec.buf[i]); return data; } */ /// /// [MonitoringDescription(SR.LogEntryIndex)] public int Index { get { return IntFrom(dataBuf, bufOffset + FieldOffsets.RECORDNUMBER); } } ////// Gets the index of this entry in the event /// log. /// ////// [MonitoringDescription(SR.LogEntryCategory)] public string Category { get { if (category == null) { string dllName = GetMessageLibraryNames("CategoryMessageFile"); string cat = owner.FormatMessageWrapper(dllName, (uint) CategoryNumber, null); if (cat == null) category = "(" + CategoryNumber.ToString(CultureInfo.CurrentCulture) + ")"; else category = cat; } return category; } } ////// Gets the text associated with the ///for this entry. /// /// /// [ MonitoringDescription(SR.LogEntryCategoryNumber) ] public short CategoryNumber { get { return ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTCATEGORY); } } ////// Gets the application-specific category number for this entry /// /// ////// [ MonitoringDescription(SR.LogEntryEventID), Obsolete("This property has been deprecated. Please use System.Diagnostics.EventLogEntry.InstanceId instead. http://go.microsoft.com/fwlink/?linkid=14202") ] public int EventID { get { // Apparently the top 2 bits of this number are not // always 0. Strip them so the number looks nice to the user. // The problem is, if the user were to want to call FormatMessage(), // they'd need these two bits. return IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID) & 0x3FFFFFFF; } } ////// Gets the application-specific event indentifier of this entry. /// /// ////// [MonitoringDescription(SR.LogEntryEntryType)] public EventLogEntryType EntryType { get { return(EventLogEntryType) ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTTYPE); } } ////// /// Gets the type /// of this entry. /// /// ////// [ MonitoringDescription(SR.LogEntryMessage), Editor("System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing) ] public string Message { get { if (message == null) { string dllNames = GetMessageLibraryNames("EventMessageFile"); int msgId = IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID); string msg = owner.FormatMessageWrapper(dllNames, (uint)msgId, ReplacementStrings); if (msg == null) { StringBuilder msgBuf = new StringBuilder(SR.GetString(SR.MessageNotFormatted, msgId, Source)); string[] strings = ReplacementStrings; for (int i = 0; i < strings.Length; i++) { if (i != 0) msgBuf.Append(", "); msgBuf.Append("'"); msgBuf.Append(strings[i]); msgBuf.Append("'"); } msg = msgBuf.ToString(); } else msg = ReplaceMessageParameters( msg, ReplacementStrings ); message = msg; } return message; } } ////// Gets the localized message corresponding to this event entry. /// /// ////// [MonitoringDescription(SR.LogEntrySource)] public string Source { get { StringBuilder buf = new StringBuilder(); int pos = bufOffset + FieldOffsets.RAWDATA; char ch = CharFrom(dataBuf, pos); while (ch != '\0') { buf.Append(ch); pos += 2; ch = CharFrom(dataBuf, pos); } return buf.ToString(); } } ////// Gets the name of the application that generated this event. /// ////// [MonitoringDescription(SR.LogEntryReplacementStrings)] public string[] ReplacementStrings { get { string[] strings = new string[ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS)]; int i = 0; int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET); StringBuilder buf = new StringBuilder(); while (i < strings.Length) { char ch = CharFrom(dataBuf, bufpos); if (ch != '\0') buf.Append(ch); else { strings[i] = buf.ToString(); i++; buf = new StringBuilder(); } bufpos += 2; } return strings; } } [ MonitoringDescription(SR.LogEntryResourceId), ComVisible(false) ] public Int64 InstanceId { get { return (UInt32)IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID); } } #if false internal string StringsBuffer { get { StringBuilder buf = new StringBuilder(); int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET); int i = 0; int numStrings = ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS); while (i < numStrings) { char ch = CharFrom(dataBuf, bufpos); buf.Append(ch); bufpos += 2; if (ch == '\0') i++; } return buf.ToString(); } } #endif ////// Gets the replacement strings /// associated with the entry. /// /// ////// [MonitoringDescription(SR.LogEntryTimeGenerated)] public DateTime TimeGenerated { get { return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEGENERATED)).ToLocalTime(); } } ////// Gets the time at which this event was generated, in local time. /// /// ////// [MonitoringDescription(SR.LogEntryTimeWritten)] public DateTime TimeWritten { get { return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEWRITTEN)).ToLocalTime(); } } ////// Gets /// the time at which this event was written to the log, in local time. /// /// ////// [MonitoringDescription(SR.LogEntryUserName)] public string UserName { get { int sidLen = IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDLENGTH); if (sidLen == 0) return null; byte[] sid = new byte[sidLen]; Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDOFFSET), sid, 0, sid.Length); int[] nameUse = new int[1]; char[] name = new char[1024]; char[] refDomName = new char[1024]; int[] nameLen = new int[] {1024}; int[] refDomNameLen = new int[] {1024}; bool success = UnsafeNativeMethods.LookupAccountSid(MachineName, sid, name, nameLen, refDomName, refDomNameLen, nameUse); if (!success) { return ""; // NOTE, [....]: it would be nice to return error info, but the only right way to do that // is to throw an exception. People don't want exceptions thrown in the property though. #if false if (Marshal.GetLastWin32Error() == ERROR_NONE_MAPPED) // There are some SIDs (evidently rare) that are legitimate SIDs but don't // have a mapping to a name. return ""; else throw new InvalidOperationException(SR.GetString(SR.NoAccountInfo), SharedUtils.CreateSafeWin32Exception()); #endif } StringBuilder username = new StringBuilder(); username.Append(refDomName, 0, refDomNameLen[0]); username.Append("\\"); username.Append(name, 0, nameLen[0]); return username.ToString(); } } private char CharFrom(byte[] buf, int offset) { return(char) ShortFrom(buf, offset); } ////// Gets the name /// of the user responsible for this event. /// ////// public bool Equals(EventLogEntry otherEntry) { if (otherEntry == null) return false; int ourLen = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH); int theirLen = IntFrom(otherEntry.dataBuf, otherEntry.bufOffset + FieldOffsets.LENGTH); if (ourLen != theirLen) { return false; } int min = bufOffset; int max = bufOffset + ourLen; int j = otherEntry.bufOffset; for (int i = min; i < max; i++, j++) if (dataBuf[i] != otherEntry.dataBuf[j]) { return false; } return true; } private int IntFrom(byte[] buf, int offset) { // assumes Little Endian byte order. return(unchecked((int)0xFF000000) & (buf[offset+3] << 24)) | (0xFF0000 & (buf[offset+2] << 16)) | (0xFF00 & (buf[offset+1] << 8)) | (0xFF & (buf[offset])); } // Replacing parameters '%n' in formated message using 'ParameterMessageFile' registry key. internal string ReplaceMessageParameters( String msg, string[] insertionStrings ) { int percentIdx = msg.IndexOf('%'); if ( percentIdx < 0 ) return msg; // no '%' at all int startCopyIdx = 0; // start idx of last [....] msg chars to copy int msgLength = msg.Length; StringBuilder buf = new StringBuilder(); string paramDLLNames = GetMessageLibraryNames("ParameterMessageFile"); while ( percentIdx >= 0 ) { string param = null; // Convert numeric string after '%' to paramMsgID number. int lasNumIdx = percentIdx + 1; while ( lasNumIdx < msgLength && Char.IsDigit(msg, lasNumIdx) ) lasNumIdx++; uint paramMsgID = 0; // If we can't parse it, leave the paramMsgID as zero. We'll skip the replacement and just put // the %xxxx into the final message. if (lasNumIdx != percentIdx + 1 ) UInt32.TryParse( msg.Substring(percentIdx + 1, lasNumIdx - percentIdx - 1), out paramMsgID); if ( paramMsgID != 0 ) param = owner.FormatMessageWrapper( paramDLLNames, paramMsgID, insertionStrings); if ( param != null ) { if ( percentIdx > startCopyIdx ) buf.Append(msg, startCopyIdx, percentIdx - startCopyIdx); // original chars from msg buf.Append(param); startCopyIdx = lasNumIdx; } percentIdx = msg.IndexOf('%', percentIdx + 1); } if ( msgLength - startCopyIdx > 0 ) buf.Append(msg, startCopyIdx, msgLength - startCopyIdx); // last span of original msg return buf.ToString(); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private static RegistryKey GetSourceRegKey(string logName, string source, string machineName) { RegistryKey eventKey = null; RegistryKey logKey = null; try { eventKey = EventLog.GetEventLogRegKey(machineName, false); if (eventKey == null) return null; if (logName == null) logKey = eventKey.OpenSubKey("Application", /*writable*/false); else logKey = eventKey.OpenSubKey(logName, /*writable*/false); if (logKey == null) return null; return logKey.OpenSubKey(source, /*writable*/false); } finally { if (eventKey != null) eventKey.Close(); if (logKey != null) logKey.Close(); } } // ----------------------------------------------------------------------------- // Returns DLL names list. // libRegKey can be: "EventMessageFile", "CategoryMessageFile", "ParameterMessageFile" private string GetMessageLibraryNames(string libRegKey ) { // get the value stored in the registry string fileName = null; RegistryKey regKey = null; try { regKey = GetSourceRegKey(owner.Log, Source, owner.MachineName); if (regKey != null) { if (owner.MachineName == ".") fileName = (string)regKey.GetValue(libRegKey); else fileName = (string)regKey.GetValue(libRegKey, null, RegistryValueOptions.DoNotExpandEnvironmentNames); } } finally { if (regKey != null) regKey.Close(); } if (fileName == null) return null; // convert any environment variables to their current values // (the key might have something like %systemroot% in it.) // if we're looking at a remote machine, just try to replace %systemroot% at the beginning if (owner.MachineName != ".") { if (fileName.EndsWith(EventLog.DllName, StringComparison.Ordinal)) { // if it's our EventLogMessages.dll, just use the local copy return EventLog.GetDllPath("."); } else if (String.Compare(fileName, 0, "%systemroot%", 0, 12, StringComparison.OrdinalIgnoreCase) == 0) { // the final length is: // fileName.Length + owner.MachineName.Length // + 2 for the double slash // + 7 for the \admin$ // - 12 for the %systemroot% we're removing. StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length - 3); result.Append(@"\\"); result.Append(owner.MachineName); result.Append(@"\admin$"); result.Append(fileName, 12, fileName.Length - 12); return result.ToString(); } else if (fileName[1] == ':') { StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length + 3); result.Append(@"\\"); result.Append(owner.MachineName); result.Append(@"\"); result.Append(fileName[0]); result.Append("$"); result.Append(fileName, 2, fileName.Length - 2); return result.ToString(); } else return null; } else { // no need to expand environment variables, since this is done automatically by RegistryKey.GetValue() return fileName; } } private short ShortFrom(byte[] buf, int offset) { // assumes little Endian byte order. return(short) ((0xFF00 & (buf[offset+1] << 8)) | (0xFF & buf[offset])); } ////// Performs a comparison between two event log entries. /// /// ////// /// void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { int len = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH); byte[] buf = new byte[len]; Array.Copy(dataBuf, bufOffset, buf, 0, len); info.AddValue("DataBuffer", buf, typeof(byte[])); info.AddValue("LogName", owner.Log); info.AddValue("MachineName", owner.MachineName); } ////// Saves an entry as a stream of data. /// ////// Stores the offsets from the beginning of the record to fields within the record. /// private static class FieldOffsets { /** int */ internal const int LENGTH = 0; /** int */ internal const int RESERVED = 4; /** int */ internal const int RECORDNUMBER = 8; /** int */ internal const int TIMEGENERATED = 12; /** int */ internal const int TIMEWRITTEN = 16; /** int */ internal const int EVENTID = 20; /** short */ internal const int EVENTTYPE = 24; /** short */ internal const int NUMSTRINGS = 26; /** short */ internal const int EVENTCATEGORY = 28; /** short */ internal const int RESERVEDFLAGS = 30; /** int */ internal const int CLOSINGRECORDNUMBER = 32; /** int */ internal const int STRINGOFFSET = 36; /** int */ internal const int USERSIDLENGTH = 40; /** int */ internal const int USERSIDOFFSET = 44; /** int */ internal const int DATALENGTH = 48; /** int */ internal const int DATAOFFSET = 52; /** bytes */ internal const int RAWDATA = 56; } // times in the struct are # seconds from midnight 1/1/1970. private static readonly DateTime beginningOfTime = new DateTime(1970, 1, 1, 0, 0, 0); // offsets in the struct are specified from the beginning, but we have to reference // them from the beginning of the array. This is the size of the members before that. private const int OFFSETFIXUP = 4+4+4+4+4+4+2+2+2+2+4+4+4+4+4+4; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataSourceUtil.cs
- XpsDigitalSignature.cs
- MsmqProcessProtocolHandler.cs
- Button.cs
- ServiceNameElement.cs
- ToolStripStatusLabel.cs
- WbemException.cs
- KeyGestureValueSerializer.cs
- XmlImplementation.cs
- SequentialWorkflowHeaderFooter.cs
- DataViewManagerListItemTypeDescriptor.cs
- ReadWriteObjectLock.cs
- ProviderCollection.cs
- ScrollPatternIdentifiers.cs
- CodeConditionStatement.cs
- BufferedWebEventProvider.cs
- TempFiles.cs
- ModulesEntry.cs
- BezierSegment.cs
- PeerContact.cs
- MatchNoneMessageFilter.cs
- SqlInternalConnection.cs
- PingReply.cs
- XsltContext.cs
- WindowsListBox.cs
- PropertyPushdownHelper.cs
- ByteRangeDownloader.cs
- TraversalRequest.cs
- RegexCaptureCollection.cs
- RSAPKCS1SignatureFormatter.cs
- SuppressIldasmAttribute.cs
- CodeComment.cs
- PenThreadPool.cs
- HtmlButton.cs
- X509WindowsSecurityToken.cs
- ObjectAnimationUsingKeyFrames.cs
- ByteStream.cs
- SqlDataSourceQueryEditor.cs
- FileLoadException.cs
- XsltInput.cs
- XmlIgnoreAttribute.cs
- CollectionType.cs
- SQLUtility.cs
- ProxyElement.cs
- PatternMatchRules.cs
- EntityContainerEmitter.cs
- WinFormsComponentEditor.cs
- SettingsAttributes.cs
- DataServiceQuery.cs
- KeyedHashAlgorithm.cs
- TableCell.cs
- WebPartTransformerCollection.cs
- ChangeConflicts.cs
- DivideByZeroException.cs
- sitestring.cs
- DocumentSchemaValidator.cs
- HttpStreamFormatter.cs
- PolyQuadraticBezierSegment.cs
- MappingSource.cs
- DropDownList.cs
- SmtpFailedRecipientsException.cs
- AnnotationResourceCollection.cs
- WebPartConnectionsEventArgs.cs
- JsonWriterDelegator.cs
- RowToParametersTransformer.cs
- DataMemberAttribute.cs
- GridSplitterAutomationPeer.cs
- CompiledQueryCacheEntry.cs
- dataSvcMapFileLoader.cs
- FileLevelControlBuilderAttribute.cs
- RightNameExpirationInfoPair.cs
- PrePostDescendentsWalker.cs
- UIPermission.cs
- SpellerStatusTable.cs
- WindowsListViewItem.cs
- HttpCachePolicyWrapper.cs
- ExceptionUtil.cs
- ContextInformation.cs
- CodeVariableDeclarationStatement.cs
- __Error.cs
- SrgsElementFactory.cs
- InvokeBase.cs
- SiteMembershipCondition.cs
- TrackingProfileCache.cs
- GPStream.cs
- RemotingConfiguration.cs
- HelpInfo.cs
- TableLayoutPanelBehavior.cs
- ScriptManager.cs
- XmlBinaryReader.cs
- QueryStringParameter.cs
- LogLogRecordHeader.cs
- sapiproxy.cs
- CodeParameterDeclarationExpression.cs
- X509CertificateTrustedIssuerElementCollection.cs
- ExpandoObject.cs
- RequestSecurityToken.cs
- Application.cs
- RepeaterCommandEventArgs.cs
- OrderedParallelQuery.cs