部分代码如下:
(不知道为什么,当调用他的程序退出后,此dll并没有从内存中卸载。当我们想删除他时系统提示正在被windows使用不能删除,如果把钩子去掉就不存在这个问题了。请各位大侠指教!!!)#pragma data_seg(".shared")     
HHOOK mhkb = NULL;
HHOOK hkb = NULL;
#pragma data_seg()BOOL g_IsHookingProcess = FALSE;BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  reasonForCall, 
                       LPVOID lpReserved )
{
HMODULE originDll = NULL;
    switch (reasonForCall)
{
case DLL_PROCESS_ATTACH:

//alloc Thread Local Storage slot.
g_TlsIdxThreadArea = ::TlsAlloc();
ThreadAreaInit();

//InitAll();

GetSystemDirectory(g_DllPath, MAX_PATH);
strcat(g_DllPath, "\\OpenGL32.dll");
LoadLibrary(g_DllPath);

//initialize critical section
if (::InitializeCriticalSectionAndSpinCount(&g_CS, 0) == NULL)
CatchErr(NOT_ENOUGH_MEMORY,__FILE__,__LINE__);
hins = (HINSTANCE)hModule;
if (hkb)
return FALSE;
g_IsHookingProcess = true;
hkb = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
mhkb = SetWindowsHookEx(WH_CALLWNDPROCRET,(HOOKPROC)CallWndRetProc,hins,0); break; case DLL_THREAD_ATTACH:
ThreadAreaInit();
break; case DLL_THREAD_DETACH:
ThreadAreaClean();
break;

case DLL_PROCESS_DETACH:
if(g_IsHookingProcess && hkb)
{
g_IsHookingProcess = false;
WriteLogTail();
WriteMaxMem();
UnhookWindowsHookEx(hkb);
UnhookWindowsHookEx(mhkb);
hkb = 0;
mhkb = 0;
::DeleteCriticalSection(&g_CS);
ThreadAreaClean();
::TlsFree(g_TlsIdxThreadArea);


delete g_pLogGen;
}
break; default: 
break;
    }
    return TRUE;
}

解决方案 »

  1.   

    加上:
    #pragma comment(linker, "/section:.shared, rws")
      

  2.   

    而g_IsHookingProcess,变量是根本用不着的,而且会出现错误,如果在你的应用程序之前有另外一个程序退出,则此应用程序同样会Unhook掉你所装的Hook,这时Hook被Unload,hkb变成了NULL,
    所以你的::DeleteCriticalSection(&g_CS);ThreadAreaClean();::TlsFreeg_TlsIdxThreadArea);等函数就不会调用。当然,也就造成了Memory Leak。所以,
    在你的DllMain函数中,在DLL_PROCESS_ATTACH,DLL_PROCESS_DETACH会造成钩子的多次安装及多次Unload,其行为是未定义的,此时,最好提供两个显式函数,分别进行Setup和Unload Hook的工作。当然,以上讲的全是全局钩的情况,在局部钩中,虽然如你所写并无错误,但局限性则也太大了。不知你写的是一个全局钩还是局部钩?