Search code examples
comclsid

Given a Win32 COM interface locate its typelib


Consider the IUniformResourceLocator Interface defined in intshcut.h. I know how to manually define it for managed COM interop, but I'm trying to understand if I can get tlbimp to do that for me. Here's what I've tried:

  • Search the web - I can only find the header file and CLSID
  • Search the registry for the CLSID - I only found it in a ShellEx folder, no binary path
  • findstr [CLSID] /s *.* of the in both the system32 and Windows SDK folders

Is there in fact a type library definition for it somewhere (possibly as a resource of some dll or exe) ? If so, how can I fid it?


Solution

  • You can tell from the intshcut.h SDK header file that there is no point in looking for a type library.

    The normal source of type libraries in Microsoft code is midl.exe, the compiler that translate declarations written in IDL, the Interface Description Language. This starts with an .idl file, the SDK has a bunch of them included, although not consistently. Midl auto-generates a .h file from the IDL, you can recognize them by the autogenerated /* this ALWAYS GENERATED file contains the definitions for the interfaces */ comment. That .h file is suitable for C or C++. And it generates a type library, often embedded as a resource in a DLL, suitable for other languages.

    You can locate such a type library by looking in the registry with Regedit.exe. Starting point is the HKLM\Software\Classes\Typelib key, look for the guid that matches the [uuid] attribute on the library keyword in the IDL.

    But type libraries have limitations, they were originally designed to support the Automation subset well but cannot express every possible declaration. The need to interop with any language can be very restrictive or cause too much overhead to be considered suitable. So a Microsoft programmer not uncommonly hand-crafts a .h file. Still using the COM programming style with interfaces derived from IUnknown but not using IDL to declare them. The most common examples are the shell interfaces and DirectX.

    Summarizing, strong hints that you'll have little hope of finding a type library:

    • Interfaces that derive from IUnknown instead of IDispatch. IDispatch is the favorite base interface for Automation, it supports late binding. The kind that scripting languages use
    • A .h file that was not auto-generated by midl.exe, providing a strong hint that IDL wasn't used
    • The lack of a .idl file. Not a complete slamdunk, Microsoft sometimes ships only the .h file that was generated from .idl for reasons that are not clear to me
    • The presence of cpp_quote() in the IDL. It is a backdoor to inject C++ declarations into the generated .h file, the kind that cannot be easily declared in IDL. Not a slamdunk, but a strong signal you'll have trouble consuming the library in a language other than C++.
    • The presence of factory functions that return an interface type. A very strong hint that the normal COM class factories are not used to create a co-class, the kind that you invoke with the CoCreateInstance() function
    • The presence of native Windows typedefs in the .h file, like HWND and LPCWSTR. Or arrays that are passed as a raw pointer. They are not Automation compatible.

    The intshcut.h header file hits almost all of these bullets. You'll have to craft the [ComImport] interface declarations by hand. Yes, very painful, small mistakes produce very hard to diagnose runtime errors. Do keep in mind that there might well be another programmer somewhere that did what you want to do. With some luck, Google will help you find his code. And keep in mind that you can always fall back to C++/CLI, a language that is very good at this kind of interop because it can directly consume the .h file.