В процессе обработки определенного irp-пакета нужно дописывать в файл информацию, ZwWriteFile() возвращает в качестве результата успешное выполнение операции, но не пишет, насколько я понимаю, она отправляет irp пакет и возвращает факт отправки, а не результат записи, мне нужно дождаться факта записи, а потом отправлять обрабатываемый irp-пакет следующему драйверу в стеке. Заменил вызов функции на свою, которая формирует пакет с помощью IoBuildSynchronousFsdRequest, где DeviceObject получался как FileObject->DeviceObject, IoCallDriver() возвращает код c000000D или STATUS_INVALID_PARAMETER. offset правильный. Собственно в чем я не прав или какие альтернативные способы решения данного вопроса
ZwWriteFile сойдет, только файл открывайте без буфферизации с прямой записью (там флажки есть у крейт файл)
а интересно относительно IoBuildSynchronousFsdRequest, если я пишу в файл, для которого идет irp-пакет, обработку которого я приостанавливаю
Код (Text): NTSTATUS status; IO_STATUS_BLOCK ioStatus; PIRP irp; KEVENT event; PVOID buffer; LARGE_INTEGER offset; ULONG length; PDEVICE_OBJECT deviceObject = fileObject->DeviceObject; KeInitializeEvent (&event, NotificationEvent, FALSE); irp = IoBuildSynchronousFsdRequest ( IRP_MJ_WRITE, deviceObject, buffer, length, &offset, &event, &ioStatus); if (!irp) return STATUS_INSUFFICIENT_RESOURCES; ObReferenceObject (deviceObject); status = IoCallDriver (deviceObject, irp); if (status == STATUS_PENDING) status = KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); ObDereferenceObject (deviceObject); return status;
при получении NTSTATUS = 0хс000000d (STATUS_INVALID_PARAMETER) можно узнать какой параметр не корректный или нет? и правильно ли записывать в файл с помощью посылки IRP_MJ_WRITE, посылая пакет FileObject->DeviceObject?
и еще вопрос - при построении irp-пакета указывается deviceobject, потом для iocalldriver также определяется deviceobject, они должны быть одним и тем же?
К сожалению, ядро писали много людей, поэтому в подсистеме памяти обычно возвращются статусы STATUS_INVALID_PARAMETER_X (0 < x <= 9), что удобно, но не используется в других местах
Давайте я уже отвечу, а то эта тема в какое-то мутево нездоровое превращается потихоньку. Прежде всего, не надо ничего делать руками через IoCallDriver() ибо в 90% случаев этого не требуется (хотя тут, конечно, ситуацию более подробно надо смотреть, исходя из того, что есть под рукой). Во-вторых, опиши подробно, почему ты считаешь что реально данные не пишутся во время вызова ZwWriteFile(), при этом учти кэширование, если ты его используешь, то реально данные могут быть записаны уже после возврата управления из ZwWriteFile(). В-третьих, статус, возвращаемый из ZwWriteFile(), это как правило код, возвращённый самой файловой системой (FSD), - особенно, если это STATUS_SUCCESS. Если успех и запрос синхронный, то ядро гарантирует одно из двух: 1. Данные были переданы файловой системе, которая записала их в кэш. 2. Данные были переданы файловой системе, которая передала их в storage stack, и оттуда вернули успех, т.е. данные физически ушли в устройство хранения. Если нужно дождаться реальной записи, поставь флаг FILE_NO_INTERMEDIATE_BUFFERING в ZwCreateFile() и будет тебе счастие.
а если файл был открыт с эксклюзивной блокировкой в пространстве пользователя, как записать в него информацию из драйвера-фильтра? IoCreateFileSpecifyDeviceObjectHint с IO_IGNORE_SHARE_ACCESS_CHECK возвращает STATUS_ACCESS_VIOLATION, видимо файловая система все еще проверяет права
Во-первых, не очень понимаю, откуда такая нужда вообще взялась - писать в файл, открытый эксклюзивно? Кривой архитектурной попахивает. Ну или задача уж очень специфическая. А во-вторых, если у тебя фильтр, значит под рукой должен уже готовый file object, почему бы не использовать его для ручного создания подзапросов в файловую систему? В этом случае не придётся ничего открывать. IoBuildSynchronousFsdRequest() с кодом IRP_MJ_WRITE и вперёд.
тогда вопрос относительно параметра offset для IoBuildSynchronousFsdRequest - от начала файла или от начала устройства, на котором расположен файл нужно его задавать?
Зависит от типа целевого объекта (file object), если это файл - относительно файла, если том - относительно начала тома и т.д., но в любом случае это значение задаётся в пределах того объекта, над которым производится операция.