Professional System Library: Introduction

Foreword

Most software developers share the same pattern in their professional career of having to deal with projects of a similar nature, although a few developers manage to jump from one project to a completely different one.

Personally for me, I found one particular area that has always taken a great deal of my time from one project to another, and that’s coding around retrieving and changing information about the system/OS, about the current process, threads, various hardware and software configuration of the system, security context, and so on. I do hope this all sounds very familiar to many developers.

Not only does one have to spend some time trying to figure out how to access the same information required, depending on which development platform is being used, but also this knowledge is very hard to interpolate from one platform to another. For example, VC++, VB6, C#, Delphi, Office—all so different in every way, your code from one may seem totally unusable in the other.

Then, the complexity kicks in. If we can pull just about any trick in C++ in quite a natural way, doing the same things in more restrictive environments either impossible or breaks the seemingly integrity of the system, like using unmanaged code in .NET or lots of external procedure imports for VB6, and so on.

Out of systematic practice in various development environments came the idea to summarise all my knowledge in this area and offer software developers a simple and unified way in which all such information can be accessed easily, in the same way in any development environment, and with the very minimum of effort.

This whole article is an introduction to the initiative of writing a library that would allow easy access to most frequently used information in the system, client’s process, and environment.

It is a very recently started project (July 2008). All additional information about this project as well as the development efforts for it I am trying to organize on the www.prosyslib.org website.

Introduction

There are four ways in which an application can retrieve information from the system are as follows:

  1. Standard Windows API
  2. Undocumented Windows API
  3. Direct access to the system: Windows Registry + File System
  4. WMI (Windows Management Interface)

When it comes to choosing which method is best to use our choice depends mostly on the following criteria (given in the order in which your average developer looks at these things):

  1. Complexity of implementation
  2. Reliability
  3. Speed of execution
  4. Resource consumption

Professional System Library (ProSysLib) is a project that offers unification in accessing information about process/system/environment where the developer would no longer have to make a tough choice looking at these criteria trying to decide which one is most important or which can be sacrificed.

ProSysLib presents all information using the concept of a root namespace, very much similar to that in .NET where System is the root namespace for everything. Much like it, ProSysLib has its own System root namespace that defines the entry point for all the sub-namespaces and functionality of the library.

The picture at the beginning of this article shows the top hierarchy of namespaces below System. These define the basis for further classification of all the information that can be retrieved.

Technology Highlights

ProSysLib DLL is a Unicode COM in-process server that uses a Neutral memory model. It is Thread-Safe, and implements Automation interfaces only. The protocol (type library) declarations of 32-bit and 64-bit versions of the component are identical, thus allowing transparent integration with development tools that can mix 32-bit and 64-bit modes, while using the same type library (signature) of the component. ProSysLib is also immune to the DLL Hell problem (read ProSysLib SDK for details).

Implementation is done entirely in VC++ 2008, using only COM, ATL, STL, and Windows API.

The entire ProSysLib framework is based on Just-On-Time Activation, which means that each and every namespace and object is instantiated and initialized only when used by the client application for the first time; until then, ProSysLib is completely weightless resource-wise.

At the moment of publishing this article, only a few objects and namespaces of the library were introduced. As for the rest of the namespaces, properties and methods, if an application tries to use them, the library will throw the COM exception “NOT IMPLEMENTED” to tell you that you are trying to use something in the library that has been declared but not yet implemented.

Using the Code

Because the library concept is built upon a root namespace, it is the only interface that needs to be created by the client application to have access to everything else, much like System namespace in .NET. In fact, the foo-proof implementation of the library won’t let you create any other interface of the library even if you try.

Declaring and instantiating a variable in different development environments can look different from each other, although using it will look pretty much the same. In this article, you simplify all your code examples for C# clients only. Any developer should be able to work it out how this would look in his environment of choice.

// Declare and instantiate ProSysLib root namespace;
PSLSystem sys = new PSLSystem();

Now, by using this variable you can access anything you want underneath the root namespace.

Even though ProSysLib is targeted to implement access to many kinds of information, the project started only recently, and there are not that many features implemented so far. However, I did not want to draw abstractions with a finger in the air; one can figure them out by looking at the ProSysLib Documentation, so all the examples provided here below are real ones; in other words, they are fully functional already.

So, consider a few examples of what you can do with ProSysLib as of today, which is less than one month from the beginning of the project.

Privileges

Many applications need to know about and control the availability to the process privileges. For instance, the Debug privilege can be important when accessing some advanced information in the system that’s otherwise unavailable. ProSysLib provides a collection of all available privileges under the namespace of PSLSystem.Security.Privileges. If one needs to enable the Debug privilege in the process, the code would be as shown here:

sys.Security.Privileges.Find("SeDebugPrivilege").Enabled = true;

In other words, you access the collection of privileges, locate the privilege of interest, and enable it. You normally would need to verify that the Find method successfully located the privilege in the list, but because the Debug privilege is always available, you can simplify it here.

Process Enumeration

One of very popular subjects that can be found in articles here is about enumerating all available processes in the system, or finding a particular process, or how to kill a process by name, and the like. ProSysLib enumerates all processes running in the system under the PSLSystem.Software.Processes namespace. This collection is very flexible and allows any kind of operation one needs to do with processes in the system.

Attached to this article is a simple C# application that shows just one example of how ProSysLib can be used. The example enumerates either all processes or the ones that were launched under the current user account. It displays just some of the available information about each process, and allows killing any process with the press of a button.

Here is just a small code snippet from the example where you populate a list view object with information about processes:

// Go through all processes;
foreach (PSLProcess p in sys.Software.Processes)
{
   ListViewItem item = ProcessList.Items.Add(p.ProcessID.ToString());

   string sProcessName = "";
   if (p.ProcessID == 0)    // System Idle Process
      sProcessName = "System Idle Process";
   else
   {
       sProcessName = p.FileName;
       // If OS is 64-bit, and the found process
       // is not 64-bit, we add " *32" like in TaskManager;
       if (sys.Software.OS.Is64Bit && p.Is64Bit == false)
            sProcessName += " *32";
   }

   // Adding some of the available process details...
   //
   // NOTE: p.FilePath for 64-bit processes will always be
   // empty for a 32-bit client running on a 64-bit system,
   // simply because Windows prohibits 32-bit processes to
   // have any access to 64-bit-specific folders;

   item.SubItems.Add(sProcessName);
   item.SubItems.Add(p.FilePath);
   item.SubItems.Add(p.UserName);
   item.SubItems.Add(p.ThreadCount.ToString());
   item.SubItems.Add(p.HandleCount.ToString());

   // Associate each list item with the process object;
   item.Tag = p;
}

The demo application binary is provided both in 32-bit and 64-bit versions. One of the very interesting things about ProSysLib is that it offers new ways of efficient COM usage, bypassing the COM layer/requirements altogether. Both 32-bit and 64-bit versions will unpack and allow you to run the demo application, using ProSysLib COM library in spite of the fact that you do not register the component on your PC. If somebody assumes that this is COM Isolation for .NET, he would be wrong. This is an implementation of Stealth Deployment for COM, which I invented in my long practice of distributing COM projects. A full description of the idea is given in ProSysLib SDK, in the Deployment chapter.

More by Author

Must Read