Приветствую всех! Есть WDM драйвер PCI-ной платы, которая является шиной для некоего устройства хранения (FILE_DEVICE_DISK). PDO (PhysicalDeviceObject) этого устройства хранения создается моим драйвером, и подцепляется драйвером disk.sys, который и становится его функциональным драйвером. Доступ к устройству хранения достаточно медленный - пара мегабайт/сек. При записи на него 100 МБайтного файла под Windows 2003 Server. Vista и 7 картина выглядит так, как будто запись проходит почти мгновенно, хотя в действительности это не так - IRP продолжают сыпаться в течение минуты. Под XP SP3 все выглядит не так страшно, но все равно визуально процесс записи заканчивается гораздо раньше, чем на самом деле. Явно такое поведение является следствием реализации кэширования при записи. Пытался поиграть с параметром SystemCacheDirtyPageThreshold ключа HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\MemoryManagement\, безрезультатно. Выбор политики "Оптимизировать для быстрого удаления" влияет на ситуацию под Windows 7: в FARе прогресс записи сразу после ее начала проходит все 100%, но подвисает в конце до ее выполнения. А в 2003 Server ситуация всегда одинакова - почти мгновенная запись и закрытие окна с полосой прокрутки. Что интересно, с USB флэшками все выглядит так, как ожидается: полоса бежит в соответствии с реальным процессом записи. Все флаги и capabilities дисковых устройств, создаваемых моим драйвером и usbstor.sys одинаковы. Никаких запросов сверху, которые бы могли бы определить такое поведение драйверов верхнего уровня к моему драйверу не поступает. Вопрос: как сделать так, чтобы прогресс операции записи соответствовал реальному положению дел?
Думается мне, проблема в кэше файловой системы. Решение: написать файловой фильтр и принудительно выключать кэш у открываемых файлов.
x64, спасибо за ответ. Не хотелось бы интегрировать в проект дополнительные компоненты, весь вопрос-то лишь в неправильном на мой взгляд отображении процесса записи (записав гигабайт за 2 секунды и нажав кнопку питания, можно потом 10 минут удивляться, почему машина, свернув все окна, не выключается). Интересно, почему же с USB MCS девайсами такой проблемы нет? Какое дело драйверам верхнего уровня в контексте кэширования до тех шин, к которым подключена конкретная аппаратура (хотя при этом я пробовал сообщать и BusTypeScsi и BusTypeUsb в структурах, возвращаемых на запрос IOCTL_STORAGE_QUERY_PROPERTY - безрезультатно)? Но повторюсь, драйвер написан в стиле WDM, а не port driver, на то были свои причины. Под 2003 Server IRPTrace для моего драйвера и usbstor.sys выдает почти идентичные, за исключением нескольких явно не имеющих отношения к проблеме запросов, логи.
CRA Посмотреть работу с IRP запросами, нет ли приждивременного ответа на не завершонный IRP (путем копирования, дапы измебжать простой потока ), в это время как для removable (USB )это будет не допустимо. Вообще WinDbg в помощь. Можно взять еще иду. Ну или какойто IRP трасир. ( IRPTrace ? )
CRA Ну сам посуди. Выше тебя только disk.sys (драйвер класса) и FSD (драйвер файловой системы). В первом, насколько я знаю, никакого кэширования не предусмотрено (его исходники есть в WDK, можешь ознакомиться), а вот во втором кэширование используется по полной программе. Вывод: проблема в кэше файловой системы. И ты это можешь легко проверить, написав простейший файловый фильтр, который будет в обработчике Create-запросов выставлять флаг, запрещающий кэширование.
Еще раз спасибо всем за помощь. Как это часто бывает, перелопатил много исходников, логов и форумов. В итоге решение было найдено, обрисую картину, вдруг кому пригодится. Стал копать исходники fastfat из WDK. В ф-и FatUnpinRepinnedBcbs есть флаг WriteThroughToDisk, устанавливаемый в ряде ситуаций. В случае, когда порт драйвером являлся usbstor.sys, флаг WriteThroughToDisk устанавливался, когда был установлен флаг VCB_STATE_FLAG_DEFERRED_FLUSH в IrpContext->Vcb->VcbState. В свою очередь флаг VCB_STATE_FLAG_DEFERRED_FLUSH устанавливался при монтировании ФС в случае неудачного завершения вызова FatToggleMediaEjectDisable(...) (см. FatInitializeVcb(...)), что и наблюдалось. Ф-я FatToggleMediaEjectDisable отправляет нижележащему драйверу (PartMgr и disk) запрос IOCTL_DISK_MEDIA_REMOVAL, который выраждается в команду SCSIOP_MEDIUM_REMOVAL для нижележащего порт драйвера. Мой драйвер как раз-таки успешно обрабатывал SCSIOP_MEDIUM_REMOVAL, в результате чего флаг WriteThroughToDisk не устанавливался. SCSIOP_MEDIUM_REMOVAL это PREVENT ALLOW MEDIUM REMOVAL из SPC (в свое время я полагался на ее использование для решения первично подразумеваемой задачи - запретить/разрешить возможность извлечения носителя, в моем случае это был CD). Но как оказалось, и честно говоря для меня это было не очевидно, драйвер файловой системы (по крайней мере FAT) в случае успешного запроса IOCTL_DISK_MEDIA_REMOVAL на запрет извлечения НЕ использует режим записи WriteThrough, т.е. использует КЭШирование, полагаясь на то, что без его ведома носитель извлечь нельзя.