关于DLL中DllMain的线程死锁问题

  前一阶段闲着无聊,用远程线程注入的方法把DLL注入到Explorer.exe进程实现音乐循环播放。

  在DLL中的代码是这样的:

BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad)
{
   
static HANDLE hThread;
    
static DWORD dwThreadId;
    
switch (fdwReason)
    {
    
case DLL_PROCESS_ATTACH:
        g_hInstDll 
= hInstDll;
        hThread 
= BEGINTHREADEX(NULL, 0, ThreadProc, (PVOID)hInstDll, 0&dwThreadId);
        
if (hThread == NULL)
        {
            
return FALSE;
        }
        
break;

    
case DLL_PROCESS_DETACH:
        SendMessage(g_hWnd, WM_CLOSE, 
00);
        WaitForSingleObject(hThread, INFINITE);    
// 这里存在死循环

        CloseHandle(hThread);    
// 执行不到这里
        break;

    
case DLL_THREAD_ATTACH:
        
break;

    
case DLL_THREAD_DETACH:
        
break;

    
default:
        
break;
    }
    
return TRUE;
}

  在DLL_PROCESS_ATTACH的时候创建了一个线程,这个线程中创建了一个隐藏的窗口,并利用MCI实现播放音乐,具体就不贴出了。然后在DLL_PROCESS_DETACH中停止和关闭设备。

  但是在应用程序中,发现注入时无异常,在需要撤销DLL映射时出现了问题,程序出现了死循环,在等待远程线程执行FreeLibaray完毕时不返回了。

  注意上面代码中DLL_PROCESS_DETACH的代码,SendMessage用来关闭窗口,窗口会在WM_DESTROY通知下调用PostQuitMessage(0)使得线程的消息循环退出,从而线程退出。但是WaitForSingleObject函数无法返回。

  后来发现这里存在死循环,因为执行DllMain的线程是序列化的,必须等待一个线程执行完毕之后另一个线程才能执行。在SendMessage后,导致创建的线程即将退出,这时该线程会调用DllMain,并以DLL_THREAD_DETACH作为通知。可是调用SendMessage的线程调用DllMain时却还在等待即将退出的线程结束,DllMain还没有返回,因此存在了死循环。

  因此,在DllMain中不适合调用WaitForSingleObject等函数来等待线程完毕。

posted on 2009-05-22 22:22 小虎无忧 阅读(1627) 评论(0)  编辑 收藏 引用 所属分类: DLL


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜