Запись/чтение данных с клавиатуры

Тема в разделе "WASM.NT.KERNEL", создана пользователем sja, 22 дек 2008.

  1. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    Всем доброго времени суток!

    Имеется программируемая клавиатура собственного производства.
    Необходимо организовать с ней обмен данными через порт ps/2.
    Посмотрев стандартный драйвер в ddk, я понял что не справится он с этой задачей, т.е. придется писать свой драйвер?
    я вижу такой путь:
    добавить IOCTL типа IOCTL_INTERNAL_I8042_CONTROLLER_WRITE_BUFFER, на чтение и запись непосредственно в контроллер в драйвер pnpi8042.
    И выставлять какой-то флаг для перехвата данных, или данные посылать с какого-то спец кода, которого нет в обмене ps/2.
    я в драйвера под windows еще юнец, скажите, туда ли я смотрю, или есть лучший путь ?
    заранее, спасибо.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    у контроллера 8042 есть команда записать байт в выходной буффер. тогда драйвер сможет его прочитать.
     
  3. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    я согласен с вами. и планировал это делать типа как _outp или WRITE_PORT_XXX, но для начала интересно где это делать :)
    в коде драйвера i8024.sys ? чтобы при приеме данных садиться на его прерывание, и при необходимости читать данные для себя?
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    есть хороший ioctl - IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. посмотри в его сторону. хук вызывается почти сразу из ISR и там можно сделать что угодно.
     
  5. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    а можно ли будет с его помощью читать/писать в порт 8042 байты данных, например 0x00, 0x01, 0xff (т.е. организовать полноценный обмен данными) ?
    т.е. это будет что-то типа фильтра между портом8042 и драйвером клавиатуры или я не правильно понимаю?
    если по записи в порт еще более-менее понятно - использование PI8042_ISR_WRITE_PORT callback, то по чтению с порта - пока не ясно вообще :dntknw: - или при чтении тоже вернется структура _INTERNAL_I8042_HOOK_KEYBOARD ?

    но по вашим словам я понимаю задача может быть решена с использованием стандартного драйвера?
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    я не разбирался с остальными полями структуры, потому как организовал свой минидрайвер 8042 ps/2, единственное для чего мне требуется стандартный - хук на ISR через IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. это я у себя в отладчике так сделал.
    вероятно, тебе будет вполне достаточно стандартного
     
  7. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    А этот IOCTL можно ли вызывать из user-mode ?
    Т.е. например, я из юзер моде вызываю такой IOCTL:
    Код (Text):
    1. DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_SET_INDICATORS, &OutputBuffer, DataLength, NULL, 0, &ReturnedLength, NULL))
    Т.е. вообще не влезая ни в какие драйвера, обойтись только user-mode ?
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Это internal device i/o control code. он обрабатывается там внутри по IRP_MJ_INTERNAL_DEVICE_CONTROL и может быть передан только драйвером драйверу через IoBuildDeviceIoControlRequest с параметром Internal = TRUE.
    Да и как ты себе представляешь ISR-хук в юзермоде? Который выполняется на DIRQL
     
  9. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    Уважаемый, Great!
    К сожалению, я пока и из kernel-mode не представляю :)

    Т.е. я понял, что я делаю "пустой" драйвер, в котором "регистрирую" этот хук, и работаю со своим драйвером, который будет отдавать мне все данные клавиатуры, и посылать ей мои данные.
    Теперь я правильно понял :) ?
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну.. вероятно.
     
  11. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    начитался книг, сделал около 300 BSOD и пришел пока к следующему:
    пока про запись в порт:
    у меня есть мой драйвер, в котором я делаю следующее в соем ioctl запросе:
    Код (Text):
    1. WRITE_PORT_UCHAR( KEYBOARD_PORT_60, 0x01);
    но в мою клавиатуру приходит почему-то 0xff (команда сброса), притом независимо от посылаемого значения.
    нюанс такой: моя клава не отвечает контроллеру никогда, никаких ACK, за что он, как я понимаю, выставляет recv timeout (bit 6, port 0x64 read).
    вопрос такой: при выполнении WRITE_PORT_UCHAR на порт 0x60 я пишу не сразу в клаву, а всё это проходит обработку контроллером сначала ? или я ошибаюсь?
    когда подключаю осциллограф - то тоже вижу что идет 0xff, хотя когда я подключаю осциллограф к клаве и шлю данные - он показывает что там не 0xff (более точно не показывает :dntknw: )

    но вот еще в одной книге нашел следующее:
    "Программно-вызываемое прерывание BIOS INT 16h... Функции задаются в регистре AH при вызове:
    AH = 00 - чтение и выборка слова из буфера
    ...
    AH = 05 - запись слова в буфер
    "
    Как этим воспользоваться, и вообще нужно ли мне это (в смысле пригодится ли) ?
    А также даны "ячейки BIOS DATA AREA" - там вообще я понимаю что адреса ( указатели на начало и конца буффера и на сам буффер).
    Может напрямую в буфер писать или лиху я заморачиваюсь?
    спасибо Great и katrus за ЦУ.
     
  12. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    sja
    По одной строчки не скажешь. Перед отправке данных нужно проверить чтобы входной буффер контроллера 8042 был пуст. А если отправлять в клавиатуру то и выходной. Порты 60h и 64h это порты контроллера 8042.
     
  13. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    Отлично, я проверяю готов ли контроллер к передаче данных по 1 биту статус - регистра (64h read).

    и всё еще не ясно:
    вопрос такой: при выполнении WRITE_PORT_UCHAR на порт 0x60 я пишу не сразу в клаву, а всё это проходит обработку контроллером сначала ? или я ошибаюсь?
     
  14. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    sja

    В начале данные попадает в входной буффер контроллера 8042. А он уже решает куда дальше. Если установлен флаг c/d (код/данные) то он воспринимает входной буфер как код. Если нет как данные. Флаг этот устанавливается если мы пишем через порт 64h если через 60h то не выставляется. После записи в входной буфер выставляется флаг входной буфер полон. Дальше из входного он может передать в выходной и отправить в клавиатуру.
    А может просто податься на порт выхода. А может попасть в системный регистр. Это определяет команда которая была подано до этого или неподана. Если не было команды то данные отправляются прямиком в клавиатуру.
     
  15. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    Pavia, спасибо. У меня было это на аглицком, но прочитав по-русски, я еще раз пересмотрел ман по ps/2, оказалась, что ошибка была в том (что 0xff всегда принимает) - надо было клоки клавой генерить - поправили передается доброе теперь.

    Теперь вопрос как ловить данные с клавы. я планирую использовать wxWidgets для GUI, т.е. у меня не будет доступа к очереди сообщений венды. Я понимаю best way (согласно совету Даоса Great) использовать IOCTL_INTERNAL_I8042_HOOK_KEYBOARD для ps/2?
    а как ловить данные с ps/2 и с usb клав отдельно ?
     
  16. sja

    sja New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2008
    Сообщения:
    15
    Great
    Большое спасибо за ссылку. Теперь хук подключается, и ловит скан-коды - просто чума!

    Теперь возникли следующие вопросы:
    1. Как ловить эти скан коды в моей app что в user-mode?
    Или чере ioctl каждые несколько миллисекунд проверять пришло-ли что-нибудь ?
    2. Проблема при выгрузке драйвера - как вернуть клаву обратно ? А то любую клавишу жму и BSOD...
    пробовал так:
    Код (Text):
    1. hookkbd.IsrRoutine = NULL;
    но если, туда я раньше что-то писал (всмысле callback на мою функцию), то это толку не приносит :dntknw: