| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > отключить кеширование файла(ов) |
| Автор: shara 8.2.2010, 23:20 |
| нуждаюсь в помощи.. имея на руках драйвер фильтр ФС, хочу отключить кеширование определенных файлов? цель - что бы все запросы на чтение\запись файла с диска проходили через мой фильтр, т.к. если файл кеширован то целевое приложение посылает фильтру лишь IRP_MJ_CREATE и все... затем оно получает данные из кеша МИНУЯ всю файловую систему и чтобы это отключение кеша не повлияло на работу с файлами как таковую: FileMapping \ File Open \ FileRead \ FileWrite и им подобные функции должны работать как обычно.... уже не первый день ломаю голову мысли пришли следующие:
|
| Автор: bra1ny 9.2.2010, 00:15 |
| Чего вы мудрите коли у вас дарйвер фильтр фс , фильтруйте фаст ио для своих файлов. Если хотите запись и чтение , то это FastIoRead / FastIoWrite. |
| Автор: shara 9.2.2010, 00:17 |
| не понял, что именно фильтровать в фаст ио? можно чуть конкретнее... в том то и дело что и фаст ИО тоже не приходят если файл кеширован то от подопытного приложения приходит лишь IRP_MJ_CREATE и все.. затем в пост обработке этого самого ИРПа видно что в "FileObject->SectionObkectPointer->DataSectionObject" лежит не 0 (это значит что ДАННЫЕ из вайла уже в памяти) и как следствие ФС не получит запрос IRP_MJ_READ на чтение данных. тоесть данные идут в обход драйвера ФС, потому что они прокешированы ... или поправьте если ошибаюсь... |
| Автор: bra1ny 9.2.2010, 00:25 | ||
Ну даже не знаю с чего начать?
Правильно если файл кеширован , то на чтение например не будет генерироваться IRP пакет , а будет произведен быстрый ввод вывод в данном случаи FastIoRead. |
| Автор: bra1ny 9.2.2010, 00:31 |
| Вот Вам еше почитать про фаст ио. Если файл кеширован , то нафига генирить IRP_MJ_READ? смысл теряется)) |
| Автор: shara 9.2.2010, 22:17 |
| bra1ny, за доку агрмадное спасибо - хорошая вещ у меня еще один вопрос, если файл 100% кеширован - то может ли ОСь или ДспетчерКеша вызвать http://msdn.microsoft.com/en-us/library/ms791433.aspx и напрямую записать данные в пользовательский буфер минуя драйаер ФС (IRP_MJ_Xxx \ FastIoXxx) ? |
| Автор: bra1ny 9.2.2010, 23:15 | ||
| И так у вас каша сурьезная. Считаю лучше прям на примере показать. И так маленькая иллюстрация (извините но рисовать я не умею))) ) 2 варианта . 1 - файл не кеширован 2 - файл кеширован проходим первый путь : ReadFile -> NtReadFile -> ... -> генерация IRP -> драйвер фс -> драйвер устройства памяти. тут все предельно ясно второй путь ReadFile->NtReadFile->...->FastIoRead->драйвер фс ->CcCopyRead->Диспетчер кеша. На деле винда делает так.
Ну вот вроде все сказал , что хотел ) |
| Автор: shara 16.2.2010, 21:23 |
| я ставлю свои обработчики на IRP_MJ_CREATE IRP_MJ_READ\WRITE и на IRP_MJ_CLOSE при пост обработке IRP_MJ_CREATE сверяю имя файла с заданным, при помощи RtlUnicodeXxx (или как-то так, точно не помню) с опцией не чувствительности к регистру, и если был открыт интерисующий меня файл (C:\test.txt) я запоминаю его указатель FileObject->FsContext в свой буфер. Помечаяя таким образом этот объект_файла для всех остальных IRP'ов и FastIO's затем при обработке IRP_MJ_WRITE\READ FastIOWrite\Read я определенным образом подменяю содержимое дуферов с данными, только для помеченых файлов. написал простую прогрммку которая пишет и читает файл стандартными ВинАПИ функциями - и все работает отлично ( иногда проскакивает FastIO который успешно отлавливается и делает нужное мне дело) интересные вещи начинаются когда тестирую таким образом Блокнот.ехе если я пытаюсь открыть блокнотом файл и этот файл ранее не был открыт никаким приложением - то все работает отлично, НО если перед этим производилось запись в этот файл из другой программы, или из блокнота, то повторное чтение файла не дает нужного результата. по протоколу смотрю смотрю какие действия производились с этим файлом, и выходит что кроме как CREATE запроса блокнот никаких требований не предявля к системе.. (на все другие FastIO и IRP_MJ у меня стоят "пищали"). другое дело что Explorer.exe читает из файла - но все его поползновения были обработаны мною должным образом но это не дает требуемого эффекта. возможно я не все Fast'ы и IRP'ы фильтрую.. но мне всегда казалось что файл на диске однозначно определяется по его полному пути... и что того условия отбора о котором я писал в начале достаточно. еще один замеченный мною нюанс, когда файл блокнотом открывается в первый раз, (т.е. он не кеширован) то приходи IRP_MJ_READ у которого поле RequestorMode == KernelMode и буфер MdlAddress не пустой. я так понимаю что это запрос от диспетчера кеша а если файл уже в памяти есть то такой запрос не приходит буду очень рад услышать любые мысли на сей счет ... |
| Автор: bra1ny 17.2.2010, 14:17 |
| код бы показали |
| Автор: shara 17.2.2010, 20:59 | ||
код постараюсь выложить в ближайшее время.. пока не могу это сделать физически вот цитата из книги Олифера "Сетевые ОС" Глава 8
я решил проверить свой фильтр чем-то более авторитетным. взял утилиту ProccesMonitor v2.8 настроил его так чтобы показывать любые поползновения ОС в сторону подопытного файла "test.txt" в результате было видно что Notepad.exe на прямую не посылает запросов чтения (IRP и FastIO) к этому файлу. за него это ТРИ раза делает Explorer.exe (первый раз он читает файл в кеш) и еще два раза ХЗ зачем он туда лезет... кстати еще один нюанс, есть функция CcPurgeCacheSection которая очищает кеш файла по его FileObject. я использую ее при обработке IRP_MJ_CREATE если вижу что целевой файл КЕШИРОВАН. т.е. принудительно очищаю кеш. и эффект был весьма положительный. Блокнот послушно читал из файла то что я ему подсовывал в IRP_MJ_READ (FastIO) не зависимо от того кто\что и сколько раз писали в этот файл ранее есть большое желание разобраться как ДиспетчерКеша работает с драфверами ФС и фильтрами ФС, покаместь, я думаю, что если требуемая часть файл имеется в ОЗУ - запросы типа IRP_MJ_READ (FastIORead) не послылаются воовсе... вместо этого данные сразу перекладываются в пользовательский буфер (возможно мапируются)... без создания и отправки в них по драйверскому стеку каких либо дополнительных IRPов. в общем думаем дальше |
| Автор: bra1ny 17.2.2010, 23:03 |
| Во первых у Windows своя система кэширования , ваша цитата как я понял , что каждая фс кеширует данные индивидуально. У windows этот механизм единый для всех фс. Вы прочитали 11 главу Руссиновича диспетчер кеша там описан ну очень детально.Буду дома вечером просмотрю ваши вопросы , желательно чтобы вы еше тз написали , а то приходится догадываться что вы там делаете |
| Автор: shara 17.2.2010, 23:22 |
| bra1ny, ТЗ весьма прост - прозрачное шифрование файлов как я уже говорил, с тестовой програмкой процесс прозрачного шифрования проходит на ура. т.е. она пишет\читает на диск зашифрованные файлы но получает - в нормальном (читаемом) виде проблемы с правильной обработкой кешируемых файлов, не всегда мой фильтр видит данные которые идут к\от конечного приложения ( в нашем случае notepad.exe) постараюсь выложить исходник, сарзу скажу что это гибрид SFilter и драйвера от SysInternals (когда они еще давали исходники к ProcessMonitor) сейчас вот буду чиать Русиновича |
| Автор: shara 18.2.2010, 00:49 |
| если быть совсем точным, то проблема с модификацией данных ранее загруженных в кеш. т.е. когда файл читается впервые: 1. данные читаются с диска 2. мой фильтр перехватывает их и расшифровывает 3. данные в расшифрованном виде грузятся в кеш затем, если данные в процессе работы обновляются и затем сохраняются на диск: 1. мой фильтр перехватывает записываемые данные и зашифровывает их 2. в зашифрованном виде они попадают на диск и в кеш. при последующем чтении данные уже не читаются из диска, а грузятся из ОЗУ (поскольку данные кешированы) сразу в память процесса. и получается так что этот момент я упускаю - notepad.exe получает данные в зашифрованном виде ВМЕСТО того чтобы получить читаемый текст я хочу либо отключить кеширование целевых файлов как таковое. думаю для этих целей принудительно использовать флаг http://msdn.microsoft.com/en-us/library/ms791436.aspx при отправке IPR_MJ_CREATE в низ по стэку (кстати об этом и Руссинович пишет) либо всегда держать в кеше данные в открытом виде ( и шифровать их только при сбросе на диск) либо всегда держать в кеше данные в шифрованном виде ( и расшифровывать при чтении из кеша) второй & третий способы ХЗ как сделать... |
| Автор: shara 18.2.2010, 22:57 |
| форсировать использование флага FILE_NO_INTERMEDIATE_BUFFERING нельзя сделал рабочий!! фильтр который шифрует данные на стадии записи\чтения инфы из диска в кеш т.е. в кеше хранится информация в открытом виде. от Диспетчера Кеша всегда приходят запросы из KernelMode у которых стоит метод НИКАКОЙ (NEITHER) и IRP->MdlAddress != 0 хотелось бы еще попробовать сделать два оставшихся варианта, с отключением кеша, и с хранением инфы в кеше в шифрованном виде... bra1ny, посмотрите пожалуйста код. я уверен что у Вас буду замечания к нему не подскажите как быть с записью? при записи шифрую информацию в буфере, затем опускаю запрос ниже по стеку, а в пост_обработчике IRP_MJ_WRITE повторно шифрую буфер (т.е. восстанавливаю исходное состояние данных) шифр на основе гаммирования. не хочется дважды запускать процесс шифрования.. была высль веделить буфер в который записать шифрованную ифу и подменить адрес в IRP->MdlAddress на него, но тогда идет двойной расход памяти.... (выложил не весь исходник, а лишь критически важные секции) т.е. процесс инициализации драйвера и установки обработчиков частично опущен |