mwasoftware.co.uk

DLL Hell is a cruel and unusual form of punishment that came about as a consequence of the way DLLs work and are installed on Windows. Different installers can often interfere with each other, existing programs and Windows itself, through a mixture of stealth upgrades, downgrades and just by deleting files they shouldn't delete. The Windows Installer framework has done a lot to remove much of the worst of DLL Hell, but there are still several Elephant traps waiting for the unwary and this article attempts to document those that are waiting for the installer of Firebird Client Applications.

As is usual with such blogs, do not assume I am right - I may be wrong. You should always verify the advice given here before using it. Please let me know of any errors or omissions.  

Firebird Client DLLs

The first problem you have is that there are two - arguably three -  DLLs that you really have to manage carefully if you are not going to end up with a broken installation. These are, in no particular order:

  • fbclient.dll: 
This is the standard client library used to access Firebird databases via a Firebird Server. The Server is usually on a different system - but doesn't have to be - and the normal resting place for this dll is in the Firebird "bin" folder (e.g. c:\Program Files\Firebird\Firebird_1_5\bin). It may also be found in the Windows System32 folder or in an application installation folder.
  • fbembed.dll
This is the Firebird embedded server. It does all that fbclient.dll will do for you plus it can access a local Firebird Database without having to go through a separate server. Normal file system access controls then apply for access to local databases, rather than the username/password controls that the normal server uses.. Its normal resting place is the application installation folder. fbembed.dll is often renamed to fbclient.dll or gds32.dll to make it interchangeable with an application designed to use the normal client  dll.
  • gds32.dll
This is the old name for the client dll and is the name still used by InterBase for its client library. Traditionally, this was installed in the Windows System32 folder, but can also be found in the application installation folder. fbclient.dll is often renamed "gds32.dll" when it is used to support Delphi applications that use IBX. It is typically also patched to version 6.3.x so that it is accepted by the Delphi 7 version of IBX. However, this is not necessary for later versions.

 

So: What can go wrong?

Just about anything, stealth upgrades and downgrades, confusion with InterBase 7 and lots of problems that come from renaming the dlls. Firebird 2 has not helped by changing the installation folder for Firebird but retaining the same registry entry name. Here's my list of the problems you may come up against:

1. fbclient.dll stealth upgrades from 1.5 to 2.0 or later.

Generally not a big problem (so far) as Firebird 2 fbclient.dll seems to be reasonably backwards compatible with firebird 1.5. A stealth upgrade can occur when you install fbclient.dll in the Windows System32 folder or the Firebird bin folder. If it's in Windows System32 then you are always vulnerable to another installer coming along and upgrading you. That's just life. It can also happen if you install the dll in the Firebird installation folder and use the Firebird SQL registry key to find it. A Firebird 2 installer can legitimately come along, install a new copy in the Firebird2 installation directory and update the registry entry to point to the new folder. Your dll is still on the system but you won't find it. The same can also happen if you rely on the Environment Path to find the dll as that can just as easily be redirected to the new installation folder. The safest way to avoid a stealth upgrade is to locate fbclient.dll in your application installation folder.

2. fbclient.dll stealth downgrades from 2.0 to 1.5.  

This can be much nastier if you are relying on using the Firebird 2 dll and suddenly you get the Firebird 1.5 dll. If you are using Windows Installer then an older dll should not overwrite a later dll, but you are still at risk of someone using a broken installation script from another source. However, the big risk is of an installation of a Firebird 1.5 client into its standard folder (which is not the same as the Firebird 2 installation folder and hence won't be trapped by Windows Installer) and then the installer overwriting the registry key that you were using to find the dll, or switching the environment path. Windows Installer does not protect either of these and if the writer of a Firebird 1.5 installation package did not foresee that the installation folder could change while the registry did not, then this can easily happen. An apology - I did not foresee this event in my Firebird 1.5 merge modules prior to the new 1.5.4 modules (20-20 hindsight is a gift only given to critics and lawyers) - and now you know why these Merge Modules come labeled with NO WARRANTEE. Again, the safest way to avoid a stealth upgrade is to locate fbclient.dll in your application installation folder.

3. gds32.dll confusion

If you rename fbclient.dll to gds32.dll and patch it to version 6.3 - so that Delphi 7 doesn't complain - then you are at risk as soon as you put it in the Windows System32 folder. This is a sensible place for a development computer but not on a user system. In Windows System32 you are always at risk from an InterBase 7 application installing a version 7 of this dll and throwing yours away. The more Firebird and InterBase diverge the worst are the consequences. If you need to rename fbclient to gds32 then put it in your application installation folder.

Even here is not ideal. Patching the version needs to be done carefully so that when you want to install a later version you can do so without causing problems with Delphi 7. Rename it to 6.3 but make sure that the last number in the version number sequence is the Firebird build number. At least then you will have a reasonable chance of being able to upgrade it when the time comes.

4. fbclient and fbembed confusion

The easy way to use fbembed.dll is to rename it fbclient.dll (or even gds32.dll). Ok this works, and as long as it is done for consenting applications in the privacy of their own installation folder then no harm should follow. But don't put it anywhere else. Put a renamed fbembed in the Windows System folder and you are at risk of a stealth upgrade to the real fbclient.dll. The same is true of the Firebird installation folder. If your users can choose the installation folder then you are also at risk of a user installing a similar application in the same folder but with the normal fbclient.dll and creating hours of fun for  your support desk. If your application uses the embedded server then why not just load fbembed.dll

5. firebird.msg and firebird.conf confusion

Putting fbclient.dll in your application installation folder insulates you from many of the problems discussed above but there is a still another gotcha waiting for the unwary. This is the location of the firebird.msg  and the firebird.conf files. Both fbembed.dll and fbclient.dll want access to both of these files, but they differ in how they locate them.

Both start by checking the FIREBIRD environment variable. If this is set then it is assumed to be the path for the folder in which these files are located. If this is not set then fbembed.dll looks in the same folder in which it is located. On the other hand, fbclient first checks the registry key HKLM\SOFTWARE\Firebird Project\Firebird Server\Instances\DefaultInstance and, if this is present assumes that its value is the full pathname for the folder in which it can find these files. Otherwise, it looks in the parent folder for the application executable.

For fbembed.dll it is usually safe enough to to place firebird.msg  and the firebird.conf in the application installation folder alongside fbembed.dll. However, with fbclient.dll you are at risk from stealth upgrades and downgrades replacing them or redirecting the registry to a different version. For most installations this won't be much if a problem. With firebird.msg the worse case should be that an error message text is missing. However, if you rely on firebird.conf for, for example, a non-standard tcp port setting then you are at risk.

If you place fbclient.dll in the application installation folder then the safest thing to do is to place firebird.msg  and the firebird.conf in the application installation folder alongside fbclient.dll and before you call the dll from your application, set the FIREBIRD environment variable to the path to the installation folder.

Do's and Don'ts

So what's my conclusion from all this:

  1. Don't use my fbclient merge module to support your applications. Leave this to support Server installations and the command line tools.
  2. Always install fbclient.dll or fbembed.dll in the application installation folder rather than Windows System32 or the Firebird Installation Folder.
  3. With fbembed.dll you need also to install its support files including firebird.msg and firebird.conf in the same folder.
  4. With fbclient.dll also install firebird.msg and firebird.conf in the same folder and set the FIREBIRD environment variable to the full path of the folder.
  5. When your application is designed to be installed with the embedded server then load fbembed.dll. Don't rename it to fbclient.dll.
  6. If you are using Delphi 7 then you either have to hack the IBX source, or rename fbclient or fbembed to gds32.dll and patch it to version 6.3. If you do always install it in the application installation folder. For Delphi 2005 and later, there is a better way.

Firebird 2.0 and later also require that fbclient.dll is distributed with support dlls.