Потеря событий пр ипередаче из драйвера в ring3.

Тема в разделе "WASM.NT.KERNEL", создана пользователем souzz, 4 сен 2006.

  1. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Собсно есть драйвер и user-mode приложение.

    Драйвер сообщает приложению через shared KEvent
    Код (Text):
    1. ...
    2. //собственно само событие,
    3.         hEvent = (HANDLE) irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
    4.         status = ObReferenceObjectByHandle(
    5.                 hEvent,
    6.                 GENERIC_ALL,
    7.                 NULL,
    8.                 KernelMode,
    9.                 &gpEventObject,
    10.                 &objHandleInfo);
    11.  
    12. ...
    13. //сигнал приложению о готовности данных
    14. KeSetEvent(gpEventObject,0, FALSE);
    в данном случае , при быстром обмене часть сообщений ring3 APP просто не получает.

    т.е. используется для сигнализации
    //IOCTL with METHOD_NEITHER
    DeviceIoControl(hdrive, TL_CODE(FILE_DEVICE_COMM_DRIVER,IO_REFERENCE_EVENT,3,0),
    pointer(m_hCommEvent), 0, nil, 0, dwBytesReturned, nil);

    для передачи данных использую METHOD_BUFFERED
    Проблема в том, что DbgPrint кажет ВСЕ посылки в ring3,
    следующая за ним строка SetEvent() посылает уведомления приложению, но до приложения доходят не все посылки....

    Что может быть?
    Подозреваю что нужно дождаться отлупа от приложение по обработке отправленного события, но как это сделать, затрудняюсь.

    Спасибо.

    В чем может быть трабла?
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Событие не накапливает информацию о том, сколько раз его просигналили. Поэтому единственное, что может узнать юзер-мода, так это то, что событие в данный конкретный момент находиться в сигнальном/несигнальном состоянии. Отсюда и твои пропуски. Обычно сигнал события означает для юзер-моды, что у драйвера имеются некие данные для него. По сигналу юзер дает драйверу буфер, а драйвер складывает в него всё, что у него есть на данный момент, пока хватит буфера.
     
  3. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Вот именно, приложение используй METHOD_NEITHER ждет перевода в сигнальное состояние. И, по-моему, не всегода его отлавливает. Т.е. задача в том, чтобы отловить ВСЕ изменения события.
    Я по-моему так и делаю.
    При переходе себытия в сигнальное положение, user-mode приложение отправляет драйверу запрос DeviceIOControl() на чтение данных из буфера и очищает событие.

    Проблема в том что не все переходы в сигнальное положение "видит" приложение.
    Может быть дело в типе события? Я использую тип NotificationEvent. Может быть стоит попробовать Synchronization?

    Грубо говоря, на 4 сигнализации, от user-mode приложения приходит только 1 запрос на чтение. Рассинхронизация?
     
  4. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В данном случае метод не имеет никакого значения.

    Это невозможно сделать, используя одно только событие. Если только завести доп. счетчик.

    Так да не так. Ты расчитываешь на прямое соответствие KeSetEvent - DeviceIoControl. Но это работать не будет. Тебе нужен один DeviceIoControl, который забирает всё, что имеется на данный момент у драйвера сколько бы раз он не сигналил событие.

    Нет. Это ничего не даст.

    Повторяю - событие не накапливает информацию о том, сколько раз его просигналили. Допустим ты дождался обвобождения события на WaitForSingleObject и начинаешь что-то делать: вызывать DeviceIoControl, обрабатывать полученные данные и т.п. Но пока ты это делаешь, твой поток может быть сколько угодно раз прерван. Драйвер может сколько угодно раз вызвать KeSetEvent. Это весьма вероятно даже на однопроцессорной машине, не говоря уже о мультипроцессорах. И когда ты завершишь один цикл обработки полученных данных, то снова вернёшься к WaitForSingleObject. Ну и как ты узнаешь сколько раз за это время событие было просигналено?

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

    Теперь понятно?
     
  5. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Спасибо, как раз синхронно с твоим ответом додумался сделать счетчик входящих и внутренний буфер в драйвере. Теперь приложение вычитывает буфер, независимо от попадания в него новых событий с данными.
    Еще раз благодарю:)