Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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
- LinkedResource.cs
- OrderToken.cs
- RtType.cs
- WebSysDisplayNameAttribute.cs
- ApplicationSecurityManager.cs
- SmiSettersStream.cs
- FontSizeConverter.cs
- ImageListStreamer.cs
- SchemaMapping.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- EntityCodeGenerator.cs
- TextBoxLine.cs
- Latin1Encoding.cs
- TreeBuilder.cs
- SqlDataSourceFilteringEventArgs.cs
- TreeNodeConverter.cs
- ConnectionManagementElementCollection.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- CompilationRelaxations.cs
- LookupBindingPropertiesAttribute.cs
- XmlArrayItemAttributes.cs
- TdsValueSetter.cs
- BatchParser.cs
- QueryReaderSettings.cs
- PathFigure.cs
- SourceFilter.cs
- FrameworkElementFactory.cs
- DataKeyArray.cs
- ProviderUtil.cs
- AnonymousIdentificationModule.cs
- CustomTypeDescriptor.cs
- EntityClassGenerator.cs
- SystemPens.cs
- DefinitionUpdate.cs
- FaultPropagationRecord.cs
- AddInAttribute.cs
- XsdDataContractExporter.cs
- UnsafeNativeMethods.cs
- CategoryAttribute.cs
- DeferredSelectedIndexReference.cs
- ZoomPercentageConverter.cs
- Soap.cs
- GeneratedCodeAttribute.cs
- BindingSource.cs
- DataServiceRequestOfT.cs
- OneWayBindingElementImporter.cs
- ActivityPreviewDesigner.cs
- ValidatingReaderNodeData.cs
- Stack.cs
- ViewSimplifier.cs
- SymbolMethod.cs
- SqlUtil.cs
- ApplicationException.cs
- ZipPackage.cs
- WindowHideOrCloseTracker.cs
- IntSecurity.cs
- BreadCrumbTextConverter.cs
- CommandField.cs
- odbcmetadatacolumnnames.cs
- SmtpCommands.cs
- bidPrivateBase.cs
- CodeTryCatchFinallyStatement.cs
- AppDomainGrammarProxy.cs
- XmlSerializerNamespaces.cs
- AsymmetricSignatureFormatter.cs
- ConnectionPoint.cs
- Selection.cs
- LocatorGroup.cs
- PropertyChangedEventManager.cs
- CodeDirectiveCollection.cs
- RMEnrollmentPage2.cs
- SignalGate.cs
- DomNameTable.cs
- CipherData.cs
- ObjectManager.cs
- TreeNodeBindingCollection.cs
- GAC.cs
- ResourceType.cs
- HtmlUtf8RawTextWriter.cs
- Vector.cs
- RawStylusSystemGestureInputReport.cs
- TypeUnloadedException.cs
- SafeLocalMemHandle.cs
- COM2ExtendedUITypeEditor.cs
- SqlResolver.cs
- HwndKeyboardInputProvider.cs
- DataControlFieldsEditor.cs
- ReadWriteSpinLock.cs
- TraceRecords.cs
- SqlReferenceCollection.cs
- DictionaryTraceRecord.cs
- XmlSchemaProviderAttribute.cs
- ProcessManager.cs
- ValueSerializer.cs
- OleCmdHelper.cs
- DataGridItem.cs
- __ComObject.cs
- ColumnWidthChangingEvent.cs
- mediaeventargs.cs
- InheritanceRules.cs