Discussion:
Keyboard input in native app
(too old to reply)
Michael H___
2016-12-05 17:04:59 UTC
Permalink
I hope, this is the correct group. Please excuse, if not...
Anyway, here is my problem:

I am writing a native app (running at boot time, ie. from BootExec) for WinXP. I am reading keyboard input as follows:

Getting keyboard handles:
- I try to open devices with NtOpenFile for \\Device\\KeyboardClass%i, with %i from 0-31. (I use ACCESS_MASK including SYNCHRONIZE, ie. asynchronous read.)
- I store each successfully opened handle in an array. I ignore all others.

Reading:
- I loop through the handle array. For each handle I call NtReadFile (I am not using events).
- When the loop is finished, I wait for multiple objects (all the keyboard handles, WaitAny, no timeout).
- When a key is pressed, NtWaitForMultipleObjects returns with the index of the signaled handle (I presume).

This all works well. The hardware is as follows:
I have one physical PS/2 keyboard attached. In the Registry I see in 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\kbdclass\Enum' the name '0' with value 'Root\RDP_KBD\0000' and the name '1' with value 'ACPI\PNP0303\4&1d401fb5&0'.
I think the former is the Terminal Service Virtual Keyboard, and the latter is the physical PS/2 keyboard.
Indeed, I get valid handles for 'KeyboardClass0' and 'KeyboardClass1'.

Now comes the strange part:
Everytime I get a scancode from the NtReadFile, it comes from device #0 (the virtual keyboard). Not from the physical keyboard, as I would expect.

Can someone explain why?

kind regards,
Mike
Michael H___
2016-12-06 10:33:24 UTC
Permalink
A follow up (just in case someone has the same problem):

As it turned out, the keyboard that signaled my NtWaitForMultipleObjects was the physical device alright. It came with return value 0 (corresponding to \Device\KeyboardClass0), but still this is the ACPI-keyboard, despite it is enumed as '1' in ...\Services\kbdclass.

The background why I even bothered was, that I failed to set the indicator LEDs. But this had an entirely different reason. My call to NtDeviceIoControlFile(IOCTL_KEYBOARD_SET_INDICATORS, bla bla) always failed with STATUS_INVALID_PARAMETER. I was setting the KEYBOARD_INDICATOR_PARAMETERS.LedFlags to KEYBOARD_NUM_LOCK_ON and the like (#defined in winddk.h), which I found on Google in a hundred code examples. As it turned out, these are completely the wrong flags. They should be 0x01, 0x02 and 0x04 for SCROLL, NUM, CAPS respectively (#defined nowhere). With these flags, the DeviceIoControl call returns ok.
Roberta Bahr
2020-02-22 08:15:56 UTC
Permalink
Post by Michael H___
I hope, this is the correct group. Please excuse, if not...
- I try to open devices with NtOpenFile for \\Device\\KeyboardClass%i, with %i from 0-31. (I use ACCESS_MASK including SYNCHRONIZE, ie. asynchronous read.)
- I store each successfully opened handle in an array. I ignore all others.
- I loop through the handle array. For each handle I call NtReadFile (I am not using events).
- When the loop is finished, I wait for multiple objects (all the keyboard handles, WaitAny, no timeout).
- When a key is pressed, NtWaitForMultipleObjects returns with the index of the signaled handle (I presume).
I have one physical PS/2 keyboard attached. In the Registry I see in 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\kbdclass\Enum' the name '0' with value 'Root\RDP_KBD\0000' and the name '1' with value 'ACPI\PNP0303\4&1d401fb5&0'.
I think the former is the Terminal Service Virtual Keyboard, and the latter is the physical PS/2 keyboard.
Indeed, I get valid handles for 'KeyboardClass0' and 'KeyboardClass1'.
Everytime I get a scancode from the NtReadFile, it comes from device #0 (the virtual keyboard). Not from the physical keyboard, as I would expect.
Can someone explain why?
kind regards,
Mike
Roberta Bahr
2020-02-22 08:18:11 UTC
Permalink
Post by Michael H___
I hope, this is the correct group. Please excuse, if not...
- I try to open devices with NtOpenFile for \\Device\\KeyboardClass%i, with %i from 0-31. (I use ACCESS_MASK including SYNCHRONIZE, ie. asynchronous read.)
- I store each successfully opened handle in an array. I ignore all others.
- I loop through the handle array. For each handle I call NtReadFile (I am not using events).
- When the loop is finished, I wait for multiple objects (all the keyboard handles, WaitAny, no timeout).
- When a key is pressed, NtWaitForMultipleObjects returns with the index of the signaled handle (I presume).
I have one physical PS/2 keyboard attached. In the Registry I see in 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\kbdclass\Enum' the name '0' with value 'Root\RDP_KBD\0000' and the name '1' with value 'ACPI\PNP0303\4&1d401fb5&0'.
I think the former is the Terminal Service Virtual Keyboard, and the latter is the physical PS/2 keyboard.
Indeed, I get valid handles for 'KeyboardClass0' and 'KeyboardClass1'.
Everytime I get a scancode from the NtReadFile, it comes from device #0 (the virtual keyboard). Not from the physical keyboard, as I would expect.
Can someone explain why?
kind regards,
hello,my,spacebar,doesnt,work,and,when,i,use,capslock,it,stays,locked,unless,i,use,shift+capslock??I,am,so,stuck,please,advise.yes,changed,equipment,several,times.
Loading...