A un livello superiore, il vero problema con questo codice è che sta mescolando i modelli. Stai tentando di creare o aprire un file con un sistema (sistema VCL TStream) ma stai testando gli errori prodotti da un sistema diverso (API Win32).
L'unico modo per fare affidamento sul risultato GetLastError Win32 è se si chiamano da soli le funzioni Win32. Perché? Perché questo è l'unico modo per garantire che non ci siano altre chiamate a funzioni Win32 tra la chiamata di funzione Win32 e la chiamata a GetLastError. Ogni chiamata API Win32 ha il potenziale per (re) impostare GetLastError.
Anche se VCL si trova in cima a Win32, è possibile che si verifichi un'altra chiamata API Win32 tra quando si verifica l'errore e quando l'eccezione raggiunge il gestore. Anche se oggi le cose andassero bene, alcuni cambiamenti futuri nell'implementazione VCL potrebbero facilmente interrompere la felice coincidenza che è la situazione attuale.
Il modo migliore per evitare questo "tempo di attesa" in cui i dati necessari sono vulnerabili a essere sovrascritti consiste nell'ottenere il valore GetLastError catturato il più vicino possibile al punto di errore e incorporato in una proprietà dell'oggetto di eccezione VCL .Ciò non farebbe altro che eliminare il rischio di alcuni interlocutori innocenti tra il gestore delle eccezioni e il punto di errore che cancella lo stato globale GetLastError.
Cosa ti aspetti che sia? GetLastError restituisce l'ultimo errore generato da una funzione API di Windows e c'è solo uno slot, quindi qualsiasi cosa che il sistema di gestione delle eccezioni di Delphi potrebbe fare con l'API di Windows potrebbe reimpostare o modificare quel valore. Normalmente, le eccezioni personalizzate per le quali il valore di LastError è rilevante racchiudono il valore in una proprietà personalizzata. –
Devi chiamarlo immediatamente dopo una chiamata API. Non lo stai facendo. Prova a farlo subito dopo un fallito CreateFile. La linea di fondo è che il tuo codice non è valido. –