Aujourd’hui on va voir **des notions fondamentales mais souvent mal comprises** en Win32 :
* les **handles**
* l’**héritage de handles**
* les **types Win32** (HANDLE, DWORD, LPVOID, etc.)
* **Unicode vs ANSI**
Ce sont des bases indispensables.
Si tu ne comprends pas ça, tu fais du Win32 à l’aveugle.
---
# 1) C’est quoi un handle
Un **HANDLE** est une **référence opaque** vers un objet noyau Windows.
Un handle :
* n’est PAS un pointeur
* n’est PAS une adresse mémoire utilisable
* n’a aucun sens en dehors du processus
Il permet d’accéder à :
* fichier
* processus
* thread
* mutex
* event
* job
* token
---
# 2) Pourquoi Windows utilise des handles
Windows sépare :
* l’espace utilisateur
* l’espace noyau
Le noyau ne donne jamais d’adresses directes.
À la place :
* le noyau garde l’objet
* l’utilisateur reçoit un handle
Le handle est une **clé d’accès contrôlée**.
---
# 3) Cycle de vie d’un handle
Un handle est :
* créé par une API
* utilisé
* fermé avec CloseHandle
Code: Select all
HANDLE hFile = CreateFileW(...);
CloseHandle(hFile);
* fuite de handle
* fuite noyau
* process instable
---
# 4) Pseudo-handles
Certaines fonctions retournent des **pseudo-handles**.
Exemples :
* GetCurrentProcess
* GetCurrentThread
Code: Select all
HANDLE hProc = GetCurrentProcess();
* un pseudo-handle ne doit PAS être fermé
* il est valable uniquement dans le processus courant
---
# 5) Héritage de handles
Par défaut :
* un processus enfant n’hérite de rien
Mais tu peux rendre un handle héritable.
Cela se fait via :
* SECURITY_ATTRIBUTES
* CreateProcess
---
# 6) Rendre un handle héritable
Code: Select all
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
HANDLE hPipe = CreatePipe(..., &sa, 0);
Code: Select all
CreateProcessW(
NULL,
cmdLine,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi
);
---
# 7) Dupliquer un handle
Pour transmettre un handle explicitement :
Code: Select all
DuplicateHandle(
hSrcProcess,
hHandle,
hDstProcess,
&hNewHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
* IPC
* sandbox
* services
---
# 8) Types Win32 : pourquoi autant de noms
Win32 utilise des **typedef** pour :
* la portabilité
* la lisibilité
* la sécurité
Les types décrivent l’intention.
---
# 9) Types entiers importants
* BYTE → 8 bits
* WORD → 16 bits
* DWORD → 32 bits non signé
* LONG → 32 bits signé
* ULONGLONG → 64 bits
Code: Select all
DWORD pid = GetCurrentProcessId();
# 10) Types pointeurs
* LPVOID → pointeur générique
* LPCVOID → pointeur constant
* LPBYTE → pointeur vers BYTE
Code: Select all
LPVOID buffer = VirtualAlloc(...);
---
# 11) Types handles spécialisés
Tous dérivent de HANDLE :
* HMODULE
* HINSTANCE
* HWND
* HDC
* HKEY
Ils ne sont PAS interchangeables.
---
# 12) BOOL vs bool
En Win32 :
* BOOL = int (4 octets)
* TRUE / FALSE
Ce n’est PAS le bool C++.
---
# 13) Unicode vs ANSI
Windows est **nativement Unicode**.
Deux versions d’API existent :
* ANSI → suffixe A
* Unicode → suffixe W
Exemple :
* CreateFileA
* CreateFileW
---
# 14) Les macros génériques
Si UNICODE est défini :
* CreateFile → CreateFileW
Sinon :
* CreateFile → CreateFileA
Types associés :
* TCHAR
* LPTSTR
* LPCTSTR
---
# 15) Bonnes pratiques Unicode
Toujours :
* utiliser les fonctions W
* utiliser wchar_t
* utiliser L"string"
Code: Select all
CreateFileW(L"test.txt", ...);
---
# 16) Erreurs classiques
* fermer un pseudo-handle
* oublier CloseHandle
* confondre HANDLE et pointeur
* mélanger A et W
* utiliser char au lieu de wchar_t
---
# À retenir
Un handle est une référence noyau.
Il doit être fermé.
L’héritage est explicite.
Les types Win32 ont un sens précis.
Windows est Unicode.
Comprendre les handles et les types, c’est écrire **du Win32 propre et sûr**.
