Re: Фильтры
От: Maxim S. Shatskih Россия  
Дата: 21.05.04 17:39
Оценка: 42 (9)
А>Задача состоит в следующем. Имеется драйвер на подобии filemon,

Забудьте о filemon Руссиновича. Он неправильно написан. Он лезет на ходу к структурам данных, при невозможности захватить лок, связанный с ними. Это из серии "решение на соплях".

Правильный шаблон FS filter — SFILTER из MS IFS Kit. В последнем ките было что-то поновее, но, если нужна поддержка хотя бы w2k, не говоря об NT4 — то можно смело забыть про все новомодные заморочки.

А>а) как отследить появление в дисководе FDD дискеты;

А>б) как отследить появление в дисководе CDROM cd-диска;

Ха! Ну давайте расскажу все, что там происходит.

В случае флопика — если юзер тронул кнопочку eject, то дисковод взводит некий провод, и этот факт потом виден драйверу в одном из статусных регистров контроллера. Старые дисководы и контроллеры не умели, и в этом случае драйвер делал все по таймеру — "если со времени выполнения последней операции прошла секунда, то подозревать media change".

В случае сидюка все чуть иначе. Драйвер CdRom.sys постоянно пингует сидюк командой TEST UNIT READY. Команда описана в стандарте SCSI на www.t10.org, и работает примерно так — если в сидюке есть диск и его не меняли со времен последней команды, то она ничего не делает и завершается успешно. Если диск есть, но его меняли со времен последней команды — то TUR обламывается с ошибкой unit attention (это такое понятие в SCSI есть). Если диска нет — TUR обламывается с еще каким-то кодом ошибки. Если открыта дверца или высунут язык — то и еще с другим кодом ошибки .

Что такое unit attention. Если в SCSI приводе меняли дискету или ленту — он входит в состояние unit attention. В этом состоянии он обламывают любую — абсолютно любую — входящую команду с кодом ошибки unit attention. В момент этого облома состояние unit attention снимается, и на последующие команды уже не распространяется. Их выполнение будет или успешным, или с какой-то еще ошибкой, но не unit attention.

А дальше completion внутри CdRom.sys отслеживает ошибки уровня SCSI, и, в случае unit attention — считает, что в сидюке сменили диск.

Сидюки, понятное дело, у нас обычно ATAPIшные, но ATAPI — это SCSI по IDEшным проводам, и все вышесказанное верно и там.

А дальше — между диском и файловой системой — идет механизм, основанный на STATUS_VERIFY_REQUIRED и DO_VERIFY_VOLUME, см. книгу Раджива Нагара или исходники из IFS Kit.

Кстати, а USBшные флешки Вам неинтересны? С ними свои заморочки

А>в) где на fast io узнать серийный номер тома.


А почему на FastIo?

А>Нужно вот зачем. Узнав, что вставлен флоппи-диск/cd-диск,

А>даю команду драйверу. Драйвер прикрепляет себя к стеку

Неправильно! Поздно!

Прикрепиться к стеку можно только по ходу его построения, а не когда-то в будущем. Правильный способ — вписать себя в реестр как UpperFilters для классов Floppy и CdRom, и потом вести себя как обычный PnP/WDM фильтр.

Если речь о флешках — то там все суровей немножко, они как бы почти неотличимы от винчестера, и фильтр придется ставить на класс Disk. Писать придется его очень аккуратно, поскольку он и для бутового диска будет пытаться загрузиться.

Теперь ответ на вопрос: влезть в механизм STATUS_VERIFY_REQUIRED/DO_VERIFY_VOLUME между диском и файловой системой. Только будучи в этом механизме, можно четко отследить новую дискету или новый сидюк. Фильтр файловой системы, кстати, необязателен — проще прямо с диска IRPом прочитать кусочек метаданных, где сидит volume serial number.
Занимайтесь LoveCraftом, а не WarCraftом!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.