Я использую DDK XP Checked Build Environment. пытаюсь использовать как в примерах, но получаю ошибку unresolved external. причем как для NtFlushBuffers, так и для ZwFlushBuffers
В глаза не видел DDK, в фасме можно так или так Код (Text): ;==========================================================так1 ntdll db 'ntdll.dll',0 fname db 'NtFlushBuffersFile',0 ;============================================================== invoke GetModuleHandle,ntdll invoke GetProcAddress,eax,fname stdcall eax,FileHandle,IoStatusBlock ;============================================================== ;==========================================================так2 invoke NtFlushBuffersFile,FileHandle,IoStatusBlock ;============================================================== data import library ntdll,'ntdll.dll' import ntdll,NtFlushBuffersFile,'NtFlushBuffersFile' end data ;==============================================================
Я использую KeWriteFile для записи информации в файл и хочу, чтоб сразу после вызова этой функции кеш сбрасывался на диск. флаги FILE_NO_INTERMEDIATE_BUFFERING |FILE_WRITE_THROUGH не помагают!
Ищи в примерех к ДДК использование IRP_MJ_FLUSH_BUFFERS, например, в исходнике DDK\src\filesys\fastfat\ функция FatHijackIrpAndFlushDevice. В конечном счете все сводится к формированию нужного IRP и посылке его девайсу, обслуживающему файл. Вопрос в обвязке посылки этого IRP. Например, нужно ли получать эксклюзивный доступ к файлу, как это делает ядерная NtFlushBuffersFile или нет. Этих деталей я не знаю. Также можно глянуть CcFlushCache и CcPurgeCacheSection, но вызывать их просто так точно нельзя. ЗЫ: Можешь ещё эти ветки глянуть: http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=6794 http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=5785
Короче есть такой проект FileDisk. - всем хорошо известный. Я хочу пришить к нему возможность шифрования перед записью на диск и дешифрации перед читанием с диска. Но в результате из-за кеша, когда я читаю функцией ZwReadFile , то получаю не разшифрованые, а зашифрованые данные из кеша, как я догадываюсь. Нужно решить эту проблему
Используй промежуточный буфер Когда я писАл такую штуку исследовал этот процесс. Очень интересно получается... Когда юзверь выделяет файл (пока не читает), Вынь читает, кажется один сектор - это называется кэширование У тебя происходит чтение/расшифровка. Затем юзверь читает файл - Вынь за каким-то X<sup>3</sup> этот сектор записывает - происходит шифрование/запись, а затем этот же буфер подсовывает юзверю, который видит шифрованные данные )) Вот для этого и нужен промежуточный буфер
Трудности в следующем. Я записываю зашифрованные данные на диск с помощью KeWriteFile. Расшифровка по идее должна происходить при подачи запроса IRP_MJ_WRITE. Но проблема в том, что файл записывается не на диск, а в кеш. и когда система пытается открыть файл, который в кеше, то данные не проходят через фильтр, а берутся прямо из кеша. Т.е. пользователь получает зашифрованные данные вместо расшифрованных. Если демонтировать раздел, а потом замонтировать опять, то кеш очищается и данные расшифровуются нормально. Я пробую кидать IRP_FLUSH_BUFFERS_FILE вот код: ............................................................ \\пишем инфу в файл ZwWriteFile( device_extension->file_handle, NULL, NULL, NULL, &irp->IoStatus, buff, io_stack->Parameters.Write.Length, &io_stack->Parameters.Write.ByteOffset, NULL ); NtFlushBuffersFiles(device_extension->file_handle,0); } NTSTATUS NtFlushBuffersFiles ( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock ) /* * FUNCTION: Flushes cached file data to disk * ARGUMENTS: * FileHandle = Points to the file * IoStatusBlock = Caller must supply storage to receive the result of * the flush buffers operation. The information field is * set to number of bytes flushed to disk. * RETURNS: Status * REMARKS: This function maps to the win32 FlushFileBuffers */ { PFILE_OBJECT FileObject = NULL; PIRP Irp; PIO_STACK_LOCATION StackPtr; KEVENT Event; NTSTATUS Status; Status = ObReferenceObjectByHandle(FileHandle, FILE_WRITE_DATA, NULL, KernelMode, (PVOID*)&FileObject, NULL); if (Status != STATUS_SUCCESS) { return(Status); } KeInitializeEvent(&Event,NotificationEvent,FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS, FileObject->DeviceObject, NULL, 0, NULL, &Event, IoStatusBlock); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; Status = IoCallDriver(FileObject->DeviceObject,Irp); if (Status==STATUS_PENDING) { KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = Irp->IoStatus.Status; } return(Status); } Но когда я смотрю с помощью Irptracker запросы, то вижу, что никакой IRP_MJ_FLUSH_BUFFERS не посылается. Может я что-то не так делаю???
FileDisk не смотрел, но возможно нужно добавить fast I/O dispatch - структура FAST_IO_DISPATCH. Запросы к кэшированным данным через через неё проходят. См. DDK\src\filesys\filter\filespy\
Нет, господа FlushBuffer дает команду ДРАЙВЕРУ ДИСКА сбросить буфер HDD (если кто не знает, сейчас идут диски с размером 2 и 8 Мб). ОС не сбрасывает кэш файловой системы (или я не нашёл эту оооочень полезную штуку). Four-F Если помнишь на форуме я спрашивал как сбросить кэш файловой системы, т.к. периодически получал битые исходники Прочитал Солдатова... стр. 238 в таблице 8.7б Как видно из описания, вопрос сброса кэш ФС остается открытым axelx А чем тебе не подходит промежуточный буфер? У меня именно так и работает
Господа, а чем вам, все-таки, не нравится CcFlushCache? Тем более что ее уже упоминали, да и ссылки давали? - даже если ты и сбросишь содержимое кэша на диск при помощи CcFlushCache, система при следующем чтении опять возьмет зашифрованные данные из кэша, не затрагивая накопитель. Если я правлильно понял, расшифровка происходит при IRP_MJ_READ? Тогда, после записи на диск, необходимо очистить кэш при помощи CcPurgeCacheSection, чтобы при следующем запросе на чтение, данные были подняты из файла.
Есть хорошая книга на эту тему: "Windows NT File System Internals" вот ее описалово: http://www.oreilly.com/catalog/wininternals/index.html Там и описание функций, и практически все структуры. Ищи в инете, если повезет, найдешь в электронном виде , я в свое время нашел некоторые главы...
>>А чем тебе не подходит промежуточный буфер? У меня >>именно так и работает что ты имеешь ввиду?? Можно поконкретней??
<font color="gray][ axelx</font><!--color--><font color="gray]: Где можно найти пример или документацию по CcFlushCache или CcPurgeCacheSection? ]</font><!--color--> Они документированы в IFS KIT. Наверное в онлайновом ДДК на microsoft.com или osr.com тоже есть. Примеры использования есть в том же IFS KIT. Используются они гениально просто, вопрос кто, когда и при каких условиях может их юзать. CcFlushCache( pFileObject->SectionObjectPointer, NULL, 0, NULL ); CcPurgeCacheSection( pFileObject->SectionObjectPointer, NULL, 0, FALSE );
axelx Код (Text): .if [edi].MajorFunction==IRP_MJ_READ читаем данные из файла в буфер расшифровываем копируем в системный буфер .elseif [edi].MajorFunction==IRP_MJ_WRITE копируем данные из системного буфера шифруем записываем в файл .endif Из за особенности работы ФС приходится пользоваться промежуточным буфером Может есть способ покруче, но мне ничего на ум не пришло...