tig / mcec

Robust remote control of Windows PCs over the network.
https://tig.github.io/mcec/
MIT License
80 stars 13 forks source link

Non-alphanumeric single character commands #13

Closed hotelfoxtrotnovember closed 4 years ago

hotelfoxtrotnovember commented 4 years ago

I'm not actually sure whether this is a bug or not, but I wanted to verify what the intended behavior was for non-alphanumeric single-character commands (both with and without shiftup/down). For example, if I send just a backtick (), the server appears to interpret that as VK_NUMPAD0 (0x60) and will type a zero (0) in notepad. shiftdown:shift also appears to have no effect on it (that is, whether or not preceded by shiftdown:shift, sending is interpreted as VK_NUMPAD0). Similar mis-mappings occur for almost all (or perhaps all) non-alphanumeric keyboard symbols sent as single-character commands, such as ! (VK_PRIOR), [ (VK_LWIN), and ] (VK_APPS).

So my questions are: (1) are non-alphanumeric single-character commands supported/intended to be supported? (2) are such commands supposed to respond to shiftup/down? [edit]: (3) is shiftup/down supposed to be ignored by alphanumeric values specified by "chars:"? For example, if shiftdown:shift is specified first, and then "a" is sent, a capital "A" is typed, but if "chars:a" is sent, then a lowercase "a" is typed.

I will note that the non-alphanumeric characters go through fine when preceded by "chars:", so this is more about understanding proper usage/behavior for the non-alphanumeric case. For context, I'm building a fully-functional keyboard in Home Remote and am trying to verify I'm sending commands correctly and how much of the shift functionality I can offload to MCEC vs. having to handle in the remote.

If non-alphanumeric single-character commands are not intended to be supported, it may be helpful to actively screen the single-character commands because you can get some really weird behavior otherwise and it may be more secure to verify only-permitted single-character inputs.

Please let me know if I can provide any additional information or clarification. Thanks again for this awesome project!

tig commented 4 years ago

From the docs:

Sending a single character without the chars: command (e.g. just c) is equivalent to a SendInput command defined as (see below). In other words, sending a single character is the same as a single key press of a key on the keyboard. For example sending a will result in the A key being pressed. 1 will result in the 1 key being pressed. There is no difference between sending a and A. Use shiftdown:/shiftup: to simulate the pressing of the shift, control, alt, and windows keys.

IOW, if you just send a single char, MCE Controller tries to map that char to a VK_ code. Hence backtick gets translated into the VK code for 0x60 (VK_NUMPAD0), not it's actually VK code (which is VK_OEM_3).

See: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

If you want to send non-alpha chars, you can either:

or

or

Please let me know if you still are having trouble. Happy to tweak it to make it work for you.

hotelfoxtrotnovember commented 4 years ago

Thank you so much for the explanation. Now that I've connected one missing dot, I believe I understand what's going on. Just for the benefit of anyone else looking at this in the future, the dot I was missing is that the ascii byte value for the backtick character is 0x60, which is what I was sending over the connection and that is why it then got mapped to the VK_NUMPAD0 code (which is value 0x60). I'm not particularly familiar with keyboard layout/region mapping stuff so I just incorrectly assumed the non-alphanumeric characters worked the same as the alphanumeric ones and that the key mappings were the same as well.

Now that I have a clearer picture of what is going on, I should be able to make things work with "chars:". One last thing I just discovered, that again may or may not be a bug, is that "chars:" followed by a single backslash character results in typing 0 characters. I suspect that is because the single backslash is being treated as an escape character? However, since "chars:" uses literal values, does having an escape character make sense? All the other non-alphanumeric characters I tried worked fine with "chars:" (including the ones that typically need an escape character) and "chars:" with two backslashes does type a single backslash. Just wanted to confirm this was intentional behavior.

That's kind of a long-winded way to say I think I've got everything I need and thank you again for your help with this!

tig commented 4 years ago

chars: supports escaped characters, and thus chars:\ is invalid. To send a \ you need to do chars:\\. I should log when this happens and fix the docs.

Thanks.