Fonction NtCreateFile (ntifs.h)
La routine NtCreateFile crée un fichier ou ouvre un fichier existant.
Syntaxe
__kernel_entry NTSYSCALLAPI NTSTATUS NtCreateFile(
[out] PHANDLE FileHandle,
[in] ACCESS_MASK DesiredAccess,
[in] POBJECT_ATTRIBUTES ObjectAttributes,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[in, optional] PLARGE_INTEGER AllocationSize,
[in] ULONG FileAttributes,
[in] ULONG ShareAccess,
[in] ULONG CreateDisposition,
[in] ULONG CreateOptions,
[in, optional] PVOID EaBuffer,
[in] ULONG EaLength
);
Paramètres
[out] FileHandle
Pointeur vers une variable HANDLE qui reçoit un handle vers le fichier.
[in] DesiredAccess
Spécifie une valeur ACCESS_MASK qui détermine l’accès demandé à l’objet.
Outre les droits d’accès standard définis pour tous les types d’objets, l’appelant peut spécifier l’un des droits d’accès spécifiques ; c’est-à-dire des droits spécifiques aux fichiers.
indicateur de ACCESS_MASK | Permet à l’appelant de procéder ainsi |
---|---|
FILE_READ_DATA | Lit les données du fichier. |
FILE_READ_ATTRIBUTES | Lisez les attributs du fichier. Pour plus d’informations, consultez la description du paramètre FileAttributes. |
FILE_READ_EA | Lisez les attributs étendus du fichier. Cet indicateur n’est pas pertinent pour les pilotes de périphérique et intermédiaire. |
FILE_WRITE_DATA | Écrivez des données dans le fichier. |
FILE_WRITE_ATTRIBUTES | Écrivez les attributs du fichier. Pour plus d’informations, consultez la description du paramètre FileAttributes. |
FILE_WRITE_EA | Modifiez les attributs étendus du fichier. Cet indicateur n’est pas pertinent pour les pilotes de périphérique et intermédiaire. |
FILE_APPEND_DATA | Ajoutez des données au fichier. |
FILE_EXECUTE | Utilisez les E/S de pagination système pour lire les données du fichier en mémoire. Cet indicateur n’est pas pertinent pour les pilotes de périphérique et intermédiaire. |
Note
Ne spécifiez pas FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA ou FILE_EXECUTE lorsque vous créez ou ouvrez un répertoire.
L’appelant peut également spécifier le générique droits d’accès (droits qui s’appliquent à tous les types d’objets, où la signification de chaque droit d’accès générique est spécifique au type d’objet). Les droits d’accès génériques pour les objets de fichier correspondent à des droits d’accès spécifiques, comme indiqué dans le tableau suivant. (Notez que « correspond » signifie « mappe » et ne signifie pas que la valeur du droit générique est « égale à » la valeur de l’OR au niveau du bit de son mappage de droits spécifiques). Le gestionnaire d’E/S définit le mappage réel.
Droit d’accès générique | Mappe à ces droits d’accès spécifiques |
---|---|
GENERIC_READ | STANDARD_RIGHTS_READ, FILE_READ_DATA, FILE_READ_ATTRIBUTES, FILE_READ_EA et SYNCHRONIZE |
GENERIC_WRITE | STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA, FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, FILE_APPEND_DATA et SYNCHRONIZE |
GENERIC_EXECUTE | STANDARD_RIGHTS_EXECUTE, FILE_EXECUTE, FILE_READ_ATTRIBUTES et SYNCHRONIZE. Cette valeur n’est pas pertinente pour les pilotes de périphérique et intermédiaire. |
GENERIC_ALL | FILE_ALL_ACCESS |
Note
droits d’accès génériques ne peuvent être spécifiés que pour un fichier ; ils ne peuvent pas être spécifiés pour un répertoire.
Certains indicateurs CreateOptions nécessitent que certains indicateurs d’accès soient définis dans DesiredAccess lorsque NtCreateFile est appelé. Pour plus d’informations, consultez le paramètre CreateOptions.
Par exemple, si vous spécifiez GENERIC_READ pour un objet de fichier, la routine mappe cette valeur au masque de bits FILE_GENERIC_READ des droits d’accès spécifiques. Dans le tableau précédent, les droits d’accès spécifiques répertoriés pour GENERIC_READ correspondent à (mais ne sont pas égaux) aux indicateurs d’accès contenus dans le masque de bits FILE_GENERIC_READ.
Si le fichier est en fait un répertoire, l’appelant peut également spécifier les droits d’accès génériques suivants.
indicateur DesiredAccess | Permet à l’appelant de procéder ainsi |
---|---|
FILE_LIST_DIRECTORY | Répertoriez les fichiers dans le répertoire. |
FILE_TRAVERSE | Parcourez le répertoire, en d’autres termes, incluez le répertoire dans le chemin d’accès d’un fichier. |
Pour plus d’informations sur les droits d’accès, consultez ACCESS_MASK et droits d’accès.
[in] ObjectAttributes
Pointeur vers une structure OBJECT_ATTRIBUTES qui spécifie le nom de l’objet et d’autres attributs. Utilisez InitializeObjectAttributes pour initialiser cette structure. Si l’appelant n’est pas en cours d’exécution dans un contexte de thread système, il doit définir l’attribut OBJ_KERNEL_HANDLE lorsqu’il appelle InitializeObjectAttributes.
[out] IoStatusBlock
Pointeur vers une structure IO_STATUS_BLOCK qui reçoit l’état d’achèvement final et d’autres informations sur l’opération demandée. En particulier, l'Information membre reçoit l’une des valeurs suivantes :
- FILE_CREATED
- FILE_OPENED
- FILE_OVERWRITTEN
- FILE_SUPERSEDED
- FILE_EXISTS
- FILE_DOES_NOT_EXIST
[in, optional] AllocationSize
Pointeur vers un LARGE_INTEGER qui contient la taille d’allocation initiale, en octets, pour un fichier créé ou remplacé. Si AllocationSize est NULL, aucune taille d’allocation n’est spécifiée. Si aucun fichier n’est créé ou remplacé, AllocationSize est ignoré.
[in] FileAttributes
Spécifie un ou plusieurs indicateurs FILE_ATTRIBUTE_XXX, qui représentent les attributs de fichier à définir si vous créez ou remplacez un fichier. L’appelant spécifie généralement FILE_ATTRIBUTE_NORMAL, qui définit les attributs par défaut. Pour obtenir la liste des indicateurs de XXX FILE_ATTRIBUTE_
[in] ShareAccess
Type d’accès de partage, qui est spécifié comme zéro ou toute combinaison des indicateurs suivants.
indicateur de ShareAccess | Permet à d’autres threads de procéder ainsi |
---|---|
FILE_SHARE_READ | Lire le fichier |
FILE_SHARE_WRITE | Écrire le fichier |
FILE_SHARE_DELETE | Supprimer le fichier |
Les pilotes de périphérique et intermédiaire définissent généralement ShareAccess sur zéro, ce qui donne à l’appelant un accès exclusif au fichier ouvert.
[in] CreateDisposition
Spécifie l’action à effectuer si le fichier existe ou n’existe pas. CreateDisposition peut être l’une des valeurs du tableau suivant.
valeur CreateDisposition | Action si le fichier existe | Action si le fichier n’existe pas |
---|---|---|
FILE_SUPERSEDE | Remplacez le fichier. | Créez le fichier. |
FILE_CREATE | Retourne une erreur. | Créez le fichier. |
FILE_OPEN | Ouvrez le fichier. | Retourne une erreur. |
FILE_OPEN_IF | Ouvrez le fichier. | Créez le fichier. |
FILE_OVERWRITE | Ouvrez le fichier et remplacez-le. | Retourne une erreur. |
FILE_OVERWRITE_IF | Ouvrez le fichier et remplacez-le. | Créez le fichier. |
[in] CreateOptions
Spécifie les options à appliquer lorsque le pilote crée ou ouvre le fichier. Utilisez un ou plusieurs indicateurs dans le tableau suivant.
[in, optional] EaBuffer
Pour les pilotes de périphérique et intermédiaire, ce paramètre doit être un pointeur NULL.
[in] EaLength
Pour les pilotes de périphérique et intermédiaire, ce paramètre doit être égal à zéro.
Valeur de retour
NtCreateFile retourne STATUS_SUCCESS sur la réussite ou un code d’erreur NTSTATUS approprié en cas d’échec. Dans ce dernier cas, l’appelant peut déterminer la cause de l’échec en vérifiant le paramètre IoStatusBlock.
Note
Remarques
NtCreateFile fournit un handle que l’appelant peut utiliser pour manipuler les données d’un fichier, ou l’état et les attributs de l’objet de fichier. Pour plus d’informations, consultez Using Files in a Driver.
Une fois que le handle pointé par FileHandle n’est plus utilisé, le pilote doit appeler NtClose pour le fermer.
Si l’appelant n’est pas en cours d’exécution dans un contexte de thread système, il doit s’assurer que les handles qu’il crée sont des handles privés. Sinon, le handle est accessible par le processus dans lequel le pilote est en cours d’exécution. Pour plus d’informations, consultez Descripteurs d’objets.
Il existe deux façons de spécifier le nom du fichier à créer ou ouvrir avec NtCreateFile:
- En tant que chemin d’accès complet, fourni dans le ObjectName membre de l’entrée ObjectAttributes.
- En tant que chemin d’accès relatif au fichier de répertoire représenté par le handle dans le RootDirectory membre de l’entrée ObjectAttributes.
La définition de certains indicateurs dans le paramètre DesiredAccess entraîne les effets suivants :
- Pour qu’un appelant synchronise une saisie semi-automatique en attendant laFileHandle
retournée, l’indicateur SYNCHRONIZE doit être défini. Sinon, un appelant qui est un périphérique ou un pilote intermédiaire doit synchroniser une saisie semi-automatique à l’aide d’un objet d’événement. - Si l’appelant définit uniquement les indicateurs FILE_APPEND_DATA et SYNCHRONIZE, il peut écrire uniquement à la fin du fichier, et toutes les informations de décalage sur les opérations d’écriture dans le fichier sont ignorées. Le fichier sera automatiquement étendu si nécessaire pour ce type d’opération.
- La définition de l’indicateur FILE_WRITE_DATA pour un fichier permet également à l’appelant d’écrire au-delà de la fin du fichier. Là encore, le fichier est automatiquement étendu si nécessaire.
- Si l’appelant définit uniquement les indicateurs FILE_EXECUTE et SYNCHRONIZE, il ne peut pas lire ou écrire directement des données dans le fichier à l’aide du FileHandle retourné. Autrement dit, toutes les opérations sur le fichier se produisent via le pagineur système en réponse aux opérations d’instruction et d’accès aux données. Les pilotes de périphérique et intermédiaire ne doivent pas définir l’indicateur de FILE_EXECUTE.
Le paramètre ShareAccess détermine si des threads distincts peuvent accéder au même fichier, éventuellement simultanément. À condition que les deux appelants disposent des privilèges d’accès appropriés, le fichier peut être correctement ouvert et partagé. Si l’appelant d’origine de NtCreateFile ne spécifie pas FILE_SHARE_READ, FILE_SHARE_WRITE ou FILE_SHARE_DELETE, aucun autre appelant ne peut ouvrir le fichier, autrement dit, l’appelant d’origine reçoit un accès exclusif.
Pour ouvrir un fichier partagé, les indicateurs de DesiredAccess
La valeur CreateDisposition FILE_SUPERSEDE
Les valeurs CreateDisposition FILE_OVERWRITE_IF et FILE_SUPERSEDE sont similaires. Si NtCreateFile est appelé avec un fichier existant et l’une de ces valeurs CreateDisposition, le fichier est remplacé.
Le remplacement d’un fichier équivaut sémantiquement à une opération de remplacement, à l’exception des éléments suivants :
- L’appelant doit disposer d’un accès en écriture au fichier, plutôt que de supprimer l’accès. Cela implique que, si le fichier a déjà été ouvert par un autre thread, il a ouvert le fichier avec l’indicateur de FILE_SHARE_WRITE défini dans l’entrée ShareAccess.
- Les attributs de fichier spécifiés sont logiquement ORed avec ceux déjà présents dans le fichier. Cela implique que, si le fichier a déjà été ouvert par un autre thread, un appelant suivant de NtCreateFile ne peut pas désactiver les indicateurs de FileAttributes existants, mais peut activer des indicateurs supplémentaires pour le même fichier. Notez que ce style de remplacement de fichiers est cohérent avec MS-DOS, Microsoft Windows 3.1 et OS/2.
La valeur FILE_DIRECTORY_FILE CreateOptions spécifie que le fichier à créer ou ouvert est un répertoire. Lorsqu’un fichier de répertoire est créé, le système de fichiers crée une structure appropriée sur le disque pour représenter un répertoire vide pour la structure sur disque de ce système de fichiers particulier. Si cette option a été spécifiée et que le fichier donné à ouvrir n’est pas un fichier de répertoire, ou si l’appelant a spécifié une createOptions incohérente ou valeur CreateDisposition, l’appel à NtCreateFile échouera.
L’indicateur FILE_NO_INTERMEDIATE_BUFFERING CreateOptions empêche le système de fichiers d’effectuer une mise en mémoire tampon intermédiaire pour le compte de l’appelant. La spécification de cet indicateur place les restrictions suivantes sur les paramètres de l’appelant à d’autres routines ZwXxxFile.
- Toute ByteOffset facultative passée à NtReadFile ou NtWriteFile doit être un multiple de la taille du secteur.
- Le length
passé à NtReadFile ou NtWriteFile doit être une partie intégrante de la taille du secteur. Notez que la spécification d’une opération de lecture dans une mémoire tampon dont la longueur est exactement la taille du secteur peut entraîner un nombre moindre d’octets significatifs transférés vers cette mémoire tampon si la fin du fichier a été atteinte pendant le transfert. - Les mémoires tampons doivent être alignées conformément aux exigences d’alignement de l’appareil sous-jacent. Pour obtenir ces informations, appelez NtCreateFile pour obtenir un handle pour l’objet de fichier qui représente l’appareil physique et transmettez ce handle à NtQueryInformationFile. Pour obtenir la liste des valeurs de_ALIGNMENT XXX FILE_
du système, consultez DEVICE_OBJECT . - Les appels à
NtSetInformationFile avec le paramètre FileInformationClass défini sur FilePositionInformation doivent spécifier un décalage qui est un multiple de la taille du secteur.
Les indicateurs FILE_SYNCHRONOUS_IO_ALERT et FILE_SYNCHRONOUS_IO_NONALERT CreateOptions (qui s’excluent mutuellement) spécifient que toutes les opérations d’E/S sur le fichier seront synchrones, tant que les opérations se produisent via l’objet de fichier référencé par le FileHandle retourné. Toutes les E/S sur un tel fichier sont sérialisées sur tous les threads à l’aide du handle retourné. Si l’un de ces indicateurs CreateOptions est défini, l’indicateur SYNCHRON DesiredAccess doit également être défini pour obliger le gestionnaire d’E/S à utiliser l’objet de fichier comme objet de synchronisation. Dans ce cas, le gestionnaire d’E/S effectue le suivi du décalage de position de fichier actuel, que vous pouvez passer à NtReadFile et NtWriteFile. Appelez NtQueryInformationFile ou NtSetInformationFile pour obtenir ou définir cette position.
Si l’indicateur FILE_OPEN_REPARSE_POINT CreateOptions
L’indicateur de FILE_OPEN_REQUIRING_OPLOCK CreateOptions
Dans Windows 7, si d’autres handles existent sur le fichier lorsqu’une application utilise l’indicateur FILE_OPEN_REQUIRING_OPLOCK, l’opération de création échoue avec STATUS_OPLOCK_NOT_GRANTED. Cette restriction n’existe plus à partir de Windows 8.
Si cette opération de création interrompt un oplock qui existe déjà sur le fichier, la définition de l’indicateur de FILE_OPEN_REQUIRING_OPLOCK entraîne l’échec de l’opération de création avec STATUS_CANNOT_BREAK_OPLOCK. L’oplock existant ne sera pas rompu par cette opération de création.
Une application qui utilise l’indicateur de FILE_OPEN_REQUIRING_OPLOCK doit demander un oplock une fois cet appel réussi, ou toutes les tentatives suivantes d’ouverture du fichier seront bloquées sans bénéficier du traitement normal d’oplock. De même, si cet appel réussit mais que la requête oplock suivante échoue, une application qui utilise cet indicateur doit fermer son handle après qu’elle détecte que la demande oplock a échoué. L’application ne doit effectuer aucune autre opération de système de fichiers sur le fichier avant de demander l’oplock (en plus de fermer le handle de fichier), sinon un blocage peut se produire.
Note
L’indicateur FILE_OPEN_REQUIRING_OPLOCK est disponible dans les systèmes d’exploitation Windows 7, Windows Server 2008 R2 et versions ultérieures. Les systèmes de fichiers Microsoft qui implémentent cet indicateur dans Windows 7 sont NTFS, FAT et exFAT.
L’indicateur CreateOptions FILE_RESERVE_OPFILTER permet à une application de demander un oplock De niveau 1, Batch ou Filter pour empêcher d’autres applications d’obtenir des violations de partage. Toutefois, FILE_RESERVE_OPFILTER n’est pratiquement utile que pour les verrous de filtre. Pour l’utiliser, vous devez effectuer les étapes suivantes :
- Émettre une demande de création avec CreateOptions de FILE_RESERVE_OPFILTER, DesiredAccess exactement FILE_READ_ATTRIBUTES et ShareAccess exactement FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
- S’il existe déjà des handles ouverts, la demande de création échoue avec STATUS_OPLOCK_NOT_GRANTED, et le verrou d’opération demandé suivant échoue également.
- Si vous ouvrez avec plus d’accès ou moins de partage, cela entraîne également un échec de STATUS_OPLOCK_NOT_GRANTED.
- Si la demande de création réussit, demandez un oplock.
- Ouvrez un autre handle dans le fichier pour effectuer des E/S.
L’étape 3 rend cette opération pratique uniquement pour les verrous de filtre. Le handle ouvert à l’étape 3 peut avoir un DesiredAccess qui contient un maximum de FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONISER | READ_CONTROL et n’interrompez toujours pas un blocage de filtre. Toutefois, toute DesiredAccess supérieure à FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE interrompt un oplock de niveau 1 ou Batch et rend l’indicateur FILE_RESERVE_OPFILTER inutile pour ces types d’oplock.
NTFS est le seul système de fichiers Microsoft qui implémente FILE_RESERVE_OPFILTER.
Pour l’indicateur FILE_OPEN_BY_FILE_ID CreateOptions
\??\C:\<FileID>
\device\HardDiskVolume1\<ObjectID>
où FileID est de 8 octets et ObjectID est de 16 octets :
- Sur NTFS, il peut s’agir d’un numéro de référence de 8 octets ou de 16 octets ou d’un ID d’objet. Un numéro de référence de 16 octets est identique à un nombre de 8 octets rempli de zéros.
- Sur ReFS, il peut s’agir d’un numéro de référence de 8 octets ou de 16 octets. Un nombre de 16 octets n’est pas lié à un nombre de 8 octets. Les ID d’objet ne sont pas pris en charge.
- Les systèmes de fichiers FAT, ExFAT, UDFS et CDFS ne prennent pas en charge l’indicateur de FILE_OPEN_BY_FILE_ID.
Ce nombre est attribué et spécifique au système de fichiers particulier. Étant donné que le champ de nom de fichier contient en partie un objet blob binaire, il est incorrect de supposer qu’il s’agit d’une chaîne Unicode valide, et plus important encore, ne peut pas être une chaîne terminée null.
Les appelants de NtCreateFile doivent s’exécuter à IRQL = PASSIVE_LEVEL et avec des API de noyau spéciales activées.
Note
Si l’appel à cette fonction se produit en mode utilisateur, vous devez utiliser le nom «NtCreateFile» au lieu de «ZwCreateFile».
Pour les appels à partir de pilotes en mode noyau, les versions NtXxx et ZwXxx d’une routine Windows Native System Services peuvent se comporter différemment de la façon dont elles gèrent et interprètent les paramètres d’entrée. Pour plus d’informations sur la relation entre les versions NtXxx et ZwXxx d’une routine, consultez Using Nt and Zw Versions of the Native System Services Routines.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Windows 2000 |
plateforme cible | Universel |
d’en-tête | ntifs.h (include Wdm.h, Ntddk.h, Ntifs.h) |
bibliothèque | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (voir la section Remarques) |
règles de conformité DDI | HwStorPortProhibitedDDIs, PowerIrpDDis |