Usar ni almacenado en búfer ni E/S directa
Si un controlador no usa ninguna E/S almacenada en búfer ni directa, el administrador de E/S pasa las direcciones virtuales de espacio de usuario originales en IRP que envía al controlador. Para acceder a estos búferes de forma segura, el controlador debe ejecutarse en el contexto del subproceso que llama. Normalmente, por lo tanto, solo los controladores de nivel más alto, como los FSD, pueden usar este método para acceder a los búferes.
Un controlador intermedio o de nivel inferior no siempre puede cumplir esta condición. Por ejemplo, si un subproceso solicitante espera la finalización de una solicitud de E/S o si un controlador de nivel superior se superpone al controlador intermedio o de nivel inferior, es poco probable que se llame a las rutinas del controlador de nivel inferior en el contexto del subproceso solicitante.
El administrador de E/S determina que una operación de E/S no usa ni E/S almacenada en búfer ni E/S directa como se indica a continuación:
Para las solicitudes IRP_MJ_READ y IRP_MJ_WRITE , ni DO_BUFFERED_IO ni DO_DIRECT_IO se establecen en el miembro Flags de la estructura DEVICE_OBJECT . Para obtener más información, consulte Inicialización de un objeto de dispositivo.
Para las solicitudes IRP_MJ_DEVICE_CONTROL y IRP_MJ_INTERNAL_DEVICE_CONTROL , el valor del código IOCTL contiene METHOD_NEITHER como el valor TransferType en el valor IOCTL. Para obtener más información, vea Definir códigos de control de E/S.
Cuando un controlador recibe un IRP que especifica una operación de E/S sin búfer ni E/S directa, debe hacer lo siguiente:
Compruebe la validez del intervalo de direcciones del búfer de usuario y compruebe si se permite el acceso de lectura o escritura adecuado, mediante las rutinas de compatibilidad de ProbeForRead y ProbeForWrite . El controlador debe incluir sus accesos al intervalo de direcciones del búfer dentro de un controlador de excepciones proporcionado por el controlador, de modo que un subproceso de usuario no pueda cambiar los derechos de acceso del búfer mientras el controlador accede a la memoria. Si el sondeo genera una excepción, el controlador debe devolver un error. El controlador debe llamar a estas rutinas dentro del contexto del subproceso que realizó la solicitud de E/S; por lo tanto, solo un controlador de nivel superior puede realizar esta tarea.
Administre búferes y operaciones de memoria de una de las maneras siguientes:
- Realice sus propias operaciones de almacenamiento en búfer doble, como hace el administrador de E/S para los controladores que usan E/S almacenados en búfer. Para obtener más información, consulte Uso de E/S almacenada en búfer.
- Cree sus propias MDL y bloquee el búfer llamando a las rutinas de soporte técnico del administrador de memoria, ya que el administrador de E/S lo hace para los controladores que usan E/S directa. Para obtener más información, consulte Uso de E/S directa.
- Realice todas las operaciones necesarias en el búfer de usuario directamente en el contexto del subproceso que realiza la llamada. El controlador debe encapsular su acceso al búfer dentro de un controlador de excepciones proporcionado por el controlador, en caso de que un subproceso de usuario cambie los derechos de acceso para el búfer o los datos del búfer mientras el controlador accede a la memoria. Para obtener más información, consulte Control de excepciones.
En efecto, el controlador debe elegir por IRP si se debe realizar la E/S almacenada en búfer, la E/S directa o la E/S en el contexto del subproceso que realiza la llamada, y debe controlar las excepciones que puedan producirse en un contexto de subproceso en modo de usuario. El controlador debe administrar sus propios accesos de búfer de usuario, operaciones de doble búfer y asignaciones de memoria, según sea necesario, en lugar de permitir que el administrador de E/S controle estas operaciones para el controlador.