SetWindowsHookEx与全局共享钩子

来源:互联网 发布:js修改style display 编辑:程序博客网 时间:2024/06/01 07:41

SetWindowsHookEx与全局共享钩子

对于远程钩子,钩子函数必须放到DLL中,它们将从DLL中映射到其它的进程空间中去。当WINDOWS映射DLL到其它的进程空间中去时,不会把数据段也进行映射。简言之,所有的进程仅共享DLL的代码,至于数据段,每一个进程都将有其单独的拷贝。这是一个很容易被忽视的问题。您可能想当然的以为,在 DLL中保存的值可以在所有映射该DLL的进程之间共享。在通常情况下,由于每一个映射该DLL的进程都有自己的数据段,所以在大多数的情况下您的程序运行得都不错。但是钩子函数却不是如此。对于钩子函数来说,要求DLL的数据段对所有的进程也必须相同。这样您就必须把数据段设成共享的,这可以通过在链接开关中指定段的属性来实现。

#pragma   data_seg("Shared")
HINSTANCE g_hInstance = NULL;
HHOOK       g_hHook = NULL;
HWND         g_hWnd = NULL;
#pragma   data_seg()
#pragma   comment(linker,"/SECTION:Shared,RWS")  

Shared代表该段是共享段。

例子:
一共有两个模块:一个是GUI部分,见光盘D:\mybook\examples\FirstWindow22\exe
另一个是安装和卸载钩子的DLL,见光盘D:\mybook\examples\FirstWindow22\dll

dll代码:
#include "windows.h"
#define WM_MOUSEHOOK WM_USER+6

#pragma   data_seg("Shared")
HINSTANCE g_hInstance = NULL;
HHOOK       g_hHook = NULL;
HWND         g_hWnd = NULL;
#pragma   data_seg()
#pragma   comment(linker,"/SECTION:Shared,RWS")  

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hInstance = (HINSTANCE)hModule;
return TRUE;
}

LRESULT CALLBACK MouseProc(          int nCode,
WPARAM wParam,
LPARAM lParam
)
{
CallNextHookEx(g_hHook,nCode,wParam,lParam);
LPMOUSEHOOKSTRUCT ps = (LPMOUSEHOOKSTRUCT)lParam;
HWND hWnd = WindowFromPoint(ps->pt);
PostMessage(g_hWnd,WM_MOUSEHOOK,(WPARAM)hWnd,0);
return 0;
}

HHOOK InstallHook (HWND hWnd)
{
g_hWnd = hWnd;
g_hHook = SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0);
return g_hHook;
}

void UninstallHook()
{
UnhookWindowsHookEx(g_hHook);
}

原创粉丝点击