Перехват данных PS/2 порта

Тема в разделе "WASM.NT.KERNEL", создана пользователем SlyBit, 21 май 2009.

  1. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    Всем привет!
    Необходимо получать все данные с PS/2 порта, но без использования драйвер фильтра. Пробовал хукать IRP_MJ_* драйвера i8042prt, только никаких irp там не обнаружил.
    Сейчас разбираюсь с чтением данных из порта. Тут несколько ключевых вопросов. По возникновению какого прерывания считывать данные из портов и из каких именно? Может есть другие способы перехвата инфы порта.
    Спасибо.
     
  2. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Почему же без фильтра?

    Не i8042prt, а kbdclass.

    Не занимайся хернёй, драйвер-фильтр класса Keyboard - вот что тебе нужно.
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    SlyBit
    IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
    Operation
    The IOCTL_INTERNAL_I8042_HOOK_KEYBOARD request adds the following callback routines to I8042prt's operation:

    An optional initialization callback that I8042prt calls when it initializes a keyboard
    An optional callback into the I8042prt keyboard ISR

    Пример как юзать - в моем отладчике:
    http://code.google.com/p/ngdbg/source/browse/trunk/8042/8042.cpp#719
     
  4. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    А если клавиатура подключена через USB?
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    x64
    читаем название топика
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Вероятно, автор не знает, что существуют другие способы подключения клавиатур. А что ты предлагаешь - не есть правильно. Модель WDM предусматривает классовые драйвера-фильтры, в данном случае это класс Keyboard, к которому следует прицепиться как upper filter. Пример см. в исходниках ctrl2cap от Sysinternals (смотрим внимательно, потому что сам исходник ещё времён NT4 и некоторые базовые вещи теперь делаются по-другому, но сам принцип фильтрации реализован правильно).
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    x64
    Ну оно то конечно так. Но если автору нужно именно PS/2 то этот вариант подходит больше, если нужно именно на низком уровне подключаться. А классовые фильтры это, конечно, хорошо.
    Так что надо спрашивать автора - ему нужен именно PS/2 или вообще клавиатуры любые.
     
  8. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    Спасибо за советы. Нужно перехватывать данные любого устройства, подключаемого к PS/2 порту (мышь, клавиатура и т.д.). Желательно без перезагрузки компьютера после инсталляции драйвера.
     
  9. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    Хукаю прерывание клавиатуры IRQ 1. В моём обработчике прерывания читаю байт из порта PS/2, сохраняю его и затем записываю назад в порт. Проблема заключается в том, что после записи байта в порт опять срабатываем моё прерывание и происходит зацикливание. Есть идеи как можно решить эту проблему?

    Код (Text):
    1. VOID WINAPI KbdInterruptHook()
    2. {
    3.     UCHAR btData = 0;
    4.  
    5.     btData = READ_PORT_UCHAR(KEYBOARD_PORT_60);
    6.    
    7.     // save btData
    8.  
    9.     WRITE_PORT_UCHAR(KEYBOARD_PORT_64, 0xD2);
    10.     WaitForKeyboard();
    11.     WRITE_PORT_UCHAR(KEYBOARD_PORT_60, btData);
    12. }
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Есть, не надо записывать его назад. Надо использовать другую команду PS/2 контроллера,там есть какая-то типа "записать выходной порт" которая не генерит прерывания.
     
  11. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    нужно отключить генерацию прерывания от клавиатуры/мыши при готовности данных в буффере контроллера
    а после включить

    но на деле чет получается фигня какая-то

    Great
    можно код команды?
    что-то не вижу такой в спецификации

    вот например команды которые я определил у себя
    какая-то из них?

    Код (Text):
    1. typedef enum _I8042_COMMAND
    2. {
    3.     I8042CMD_READ_CMDBYTE           = 0x20,
    4.     I8042CMD_WRITE_CMDBYTE          = 0x60, // :: struct _I8042_COMMAND_60_REG
    5.     I8042CMD_AUX_INTERFACE_DISABLE  = 0xA7,
    6.     I8042CMD_AUX_INTERFACE_ENABLE   = 0xA8,
    7.     I8042CMD_AUX_INTERFACE_TEST     = 0xA9,
    8.     I8042CMD_CONTROLLER_SELFTEST    = 0xAA,
    9.     I8042CMD_KBD_INTERFACE_TEST     = 0xAB,
    10.     I8042CMD_KBD_INTERFACE_DISABLE  = 0xAD,
    11.     I8042CMD_KBD_INTERFACE_ENABLE   = 0xAE,
    12.     I8042CMD_QUERY_VERSION          = 0xAF,
    13.     I8042CMD_READ_INPUT_PORT        = 0xC0,
    14.     I8042CMD_POLL_INPUT_PORT_LOW    = 0xC1,
    15.     I8042CMD_POLL_INPUT_PORT_HIGH   = 0xC2,
    16.     I8042CMD_READ_OUTPUT_PORT       = 0xD0,
    17.     I8042CMD_WRITE_OUTPUT_PORT      = 0xD1,
    18.     I8042CMD_WRITE_KBD_OUTPUT_BUFFER= 0xD2,
    19.     I8042CMD_WRITE_AUX_OUTPUT_BUFFER= 0xD3,
    20.     I8042CMD_WRITE_AUX              = 0xD4,
    21.     I8042CMD_READ_TEST_INPUTS       = 0xE0,
    22.     I8042CMD_SET_LEDS_STATE = 0xED,
    23.     I8042CMD_ECHO_DIAGNOSTICS       = 0xEE,
    24.     I8042CMD_CHANGE_WORK_MODE       = 0xF0,
    25.     I8042CMD_QUERY_ID_CODES         = 0xF2,
    26.     I8042CMD_SET_AUTOREPEAT_PARAMS  = 0xF3,
    27.     I8042CMD_ENABLE_DATAFLOW        = 0xF4,
    28.     I8042CM_DEFAULTS_DISABLE_POLLING= 0xF5,
    29.     I8042CMD_DEFAULTS               = 0xF6,
    30.     I8042CMD_ENABLE_AUTOREPEAT      = 0xF7,
    31.     I8042CMD_PRESS_RELEASE_ENABLE   = 0xF8,
    32.     I8042CMD_PRESS_ONLY_ENABLE      = 0xF9,
    33.     I8042CMD_ENABLE_ALL             = 0xFA,
    34.     I8042CMD_AUTOREPEAT_DIRECT      = 0xFB,
    35.     I8042CMD_PRESS_DIRECT           = 0xFC,
    36.     I8042CMD_PRESS_RELEASE_DIRECT   = 0xFD,
    37.     I8042CMD_REPEAT_TRANSMISSION    = 0xFE,
    38.     I8042CMD_RESET                  = 0xFF
    39. }I8042_COMMAND;
     
  12. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    либо замаскировать irq1/irq12 в ioapic
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А вот, вспомнил, можно так: там есть команды disable/enable keyboard, disable/enable mouse.

    Код (Text):
    1.     //
    2.     // Write scan-code back to i8042 controller.
    3.     // Controller will write it to output port
    4.     //
    5.    
    6.     // Temporarily disable keyboard & mouse
    7.     I8xPutBytePolled (CommandPort,
    8.         ControllerDevice,
    9.         FALSE,
    10.         (UCHAR) I8042_DISABLE_KEYBOARD
    11.         );
    12.     I8xPutBytePolled (CommandPort,
    13.         ControllerDevice,
    14.         FALSE,
    15.         (UCHAR) I8042_DISABLE_MOUSE
    16.         );
    17.  
    18.     I8xPutBytePolled (CommandPort,
    19.         ControllerDevice,
    20.         FALSE,
    21.         (UCHAR)I8042_WRITE_OUTPUT_REGISTER);
    22.  
    23.     I8xPutBytePolled (DataPort,
    24.         ControllerDevice,
    25.         FALSE,
    26.         ScanCode);
    27.  
    28.     // Enable keyboard & mouse
    29.     I8xPutBytePolled (CommandPort,
    30.         ControllerDevice,
    31.         FALSE,
    32.         (UCHAR) I8042_ENABLE_KEYBOARD
    33.         );
    34.     I8xPutBytePolled (CommandPort,
    35.         ControllerDevice,
    36.         FALSE,
    37.         (UCHAR) I8042_ENABLE_MOUSE
    38.         );
    Вроде работало у меня (насколько я помню, писалось год назад...)

    Еще нашел команду клавиатуры (не контроллера, а клавиатуры)
    #define KBD_RESEND 0xFE
    Судя по всему, запрашивает повторную отсылку последнего скан-кода (я уже не помню пробовал ли я ее, или нет, но вроде работало...)

    А вообще, я остановился на IOCTL_INTERNAL_I8042_HOOK_KEYBOARD - для моих целей отладчика это подходило
     
  14. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    странно
    вроде как команды отключения устройств используются для того чтобы можно было считать данные от контроллера, при передаче ему команды, возвращающей результат
    после передачи контроллеру команд 0xD2/0xD3 и данных, произойдет прерывание от соответствующего устройства если оно не маскировано
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну этот алгоритм я гдето взял. да и не помню работает или нет. давно было-\
     
  16. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    вобщем если вдруг кому это интересно было
    то рабочее решение для фильтрации до оригинальной ISR
    может иметь следующий вид

     
  17. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    а какой это бит?
     
  18. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
     
  19. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    ну и 2й
    (без редактирования что-то совсем плохо)