Search code examples
c++dllcomdirectshow

Get the DLL-file for a COM-Object without using CLSID and registry in c++


Is it possible to get the DLL-filename for a loaded COM-Object without using the CLSID and a registry lookup?

I have an IUnknown or in my case an IBaseFilter interface pointer and now I want to get the DLL-filename who created this COM-Object. Can I use the object point adress to reverse lookup the loaded module where it was created? And then get the HMODULE to use it in GetModuleFileName.


Solution

  • Only using some hacks, naturally. The object itself is on the heap, which is shared, but you could see where the its virtual table resides - it should be almost universally in the read-only data section of the creator's binary.

    So load the first pointer in the object, as that's where virtual table pointers reside in Windows COM ABI:

    IBaseFilter* pFilter = ...;
    char* vtbl = *reinterpret_cast<char**>(pFilter);
    

    Then I originally suggested to do some circus with EnumProcessModules() like e.g. here, call GetModuleInformation() on each module and check if the vtbl pointer falls into its memory ranges. Stupid me, I forgot about VirtualQueryEx(), so better do it as Roman described in his answer.

    Of course, all this can work only for in-process COM objects and where there are no proxies involved. I assume it can still be useful in your DirectShow case though.

    Also see the comment about using IPersist::GetClassId() and registry lookup, it should apply nicely to most DirectShow filters.