Такая вот вещь понадобилась: прога под DOS. надо нажатые клавиши записывать в файлик - следить так сказать, чего люди нажимают. Я перехватываю прерывание BIOS, выполняю сачала его, а потом записываю нажатую клавишу. Но программа ведёт себя очень странно: под NC работает нормально, под VC: (Volkov Commander) вешается VC при попытке просмотреть какой-либо файл, а из DOS Navigatora вообще запускаться нехотит - сразу виснет Navigator
Как ты записываешь данные в файл ? Контролируешь ли флаг занятости ДОС (int 28h) ? Вообще код приведи...
ChelL Ну так в ДОС в файлы не всегда можно записывать. Особенно в программах обработки прерываний. Обычно скидывают все в память и в фоне пишут в файл.
_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]
А, я понял ! Ты возвращаешься из перехватчика iret, а надо - retf 2 или как-то иначе флаги сохранять.
valterg была такая идея... " и в фоне пишут в файл" в смысле в фоне? прогу не делать резидентной а запустиь цикл и раз в секунду проверять? а как прогу на секунду остановить?
_Chingachguk_ pushf я делаю для call dword ptr cs:int16h_oldhandl. А он вроде сам из стека удаляет флаги... или нет?
Ёиоу ! Смотри: pushf call dword ptr Old_Handler ; Сейчас флаг ZF вернулся из int 16h оригинального ... ; cmp или любые другие команды - портят его ! ... iret ; Вообще выталкивает флаги из стека retf 2 ; Возвращает уже совсем другие флаги...
так... что то не пойму я... то есть мне надо ещё раз после 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 так надо сделать?
так... что то не пойму я... то есть мне надо ещё раз после 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 так надо сделать?
Ну типа того. Тока вложение другое. push ds push es ... pushf call dword ptr OldHandler pushf ... ; do everything popf pop es pop ds retf 2
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 лучше не прерывать во время выполнения-оно нереентабильно.
ChelL Нельзя в программе обработки прерываний писать в файл. Ты должен только писать в буфер и каким-то образом организовать фоновый процесс ( в ДОС-е вроде INT 2F этим заправляет), который будет это делать. Проверить, что дело именно в записи легко. На время убери его и проверь.
Спасибо всем за советы - извините что с опозданием - приболел тут немного... Zombyte - спасибо, вставил и такую проверку. Valterg - да я и сам понимаю что плохо так делать, но просто оно и так вроде работает. Только почему-то оно работает только по VC, NC, или DOS Navigator. При вызове из чистого DOS - клавиши не перехватывает, и когда программу одну (есть тут нужная прога - из за неё весь сыр-бор и начался - надо узнать - что там операторы нажимают при работе с прогой) загружаеш - тоже - то что нажимается в программе не перехватывается. Почему? Что перехватить надо, что бы узнать?
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.
А если так сделать: перехватить 9 прерывание и заносить клавиши в буфер. Перехватить прерывание таймера и в нём записывать файл?