Compatibilidad con operaciones bypassIO

A partir de Windows 11, todos los minifiltros deben agregar compatibilidad con las operaciones BypassIO. Las operaciones bypassIO se solicitan llamando a FltFsControlFile o ZwFsControlFile con:

  • Código de control FSCTL_MANAGE_BYPASS_IO .
  • Información específica de la solicitud en una estructura de FS_BPIO_INPUT a la que apunta el parámetro InputBuffer .
  • Estructura de FS_BPIO_OUTPUT asignada por el autor de la llamada a la que apunta el parámetro OutputBuffer , en el que el sistema devuelve los resultados de la operación.

En esta página se proporcionan detalles para cada operación BypassIO. La solicitud de operación se especifica como un valor FS_BPIO_OPERATIONS en el miembro Operation de FS_BPIO_INPUT.

Para obtener más información sobre BypassIO, consulte BypassIO para filtros.

solicitud de FS_BPIO_OP_ENABLE

Esta solicitud puede proceder del modo de usuario o kernel. Actualmente no se admite bypassIO en escrituras no almacenadas en caché.

FS_BPIO_OP_ENABLE solicita que el sistema habilite BypassIO para el archivo especificado, lo que significa que es posible que un controlador no vea todas las lecturas no almacenadas en caché para ese archivo.

BypassIO es un concepto por archivo abierto; es decir, una solicitud de FS_BPIO_OP_ENABLE solo afecta al objeto de archivo asociado a la solicitud enable y no cambia el comportamiento de otras aperturas en el mismo archivo o secuencia. Si se envían varias solicitudes de habilitación al mismo objeto de archivo, solo la primera solicitud es significativa y se omiten todas las solicitudes posteriores.

En la devolución de llamada de preoperación del controlador:

  • Si un controlador puede admitir BypassIO para el archivo especificado, debe reenviar la solicitud hacia abajo en la pila.

  • Si el controlador no puede admitir BypassIO para el archivo especificado, debe llamar a FltVetoBypassIo con la siguiente información:

    • El nombre del controlador, que se encuentra en la estructura FLT_RELATED_OBJECTS a la que apunta el parámetro FltObjects .
    • Código de error NTSTATUS que describe por qué está vetando la solicitud de habilitación en el parámetro OperationStatus .
    • Una cadena única y descriptiva con detalles sobre por qué ha vetado la solicitud de habilitación en el parámetro FailureReason .

    FltVetoBypassIo escribe el nombre del controlador, el código de error y la cadena que describe por qué el minifiltro bloqueó la solicitud de habilitación en la estructura de FS_BPIO_OUTPUT y escribe un evento ETW con el estado, el motivo proporcionado por el filtro y el nombre del filtro en el registro de eventos.

El minifiltro debe completarse FSCTL_MANAGE_BYPASS_IO con STATUS_SUCCESS si FltVetoBypassIo se realiza correctamente; de lo contrario, debería devolver el error que FltVetoBypassIo devolvió.

Durante la operación posterior, el controlador puede ver si todos los controladores debajo son capaces de admitir BypassIO. Si es así, el controlador debe conservar cualquier estado necesario para el archivo y continuar con el procesamiento de finalización. Es responsabilidad del sistema de archivos y del filtro mantener el estado para controlar correctamente las solicitudes que podrían no ser compatibles con el estado BypassIO habilitado.

Nota

Todos los filtros de la pila del sistema de archivos tienen la oportunidad de vetar la solicitud de habilitación bypassIO durante la operación previa, pero se recomienda mantenerla habilitada tanto como sea posible.

El sistema de archivos elimina automáticamente una solicitud de habilitación bypassIO para los siguientes tipos de archivos:

  • Directorios (los flujos de datos alternativos de un directorio pueden usar BypassIO)
  • Volúmenes (se abre DASD)
  • Archivos comprimidos ntfs
  • Archivos con codificación NTFS
  • Archivos dispersos
  • Archivos de paginación
  • Todos los archivos de volúmenes DAX

La mayoría de los filtros no necesitan mantener el estado de que BypassIO se ha habilitado en una secuencia específica. En su lugar, esta información se puede consultar llamando a FsRtlGetBypassIoOpenCount.

FS_BPIO_OP_ENABLE ejemplo: filtro de cifrado

Cuando un filtro de cifrado recibe una operación de FS_BPIO_OP_ENABLE en un archivo:

  • Si el archivo ya está cifrado, el filtro debe llamar a FltVetoBypassIo para vetar la operación BypassIO, proporcionando el estado adecuado y un mensaje de diagnóstico, como:

    • OpStatus = STATUS_NOT_SUPPORTED_WITH_ENCRYPTION
    • FailureReason = "No se admite el archivo cifrado"
  • Si el archivo no está cifrado actualmente, el filtro debe permitir BypassIO. Si se realiza una solicitud posterior para cifrar este archivo, el filtro puede usar la operación de FS_BPIO_OP_STREAM_PAUSE para deshabilitar BypassIO.

solicitud de FS_BPIO_OP_DISABLE

Esta solicitud puede proceder del modo de usuario o kernel. Permite que un controlador limpie cualquier estado bypassIO asociado.

Si un controlador permitía habilitar BypassIO previamente en este archivo y ahora debe desactivar la compatibilidad con BypassIO para un archivo, debe enviar la operación de FS_BPIO_OP_DISABLEFSCTL_MANAGE_BYPASS_IO a la parte superior de la pila del sistema de archivos mediante el identificador asociado. Un ejemplo de cuándo se puede producir esta condición es un controlador de cifrado que recibió una solicitud para cifrar este archivo.

Si un controlador recibe FS_BPIO_OP_DISABLE pero actualmente no tiene BypassIO habilitado, debe omitir la solicitud. Si esta operación se envía en un archivo que actualmente no tiene BypassIO habilitado, se debe omitir.

No se debe dar error a esta operación.

solicitud de FS_BPIO_OP_QUERY

Esta solicitud puede proceder del modo de usuario o kernel.

Un filtro debe procesar una solicitud de FS_BPIO_OP_QUERY similar a una operación de FS_BPIO_OP_ENABLE , llamando a FltVetoBypassIo para vetar según corresponda con la misma información de diagnóstico que se ha descrito anteriormente en los parámetros adecuados. La principal diferencia es que el controlador no entra en el estado BypassIO ENABLE durante una consulta.

La operación de FS_BPIO_OP_QUERY se puede enviar en identificadores de directorio y volumen (no se puede enviar una solicitud de FS_BPIO_OP_ENABLE en identificadores de directorio o volumen).

Ejemplo de consulta: filtro de cifrado

Cuando un filtro de cifrado recibe una operación de FS_BPIO_OP_QUERY en un archivo:

  • Si el archivo ya está cifrado, el filtro debe llamar a FltVetoBypassIo para vetar la operación BypassIO, proporcionando un estado adecuado y un mensaje de diagnóstico, como:

    • OpStatus = STATUS_NOT_SUPPORTED_WITH_ENCRYPTION
    • FailureReason = "No se admite el archivo cifrado"
  • Si el archivo no está cifrado actualmente, el filtro debe realizarse correctamente en la solicitud de consulta.

solicitud de FS_BPIO_OP_VOLUME_STACK_PAUSE

Esta solicitud puede proceder del modo de usuario o kernel.

Si un controlador de pila de volúmenes permitía previamente habilitar BypassIO en un volumen y ahora debe detener BypassIO (por ejemplo, debido a alguna solicitud externa), el controlador debe enviar una operación de FS_BPIO_OP_VOLUME_STACK_PAUSEFSCTL_MANAGE_BYPASS_IO a la parte superior de la pila de volúmenes para notificar al sistema de archivos que deje de realizar BypassIO en las pilas de almacenamiento y volumen de este volumen. El sistema de archivos purga todas las operaciones BypassIO activas de este volumen y, a continuación, devuelve. Después, el controlador de pila de volúmenes puede procesar la solicitud externa.

Todos los archivos activos habilitados para BypassIO dejan de realizar operaciones bypassIO de nivel de pila de almacenamiento. Esta solicitud de operación:

  • Se puede enviar en un identificador de volumen o en cualquier identificador de archivo para el volumen especificado.
  • Se puede enviar varias veces al mismo volumen.
  • Se puede enviar si no hay archivos habilitados para BypassIO en el volumen.

BypassIO sigue funcionando en la pila del sistema de archivos.

No se debe dar error a esta operación.

Ejemplo de pausa de pila de volúmenes

BitLocker es un ejemplo de un componente que usa esta operación cuando necesita habilitar el cifrado en un volumen.

Otro ejemplo es el siguiente escenario: supongamos que Volsnap permitió que BypassIO se habilitara en un volumen que no tenía instantáneas de volumen activas. Más adelante, se realizó una solicitud para crear una instantánea de volumen. Volsnap realiza las siguientes acciones antes de continuar:

  • Envía la operación FS_BPIO_OP_VOLUME_STACK_PAUSE a la parte superior de la pila que solicita que el sistema deshabilite BypassIO en la pila de volúmenes. Lo hace cada vez que se crea una nueva instantánea. Tras la devolución correcta, BypassIO ahora está deshabilitado y purgado en el volumen especificado.
  • Procesa la solicitud de creación de instantáneas

Después, Volsnap debe vetar todas las solicitudes de BPIO_OP_ENABLE y BPIO_OP_QUERY futuras en este volumen.

solicitud de FS_BPIO_OP_VOLUME_STACK_RESUME

Un controlador de pila de volúmenes envía esta operación FSCTL al sistema de archivos para reanudar el procesamiento bypassIO en el volumen especificado. Envía esta operación cuando el escenario que provocó que el controlador enviara FS_BPIO_OP_VOLUME_STACK_PAUSE ya no está activo. Esta operación se puede enviar incluso si BypassIO no está habilitada o en pausa actualmente.

Esta solicitud puede proceder del modo de usuario o kernel.

No se debe dar error a esta operación.

Ejemplo de reanudación de la pila de volúmenes

Con el escenario de pausa de la pila de volúmenes descrito anteriormente, suponga que el volumen ya no tiene instantáneas activas. Volsnap enviará FS_BPIO_OP_VOLUME_STACK_RESUME solo después de que la última instantánea desaparezca.

solicitud de FS_BPIO_OP_STREAM_PAUSE

Un filtro puede enviar una operación de FS_BPIO_OP_STREAM_PAUSE para pausar BypassIO en una secuencia. Esta solicitud puede proceder del modo de usuario o kernel. Todos los archivos activos habilitados para BypassIO dejan de realizar operaciones bypassIO.

En concreto, si un filtro previamente permitía que BypassIO estuviera habilitado en una secuencia y más adelante necesita detener BypassIO (debido a una solicitud externa, como una solicitud para cifrar un archivo o directorio), puede enviar un FS_BPIO_OP_STREAM_PAUSEla pila de filtros para indicar al sistema de archivos que deje de realizar BypassIO en la secuencia especificada. Un filtro no debe enviar esta operación a la parte superior de la pila.

Antes de que el sistema de archivos vuelva, detiene todos los identificadores bypassIO abiertos en la secuencia y completa todas las operaciones de BypassIO activas en la secuencia. Estas acciones garantizan que, al devolver, el filtro puede realizar la operación de archivo que necesita hacer.

Esta operación se puede enviar varias veces a la misma secuencia. El sistema de archivos lo omite si se envía en una secuencia que actualmente no está habilitada para BypassIO.

Si un filtro realiza una operación de pausa de flujo, BypassIO continúa en el volumen y las pilas de almacenamiento.

No se debe realizar esta operación.

Ejemplo de pausa de secuencia: filtro de cifrado

Supongamos que un filtro de cifrado permitió que BypassIO estuviera habilitado en una secuencia que no se cifró, pero más adelante recibió una solicitud para cifrar esta secuencia.

Antes de que continúe el filtro de cifrado, debe llamar a FsRtlGetBypassIoOpenCount para determinar si BypassIO está activo en esta secuencia. Si es así, el filtro de cifrado envía una operación de FS_BPIO_OP_STREAM_PAUSE que solicita que el sistema deshabilite BypassIO. Tras la devolución correcta, BypassIO está deshabilitado y purgado, por lo que el filtro puede realizar la solicitud de cifrado de forma segura. Para eliminar posibles condiciones de carrera, el filtro debe vetar todas las solicitudes de FS_BPIO_OP_ENABLE y FS_BPIO_OP_QUERY futuras en esta secuencia ahora cifrada.

solicitud de FS_BPIO_OP_STREAM_RESUME

Cuando el escenario que provocó que el filtro enviara una operación de FS_BPIO_OP_STREAM_PAUSE ya no existe, el filtro envía una operación de FS_BPIO_OP_STREAM_RESUME al sistema de archivos para reanudar el procesamiento bypassIO de una secuencia determinada. Esta solicitud puede proceder del modo de usuario o kernel.

Si esta operación se envía cuando BypassIO no está habilitado o en pausa actualmente, se omite.

Pausar y reanudar no se cuentan las referencias. En su lugar, en un currículum, el sistema de archivos emite una solicitud de FS_BPIO_OP_QUERY a la parte superior de la pila del sistema de archivos para determinar si los filtros restantes siguen bloqueando. El sistema de archivos reanuda BypassIO solo si todos los filtros de la pila no bloquean BypassIO.

No se debe realizar esta operación.

Ejemplo de stream resume: filtro de cifrado

Con el escenario de FS_BPIO_OP_STREAM_PAUSE descrito anteriormente, supongamos que el archivo que se cifró anteriormente después de llamar a FS_BPIO_OP_STREAM_PAUSE ya no está cifrado. A continuación, el filtro debe enviar la operación de FS_BPIO_OP_STREAM_RESUME para permitir que BypassIO se reanude en esa secuencia.

solicitud de FS_BPIO_OP_GET_INFO

Esta solicitud puede proceder del modo de usuario o kernel. El sistema de archivos devuelve información sobre BypassIO para el volumen en una estructura de FS_BPIO_INFO .