EventLogEntry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Monitoring / system / Diagnosticts / EventLogEntry.cs / 1305376 / 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;

    /// 
    ///     
    ///    
    ///    encapsulates a single record in the NT event log. 
    ///  
    /// 
    [ 
    ToolboxItem(false),
    DesignTimeVisible(false),
    Serializable,
    ] 
    public sealed class EventLogEntry : Component, ISerializable {
        internal byte[] dataBuf; 
        internal int bufOffset; 
        private EventLogInternal owner;
        private string category; 
        private string message;

        // make sure only others in this package can create us
        internal EventLogEntry(byte[] buf, int offset, EventLogInternal log) { 
            this.dataBuf = buf;
            this.bufOffset = offset; 
            this.owner = log; 

            GC.SuppressFinalize(this); 
        }

        /// 
        ///  
        /// 
        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 EventLogInternal(logName, machineName, "");
            GC.SuppressFinalize(this);
        }
 
        /// 
        ///     
        ///       Gets the name of the computer on which this entry was generated. 
        ///
        ///     
        /// 
        [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 binary data associated with the entry.
        /// 
        ///     
        /// 
        [ 
        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; 
            }
        }

        /* 
        /// 
        ///     
        ///       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;
        } 
        */
 
        ///  
        ///    
        ///       Gets the index of this entry in the event 
        ///       log.
        ///    
        /// 
        [MonitoringDescription(SR.LogEntryIndex)] 
        public int Index {
            get { 
                return IntFrom(dataBuf, bufOffset + FieldOffsets.RECORDNUMBER); 
            }
        } 

        /// 
        ///    
        ///       Gets the text associated with the  for this entry. 
        ///
        ///     
        ///  
        [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 application-specific category number for this entry
        /// 
        ///    
        /// 
        [
        MonitoringDescription(SR.LogEntryCategoryNumber) 
        ]
        public short CategoryNumber { 
            get { 
                return ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTCATEGORY);
            } 
        }

        /// 
        ///     
        ///       Gets the application-specific event indentifier of 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 type
        ///       of this entry. 
        ///
        ///    
        /// 
        [MonitoringDescription(SR.LogEntryEntryType)] 
        public EventLogEntryType EntryType {
            get { 
                return(EventLogEntryType) ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTTYPE); 
            }
        } 

        /// 
        ///    
        ///       Gets the localized message corresponding to this event 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 name of the application that generated this event.
        ///     
        ///  
        [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 replacement strings 
        ///       associated with the entry.
        ///
        ///    
        ///  
        [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 time at which this event was generated, in local time. 
        ///
        ///     
        ///  
        [MonitoringDescription(SR.LogEntryTimeGenerated)]
        public DateTime TimeGenerated { 
            get {
                return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEGENERATED)).ToLocalTime();
            }
        } 

        ///  
        ///     
        ///       Gets
        ///       the time at which this event was written to the log, in local time. 
        ///
        ///    
        /// 
        [MonitoringDescription(SR.LogEntryTimeWritten)] 
        public DateTime TimeWritten {
            get { 
                return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEWRITTEN)).ToLocalTime(); 
            }
        } 

        /// 
        ///    
        ///       Gets the name 
        ///       of the user responsible for this event.
        ///     
        ///  
        [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 userNameLen = 256; 
                int domainNameLen = 256;
                int sidNameUse = 0;
                StringBuilder bufUserName = new StringBuilder(userNameLen);
                StringBuilder bufDomainName = new StringBuilder(domainNameLen); 

                StringBuilder retUserName = new StringBuilder(); 
 
                if(UnsafeNativeMethods.LookupAccountSid(MachineName, sid, bufUserName, ref userNameLen, bufDomainName, ref domainNameLen, ref sidNameUse) != 0) {
                    retUserName.Append(bufDomainName.ToString()); 
                    retUserName.Append("\\");
                    retUserName.Append(bufUserName.ToString());
                }
 
                return retUserName.ToString();
            } 
        } 

        private char CharFrom(byte[] buf, int offset) { 
            return(char) ShortFrom(buf, offset);
        }

        ///  
        ///    
        ///       Performs a comparison between two event log entries. 
        /// 
        ///    
        ///  
        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" 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        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) {
                    fileName = (string)regKey.GetValue(libRegKey); 
                }
            }
            finally {
                if (regKey != null) 
                    regKey.Close();
            } 
 
            if (fileName == null)
                return null; 

            // convert any absolute paths on a remote machine to use the \\MACHINENAME\DRIVELETTER$ shares
            // so we pick up message dlls from the remote machine.
            if (owner.MachineName != ".") { 

                string[] fileNames = fileName.Split(';'); 
 
                StringBuilder result = new StringBuilder();
 
                for (int i = 0; i < fileNames.Length; i++) {
                    if (fileNames[i].EndsWith(EventLog.DllName, StringComparison.Ordinal)) {
                        // if it's our EventLogMessages.dll, just use the local copy
                        result.Append(EventLog.GetDllPath(".")); 
                        result.Append(';');
                    } else if (fileNames[i].Length >= 2 && fileNames[i][1] == ':') { 
                        result.Append(@"\\"); 
                        result.Append(owner.MachineName);
                        result.Append(@"\"); 
                        result.Append(fileNames[i][0]);
                        result.Append("$");
                        result.Append(fileNames[i], 2, fileNames[i].Length - 2);
                        result.Append(';'); 
                    }
                } 
 
                if (result.Length == 0) {
                    return null; 
                } else {
                    return result.ToString(0, result.Length - 1); // Chop of last ";"
                }
            } 
            else {
                return fileName; 
            } 
        }
 

        private short ShortFrom(byte[] buf, int offset) {
            // assumes little Endian byte order.
            return(short) ((0xFF00 & (buf[offset+1] << 8)) | (0xFF & buf[offset])); 
        }
 
        ///  
        /// 
        ///  
        /// Saves an entry as a stream of data.
        /// 
        /// 
        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);
        }
 
        /// 
        ///     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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK