Mon Hook système n'est actif que sur l'appli courante

Mon Hook système n'est actif que sur l'appli courante - C++ - Programmation

Marsh Posté le 22-03-2004 à 10:25:31    

Je suis en train de mettre en place un hook système.  
J'installe le hook (SetWindowsHookEx) dans une appli MFC (DialogBased).  
Le problème est le suivant : le hook n'est actif que sur le thread de l'appli installant le thread.
Il me semble pourtant avoir fait ce qu'il faut pour que la portée du hook soit au niveau du système, à savoir :
- extraire dans une dll la fonction filtre du hook (MouseProc en l'occurence)
- lors de l'appel à SetWindowsHookEx, préciser le HMODULE de la dll chargée depuis l'appli principale (3e paramètre de la fonction)
- lors de l'appel à SetWindowsHookEx, ne pas indiquer de thread (4e paramètre à zéro)
 
Pourtant, seuls les messages de souris adressés à mon appli sont filtrés par mon hook. Quelqu'un voit une raison possible à ça ?


---------------
Les Vers Solitaires, on aime ... ou pas !
Reply

Marsh Posté le 22-03-2004 à 10:25:31   

Reply

Marsh Posté le 22-03-2004 à 15:56:51    

Personne ne s'interresse aux hooks ? Vous devriez, c'est caotivant comme truc, et ça offre des possibilités assez énormes.


---------------
Les Vers Solitaires, on aime ... ou pas !
Reply

Marsh Posté le 22-03-2004 à 17:05:12    

Citation :

Pourtant, seuls les messages de souris adressés à mon appli sont filtrés par mon hook.


Il ressemble à quoi ton filtre ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-03-2004 à 17:08:54    

J'ai pas le code ici, mais le problème est le même en réduisant le code au strict minimum, c'est à dire :
- définition de la fonction MouseProc comme demandé dans la MSDN.
- cette fonction retourn 0, tout simplement (normalement elle devrait retourner CallNextHook, mais ne pas le faire a juste puor effect de corrompore le fonctionnement d'éventuels autres hook de souris installés).
Bref, je pense pas que ça vienne de la fonction filtre.

Reply

Marsh Posté le 22-03-2004 à 17:12:57    

En fait, je veux savoir comment tu sais si ton hook fonctionne ou pas ?
As-tu un lien quelconque avec ton appli d'origine (handle...), utilises-tu les MFC dans ta dll ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-03-2004 à 09:01:10    

Je sais si mon hook fonctionne ou pas parce qu'il a effectivement un lien avec mon appli principale : il affiche les coordonnées du pointeur à chaque message de souris reçu.
Pour cela, la dll possède un pointeur vers l'instance "CMouseCommanderApp" (donc, oui, j'utilise les MFC dans mon appli, ET dans ma dll). pourquoi ?
 
Apparement, ce que je faisais ne pouvait pas fonctionner : je ne précisait pas explicitement que le pointeur vers "CMouseCommanderApp" contenu dans la dll était une donnée partagée (fixé avec un pragma). Maintenant que je le fais, ça semble la même chose : les données ne semblent pas être partagées.

Reply

Marsh Posté le 23-03-2004 à 09:08:33    

EDIT :
Le modèle de pragma utilisé est le suivant :
http://www.flounder.com/hooks.htm

Reply

Marsh Posté le 23-03-2004 à 15:20:47    

Tu ne peux pas appeler une fonction de ton process depuis ta dll hook.
Cette dll est mappée dans l'espace d'adressage de tous les processus qui appelent son code quand il faut (enfin, Windows le leur fait appeler).
Donc, il faut voir le code de ta dll comme s'il était exécuté depuis une autre appli. Et cette autre appli, quand elle tente d'appeler une fonction de ton process, je te laisse deviner la suite.  
Il faut donc utiliser un mécanisme cross-process pour communiquer entre ta dll et ton appli.
Pour cela, code en Win32 pur dans ta dll (car je ne pense pas que les MFC soit chargées dans les autres applis) et communique avec ton appli via des messages. Ta section shared ne doit contenir que le handle Win32 et pas un CWnd * de ton appli.
Tout ça est bien expliqué dans l'article de flounder. Faut lire jusqu'au bout...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-03-2004 à 17:05:52    

Hé oui, j'suis en multi-process en fait, vu que ma dll est attachée entant que hook à chaque thread. Du coup ça devrait quand même être possible en synchronisant avec des mutex et tout le toutim, non !?
Evidement, c'est beaucoup plus simple de communiquer simplement par messages.
Merci beaucoup.

Reply

Marsh Posté le 24-03-2004 à 08:19:37    

L'adresse de la fonction du process A n'a de sens qu'au sein du process A. Si le process B effectue un appel à cette adresse, il n'appelera pas la fonction de A, mais soit une fonction à lui (B) soit ça plante. Chaque process a son propre espace d'adressage privé.
Ta dll stocke un pointeur d'instance de classe créé par A.
Ce pointeur n'a aucun sens au sein du process B. Sinon, ça voufrait dire que si le process A crée une instance de ta classe X, celle-ci est créée dans tous les autres process...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 24-03-2004 à 08:19:37   

Reply

Marsh Posté le 24-03-2004 à 08:54:10    

ok, compris.
Par contre, ça y est, j'ai mis en place une communication par messages : je transmet un message de mon cru à ma fenêtre principale à chaque fois que mon filtre attrappe un message de souris. Mais ça pose encore PB dès que des messages viennenent d'un autre thread que celui de mon appli. J'comprend pas !!!
Je poste mon code d'ici 2 minutes...

Reply

Marsh Posté le 24-03-2004 à 09:28:51    

Voila le code de mon Hook, au plus simple :
 

Code :
  1. //===========================================================================
  2. // Variables globales
  3. //===========================================================================
  4. #pragma data_seg( "MYDATA" )
  5. HINSTANCE g_hModule  = NULL ;
  6. HHOOK  g_hMouseHook = NULL ;
  7. HWND  g_hWndMC  = NULL;
  8. UINT  g_WmHook     = 0;
  9. UINT  g_WmUnHook   = 0;
  10. #pragma data_seg()
  11. #pragma comment( linker, "/SECTION:MYDATA,rws" ) // read, write and share
  12. BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
  13. {
  14. switch ( ul_reason_for_call )
  15. {
  16. case DLL_PROCESS_ATTACH:
  17.  // Save module handle
  18.  g_hModule = (HINSTANCE) hModule;
  19.  //  Register messages
  20.  if ( g_WmHook == 0 )
  21.   g_WmHook = RegisterWindowMessage( MSG_HOOK );
  22.  if ( g_WmUnHook == 0 )
  23.   g_WmUnHook = RegisterWindowMessage( MSG_UNHOOK );
  24.  break;
  25. case DLL_PROCESS_DETACH:
  26.  //CleanUp
  27.  break;
  28. }
  29. return (TRUE);
  30. }
  31. LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  32. {
  33. if ( nCode == HC_ACTION )
  34. {
  35.  MOUSEHOOKSTRUCT* lpMouseData = (MOUSEHOOKSTRUCT*) lParam;
  36.  // Transmet le message à la fenêtre de l'appli
  37.  SendMessage (g_hWndMC, WM_MOUSE_CATCHED, wParam, lParam);
  38. }
  39. return CallNextHookEx( g_hMouseHook, nCode, wParam, lParam );
  40. }
  41. BOOL WINAPI StartHook( HWND _hWnd )
  42. {
  43. if (( g_hMouseHook == NULL ) && (_hWnd != NULL))
  44. {
  45.  g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hModule, 0 );
  46.  //g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId () );
  47.  g_hWndMC  = _hWnd;
  48.  return TRUE;
  49. }
  50. return FALSE;
  51. }
  52. BOOL WINAPI StopHook( void )
  53. {
  54. if ( g_hMouseHook != NULL )
  55. {
  56.  if ( UnhookWindowsHookEx( g_hMouseHook ) != 0 )
  57.   g_hMouseHook = NULL;
  58. }
  59. return( g_hMouseHook == NULL );
  60. }


 
 
Et voici le code (enfin, la partie qui nous interressé) de mon appli principale :
 

Code :
  1. LRESULT CMagicCommanderDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3. // Traitement de messages particuliers à l'appli
  4. switch (message)
  5. {
  6.  case WM_MOUSE_CATCHED :
  7.  {
  8.   MOUSEHOOKSTRUCT* lpMouseData = (MOUSEHOOKSTRUCT*) lParam;
  9.    char szX[16];
  10.    char szY[16];
  11.    ltoa (lpMouseData->pt.x, szX, 10);
  12.    ltoa (lpMouseData->pt.y, szY, 10);
  13.    UpdateData (FALSE);
  14.    m_editMouseX.SetWindowText (szX);
  15.    m_editMouseY.SetWindowText (szY);
  16.    UpdateData ();
  17.  }
  18. }
  19. return CDialog::WindowProc(message, wParam, lParam);
  20. }


Message édité par El_gringo le 24-03-2004 à 09:44:16
Reply

Marsh Posté le 24-03-2004 à 15:25:07    

Code :
  1. g_WmHook = RegisterWindowMessage( MSG_HOOK );
  2. ...
  3. SendMessage (g_hWndMC, WM_MOUSE_CATCHED, wParam, lParam);


Utilises déjà le message enregistré sinon ton g_WmHook ne sert à rien vu que tu l'utilises pas.
T'as besoin que de g_hMouseHook et de g_hWndMC en shared.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 24-03-2004 à 15:29:05    

Non, mais j'en ai pas besoin du message enregistré. Je sais que je l'utilise pas, c pas grave.
Dans mon MyHooks.h, j'ai un

Code :
  1. #define   WM_MOUSE_CATCHED        (WM_USER + 1)


Que j'attrape bien dans la fenêtre à laquelle jel e passe.

Reply

Marsh Posté le 24-03-2004 à 16:24:25    

Met des MessageBeep dans ta MouseProc pour savoir si c'est un pblm de hook ou d'envoie de message.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 24-03-2004 à 16:41:36    

C'est super chiant à débugger les hook système : VC++ aussi reçoit des messages de souris.
En fait, en l'état,le comportement est le suivant :
Tant que je reste dans ma fenêtre principale, ou dans une fenêtre fille (les différents contrôles de ma fenêtre), ça marche nickel. Dès que je sors mon pointeur de la fenêtre (les messages de souris filtrés par le hook sont issus d'un autre thread), j'ai un plantage plutôt violent : tout se freeze, et je ne peux plus rien faire. Juste redémarrer le PC avec le bouton reset. Pas simple à débugger tout ça. :-(

Reply

Marsh Posté le 24-03-2004 à 16:46:55    

J'ai testé ton WM_USER+1 dans les MFC en debug, hop, assertion failed. Il veut du register message.
 
Au fait, c'est quoi ton OS ?


Message édité par HelloWorld le 24-03-2004 à 16:47:21

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 24-03-2004 à 16:56:28    

HelloWorld a écrit :

J'ai testé ton WM_USER+1 dans les MFC en debug, hop, assertion failed. Il veut du register message.
 
Au fait, c'est quoi ton OS ?


 
Mon WM_USER passe très bien chez moi, tant que j'suis dans la fenêtre courante, mais je doute que ce soit lié. D'ailleurs j'utilise courament ce type de message en MFC. ton assertion doit venir d'autre chose.
 
Mo OS c'est XP (donc NT).

Reply

Marsh Posté le 24-03-2004 à 17:25:10    

Fait un truc genre MessageBeep dans ta dll pour savoir si le hook fonctionne ou pas.
Si oui, c'est un pblm d'envoie de msg à ton appli.
Je pense à un truc aussi, remplace SendMessage par PostMessage.
Il se pourrait que tu entre dans un truc récursif.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 29-03-2004 à 10:13:25    

HelloWorld a écrit :

Fait un truc genre MessageBeep dans ta dll pour savoir si le hook fonctionne ou pas.
Si oui, c'est un pblm d'envoie de msg à ton appli.
Je pense à un truc aussi, remplace SendMessage par PostMessage.
Il se pourrait que tu entre dans un truc récursif.
 


 
Apparement, l'envois de message est OK :  
Si je supprime tous les traitements effectués lorsque mon appli principale reçoit le message, ça semble mieux...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed