Newsgroup: it.comp.programmare.win32
Titolo: Maledetti uncini!!!

Questi Windows Hooks mi stanno facendo impazzire!
Allora, io voglio monitorare TUTTI i messaggi del mio computer, proprio
come potrebbe fare Spy++ (e credo pure WinSight), quindi già parto sapendo
che quello che voglio fare è fattibilissimo; avevo inizialmente installato
un hook WH_GETMESSAGE globale, cioè L'HO MESSO IN UNA DLL, solo che non
funzionava quasi per niente; mi sono studiato come funziona "Spy", un
esempio che ho trovato nella MSDN, e ho visto che lui oltre a
WH_GETMESSAGE installa anche WH_CALLWNDPROC; ho installato anche quello,
SEMPRE NELLA DLL, e devo dire che tutti e due messi insieme funzionano un
po' di più, nel senso che i messaggi arrivano tutti, ma ARRIVANO SOLO
QUELLI DELLA MIA APPLICAZIONE PORC... (e censuriamo, va') !!!
La parete accanto al mio PC l'ho già sfondata e ora non so più dove
sbattere la testa; AIUTATEMIIII
a proposito: le chiamate a SetWindowsHookEx si trovano nella dll, ma
secondo l'MSDN questo NON DEVE compromettere la globalità dell'hook (anche
perché ho provato pure a metterle nell'exe lasciando le HookProc nella
dll, ma niente); qui sotto riporto le chiamate:
 hhkGetMsg = SetWindowsHookEx(WH_GETMESSAGE, MyGetMsgProc, hinstDLL, 0);
 hhkCallWnd = SetWindowsHookEx(WH_CALLWNDPROC, MyCallWndProc, hinstDLL, 0);
Facendo il debug ho controllato che hinstDLL sia inizializzato
correttamente e che le due chiamate non diano risultati nulli;
apparentemente è tutto a posto.
p.s.: non ho intenzione di fare un programma che blocca il computer; le
mie due HookProc chiamano regolarmente CallNextHookEx, come da MSDN.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 !!!
Come comunichi i dati delle notifiche che arrivano alla hook procedure al
tuo processo? Da come descrivi il problema mi pare che tu non stia usando,
come dovresti invece fare, un qualche tipo di comunicazione interprocesso
(es. memoria condivisa, memory mapped file ecc..).
-- 
Lorenzo

Lorenzo ha scritto:



Certo che lo comunico, caspiterina! Le mie due HookProc inviano un
messaggio WM_COPYDATA ad una finestra della mia applicazione; e comunque
anche se mi fossi dimenticato di far comunicare dll e processo, come
sarebbe possibile che i messaggi della mia applicazione, almeno quelli,
arrivano?


 arrivano?
Se ad esempio usassi delle variabili globali messe in una zona di memoria
non condivisa succederebbe proprio cio` che descrivi.
Qualche idea:
-Ovviamente lo stesso discorso dei dati di ritorno vale anche per lo hHook
(devi trovare il modo per comunicarlo a tutte le hook procedure di tutti i
processi, il modo piu` semplice e` usare la memoria condivisa).
-Hai verificato (con PWALK o programmi simili) che la DLL sia caricata anche
negli altri processi?
-Hai provato a scrivere su un file dei log con informazioni utili (PID del
processo, entrata nella LibMain, prima entrata nella hook procedure, e cose
del genere) per accertarti che tutto sia in ordine? Ovviamente dovrai
trovare un modo per scrivere sul file in maniera concorrente, il modo piu`
facile e` aprirlo in modo esclusivo da ogni processo e far "riprovare" gli
altri finche` non ci riescono a loro volta.
-- 
Lorenzo

 altri finche` non ci riescono a loro volta.
bè, uso Visual C++, quindi posso fare tutti i TRACE che voglio... ma
ancora una volta il tuo discorso mi dà l'idea che non ci siamo ancora bene
intesi sul'espressione "altri processi"... che vuoi dire con "aprirlo da
ogni processo"? io di processo ne ho uno solo!


 ogni processo"? io di processo ne ho uno solo!
Ogni processo dispone di uno spazio di indirizzamento separato. Quando
tu installi uno hook globale, la tua DLL viene "replicata" in ogni
processo e dopodiche` ogni copia e` dotata di vita propria.
Prima di usare gli hook dovresti chiarirti meglio questi concetti... ti
consiglio "Advanced Windows Programming" di Richter, e` un libro
praticamente perfetto per i tuoi scopi.
-- 
Lorenzo

 arriveranno mai dalle istanze della DLL copiate negli altri processi
e invece sě. L'idea dietro a OutputDebugString č proprio poter vedere i 
trace di *tutte* le applicazioni. Vedi l'implementazione di ReactOS per 
farti un'idea di come funziona (e Al potrebbe prenderla come esempio di 
protocollo di scambio di messaggi), e il programma "dbmon" del PSDK per 
vederlo in azione dal vivo
-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.3. C, C++ and ASM developers
                               and beta testers are welcome!

 trace di *tutte* le applicazioni.
Sono d'accordo, ma TRACE del Visual C++ non usa OutputDebugString:
Remarks
Provides similar functionality to the printf function by sending a formatted
string to a dump device such as a file or debug monitor. Like printf for C
programs under MS-DOS, the TRACE macro is a convenient way to track the
value of variables as your program executes. In the Debug environment, the
TRACE macro output goes to afxDump. In the Release environment, it does
nothing.
-- 
Lorenzo

 praticamente perfetto per i tuoi scopi.
Non posso mettermi a leggere, devo fare 'sto programma; per ora sto
sviluppando un'altra parte, ma poi quando lo finisco devo risolvere questo
problema.
Cmq a parte tutto non è la prima volta che gli hook non mi funzionano;
tempo fa mi era accaduta una cosa strana: volevo installare un hook da
tastiera (non low level, quello normale) che inizialmente funzionava come
locale anche se era globale; poi assieme a quello ne ho installato anche
da mouse (sempre normale) e funzionavano tutti e due corretamente.
Sono sicuro di non aver fatto altre modifiche quando ho aggiunto l'hook
per il mouse; l'ho solo aggiunto chiamando SetWindowsHookEx e scrivendo
una nuova HookProc.


come li mandi i messaggi alla tua applicazione dalla dll???
quando lo feci io, usavo la PostMessage(); e avevo avuto il tuo stesso
problema finche qualcuno (e lo ringrazio ancora ;o) ) su questo newsgroup mi
disse quello che praticamente ti ha detto Lorenzo...
in pratica dovevo dichiarare l'handle della mia finestra, in una zona di
memoria condivisa....
#pragma data_seg ("shared")
     static HWND hwnd = NULL;
#pragma data_seg ()
poi assegni ad hwnd l'handle della finestra che crea l'hook
... CreateHook (HWND hWnd)
{
hwnd = hWnd;
....
}
in questo modo a me funziona......

ah, comunque per vedere se si tratta di un problema di memoria condivisa, o
altro, potresti provare
a fare un Beep(); ad un certo tipo di messaggio, se vedi che quando
"avviene" quell'evento, senti il beep ma alla tua
applicazione non arriva nulla.... allora c'e' un problema nel passaggio dei
dati, se non avviene neanche il beep... bo ;o)

 Non posso mettermi a leggere, devo fare 'sto programma;
Evidentemente non lo consideri molto importante.
-- 
Lorenzo

 Evidentemente non lo consideri molto importante.
Cosa, leggere o il mio programma?
Comunque sia non perdiamoci in altre discussioni, in questo newsgroup si
parla di argomenti tecnici; qualcuno ha qualche idea sul quando, come e
perché i Windows Hook possono non funzionare? Oppure sono stato
sicuramente io a sbagliare qualcosa?


Badkill ha scritto:

So già che non avverrebbe neanche il beep, perché facendo il debug alla
dll ho messo un breakpoint alla HookProc (anzi a tutte e due per la
precisione), e questa viene chiamata solo quando riceve un messaggio della
MIA applicazione (lo so perché so che gli handle che riceve sono miei),
come se l'hook non fosse globale ma locale!


 come li mandi i messaggi alla tua applicazione dalla dll???
Uffaaaa ancora? Perché non leggi tutto il thread prima di rispondermi? Ho
già detto a Lorenzo che per fare in modo che la mia dll comunichi col mio
programma ho usato un messaggio WM_COPYDATA che viene ricevuto
correttamente da una delle finestre del mio programma!


 come se l'hook non fosse globale ma locale!
bhe se e' per questo pure a me fa cosi, ma i messaggi me li riceve tutti....
infatti secondo me era un problema del debugger, ma qualcuno mi disse che
stavo bestemmiando ;o)
e quindi sara' forse che non lo so usare bene io, ma mi si ferma sul
breakpoint solo nel caso
in cui il messaggio arrivi dalla mia finestra, altrimenti no, cio'nonostante
intercetta tutti i messaggi....
poi se non vuoi provare.... non farlo ;o)

 stavo bestemmiando ;o)
hanno ragione: hai praticamente bestemmiato... :)


 simili lo fanno!!!
forse non mi hai capito bene...
allora i messaggi li riceve (come dici tu) "da tutto il computer" certo che
si può fare
e certo che la mia applicazione lo fa, il problema e' che non si ferma sul
breakpoint
nel caso in cui il messaggio arrivi da un altra applicazione. il problema e'
solo nel debug....

 Oppure sono stato sicuramente io a sbagliare qualcosa?
sei stato tu a sbagliare qualcosa
