다음을 통해 공유


레거시 필터 드라이버 포팅에 대한 지침

개발자는 필터 드라이버에 대한 더 나은 기능을 얻고 시스템 안정성을 개선하기 위해 레거시 필터 드라이버를 필터 관리자 모델로 이식하는 것이 좋습니다. 숙련된 개발자는 레거시 필터 드라이버를 미니필터 드라이버로 이식하는 것이 비교적 쉽습니다. Microsoft의 필터 드라이버 개발자는 다음 방법을 권장합니다.

  • 신뢰할 수 있는 회귀 테스트 도구 모음으로 시작하여 레거시 필터 드라이버와 포티드 미니필터 드라이버 간의 동작을 확인합니다.

  • 미니필터 드라이버 셸을 만들고 레거시 필터 드라이버에서 미니필터 드라이버로 기능을 체계적으로 이동합니다. 예를 들어 첨부 파일이 작동한 다음 한 번에 하나의 작업을 포팅하고 각 작업 후에 테스트합니다.

  • 사용자 모드/커널 모드 통신을 마지막으로 변경하여 기존 도구를 사용하여 미니필터 드라이버를 테스트할 수 있습니다.

  • PREfast를 사용하여 컴파일하고 드라이버 검증 도구에서 필터 검증 도구 I/O 확인 옵션을 사용하도록 설정하여 테스트합니다.

포팅 프로세스 중에는 모든 레거시 필터 드라이버 코드를 검토하여 필터 관리자 기능을 최대한 활용해야 합니다. 특히 다음 사항에 유의하세요.

  • IRP 기반 I/O 및 빠른 I/O 작업은 적절한 경우 동일한 작업을 통해 올 수 있으므로 코드 중복을 줄이는 데 도움이 됩니다.

  • 작업을 등록할 때 미니필터 드라이버는 모든 페이징 I/O 및 캐시된 I/O를 무시하도록 명시적으로 선택할 수 있습니다. 이를 검사 코드가 필요하지 않습니다.

  • 인스턴스 알림은 연결/분리 논리를 크게 간소화합니다.

  • 미니필터 드라이버가 처리해야 하는 작업에 대해서만 등록합니다. 다른 모든 항목을 무시할 수 있습니다.

  • 필터 관리자 컨텍스트 및 이름 관리 지원을 활용합니다.

  • 재귀적이지 않은 I/O를 발급하기 위한 필터 관리자 지원을 활용합니다.

  • 레거시 필터 드라이버와 달리 미니필터 드라이버는 사전 운용 처리에서 사후 처리에 이르기까지 컨텍스트를 유지하기 위해 지역 변수를 사용할 수 없습니다. lookaside 목록을 할당하여 작업 상태를 저장하는 것이 좋습니다.

  • 이름 또는 컨텍스트로 완료되면 참조를 해제해야 합니다.

  • 사용자 모드의 완료 포트는 큐를 빌드하는 강력한 기술을 추가합니다. 명명된 단일 포트에 대한 단일 연결만 필요할 수 있습니다.

다음 표에서는 레거시 필터 드라이버의 일반적인 작업과 필터 관리자 모델에 매핑하는 방법을 나열합니다.

레거시 필터 드라이버 모델 필터 관리자 모델

완료 루틴이 없는 통과 작업

미니필터 드라이버가 이러한 유형의 I/O 작업에 대해 작동하지 않는 경우 이 작업에 대한 사전 작업 또는 사후 콜백 루틴을 등록하지 마세요.

그렇지 않으면 이 작업에 대해 등록된 사전 운용 콜백 루틴에서 FLT_PREOP_SUCCESS_NO_CALLBACK 반환합니다.

FLT_PREOP_SUCCESS_NO_CALLBACK 반환을 참조하세요.

완료 루틴을 사용하는 통과 작업

사전 운용 콜백 루틴에서 FLT_PREOP_SUCCESS_WITH_CALLBACK 반환합니다.

FLT_PREOP_SUCCESS_WITH_CALLBACK 반환을 참조하세요.

사전 운용 콜백 루틴에서 보류 중인 작업

필요에 따라 FltLockUserBuffer 를 호출하여 모든 사용자 버퍼가 작업자 스레드에서 액세스할 수 있도록 올바르게 잠겨 있는지 확인합니다.

FltAllocateDeferredIoWorkItemFltQueueDeferredIoWorkItem과 같은 지원 루틴을 호출하여 작업자 스레드에 작업을 큐에 추가합니다.

사전 운용 콜백 루틴에서 FLT_PREOP_PENDING 반환합니다.

I/O 작업을 필터 관리자로 반환할 준비가 되면 FltCompletePendedPreOperation을 호출합니다.

사전 운용 콜백 루틴에서 I/O 작업 보류를 참조하세요.

사후 콜백 루틴에서 보류 중인 작업

사전 운용 콜백 루틴에서 FltLockUserBuffer 를 호출하여 사용자 버퍼가 작업자 스레드에서 액세스할 수 있도록 올바르게 잠겨 있는지 확인합니다.

FltAllocateGenericWorkItemFltQueueGenericWorkItem과 같은 지원 루틴을 호출하여 작업자 스레드에 작업을 큐에 추가합니다.

사후 콜백 루틴에서 FLT_POSTOP_MORE_PROCESSING_REQUIRED 반환합니다.

I/O 작업을 필터 관리자로 반환할 준비가 되면 FltCompletePendedPostOperation을 호출합니다.

사후 콜백 루틴에서 I/O 작업 보류 중을 참조하세요.

작업 동기화

사전 운용 콜백 루틴에서 FLT_PREOP_SYNCHRONIZE 반환합니다.

FLT_PREOP_SYNCHRONIZE 반환을 참조하세요.

사전 운용 콜백 루틴에서 작업 완료

작업에 대한 FLT_CALLBACK_DATA 구조체의 IoStatus 멤버에서 최종 작업 상태 및 정보를 설정합니다.

사전 운용 콜백 루틴에서 FLT_PREOP_COMPLETE 반환합니다.

사전 운용 콜백 루틴에서 I/O 작업 완료를 참조하세요.

사전 운용 콜백 루틴에서 보류된 후 작업을 완료합니다.

작업에 대한 FLT_CALLBACK_DATA 구조체의 IoStatus 멤버에서 최종 작업 상태 및 정보를 설정합니다.

I/O 작업을 처리하는 작업자 스레드에서 FltCompletePendedPreOperation 을 호출하고 FLT_PREOP_COMPLETE CallbackStatus 매개 변수로 전달합니다.

사전 운용 콜백 루틴에서 I/O 작업 완료를 참조하세요.

완료 루틴에서 모든 완료 작업 수행

사후 콜백 루틴에서 FLT_POSTOP_FINISHED_PROCESSING 반환합니다.

사후 콜백 루틴 작성을 참조하세요.

안전한 IRQL에서 완료 작업 수행

사후 콜백 루틴에서 FltDoCompletionProcessingWhenSafe 를 호출합니다.

안전한 IRQL에서 완료 처리가 수행되는지 확인 을 참조하세요.

완료 루틴에서 이벤트 신호

이 작업에 대한 사전 운용 콜백 루틴에서 FLT_PREOP_SYNCHRONIZE 반환합니다.

필터 관리자는 IRQL <= APC_LEVEL 사전 운용 콜백 루틴과 동일한 스레드 컨텍스트에서 사후 콜백 루틴을 호출합니다.

FLT_PREOP_SYNCHRONIZE 반환을 참조하세요.

성공적인 만들기 작업 실패

만들기 작업에 대한 사후 콜백 루틴에서 FltCancelFileOpen 을 호출합니다.

작업에 대한 FLT_CALLBACK_DATA 구조체의 IoStatus 멤버에서 적절한 오류 NTSTATUS 값을 설정합니다.

FLT_POSTOP_FINISHED_PROCESSING 반환합니다.

사후 콜백 루틴에서 I/O 작업 실패를 참조하세요.

I/O 작업에 대한 빠른 I/O 경로를 통해 I/O 허용 안 하세요.

작업에 대한 사전 운용 콜백 루틴에서 FLT_STATUS_DISALLOW_FAST_IO 반환합니다.

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

I/O 작업에 대한 매개 변수 수정

작업에 대한 FLT_CALLBACK_DATA 구조체의 Iopb 멤버에서 수정된 매개 변수 값을 설정합니다.

FLT_CALLBACK_DATA 구조체의 IoStatus 멤버의 내용을 수정한 경우를 제외하고 FltSetCallbackDataDirty를 호출하여 FLT_CALLBACK_DATA 구조를 더티 표시합니다.

I/O 작업에 대한 매개 변수 수정을 참조하세요.

작업에 대한 사용자 버퍼 잠금

I/O 작업에 대한 사용자 버퍼 액세스에 설명된 기술 및 지침을 사용합니다.