При открытии+чтении файла NT кэширует его содержимое так, что последующие запросы на чтение фактически получают содержимое кэша а не физического носителя. Вся эта кухня довольно подробно описана у Соломона/Русиновича. Проблема вот в чем: можно ли мгновенно очистить содержимое этого самого кэша, так чтобы следующий запрос на чтение заново поднимал файл с диска?
По поводу NtFlushBuffersFile: маленькая прога: call NtCreateFile ; получили handle FILE_READ_DATA+FILE_WRITE_DATA call NtReadFile ; прочитали 4кб call NtFlushBuffersFile ; типа почистили буферы call NtClose ; убили handle ; теперь берем SoftIce и лезим в FILE_OBJECT ; поле PRIVATE_CACHE_MAP = 0 вроде как файл не кэширован... ; однако SHARED_CACHE_MAP - существует и указывает на VACB где мы находим mapped наши прочитанные 4 кб ; ручками изменяем первые 2-4 байта. call NtCreateFile ; снова получаем handle FILE_READ_DATA call NtReadFile ; и мы имеем не исходный файл, а наши измененные 2-4 байта Вариантов - 2: 1. NtFlushBuffersFile сливает содержимое кэша на диск, но сам кэш остается и используется далее. 2. NtFlushBuffersFile инициирует отложенную запись (lazy-write) и сливает содержимое + чистит кэш не сразу, а как придется.
1) Смотри флаги: FILE_WRITE_THROUGH FILE_NO_INTERMEDIATE_BUFFERING FILE_SYNCHRONOUS_IO_NONALERT И вообше: This service causes all buffered data to the file to be written. По-моему она синхронна и осылает IRP_MJ_FLUSH_BUFFERS, а у Four-F илвользуется FlushFileBuffers, которая вызаваетStatus = NtFlushBuffersFile(hFile,&IoStatusBlock); Требуются права: FILE_WRITE_DATA 2)Ждем Four-F
Sync и NtFlushBuffersFile просто немедленно сбрасывают последние изменения в файл. Но кеширование продолжается. Как вытолькнуть из кеша уже кешируемый файл я не знаю. Если из ядра надо, то можно посмотреть в сторону менеджера кэша. Например, есть CcPurgeCacheSection, которая, если я всё правильно понимаю, делает сабж. Но сам я Сс... функциями не работал, поэтому ничего умного не скажу. Если надо из юзера, то, наверное, только отменять кэширование при открытии файла.
А тогда у меня крыша едет: Чтоже теперь? Открыли файл прочитали 4 кб, потом какой-то процесс открыл этот файл, изменил 2-4 байта и закрыл. А мы опять читаем из этого файла (мы его ещё не закрывали) те же самые 4 кб, а они всё те же что-ли? Из этого кэша прочитанные? Да ведь нет же - тогдабы хаос какой-то был бы... Что за чёрт?
PavPS Сделать файл не разделяемым, пусть остальные приложения подождут, или сообщают твоему, что файл им нужен.
PavPS Касательно флагов: FILE_WRITE_THROUGH - требует немедленной записи на диск, т.е. отключает lazy-write для конкретного файла, кэш при этом сохраняется. FILE_NO_INTERMEDIATE_BUFFERING - отключает кэширование на уровне драйвера ФАЙЛОВОЙ СИСТЕМЫ, т.е. при чтении/записи логического блока (кластера). Это значит, что чтение может быть осуществлено только в размере кратном размеру кластера и только с позиции в файле выравненой на размер кластера. Соответствено file stream (как некоторый поток данных) кэшируется как всегда. FILE_SYNCHRONOUS_IO_NONALERT - это просто синхронное IO, на кэш не влияет. NtFlushBuffersFile - действительно отсылает IRP_MJ_FLUSH_BUFFERS. - наш процесс увидит все изменения файла, поскольку кэширование осуществляется на уровне FILE STREAM т.е. один файл окрытый разными процессами представлен только одним stream-ом в памяти, это ни что иное как те-же самые страницы mapped на разные процессы. pas это ничего не дает, на кэширование не влияет.