사전 작업 콜백 루틴에서 사용자 버퍼 액세스
미니필터 드라이버의 사전 운용 콜백 루틴 은 다음과 같이 IRP 기반 I/O 작업에서 버퍼를 처리해야 합니다.
버퍼에 대한 MDL이 있는지 확인합니다. MDL 포인터는 작업에 대한 FLT_PARAMETERSMdlAddress 또는 OutputMdlAddress 매개 변수에서 찾을 수 있습니다. 미니필터 드라이버는 FltDecodeParameters를 호출하여 MDL 포인터를 쿼리할 수 있습니다.
유효한 MDL을 가져오는 한 가지 방법은 콜백 데이터에서 FLT_IO_PARAMETER_BLOCK I/O 매개 변수 블록의 MinorFunction 멤버에서 IRP_MN_MDL 플래그를 찾는 것입니다. 다음 예제에서는 IRP_MN_MDL 플래그에 대해 검사 방법을 보여 있습니다.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; if (FlagOn(CallbackData->Iopb->MinorFunction, IRP_MN_MDL)) { ReadMdl = &CallbackData->Iopb->Parameters.Read.MdlAddress; }
그러나 IRP_MN_MDL 플래그는 읽기 및 쓰기 작업에 대해서만 설정할 수 있습니다. 루틴이 모든 작업에 대해 유효한 MDL을 확인하므로 FltDecodeParameters 를 사용하여 MDL을 검색하는 것이 가장 좋습니다. 다음 예제에서는 유효한 경우 MDL 매개 변수만 반환됩니다.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; status = FltDecodeParameters(CallbackData, &ReadMdl, NULL, NULL, NULL);
버퍼에 대한 MDL이 있는 경우 MmGetSystemAddressForMdlSafe 를 호출하여 버퍼에 대한 시스템 주소를 가져온 다음 이 주소를 사용하여 버퍼에 액세스합니다.
이전 예제에서 계속 다음 코드는 시스템 주소를 가져옵니다.
if (*ReadMdl != NULL) { ReadAddress = MmGetSystemAddressForMdlSafe(*ReadMdl, NormalPagePriority); if (ReadAddress == NULL) { CallbackData->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; CallbackData->IoStatus.Information = 0; } }
버퍼에 대한 MDL이 없는 경우 버퍼 주소를 사용하여 버퍼에 액세스합니다. 사용자 공간 버퍼 주소가 유효한지 확인하려면 미니필터 드라이버는 ProbeForRead 또는ProbeForWrite와 같은 루틴을 사용하여 블록을제외한try/의 모든 버퍼 참조를 묶어야 합니다.
사전 운용 콜백 루틴은 다음과 같이 빠른 I/O 작업에서 버퍼를 처리해야 합니다.
버퍼 주소를 사용하여 버퍼에 액세스합니다(빠른 I/O 작업에 MDL이 있을 수 없기 때문).
사용자 공간 버퍼 주소가 유효한지 확인하려면 미니필터 드라이버는 ProbeForRead 또는ProbeForWrite와 같은 루틴을 사용하여 블록을제외한try/의 모든 버퍼 참조를 묶어야 합니다.
빠른 I/O 또는 IRP 기반이 될 수 있는 작업의 경우 블록을제외한 모든 버퍼 참조를 try/로 묶어야 합니다. 버퍼링된 I/O를 사용하는 IRP 기반 작업에 대해 이러한 참조를 묶을 필요는 없지만 블록을제외한시도는/ 안전한 예방 조치입니다.