A COM class is code which is capable of instantiating or creating an object, or multiple objects for that matter. These objects can have methods and properties which allow manipulation of the object and or its contents. An example COM object which could be used with everyday use is the "FileSystemObject". Instantiation of a "FileSystemObject" will allow you to manipulate the file system using methods and properties of the "FileSystemObject".
The following example is how you could use an VBS API call to a COM class to instantiate the "FileSystemObject"
Set objFSO = CreateObject("Scripting.FileSystemObject")
A method is a function or piece of code which performs an action against an object created from a COM class. A common example of a method which is easy to relate to an everyday task is creating a folder.
Using the same "FileSystemObject" we can manipulate the file system or perform an action on that file system object using one of its methods.
Based on this using the object previous created objFSO we can now utilize a method to perform the required action in this case creating a folder. The method name is CreateFolder.
objFSO.CreateFolder("Your folder path would go here")
A property is a little simpler and acts simply like a variable would in any other coding language. A property can be set or retrieved using a syntax similar to the following.
To set a property a syntax similar to the following would be used.
objTest.Property = "Your New Value"
To retrieve a property a syntax similar to the following would be used.
strPropertyValue = objTest.Property
What is an API
An Application Programming Interface (API). The API made it easier for applications to integrate with the Operating System and also allowed for a scriptable interface to the application. Windows Installer has a very comprehensive API or COM class which allows accessibility to the entire Windows Installer Service and its applications via a scriptable interface. This will be covered heavily in a future blog or (my advanced courses).
To understand how an API works it is necessary to break down more of the components of a COM class and how they are written to the registry.
What is a Programmatic Identifier (ProgID). A ProgID acts in a very similar way to that which DNS acts with an IP address. Where DNS will resolve a DNS name to an IP address and vice versa. The ProgID can be likened to that of the DNS name.
The ProgID is a friendly name which relates to a ClassID (a value which is significantly harder to remember than a ProgID)
The ProgID is stored in the Windows Registry in the HKEY_CLASSES_ROOT hive.
An example of such a key is. [HKEY_CLASSES_ROOT\WindowsInstaller.Installer]
As mentioned previously the ProgID relates directly to a ClassID in the same way as DNS does an IP address. The diagram above shows a child key with the name CLSID. Selecting this item as shown in the following diagram will expose the CLSID entry which is related to the WindowsInstaller.Installer ProgID
A ClassID is a unique descriptor which identifies a COM class. These descriptors use a common naming structure known as a GUID in the case of a COM dll the GUID is a 32 bit Hexadecimal GUID.. A 32 bit GUID looks similar to the following item:
It is thought to be extremely rare if not impossible to randomly create two GUID's with the same details. The ClassID is stored in the Windows Registry in the hive HKEY_CLASSES_ROOT.
The following example shows the subkey's present for this particular ClassID.
A COM class has a few subkey's of particular interest to a packager and his associated support teams. One of these attributes in particular is: InProcServer32
These items are of particular interest as they are core in understanding a common problem often referred to as DLL Hell. The InProcServer32 key contains the path to the actual DLL itself, or to confuse things a little more can also contain a Windows Installer Darwin Descriptor.
As such the ProgID, ClassID and InprocServer32 keys are all heavily related. In this example we have learnt the following items about this particular COM class.
The COM class has a ProgID of:
That ProgID is related to this ClassID.
This ClassID has an InprocServer32 value of:
C:\WindowsSystem32\msi.dll as shown in the following table.
As such when an API call is made the following items occur.
Where an application or script uses an API call such as:
Set objWindowsInstaller = CreateObject("WindowsInstaller.Installer")
The operating system will first lookup the ProgID in the Windows registry, it will then cross reference the ProgID with its associated ClassID which will in turn look for an InProcServer32 value which will contain the path to the actual DLL which contains the COM class.
A simpler model of this is depicted in the following diagram.
A typelib file is used to assist with understanding the content within an unknown DLL. For example if a vendor write a COM class but doesn't want to disclose the source code they can generate a typelib file. The typelib identifies the content of the DLL without exposing the source. In lamens terms it sort of documents the content of DLL. Tools such as Visual Studios, Microsoft Basic editor leverage functionality in the typelib to expose methods and properties within the script editors.
How does this information get into the registry
One may ask how does this registry information get into the registry and what is its importance. Most of you are likely to of heard of a tool called REGSVR32.EXE maybe some of you have even used it yet not understood what it was actually doing behind the scenes.
REGSVR32.EXE is relatively simple to use, its purpose is to populate the HEY_CLASSES_ROOT registry hive with the information shown in the previous descriptions. In actual fact it can input considerably more information into the registry however that is best left for another lesson.
To run REGSVR32 you can use one of the following two command lines.
To register a DLL
REGSVR32.EXE /R <path to your dll that requires registration>
To unregister a DLL
REGSVR32.EXE /U <path to your dll that requires unregistered>
The only downside to the REGSVR32.EXE tool is it give very little information away as to what it is actually doing. There is however a solution to this mystery and that solution is WISECOMCAPTURE.EXE (only available to licensed Wise users).
WISECOMCAPTURE.EXE is a tool developed by Altiris / Wise which mimics that of REGSVR32.EXE and in addition it also creates a .REG file which can be used for the purpose of examining what happened during your registration process. This tool is really useful when troubleshooting specific DLL hell issues.
To run WISECOMCAPTURE.EXE you can use one of the following two command lines.
To register a DLL
WISECOMCAPTURE.EXE /R <path to dll> <path to output file .REG>
To unregister a DLL
WISECOMCAPTURE.EXE /U <path to dll> <path to output file .REG>
Why is all of this information important.
The importance of this information is heavily dependant on your role. For an application packager it is very important to know when a dll should be registered and even more importantly when it should not be registered.
A specific example of when not to register a DLL is when a DLL is present in System or System32 folder and another copy of the same DLL for some reason is delivered to the application directory. Such as "c:\program files\Your application".
Using this example lets trace back a few steps, registering a dll will add the following entries.
When registered in System32
If you registered the same dll into "c:\program files\myApplication\msi.dll"
Did anyone spot the similarities ? The only change in both instances the InProcServer32 entry has changed. This becomes problematic as the last registration of a DLL will rewrite the location of the InProcServer32 keys. Although initial inspection one would think this is not an issue. As both the file and its registration will be present. So what's the big deal?
The big deal actually doesn't rare its very ugly head until you uninstall the application which last registered the dll. Uninstalling the application is likely to remove the files from the program files location as its is highly unlikely a reference count exists. If it removes the file and any other application was reliant on it being present you now have a broken COM object. Or worse still if it removes the file and its registration you have even less information about that COM object.
So from a packagers perspective its very important to know when you should and shouldn't register a DLL.
If the file remained in System32 it is far less likely to be removed from a machine for a few reasons such as:
MSI Component Reference counting, Shared dll Reference counting.
What else should a packager be aware of ? Upgrading and downgrading DLL's is particularly problematic also. With old installation technologies such as SETUP.EXE an installer would simply drop a DLL with little or no regard to the version of such a DLL. These installers could cause al kinds of havoc particularly if a DLL was downgraded. As this would mean the DLL may have methods and properties which were simply no longer present within the dll. The upgrade on the other hand should support backwards compatibility particularly if the DLL is made by the same vendor, as such upgrade are often less problematic than downgrades.
With the advent of Windows Installer the downgrade of DLL's is considerably more controllable. As Windows Installer can be told to only allow upgrades of files and never allow a downgrade. (check out the REINSTALLMODE property in the SDK).
So what does all of this mean for a support person. A support person needs to know that older installation technologies can downgrade DLL's without warning. Where Windows Installer is concerned it is important a support person know how to control and suspend downgrading of a DLL.
Knowing how a DLL lookup is performed can allow reverse engineering and tracking of problematic and hidden DLL issues.
Ok I'm getting tired so moving on from here I will cover Isolation topics etc...