Слежение за кешем файловой системы

Тема в разделе "WASM.NT.KERNEL", создана пользователем ViP, 14 дек 2009.

  1. ViP

    ViP New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2009
    Сообщения:
    7
    Добрый день,

    У меня есть такая задача - есть fs legacy filter, необходимо выявить IRP пакеты чтения, которые читают из кеша, причем данные в кеш были помещены до того, как был загружен мой драйвер, после чего попытаться сбросить кеш.
    Драйвер должен загружаться именно по запросу, не при старте системы.

    Примерная идея реализации номер 1 -
    1. добавлять свой контекст при помощи FsRtlInsertPerStreamContext в тот момент, когда происходит чтение с флагом IRP_NOCACHE.
    2. при создании проверять контекст, если есть и если CCIsFileCached - пытаться сбросить кеш либо просто запрещаем открытие файла или ставим флаг создания FILE_NO_INTERMEDIATE_BUFFERING.
    3. как вариант при кешированном чтении проверять контекст, если есть - пытаться сбросить кеш (похоже это все, что можно сделать в данном пути)

    Второй вариант:
    1. Хранить список FileObject->FSContext, которые читали с флагом IRP_NOCACHE.
    2. При create проверяем наличие в кеше - CCIsFileCached и в нашем списке FileObject->FSContext, если оба условия выполняются - пытаться сбросить кеш либо просто запрещаем открытие файла или ставим флаг создания FILE_NO_INTERMEDIATE_BUFFERING.

    ответьте плз на следующие вопросы, чтобы получше понять подводные камни:

    FsRtlInsertPerStreamContext сохраняет данные в дебрях FileObject->FSContext. Возможно оба варианта ничем не отличаются?
    Когда StreamContext освобождается? Значит ли это, что кеш в этот момент тоже удаляется (думаю врядли)?
    Когда удаляется FSContext? Значит ли это, что кеш в этот момент тоже удаляется?
    Флаг создания FILE_NO_INTERMEDIATE_BUFFERING. Говорят, что при этом система самостоятельно обнуляет кеш и читает с диска, это так?
    В precreate будет ли доступен FileObject->FSContext или StreamContext?

    Не хочется начинать не разобравшись как все это работает, заранее спасибо за ответы.
     
  2. ViP

    ViP New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2009
    Сообщения:
    7
    В общем удалось устанавливать StreamContext, отлавливать нужные файлы и очищать для них кеш в IRP_MJ_READ.

    Я так понимаю, освобождение StreamContext означает скорое освобождение FileObject->FSContext и очистку кеша? Тогда все должно работать как надо -)

    На счет флага FILE_NO_INTERMEDIATE_BUFFERING еще вопрос актуален.
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Во-первых, поясни, зачем это вообще нужно и чего ты хочешь добиться? Я пока не осилил понять это. Во-вторых, напомню, что в Pre-Read мы ещё не знаем, будут ли данные прочитаны из кэша или с диска. Об этом можно судить только по косвенными признакам, в частности, можно использовать такие флаги как FO_NO_INTERMEDIATE_BUFFERING, FO_CACHE_SUPPORTED или тот же IRP_NOCACHE.

    По поводу вариантов реализации пока ничего не могу сказать, я пока не вижу цели. Могу только сказать, что stream context и адрес в поле FsContext это почти одно и тоже, т.е. и то и другое вполне можно задействовать для одной и той же задачи, просто вариант с per-stream contexts появился только начиная с Windows XP и, насколько я понимаю, именно этот способ будет поддерживаться Microsoft в будущем.

    Per-stream context освобождаешь ты сам в предоставленной тобой же free routine. Эту функцию косвенно вызывает файловая система при уничтожении файлового объекта, то бишь при обработке IRP_MJ_CLOSE. Структура FsContext, которая реально указывает на File Control Block (FCB), освобождается там же, в обработчике Close-запроса. Один только момент: оба контекста освобождаются только тогда, когда счётчик ссылок на файловый поток (file stream) падает до нуля. При этом важно понимать, что файловый поток это не тоже самое, что файловый объект (file object), ибо один и тот же файловый поток может быть представлен несколькими файловыми объектами, и данные этого файлового потока будут удалены из кэша только тогда, когда будет закрыт последний файловый объект, который указывает на этот поток. Вот тут я, правда, не помню, вроде бы данные в кэше сохраняются даже после закрытия файлового потока, надо проверять.

    Да, это так. По крайне мере, для FAT и NTFS это работает.

    Нет, для этого необходима обработка в Post-Create.

    Сначала освобождаются все stream contexts, связанные с файловым объектом, затем FCB. По крайне мере, это справедливо для FAT. Для NTFS надо бы глянуть, но мне сейчас уже неохота.
     
  4. ViP

    ViP New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2009
    Сообщения:
    7
    x64, спасибо за ответ,

    задача - шифрование на лету dvd/cd дисков. Юзер вставляет диск, запускает прогу с диска, вводит пароль, устанавливается и запускается драйвер, перехватывает диск, расшифровывает на лету некешированные пакеты чтения. Все бы хорошо, но если до ввода пароля юзер "почитал" зашифрованные файлы на диске - они помещаются в кеш в зашифрованном виде и после запуска драйвера не расшифровываются.
    Поэтому я и решил определять данные, которые попали в кеш до запуска драйвера.
     
  5. ViP

    ViP New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2009
    Сообщения:
    7
    В принципе пока все работает, думаю, даже если контекст будет освобожден, а кеш нет, то ничего страшного, лишний раз кеш очистим.

    Но есть еще одна нерешенная проблема - сразу при размонтировании диска ничего не приходит. Т.е. если даже подождать минут 5, вставить диск снова - данные будут все также расшифровываться, а по заданию необходимо, чтобы если диск вынули - расшифровка сразу прекратилась.
    Единственное что заметил - после того как вставили диск и смотрим его листинг, cdfs инициирует запрос create и возвращает статус reparse. Если диск не вынимать - такого статуса не будет.

    Ну или, как вариант, в потоке делать опросы каждые N минут... Но не нравится мне этот вариант.