Creazione e apertura di file
La funzione CreateFile può creare un nuovo file o aprire un file esistente. È necessario specificare il nome del file, le istruzioni di creazione e altri attributi. Quando un'applicazione crea un nuovo file, il sistema operativo lo aggiunge alla directory specificata.
Il sistema operativo assegna un identificatore univoco, denominato handle, a ogni file aperto o creato tramite CreateFile. Un'applicazione può usare questo handle con funzioni che leggono, scrivono e descrivono il file. È valido fino a quando non vengono chiusi tutti i riferimenti a tale handle. All'avvio di un'applicazione, eredita tutti gli handle aperti dal processo che lo ha avviato se gli handle sono stati creati come ereditabili.
Un'applicazione deve controllare il valore dell'handle restituito da CreateFile prima di tentare di usare l'handle per accedere al file. Se si verifica un errore, il valore dell'handle verrà INVALID_HANDLE_VALUE e l'applicazione può usare la funzione GetLastError per informazioni estese sull'errore.
Quando un'applicazione usa CreateFile, deve usare il parametro dwDesiredAccess per specificare se intende leggere dal file, scrivere nel file, leggere e scrivere o nessuno dei due. Questa operazione è nota come richiesta di una modalità di accesso. L'applicazione deve anche usare il parametro dwCreationDisposition per specificare l'azione da eseguire se il file esiste già, noto come eliminazione della creazione. Ad esempio, un'applicazione può chiamare CreateFile con dwCreationDisposition impostata su CREATE_ALWAYS per creare sempre un nuovo file, anche se esiste già un file con lo stesso nome (sovrascrivendo così il file esistente). L'esito positivo o negativo dipende da fattori come gli attributi e le impostazioni di sicurezza del file precedente (vedere le sezioni seguenti per altre informazioni).
Un'applicazione usa anche CreateFile per specificare se vuole condividere il file per la lettura, la scrittura, entrambe o nessuna delle due. Questa operazione è nota come modalità di condivisione. Non è possibile aprire di nuovo un file aperto non condiviso (dwShareMode impostato su zero) dall'applicazione che l'ha aperta o da un'altra applicazione fino alla chiusura del relativo handle. Si tratta anche di accesso esclusivo.
Quando un processo usa CreateFile per tentare di aprire un file già aperto in modalità di condivisione (dwShareMode impostato su un valore diverso da zero valido), il sistema confronta le modalità di accesso e condivisione richieste con quelle specificate all'apertura del file. Se si specifica una modalità di accesso o condivisione in conflitto con le modalità specificate nella chiamata precedente, CreateFile ha esito negativo.
La tabella seguente illustra le combinazioni valide di due chiamate a CreateFile usando varie modalità di accesso e modalità di condivisione (rispettivamente dwDesiredAccess, dwShareMode). Non importa in quale ordine vengono effettuate le chiamate CreateFile . Tuttavia, tutte le operazioni di I/O di file successive su ogni handle di file saranno comunque vincolate dalle modalità di accesso e condivisione correnti associate a tale handle di file specifico.
Prima chiamata a CreateFile | Second call valide a CreateFile |
---|---|
GENERIC_READ, FILE_SHARE_READ |
|
GENERIC_READ, FILE_SHARE_WRITE |
|
GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE |
|
GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE |
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE |
|
Oltre agli attributi di file standard, è anche possibile specificare gli attributi di sicurezza includendo un puntatore a una struttura SECURITY_ATTRIBUTES come quarto parametro di CreateFile. Tuttavia, il file system sottostante deve supportare la sicurezza per avere alcun effetto (ad esempio, il file system NTFS lo supporta, ma i vari file system FAT non lo supportano). Per altre informazioni sugli attributi di sicurezza, vedere Controllo di accesso.
Un'applicazione che crea un nuovo file può fornire un handle facoltativo a un file modello, da cui CreateFile accetta attributi di file e attributi estesi per la creazione del nuovo file.
Scenari CreateFile
Esistono diversi scenari fondamentali per avviare l'accesso a un file usando la funzione CreateFile. Questi sono riepilogati come segue:
- Creazione di un nuovo file quando un file con tale nome non esiste già.
- Creazione di un nuovo file anche se esiste già un file con lo stesso nome, cancellando i dati e avviando vuoto.
- Apertura di un file esistente solo se esistente e solo intatta.
- Apertura di un file esistente solo se esistente, troncandolo in modo che sia vuoto.
- Apertura di un file sempre: così come è se esiste, crearne uno nuovo se non esiste.
Questi scenari sono controllati dall'uso appropriato del parametro dwCreationDisposition . Di seguito è riportata una suddivisione del mapping di questi scenari ai valori per questo parametro e di cosa accade quando vengono usati.
Quando si crea o si apre un nuovo file quando un file con tale nome non esiste già (dwCreationDisposition impostato su CREATE_NEW, CREATE_ALWAYS o OPEN_ALWAYS), la funzione CreateFile esegue le azioni seguenti:
- Combina gli attributi e i flag di file specificati da dwFlagsAndAttributes con FILE_ATTRIBUTE_ARCHIVE.
- Imposta la lunghezza del file su zero.
- Copia gli attributi estesi forniti dal file modello nel nuovo file se viene specificato il parametro hTemplateFile (sostituisce tutti i flag FILE_ATTRIBUTE_* specificati in precedenza).
- Imposta il flag di ereditarietà specificato dal membro bInheritHandle e dal descrittore di sicurezza specificato dal membro lpSecurityDescriptor del parametro lpSecurityAttributes (struttura SECURITY_ATTRIBUTES ), se specificato.
Quando si crea un nuovo file anche se esiste già un file con lo stesso nome (dwCreationDisposition impostato su CREATE_ALWAYS), la funzione CreateFile esegue le azioni seguenti:
- Controlla gli attributi del file correnti e le impostazioni di sicurezza per l'accesso in scrittura, se viene negato.
- Combina gli attributi e i flag di file specificati da dwFlagsAndAttributes con FILE_ATTRIBUTE_ARCHIVE e gli attributi di file esistenti.
- Imposta la lunghezza del file su zero, ovvero tutti i dati presenti nel file non sono più disponibili e il file è vuoto.
- Copia gli attributi estesi forniti dal file modello nel nuovo file se viene specificato il parametro hTemplateFile (sostituisce tutti i flag FILE_ATTRIBUTE_* specificati in precedenza).
- Imposta il flag di ereditarietà specificato dal membro bInheritHandle del parametro lpSecurityAttributes (struttura SECURITY_ATTRIBUTES ) se specificato, ma ignora il membro lpSecurityDescriptor della struttura SECURITY_ATTRIBUTES .
- Se in caso contrario, CreateFile restituisce un handle valido, la chiamata a GetLastError restituirà il codice ERROR_ALREADY_EXISTS, anche se per questo particolare caso d'uso non si tratta effettivamente di un errore come tale (se si intende creare un file "nuovo" (vuoto) al posto di quello esistente.
Quando si apre un file esistente (dwCreationDisposition impostato su OPEN_EXISTING, OPEN_ALWAYS o TRUNCATE_EXISTING), la funzione CreateFile esegue le azioni seguenti:
- Controlla gli attributi del file correnti e le impostazioni di sicurezza per l'accesso richiesto, se viene negato.
- Combina i flag di file (FILE_FLAG_*) specificati da dwFlagsAndAttributes con gli attributi di file esistenti e ignora gli attributi di file (FILE_ATTRIBUTE_*) specificati da dwFlagsAndAttributes.
- Imposta la lunghezza del file su zero solo se dwCreationDisposition è impostato su TRUNCATE_EXISTING; in caso contrario, la lunghezza del file corrente viene mantenuta e il file viene aperto così come è.
- Ignora il parametro hTemplateFile .
- Imposta il flag di ereditarietà specificato dal membro bInheritHandle del parametro lpSecurityAttributes (struttura SECURITY_ATTRIBUTES ) se specificato, ma ignora il membro lpSecurityDescriptor della struttura SECURITY_ATTRIBUTES .
Attributi e directory dei file
Gli attributi di file fanno parte dei metadati associati a un file o a una directory, ognuno con il proprio scopo e regole su come può essere impostato e modificato. Alcuni di questi attributi si applicano solo ai file e alcuni solo alle directory. Ad esempio, l'attributo FILE_ATTRIBUTE_DIRECTORY si applica solo alle directory: viene usato dal file system per determinare se un oggetto su disco è una directory, ma non può essere modificato per un oggetto file system esistente.
Alcuni attributi di file possono essere impostati per una directory, ma hanno un significato solo per i file creati in tale directory, che fungono da attributi predefiniti. Ad esempio, FILE_ATTRIBUTE_COMPRESSED può essere impostato su un oggetto directory, ma poiché l'oggetto directory stesso non contiene dati effettivi, non viene effettivamente compresso. Tuttavia, le directory contrassegnate con questo attributo indicano al file system di comprimere tutti i nuovi file aggiunti alla directory. Qualsiasi attributo di file che può essere impostato in una directory e verrà impostato anche per i nuovi file aggiunti a tale directory viene definito attributo ereditato.
La funzione CreateFile fornisce un parametro per l'impostazione di determinati attributi di file quando viene creato un file. In generale, questi attributi sono i più comuni per un'applicazione da usare in fase di creazione di file, ma non tutti gli attributi di file possibili sono disponibili per CreateFile. Alcuni attributi di file richiedono l'uso di altre funzioni, ad esempio SetFileAttributes, DeviceIoControl o DecryptFile dopo che il file esiste già. Nel caso di FILE_ATTRIBUTE_DIRECTORY, la funzione CreateDirectory è necessaria in fase di creazione perché CreateFile non può creare directory. Gli altri attributi di file che richiedono una gestione speciale sono FILE_ATTRIBUTE_REPARSE_POINT e FILE_ATTRIBUTE_SPARSE_FILE, che richiedono DeviceIoControl. Per altre informazioni, vedere SetFileAttributes.
Come indicato in precedenza, l'ereditarietà degli attributi dei file si verifica quando viene creato un file con attributi di file letti dagli attributi della directory in cui si trova il file. Nella tabella seguente vengono riepilogati questi attributi ereditati e il modo in cui sono correlati alle funzionalità CreateFile .
Stato dell'attributo della directory | Funzionalità di override dell'ereditarietà CreateFile per i nuovi file |
---|---|
FILE_ATTRIBUTE_COMPRESSED impostata . |
Nessun controllo. Usare DeviceIoControl per cancellare. |
FILE_ATTRIBUTE_COMPRESSED non impostato. |
Nessun controllo. Usare DeviceIoControl per impostare. |
FILE_ATTRIBUTE_ENCRYPTED impostata . |
Nessun controllo. Usare DecryptFile. |
FILE_ATTRIBUTE_ENCRYPTED non impostato. |
Può essere impostato usando CreateFile. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED impostata . |
Nessun controllo. Usare SetFileAttributes per cancellare. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED non impostato. |
Nessun controllo. Usare SetFileAttributes per impostare. |