Проблема с переопределением обработчика int 17h
Модератор: Andy
Проблема такова:
Все происходит в ДОС-сессии Windows'a 98.
Пусть имеется резидент, переопределяющай хэндлер прерывания 17h (печать через LPT порт) для вывода печатаемых данных в файл. Пусть также есть 2 варианта этого резидента - 1) старый хэндлер используется, т.е. осуществляется печать - для пользовательской проги, использующей int 17h резидент абсолютно прозрачен. 2) старый хэндлер не используется - прога думает, что напечатала, а на самом деле - нет.
Далее, пусть есть компьютер с одним свободным ЛПТ портом (в который ничего не воткнуто). БИОС по умолчанию присваивает ему адрем 3BCh (находится в 0040:0008). В этом случае резидент работает нормально: в случае 1) естественно все виснет, т.к. принтера нет. 2) пользовательская прога отрабатывает нормально, резидент пишет в файл данные.
Далее, подключаем принтер. БИОС присваивает ему адрес 378h
Здесь то и проблема:
В обоих случаях нормально производится печать, а установленный резидентом обработчик вообще не вызывается и как следствие, ничего в файл не записывается.
А в чистом ДОСе вообще все это виснет намертво.
Следственный эксперимент показал, что адрес обработчика устанавливается корректно, более того, на таймер вешается обработчик, который отслеживает изменение этого адреса, и, если он изменен, ставит его обратно.
Это вообще нормально ?? - в таблице указан адрес хэндлера, но при вызове прерывания он не отрабатывает, а печать производится так, как должна...
Все происходит в ДОС-сессии Windows'a 98.
Пусть имеется резидент, переопределяющай хэндлер прерывания 17h (печать через LPT порт) для вывода печатаемых данных в файл. Пусть также есть 2 варианта этого резидента - 1) старый хэндлер используется, т.е. осуществляется печать - для пользовательской проги, использующей int 17h резидент абсолютно прозрачен. 2) старый хэндлер не используется - прога думает, что напечатала, а на самом деле - нет.
Далее, пусть есть компьютер с одним свободным ЛПТ портом (в который ничего не воткнуто). БИОС по умолчанию присваивает ему адрем 3BCh (находится в 0040:0008). В этом случае резидент работает нормально: в случае 1) естественно все виснет, т.к. принтера нет. 2) пользовательская прога отрабатывает нормально, резидент пишет в файл данные.
Далее, подключаем принтер. БИОС присваивает ему адрес 378h
Здесь то и проблема:
В обоих случаях нормально производится печать, а установленный резидентом обработчик вообще не вызывается и как следствие, ничего в файл не записывается.
А в чистом ДОСе вообще все это виснет намертво.
Следственный эксперимент показал, что адрес обработчика устанавливается корректно, более того, на таймер вешается обработчик, который отслеживает изменение этого адреса, и, если он изменен, ставит его обратно.
Это вообще нормально ?? - в таблице указан адрес хэндлера, но при вызове прерывания он не отрабатывает, а печать производится так, как должна...
Неа, не нормально :-)RG писал(а):Это вообще нормально ?? - в таблице указан адрес хэндлера, но при вызове прерывания он не отрабатывает, а печать производится так, как должна...
Если обработчик установлен, но не получает управление - значит печать производится как-то по-другому.В обоих случаях нормально производится печать, а установленный резидентом обработчик вообще не вызывается и как следствие, ничего в файл не записывается.
*provided AS IS
2 mm: Это был риторический вопрос
))
2 Andy: Это, конечно, вполне логично, я в общем-то так и думал. Тогда, каким образом Ось перехватывает прерывание и можно ли этому помешать?...

2 Andy: Это, конечно, вполне логично, я в общем-то так и думал. Тогда, каким образом Ось перехватывает прерывание и можно ли этому помешать?...
RG, не все программы работают с принтером через int 17h. Ось его (прерывание int 17h) не перехватывает. Я уверен, что это прерывание даже не происходит. Скорее всего та самая прога выводит на печать через порты. http://electronics.org.ua/techinfo/lpt/p1_5.htm - тут можешь почитать про это дело. Так что int 17h не единственный способ для печати.
*provided AS IS
2 Andy: Полностью с тобой согласен! Только один нюанс - эту прогу (которая печатает) тоже я писал
, в целях эксперимента, и естественно, через int 17h. Так что, вопрос остается в силе.
А то что ось НЕ перехватывает int 17h - уже ценная информация - спасибо!!
Дело в том, что этот резидент, о котором идет речь, должен отработать один единственный раз и абсолютно безотказно. Кстати, насчет портов, я пробовал сделать такой же резидент, перехватывающий int 0Fh (IRQ 7), который генерируется портом при понижении сигнала 'Ack'. Насколько я понимаю, только что переданный байт в этот момент еще остается в силе и его можно получить, прочитав с базового регистра порта. Правда такой вариант тоже оказался неудачным... Может механизм (описаный выше) неправильный ??? И еще, хотелось бы узнать, если пользоваться дополнительными регистрами EPP (на уровне портов), возможно ли вообще, таким же образом перехватить данные??

А то что ось НЕ перехватывает int 17h - уже ценная информация - спасибо!!
Дело в том, что этот резидент, о котором идет речь, должен отработать один единственный раз и абсолютно безотказно. Кстати, насчет портов, я пробовал сделать такой же резидент, перехватывающий int 0Fh (IRQ 7), который генерируется портом при понижении сигнала 'Ack'. Насколько я понимаю, только что переданный байт в этот момент еще остается в силе и его можно получить, прочитав с базового регистра порта. Правда такой вариант тоже оказался неудачным... Может механизм (описаный выше) неправильный ??? И еще, хотелось бы узнать, если пользоваться дополнительными регистрами EPP (на уровне портов), возможно ли вообще, таким же образом перехватить данные??
RG, http://electronics.org.ua/techinfo/lpt/lpt.htm - это рекомендую прочитать для общего развития. А перехватывать данные с портов как-то умеют...
Хм... Интересно получается - прерывание перехвачено, прерывание точно происходит, обработчик не вызывается...
Есть один простой способ попытаться разобраться. Запускаешь резидент, он перехватит int 17h и останется в памяти. Дале в проге, которая осуществляет печать в самом начале вместо вызова int 17h вставляешь следующий кусок кода: 1) получение адреса обработчика (можно из таблицы прерываний) 2) pushf/call dword ptr int17_handler (тобишь эмулируешь прерывание). Пошагово прогоняешь это в Turbo Debuger'е и смотришь после call ... куда ты попал - твой резидент или еще что-то.
Тут даже не вопрос в портах, проблема куда более бытовая на мой взгляд, - не вызывается обработчик.
Хм... Интересно получается - прерывание перехвачено, прерывание точно происходит, обработчик не вызывается...
Есть один простой способ попытаться разобраться. Запускаешь резидент, он перехватит int 17h и останется в памяти. Дале в проге, которая осуществляет печать в самом начале вместо вызова int 17h вставляешь следующий кусок кода: 1) получение адреса обработчика (можно из таблицы прерываний) 2) pushf/call dword ptr int17_handler (тобишь эмулируешь прерывание). Пошагово прогоняешь это в Turbo Debuger'е и смотришь после call ... куда ты попал - твой резидент или еще что-то.
Тут даже не вопрос в портах, проблема куда более бытовая на мой взгляд, - не вызывается обработчик.

*provided AS IS
Странное дело - перетащил принтер на другой комп, где стоит WinXP и... все оно работает.......
Может есть какие-то особенности работы с int 17h из-под win98 ??
А "эмуляцию" прерывания пока не пробовал. Но, надеюсь, это должно пролить свет на проблему.
Кстати, Andy, а нет ли у тебя случайно ссылочки на действительно полезную информацию по работе с портами напрямую и перехвате вводимых и выводимых данных с порта? заранее благодарен
Спасибо за уделенное внимание!
Может есть какие-то особенности работы с int 17h из-под win98 ??
А "эмуляцию" прерывания пока не пробовал. Но, надеюсь, это должно пролить свет на проблему.
Кстати, Andy, а нет ли у тебя случайно ссылочки на действительно полезную информацию по работе с портами напрямую и перехвате вводимых и выводимых данных с порта? заранее благодарен

Действительно полезной информации мало. По каждым конкретным портам (video/hdd и т.п.) надо искать информацию отдельно. Вобщем неплохо расписана работа с портами различными портами на базовом уровне в книге (как это не странно, есть еще хорошие книги!) Зубкова "Ассемблер для DOS, Windows и Unix". А так я пользуюсь инфой из разных источников...действительно полезную информацию по работе с портами напрямую
Этого нет. Сам бы почитали перехвате вводимых и выводимых данных с порта

Не думаю. Но интересно! Я бы любопытства ради во-первых протрессил прерывание (как я говорил) на том компе, во-вторых нашел бы еще один комп с 98-й и попробовал прогу там. Сомнительно что дело в 98-й, но все же...Странное дело - перетащил принтер на другой комп, где стоит WinXP и... все оно работает.......
Может есть какие-то особенности работы с int 17h из-под win98 ??
*provided AS IS