Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SetWindowsHook stops working after some time

I defined a global hook on WM_MOUSE that works perfectly for some time. It post a message to a specific window each time the mouse move.

After some random time the hook stop sending messages. If I unregister and register the hook it works again. I suppose some specific thing happening in Windows cause the hook to stop, but I can't find what.

Any ideas ?

Edit: I attached a debugger to other processes when the hook is not active anymore, and I observed that the dll is not loaded anymore.

What could cause a hook dll to unload ?

Edit2 : I find out that a crash in MouseHookProc the dll in any process unload the hook dll from every process it's loaded in. I can't find a cause to a crash in my code. Might be some race condition or something ? Here is the hook dll code :

#include "stdafx.h"

// define a data segment
#pragma data_seg(".SHARED")
HWND  hwnd=0;
HHOOK hHook=0;
#pragma data_seg()

// tell the linker to share the segment
#pragma comment(linker, "/section:.SHARED,RWS")

#define WM_MOUSEHOOK            WM_USER+0x100

HINSTANCE hInstance=0;


// this allow to build a very small executable without any extra libraries
// (probably not the problem, the bug still occurs without this )
#ifndef _DEBUG
void *__cdecl operator new(unsigned int bytes)
{
    return HeapAlloc(GetProcessHeap(), 0, bytes);
}

void __cdecl operator delete(void *ptr)
{
    if(ptr) HeapFree(GetProcessHeap(), 0, ptr);
}

extern "C" int __cdecl __purecall(void)
{
    return 0;
}
#endif

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

LRESULT CALLBACK MouseHookProc(int nCode, WORD wParam, DWORD lParam)
{
    if(nCode==HC_ACTION && (wParam==WM_MOUSEMOVE || wParam==WM_NCMOUSEMOVE))
    {            
        MSLLHOOKSTRUCT *mhs=(MSLLHOOKSTRUCT*)lParam;        
        PostMessage(hwnd, WM_MOUSEHOOK, wParam, 0);
    }
    return CallNextHookEx(hHook,nCode,wParam,lParam);
}

extern "C" __declspec(dllexport) HHOOK InitializeWindowsHook(char *title)
{
    hwnd=FindWindow(0, title);
    if(hwnd)
        hHook=SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, hInstance, 0);
    return hHook;
}

extern "C" __declspec(dllexport) BOOL DeinitializeWindowsHook()
{
    if(hHook) {
        BOOL b=UnhookWindowsHookEx(hHook);
        hHook=0;
        return b;
    }
    return FALSE;
}
like image 215
Emmanuel Caradec Avatar asked Sep 23 '09 10:09

Emmanuel Caradec


1 Answers

Did you check, if the hook is still installed when its not called any more (i.e. check the return value from BOOL UnhookWindowsHook)?

Possibly another hook is installed that does not preserve your hook, not calling CallNextHookEx().

like image 140
RED SOFT ADAIR Avatar answered Sep 27 '22 16:09

RED SOFT ADAIR