Création et ouverture de fichiers

La fonction CreateFile peut créer un fichier ou ouvrir un fichier existant. Vous devez spécifier le nom de fichier, les instructions de création et d’autres attributs. Lorsqu’une application crée un fichier, le système d’exploitation l’ajoute au répertoire spécifié.

Le système d’exploitation affecte un identificateur unique, appelé handle, à chaque fichier ouvert ou créé à l’aide de CreateFile. Une application peut utiliser ce handle avec des fonctions qui lisent, écrivent et décrivent le fichier. Il est valide jusqu’à ce que toutes les références à ce handle soient fermées. Lorsqu’une application démarre, elle hérite de tous les handles ouverts du processus qui l’ont démarré si les handles ont été créés comme hérités.

Une application doit vérifier la valeur du handle retourné par CreateFile avant de tenter d’utiliser le handle pour accéder au fichier. Si une erreur se produit, la valeur de handle est INVALID_HANDLE_VALUE et l’application peut utiliser la fonction GetLastError pour obtenir des informations d’erreur étendues.

Lorsqu’une application utilise CreateFile, elle doit utiliser le paramètre dwDesiredAccess pour spécifier s’il a l’intention de lire à partir du fichier, d’écrire dans le fichier, de lire et d’écrire ou non. Il s’agit de la demande d’un mode d’accès. L’application doit également utiliser le paramètre dwCreationDisposition pour spécifier quelle action effectuer si le fichier existe déjà, appelé disposition de création. Par exemple, une application peut appeler CreateFile avec dwCreationDisposition définie sur CREATE_ALWAYS pour créer toujours un fichier, même si un fichier du même nom existe déjà (ce qui remplace le fichier existant). Si cela réussit ou non dépend de facteurs tels que les attributs et les paramètres de sécurité du fichier précédent (consultez les sections suivantes pour plus d’informations).

Une application utilise également CreateFile pour spécifier s’il souhaite partager le fichier pour la lecture, l’écriture, les deux ou non. Il s’agit du mode de partage. Un fichier ouvert qui n’est pas partagé (dwShareMode défini sur zéro) ne peut pas être ouvert à nouveau, soit par l’application qui l’a ouverte ou par une autre application, tant que son handle n’a pas été fermé. Il s’agit également d’un accès exclusif.

Lorsqu’un processus utilise CreateFile pour tenter d’ouvrir un fichier qui a déjà été ouvert en mode de partage (dwShareMode défini sur une valeur non nulle valide), le système compare les modes d’accès et de partage demandés à ceux spécifiés lors de l’ouverture du fichier. Si vous spécifiez un mode d’accès ou de partage qui est en conflit avec les modes spécifiés dans l’appel précédent, CreateFile échoue.

Le tableau suivant illustre les combinaisons valides de deux appels à CreateFile à l’aide de différents modes d’accès et modes de partage (dwDesiredAccess, dwShareMode respectivement). Il n’est pas important dans quel ordre les appels CreateFile sont effectués. Toutefois, les opérations d’E/S de fichier suivantes sur chaque handle de fichier seront toujours limitées par les modes d’accès et de partage actuels associés à ce handle de fichier particulier.

Premier appel à CreateFile Deuxième appel valide à CreateFile
GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READFILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READFILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READGENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READGENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE

En plus des attributs de fichier standard, vous pouvez également spécifier des attributs de sécurité en incluant un pointeur vers une structure de SECURITY_ATTRIBUTES comme quatrième paramètre de CreateFile. Toutefois, le système de fichiers sous-jacent doit prendre en charge la sécurité pour que cela ait un effet (par exemple, le système de fichiers NTFS le prend en charge, mais les différents systèmes de fichiers FAT ne le font pas). Pour plus d’informations sur les attributs de sécurité, consultez Access Control.

Une application qui crée un fichier peut fournir un handle facultatif à un fichier de modèle, à partir duquel CreateFile accepte des attributs de fichier et des attributs étendus pour la création du nouveau fichier.

Scénarios CreateFile

Il existe plusieurs scénarios fondamentaux pour lancer l’accès à un fichier à l’aide de la fonction CreateFile . Ces éléments sont résumés comme suit :

  • La création d’un fichier lorsqu’un fichier portant ce nom n’existe pas déjà.
  • Création d’un fichier même si un fichier du même nom existe déjà, effacez ses données et démarrez vide.
  • Ouverture d’un fichier existant uniquement s’il existe, et uniquement intact.
  • Ouverture d’un fichier existant uniquement s’il existe, tronquer celui-ci pour être vide.
  • Ouverture d’un fichier toujours : tel quel s’il existe, création d’un fichier s’il n’existe pas.

Ces scénarios sont contrôlés par l’utilisation appropriée du paramètre dwCreationDisposition . Voici une répartition de la façon dont ces scénarios sont mappés aux valeurs de ce paramètre et ce qui se passe lorsqu’ils sont utilisés.

Lors de la création ou de l’ouverture d’un fichier lorsqu’un fichier portant ce nom n’existe pas déjà (dwCreationDisposition défini sur CREATE_NEW, CREATE_ALWAYS ou OPEN_ALWAYS), la fonction CreateFile effectue les actions suivantes :

  • Combine les attributs de fichier et les indicateurs spécifiés par dwFlagsAndAttributes avec FILE_ATTRIBUTE_ARCHIVE.
  • Définit la longueur du fichier sur zéro.
  • Copie les attributs étendus fournis par le fichier de modèle dans le nouveau fichier si le paramètre hTemplateFile est spécifié (cela remplace tous les indicateurs FILE_ATTRIBUTE_* spécifiés précédemment).
  • Définit l’indicateur hérite spécifié par le membre bInheritHandle et le descripteur de sécurité spécifié par le membre lpSecurityDescriptor du paramètre lpSecurityAttributes (structure SECURITY_ATTRIBUTES ), s’il est fourni.

Lors de la création d’un fichier même si un fichier du même nom existe déjà (dwCreationDisposition défini sur CREATE_ALWAYS), la fonction CreateFile effectue les actions suivantes :

  • Vérifie les attributs de fichier actuels et les paramètres de sécurité pour l’accès en écriture, en cas d’échec s’il est refusé.
  • Combine les attributs de fichier et les indicateurs spécifiés par dwFlagsAndAttributes avec FILE_ATTRIBUTE_ARCHIVE et les attributs de fichier existants.
  • Définit la longueur du fichier sur zéro (autrement dit, toutes les données figurant dans le fichier ne sont plus disponibles et le fichier est vide).
  • Copie les attributs étendus fournis par le fichier de modèle dans le nouveau fichier si le paramètre hTemplateFile est spécifié (cela remplace tous les indicateurs FILE_ATTRIBUTE_* spécifiés précédemment).
  • Définit l’indicateur hérite spécifié par le membre bInheritHandle du paramètre lpSecurityAttributes (structure SECURITY_ATTRIBUTES ) s’il est fourni, mais ignore le membre lpSecurityDescriptor de la structure SECURITY_ATTRIBUTES .
  • S’il réussit (autrement dit, CreateFile retourne un handle valide), l’appel de GetLastError génère le code ERROR_ALREADY_EXISTS, même si pour ce cas d’usage particulier, il n’est pas réellement une erreur telle (si vous souhaitez créer un fichier « nouveau » (vide) à la place de l’existant.

Lors de l’ouverture d’un fichier existant (dwCreationDisposition défini sur OPEN_EXISTING, OPEN_ALWAYS ou TRUNCATE_EXISTING), la fonction CreateFile effectue les actions suivantes :

  • Vérifie les attributs de fichier actuels et les paramètres de sécurité pour l’accès demandé, en cas d’échec s’il est refusé.
  • Combine les indicateurs de fichier (FILE_FLAG_*) spécifiés par dwFlagsAndAttributes avec les attributs de fichier existants et ignore tous les attributs de fichier (FILE_ATTRIBUTE_*) spécifiés par dwFlagsAndAttributes.
  • Définit la longueur du fichier sur zéro uniquement si dwCreationDisposition est défini sur TRUNCATE_EXISTING, sinon la longueur de fichier actuelle est conservée et le fichier est ouvert en tant que tel.
  • Ignore le paramètre hTemplateFile .
  • Définit l’indicateur hérite spécifié par le membre bInheritHandle du paramètre lpSecurityAttributes (structure SECURITY_ATTRIBUTES ) s’il est fourni, mais ignore le membre lpSecurityDescriptor de la structure SECURITY_ATTRIBUTES .

Attributs de fichier et répertoires

Les attributs de fichier font partie des métadonnées associées à un fichier ou un répertoire, chacune ayant ses propres objectifs et règles sur la façon dont elle peut être définie et modifiée. Certains de ces attributs s’appliquent uniquement aux fichiers, et certains uniquement aux répertoires. Par exemple, l’attribut FILE_ATTRIBUTE_DIRECTORY s’applique uniquement aux répertoires : il est utilisé par le système de fichiers pour déterminer si un objet sur disque est un répertoire, mais il ne peut pas être modifié pour un objet de système de fichiers existant.

Certains attributs de fichier peuvent être définis pour un répertoire, mais ont une signification uniquement pour les fichiers créés dans ce répertoire, agissant comme attributs par défaut. Par exemple, FILE_ATTRIBUTE_COMPRESSED peut être défini sur un objet d’annuaire, mais parce que l’objet d’annuaire lui-même ne contient pas de données réelles, il n’est pas vraiment compressé ; Toutefois, les répertoires marqués avec cet attribut indiquent au système de fichiers de compresser les nouveaux fichiers ajoutés à ce répertoire. Tout attribut de fichier qui peut être défini sur un répertoire et qui sera également défini pour les nouveaux fichiers ajoutés à ce répertoire est appelé attribut hérité.

La fonction CreateFile fournit un paramètre pour définir certains attributs de fichier lorsqu’un fichier est créé. En général, ces attributs sont les plus courants pour une application à utiliser au moment de la création de fichiers, mais tous les attributs de fichier possibles sont disponibles pour CreateFile. Certains attributs de fichier nécessitent l’utilisation d’autres fonctions, telles que SetFileAttributes, DeviceIoControl ou DecryptFile une fois que le fichier existe déjà. Dans le cas de FILE_ATTRIBUTE_DIRECTORY, la fonction CreateDirectory est requise au moment de la création, car CreateFile ne peut pas créer de répertoires. Les autres attributs de fichier qui nécessitent une gestion spéciale sont FILE_ATTRIBUTE_REPARSE_POINT et FILE_ATTRIBUTE_SPARSE_FILE, ce qui nécessite DeviceIoControl. Pour plus d’informations, consultez SetFileAttributes.

Comme indiqué précédemment, l’héritage des attributs de fichier se produit lorsqu’un fichier est créé avec des attributs de fichier lus à partir des attributs d’annuaire où se trouve le fichier. Le tableau suivant récapitule ces attributs hérités et leur relation avec les fonctionnalités CreateFile .

État de l’attribut d’annuaire Fonctionnalité de remplacement de l’héritage CreateFile pour les nouveaux fichiers
FILE_ATTRIBUTE_COMPRESSED défini.
Aucun contrôle. Utilisez DeviceIoControl pour effacer.
FILE_ATTRIBUTE_COMPRESSED pas défini.
Aucun contrôle. Utilisez DeviceIoControl pour définir.
FILE_ATTRIBUTE_ENCRYPTED défini.
Aucun contrôle. Utilisez DecryptFile.
FILE_ATTRIBUTE_ENCRYPTED pas défini.
Peut être défini à l’aide de CreateFile.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED défini.
Aucun contrôle. Utilisez SetFileAttributes pour effacer.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED pas défini.
Aucun contrôle. Utilisez SetFileAttributes pour définir.

Contrôle d’accès

CreateFile

DeviceIoControl

Constantes d’attribut de fichier

Compression de fichier et décompression

Chiffrement des fichiers

Fonctions de gestion des fichiers

Handles et objets

Gérer l’héritage

Ouverture d’un fichier pour la lecture ou l’écriture

SetFileAttributes