Función ZwWriteFile (wdm.h)

La rutina ZwWriteFile escribe datos en un archivo abierto.

Sintaxis

NTSYSAPI NTSTATUS ZwWriteFile(
  [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 ZwCreateFile o ZwOpenFile.

[in, optional] Event

Opcionalmente, un identificador de un objeto de evento que se va a 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 después de la marca de fin de archivo actual, ZwWriteFile extiende automáticamente el archivo y actualiza la marca de fin de archivo; los bytes que no se escriben explícitamente entre estas marcas de fin de archivo antiguas y nuevas se definen como cero.

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

Si la llamada a ZwCreateFile 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 ZwWriteFile 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.

ZwWriteFile 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 actual del archivo, el autor de la llamada puede restablecer esta posición pasando un valor ByteOffset explícito a ZwWriteFile. 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 el servicio atomic seek-and-write.

También es posible 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

ZwWriteFile 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 ZwWriteFile ya deben haber llamado ZwCreateFile 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 cualquier parte 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 ZwCreateFile establece la marca CreateOptions FILE_NO_INTERMEDIATE_BUFFERING, los parámetros Length y ByteOffset en ZwWriteFile deben ser integrales del tamaño del sector. Para obtener más información, vea ZwCreateFile.

ZwWriteFile comienza 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 ZwWriteFile en el contexto del proceso del sistema en tres casos:

  1. El controlador crea el identificador de archivo que pasa a ZwWriteFile.

  2. ZwWriteFile notifica al controlador la finalización de E/S mediante un evento creado por el controlador.

  3. ZwWriteFile notifica al controlador de finalización de E/S mediante una rutina de devolución de llamada de APC que el controlador pasa a ZwWriteFile.

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 ZwWriteFile 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 ZwWriteFile 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 ZwWriteFile 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 alertable.

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

Los autores de llamadas de ZwWriteFile 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 Servicios del sistema nativo de Windows se pueden comportar 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
Plataforma de destino Universal
Encabezado wdm.h (incluya 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(storport), PowerIrpDDis(wdm)

Consulte también

KeInitializeEvent

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile