Как грамотно организовать выборку из KM ?
От: Аноним  
Дата: 30.10.07 15:24
Оценка:
Здравствуйте!
Помогите, пожалуйста, найти грамотное решение вот такой задачки.

Есть файловый фильтр, осуществляющий фильтрацию IRP_MJ_CREATE.
Этот фильтр на основе тех или иных критериев должен сделать одно из следующего:

  • Разрешить операцию, т.е. просто переслать запрос ниже.
  • Запретить операцию, т.е. завершить запрос с соответствующим статусом.
  • Спросить у пользователя "что делать с этим запросом?".

    Вот сейчас думаю как грамотно реализовать третий пункт?
    Придумалось пока вот что:

    1. Драйвер создаёт именованное событие через IoCreateNotificationEvent() с именем что-то типа \??\EventName. Юзермодное приложение открывает это событие через OpenEvent().
    2. Драйвер создаёт внутренний список (очередь FIFO) pending-запросов.
    3. Для всех поступающих IRP, соответствующих определённым критериям, драйвер делает следующее:
    3.1. Создаёт примерно такую структуру:

    typedef struct _REQUEST_ENTRY
    {
      KEVENT Event;
      PIRP Irp;
      ULONG UserAction;
    }
    REQUEST_ENTRY, *PREQUEST_ENTRY;


    3.2. Ставит её во внутреннюю очередь.
    3.3. Ставит глобальное событие \??\EventName в состояние signaled.
    3.4. Входит в ожидание события REQUEST_ENTRY.Event через KeWaitForSingleObject().
    4. Приложение получает уведомление о событии \??\EventName через WaitForSingleObject().
    5. По получении уведомления приложение шлёт что-то типа IOCTL_QUERY_REQUEST_DATA драйверу.
    6. Драйвер заполняет буфер приложения данными по первому запросу в очереди (в том числе передаёт и указатель на IRP) и завершает запрос IOCTL_QUERY_REQUEST_DATA.
    7. Приложение отображает пользователю окно с данными запроса (например, имя файла) и пользователь жмёт, например, либо "Разрешить" либо "Запретить".
    8. Приложение шлёт драйверу что-то типа IOCTL_RESOLVE_REQUEST вот с такой примерно структурой:

    typedef struct _RESOLVE_ENTRY
    {
      PIRP Irp;
      ULONG UserAction;
    }
    RESOLVE_ENTRY, *PRESOLVE_ENTRY;


    9. Драйвер по получении IOCTL_RESOLVE_REQUEST делает следующее:
    9.1. Прочёсывает всю свою внутреннюю очередь и ищет в ней указанный IRP по указателю RESOLVE_ENTRY.Irp.
    9.2. Если нашёл — ставит поле REQUEST_ENTRY.UserAction в значение RESOLVE_ENTRY.UserAction.
    9.3. Ставит событие REQUEST_ENTRY.Event в состояние signaled.
    10. Далее запрос IRP_MJ_CREATE, который заснул в ожидании события REQUEST_ENTRY.Event, просыпается и происходит следующее:
    10.1. Считывается значения поля REQUEST_ENTRY.UserAction и запоминается в локальной переменной.
    10.2. REQUEST_ENTRY удаляется из внутреней очереди и уничтожается.
    10.3. Выполняется выбранное пользователем действие.

    Вот так, что-то вроде того .

    Просьба к гуру: прокомментируйте, пожалуйста, мои мысли.
    Насколько приведённый алгоритм грамотен?
    Какие могут быть подводные камни?
    Как можно сделать безопаснее / красивее / эффективнее?

    Спасибо!
  •  
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.