IRP_MJ_WRITE (controladores de filtro y FS)

Cuándo se envió

El Administrador de E/S o un controlador del sistema de archivos envía la solicitud de IRP_MJ_WRITE. Esta solicitud se puede enviar, por ejemplo, cuando una aplicación en modo de usuario ha llamado a una función Win32 como WriteFile o cuando un componente en modo kernel ha llamado ZwWriteFile.

Operación: controladores del sistema de archivos

El controlador del sistema de archivos debe extraer y descodificar el objeto de archivo para determinar los parámetros y el código de función secundaria.

Para las solicitudes de escritura MDL, el sistema de archivos debe comprobar el código de función secundaria para determinar qué operación se solicita. A continuación se muestran los códigos de función secundaria válidos, que solo se pueden usar para E/S de archivos almacenados en caché:

  • IRP_MN_COMPLETE
  • IRP_MN_COMPLETE_MDL
  • IRP_MN_COMPLETE_MDL_DPC
  • IRP_MN_COMPRESSED
  • IRP_MN_DPC
  • IRP_MN_MDL
  • IRP_MN_MDL_DPC
  • IRP_MN_NORMAL

Para obtener más información sobre cómo controlar este IRP, estudie el ejemplo FASTFAT que se incluye en el Kit de controladores de Windows (WDK).

Operación: controladores de filtro del sistema de archivos heredados

El controlador de filtro debe realizar cualquier procesamiento necesario y, en función de la naturaleza del filtro, realice una de las siguientes acciones:

  • Complete o produzca un error en el IRP, o bien
  • Pase el IRP al controlador siguiente inferior de la pila.

Parámetros

Un controlador de filtro o sistema de archivos llama a IoGetCurrentIrpStackLocation para que el IRP especificado obtenga un puntero a su propia ubicación de pila en el IRP. En los parámetros siguientes, Irp apunta a IRP e IrpSp apunta al IO_STACK_LOCATION. El controlador puede usar la información que se establece en los siguientes miembros del IRP y la ubicación de la pila irP para procesar una solicitud de creación:

  • DeviceObject es un puntero al objeto de dispositivo de destino.

  • Irp->AssociatedIrp.SystemBuffer apunta a un búfer proporcionado por el sistema que se usará como búfer intermedio del sistema, si la marca DO_BUFFERED_IO está establecida en DeviceObject-Flags>. De lo contrario, este miembro se establece en NULL.

  • Irp->IoStatus apunta a una estructura de IO_STATUS_BLOCK que recibe el estado de finalización final e información sobre la operación solicitada. Si se produce un error en la solicitud de IRP_MJ_WRITE, la rutina de distribución de escritura del sistema de archivos devuelve un valor NTSTATUS de error y el valor de Irp-IoStatus.Information> no está definido y no se debe usar.

  • Irp->MdlAddress es la dirección de una lista de descriptores de memoria (MDL) que describe las páginas a las que se van a escribir los datos.

  • IrpSp->FileObject apunta al objeto de archivo asociado a DeviceObject. Si la marca de FO_SYNCHRONOUS_IO se establece en IrpSp-FileObject-Flags>>, el objeto de archivo se abrió para E/S sincrónica.

    El parámetro IrpSp-FileObject> contiene un puntero al campo RelatedFileObject, que también es una estructura FILE_OBJECT. El campo RelatedFileObject de la estructura FILE_OBJECT no es válido durante el procesamiento de IRP_MJ_WRITE y no se debe usar.

  • IrpSp->Marcas: si se establece la marca de SL_FORCE_DIRECT_WRITE, los controladores en modo kernel pueden escribir en áreas de volumen en las que normalmente no se pueden escribir debido al bloqueo de escritura directa. El bloqueo directo de escritura se implementó por motivos de seguridad en Windows Vista y en sistemas operativos posteriores. Esta marca se comprueba tanto en la capa del sistema de archivos como en la capa de pila de almacenamiento. Para obtener más información sobre el bloqueo de escritura directa, vea Bloqueo de operaciones de escritura directa en volúmenes y discos. La marca SL_FORCE_DIRECT_WRITE está disponible en Windows Vista y versiones posteriores de Windows.

  • IrpSp->MajorFunction se establece en IRP_MJ_WRITE.

  • IrpSp->MinorFunction especifica la operación que se solicita y contiene una de las siguientes opciones:

    • IRP_MN_COMPLETE
    • IRP_MN_COMPLETE_MDL
    • IRP_MN_COMPLETE_MDL_DPC
    • IRP_MN_COMPRESSED
    • IRP_MN_DPC
    • IRP_MN_MDL
    • IRP_MN_MDL_DPC
    • IRP_MN_NORMAL
  • IrpSp->Parameters.Write.ByteOffset es una variable LARGE_INTEGER que especifica el desplazamiento de bytes inicial dentro del archivo de los datos que se van a escribir.

    En determinadas circunstancias, este parámetro puede contener un valor especial. Por ejemplo, cuando es true, la siguiente condición indica que se debe usar el final actual del archivo en lugar de un valor de desplazamiento de archivo explícito: IrpSp-Parameters.Write.ByteOffset.LowPart> == FILE_WRITE_TO_END_OF_FILE e IrpSp-Parameters.Write.ByteOffset.HighPart> == -1

  • IrpSp->Parameters.Write.Key es el valor de clave asociado a un bloqueo de intervalo de bytes en el archivo de destino.

  • IrpSp->Parameters.Write.Length es la longitud en bytes de los datos que se van a escribir. Si la operación de escritura se realiza correctamente, el número de bytes escritos se devuelve en el miembro Information de la estructura de IO_STATUS_BLOCK a la que apunta Irp-IoStatus>.

Comentarios

Los sistemas de archivos redondean las operaciones de escritura y lectura al final del archivo hasta un múltiplo del tamaño del sector del dispositivo de almacenamiento de archivos subyacente. Cuando los filtros procesan operaciones de lectura previa o escritura previa, esos filtros que asignan y intercambian búferes deben redondear el tamaño de un búfer asignado a un múltiplo del tamaño de sector del dispositivo asociado. Si no lo hacen, la longitud de los datos transferidos desde el sistema de archivos subyacente superará la longitud asignada del búfer. Para obtener más información sobre el intercambio de búferes, vea swapBuffers Minifilter Sample( Ejemplo de minifiltro de swapBuffers).

Consulte también

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE (referencia del kernel de WDK)

ZwWriteFile