Función NtWriteFile (ntifs.h)

La rutina ZwWriteFile escribe datos en un archivo abierto.

Sintaxis

__kernel_entry NTSYSCALLAPI NTSTATUS NtWriteFile(
  [in]           HANDLE           FileHandle,
  [in, optional] HANDLE           Event,
  [in, optional] PIO_APC_ROUTINE  ApcRoutine,
  [in, optional] PVOID            ApcContext,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [in]           PVOID            Buffer,
  [in]           ULONG            Length,
  [in, optional] PLARGE_INTEGER   ByteOffset,
  [in, optional] PULONG           Key
);

Parámetros

[in] FileHandle

Identificador del objeto de archivo. Este identificador se crea mediante una llamada correcta a NtCreateFile o NtOpenFile.

[in, optional] Event

Opcionalmente, un identificador de un objeto de evento para establecer en el estado señalado una vez completada la operación de escritura. Los controladores intermedios y de dispositivo deben establecer este parámetro en NULL.

[in, optional] ApcRoutine

Este parámetro está reservado. Los controladores intermedios y de dispositivo deben establecer este puntero en NULL.

[in, optional] ApcContext

Este parámetro está reservado. Los controladores intermedios y de dispositivo deben establecer este puntero en NULL.

[out] IoStatusBlock

Puntero a una estructura de IO_STATUS_BLOCK que recibe el estado de finalización final e información sobre la operación de escritura solicitada. El miembro Information recibe el número de bytes escritos realmente en el archivo.

[in] Buffer

Puntero a un búfer asignado por el autor de la llamada que contiene los datos que se van a escribir en el archivo.

[in] Length

Tamaño, en bytes, del búfer al que apunta Buffer.

[in, optional] ByteOffset

Puntero a una variable que especifica el desplazamiento de bytes inicial en el archivo para iniciar la operación de escritura. Si Length y ByteOffset especifican una operación de escritura más allá de la marca de fin de archivo actual, NtWriteFile extiende automáticamente el archivo y actualiza la marca de fin de archivo; los bytes que no se escriben explícitamente entre dichas marcas de fin de archivo y antiguas se definen como cero.

Si la llamada a NtCreateFile establece solo la marca DesiredAccess FILE_APPEND_DATA, se omite ByteOffset . Los datos del búfer especificado, para bytes de longitud , se escriben a partir del final actual del archivo.

Si la llamada a NtCreateFile establece cualquiera de las marcas CreateOptions , FILE_SYNCHRONOUS_IO_ALERT o FILE_SYNCHRONOUS_IO_NONALERT, el Administrador de E/S mantiene la posición del archivo actual. Si es así, el autor de la llamada de NtWriteFile puede especificar que se use el desplazamiento de posición del archivo actual en lugar de un valor ByteOffset explícito. Esta especificación se puede realizar mediante uno de los métodos siguientes:

  • *Especifique un puntero a un valor de LARGE_INTEGER con el miembro HighPart establecido en -1 y el miembro LowPart establecido en el valor definido por el sistema FILE_USE_FILE_POINTER_POSITION.
  • Pase un puntero NULL para ByteOffset.

NtWriteFile actualiza la posición del archivo actual agregando el número de bytes escritos cuando completa la operación de escritura, si usa la posición del archivo actual mantenida por el Administrador de E/S.

Incluso cuando el Administrador de E/S mantiene la posición del archivo actual, el autor de la llamada puede restablecer esta posición pasando un valor ByteOffset explícito a NtWriteFile. Esto cambia automáticamente la posición del archivo actual a ese valor ByteOffset, realiza la operación de escritura y, a continuación, actualiza la posición según el número de bytes realmente escritos. Esta técnica proporciona al autor de la llamada servicio atomic seek-and-write.

También es posible hacer que una operación de escritura se inicie al final actual del archivo especificando para ByteOffset un puntero a un valor de LARGE_INTEGER con HighPart establecido en -1 y LowPart establecido en FILE_WRITE_TO_END_OF_FILE. Esto funciona independientemente de si el Administrador de E/S mantiene la posición actual del archivo.

[in, optional] Key

Los controladores intermedios y de dispositivo deben establecer este puntero en NULL.

Valor devuelto

NtWriteFile devuelve STATUS_SUCCESS si se ejecuta correctamente o el código de error NTSTATUS adecuado en caso de error.

Comentarios

Los autores de llamadas de NtWriteFile ya deben haber llamado a NtCreateFile con la marca FILE_WRITE_DATA, FILE_APPEND_DATA o GENERIC_WRITE establecida en el parámetro DesiredAccess . Tenga en cuenta que tener solo FILE_APPEND_DATA acceso a un archivo no permite que el autor de la llamada escriba en ningún lugar del archivo excepto en la marca de fin de archivo actual, mientras que tener FILE_WRITE_DATA acceso a un archivo no impide que el autor de la llamada escriba en o más allá del final de un archivo.

Si la llamada anterior a NtCreateFile establece la marca CreateOptions FILE_NO_INTERMEDIATE_BUFFERING, los parámetros Length y ByteOffset en NtWriteFile deben ser una parte integral del tamaño del sector. Para obtener más información, vea NtCreateFile.

NtWriteFile inicia la operación de escritura en el archivo en ByteOffset, en la posición del archivo actual o en la marca final del archivo. Finaliza la operación de escritura cuando ha escrito bytes de longitud del búfer. Si es necesario, extiende la longitud del archivo y restablece la marca de fin de archivo.

Si el autor de la llamada abrió el archivo con la marca DesiredAccess SYNCHRONIZE establecida, el autor de la llamada puede esperar a que esta rutina establezca fileHandle dado en el estado señalado.

Los controladores deben llamar a NtWriteFile en el contexto del proceso del sistema en tres casos:

  • El controlador crea el identificador de archivo que pasa a NtWriteFile.
  • NtWriteFile notifica al controlador la finalización de E/S mediante un evento creado por el controlador.
  • NtWriteFile notifica al controlador la finalización de E/S mediante una rutina de devolución de llamada de APC que el controlador pasa a NtWriteFile.

Los identificadores de archivos y eventos solo son válidos en el contexto de proceso donde se crean los identificadores. Por lo tanto, para evitar agujeros de seguridad, el controlador debe crear cualquier archivo o identificador de eventos que pase a NtWriteFile en el contexto del proceso del sistema en lugar del contexto de proceso en el que se encuentra el controlador.

Del mismo modo, se debe llamar a NtWriteFile en el contexto del proceso del sistema si notifica al controlador de finalización de E/S mediante un APC, ya que las API siempre se activan en el contexto del subproceso que emite la solicitud de E/S. Si el controlador llama a NtWriteFile en el contexto de un proceso distinto del proceso del sistema, el APC podría retrasarse indefinidamente o podría no activarse en absoluto, ya que el subproceso de origen nunca puede entrar en un estado de espera que se pueda alertar.

Para obtener más información sobre cómo trabajar con archivos, vea Uso de archivos en un controlador.

Los autores de llamadas de NtWriteFile deben ejecutarse en IRQL = PASSIVE_LEVEL y con las API de kernel especiales habilitadas.

Si la llamada a esta función se produce en modo de usuario, debe usar el nombre "NtWriteFile" en lugar de "ZwWriteFile".

En el caso de las llamadas desde controladores en modo kernel, las versiones NtXxx y ZwXxx de una rutina de Windows Native System Services pueden comportarse de forma diferente en la forma en que controlan e interpretan los parámetros de entrada. Para obtener más información sobre la relación entre las versiones NtXxx y ZwXxx de una rutina, vea Using Nt and Zw Versions of the Native System Services Routines.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000
Plataforma de destino Universal
Encabezado ntifs.h (incluye Wdm.h, Ntddk.h, Ntifs.h)
Library NtosKrnl.lib
Archivo DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL (consulte la sección Comentarios)
Reglas de cumplimiento de DDI HwStorPortProhibitedDIs, PowerIrpDDis

Consulte también

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile