How Old Is Your Type Library?

I ran into an interesting problem this week trying to get a legacy application running on Windows Vista. If you ran the installer, it would fail, claiming that it was unable to register a required component. So, I grabbed the ocx it was trying to install to have a look. Taking a peek by attaching a debugger to regsvr32, I could see that the component itself was just calling MFC42!AfxOleRegisterTypeLib, so it wasn’t trying to do anything strange inside of DllRegisterServer. So, what was the problem?

Well, you can take a peek at the source for MFC, and see that it just calls in to OLEAUT32!RegisterTypeLib, so I started by setting a breakpoint there. It was reading through the type library, added registry values for the typelib itself, but then choked when adding the interface registry entries. Specifically, it was failing at OLEAUT32!CTypeLib2::IsValidHinfoDef. It turns out that we changed the format for type libraries quite some time ago, and we stopped supporting the old format as of Windows XP (but it was working fine on Windows 2000). This ocx was using the old format, so it couldn’t register. How can you tell if your type library is doing the same thing? Set a breakpoint on OLEAUT32!CTypeLib2::IsValidHinfoDef and keep an eye on the EAX register. If you see it change from 0 to an HRESULT value (specifically 0x80004005), then it’s basically telling you that the type library is not valid.

Of course, understanding the issue is only half of the battle – if you are doing serious application compatibity work, you aren’t done until you have either fixed it or proven it unfixable. I hadn’t proven it unfixable yet, so I had to start thinking about how to fix it. The type library is embedded as a resource, so we could theoretically replace it, but first we have to generate a new one with the updated format.

So, I just walked over to a Windows 2000 machine and used OLEVIEW to crack the binary and extract the typelib. Conveniently, it generates IDL from the type library it finds. I then copied that IDL, stuck it on a USB drive, and brought it over to my Windows Vista box. After updating the IDL to be compliant with current formats, I ran it through MIDL.exe to generate a new type library. I then opened up the ocx in Visual Studio, which gives you a nice view of the resources in a file. I added the new tlb, deleted the old one, renumbered the tlb resource to 1, and saved. Voila – same binary, new (and valid) type library. Running regsvr32 this time succeeds – hooray! Now we just need to verify that the component we registered doesn’t have other compatibility issues!

Comments (4)

  1. Semyon A. Semakov says:


    it’s look like the hack, do You know any more "legal" solutions to this problem? I mean creation of valid type library without stealing auto-generated, right IDL from oleview.


  2. cjacks says:

    Well, obviously the best solution would be to have the vendor supply an updated version. Second to that would be to have the actual IDL itself. However, in many cases, this is simply not possible. I don’t really see how this is illegal (disclaimer: I am not a lawyer) based on the intent of a type library. Its purpose is to declare the publicly available interfaces that a COM component offers. It happens to be in a machine-readable format optimized for use by the operating system rather than by humans, but you are not reverse-engineering any functionality. Rather, you are just converting publicly declared functions from one machine-readable format to another machine-readable format. If the developer didn’t want you to know about the functionality, then they certainly wouldn’t have put it into a type library that advertises this functionality. Creating a COM Callable Wrapper in .NET similarly converts from one interface format to another – it just happens to have a tool that automates the process.

  3. Frank says:

    How could I determine if the Microsoft Outlook 2002 Type Library, msoutl.olb, ProductVersion = 10.0.2607 is the old or new version. I have a customer that has a problem with this library – receivng error 0x80029C4A.

  4. cjacks says:

    Hi Frank,

    You wouldn’t be able to register it at all if it’s using the deprecated format. This error is TYPE_E_CANTLOADLIBRARY, and comes from the type library API. I’d need to see it with a debugger to find out more.