Newsgroup: it.comp.programmare.win32
Titolo: Rilevare un MessageBox con WorkStation Locked

Ciao a tutti.
Ho creato una piccola funzione che, dato il titolo,
rileva una Dialog Box nello schermo:
char *find_window(char *prg)
{
   HWND hWnd;
   HWND fhWnd;
   char *testo;
   int len=0;
   BOOL pop;
   LRESULT result;
   PDWORD_PTR lpdwResult;
   LPARAM mylParam = 0;
   LPTSTR txt;
   LPTSTR lpText;
   char *name = (char *)calloc(strlen(prg)+2,sizeof(char));
   strcpy(name,prg);
   name=strtok(name,".");
   hWnd = FindWindow(NULL,name);
   if (hWnd == 0)  {
             printf("Cannot find window!\r\n");
             free(name);
             return NULL;
   }
   else {
             printf("Window found.\r\n");
     fhWnd=GetDlgItem(hWnd,0xFFFF);
     if(fhWnd) {
       printf("Message Box found.\r\n");
       txt = (char *)calloc(GetWindowTextLength(fhWnd)+5,sizeof(char));
       GetWindowText(fhWnd,txt,2000);
	CloseHandle(fhWnd);
     }
     else txt = NULL;
     free(name);
     PostMessage(hWnd,WM_COMMAND,IDOK,fhWnd);
     CloseHandle(hWnd);
     return txt;
   }
}
Questa funziona perfettamente,
ma non nel caso in cui la workstation sia "lockata".
In questo caso se compare la finestrella di errore,
(dietro rimane quella con su scritto "Press Ctrl + Alt + Canc ....")
la mia funzione, proprio non riesce a "vederla".
Il programma, che deve rilevare queste finestre di errore
anche a macchina lockata, gira in background con la shell nascosta.
Come posso risolvere il problema?
Approfitto per fare un'altra domanda:
qual'è il modo migliore per chiudere tali finestre di errore?
Attualmente faccio un parsing del testo,
alla ricerca della riga con "pid = 1111',
perchè so a priori di trovare tale informazione.
Ho provato con PostMessage(hWnd,WM_COMMAND,IDOK,fhWnd);
o DestroyWindow(fhWnd), ma senza risultati.
Potreste darmi una mano?
Mille grazie
bye ;-)

 o DestroyWindow(fhWnd), ma senza risultati.
Sicuro che l'hwnd sia valido? Se è in un altro desktop quell'hwnd non è più 
valido.
-- 
Raffaele Rialdi
Roadshow developer security ... adesso si va a Bologna e Bari
http://www.microsoft.com/italy/msdn/eventi/developer/securitytour.mspx
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
http://italy.mvps.org
 UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
 Weblog: 
http://blogs.ugidotnet.org/raffaele

 valido.
Io credo di si, dato che tramite quello,
riesco a prelevare il contenuto del messaggio di errore...
Grazie già da ora per l'interessameto.
   Stefano

 Grazie già da ora per l'interessameto.
Prego :)


 
Credo che dovrň studiare un bel po'.
Purtroppo non sono un programmatore,
e quel poco che ho messo in piedi,
l'ho fatto nei ritagli di tempo lavorativi,
leggendo qua e la (per lo + su msdn),
ma probabilmente mi mancano alcuni concetti base..
Grazie ancora
	Stefano

 Grazie ancora
Prego



Crepi
bye ;-)

[...]
scusa, ma sei sicuro che sia VB6? non sapevo che la virtual machine di VB6
usasse MFC... (e mi pare anche strano a dir la verità)
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 0x00030034
Sicuro che la dialog in questione non sia quella di drwtsn32 che salva il 
crash dump dell'applicazione in questione?
Prova a lanciare drwtsn32 da command prompt e togliere la checkbox "visual 
notification".
E nelle cartelle che vedi in drwtsn32, ci sono dei file di log?
C000'0005 è un accesso negato e in quel contesto significa che 
l'applicazione ha tentato di scrivere in un indirizzo che non è stato 
allocato. Conseguentemente viene lanciata un'eccezione e se questa non è 
gestita, l'applicazione termina e come conseguenza l'OS può passare tutti i 
dati del crash ad un applicativo come doctor watson di Windows che salva il 
crash dump (che dovresti trovare anche nell'event log).
Se ti ritrovi quell'applicativo nuovamente aperto, evidentemente c'è un 
launcher che lo rilancia dopo il crash.
Ma a questo punto mi chiedo perchè continuate ad usare quell'applicazione. 
Essendoci un crash gli handle gdi dell'applicazione non vengono chiusi e 
come risultato alla lunga sarà necessario fare un reboot.


 come risultato alla lunga sarà necessario fare un reboot.
quando un programma termina brutalmente gli handle non vengono chiusi? non
sapevo... ma la memoria viene deallocata? e se lo termino con
TerminateProcess?


 
Sono sicuro che si tratti di VB6,
ma forse l'errore è dato dal qualche dll di terze parti,
richiamata dal programma scritto in VB.
Grazie :-)

 come risultato alla lunga sarà necessario fare un reboot.
E' vero: ogni tanto è necessario un reboot,
proprio per la quantità di memoria allocata dal sistema.
Ma purtroppo, per vari motivi, dobbiamo tenerci quell'applicazione..
Spero cmq di aver risolto il problema con drwtsn.
Mille grazie ancora.
bye ;-)

 TerminateProcess?
E' quello che faccio normalemte:
faccio un parsing del messaggio di errore rilevando il pid,
verifico che si tratti di una delle applicazioni che sto controllando,
e poi la killo con TerminateProcess.
Generalmente non tutta la memoria viene deallocata,
ma non so se il problema sia dell'applicazione,
o del SO (WINNT 4 server)..
Il mio problema cmq è che da un po' di tempo a questa parte,
TerminateProcess mi restituisce un valore diverso da 0,
come indicato su msdn: 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/terminateprocess.asp
il che significa che il processo è stato terminato correttamente,
ma in realtà quel PID continua a comparire nel task manager...
Sto cercando di capire il motivo di questo comportamento,
per il quale avevo fatto già un post tempo fa...
Appena ho news, vi faccio sapere.
Grazie ancora a entrambi per l'interessamento,
e scusate se ho risposto in ritardo,
ma ero impegnato con un esame...
bye ;-)

 richiamata dal programma scritto in VB.
probabile
ciao


 con TerminateProcess?
Scusa per il ritardo nella risposta ma ero in giro per il roadshow.
Non tutti gli handle vengono chiusi. Io parlo solo di quelli GDI che 
purtroppo vengono persi e numericamente nel sistema sono limitati.
Quando alla lunga gli handle gdi sono terminati, si verifica quel noto 
fenomeno che si riscontra tipicamente nei driver bucati che hanno dei gdi 
leak. I sintomi di questo fenomeno sono icone nere al posto dell'immagine, 
la font standard sans serif di dimensione grossa al posto della font 
corretta e così via. Tutte cose che derivano dal fatto di non riuscire più a 
creare oggetti GDI in quanto gli handle sono terminati.
TerminateProcess purtroppo non ti aiuta. Tutte le operazioni di terminazione 
di thread e processo sono incondizionate e non permettono al possessore 
dell'handle di chiuderlo. Solo gli oggetti non-gdi vengono chiusi.
Alla lunga potrebbe essere necessario dover fare reboot.
È sempre meglio mai killare un processo o un thread. Questi devono ricevere 
un messaggio (per esempio WM_QUIT) per auto-terminarsi a seguito di una 
corretta chiusura di tutti gli handle.


 [...]
la tua risposta mi ha interessato molto; il problema suppongo dipenda
dalla particolare implementazione che penso che abbiano gli handles GDI,
visto che non si tratta di HANDLE's veri e propri, cioè di oggetti del
kernel, ma di oggetti implementati dalla GDI; suppongo che la GDI non
abbia modo di avere notifica quando un thread/processo termina brutalmente.
ma tu come fai a conoscere il problema? è descritto in MSDN? non è stato
ancora corretto da Microsoft? verrà forse corretto in Windows LH? esiste
un problema simile nella GDI+?
tieni presente che non conosco l'interfaccia della GDI+ e non so come si
usa, ma immagino che sia basata su COM e che quindi non abbia questo
problema; certo, il problema dei leak degli oggetti COM c'è sempre (se ti
scordi di dereferenziarli tante volte quante li hai referenziati), ma le
aree di memoria non sono come gli handle, vengono comunque disallocate
alla terminazione di un processo; quindi GDI+ dovrebbe risolvere la cosa,
dico bene?
grazie
ciao :)


 ciao :)
Prego :)
-- 
Raffaele Rialdi
Roadshow developer security ... adesso si va a Udine e poi Palermo


 rimessi come disponibili e quindi persi.
capisco; ma mi viene in mente una cosa: da questo problema si evince
chiaramente che gli handles della GDI non si trovano all'interno del
processo che li ha aperti, ma all'interno di uno dei processi di sistema
che implementano il subsystem Win32 (forse csrss.exe) oppure in una
sezione SHARED di qualche DLL di sistema (forse gdi32.dll). ma come mai
questo fatto? gli handles degli oggetti GDI sono pubblici? sono validi in
qualsiasi processo? oppure la loro gestione viene implementata in un altro
processo solo per rispettare il modello microkernel?
in realtà sapevo (potrei sbagliarmi) che la GDI era stata implementata in
kernel mode (cioè senza seguire il modello microkernel, ma in maniera
"monolitica") per maggiore performance; è vero questo?
grazie ancora per le tue risposte :)
ciao


 sezione SHARED di qualche DLL di sistema (forse gdi32.dll).
mi spiego meglio per sicurezza: intendo dire che *la loro implementazione*
si trova nei posti che ho ipotizzato; la lista degli handles aperti nel
sistema mantenuta dalla GDI insomma :)


 ciao


 male ...
vabbè, però quando ricevo BSOD non è mai colpa di win32.sys, almeno non
sembra (leggo sempre il nome del file in cui si verifica l'errore).


 l'errore).
Questo è molto variabile perchè dipende cosa sta facendo in quel momento il 
driver. Sui BSOD ci si può scrivere un libro (e pure molto noioso ;-))
I bsod più tipici (irql_not_less_or_equal, kmode_exception_not_handled, etc) 
sono dovuti per lo più a ram fallata o driver che accedono della memoria che 
non dovrebbero usare (il classico bug del puntatore a null o a un valore 
invalido).
Senza i problemi di driver o di consumo di handle Windows difficilmente 
incorre in problemi.
Il mio win2k3 per esempio dopo una settimana crashava e poi ho scoperto che 
il servizio di management del raid Promise consumava tutti gli handle di 
sistema lasciando tutti gli altri processi all'asciutto. Corretto questo, lo 
lascio sempre acceso senza più problemi.
-- 
Raffaele Rialdi
Roadshow developer security ... Palermo aspettaci
