Newsgroup: it.comp.lang.visual-basic
Titolo: handle di api.

Ciao a tutti,
ho un problema con un handle ritornato da certe api.Per risolvere i miei
problemi dovrei capirne di più sull'handle.Vorrei capire se ci sono dei
valori predefiniti di handles ritornati in corrispondenza di certe
operazioni eseguite.Potete aiutarmi?Dove posso trovare informazioni
dettagliate?Ho saputo,inoltre, che gli handle tornati per le stesse api
cambiano da SO a SO.E' vero?Come posso fare se mi trovo a gestire dei
problemi con handle differenti passando da Millennium a XP?
Grazie per la collaborazione,ciao
Alessandro.
--

 Millennium a XP?
Gli handle... argomento che adoro. Esistono diversi tipi di handle, non 
compatibili tra di loro e implementati in modo completamente diverso. 
E' importante imparare a distinguerli e imparare come funzionano. Non è 
assolutamente una lista completa, ma almeno i più importanti ho cercato 
di metterceli:
 - OGGETTI DEL KERNEL -
Includono: file, directory, periferiche, driver, eventi, mutanti (in 
terminologia Win32: mutex), timer, semafori, porte LPC, processi, 
thread, token, chiavi di registro, sezioni di memoria condivisa (in 
terminologia Win32: file mapping), link simbolici, window station (se 
interessa posso spiegare anche la natura di tutti questi oggetti) e 
diversi altri tipi esoterici di cui ignoro natura e scopi
Gli handle per eccellenza. Questi oggetti costituiscono il cuore delle 
funzionalità del sistema operativo (I/O, periferiche, comunicazione 
inter-processo), quindi devono essere disponibili per qualsiasi 
programma, anche in modalità kernel. A questo tipo di oggetti è 
associato un descrittore che contiene il tipo dell'oggetto, alcuni dati 
usati internamente e un puntatore all'oggetto vero e proprio, e in caso 
di Windows NT anche una ACL, ossia un descrittore di sicurezza. A questo 
tipo di oggetti, infatti, è possibile applicare restrizioni di accesso. 
Altra particolarità è l'uso del reference counting: ogni oggetto 
mantiene un conteggio interno di quante volte è stato referenziato, 
ossia in quanti lo stanno usando. Quando il conteggio scende a zero, a 
meno che non abbia qualche meccanismo di persistenza (come avviene per i 
file, che vengono salvati su disco), l'oggetto viene distrutto.
Il valore nullo per questo tipo di handle è INVALID_HANDLE_VALUE, uguale 
a &HFFFFFFFF&, ossia -1, e rappresenta un handle che non punta ad alcun 
oggetto. Tradizionalmente anche lo zero può essere usato per 
rappresentare un handle nullo o non valido
 - OGGETTI DI MEMORIA WIN32 -
Includono: oggetti di memoria e moduli eseguibili (nota: moltissimi 
altri oggetti, come le risorse, in realtà sono oggetti di memoria)
Sono gli handle ritornati dalle funzioni di allocazione memoria 
(GlobalAlloc e LocalAlloc), ma anche da quelle per il caricamento dei 
moduli (LoadLibrary, GetModuleHandle), e possono essere di due tipi: 
fixed e moveable (la distinzione tra oggetti globali e locali presente 
originariamente nell'API Windows non è più rilevante nell'API Win32, a 
causa del nuovo modello di memoria; i due tipi di oggetti possono essere 
scambiati tra di loro liberamente). I fixed sono normali buffer, e gli 
handle a questo tipo di oggetti di memoria sono utilizzabili 
direttamente come puntatori. I moduli eseguibili sono sempre di tipo 
fixed. I moveable sono buffer che, se necessario, possono essere copiati 
in un'altra area di memoria se mancasse lo spazio per riallocarli (a 
differenza dei file su disco i blocchi di memoria devono essere 
contigui), quindi l'handle non punta direttamente al buffer: per 
ottenere un puntatore al buffer è necessario prima incrementare il lock 
count dell'oggetto di memoria, con GlobalLock o LocalLock. Il lock count 
viene usato unicamente quando un oggetto deve essere ridimensionato: se 
il lock count è maggiore di zero, l'oggetto non verrà spostato, se 
questo fosse necessario per ridimensionarlo, e l'operazione di 
ridimensionamento fallirà, perchè il lock count indica che l'oggetto è 
in uso. Il lock count degli oggetti fixed è considerato immutabile e 
sempre uguale a zero
Trattandosi di puntatori, valgono le regole normalmente applicate ai 
puntatori: lo zero è l'oggetto nullo, e vengono considerati non validi 
handle compresi tra zero e &H00010000, e tra &HFFFEFFFF e &HFFFFFFFF, 
ossia i 64 kb superiori e inferiori della memoria virtuale
 - OGGETTI USER32 -
Includono: window station e desktop
Iniziamo con una premessa: sì, queste window station sono le stesse che 
fanno parte degli oggetti del kernel. Essenzialmente, mentre tutti gli 
oggetti, window station escluse, sono gestite dallo stesso processo 
kernel, le window station vengono aggiunte da un'estensione del kernel 
costituita dal sottosistema User/GDI, quindi questo tipo di oggetti è 
valido in entrambi i contesti. Ma definiamo queste due entità. Una 
window station è un oggetto sicuro contenente una clipboard, una tabella 
globale di atomi e una serie di oggetti desktop. Le window station 
possono essere interattive o non interattive. Quelle interattive hanno 
l'accesso alle periferiche di input e output per l'interfaccia utente 
(quindi mouse, tastiera e schermo). Una sola window station può essere 
interattiva, e viene usata per l'interazione con l'utente, tutte le 
altre nascono non interattive e rimangono tali. Le window station 
vengono usate per fornire i servizi dell'interfaccia utente a servizi 
che all'interfaccia vera e propria non devono poter accedere. La window 
station di appartenenza di un processo è un attributo (di sola lettura) 
di quel particolare processo. I desktop sono oggetti sicuri, come le 
window station (hanno cioè una ACL che definisce i permessi di accesso), 
e contengono una superficie schermo logica, finestre, menu e hook. 
Possono essere visibili o non visibili, un solo desktop alla volta può 
essere reso visibile ed è quello a cui la window station interattiva 
invia l'input dell'utente e dalla cui superficie logica preleva la 
bitmap da disegnare su schermo. A differenza delle window station, il 
desktop di appartenenza è un attributo dei thread, ed è di lettura-
scrittura. Le finestre, i menu e gli hook creati in un desktop 
appartengono a quel desktop e non possono essere spostati ad un altro, 
questo significa ad esempio che ad un thread che ha creato finestre in 
un desktop non può esserne assegnato un altro. I desktop vengono usati 
ad esempio dal logon manager per separare in modo sicuro la schermata di 
login dal desktop dell'utente, e per garantire il bloccaggio sicuro 
delle postazioni di lavoro, sia tramite bloccaschermo sia tramite 
salvaschermi tradizionali
Gli handle a window station seguono le stesse regole degli handle ad 
oggetti del kernel. Il valore nullo di handle a desktop è zero
 - OGGETTI GDI32 -
Includono: penne, pennelli, regioni, font, tavolozze, percorsi e bitmap
Gli oggetti di questo tipo servono a definire gli "strumenti" usati in 
funzioni di disegno della GDI. Le penne definiscono il modo in cui un 
contorno verrà disegnato, i pennelli servono a definire il riempimento 
delle figure disegnate con una penna, le regioni servono a delimitare le 
aree ridisegnabili di una bitmap, i font definiscono l'aspetto che un 
output testuale dovrà avere, le tavolozze servono a stabilire 
corrispondenze tra i colori usati nelle operazioni di disegno e i colori 
che la periferica grafica effettivamente userà, i percorsi definiscono 
forme utilizzabili in operazioni di disegno, e infine le bitmap 
rappresentano i dati grafici veri e propri. Questo tipo di oggetti è 
gestito in un processo a parte, il sottosistema User/GDI, quindi gli 
stessi valori di handle possono essere usati da qualsiasi processo 
(mentre gli handle ad oggetti del kernel vanno esplicitamente duplicati 
e scritti nella memoria del processo che richiede il duplicato). 
Impossibile non notare nella nomenclatura di questa classe di oggetti un 
uso estensivo di terminologia tipica degli editor grafici: la GDI di 
Windows, infatti, originariamente era un programma di editing grafico 
per DOS, da cui ereditò i concetti basilari
Gli handle a oggetti GDI32, internamente, sono dei puntatori, quindi 
valgono le regole sulla validità dei puntatori
 - CONTESTI DI PERIFERICA -
Sono oggetti contenenti un set di un oggetto GDI per tipo (una penna, un 
pennello, una regione, ecc) e una serie di modalità grafiche, e sono 
associati ad una periferica di output. Un contesto di periferica 
definisce i "come" di qualsiasi operazione di output sulla periferica 
associata. L'argomento GDI è estremamente ampio, troppo per questa 
panoramica generale, quindi per ora non approfondirò ulteriormente.
Gli handle a contesti di periferica sono, internamente, dei puntatori, 
con tutto quello che ne consegue
 - FINESTRE -
Il tipo più anomalo di handle è quello a finestra. A differenza di quasi 
tutti gli altri handle, gli handle a finestra sono globali, pubblici a 
tutti i processi in esecuzione, e soprattutto per riferirsi allo stesso 
oggetto si usa sempre e comunque lo stesso valore. Più che degli handle 
si tratta di identificatori, molto simili a quelli dei processi e dei 
thread, di cui cioè un unico processo server (nel caso di processi e 
thread il kernel, nel caso delle finestre il sottosistema User/GDI) 
mantiene una tabella interna
Non trattandosi di riferimenti ad oggetti, ma piuttosto di 
identificatori, gli handle a finestra non hanno il concetto di valore 
nullo. Lo zero, unico valore "riservato" e non valido come handle 
effettivo a finestra, può indicare sia "nessuna finestra", sia "tutte le 
finestre", sia avere significati più specifici, a seconda dei casi (ad 
esempio può indicare l'intera superficie logica del desktop visibile, 
dove per desktop si intende uno degli oggetti User32 di cui sopra)
 - CHIAVI DI REGISTRO WIN32 -
Si tratta essenzialmente di un wrapper (ossia uno strato ulteriore) 
aggiunto da advapi32.dll attorno agli handle a chiavi di registro usati 
all'interno del kernel. Questo passo è necessario dato che Win32 usa dei 
valori costanti (i famosi HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE, 
eccetera) come segnaposto per gli handle (che in realtà NON sono 
costanti, ma ricavati, quando necessario, da avdapi32.dll usando le 
funzioni del kernel) a chiavi che rivestono un particolare ruolo in 
Win32 (HKEY_LOCAL_MACHINE ad esempio viene tradotto in un handle alla 
chiave \REGISTRY\MACHINE)
A parte le costanti di cui sopra, che vengono tradotte automaticamente 
nei rispettivi handle, questo tipo di oggetto non ha nessun altro valore 
particolare, soprattutto nessun valore implicito di handle non valido è 
definito. E' evidente che questo tipo di oggetti si intende "opaco" e 
non direttamente manipolabile, e quindi occorre accettare che qualsiasi 
valore venga ritornato dalle funzioni del registro di advapi32.dll come 
handle a chiave sia valido
 - BUFFER DI CONSOLE WIN32 -
Contrariamente a quanto potrebbe sembrare, le console Win32 non sono dei 
file, e gli handle a console non sono compatibili con gli handle a file. 
Esistono funzioni all'interno di Win32 per decidere se un handle è un 
handle a console o ad un oggetto del kernel (come i file), e comportarsi 
di conseguenza: gli handle a oggetti del kernel vengono passati al 
kernel, gli handle a console vengono passati al processo server del 
sottosistema Win32, csrss.exe, che contiene l'implementazione vera e 
propria delle console (inclusa la loro rappresentazione su schermo come 
finestre). Le funzioni ReadFile e WriteFile, ad esempio, eseguono 
immediatamente un controllo sul tipo di handle, dato che le console non 
sono periferiche e quindi, nell'ipotesi che i loro handle fossero 
compatibili con quelli degli oggetti del kernel, non sarebbero in grado 
di rispondere ai pacchetti di richieste I/O (IRP), ossia ai meccanismi 
standard di I/O (mentre lo schermo blu, nonostante l'apparente 
somiglianza con i buffer di console, è gestito da un driver che risponde 
correttamente, ad esempio, ai pacchetti IRP_MJ_WRITE, ossia permette la 
scrittura tramite WriteFile). Tutto questo vale unicamente per Windows 
NT: nei Windows basati su DOS le console sono in tutto e per tutto 
oggetti del kernel
Per ragioni di coerenza gli handle a buffer di console seguono le stesse 
convenzioni riguardo al valore nullo seguite dagli handle a oggetti del 
kernel
 - PROCESSI E THREAD -
Questa parte riguarda unicamente i processi come sono gestiti in Windows 
95 e superiori, in Windows NT niente di quello che segue è vero
Gli id dei processi e dei thread, in realtà, sono degli handle globali. 
Sono dei puntatori alle strutture usate internamente da funzioni come 
GetCommandLine, GetStdHandle, eccetera, ossia le strutture che 
conservano lo stato dei processi e dei thread. Prima della release 
ufficiale di Windows 95 si decise che era troppo pericoloso esporre 
direttamente questo genere di informazioni, il cui formato tra l'altro 
era potenzialmente soggetto a miglioramenti e altre modifiche, dunque si 
aggiunse un meccanismo che all'avvio del sistema generava una chiave 
casuale a 32 bit, chiave che veniva usata per tutta la sessione per 
mascherare (tramite uno Xor) il reale valore degli id di processi e 
thread. Questa chiave entrò nella storia, oltre che per i tentativi di 
ottenerne il valore di volta in volta per avere accesso alle 
informazioni complete su un processo o thread, per il nome dato dal 
programmatore alla variabile che la conservava: dalle informazioni di 
debug incluse nel kernel32.dll delle beta di Windows 95 detta variabile 
risultò chiamarsi "obsfucator"... (ossia "obfuscator" con un errore di 
ortografia)
Maggiori informazioni su quest'argomento le trovate nei libri "Windows 
95 system programming secrets" e "Undocumented Windows 95", assieme al 
codice che permette di ottenere il valore dell'"obsfucator" e a 
tantissimo altro codice interessante
PS: che dite, spedisco al sito comune?

> PS: che dite, spedisco al sito comune?
risposta egoistica: a me non interessa, l'ho già salvato nella cartella
News Archiviate :)))
--
Fibia "BrokenHeart" FBI

di metterceli:
[snippone da gara]
Eccezionale: Windows in a nutshell :-)
spedisci pure al sc, tanto ho salvato il tutto gia' dopo il primo paragrafo :-)
ciao, hal

 PS: che dite, spedisco al sito comune?
Direi proprio di sě...   :-)
ciao
ugo

PS: che dite, spedisco al sito comune?
Perché? Non l'hai ancora fatto????
 :-PP
Ciao,
Moreno
#sirri#@#morenosoft#.com
(togliete "#" dall'indirizzo)
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------