사전 작업 콜백 루틴 작성

미니필터 드라이버는 하나 이상의 사전 작업 콜백 루틴을 사용하여 I/O 작업을 필터링합니다. 사전 작업 콜백 루틴은레거시 필터 모델에 사용되는 디스패치 루틴과 유사합니다.

미니필터는 콜백 루틴의 진입점을 FLT_REGISTRATION 구조체OperationRegistration 멤버에 저장하여 특정 유형의 I/O 작업에 대한 사전 작업 콜백 루틴을 등록합니다. 미니필터는 DriverEntry 루틴에서 FltRegisterFilter에 매개 변수로 이 멤버를 FltMgr에 전달합니다.

미니필터는 사전 작업 또는 사후 작업 콜백 루틴을 등록한 이러한 유형의 I/O 작업만 받습니다. 미니필터는 작업 후 콜백 루틴을 등록하지 않고 지정된 유형의 I/O 작업에 대한 사전 작업 콜백 루틴을 등록할 수 있으며 그 반대의 경우도 마찬가지입니다.

모든 사전 작업 콜백 루틴은 다음과 같이 정의됩니다.

typedef FLT_PREOP_CALLBACK_STATUS 
(*PFLT_PRE_OPERATION_CALLBACK) ( 
    IN OUT PFLT_CALLBACK_DATA Data, 
    IN PCFLT_RELATED_OBJECTS FltObjects, 
    OUT PVOID *CompletionContext 
    ); 

FltMgr이 지정된 I/O 작업에 대해 미니필터의 사전 작업 콜백 루틴을 호출하면 미니필터가 일시적으로 I/O 작업을 제어합니다. 미니필터는 다음 중 하나가 될 때까지 이 컨트롤을 유지합니다.

  • 작업 전 콜백 루틴에서 FLT_PREOP_PENDING 이외의 상태 값을 반환합니다.

  • 이전에 작업 전 콜백 루틴에서 보류된 작업을 처리한 작업 루틴에서 FltCompletePendedPreOperation 을 호출합니다.

다음 표에서는 미니필터의 사전 작업 콜백 루틴에 대해 가능한 몇 가지 사용 시나리오를 나열하고 각 시나리오에 대한 구현 세부 정보 및 반환 값을 제공합니다.

사용 시나리오 구현 반환된 값
루틴은 작업과 관련이 없으며 작업의 최종 상태 필요하지 않거나 작업 후 콜백이 없습니다. I/O 작업을 통과하고 완료 시 미니필터의 작업 후 콜백을 호출하지 않도록 FltMgr 에 지시합니다. FLT_PREOP_SUCCESS_NO_CALLBACK
루틴에는 작업의 최종 상태 필요합니다. 작업을 통과하고 FltMgr 에게 미니필터의 작업 후 콜백 루틴을 호출하도록 지시합니다. FLT_PREOP_SUCCESS_WITH_CALLBACK
미니필터는 나중에 이 작업을 완료하거나 계속 처리해야 합니다. 작업을 보류 중인 상태로 전환합니다. FltCompletePendedPreOperation을 사용하여 나중에 작업을 완료합니다. FLT_PREOP_PENDING 반환하는 사전 작업 루틴과 FltCompletePendingOperation 이 호출되는 경합이 있을 수 있습니다. FltMgr은 드라이버의 입력 없이 이 시나리오를 처리합니다. FLT_PREOP_PENDING
사후 작업 처리는 디스패치 루틴이 호출된 것과 동일한 스레드의 컨텍스트에서 발생해야 합니다. 이 조건은 일관된 IRQL을 보장하고 지역 변수 상태를 유지 관리합니다. 작업을 사후 작업과 동기화합니다. FLT_PREOP_SYNCHRONIZE
사전 작업 콜백 루틴은 작업을 완료해야 합니다. 작업에 대한 처리를 중지하고 최종 NTSTATUS 값을 할당합니다. FLT_PREOP_COMPLETE

IRQL 및 사전 작업 콜백 루틴

FltMgr은 미니필터가 사전 작업 콜백(또는 콜백)에서 수행할 수 있는 작업을 알 수 있는 방법이 없습니다. 따라서 FltMgr은 미니포트의 사전 작업 콜백에 대한 호출이 문제를 일으킬 수 있는지 여부를 알 방법이 없습니다. (상승된 IRQL에서 안전하게 수행할 수 있는 작업과 수행할 수 없는 사항이 있습니다.) 따라서 IRQL을 인식하고 적절하게 처리하는 것은 미니필터의 입니다. 미니필터는 호출된 IRQL을 알아야 하는 상황에 대해 KeGetCurrentIRQL 을 안전하고 저렴하게 호출할 수 있습니다.

미니필터의 사전 작업 콜백 루틴 IRQL에 대한 다음 정보는 아는 데 유용합니다.

  • 사전 작업 콜백은 IRQL = PASSIVE_LEVEL 또는 IRQL = APC_LEVEL 호출할 수 있습니다. 대부분의 사전 작업 콜백은 I/O 요청을 시작한 스레드의 컨텍스트에서 IRQL = PASSIVE_LEVEL 호출됩니다. IRQL = APC_LEVEL 소수의 사전 작업 콜백만 호출할 수 있습니다.

  • IRP 기반 작업의 경우 더 높은 필터 또는 미니필터 드라이버가 작업자 스레드의 처리를 위해 작업을 보류하는 경우 시스템 작업자 스레드의 컨텍스트에서 미니필터의 사전 작업 콜백을 호출할 수 있습니다. 사전 작업 콜백은 레거시 필터의 디스패치 루틴과 동일하므로 레거시 필터의 디스패치 루틴의 IRQL 및 스레드 컨텍스트를 아는 것이 유용할 수 있습니다.

  • IRQL > APC_LEVEL 작업 후 루틴에서는 컨텍스트 개체를 검색할 수 없습니다. 대신 사전 작업 루틴 중에 컨텍스트 개체를 가져와서 작업 후 루틴에 전달하거나 IRQL <= APC_LEVEL 사후 작업 처리를 수행합니다. 컨텍스트에 대한 자세한 내용은 컨텍스트 관리를 참조하세요.

미니필터 인스턴스 스택 아래로 I/O 작업 전달

사전 작업 콜백 루틴에서 I/O 작업 완료

사전 작업 콜백 루틴에서 빠른 I/O 작업 허용 안 하세요.

사전 작업 콜백 루틴에서 I/O 작업 보류 중