File System Filter Unloading
От: Аноним  
Дата: 04.12.07 16:02
Оценка:
Доброго времени суток всем...

Есть драйвер — некое подобие filemon.
Проблема заключается в его "выгрузке". Драйвер якобы корректно выгружается, но IRP'ы продолжают приходить. В итоге слетает стек и BSOD.

Очевидно, что допустил ошибку в реализации detach'а дисков, на IRP'ы которых подписался

Вот так пытаюсь "отцепиться" от дисков
    ULONG            drive, i;
    PDEVICE_OBJECT        device;
    LPHOOK_EXTENSION    hookExt;

    //
    // Detach from file system devices
    //
    for( drive = 0; drive < MAXHOOKEDDEV; drive++ )
    {
        if( m_arrDriveHookDevices[drive] )
        {
            device    = m_arrDriveHookDevices[drive];
            hookExt    = (LPHOOK_EXTENSION)device->DeviceExtension;

            IoDetachDevice( hookExt->FileSystem );
            IoDeleteDevice( device );
        }
    }


Подскажите, где грабли...
Re: File System Filter Unloading
От: Sergey Storozhevykh Россия  
Дата: 04.12.07 16:08
Оценка: +2
А>Подскажите, где грабли...

Невозможно выгрузить legacy FS Filter корректно. Подумайте о фильтрах сверху, например. Пишите минифильтр, если выгружаться все же хочется. Кстати это не единственная причина в пользу мимнифильтров
Re: File System Filter Unloading
От: Alter_ Украина http://alter.org.ua
Дата: 05.12.07 03:15
Оценка:
Доброго!

А>Есть драйвер — некое подобие filemon.

А>Проблема заключается в его "выгрузке". Драйвер якобы корректно выгружается, но IRP'ы продолжают приходить. В итоге слетает стек и BSOD.

А>Очевидно, что допустил ошибку в реализации detach'а дисков, на IRP'ы которых подписался


Да, кое-чего не хватает. Идея такая:
1) Detach. После этого новые IRP приходят уже мимо фильтра.
2) (этого-то и не хватает) ждем пока вернутся ушедшие вниз IRP. Точнее, пока вернется управление, ждать Complete'а не нужно, если нет собственных CompletionRoutines. Для этого в цикле проверяем счетчик в DeviceExtension'е. Как только обнулится — значит ни в одном потоке наших адресов уже нет на стеке возврата, можно переходть к 3
3) IoDeleteDevice

А>Вот так пытаюсь "отцепиться" от дисков

device    = m_arrDriveHookDevices[drive];
hookExt    = (LPHOOK_EXTENSION)device->DeviceExtension;
IoDetachDevice( hookExt->FileSystem );

Delay.QuadPart = -1*1000*1000; // 0.1 sec
while(hookExt->EnterCount) {
    KeDelayExecutionThread(KernelMode, FALSE, &Delay); // чтобы другие потоки могли работать
}
/*
а это на всякий случай. Если система сильно нагружена,
мы счетчик можем уже обнулить, а до RET не успеть дойти.
*/
Delay.QuadPart = -50*1000*1000; // 5 sec
KeDelayExecutionThread(KernelMode, FALSE, &Delay);

IoDeleteDevice( device );
--
Alter, http://alter.org.ua
Re[2]: File System Filter Unloading
От: Аноним  
Дата: 05.12.07 08:17
Оценка:
Здравствуйте, Alter_, Вы писали:

Правила форума нарушены.
— оверквотинг
Правила можно найти в разделе FAQ данного форума и\или ресурса.
Нарушение правил может повлечь за собой санкции, описанные там же — модератор

Спасибо. Можно кое-что уточнить?
У меня есть собственные CompletionRoutines. В этом случае сценарий подсчета ссылок будет таким:
1) Когда приходит IRP, счетчик EnterCount увеличивается.
2) И в completionroutine он уменьшается.

Правильно я понимаю?
Re[2]: File System Filter Unloading
От: Ivan Россия www.rsdn.ru
Дата: 05.12.07 09:23
Оценка: 6 (1) +2
Здравствуйте, Alter_, Вы писали:

A_>/*

A_>а это на всякий случай. Если система сильно нагружена,
A_>мы счетчик можем уже обнулить, а до RET не успеть дойти.
A_>*/
A_>Delay.QuadPart = -50*1000*1000; // 5 sec
A_>KeDelayExecutionThread(KernelMode, FALSE, &Delay);

я бы не стал использовать такой код в production драйвере — более правильный путь (как уже советовали) перейти на минифильтр, это не только решиит проблему выгрузки, но и значительно упростит логику драйвера.

по поводу задержки в 5 секунд — ответ на osronline разработчика filtermanager'а:
http://www.osronline.com/showThread.cfm?link=13281

In WindowsXP the IO Manager will not call a filters DriverUnload routine
until all of its DeviceObjects are at the top of their respective stacks
and there are no more references to them. The problem is that the IO
Manager does not keep track of what IRPs might be pending inside a given
file system stack.

The SFilter and FileSpy examples handle this in their DriverUnload
routines by pausing for 5 seconds after detaching all of their device
objects but before deleting them. This is a reasonable solution for a
filter under development when you want to quickly unload and reload a
new version of the driver. This works most of the time but if a test
machine crashes once in a while, so what; at least you don't have to
reboot every time you want to load a new version of your filter. This
is a totally unreasonable solution for a production filter.

Re: File System Filter Unloading
От: __Dee0  
Дата: 05.12.07 15:17
Оценка:
Большое спасибо. Разобрался.
Чисто технический вопрос можно?

В CompletionRountine приходит какая-то ересь... А именно FileInformationClass.
Кроме 0 и жутко огромных значений я не получал.

    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    if(    IrpSp->MajorFunction == IRP_MJ_DIRECTORY_CONTROL &&
        IrpSp->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
        KeGetCurrentIrql() == PASSIVE_LEVEL)
    {
        FILE_INFORMATION_CLASS FileInfoClass    = IrpSp->Parameters.QueryFile.FileInformationClass;
        DebugPrint("FileInfoClass: %x\n", FileInfoClass);
                ...


Re: File System Filter Unloading
От: Maxim S. Shatskih Россия  
Дата: 06.12.07 11:13
Оценка: +1
А>Подскажите, где грабли...

Везде. Невозможно 100% надежно удалить такой фильтр.

Filemon 100% надежным не является. Потому вопросы типа "код, основанный на filemon, иногда валится" не имеют ответа.

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

В качестве неотгружаемой части можно использовать готовый микрософтный fltmgr.sys, написав таким образом минифильтр. Вот они отгружаемы.
Занимайтесь LoveCraftом, а не WarCraftом!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.