Пожалуйста, обьясните мне зачем нужен CTL_CODE IOCTL_INTERNAL_I8042_HOOK_KEYBOARD и как его обрабатывать. На русском языке в инете я об этом не нашёл, а английского я не знаю. А спрашиваю я потому, что PS/2 клава ведёт себя как-то неадекватно, хотя USB клава с моим фильтром работает более менее нормально
и ещё вопрос такой: если заменить скан-код в полях makecode и flags в структуре KEYBOARD_INPUT_DATA на 0, хоть какая-то реакция винды будет или это эквивалентно как если фильтр вообще не пропустил бы этот callback дальше?
Найдите в интернете и скачайте книгу Уолтера Они "Использование Windows Driver Model". Там есть ответы на все ваши вопросы. Но Си все-таки придется выучить.
Плохо искали значит http://mirknig.com/knigi/programming/1181183378-ispolzovanie-microsoft-windows-driver-model.html
зато там есть про это Что касается таких специфичных тем как "нуль в makecode" то могу посоветовать ковырять исходники WDK и читать собственно WDK. Но тут без английского никак. Если вы принципиально учить английский не хотите, то забудьте про драйвера - русскоязычных источников практически нет. Лично я делал так - открывал WDK, открывал переводчик гугл и все непонятные мне слова переводил. И так до полного просветления. А вы как хотели, без труда, как говорится, и рыбки не пожрешь.
Извините, а в какой главе главе говорится о IOCTL_INTERNAL_I8042_HOOK_KEYBOARD? что-то я не могу найти
В главе номер 9 подробно рассказывается о макросе CTL_CODE, кодах ввода-вывода IOCTL_* и о том как они обрабатываются.
Ещё у меня такая проблема: мой фильтр принимает callback, обрабатывает его и отправляет дальше. Следом, при определённых условиях, он отправляет свой собственный callback, если он тут же принимает и отправляет новый callback, то он проходит раньше собственного, отправленного раньше. Я уж пробовал и так: Код (Text): kbproc proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG push eax push ecx push InputDataConsumed mov eax, pDeviceObject push InputDataEnd assume eax:ptr DEVICE_OBJECT mov ecx, [eax].DeviceExtension assume eax:nothing assume ecx:ptr FiDO_DEVICE_EXTENSION push InputDataStart push [ecx].UPPER_CONNECT_DATA.ClassDeviceObject call [ecx].UPPER_CONNECT_DATA.ClassService assume ecx:nothing pop ecx pop eax ret kbproc endp KKbFilter_ServiceCallback proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG local kInputDataEnd:PKEYBOARD_INPUT_DATA .if okk == 0 inc okk jmp nmm .endif invoke KeWaitForSingleObject, addr ikevent, Executive, KernelMode, FALSE, 0 nmm: .............................. Push ecx invoke KeInitializeEvent, addr ikevent, NotificationEvent, FALSE pop ecx .if remmm == 0 invoke kbproc, pDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed .endif invoke oszlp, pDeviceObject, kInputDataEnd; создает и отправляет собственный callback при определённых условиях invoke KeSetEvent, addr ikevent, IO_NO_INCREMENT, FALSE .............. ret KKbFilter_ServiceCallback endp и так: Код (Text): kbproc proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG push eax push ecx push InputDataConsumed mov eax, pDeviceObject push InputDataEnd assume eax:ptr DEVICE_OBJECT mov ecx, [eax].DeviceExtension assume eax:nothing assume ecx:ptr FiDO_DEVICE_EXTENSION push InputDataStart push [ecx].UPPER_CONNECT_DATA.ClassDeviceObject call [ecx].UPPER_CONNECT_DATA.ClassService assume ecx:nothing pop ecx pop eax ret kbproc endp kbproc proc pDeviceObject:PDEVICE_OBJECT, InputDataStart:PKEYBOARD_INPUT_DATA, InputDataEnd:PKEYBOARD_INPUT_DATA, InputDataConsumed:PULONG ........... lea eax, [ecx].g_EventSpinLock push ecx fastcall KfAcquireSpinLock, eax mov bl, al .if remmm == 0 invoke kbproc, pDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed .endif invoke oszlp, pDeviceObject, kInputDataEnd; создает и отправляет собственный callback при определённых условиях pop ecx lea eax, [ecx].g_EventSpinLock .if bl == DISPATCH_LEVEL fastcall KefReleaseSpinLockFromDpcLevel, eax .else and edx, 0FFh fastcall KfReleaseSpinLock, eax, edx .endif ret KKbFilter_ServiceCallback endp всё равно проходит вперед( Что посоветуете?
Llirik http://code.google.com/p/ngdbg/wiki/Intro Также для работы с клавиатурой осуществляется внутренний документированный перехват ISR клавиатуры с помощью i/o control code'а драйвера i8042 - IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. Он позволяет задать обработчик, который будет вызываться из ISR практически сразу после получения прерывания и это позволяет нам отреагировать на нажатие горячих клавиш, а так же следить за состояниями Num, Caps и Scroll lock в Windows. http://www.delphimaster.net/view/1-1180368669 Назначить обработчик на IRP_MJ_INTERNAL_DEVICE_CONTROL. в нем по приходу IOCTL_INTERNAL_KEYBOARD_CONNECT в IRP стеке придет структура CONNECT_DATA в (Parameters.DeviceIoControl.Type3InputBuffer), в ней переназначаешь ClassService на свой KeyboardClassServiceCallback вида VOID KeyboardClassServiceCallback ( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed );. После чего к тебе пойдет IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. Теперь в Type3InputBuffer будет идти структура INTERNAL_I8042_HOOK_KEYBOARD. Тебе нужно переопределить контекст устройства на свой и заменить InitializationRoutine (которе будет отвечать за инициализацию - что не обязательно, но вдруг тебе понадобится создавать выделять допбуффера или т.п.) и непосредственно IsrRoutine в который будут приходить данные. В DDK идет пример простого клавиатурного фильтра.
Блин, ну что за человек, в книге есть алгоритм - как обрабатывать подобные запросы. Вся специфическая информация есть в ДДК! То что вы не знаете английский - это ваша проблема, а не людей с этого форума! Миру в целом глубоко плевать на сей прискорбный факт!
Поясню свой вопрос. в KKbFilter_ServiceCallback состояние клавиши определяется проверкой на чётность члена структуры KEYBOARD_INPUT_DATA Flags. Если число чётное, то клавиша нажата, а если не чётное, то произошло её отпускание. В IsrRoutine же Flags не меняется и остаётся всегда чётным. Вот я и спрашиваю: как определить, что клавиша нажата или отпущена?