EventLogReader.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 / Core / System / Diagnostics / Eventing / Reader / EventLogReader.cs / 1305376 / EventLogReader.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class: EventLogReader 
**
** Purpose: 
** This public class is used for reading event records from event log.
**
============================================================*/
 
using System;
using System.IO; 
using System.Collections.Generic; 
using System.Threading;
using System.Security.Permissions; 
using Microsoft.Win32;

namespace System.Diagnostics.Eventing.Reader {
 
    /// 
    /// This public class is used for reading event records from event log. 
    ///  
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] 
    public class EventLogReader : IDisposable {

        private EventLogQuery eventQuery;
 
        private int batchSize;
 
        // 
        // access to the data member reference is safe, while
        // invoking methods on it is marked SecurityCritical as appropriate. 
        //
        private EventLogHandle handle;

        ///  
        /// events buffer holds batched event (handles).
        ///  
        private IntPtr[] eventsBuffer; 
        /// 
        /// The current index where the function GetNextEvent is (inside the eventsBuffer). 
        /// 
        private int currentIndex;
        /// 
        /// The number of events read from the batch into the eventsBuffer 
        /// 
        private int eventCount; 
 
        /// 
        /// When the reader finishes (will always return only ERROR_NO_MORE_ITEMS). 
        /// For subscription, this means we need to wait for next event.
        /// 
        bool isEof;
 
        /// 
        /// Maintains cached display / metadata information returned from 
        /// EventRecords that were obtained from this reader. 
        /// 
        ProviderMetadataCachedInformation cachedMetadataInformation; 

        public EventLogReader(string path)
            : this(new EventLogQuery(path, PathType.LogName), null) {
        } 

        public EventLogReader(string path, PathType pathType) 
            : this(new EventLogQuery(path, pathType), null) { 
        }
 
        public EventLogReader(EventLogQuery eventQuery)
            : this(eventQuery, null) {
        }
 
        [System.Security.SecurityCritical]
        public EventLogReader(EventLogQuery eventQuery, EventBookmark bookmark) { 
 
            if (eventQuery == null)
                throw new ArgumentNullException("eventQuery"); 

            string logfile = null;
            if (eventQuery.ThePathType == PathType.FilePath)
                logfile = eventQuery.Path; 

            this.cachedMetadataInformation = new ProviderMetadataCachedInformation(eventQuery.Session, logfile, 50 ); 
 
            //explicit data
            this.eventQuery = eventQuery; 

            //implicit
            this.batchSize = 64;
            this.eventsBuffer = new IntPtr[batchSize]; 

            // 
            // compute the flag. 
            //
            int flag = 0; 

            if (this.eventQuery.ThePathType == PathType.LogName)
                flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryChannelPath;
            else 
                flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath;
 
            if (this.eventQuery.ReverseDirection) 
                flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryReverseDirection;
 
            if (this.eventQuery.TolerateQueryErrors)
                flag |= (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryTolerateQueryErrors;

            EventLogPermissionHolder.GetEventLogPermission().Demand(); 

            handle = NativeWrapper.EvtQuery(this.eventQuery.Session.Handle, 
                this.eventQuery.Path, this.eventQuery.Query, 
                flag);
 
            EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark);

            if (!bookmarkHandle.IsInvalid) {
                using (bookmarkHandle) { 
                    NativeWrapper.EvtSeek(handle, 1, bookmarkHandle, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToBookmark);
                } 
            } 
        }
 
        public int BatchSize {
            get {
                return batchSize;
            } 
            set {
                if (value < 1) 
                    throw new ArgumentOutOfRangeException("value"); 
                batchSize = value;
            } 
        }

        [System.Security.SecurityCritical]
        private bool GetNextBatch(TimeSpan ts) { 

            int timeout; 
            if (ts == TimeSpan.MaxValue) 
                timeout = -1;
            else 
                timeout = (int)ts.TotalMilliseconds;

            // batchSize was changed by user, reallocate buffer.
            if (batchSize != eventsBuffer.Length) eventsBuffer = new IntPtr[batchSize]; 

            int newEventCount = 0; 
            bool results = NativeWrapper.EvtNext(handle, batchSize, eventsBuffer, timeout, 0, ref newEventCount); 

            if (!results) { 
                this.eventCount = 0;
                this.currentIndex = 0;
                return false; //no more events in the result set
            } 

            this.currentIndex = 0; 
            this.eventCount = newEventCount; 
            return true;
        } 

        public EventRecord ReadEvent() {
            return ReadEvent(TimeSpan.MaxValue);
        } 

        // security critical because allocates SafeHandle. 
        // marked as safe because performs Demand check. 
        [System.Security.SecurityCritical]
        public EventRecord ReadEvent(TimeSpan timeout) { 

            EventLogPermissionHolder.GetEventLogPermission().Demand();

            if (this.isEof) 
                throw new InvalidOperationException();
 
            if (this.currentIndex >= this.eventCount) { 
                // buffer is empty, get next batch.
                GetNextBatch(timeout); 

                if (this.currentIndex >= this.eventCount) {
                    this.isEof = true;
                    return null; 
                }
            } 
 
            EventLogRecord eventInstance = new EventLogRecord(new EventLogHandle(this.eventsBuffer[currentIndex], true), this.eventQuery.Session, this.cachedMetadataInformation);
            currentIndex++; 
            return eventInstance;
        }

        public void Dispose() { 
            Dispose(true);
            GC.SuppressFinalize(this); 
        } 

        [System.Security.SecuritySafeCritical] 
        protected virtual void Dispose(bool disposing) {

            if (disposing) {
                EventLogPermissionHolder.GetEventLogPermission().Demand(); 
            }
 
            while (this.currentIndex < this.eventCount) { 
                NativeWrapper.EvtClose(eventsBuffer[this.currentIndex]);
                this.currentIndex++; 
            }

            if (handle != null && !handle.IsInvalid)
                handle.Dispose(); 
        }
 
        [System.Security.SecurityCritical] 
        internal void SeekReset() {
            // 
            //close all unread event handles in the buffer
            //
            while (this.currentIndex < this.eventCount) {
                NativeWrapper.EvtClose(eventsBuffer[this.currentIndex]); 
                this.currentIndex++;
            } 
 
            //reset the indexes used by Next
            this.currentIndex = 0; 
            this.eventCount = 0;
            this.isEof = false;
        }
 
        // marked as SecurityCritical because it allocates SafeHandle.
        [System.Security.SecurityCritical] 
        internal void SeekCommon(long offset) { 

            // 
            // modify offset that we're going to send to service to account for the
            // fact that we've already read some events in our buffer that the user
            // hasn't seen yet.
            // 
            offset = offset - (this.eventCount - this.currentIndex);
 
            SeekReset(); 

            NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToCurrent); 
        }

        public void Seek(EventBookmark bookmark) {
            Seek(bookmark, 0); 
        }
 
        [System.Security.SecurityCritical] 
        public void Seek(EventBookmark bookmark, long offset) {
            if (bookmark == null) 
                throw new ArgumentNullException("bookmark");

            EventLogPermissionHolder.GetEventLogPermission().Demand();
 
            SeekReset();
            using (EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark)) { 
                NativeWrapper.EvtSeek(this.handle, offset, bookmarkHandle, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToBookmark); 
            }
        } 

        [System.Security.SecurityCritical]
        public void Seek(SeekOrigin origin, long offset) {
            EventLogPermissionHolder.GetEventLogPermission().Demand(); 

            switch (origin) { 
                case SeekOrigin.Begin: 

                    SeekReset(); 
                    NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToFirst);
                    return;

                case SeekOrigin.End: 

                    SeekReset(); 
                    NativeWrapper.EvtSeek(this.handle, offset, EventLogHandle.Zero, 0, UnsafeNativeMethods.EvtSeekFlags.EvtSeekRelativeToLast); 
                    return;
 
                case SeekOrigin.Current:
                    if (offset >= 0) {
                        //we can reuse elements in the batch.
                        if (this.currentIndex + offset < this.eventCount) { 
                            //
                            // We don't call Seek here, we can reposition within the batch. 
                            // 

                            // close all event handles between [currentIndex, currentIndex + offset) 
                            int index = this.currentIndex;
                            while (index < this.currentIndex + offset) {
                                NativeWrapper.EvtClose(eventsBuffer[index]);
                                index++; 
                            }
 
                            this.currentIndex = (int)(this.currentIndex + offset); 
                            //leave the eventCount unchanged
                            //leave the same Eof 
                        }
                        else {
                            SeekCommon(offset);
                        } 
                    }
                    else { 
                        //if inside the current buffer, we still cannot read the events, as the handles. 
                        //may have already been closed.
                        if (currentIndex + offset >= 0) { 
                            SeekCommon(offset);
                        }
                        else  //outside the current buffer
                        { 
                            SeekCommon(offset);
                        } 
                    } 
                    return;
            } 
        }

        public void CancelReading() {
 
            NativeWrapper.EvtCancel(handle);
        } 
 
        public IList LogStatus {
            [System.Security.SecurityCritical] 
            get {
                EventLogPermissionHolder.GetEventLogPermission().Demand();

                List list = null; 
                string[] channelNames = null;
                int[] errorStatuses = null; 
                EventLogHandle queryHandle = this.handle; 

                if (queryHandle.IsInvalid) 
                    throw new InvalidOperationException();

                channelNames = (string[])NativeWrapper.EvtGetQueryInfo(queryHandle, UnsafeNativeMethods.EvtQueryPropertyId.EvtQueryNames);
                errorStatuses = (int[])NativeWrapper.EvtGetQueryInfo(queryHandle, UnsafeNativeMethods.EvtQueryPropertyId.EvtQueryStatuses); 

                if (channelNames.Length != errorStatuses.Length) 
                    throw new InvalidOperationException(); 

                list = new List(channelNames.Length); 
                for (int i = 0; i < channelNames.Length; i++) {
                    EventLogStatus cs = new EventLogStatus(channelNames[i], errorStatuses[i]);
                    list.Add(cs);
                } 
                return list.AsReadOnly();
            } 
        } 
    }
} 

// 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