Compartir a través de


Restricciones en rutinas de finalización

Nota:

Para lograr una confiabilidad y un rendimiento óptimos, use controladores de minifiltro del sistema de archivos con compatibilidad con el Administrador de filtros de archivos en lugar de controladores de filtro del sistema de archivos heredados. Para migrar el controlador heredado a un controlador de minifiltro, consulte Directrices para migrar controladores de filtro heredados.

En las instrucciones siguientes se describe brevemente cómo evitar errores de programación comunes en las rutinas heredadas de finalización del controlador de filtro del sistema de archivos.

Dado que se puede llamar a las rutinas de finalización en irQL DISPATCH_LEVEL, están sujetas a las restricciones siguientes:

  • Las rutinas de finalización no pueden llamar de forma segura a rutinas en modo kernel que requieren un IRQL inferior, como IoDeleteDevice o ObQueryNameString.

  • Las estructuras de datos usadas en las rutinas de finalización deben asignarse desde un grupo no paginado.

  • Las rutinas de finalización no se pueden crear páginas.

  • Las rutinas de finalización no pueden adquirir recursos, exclusión mutua ni exclusión mutua rápida. Sin embargo, pueden adquirir bloqueos de giro.

Comprobación de la marca PendingReturned

  • A menos que la rutina de finalización señale un evento, debe comprobar la marca Irp-PendingReturned>. Si se establece esta marca, la rutina de finalización debe llamar a IoMarkIrpPending para marcar irP como pendiente.

  • Si una rutina de finalización señala un evento, no debe llamar a IoMarkIrpPending.

Restricciones al devolver el estado

  • Una rutina de finalización del controlador de filtro del sistema de archivos debe devolver STATUS_SUCCESS o STATUS_MORE_PROCESSING_REQUIRED. El Administrador de E/S restablece todos los demás valores NTSTATUS a STATUS_SUCCESS.

Restricciones al devolver STATUS_MORE_PROCESSING_REQUIRED

Hay tres casos en los que las rutinas de finalización deben devolver STATUS_MORE_PROCESSING_REQUIRED:

  • Cuando la rutina de distribución correspondiente está esperando a que la rutina de finalización señale un evento. En este caso, es importante devolver STATUS_MORE_PROCESSING_REQUIRED para evitar que el Administrador de E/S complete el IRP prematuramente después de que se devuelva la rutina de finalización.

  • Cuando la rutina de finalización ha publicado el IRP en una cola de trabajo y la rutina de envío correspondiente ha devuelto STATUS_PENDING. En este caso, también es importante devolver STATUS_MORE_PROCESSING_REQUIRED para evitar que el Administrador de E/S complete el IRP prematuramente después de que se devuelva la rutina de finalización.

  • Cuando el mismo controlador creó el IRP llamando a IoAllocateIrp o IoBuildAsynchronousFsdRequest. Dado que el controlador no recibió este IRP de un controlador de nivel superior, puede liberar el IRP de forma segura en la rutina de finalización. Una vez que la rutina de finalización llama a IoFreeIrp, debe devolver STATUS_MORE_PROCESSING_REQUIRED para indicar que no se necesita ningún procesamiento de finalización adicional.

Una rutina de finalización no puede devolver STATUS_MORE_PROCESSING_REQUIRED para una operación de interbloqueo. Las operaciones de interbloqueo no se pueden escribir (publicadas en una cola de trabajo) y las rutinas de envío no pueden devolver STATUS_PENDING para ellas.

Restricciones al publicar IRP en una cola de trabajo

  • Si una rutina de finalización publica IRP en una cola de trabajo, debe llamar a IoMarkIrpPending antes de publicar cada IRP en la cola de trabajo. De lo contrario, el IRP se podría poner en cola, completado por otra rutina de controlador y liberado por el sistema antes de que se produzca la llamada a IoMarkIrpPending , lo que provoca un bloqueo.