Перехват Ctrl+Alt+Delete в DOS

Тема в разделе "WASM.BEGINNERS", создана пользователем bers, 17 сен 2006.

  1. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Привет всем.
    Тут такое дело - нужно перехватить Ctrl+Alt+Delete и запросить подтверждение на перезагрузку. Пробовал перехватавать int 19h - не работает почему-то, все перепроверил. Перехватываю int 9h - ловиться-то ловится, но вот при вызове внутри своего обработчика какого-либо другого прерывания (как call-ом, так и int-ом) начинаются какие-то непонятные зависания. Тестирую все это под Dos-ом на VMWare, так как Винда очень недоверчива к подобной комбинации. Посмотрите, плиз, код и укажите ошибки.
    Код (Text):
    1. .286
    2. CSEG segment
    3.   assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
    4.   org 100h
    5. start:
    6.       jmp Init
    7.  
    8. int9 proc
    9.       pusha
    10.       in al, 60h
    11.       cmp al, 53h
    12.       je @1
    13. @2:
    14.       popa
    15.       jmp DWORD PTR cs:[ Old9 ]
    16. @1:
    17.       push ds
    18.       push 0h
    19.       pop ds
    20.       mov si, 417h
    21.       mov ax, WORD PTR [si]
    22.       pop ds
    23.       and ax, 0Ch
    24.       cmp ax, 0Ch
    25.       jne @2
    26.  
    27. _exit:
    28.       mov ah, 09h                     ;
    29.       mov dx, cs                      ;
    30.       mov ds, dx                      ;
    31.       mov dx, offset mes              ;
    32.       pushf                           ;
    33.       call DWORD PTR cs:[Old21]       ; после этого int 21h - зависание
    34.  
    35.       mov al, 20h
    36.       out 20h, al
    37.  
    38.       popa
    39.       iret
    40.  
    41.       mes   db 'C+A+D', 0dh, 0ah, '$'
    42.       Old21 dd 0
    43.       Old9  dd 0
    44. int9 endp
    45.  
    46. Init:
    47.       mov ax, 3509h
    48.       int 21h
    49.       mov WORD PTR [Old9], bx
    50.       mov WORD PTR [Old9 + 2], es
    51.        mov dx, cs
    52.        mov ds, dx
    53.       mov dx, offset int9
    54.       mov ax, 2509h
    55.       int 21h
    56.  
    57.       mov ax, 3521h
    58.       int 21h
    59.       mov WORD PTR [Old21], bx
    60.       mov WORD PTR [Old21 + 2], es
    61.  
    62.       mov dx, offset Init
    63.       int 27h
    64.  
    65. CSEG ends
    66.  
    67. end start
     
  2. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    А может надо просто вызвать
    int 21h
    без заморочек с захватыванием вектора.
     
  3. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Ну так я же вектор int 21h и не захватываю - даже если и так написать, то ничего хорошего не получится...
     
  4. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    bers
    Ты его читаешь, а потом вызываешь через
    pushf
    call DWORD PTR cs:[Old21]

    Попробуй просто
    int 21h
     
  5. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Уже пробовал )) А вообще, мне что-то кажется, что это Варины штучки, потому что подобные исходники, валяющиеся в сети так же себя ведут, то есть виснут. Почитав Зубкова, увидел что он там еще переключает клаву в конце своего обработчика. Попробовал - не работает... ))
     
  6. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    bers
    Я про ДОС уже забываю, потихоньку. Придется поднять старые архивы. В понедельник может что-то подскажу...
     
  7. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Спасибо
     
  8. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    внутри досявого обработчика поменьше мути с перехватом и вызовом, в мсдос есть проблема с реентерабельностью. даже и не вспомню щас чо там было то .....
     
  9. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    CARDINAL
    Да, похоже надо выставить соответствующий флажок.
     
  10. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    bers
    Вот нашел фрагмент старой игрушки (обработчик 9-го прерывания)

    Код (Text):
    1. Int9        proc    far
    2.         push    ax
    3.         push    cx
    4.         push    di
    5.         push    es
    6.                 in  al, 60h
    7.         mov ah, al
    8.         in  al, 61h
    9.         or  al, 80h
    10.         out 61h, al
    11.         and al, 7Fh
    12.         out 61h, al
    13.         mov al, ah
    14.         cbw
    15.         and al, 7Fh
    16.         mov es, cs:DATSEG
    17.         mov di, Offset es:KBDKEYS
    18.         mov cx, es:[di-2]
    19.         repne   scasb
    20.         sub di, (Offset es:KBDKEYS)+1
    21.         shl di, 1
    22.         jmp es:KBDPROC[di]
    23.  
    24. EscKey:     mov es:QUIT, 1
    25.         jmp short KBDRet
    26. FireKey:    xor ah, FIRE
    27.         jmp short SetKEY
    28. UpKey:      xor ah, UP
    29.         jmp short SetKEY
    30. LeftKey:    xor ah, LEFT
    31.         jmp short SetKEY
    32. RightKey:   xor ah, RIGHT
    33.         jmp short SetKEY
    34. DownKey:    xor ah, DOWN
    35. SetKEY:     and ah, ah
    36.         jns Pressed
    37.         and es:FLAGS, ah
    38.         jmp short SetSCAN
    39. Pressed:    or  es:FLAGS, ah
    40. SetSCAN:        mov es:SCAN, 0
    41.         and ah, ah
    42.         js  KBDRet
    43.         mov es:SCAN, al
    44. KBDRet:     pop es
    45.         mov al, 20h
    46.         out 20h, al
    47.         pop di
    48.         pop cx
    49.         pop ax
    50.         iret
    51. Int9        endp
     
  11. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    CARDINAL правильно сказал - из обработчиков типа int 9 нельзя вызывать функции DOS... точнее, можно - но нужно проверять так называемый флаг занятости DOS (прочесть можно у Зубкова СВ). Еще есть такой прикол как текущий видеорежим. А что если я из игры Lines нажму три клавиши ? ;)
     
  12. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    т.н. InDOS флажок
     
  13. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Самое интересное то, что если я, скажем, вывожу строку на экран 9-ой функцией int 21h, то оно выводится, но потом зависание не заставляет себя ждать )). Насчет флажка я уже говорил, что пробовал это в 3-ем посте, но все равно не пашет. Насчет нежелательного вызова прерываний внутри обработчика - понимаю, и даже сам, когда начинал писать эту хрень по нескольку раз обдумывал это действие (давно пробовал программить под Dos, потом стал писать под Винду), но с другой стороны, а что если надо будет сделать в обработчике что-нибудь более серьезное, когда без прерываний не обойтись? И вообще, ведь любой обработчик - это обычная функция, которую я вызываю по всем правилам. Не понимаю, где здесь загвоздка - кто может, объясните, плиз.
     
  14. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    сделай простейшую синхронизацию, вызывать int 21h из обработчика IRQ -- это моветон.
    Например, раздели код на "safe"- и "unsafe"-части (как красиво пишут в книжках). Unsafe -- как у тебя в обработчике int 9, т.е. дос потенциально может быть в нереентрантном состоянии. Safe -- места (точнее моменты), где ДОС можно вызывать.
    int9 получает управление, проверяет клавиши да флаги, если да -- маякует "safe"-части (если InDOS=1), мол, работай, ниггер -- выставляет флажок, который проверяется в 'безопасных' местах -- например, собственно в перехваченном int 21h или при обнаружении InDOS=0 в перехваченном int8.

    вдогонку:
    Код (Text):
    1. INT 21 34-- - DOS 2+ - GET ADDRESS OF INDOS FLAG
    2.  
    3. Category: D - DOS kernel
    4.  
    5. Inp.:
    6.     AH = 34h
    7. Return: ES:BX -> one-byte InDOS flag
    8. Notes:  this function executes on the DOS stack, and thus cannot be called
    9.       while another DOS function is already executing; you should use
    10.       this function once at the beginning of the program and store the
    11.       returned pointer rather than calling it when requiring DOS access
    12.     the value of InDOS is incremented whenever an INT 21 function begins
    13.       and decremented whenever one completes
    14.     during an INT 28 call, it is safe to call some INT 21 functions even
    15.       though InDOS may be 01h instead of zero
    16.     InDOS alone is not sufficient for determining when it is safe to
    17.       enter DOS, as the critical error handling decrements InDOS and
    18.       increments the critical error flag for the duration of the critical
    19.       error.  Thus, it is possible for InDOS to be zero even if DOS is
    20.       busy.
    21.     SMARTDRV 4.0 sets the InDOS flag while flushing its buffers to disk,
    22.       then zeros it on completion
    23.     the critical error flag is the byte immediately following InDOS in
    24.       DOS 2.x, and the byte BEFORE the InDOS flag in DOS 3.0+ and
    25.       DR DOS 3.41+ (except COMPAQ DOS 3.0, where the critical error flag
    26.       is located 1AAh bytes BEFORE the critical section flag)
    27.     for DOS 3.1+, an undocumented call exists to get the address of the
    28.       critical error flag (see AX=5D06h)
    29.     this function was undocumented prior to the release of DOS 5.0.
    30. SeeAlso: AX=5D06h,AX=5D0Bh,INT 15/AX=DE1Fh,INT 28
    31. INT 21
     
  15. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    _BC_
    Собственно так и сделано в приведенном мною обработчике. Флаги выставляются в "безопасной" области и проверяются в главном цикле программы.
     
  16. bers

    bers New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2005
    Сообщения:
    139
    Адрес:
    Russia
    Интересно, что простой вывод строки 40h-ой функцией проходит на ура, 9h-ой же вызывает подвисон.