c++ - DllMain 在注册 COM dll 时卡住

标签 c++ windows dll com regsvr32

我尝试注册一个名为 MixCenter.dll 的 COM dll。我已经找到了它所依赖的所有 dll。当执行官第一次使用它的 DllMain 时,它会卡住并且永远不会返回。这似乎是一个死锁,但我没有调用任何 LoadLibrary,它也永远不会执行到 DllMain。这种情况还有其他原因吗?这就是 DllMain 的样子:

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)  
{  
    switch(ul_reason_for_call)   
    {  
        case DLL_PROCESS_ATTACH:   
            g_hinstDLL = hModule;  
            LOG(INFO) <<"--------------Begin Logging--------------";  
            return DllEntryPoint((HINSTANCE)hModule, ul_reason_for_call, lpReserved);  
        case DLL_THREAD_ATTACH:   
            break;  
        case DLL_THREAD_DETACH:   
            break;  
        case DLL_PROCESS_DETACH:   
            LOG(INFO) << "--------------End Logging--------------";  
            break;  
    }   
    return true;  
}

我使用 Dependency Walker 记录了整个执行过程,日志的基本部分是:

LoadLibraryExW("MixCenter.dll", 0x00000000, LOAD_WITH_ALTERED_SEARCH_PATH) called from "REGSVR32.EXE" at address 0x003920FF by thread 1.  
Loaded "MIXCENTER.DLL" at address 0x10000000 by thread 1.  Successfully hooked module.  
Loaded "MSVCR80.DLL" at address 0x6F250000 by thread 1.  Successfully hooked module.  
Loaded "D3D9.DLL" at address 0x6C130000 by thread 1.  Successfully hooked module.  
Loaded "D3D8THK.DLL" at address 0x73490000 by thread 1.  Successfully hooked module.  
Loaded "D3DX9_40.DLL" at address 0x69B00000 by thread 1.  Successfully hooked module.  
Loaded "MSVCP80.DLL" at address 0x71430000 by thread 1.  Successfully hooked module.  
DllMain(0x6F250000, DLL_PROCESS_ATTACH, 0x00000000) in "MSVCR80.DLL" called by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "FlsAlloc") called from "MSVCR80.DLL" at address 0x6F253001 and returned 0x75CE8731 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "FlsGetValue") called from "MSVCR80.DLL" at address 0x6F25300E and returned 0x75CE0DC7 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "FlsSetValue") called from "MSVCR80.DLL" at address 0x6F25301B and returned 0x75CE2904 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "FlsFree") called from "MSVCR80.DLL" at address 0x6F253028 and returned 0x75CE2AD7 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "InitializeCriticalSectionAndSpinCount") called from "MSVCR80.DLL" at address 0x6F259668 and returned 0x75CE0D2B by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252BBC and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.    
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252C33 and returned 0x775FF050 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "EncodePointer") called from "MSVCR80.DLL" at address 0x6F252D3A and returned 0x77603275 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "DecodePointer") called from "MSVCR80.DLL" at address 0x6F252D4A and returned 0x775FF050 by thread 1.
GetProcAddress(0x75C90000 [KERNEL32.DLL], "IsProcessorFeaturePresent") called from "MSVCR80.DLL" at address 0x6F26A967 and returned 0x75CE0DD4 by thread 1.  
GetProcAddress(0x75BC0000 [MSVCRT.DLL], "_set_error_mode") called from "MSVCR80.DLL" at address 0x6F254447 and returned 0x75BD4A3D by thread 1.  
GetProcAddress(0x75BC0000 [MSVCRT.DLL], "?set_terminate@@YAP6AXXZP6AXXZ@Z") called from "MSVCR80.DLL" at address 0x6F254463 and returned 0x75BEEBB7 by thread 1.  
GetProcAddress(0x75BC0000 [MSVCRT.DLL], "_get_terminate") called from "MSVCR80.DLL" at address 0x6F25447F and returned NULL by thread 1. Error:  (127).
GetProcAddress(0x75C90000 [KERNEL32.DLL], "FindActCtxSectionStringW") called from "MSVCR80.DLL" at address 0x6F251DBE and returned 0x75CE18F9 by thread 1.  
GetProcAddress(0x75C90000 [KERNEL32.DLL], "GetSystemWindowsDirectoryW") called from "MSVCR80.DLL" at address 0x6F251F1A and returned 0x75CE0E64 by thread 1.  
DllMain(0x6F250000, DLL_PROCESS_ATTACH, 0x00000000) in "MSVCR80.DLL" returned 1 (0x1) by thread 1.  
DllMain(0x73490000, DLL_PROCESS_ATTACH, 0x00000000) in "D3D8THK.DLL" called by thread 1.  
DllMain(0x73490000, DLL_PROCESS_ATTACH, 0x00000000) in "D3D8THK.DLL" returned 1 (0x1) by thread 1.  
DllMain(0x6C130000, DLL_PROCESS_ATTACH, 0x00000000) in "D3D9.DLL" called by thread 1.  
DllMain(0x6C130000, DLL_PROCESS_ATTACH, 0x00000000) in "D3D9.DLL" returned 1 (0x1) by thread 1.  
DllMain(0x69B00000, DLL_PROCESS_ATTACH, 0x00000000) in "D3DX9_40.DLL" called by thread 1.  
DllMain(0x69B00000, DLL_PROCESS_ATTACH, 0x00000000) in "D3DX9_40.DLL" returned 1 (0x1) by thread 1.  
DllMain(0x71430000, DLL_PROCESS_ATTACH, 0x00000000) in "MSVCP80.DLL" called by thread 1.  
DllMain(0x71430000, DLL_PROCESS_ATTACH, 0x00000000) in "MSVCP80.DLL" returned 1 (0x1) by thread 1.  
DllMain(0x10000000, DLL_PROCESS_ATTACH, 0x00000000) in "MIXCENTER.DLL" called by thread 1.  

最佳答案

DllMain 中有很多事情是不能做的。您不仅不能自己调用​​ LoadLibrary,而且您也不能做任何会导致调用 LoadLibrary 的事情,并且注册一个 COM 服务器听起来很容易做LoadLibrary 在某个时候。

但这还不是你在DllMain中不能做的事情的程度。该列表又长又复杂,因此最好的办法通常是使用两阶段初始化方案,其中 DllMain 只是设置一个标志,然后 DLL 中的一些其他代码将执行复杂的操作初始化。这个“其他代码”可能是您的 DLL 中的另一个线程,或者它可能只是一个 Init() 函数,您在调用 DLL 的主例程时调用它们。

关于c++ - DllMain 在注册 COM dll 时卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5622759/

相关文章:

deployment - 一个大的可执行文件还是许多小的DLL?

c# - FatSecret C# 包装的 api 在 WPF 中返回空响应

c++ - 链接到某物是什么意思?

c++ - 如何向 C 窗口中的几个对等点发送多播消息

python - 无法在 Apache、WSGI、Django 和 Windows 中加载虚拟环境

windows - 如何关闭 Windows 机器上的套接字?

c++ - 进程返回 255 <0xFF>,c++,程序停止工作

c++ - 遍历字符串和 switch 语句 : C++

windows - BAT 脚本发送命令给它启动的程序

python - 未解析的外部符号构建 Python C 扩展