Directrices para migrar controladores de filtro heredados
Se recomienda a los desarrolladores migrar controladores de filtro heredados al modelo del administrador de filtros para obtener una mejor funcionalidad para sus controladores de filtro y mejorar la confiabilidad del sistema. Los desarrolladores experimentados deben encontrar que es relativamente fácil migrar un controlador de filtro heredado a un controlador de minifiltro. Los desarrolladores de controladores de filtro de Microsoft recomiendan el siguiente enfoque:
Comience con un conjunto de pruebas de regresión confiable para comprobar el comportamiento entre el controlador de filtro heredado y el controlador de minifiltro portado.
Cree un shell de controlador de minifiltro y mueva sistemáticamente la funcionalidad del controlador de filtro heredado al controlador de minifiltro. Por ejemplo, obtener datos adjuntos funcionando y, a continuación, portar una operación cada vez, probar después de cada operación.
Cambie la comunicación en modo de usuario o modo kernel por último, por lo que puede usar herramientas existentes para probar el controlador de minifiltro.
Compile con PREfast y pruebe con la opción Comprobación de E/S del comprobador de filtros en Comprobador de controladores habilitado.
Durante el proceso de portabilidad, debe revisar todo el código del controlador de filtro heredado para aprovechar al máximo las funcionalidades del administrador de filtros. En concreto, tenga en cuenta lo siguiente:
Las operaciones de E/S basadas en IRP y E/S rápidas pueden pasar por la misma operación cuando corresponda, lo que ayuda a reducir la duplicación del código.
Al registrarse para las operaciones, un controlador de minifiltro puede optar explícitamente por omitir todas las E/S de paginación y E/S almacenadas en caché, lo que elimina la necesidad de código para comprobarlos.
Las notificaciones de instancia simplifican considerablemente la lógica de asociación o desasociación.
Registre solo para las operaciones que el controlador de minifiltro debe controlar; puede omitir todo lo demás.
Aproveche el contexto del administrador de filtros y la compatibilidad con la administración de nombres.
Aproveche la compatibilidad del administrador de filtros para emitir E/S no recursiva.
A diferencia de los controladores de filtro heredados, los controladores de minifiltro no pueden depender de variables locales para mantener el contexto del procesamiento de preoperación al procesamiento posterior a la operación. Considere la posibilidad de asignar una lista de aspecto para almacenar el estado de la operación.
Asegúrese de liberar referencias cuando termine con un nombre o contexto.
Los puertos de finalización en modo de usuario agregan una técnica eficaz para crear colas. Probablemente solo necesitará una única conexión a un único puerto con nombre.
En la tabla siguiente se enumeran las operaciones comunes en un controlador de filtro heredado y cómo se asignan al modelo del administrador de filtros.
Modelo de controlador de filtro heredado | Modelo del administrador de filtros |
---|---|
Operación de paso a través sin rutina de finalización |
Si el controlador de minifiltro nunca funciona para este tipo de operación de E/S, no registre una rutina de devolución de llamada de preoperación o postoperación para esta operación. De lo contrario, devuelva FLT_PREOP_SUCCESS_NO_CALLBACK de la rutina de devolución de llamada de preoperación registrada para esta operación. Consulte Devolver FLT_PREOP_SUCCESS_NO_CALLBACK. |
Operación de paso a través con una rutina de finalización |
Devuelve FLT_PREOP_SUCCESS_WITH_CALLBACK de la rutina de devolución de llamada de preoperación. Consulte Devolver FLT_PREOP_SUCCESS_WITH_CALLBACK. |
Operación manuscrita en la rutina de devolución de llamada de preoperación |
Llame a FltLockUserBuffer según sea necesario para asegurarse de que los búferes de usuario estén bloqueados correctamente para que se pueda acceder a ellos en un subproceso de trabajo. Poner en cola el trabajo en un subproceso de trabajo llamando a rutinas de soporte técnico como FltAllocateDeferredIoWorkItem y FltQueueDeferredIoWorkItem. Devuelve FLT_PREOP_PENDING de la rutina de devolución de llamada de preoperación. Cuando esté listo para devolver la operación de E/S al administrador de filtros, llame a FltCompletePendedPreOperation. Consulte Pendiente de una operación de E/S en una rutina de devolución de llamada de preoperación. |
Operación manuscrita en la rutina de devolución de llamada de postoperación |
En la rutina de devolución de llamada de preoperación, llame a FltLockUserBuffer para asegurarse de que los búferes de usuario están bloqueados correctamente para que se pueda acceder a ellos en un subproceso de trabajo. Poner en cola el trabajo en un subproceso de trabajo llamando a rutinas de soporte técnico como FltAllocateGenericWorkItem y FltQueueGenericWorkItem. Devuelve FLT_POSTOP_MORE_PROCESSING_REQUIRED de la rutina de devolución de llamada de postoperación. Cuando esté listo para devolver la operación de E/S al administrador de filtros, llame a FltCompletePendedPostOperation. Consulte Pendiente de una operación de E/S en una rutina de devolución de llamada de postoperación. |
Sincronizar la operación |
Devuelve FLT_PREOP_SYNCHRONIZE de la rutina de devolución de llamada de preoperación. Consulte Devolver FLT_PREOP_SYNCHRONIZE. |
Completar la operación en la rutina de devolución de llamada de preoperación |
Establezca el estado y la información finales de la operación en el miembro IoStatus de la estructura de FLT_CALLBACK_DATA para la operación. Devuelve FLT_PREOP_COMPLETE de la rutina de devolución de llamada de preoperación. Consulte Completar una operación de E/S en una rutina de devolución de llamada de preoperación. |
Complete la operación una vez que se haya escrito en la rutina de devolución de llamada de preoperación. |
Establezca el estado y la información finales de la operación en el miembro IoStatus de la estructura de FLT_CALLBACK_DATA para la operación. Llame a FltCompletePendedPreOperation desde el subproceso de trabajo que procesa la operación de E/S y pase FLT_PREOP_COMPLETE como parámetro CallbackStatus . Consulte Completar una operación de E/S en una rutina de devolución de llamada de preoperación. |
Realizar todo el trabajo de finalización en la rutina de finalización |
Devuelve FLT_POSTOP_FINISHED_PROCESSING de la rutina de devolución de llamada de postoperación. Consulte Escribir rutinas de devolución de llamada de postoperación. |
Realizar el trabajo de finalización en IRQL seguro |
Llame a FltDoCompletionProcessingWhenSafe desde la rutina de devolución de llamada de postoperación. Consulte Asegurarse de que el procesamiento de finalización se realiza en IRQL seguro. |
Señal de un evento a partir de la rutina de finalización |
Devuelve FLT_PREOP_SYNCHRONIZE de la rutina de devolución de llamada de preoperación para esta operación. El administrador de filtros llama a la rutina de devolución de llamada de postoperación en el mismo contexto de subproceso que la rutina de devolución de llamada de preoperación, en IRQL <= APC_LEVEL. Consulte Devolver FLT_PREOP_SYNCHRONIZE. |
Error en una operación de creación correcta |
Llame a FltCancelFileOpen desde la rutina de devolución de llamada de postoperación para la operación de creación. Establezca un valor NTSTATUS de error adecuado en el miembro IoStatus de la estructura FLT_CALLBACK_DATA para la operación. Devuelve FLT_POSTOP_FINISHED_PROCESSING. Consulte Error de una operación de E/S en una rutina de devolución de llamada de postoperación. |
No permitir E/S a través de la ruta de acceso de E/S rápida para una operación de E/S |
Devuelve FLT_STATUS_DISALLOW_FAST_IO de la rutina de devolución de llamada de preoperación para la operación. Consulte No permitir una operación de E/S rápida en una rutina de devolución de llamada de preoperación. |
Modificación de los parámetros de una operación de E/S |
Establezca los valores de parámetro modificados en el miembro Iopb de la estructura FLT_CALLBACK_DATA para la operación. Marque la estructura de FLT_CALLBACK_DATA como desfasada llamando a FltSetCallbackDataDirty, excepto cuando haya modificado el contenido del miembro IoStatus de la estructura FLT_CALLBACK_DATA. Consulte Modificación de los parámetros de una operación de E/S. |
Bloqueo del búfer de usuario para la operación |
Use las técnicas y directrices descritas en Acceso a los búferes de usuario para una operación de E/S. |