EventLogWatcher.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Diagnostics / Eventing / Reader / EventLogWatcher.cs / 1305376 / EventLogWatcher.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class: EventLogWatcher 
**
** Purpose: 
** This public class is used for subscribing to event record
** notifications 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 { 

    ///  
    /// Used for subscribing to event record notifications from 
    /// event log.
    ///  
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public class EventLogWatcher : IDisposable {

        public event EventHandler EventRecordWritten; 

        private EventLogQuery eventQuery; 
        private EventBookmark bookmark; 
        private bool readExistingEvents;
 
        private EventLogHandle handle;
        private IntPtr[] eventsBuffer;
        private int numEventsInBuffer;
        private bool isSubscribing; 
        private int callbackThreadId;
 
        AutoResetEvent subscriptionWaitHandle; 
        AutoResetEvent unregisterDoneHandle;
        RegisteredWaitHandle registeredWaitHandle; 

        /// 
        /// Maintains cached display / metadata information returned from
        /// EventRecords that were obtained from this reader. 
        /// 
        ProviderMetadataCachedInformation cachedMetadataInformation; 
 
        EventLogException asyncException;
 
        public EventLogWatcher(string path)
            : this(new EventLogQuery(path, PathType.LogName), null, false) {
        }
 
        public EventLogWatcher(EventLogQuery eventQuery)
            : this(eventQuery, null, false) { 
        } 

        public EventLogWatcher(EventLogQuery eventQuery, EventBookmark bookmark) 
            : this(eventQuery, bookmark, false) {
        }

        public EventLogWatcher(EventLogQuery eventQuery, EventBookmark bookmark, bool readExistingEvents) { 

            if (eventQuery == null) 
                throw new ArgumentNullException("eventQuery"); 

            if (bookmark != null) 
                readExistingEvents = false;

            //explicit data
            this.eventQuery = eventQuery; 
            this.readExistingEvents = readExistingEvents;
 
            if (this.eventQuery.ReverseDirection) 
                throw new InvalidOperationException();
 
            this.eventsBuffer = new IntPtr[64];
            this.cachedMetadataInformation = new ProviderMetadataCachedInformation(eventQuery.Session, null, 50);
            this.bookmark = bookmark;
        } 

        public bool Enabled { 
            get { 
                return isSubscribing;
            } 
            set {
                if (value && !isSubscribing) {
                    StartSubscribing();
                } 
                else if (!value && isSubscribing) {
                    StopSubscribing(); 
                } 
            }
        } 

        [System.Security.SecuritySafeCritical]
        internal void StopSubscribing() {
 
            EventLogPermissionHolder.GetEventLogPermission().Demand();
 
            // 
            // need to set isSubscribing to false before waiting for completion of callback.
            // 
            this.isSubscribing = false;

            if (this.registeredWaitHandle != null) {
 
                this.registeredWaitHandle.Unregister( this.unregisterDoneHandle );
 
                if (this.callbackThreadId != Thread.CurrentThread.ManagedThreadId) { 
                    //
                    // not calling Stop from within callback - wait for 
                    // any outstanding callbacks to complete.
                    //
                    if ( this.unregisterDoneHandle != null )
                        this.unregisterDoneHandle.WaitOne(); 
                }
 
                this.registeredWaitHandle = null; 
            }
 
            if (this.unregisterDoneHandle != null) {
                this.unregisterDoneHandle.Close();
                this.unregisterDoneHandle = null;
            } 

            if (this.subscriptionWaitHandle != null) { 
                this.subscriptionWaitHandle.Close(); 
                this.subscriptionWaitHandle = null;
            } 

            for (int i = 0; i < this.numEventsInBuffer; i++) {

                if (eventsBuffer[i] != IntPtr.Zero) { 
                    NativeWrapper.EvtClose(eventsBuffer[i]);
                    eventsBuffer[i] = IntPtr.Zero; 
                } 
            }
 
            this.numEventsInBuffer = 0;

            if (handle != null && !handle.IsInvalid)
                handle.Dispose(); 
        }
 
        [System.Security.SecuritySafeCritical] 
        internal void StartSubscribing() {
 
            if (this.isSubscribing)
                throw new InvalidOperationException();

            int flag = 0; 
            if (bookmark != null)
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeStartAfterBookmark; 
            else if (this.readExistingEvents) 
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeStartAtOldestRecord;
            else 
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeToFutureEvents;

            if (this.eventQuery.TolerateQueryErrors)
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeTolerateQueryErrors; 

            EventLogPermissionHolder.GetEventLogPermission().Demand(); 
 
            this.callbackThreadId = -1;
            this.unregisterDoneHandle = new AutoResetEvent(false); 
            this.subscriptionWaitHandle = new AutoResetEvent(false);

            EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark);
 
            using (bookmarkHandle) {
 
                handle = NativeWrapper.EvtSubscribe(this.eventQuery.Session.Handle, 
                    this.subscriptionWaitHandle.SafeWaitHandle,
                    this.eventQuery.Path, 
                    this.eventQuery.Query,
                    bookmarkHandle,
                    IntPtr.Zero,
                    IntPtr.Zero, 
                    flag);
            } 
 
            this.isSubscribing = true;
 
            RequestEvents();

            this.registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject(
                this.subscriptionWaitHandle, 
                new WaitOrTimerCallback(SubscribedEventsAvailableCallback),
                null, 
                -1, 
                false);
        } 

        internal void SubscribedEventsAvailableCallback(object state, bool timedOut) {
            this.callbackThreadId = Thread.CurrentThread.ManagedThreadId;
            try { 
                RequestEvents();
            } 
            finally { 
                this.callbackThreadId = -1;
            } 
        }

        [System.Security.SecuritySafeCritical]
        private void RequestEvents() { 

            EventLogPermissionHolder.GetEventLogPermission().Demand(); 
 
            this.asyncException = null;
            Debug.Assert(this. numEventsInBuffer == 0); 

            bool results = false;

            do { 

                if (!this.isSubscribing) 
                    break; 

                try { 

                    results = NativeWrapper.EvtNext(this.handle, this.eventsBuffer.Length, this.eventsBuffer, 0, 0, ref this. numEventsInBuffer);

                    if (!results) 
                        return;
                } 
                catch (EventLogException e) { 
                    this.asyncException = e;
                } 

                HandleEventsRequestCompletion();

            } while (results); 
        }
 
        private void IssueCallback(EventRecordWrittenEventArgs eventArgs) { 

            if (EventRecordWritten != null) { 
                EventRecordWritten(this, eventArgs);
            }
        }
 
        // marked as SecurityCritical because allocates SafeHandles.
        [System.Security.SecurityCritical] 
        private void HandleEventsRequestCompletion() { 

            if (this.asyncException != null) { 
                EventRecordWrittenEventArgs args = new EventRecordWrittenEventArgs(this.asyncException);
                IssueCallback(args);
            }
 
            for (int i = 0; i < this. numEventsInBuffer; i++) {
                if (!this.isSubscribing) 
                    break; 
                EventLogRecord record = new EventLogRecord(new EventLogHandle(this.eventsBuffer[i], true), this.eventQuery.Session, this.cachedMetadataInformation);
                EventRecordWrittenEventArgs args = new EventRecordWrittenEventArgs(record); 
                this.eventsBuffer[i] = IntPtr.Zero;  // user is responsible for calling Dispose().
                IssueCallback(args);
            }
        } 

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

        [System.Security.SecuritySafeCritical]
        protected virtual void Dispose(bool disposing) {
 
            if (disposing) {
                    StopSubscribing(); 
                return; 
            }
 
            for (int i = 0; i < this.numEventsInBuffer; i++) {

                if (eventsBuffer[i] != IntPtr.Zero) {
                    NativeWrapper.EvtClose(eventsBuffer[i]); 
                    eventsBuffer[i] = IntPtr.Zero;
                } 
            } 

            this.numEventsInBuffer = 0; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class: EventLogWatcher 
**
** Purpose: 
** This public class is used for subscribing to event record
** notifications 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 { 

    ///  
    /// Used for subscribing to event record notifications from 
    /// event log.
    ///  
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public class EventLogWatcher : IDisposable {

        public event EventHandler EventRecordWritten; 

        private EventLogQuery eventQuery; 
        private EventBookmark bookmark; 
        private bool readExistingEvents;
 
        private EventLogHandle handle;
        private IntPtr[] eventsBuffer;
        private int numEventsInBuffer;
        private bool isSubscribing; 
        private int callbackThreadId;
 
        AutoResetEvent subscriptionWaitHandle; 
        AutoResetEvent unregisterDoneHandle;
        RegisteredWaitHandle registeredWaitHandle; 

        /// 
        /// Maintains cached display / metadata information returned from
        /// EventRecords that were obtained from this reader. 
        /// 
        ProviderMetadataCachedInformation cachedMetadataInformation; 
 
        EventLogException asyncException;
 
        public EventLogWatcher(string path)
            : this(new EventLogQuery(path, PathType.LogName), null, false) {
        }
 
        public EventLogWatcher(EventLogQuery eventQuery)
            : this(eventQuery, null, false) { 
        } 

        public EventLogWatcher(EventLogQuery eventQuery, EventBookmark bookmark) 
            : this(eventQuery, bookmark, false) {
        }

        public EventLogWatcher(EventLogQuery eventQuery, EventBookmark bookmark, bool readExistingEvents) { 

            if (eventQuery == null) 
                throw new ArgumentNullException("eventQuery"); 

            if (bookmark != null) 
                readExistingEvents = false;

            //explicit data
            this.eventQuery = eventQuery; 
            this.readExistingEvents = readExistingEvents;
 
            if (this.eventQuery.ReverseDirection) 
                throw new InvalidOperationException();
 
            this.eventsBuffer = new IntPtr[64];
            this.cachedMetadataInformation = new ProviderMetadataCachedInformation(eventQuery.Session, null, 50);
            this.bookmark = bookmark;
        } 

        public bool Enabled { 
            get { 
                return isSubscribing;
            } 
            set {
                if (value && !isSubscribing) {
                    StartSubscribing();
                } 
                else if (!value && isSubscribing) {
                    StopSubscribing(); 
                } 
            }
        } 

        [System.Security.SecuritySafeCritical]
        internal void StopSubscribing() {
 
            EventLogPermissionHolder.GetEventLogPermission().Demand();
 
            // 
            // need to set isSubscribing to false before waiting for completion of callback.
            // 
            this.isSubscribing = false;

            if (this.registeredWaitHandle != null) {
 
                this.registeredWaitHandle.Unregister( this.unregisterDoneHandle );
 
                if (this.callbackThreadId != Thread.CurrentThread.ManagedThreadId) { 
                    //
                    // not calling Stop from within callback - wait for 
                    // any outstanding callbacks to complete.
                    //
                    if ( this.unregisterDoneHandle != null )
                        this.unregisterDoneHandle.WaitOne(); 
                }
 
                this.registeredWaitHandle = null; 
            }
 
            if (this.unregisterDoneHandle != null) {
                this.unregisterDoneHandle.Close();
                this.unregisterDoneHandle = null;
            } 

            if (this.subscriptionWaitHandle != null) { 
                this.subscriptionWaitHandle.Close(); 
                this.subscriptionWaitHandle = null;
            } 

            for (int i = 0; i < this.numEventsInBuffer; i++) {

                if (eventsBuffer[i] != IntPtr.Zero) { 
                    NativeWrapper.EvtClose(eventsBuffer[i]);
                    eventsBuffer[i] = IntPtr.Zero; 
                } 
            }
 
            this.numEventsInBuffer = 0;

            if (handle != null && !handle.IsInvalid)
                handle.Dispose(); 
        }
 
        [System.Security.SecuritySafeCritical] 
        internal void StartSubscribing() {
 
            if (this.isSubscribing)
                throw new InvalidOperationException();

            int flag = 0; 
            if (bookmark != null)
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeStartAfterBookmark; 
            else if (this.readExistingEvents) 
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeStartAtOldestRecord;
            else 
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeToFutureEvents;

            if (this.eventQuery.TolerateQueryErrors)
                flag |= (int)UnsafeNativeMethods.EvtSubscribeFlags.EvtSubscribeTolerateQueryErrors; 

            EventLogPermissionHolder.GetEventLogPermission().Demand(); 
 
            this.callbackThreadId = -1;
            this.unregisterDoneHandle = new AutoResetEvent(false); 
            this.subscriptionWaitHandle = new AutoResetEvent(false);

            EventLogHandle bookmarkHandle = EventLogRecord.GetBookmarkHandleFromBookmark(bookmark);
 
            using (bookmarkHandle) {
 
                handle = NativeWrapper.EvtSubscribe(this.eventQuery.Session.Handle, 
                    this.subscriptionWaitHandle.SafeWaitHandle,
                    this.eventQuery.Path, 
                    this.eventQuery.Query,
                    bookmarkHandle,
                    IntPtr.Zero,
                    IntPtr.Zero, 
                    flag);
            } 
 
            this.isSubscribing = true;
 
            RequestEvents();

            this.registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject(
                this.subscriptionWaitHandle, 
                new WaitOrTimerCallback(SubscribedEventsAvailableCallback),
                null, 
                -1, 
                false);
        } 

        internal void SubscribedEventsAvailableCallback(object state, bool timedOut) {
            this.callbackThreadId = Thread.CurrentThread.ManagedThreadId;
            try { 
                RequestEvents();
            } 
            finally { 
                this.callbackThreadId = -1;
            } 
        }

        [System.Security.SecuritySafeCritical]
        private void RequestEvents() { 

            EventLogPermissionHolder.GetEventLogPermission().Demand(); 
 
            this.asyncException = null;
            Debug.Assert(this. numEventsInBuffer == 0); 

            bool results = false;

            do { 

                if (!this.isSubscribing) 
                    break; 

                try { 

                    results = NativeWrapper.EvtNext(this.handle, this.eventsBuffer.Length, this.eventsBuffer, 0, 0, ref this. numEventsInBuffer);

                    if (!results) 
                        return;
                } 
                catch (EventLogException e) { 
                    this.asyncException = e;
                } 

                HandleEventsRequestCompletion();

            } while (results); 
        }
 
        private void IssueCallback(EventRecordWrittenEventArgs eventArgs) { 

            if (EventRecordWritten != null) { 
                EventRecordWritten(this, eventArgs);
            }
        }
 
        // marked as SecurityCritical because allocates SafeHandles.
        [System.Security.SecurityCritical] 
        private void HandleEventsRequestCompletion() { 

            if (this.asyncException != null) { 
                EventRecordWrittenEventArgs args = new EventRecordWrittenEventArgs(this.asyncException);
                IssueCallback(args);
            }
 
            for (int i = 0; i < this. numEventsInBuffer; i++) {
                if (!this.isSubscribing) 
                    break; 
                EventLogRecord record = new EventLogRecord(new EventLogHandle(this.eventsBuffer[i], true), this.eventQuery.Session, this.cachedMetadataInformation);
                EventRecordWrittenEventArgs args = new EventRecordWrittenEventArgs(record); 
                this.eventsBuffer[i] = IntPtr.Zero;  // user is responsible for calling Dispose().
                IssueCallback(args);
            }
        } 

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

        [System.Security.SecuritySafeCritical]
        protected virtual void Dispose(bool disposing) {
 
            if (disposing) {
                    StopSubscribing(); 
                return; 
            }
 
            for (int i = 0; i < this.numEventsInBuffer; i++) {

                if (eventsBuffer[i] != IntPtr.Zero) {
                    NativeWrapper.EvtClose(eventsBuffer[i]); 
                    eventsBuffer[i] = IntPtr.Zero;
                } 
            } 

            this.numEventsInBuffer = 0; 
        }
    }
}

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