( Index )
Month

Brief Information about the May '09 CSIG Meeting

Using the Windows Event Logs
B. Arnold

TestMay Event Viewer Event Viewer

Welcome to the CSIG, a Special Interest Group of the ACGNJ. This is an exciting time for the C Language programming since Microsoft now has 4 different language compilers: C++, C++ Express, C-Sharp, and C-Sharp Express. These are all capable of creating Windows (tm) programs.

Here's a brief synopsis:

The Dot-Net C++ libraries provide many functions for accessing and using the Event Logs.
We will discuss a few of them as well as see the security pitfalls for Windows 7 and Vista.

The program for this month is called TESTMAY. (Well, the name comes from the fact that I'm testing something and that this is the month of May.) But, this is a very interesting program. It's a program that writes to the Event Viewer. Now, anyone who's done diagnostics on Windows TM machines from Windows 2000 all the way up to Windows 7, knows that the Event Viewer is very powerful and that there are hundreds, perhaps thousands of messages that appear there. It's a perfect place to store information. The Event Viewer includes several different Logs: an Application log, a Security log, a System log, an Internet Explorer log and others. Wouldn't it be nice if Your Program could use, let's say, the Application Log of the Event Viewer to record diagnostic information for future reference. Well, that's what this program does, and in the next paragraph I'll discuss some of the problems that I experienced.

Security Issues: when you run this program on Windows Vista or Windows 7 you find what appears to be a "Catch-22" problem. In order to write to the Registry and to the Event Viewer, you must register the source program that's doing the writing (that's your program). The first thing to do is to check if the program has been previously registered. But, it turns out that unless you are an Administrator, you can't even do the checking. Almost anything that you try produces a system error message regarding permissions. Here's the algorithm that I created to deal with this.

The program must be run once as the Administrator. When the program starts, it "catches" the errors that are created and advises the user to first run the program as the Administrator. This is the only time that they will have to do this. This is almost like "Installing" the program, but the program doesn't get installed because it just a simple stand-alone executable. Once this has been done, the second time the program starts, low and behold, the check to see if the program has been registered allows you to query that status (even though you are not an Administrator). So, we have gotten past the catch-22 and we can just use normal writing code to write information to the Event Viewer. The basic function that we will be using is called "WriteEntry() " which is very simple and allows you to add text information into the Application Log of the Event Viewer. The key to this whole thing is how you get past those initial errors when the program is used for the first time.

Along the way to developing this code, I thought that I would simply check if the user was an Administrator. Although the code for this plays only a minor role in my solution, it may be quite valuable for a future program. See sample code below.

Note: Microsoft provides a deluxe program called "InstallShield" that also solves this problem and provides many, many other features. Hopefully, in the future, we will also discuss this major topic.


There are a number of ways to refer to Microsoft's latest compilers and code. Here's what Wikipedia says: The Common Language Infrastructure (CLI) is an open specification developed by Microsoft that describes the executable code and runtime environment that form the core of the Microsoft .NET Framework. The specification defines an environment that allows multiple high-level languages to be used on different computer platforms without being rewritten for specific architectures.

Microsoft .Net Framework 3.5
C++ 9.0
.Net 3.5
CLI
Common Language Infrastructure
Managed

Sample Code

 // STEP ONE - INSTALLATION BY ADMINISTRATOR
 try
 {
   if (  !EventLog::SourceExists( eventLog1->Source ) ) // Program was never installed.
   {
     try
     {
       EventLog::CreateEventSource( eventLog1->Source, eventLog1->Log );
       // Operating System needs about 5 seconds of time to create.
       MessageBox::Show("The Event Source has been created. Program may be run normally.");
     }
     catch(...)
     {
       MessageBox::Show("Source (1) could not be created.", eventLog1->Source);
       if (!IsAdministrator()) MessageBox::Show("You must be a System Administrator.");
     }
     this->Close();  // "That's All Folks!"
   }
 }
 catch(SecurityException^ exception)  // Land here when the program is run the first time.
 {
   // MessageBox::Show(exception->ToString());
   MessageBox::Show("Check for source registration failed. Run once as as Administrator");
   this->Close();  // "That's All Folks!"
 }

//
// Check if the user is an Administrator. Return true if so.	B.Arnold 5/2009
//
bool IsAdministrator(void)
{
 try
 {
   Security::Principal::WindowsIdentity ^ user = Security::Principal::WindowsIdentity::GetCurrent();
   Security::Principal::WindowsPrincipal ^ wp = gcnew Security::Principal::WindowsPrincipal(user);

   if (wp != nullptr && wp->IsInRole("BUILTIN\\Administrators"))
   {
     // MessageBox::Show("Yes, Administrator");
     return true;
   }
   else
   {
     // MessageBox::Show("Woa, you are not an administrator.");
     ;
   }
 }
 catch (...)
 {
   // MessageBox::Show("Unable to access the roles service.", "Warning", MessageBoxButtons::OK);
   ;
 }
 return false;
}

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ i e e e . o r g
Back to C++ Main Page