Search code examples
comportable-executablecom+tlbinf32

Get importlib directives from type library


How can one programmatically determine which type libraries (GUID and version) a given native, VB6-generated DLL/OCX depends on?

For background: The VB6 IDE chokes when opening a project where one of the referenced type libraries can't load one of its dependencies, but it's not so helpful as to say which dependency can't be met--or even which reference has the dependency that can't be met. This is a common occurrence out my company, so I'm trying to supplement the VB6 IDE's poor troubleshooting information.

Relevant details/attempts:

  • I do have the VB source code. That tells me the GUIDs and versions as of a particular revision in the repo, but when analyzing a DLL/OCX/TLB file I don't know which version of the repo (if any--could be from a branch or might never have been committed to a branch) a given DLL/OCX corresponds to.
  • I've tried using tlbinf32.dll, but it doesn't appear to be able to list imports.
  • I don't know much about PE, but I popped open one of the DLLs in a PE viewer and it only shows MSVBVM60.dll in the imports section. This appears to be a special quirk of VB6-produced type libraries: they link only to MSVBVM60 but have some sort of delay-loading mechanism for the rest of the dependencies.
  • Even most of the existing tools I've tried don't give the information--e.g., depends.exe only finds MSVBVM60.dll.
  • However: OLEView, a utility that used to ship with Visual Studio, somehow produces an IDL file, which includes the importlib directives. Given that VB doesn't use IDL files, it's clearly generating the information somehow. So it's possible--I just have no idea how.

Really, if OLEView didn't do it I'd have given it up by now as impossible. Any thoughts on how to accomplish this?


Solution

  • It turns out that I was conflating basic DLL functionality and COM. (Not all DLLs are COM DLLs.)

    For basic DLLs, the Portable Executable format includes a section describing its imports. The Optional Header's directory 1 is about the DLL's imports. Its structure is given by IMAGE_IMPORT_DESCRIPTOR. This is a starting point for learning about that.

    COM DLLs don't seem to have an equivalent as such, but you can discover which other COM components its public interface needs: for each exposed interface, list out the types of their properties and their method arguments, and then use the Registry to look up where those types come from. tlbinf32.dll provides some of the basic functionality for listing members, etc. Here's and intro to that.