Доступ к пользовательским буферам в процедуре обратного вызова перед выполнением операции
Подпрограмма обратного вызова драйвера минифильтра перед операцией должна обрабатывать буфер в операции ввода-вывода на основе IRP следующим образом:
Проверьте, существует ли MDL для буфера. Указатель MDL можно найти в параметре MdlAddress или OutputMdlAddress в FLT_PARAMETERS для операции. Драйверы мини-фильтра могут вызывать FltDecodeParameters для запроса указателя MDL.
Одним из способов получения допустимого MDL является поиск флага IRP_MN_MDL в элементе MinorFunction блока параметров ввода-вывода FLT_IO_PARAMETER_BLOCK в данных обратного вызова. В следующем примере показано, как проверка для флага 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 можно задать только для операций чтения и записи. Лучше всего использовать FltDecodeParameters для получения MDL, так как подпрограмма проверяет допустимое значение 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/, кроме блоков.
Подпрограмма обратного вызова перед операцией должна обрабатывать буфер в быстрой операции ввода-вывода следующим образом:
Используйте адрес буфера для доступа к буферу (так как быстрая операция ввода-вывода не может иметь MDL).
Чтобы убедиться, что адрес буфера пользовательского пространства является допустимым, драйвер минифильтра должен использовать подпрограмму , например ProbeForRead или ProbeForWrite, заключая все ссылки на буфер в try/, кроме блоков.
Для операций, которые могут быть быстрыми операциями ввода-вывода или IRP, все ссылки на буферы должны быть заключены в try/, за исключением блоков. Хотя вам не нужно заключать эти ссылки для операций на основе IRP, использующих буферизирующиеся операции ввода-вывода, блоки try/except являются безопасной мерой предосторожности.