Managed C++: Monitoring the Windows Event Log

Due to the increasing danger posed by viruses and mal/ad-ware applications, many people have downloaded, purchased, or written their own file and Registry monitors. These monitors typically are written to detect malicious software that has been installed—or is being installed—on a machine by prompting warnings when applications attempt to modify the Windows Registry or certain files. However, an oft-overlooked area of security is the Windows event log—specifically the security event log, where the Windows operating system and key system applications log events such as invalid logon attempts, port scans, and many other events related to the security of a system.

This article illustrates how to monitor any event log from a Windows application. You then can take the basics it covers and modify them to your particular environment and needs—such as having the application e-mail you when the security event log records a particular event type.

Monitoring with the .NET EventLog Class

The code in this article uses the .NET 1.0/1.1 Managed C++ syntax. If you're using a newer version of .NET, you'll need to specify the /clr:oldSyntax option in the project's Project Properties dialog box or adjust the code below to conform to the new Managed C++ syntax.

The key .NET type to working with the Windows event log is the Diagnostics::EventLog class.

  1. Define a managed class that implements the event log notification handler.
    The handler (OnNewLogEntry) will be called when the "new event-log entry event" is raised. Also, note that the event handler must have the same signature as the EntryWrittenEventHandler delegate. Here's an example class:
    // Example event handler managed class for
    // monitoring new event log entries
    __gc class NewLogEntryEventHandler
    {
    public:
      NewLogEntryEventHandler() {}
    
    public:
      void OnNewLogEntry(Object* sender,
                         EntryWrittenEventArgs* e)
      {
        // Retrieve and work with the newly created entry...
        EventLogEntry* entry = e->Entry;
      }
    };
    
  2. Instantiate an EventLog object and set its EnableRaisingEvents property to true.
    The EventLog::EnableRaisingEvents property is a boolean type that controls whether or not events are raised after entries are added to the EventLog object's specified log:
    EventLog* log = new EventLog("Application");
    log->EnableRaisingEvents = true;
    
  3. Wire your event handler to the "new event log entry" event.
    First, instantiate the object that defines the event handler (NewLogEntryEventHandler, in this example) and then add its event handler method (OnNewLogEntry) to the list of event handlers for the EventLog::EntryWritten event:
    NewLogEntryEventHandler* handler = new NewLogEntryEventHandler();
    log->EntryWritten +=
      new EntryWrittenEventHandler(
        handler,
        &NewLogEntryEventHandler::OnNewLogEntry);
    
  4. Code the event handler to your specific needs.
    Looking back at the OnNewLogEntry method, you can see that the EntryWrittenEventArgs object passed to the event handler has a member called EventLogEntry that contains the specifics regarding the recorded event. This includes the following properties:
    • MachineName—The system name of the machine on which the event was created (see the Pitfalls and Caveats section for more information on this.)
    • Source—The event source (or application) that created the event.
    • Message—The user can read this textual value in the Event Viewer that describes the record event.
    • Event Type—This value (represented by the EventLogEntryType) is an enum that represents the type of event that was recorded: Information (the default), Warning, Error, SuccessAudit, and FailureAudit.
    • Event ID—This is an application-specific number for the event.
    • Data—This value is often used to store binary information—such as a memory dump—that is related to the event.

Pitfalls and Caveats

As you can see, .NET makes subscribing to event log events extremely easy. However, you should also know of a few limitations regarding handling event log notifications:

  • You can monitor events only on the local system.
  • The .NET documentation states that there is no guarantee that every single event will be raised if a large number of events are recorded in a short span of time.
  • If you are monitoring an especially busy event log, the event will sometimes not signal immediately, resulting in a lag between the time of the event entries and then a sudden burst of notifications for the events that had been queued.


About the Author

Tom Archer - MSFT

I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers. Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.

Comments

  • Reference from other article

    Posted by fmonroy on 09/25/2006 10:27pm

    Thank you Tom, I used your information provided in this article to write one about saving volume controls levels based on logon and logoff events, you can find it here: http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c12643/

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • Live Event Date: April 22, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Database professionals — whether developers or DBAs — can often save valuable time by learning to get the most from their new or existing productivity tools. Whether you're responsible for managing database projects, performing database health checks and reporting, analyzing code, or measuring software engineering metrics, it's likely you're not taking advantage of some of the lesser-known features of Toad from Dell. Attend this live …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds