Замена ZwWriteFile на IRP_MJ_WRITE

Тема в разделе "WASM.NT.KERNEL", создана пользователем SheriFF, 23 июл 2009.

  1. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    В процессе обработки определенного irp-пакета нужно дописывать в файл информацию, ZwWriteFile() возвращает в качестве результата успешное выполнение операции, но не пишет, насколько я понимаю, она отправляет irp пакет и возвращает факт отправки, а не результат записи, мне нужно дождаться факта записи, а потом отправлять обрабатываемый irp-пакет следующему драйверу в стеке.
    Заменил вызов функции на свою, которая формирует пакет с помощью IoBuildSynchronousFsdRequest, где DeviceObject получался как FileObject->DeviceObject, IoCallDriver() возвращает код c000000D или STATUS_INVALID_PARAMETER. offset правильный.

    Собственно в чем я не прав или какие альтернативные способы решения данного вопроса
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ZwWriteFile сойдет, только файл открывайте без буфферизации с прямой записью (там флажки есть у крейт файл)
     
  3. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    а интересно относительно IoBuildSynchronousFsdRequest, если я пишу в файл, для которого идет irp-пакет, обработку которого я приостанавливаю
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Тогда покажи код, который формирует IRP-пакет, который валится с C000000D
     
  5. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    Код (Text):
    1.     NTSTATUS status;
    2.  
    3.     IO_STATUS_BLOCK ioStatus;
    4.  
    5.     PIRP irp;
    6.  
    7.     KEVENT event;
    8.  
    9.         PVOID buffer;
    10.         LARGE_INTEGER offset;
    11.         ULONG length;
    12.  
    13.         PDEVICE_OBJECT deviceObject = fileObject->DeviceObject;
    14.  
    15.     KeInitializeEvent (&event, NotificationEvent, FALSE);
    16.  
    17.     irp = IoBuildSynchronousFsdRequest ( IRP_MJ_WRITE, deviceObject, buffer, length, &offset, &event, &ioStatus);
    18.  
    19.     if (!irp)
    20.  
    21.         return STATUS_INSUFFICIENT_RESOURCES;
    22.  
    23.  
    24.  
    25.     ObReferenceObject (deviceObject);
    26.  
    27.  
    28.  
    29.     status = IoCallDriver (deviceObject, irp);
    30.  
    31.     if (status == STATUS_PENDING)
    32.  
    33.         status = KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
    34.  
    35.  
    36.     ObDereferenceObject (deviceObject);
    37.  
    38.     return status;
     
  6. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    при получении NTSTATUS = 0хс000000d (STATUS_INVALID_PARAMETER) можно узнать какой параметр не корректный или нет?

    и правильно ли записывать в файл с помощью посылки IRP_MJ_WRITE, посылая пакет FileObject->DeviceObject?
     
  7. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    и еще вопрос - при построении irp-пакета указывается deviceobject, потом для iocalldriver также определяется deviceobject, они должны быть одним и тем же?
     
  8. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    что-то бред я какой-то написал, посылал пакет не в файл, а диску (((
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    К сожалению, ядро писали много людей, поэтому в подсистеме памяти обычно возвращются статусы STATUS_INVALID_PARAMETER_X (0 < x <= 9), что удобно, но не используется в других местах :dntknw:
     
  10. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Давайте я уже отвечу, а то эта тема в какое-то мутево нездоровое превращается потихоньку.

    Прежде всего, не надо ничего делать руками через IoCallDriver() ибо в 90% случаев этого не требуется (хотя тут, конечно, ситуацию более подробно надо смотреть, исходя из того, что есть под рукой). Во-вторых, опиши подробно, почему ты считаешь что реально данные не пишутся во время вызова ZwWriteFile(), при этом учти кэширование, если ты его используешь, то реально данные могут быть записаны уже после возврата управления из ZwWriteFile(). В-третьих, статус, возвращаемый из ZwWriteFile(), это как правило код, возвращённый самой файловой системой (FSD), - особенно, если это STATUS_SUCCESS. Если успех и запрос синхронный, то ядро гарантирует одно из двух:

    1. Данные были переданы файловой системе, которая записала их в кэш.
    2. Данные были переданы файловой системе, которая передала их в storage stack, и оттуда вернули успех, т.е. данные физически ушли в устройство хранения.

    Если нужно дождаться реальной записи, поставь флаг FILE_NO_INTERMEDIATE_BUFFERING в ZwCreateFile() и будет тебе счастие.
     
  11. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    а если файл был открыт с эксклюзивной блокировкой в пространстве пользователя, как записать в него информацию из драйвера-фильтра?
    IoCreateFileSpecifyDeviceObjectHint с IO_IGNORE_SHARE_ACCESS_CHECK возвращает STATUS_ACCESS_VIOLATION, видимо файловая система все еще проверяет права
     
  12. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Во-первых, не очень понимаю, откуда такая нужда вообще взялась - писать в файл, открытый эксклюзивно? Кривой архитектурной попахивает. Ну или задача уж очень специфическая. А во-вторых, если у тебя фильтр, значит под рукой должен уже готовый file object, почему бы не использовать его для ручного создания подзапросов в файловую систему? В этом случае не придётся ничего открывать. IoBuildSynchronousFsdRequest() с кодом IRP_MJ_WRITE и вперёд.
     
  13. SheriFF

    SheriFF New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2009
    Сообщения:
    14
    тогда вопрос относительно параметра offset для IoBuildSynchronousFsdRequest - от начала файла или от начала устройства, на котором расположен файл нужно его задавать?
     
  14. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Зависит от типа целевого объекта (file object), если это файл - относительно файла, если том - относительно начала тома и т.д., но в любом случае это значение задаётся в пределах того объекта, над которым производится операция.