What I am trying to do is something like this:
// memory address where the key press information is stored
constexpr void* KEY_PRESS_ADDRESS = reinterpret_cast<void*>(0x123456789);
// format of the data
struct KeyPressData
{
bool upArrowPressed;
bool downArrowPressed;
bool leftArrowPressed;
bool rightArrowPressed;
// etc..
};
int main()
{
while (true)
{
// read the key press data from memory
KeyPressData keyPressData;
std::memcpy(&keyPressData, KEY_PRESS_ADDRESS, sizeof(KeyPressData));
// check if the up-arrow key is being pressed
if (keyPressData.upArrowPressed)
{
// do stuff
}
}
return 0;
}
This code obviously does not work, as it is a concept. I am trying to do this from an external source such as a memory controller board. Hence I need to circumvent the use of normal methods such as "GetAsyncKeyState()" etc.
Is it even possible to do this in a safe and reliable way? And if so, how?
I realize that the memory address might differ depending on OS version, but is there even a data structure that contains the keypress information in memory? Within what section?
CodePudding user response:
In real mode, the BIOS uses data at 40:17 to store the keyboard flags, and a queue at 40:1E to store data that's been read from the keyboard. But I'm reasonably certain no modern OS uses the BIOS, so that probably doesn't work at all any more (except early in booting, while the BIOS is still active, and the OS hasn't booted yet).
If you want to make this work, you'll probably need to write a device driver (or modify an existing one) to capture the current keyboard state to allow the card to access it. On Windows, the most obvious choice would probably to make it a keyboard class filter driver. A keyboard filter driver is given the input from the keyboard so it can do things like ignoring certain input that's not desired. In your case, it'll pass all input through, unchanged--but it'll record the input to memory or (probably preferred) write it to the card.
If you really insist on writing the data to memory, you'll probably need to allocate that memory from the non-paged pool, then write its physical address to some register on the card (or something on that order) so the card will know where to read it. PCI/PCIe cards have a configuration space where you can write data to configure the card, but it's open to question what you'll need to write where to configure whatever card you're dealing with in this case.