Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Драйвер связывает Приложение с клавиатурой напрямую ?  (Прочитано 44048 раз)
0 Пользователей и 1 Гость смотрят эту тему.
buisyhanh
Постоялец

vn
Offline Offline

« : 06-09-2008 17:21 » 

Я хочу написать драйвер, который передает сразу данные с клавиатуры в Приложение.
Как я понял, что нужно:
- Перехватит данные, вводимые с клавиатуры с помобщью драйвера.
- Передать эти данные сразу (realtime) в Приложение.

Используемык функции наверно:
 -HalBeginSystemInterrupt, HalEndSystemInterrupt, HalGetInterruptVector, KeInsertQueueDpc, KeInitializeDpc, ObReferenceObjectByHandle,  ObfDereferenceObject, KeClearEvent, KeSetEvent.
 
 Но я не знаю как реализовать этот драйвер.
 Подскажите как мне надо делать, чтобы написать такой тип драйрер.
 
« Последнее редактирование: 12-09-2008 21:58 от Ochkarik » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 06-09-2008 17:43 » 

а обязательно драйвер ? Глобальный клаво-хук не подойдёт ? )
Записан

Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 06-09-2008 20:51 » 

для начала DDK. установить, почитать.
там кстати и примеры есть.
взять понравившийся пример и попробовать скомпилить.
в частности тебе нужен драйвер-фильтр. там точно был пример клавиатурного дарйвера и точнно был пример драйвера-фильтра... а вот вместе - не помню. под рукой DDK нет.
DDK рекомендую из KMDF брать.

PS и осторожнее со словом realtime;)
да, и в общем то зачем сразу драйвер? типа это круто?)))
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 06-09-2008 22:29 » 

kbfiltr
из DDK.
все уже давно ЕСТЬ!
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #4 : 07-09-2008 10:44 » 

Спасибо всем за рекоментдование !
 Но дело у меня такое:
 У меня есть некое Source Code и в котором нехватает имено *.sys файл и у меня тоже есть откомпилорованный этот драйвер, но сам проект для него нету. Я диассемблировал этого драйвера и получил такой код как описанно в прикрепленном файле, в котором я видел, что использовали такие функции как: HalBeginSystemInterrupt, HalEndSystemInterrupt, HalGetInterruptVector, KeInsertQueueDpc, KeInitializeDpc, ObReferenceObjectByHandle,  ObfDereferenceObject, KeClearEvent, KeSetEvent,
 что связанно с прерыванием и обработки DPC. А фильтр так не делает.
 Я тоже изучил DDK, разные книги, но для реализации имено такого драйвера еще не знаю как.
 Что мне делать ?

* Disass_psmkb2k.txt (75.55 Кб - загружено 1008 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 07-09-2008 12:49 » 

смотря что вам надо?)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #6 : 08-09-2008 01:32 » 

Тут я хотел перенаправить данные, поступаемые с клавиатуры в мою программу, что другая программа не может получить доступ к клаве пока моя программа еще находиться в активном состоянии. Т.е Хук нельзя залезит в поток данных.
 Кто - то почитал прикрепленный код ?.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 08-09-2008 03:44 » 

buisyhanh, что-то твой файл хреново выглядит. Unicode вроде, но через с строчку - мусор.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #8 : 08-09-2008 04:40 » 

Цитата
Тут я хотел перенаправить данные, поступаемые с клавиатуры в мою программу, что другая программа не может получить доступ к клаве пока моя программа еще находиться в активном состоянии. Т.е Хук нельзя залезит в поток данных.
Хмм... Если перехваченные данные с клавиатуры твоя прога не должна передавать пока не обработает, то тут без разницы драйвер или хук - все равно будет тормозить (в случае длительной обработки). Ну а если вышеописанное условие не нужно, то обработку данных можно делать в отдельном потоке, вызывая его из хуковой процедуры.
Записан
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #9 : 08-09-2008 07:48 » 

Извините всем, те кто скачал прикрепленный тест файл. Да - Мусорб Я дам *.pdf файл вам.

Хмм... Если перехваченные данные с клавиатуры твоя прога не должна передавать пока не обработает, то тут без разницы драйвер или хук - все равно будет тормозить (в случае длительной обработки). Ну а если вышеописанное условие не нужно, то обработку данных можно делать в отдельном потоке, вызывая его из хуковой процедуры.

  Тут в драйвер используют Isr routine, как я изучил код ассемблера. И видно что сразу обрабатываются данные, набираемые на клаве в приложение.
 
 
Записан
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #10 : 08-09-2008 07:54 » 

Вот тут польный диассемберный код моего драйвера.
Как понимаю, что в нем использовал ISR for keyboard  и данные, набираемые с клавы как-то отправить через DeviceIoControl buffer к приложению. Но задержки не были. Как только вводить сразу появить символы.
 Вы кто - то может пояснить ?

* DisFullPsmkbd2k.pdf (114.85 Кб - загружено 1117 раз.)
Записан
sss
Специалист

ru
Offline Offline

« Ответ #11 : 08-09-2008 08:15 » 

Пипец, почему не машинный код?

Что значит - как-то отправить? DPC или WorkItem не подойдут ? Или отправлять сразу с повышенных IRQL, что бы realtime был?

Записан

while (8==8)
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 08-09-2008 10:09 » 

buisyhanh, не будет там никакой задержки. на любой реализации что через фильтр, что через ISR.
потому что 1-10мс вы глазами не заметите.

была бы мышь - тогда понятно... там опрос и до килогерца может быть... а тут... ну 10 Гц... ну 30... навряд ли больше.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #13 : 08-09-2008 10:52 » 

Да использовали DPC для прерывания, и заменили ISR для клавы на DPC для Клавы. я изучил код программы и некоторые примеры в Инете видел, что в замене ISR использовли DPC когда происходит прерывание клавы. Но как-то в драйвере обрабатываются данные, чтобы могли передать их в output buffer нашей программы. После чего мы можем обрабатывать как хотим. Видно с моего кода, будет простая обработка в драйвере и в программе, так как сразу появляются на экране набираемые символы.
 У кого есть примера для такого типа драйвера или кто-то мог бы по просту дать мне обьяснение прикрепленного кода?.
 С благодарностью.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 08-09-2008 13:53 » 

Да использовали DPC для прерывания, и заменили ISR для клавы на DPC для Клавы.
- извините, не понятно что имелось в виду. попробуйте построить фразу иначе.

я изучил код программы и некоторые примеры в Инете видел, что в замене ISR использовли DPC когда происходит прерывание клавы.
- аналогично.

Но как-то в драйвере обрабатываются данные, чтобы могли передать их в output buffer нашей программы. После чего мы можем обрабатывать как хотим.
- ЧТО ВЫ ИМЕЛИ В ВИДУ?

Видно с моего кода, будет простая обработка в драйвере и в программе, так как сразу появляются на экране набираемые символы.
 У кого есть примера для такого типа драйвера или кто-то мог бы по просту дать мне обьяснение прикрепленного кода?.
 С благодарностью.
- к сожалению подробный разбор дизасемблированного листинга требует много времени. и честно говоря не очень интересно.
если в кратце, то судя по наличию комадны iret он должен модифицировать IDT и подставлять свой обработчик прерывания. впрочем могу ошибаться. в какой последовательности он действует дальше - разбираться долго.

- примеры есть в DDK. есть пример работы с PS/2 портом: pnpi8042.
есть примеры драйвера фильтра. есть

PS я так понял, что русский не ваш родной язык?
может быть проще будет если вы напишете вопросы на английском?
« Последнее редактирование: 08-09-2008 13:58 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 08-09-2008 14:00 » 

PS я так понял, что русский не ваш родной язык?
может быть проще будет если вы напишете вопросы на английском?
IP записан за Вьетнамом.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #16 : 08-09-2008 15:58 » 

Да, русский - не мой родной язык, причем уже три года не говорил по нему. Но извините меня за не внимательностью когда я выразил свои смысли в русском. Я живу во Вьетнаме.
 Спасибо всем за хорощие ответы.
 Я имел ввилу, что для обработки прерывания клавиатуры в драйвере используется вместо ISR (Interrupt Service Routine) Рутин подобного типа  DPC (Deffered Procedure Call).
 И как Ochkarik написал правильно. Я изучил код одного драйыера, в котором есть замена обработчика прерывания клавиатуры на определяемый программистом обработчик прерывания. Здесь использовали фунцию HalGetInterruptVector для модификации IDT.
MappedIrqKeyboard = HalGetInterruptVector(Internal,0,KEYBOARD_IRQ,0,&DirqlKeyboard,&Affinity);
 Как я понял, что нужно написать свой обработчик прерывания. Но еще не знаю, как указать на этот обработчик в драйвере.
Пипец, почему не машинный код?

Что значит - как-то отправить? DPC или WorkItem не подойдут ? Или отправлять сразу с повышенных IRQL, что бы realtime был?


 И наверно sss вы поняли как делать ?.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 08-09-2008 16:16 » 

http://chpie.tistory.com/attachment/dk1.pdf
к сожалению не знаю на каком языке, но по теме.

http://coding.derkeiler.com/pdf/Archive/Assembler/comp.lang.asm.x86/2005-11/msg00311.pdf
- тоже по теме. на английском.

просмотрите данные ссылки по поиску:
http://www.google.ru/search?complete=1&hl=ru&rls=GGLG%2CGGLG%3A2005-41%2CGGLG%3Aru&q=HalGetInterruptVector+keyboard&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=&aq=f&oq=
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #18 : 08-09-2008 17:10 » 

http://chpie.tistory.com/attachment/dk1.pdf
к сожалению не знаю на каком языке, но по теме.

http://coding.derkeiler.com/pdf/Archive/Assembler/comp.lang.asm.x86/2005-11/msg00311.pdf
- тоже по теме. на английском.

просмотрите данные ссылки по поиску:
http://www.google.ru/search?complete=1&hl=ru&rls=GGLG%2CGGLG%3A2005-41%2CGGLG%3Aru&q=HalGetInterruptVector+keyboard&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=&aq=f&oq=
- Первый на кореанском языке, я скачал и смотрел его.
 Спасибо Ochkarik.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #19 : 09-09-2008 01:23 » 

buisyhanh, извините конечно, но меня обескураживают фразы типа "использовали вместо ISR DPC". Как можно вообще такое применить? Вам необходимо засунуть (IoConnectInterrupt) свою подпрограмму ISR в цепочку обработчиков прерывания. Затем, когда будет вызвана Ваша ISR, внутри этой подпрограммы Вы "намечаете" (IoRequestDPC, DpcForIsr) DPC. DPC это опять же подпрограмма в Вашем драйвере, которая будет повторно вызвана системой, но уже на пониженном уровне прерывания. Почему нужно DPC? Например: при передаче сигнала приложению об готовности буферов, как правило, драйвер устанавливает в сигнальное состояние (KeSetEvent) один из объектов синхронизации системы (событие например). На повышенных IRQL вызывать такие функции как KeSetEvent нельзя. А если говорить об прямой передаче буфера приложению? Возможно конечно, закрепив общий участок памяти. Но это плохо. Потому что тогда приложение должно постоянно проверять изменения в буфере, загружая процессор.
Записан

while (8==8)
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 09-09-2008 07:56 » 

sss,
А если говорить об прямой передаче буфера приложению? Возможно конечно, закрепив общий участок памяти. Но это плохо. Потому что тогда приложение должно постоянно проверять изменения в буфере, загружая процессор.
- обычно синхронизируется собятием или APC.
- либо для скорости и потоковой обработки дважды: событие + счетчик изменений.
- либо на отложенных запросах Read/IOCTL.

а насчет остального:
ISR (и соответственно IoConnectInterrupt)- не используется. вместо нее - переписывается вектор IDT.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sss
Специалист

ru
Offline Offline

« Ответ #21 : 09-09-2008 08:43 » 

Ochkarik, я и не спорю. Но переписывать вектор IDT это грубо слишком. А как потом вызывать предыдущий обработчик, если он как "честная Маша" присоединялся к цепочки с помощью IoConnectInterrupt ?
Записан

while (8==8)
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 09-09-2008 08:47 » 

sss, что значит как? - как обычно. перез заменой вектора запомнить старое значение, и вызвать после себя. впрочем не знаю как там буфер клавиатуры себя поведет при двойном считывании... если это вообще требуется.

PS да вообще какое то решение ломовое...
вполне подошел бы стандартный драйвер фильтр - он в примерах есть. всем условиям он отвечает. интерфейс привести только в соответствие.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sss
Специалист

ru
Offline Offline

« Ответ #23 : 09-09-2008 09:00 » 

Ochkarik, понял, понял. Скорее всего там (в IDT) вызов менеджера обработчиков ISR.
Я просто подумал, как узнать контекст предыдущей ISR? Потом понял - там не сама ISR, а прыжок на код обработки списков ISR. В принципе нормально тогда... Только замес с чтением контроллера.
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #24 : 09-09-2008 10:05 » 

buisyhanh, извините конечно, но меня обескураживают фразы типа "использовали вместо ISR DPC". Как можно вообще такое применить? Вам необходимо засунуть (IoConnectInterrupt) свою подпрограмму ISR в цепочку обработчиков прерывания. Затем, когда будет вызвана Ваша ISR, внутри этой подпрограммы Вы "намечаете" (IoRequestDPC, DpcForIsr) DPC. DPC это опять же подпрограмма в Вашем драйвере, которая будет повторно вызвана системой, но уже на пониженном уровне прерывания. Почему нужно DPC? Например: при передаче сигнала приложению об готовности буферов, как правило, драйвер устанавливает в сигнальное состояние (KeSetEvent) один из объектов синхронизации системы (событие например). На повышенных IRQL вызывать такие функции как KeSetEvent нельзя. А если говорить об прямой передаче буфера приложению? Возможно конечно, закрепив общий участок памяти. Но это плохо. Потому что тогда приложение должно постоянно проверять изменения в буфере, загружая процессор.
Тут понял по принципу, но я смотрел на прикрепленный диассемблерный код драйвера, то видно не использовали IoConnectInterrupt(...) фунции. Как по документу Microsoft:
 http://technet.microsoft.com/en-us/sysinternals/bb963898.aspx
То испольлзовали в драйвере другие функции типа:KiDispatchInterrupt(...).
 А  в Undocumented NT еще использовали KiUnexpectedInterrupt(...) и поведение этой функции похоже на то, что в диассемблерном коде.
 На счет проверка буффера не нужно бы,вместо этого использовали обьект синхронизации (с использованием функции CreateEvent) и передать его  HANDLE к драйверу (by DeviceIoControl(...)). В драйвере мы будем установить состояние этото обьекта после DPC (обработка прерывания  - передача данной с клавы в буффер). А приложение после регистрации изменения состояния обьекта синхронизации будет посылать новый DeviceIoControl (...,IOCTL_GET_BUFFER,0,0,Outputbuffer, OuputLength, pReturned,NULL) к драйверу для получения данной буффера и опять изменить состояние обьекта синхронизации.
 По этой логике, то нужно как-то получить данные с клавиатуры. Но с использованием каких-то структура, переменной или функции я еще не знаю.
 
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 09-09-2008 15:01 » 

buisyhanh,
вам надо написать идентичный драйвер?
или надо повторить интерфейс драйвера?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #26 : 10-09-2008 02:48 » 

buisyhanh,
вам надо написать идентичный драйвер?
или надо повторить интерфейс драйвера?
Мне надо написать специальное драйвер для связи клавиатуры с моим приложением без помощи драйверов системы как 8042prt.sys, kbdclass.sys. И в драйвер напишу просто как захватчик вводимые информации с клавиатуры и передать его приложению - Т.е отдельный канал передачи данных.
 Это похоже на Keylogger, но в режиме ядра. И для регистрации в системе такого типа драйвера нужно получить соглащение Microsoft.
Записан
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #27 : 10-09-2008 02:53 » 

buisyhanh,
вам надо написать идентичный драйвер?
или надо повторить интерфейс драйвера?
Мне надо написать специальное драйвер для связи клавиатуры с моим приложением без помощи драйверов системы как 8042prt.sys, kbdclass.sys. И в драйвер напишу просто как захватчик вводимые информации с клавиатуры и передать его приложению - Т.е отдельный канал передачи данных.
 Это похоже на Keylogger, но в режиме ядра. И для регистрации в системе такого типа драйвера нужно получить соглащение Microsoft.
Извините меня за не грамотный тест.

Мне надо написать специальный драйвер для связи клавиатуры с моим приложением,но без помощи драйверов системы как 8042prt.sys, kbdclass.sys. И в драйвере напишу просто захватчик вводимых информаций с клавиатуры и передать его приложению - Т.е отдельный канал передачи данных.
 Это же похоже на Keylogger, но в режиме ядра. И для регистрации в системе такого типа драйвера нужно получить соглащение Microsoft.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #28 : 10-09-2008 03:22 » 

ОК buisyhanh. Для начала все таки ответь - установлен ли DDK и Visual C? Есть рабочий скелет простого legacy драйвера?
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #29 : 10-09-2008 07:48 » 

 Есть у меня все исходные коды DDK и VC. Но не знаю какие из них брать. Дело только не в выборе, а то что как видно то код моего драйвера должен очень короткий и быстро работает без задержки. 
 Как видели в диассемблерном коде, то как-то очень коротко написали драйвер и он эффективно работает. Так как он только созает Обьект и перехвает данные (char or int ) и передает в приложению.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #30 : 10-09-2008 08:04 » 

buisyhanh, пишите с нуля. Итак - есть скелет драйвера, с кодом обработки кодов от DeviceIoControl?
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #31 : 10-09-2008 08:32 » 

Есть у меня все в руках, коды всякие DeviceIoControl, Drivers DDK, SDK. Но для написания еще наверно недостачное знание обо Kernel mode программировании. Читал - читаю но еще не нашел то, что нужно.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #32 : 11-09-2008 08:54 » 

buisyhanh, я покопался в дизассемблированном примере. в общем отстой. Пример использует устаревшие функции IoQueryDeviceDescription, HalGetInterruptVector и я не могу понять чего они передают. Причем нигде не видно перезаписи вектора прерывания клавиатуры напрямую. Похоже на то, что пример не так прост и работает не заменой вентиля в IDT, а поиском (IoQueryDeviceDescription) контроллеров определенного типа, вызывает для них HalGetInterruptVector и что то делает с ними.
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #33 : 12-09-2008 16:30 » 


- к сожалению подробный разбор дизасемблированного листинга требует много времени. и честно говоря не очень интересно.
если в кратце, то судя по наличию комадны iret он должен модифицировать IDT и подставлять свой обработчик прерывания. впрочем могу ошибаться. в какой последовательности он действует дальше - разбираться долго.
[/quote]
 Тут же сказали что будет модификация IDT, и по моему правильно. И IoQueryDeviceDescription просто получает информацию о неком устройстве, HalGetInterruptVector -  получает вектор указанного в параметре типа прерывания. Мне интересно там есть HalBegin and HalEndSystemInterrupt, что могут использовали для изменения хода прерывания.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #34 : 12-09-2008 19:23 » 

HalBeginSystemInterrupt и HalEndSystemInterrupt
- если не ошибаюсь, эти функции устанавливают IRQL==DIRQL. А после обработки восстанавливают предшествующий IRQL.
побробнее об этом(с разбором асемблерного кода функций):
http://ext2fsd.sourceforge.net/documents/irql.htm

и пару слов на microsoft: http://technet.microsoft.com/en-us/sysinternals/bb963898.aspx

PS на китайском)
 http://www.inkings.cn/blog/?p=1052

PPS кстати первая ссылка - очень интересно. сам буду изучать))) а то у меня с матчастью плохо)
« Последнее редактирование: 12-09-2008 19:32 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #35 : 14-09-2008 13:03 » 

Видно,что параметр ULONG Vector функции HalBeginSystemInterrupt (KIRQL Irql, ULONG Vector, PKIRQL OldIrql) дольно представить какой - то Vector прерывания. Причем по назнванию функции, то будет происходить какое - то прерывание. А сам вектор прерывания при этом указывается в ULONG Vector. Результат прерывания возвращается как 0 или 1.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #36 : 15-09-2008 00:51 » 

buisyhanh, IoQueryDeviceDescription в принципе корневая функция. Ищет ресурс прерывания для контроллера (клавиатуры?). Интересно, с USB клавиатурой будет работать?  Вот этот Vector ей и находиться. А про HalBeginSystemInterrupt вообще ничего документированного. Что это? Пролог ISR?
Записан

while (8==8)
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #37 : 15-09-2008 15:21 » 

buisyhanh,
Нет, сама функция HalBeginSystemInterrupt - не генерирует прерываний! Она маскирует прерывания через APIC.
И устанавливает в системе новый IRQL. Это необходимо для синхронизации работы "одновременно" пришедших разных прерываний с разными приоритетами (с разными IRQL).
А так же для корректного выполнения некоторых системных функций. В случае если они будут вызваны в обработчике ISR.

PS судя по первому взгляду на ссылку выше.

sss, с USB не должно... там механизм несколько другой, формат другой. по тем же прерываниям много чего валится. с USB надо через HID. либо через фильтр клавиатурный - тогда будет универсально...
« Последнее редактирование: 15-09-2008 15:32 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #38 : 16-09-2008 07:46 » 

buisyhanh,
Нет, сама функция HalBeginSystemInterrupt - не генерирует прерываний! Она маскирует прерывания через APIC.
И устанавливает в системе новый IRQL. Это необходимо для синхронизации работы "одновременно" пришедших разных прерываний с разными приоритетами (с разными IRQL).
А так же для корректного выполнения некоторых системных функций. В случае если они будут вызваны в обработчике ISR.
Таким образом, наверно написанный уменя драйвер имеет мехнизм для обработки прерывания следующий:

 - Имеется при прерывании ISR and DPC (здесь использовали HalGetInterruptVector), В ISR будет вызваться DPC(KeInitializeDpc, KeInsertQueueDPC), в этом же DPC будет как-то передать KEYBOARD_INPUT_DATA в буффер (Irp->AssociatedIrp.SystemBuffer;), предназначенный для Приложения .
 -  Использовали HalBeginSystemInterrupt для повышения IRQL данного конкретного ISR(DPC). Т.е и DPC будет выпольнятся первым перед других  возможных DPC (так как символы сразу появятся на экране при нажатии клавищ).
 - После обработки DPC нужно уменьшить IRQL ниже предоставляя процессор другим DPC использованием: HalEndSystemInterrupt.
 - В завершении DPC нужно установить событие синхронизации (KesetEvent) информируя Приложению обо наличии данных в Irp->AssociatedIrp.SystemBuffer и можно их забрать.
 
 Но уменя тут же возникается вопрос как можно получать KEYBOARD_INPUT_DATA с вводимым данными. Эти данные автоматически где - то хранятся или сам напишем обработчик для них. Но если будет обработчик  - то он должен не короткий и как реализовать его. Видно, что мой драйвер как - то получает эти данные и передать их в буффер без серезьной обработки.
 
Записан
sss
Специалист

ru
Offline Offline

« Ответ #39 : 17-09-2008 05:52 » 

buisyhanh Вы когда нибудь писали драйвера ?  В ISR не будет вызваться DPC.  DPC никогда не вызываются напрямую, по определению. И никогда не выполниться на повышенных IRQL.

Насчет KEYBOARD_INPUT_DATA. Основная подпрограмма чтения байта буфера клавиатуры и возврат его на место SUB_L0001038E.

Использует:
  SUB_L00010377 - Ожидание опустошения буфера
  SUB_L00010382 - Ожидание заполнения буфера

Всего лишь проанализируйте логику подпрограммы.

Вот ссылка http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kcc60 для анализа работы с клавиатурными портами.

Ochkarik, вроде будет работать с USB. Не уверен однако.
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #40 : 17-09-2008 08:49 » 

buisyhanh Вы когда нибудь писали драйвера ?  В ISR не будет вызваться DPC.  DPC никогда не вызываются напрямую, по определению. И никогда не выполниться на повышенных IRQL.
  Наверно мне там в тексте не хватает слово: РУТИН, т.е DPC - Routine. Извините меня из - за этого.
  Нужно в ISR написать KeInsertQueueDPC и тогда будет отложить обработку прерывания на нижный IRQL.

  На счет INPUT_DATA  для разных устройств, например для LPT(COM) порт использовали макроопределением типа:  READ_PORT_UCHAR( pDeviceExtension->portBase + STATUS_REG ), которое выдается HAL  определением.
 Помоему для KEYBOARD также существуют разные макроопределения для обработки вводимой информации.
 Но какие я еще не знаю.
Записан
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #41 : 17-09-2008 08:56 » 

Насчет KEYBOARD_INPUT_DATA. Основная подпрограмма чтения байта буфера клавиатуры и возврат его на место SUB_L0001038E.

Использует:
  SUB_L00010377 - Ожидание опустошения буфера
  SUB_L00010382 - Ожидание заполнения буфера
Спасибо sss

 Тут же в ассемблере - да, но как в С этот реализован, какие команды ?. Дела в том, что мне не сильно разбираться в ассемблере. Нужно найти логику написания драйвера и переписать заново в С. Основный подход реализации драйвера понятно, сейчас я должен реализовать драйвер частями.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #42 : 18-09-2008 01:42 » 

buisyhanh. Я расскажу как вижу работу такого драйвера.

1. Происходит прерывание.
2. Вызывается ISR.
3. ISR читает байт буфера клавиатуры в буфер драйвера.
4. Ставит в очередь DPC.
5. Блокирует прерывания для клавиатуры.
6. Записывает байт обратно в буфер клавиатуры
7. Разрешает прерывания для клавиатуры.
8. Вызывает предыдущий обработчик.
9. После понижения IRQL вызывается DPC.
10. В DPC устанавливается событие "буфер готов".
11. Приложение в usermode реагирует на событие  и вызывает DeviceIoControl для чтения буфера.
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #43 : 18-09-2008 02:23 » 

buisyhanh. Я расскажу как вижу работу такого драйвера.

1. Происходит прерывание.
2. Вызывается ISR.
3. ISR читает байт буфера клавиатуры в буфер драйвера.
4. Ставит в очередь DPC.
5. Блокирует прерывания для клавиатуры.
6. Записывает байт обратно в буфер клавиатуры
7. Разрешает прерывания для клавиатуры.
8. Вызывает предыдущий обработчик.
9. После понижения IRQL вызывается DPC.
10. В DPC устанавливается событие "буфер готов".
11. Приложение в usermode реагирует на событие  и вызывает DeviceIoControl для чтения буфера.

 Отлично, sss Вы очень сильно разбираете в ассемблере. Спасибо большое.

 Как по этой списке, я предлагаю такой код сооветственно:

 В DriverEntry напишу: После создания Обьекта устройства.

  - Ставить код HalgetInterruptVector(...) для получения адрес вектор прерывания клавиатуры, после чего использовать IoConnectInterrupt(...) для регистрации ISR для данного прерывания и дальше:

 1. Происходить прерывание от клавиатуры.
 2. Вызывается ISR, в котором имеется фунция KeInsertQueueDPC
 3. ISR читает байт буффера порта 0х60
 4. Ставит в очередь DPC.
 5. Блокирует прерывания для клавиатуры. - Но не знаю зачем блокировать прерывания клавиатуры, и как в С реализовать, видно что нет такой функции в диассемблерном коде.
 6. Обратная запись в буффер клавиатуры - наверно это и есть байт состояния, информируя о завершении обработки, точно в буффер или в другой порт.
 7. Разрешает прерывания, какие функции не знаю, и не вижу таких там же в коде.
 8. Вызывает предыдущий обработчик. - Наверно где - то должно сохранить предыдущий обработчик, как вызывать ?
 9. DPC автоматически вызывается при понижении IRQL.
 10. В DPC устанавливается событие "буфер готов". - Тут иформируют Приложению - пользователя о готовность данной для вывода (KeSetEvent).
 11. Приложение в usermode реагирует на событие  и вызывает DeviceIoControl для чтения буфера. DeviceIoControl (...GET_BUFFER,...,OutputBuffer,size(),...);

 Как вы думаете в этой процедуре?.

 - Тут у меня тоже возникают некоторые вопросы:
    + Обратная запись байта в буффер клавиатуры - это и есть байт состояния или нет, какой был? Или использовали для     блокировки прерывания.
    + Разблокировать прерывание - как реализовать и после чего вызывается уже сохраненный где-то предыдущий обработчик.
    + Может быть при написании драйвера использовали и ассемблер и С.
 
Записан
sss
Специалист

ru
Offline Offline

« Ответ #44 : 18-09-2008 08:00 » 

buisyhanh, из DriverEntry вызывается SUB_L00010D14, где готовиться вызов
IoQueryDeviceDescription.

Код:

SUB_L00010D14:
push ebp
mov ebp,esp
       
        ...

L00010D3D:
push esi // Context (NULL)
push ebx // CalloutRoutine
push esi // PeripheralNumber  (NULL)
push esi // PeripheralType  (NULL)
push esi // ControllerNumber   (NULL)
lea eax,[ebp-04h]    // eax = &[ebp-04h]
push esi                // ControllerType  (NULL)
push eax // BusNumber 
lea eax,[ebp-0Ch] //&[ebp-0Ch]
push eax                // BusType
call edi

Что приводит к вызову CalloutRoutine ( L00010D8A), которая после проверки неких условий вызывает и выборов параметров вызывает HalgetInterruptVector. Я еще раз повторю у меня нет описаний этих функций. Поэтому дальше только можно гадать, но я предполагаю что там выясняется только адрес следующего обработчика. Переписывание таблицы векторов происходит в SUB_L000106E2 в районе метки L000106FA:
Код:
	call jmp_ntoskrnl.exe!KeGetCurrentThread
push 00000001h
mov cl,bl
pop edx
shl edx,cl
push edx
push eax
call jmp_ntoskrnl.exe!KeSetAffinityThread
sidt [L000111F0_IdtTable]
mov eax,[L00010F68]
mov eax,[eax+02h]
cli
mov edx,[L00010F60]
mov ecx,esi
mov [eax+edx*8],cx
mov ecx,[L00010F60]
mov [eax+ecx*8+06h],di
sti

Причем вызов запрятан на вызов таймера, созданного в DriverEntry. Тот, если активирован кодом 0x830020EC в обработчике L000109C8(IoControlDispatcher), постоянно проверяет, установлен ли перехватчик и если чего переустанавливает. Там же в подпрограмме таймера идет и некая проверка постановка DPC.

Цитата: MSDN
A driver’s IoTimer routine is called once per second after the driver enables the timer by calling IoStartTimer.


P.S.: Я не знаю buisyhanh в чем мне помочь Вам разобраться? Нужен скелет драйвера? Присоединяю... И еще, я на работе и дома работаю над своими проектами, поэтому извините не могу тратить много времени.

* 0002.rar (4.14 Кб - загружено 808 раз.)
Записан

while (8==8)
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #45 : 18-09-2008 08:40 » 

P.S.: Я не знаю buisyhanh в чем мне помочь Вам разобраться? Нужен скелет драйвера? Присоединяю... И еще, я на работе и дома работаю над своими проектами, поэтому извините не могу тратить много времени.
Вы очень меня помогли, большое вам спасибо. Если вы сильно занятен, то занимайтесть своими делами. Если когда нибудь у вас будет свободное время, то заходите к мне в форуме. Отставьте мне ценные замечания, я вам очень блогадарю.
 Тут я буду постепенно разбирать проект, хотя трудно, но результативно.
 Если что обращайтесь к мне, хорошо?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #46 : 18-09-2008 08:58 » 

OK
Записан

while (8==8)
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines