获取COM对象的DLL文件,而不使用CLSID和注册表在c ++ [英] Get the DLL-file for a COM-Object without using CLSID and registry in c++
问题描述
可以在不使用CLSID和注册表查找的情况下获取加载的COM对象的DLL文件名吗?
Is it possible to get the DLL-filename for a loaded COM-Object without using the CLSID and a registry lookup?
我有一个 IUnknown
或在我的情况下一个 IBaseFilter
接口指针,现在我想获得创建此COM对象的DLL文件名。我可以使用对象点地址来反向查找已创建模块的已加载模块吗?然后在 GetModuleFileName
中使用 HMODULE
。
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
.
推荐答案
自然只使用一些黑客。对象本身在堆上,是共享的,但你可以看到它的虚拟表的位置 - 它应该几乎普遍在创建者的二进制文件的只读数据部分。
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.
因此,在对象中加载第一个指针,因为虚拟表指针驻留在Windows COM ABI中:
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);
然后我最初建议用 EnumProcessModules c $ c> like eg 此处,调用
GetModuleInformation( )
,并检查 vtbl
指针是否落入其内存范围。愚蠢的我,我忘了 VirtualQueryEx()
,所以更好地做罗马描述在他的答案。
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.
当然,所有这些都只能用于进程中的COM对象,并且没有涉及到的代理。我认为它仍然可以在你的DirectShow案例中有用。
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.
还可以看到关于使用 IPersist :: GetClassId $ c>和注册表查找,它应该适用于大多数DirectShow过滤器。
Also see the comment about using IPersist::GetClassId()
and registry lookup, it should apply nicely to most DirectShow filters.
这篇关于获取COM对象的DLL文件,而不使用CLSID和注册表在c ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!